Compare commits
	
		
			197 Commits
		
	
	
		
			mesa-10.2.
			...
			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 | # Rules for making release tarballs | ||||||
|  |  | ||||||
| VERSION=7.7.1-devel | VERSION=7.7.1 | ||||||
| DIRECTORY = Mesa-$(VERSION) | DIRECTORY = Mesa-$(VERSION) | ||||||
| LIB_NAME = MesaLib-$(VERSION) | LIB_NAME = MesaLib-$(VERSION) | ||||||
| DEMO_NAME = MesaDemos-$(VERSION) | DEMO_NAME = MesaDemos-$(VERSION) | ||||||
|   | |||||||
| @@ -920,6 +920,11 @@ case $ARCH in | |||||||
|  |  | ||||||
|             # make lib |             # make lib | ||||||
|             ${LINK} ${OPTS} ${LDFLAGS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS} |             ${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 |             # make usual symlinks | ||||||
|             ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a |             ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a | ||||||
|             # finish up |             # finish up | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -20,6 +20,8 @@ AC_CANONICAL_HOST | |||||||
| dnl Versions for external dependencies | dnl Versions for external dependencies | ||||||
| LIBDRM_REQUIRED=2.4.15 | LIBDRM_REQUIRED=2.4.15 | ||||||
| LIBDRM_RADEON_REQUIRED=2.4.17 | LIBDRM_RADEON_REQUIRED=2.4.17 | ||||||
|  | LIBDRM_XORG_REQUIRED=2.4.17 | ||||||
|  | LIBKMS_XORG_REQUIRED=1.0.0 | ||||||
| DRI2PROTO_REQUIRED=1.99.3 | DRI2PROTO_REQUIRED=1.99.3 | ||||||
|  |  | ||||||
| dnl Check for progs | dnl Check for progs | ||||||
| @@ -91,6 +93,9 @@ linux*|*-gnu*|gnu*) | |||||||
| solaris*) | solaris*) | ||||||
|     DEFINES="$DEFINES -DPTHREADS -DSVR4" |     DEFINES="$DEFINES -DPTHREADS -DSVR4" | ||||||
|     ;; |     ;; | ||||||
|  | cygwin*) | ||||||
|  |     DEFINES="$DEFINES -DPTHREADS" | ||||||
|  |     ;; | ||||||
| esac | esac | ||||||
|  |  | ||||||
| dnl Add flags for gcc and g++ | dnl Add flags for gcc and g++ | ||||||
| @@ -1149,7 +1154,7 @@ yes) | |||||||
|             GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl" |             GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl" | ||||||
|         fi |         fi | ||||||
|         # Have only tested st/xorg on 1.6.0 servers |         # 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="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg", | ||||||
|             HAVE_XORG="no") |             HAVE_XORG="no") | ||||||
|         ;; |         ;; | ||||||
| @@ -1166,15 +1171,21 @@ yes) | |||||||
|             AC_MSG_ERROR([cannot build egl state tracker without EGL library]) |             AC_MSG_ERROR([cannot build egl state tracker without EGL library]) | ||||||
|         fi |         fi | ||||||
|         if test "$tracker" = xorg; then |         if test "$tracker" = xorg; then | ||||||
| 	    PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], |             PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED]) | ||||||
|                   HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71", |             PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED]) | ||||||
|                   HAVE_XEXTPROTO_71="no") |             HAVE_XORG="yes" | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
|     GALLIUM_STATE_TRACKERS_DIRS="$state_trackers" |     GALLIUM_STATE_TRACKERS_DIRS="$state_trackers" | ||||||
|     ;; |     ;; | ||||||
| esac | 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], | AC_ARG_WITH([xorg-driver-dir], | ||||||
|     [AS_HELP_STRING([--with-xorg-driver-dir=DIR], |     [AS_HELP_STRING([--with-xorg-driver-dir=DIR], | ||||||
|                     [Default xorg driver directory[[default=${libdir}/xorg/modules/drivers]]])], |                     [Default xorg driver directory[[default=${libdir}/xorg/modules/drivers]]])], | ||||||
|   | |||||||
| @@ -10,6 +10,15 @@ | |||||||
|  |  | ||||||
| <H1>News</H1> | <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> | <h2>December 21, 2009</h2> | ||||||
| <p> | <p> | ||||||
| <a href="relnotes-7.6.1.html">Mesa 7.6.1</a> is released.  This is a bug-fix | <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> | ||||||
|  |  | ||||||
| <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. | directory. | ||||||
| </p> | </p> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  |  | ||||||
| <body bgcolor="#eeeeee"> | <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> | <p> | ||||||
| Mesa 7.7.1 is a bug-fix release. | Mesa 7.7.1 is a bug-fix release. | ||||||
| @@ -26,16 +26,18 @@ for DRI hardware acceleration. | |||||||
|  |  | ||||||
| <h2>MD5 checksums</h2> | <h2>MD5 checksums</h2> | ||||||
| <pre> | <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> | </pre> | ||||||
|  |  | ||||||
|  |  | ||||||
| <h2>New features</h2> |  | ||||||
| <ul> |  | ||||||
| <li>tbd |  | ||||||
| </ul> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| <h2>Bug fixes</h2> | <h2>Bug fixes</h2> | ||||||
| <ul> | <ul> | ||||||
| <li>Assorted fixes to VMware SVGA gallium driver. | <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>Allocate constants more tightly in GL_ARB_vertex/fragment parser. | ||||||
| <li>Fixed mipmap generation bug caused by invalid viewport state. | <li>Fixed mipmap generation bug caused by invalid viewport state. | ||||||
| <li>Gallium SSE codegen for XPD didn't always work. | <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> | </ul> | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| <HTML> | <HTML> | ||||||
|  |  | ||||||
| <TITLE>Cocd Repository</TITLE> | <TITLE>Code Repository</TITLE> | ||||||
|  |  | ||||||
| <link rel="stylesheet" type="text/css" href="mesa.css"></head> | <link rel="stylesheet" type="text/css" href="mesa.css"></head> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -171,7 +171,7 @@ print_program_limits(GLenum target) | |||||||
|       GLenum token; |       GLenum token; | ||||||
|       const char *name; |       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_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" }, | ||||||
|       { GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" }, |       { GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" }, | ||||||
|       { GL_MAX_PROGRAM_TEMPORARIES_ARB, "GL_MAX_PROGRAM_TEMPORARIES_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_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_LOCAL_PARAMETERS_ARB, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" }, | ||||||
|       { GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, "GL_MAX_PROGRAM_ENV_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_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_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" }, | ||||||
|       { GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_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" }, |       { GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" }, | ||||||
|       { (GLenum) 0, NULL } |       { (GLenum) 0, NULL } | ||||||
|    }; |    }; | ||||||
|  |  | ||||||
|    PFNGLGETPROGRAMIVARBPROC GetProgramivARB_func = (PFNGLGETPROGRAMIVARBPROC) |    PFNGLGETPROGRAMIVARBPROC GetProgramivARB_func = (PFNGLGETPROGRAMIVARBPROC) | ||||||
|       glXGetProcAddressARB((GLubyte *) "glGetProgramivARB"); |       glXGetProcAddressARB((GLubyte *) "glGetProgramivARB"); | ||||||
|  |  | ||||||
|    GLint max[1]; |    GLint max[1]; | ||||||
|    int i; |    int i; | ||||||
|  |  | ||||||
| @@ -207,10 +212,18 @@ print_program_limits(GLenum target) | |||||||
|       return; /* something's wrong */ |       return; /* something's wrong */ | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    for (i = 0; limits[i].token; i++) { |    for (i = 0; common_limits[i].token; i++) { | ||||||
|       GetProgramivARB_func(target, limits[i].token, max); |       GetProgramivARB_func(target, common_limits[i].token, max); | ||||||
|       if (glGetError() == GL_NO_ERROR) { |       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 */ | #endif /* GL_ARB_vertex_program / GL_ARB_fragment_program */ | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ prefixes = SCons.Util.Split(""" | |||||||
|     i486-mingw32msvc- |     i486-mingw32msvc- | ||||||
|     i586-mingw32msvc- |     i586-mingw32msvc- | ||||||
|     i686-mingw32msvc- |     i686-mingw32msvc- | ||||||
|  |     i686-pc-mingw32- | ||||||
| """) | """) | ||||||
|  |  | ||||||
| def find(env): | def find(env): | ||||||
|   | |||||||
| @@ -235,7 +235,9 @@ def generate(env): | |||||||
|     # different scons versions building the same source file |     # different scons versions building the same source file | ||||||
|     env['build'] = build_dir |     env['build'] = build_dir | ||||||
|     env.SConsignFile(os.path.join(build_dir, '.sconsign')) |     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 |     # Parallel build | ||||||
|     if env.GetOption('num_jobs') <= 1: |     if env.GetOption('num_jobs') <= 1: | ||||||
| @@ -255,8 +257,9 @@ def generate(env): | |||||||
|             '_WINDOWS', |             '_WINDOWS', | ||||||
|             #'_UNICODE', |             #'_UNICODE', | ||||||
|             #'UNICODE', |             #'UNICODE', | ||||||
|             ('_WIN32_WINNT', '0x0501'), # minimum required OS version |             # http://msdn.microsoft.com/en-us/library/aa383745.aspx | ||||||
|             ('WINVER', '0x0501'), |             ('_WIN32_WINNT', '0x0601'), | ||||||
|  |             ('WINVER', '0x0601'), | ||||||
|             # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx, |             # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx, | ||||||
|             'WIN32_LEAN_AND_MEAN', |             'WIN32_LEAN_AND_MEAN', | ||||||
|         ] |         ] | ||||||
|   | |||||||
| @@ -347,7 +347,8 @@ vcache_check_run( struct draw_pt_front_end *frontend, | |||||||
|                        draw_count); |                        draw_count); | ||||||
|        |        | ||||||
|    if (max_index == 0xffffffff || |    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"); |       if (0) debug_printf("fail\n"); | ||||||
|       goto fail; |       goto fail; | ||||||
|    } |    } | ||||||
|   | |||||||
| @@ -179,7 +179,9 @@ pb_debug_buffer_check(struct pb_debug_buffer *buf) | |||||||
| { | { | ||||||
|    uint8_t *map; |    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); |    assert(map); | ||||||
|    if(map) { |    if(map) { | ||||||
|       boolean underflow, overflow; |       boolean underflow, overflow; | ||||||
|   | |||||||
| @@ -133,8 +133,7 @@ static const union tgsi_exec_channel ZeroVec = | |||||||
|    { { 0.0, 0.0, 0.0, 0.0 } }; |    { { 0.0, 0.0, 0.0, 0.0 } }; | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef DEBUG | static INLINE void | ||||||
| static void |  | ||||||
| check_inf_or_nan(const union tgsi_exec_channel *chan) | check_inf_or_nan(const union tgsi_exec_channel *chan) | ||||||
| { | { | ||||||
|    assert(!util_is_inf_or_nan(chan->f[0])); |    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[2])); | ||||||
|    assert(!util_is_inf_or_nan(chan->f[3])); |    assert(!util_is_inf_or_nan(chan->f[3])); | ||||||
| } | } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| @@ -338,7 +336,9 @@ tgsi_exec_machine_bind_shader( | |||||||
|             /* XXX we only handle SOA dependencies properly for MOV/SWZ |             /* XXX we only handle SOA dependencies properly for MOV/SWZ | ||||||
|              * at this time! |              * 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" |                debug_printf("Warning: SOA dependency in instruction" | ||||||
|                             " is not handled:\n"); |                             " is not handled:\n"); | ||||||
|                tgsi_dump_instruction(&parse.FullToken.FullInstruction, |                tgsi_dump_instruction(&parse.FullToken.FullInstruction, | ||||||
| @@ -1424,9 +1424,9 @@ store_dest( | |||||||
|    int offset = 0;  /* indirection offset */ |    int offset = 0;  /* indirection offset */ | ||||||
|    int index; |    int index; | ||||||
|  |  | ||||||
| #ifdef DEBUG |    if (0) { | ||||||
|    check_inf_or_nan(chan); |       check_inf_or_nan(chan); | ||||||
| #endif |    } | ||||||
|  |  | ||||||
|    /* There is an extra source register that indirectly subscripts |    /* There is an extra source register that indirectly subscripts | ||||||
|     * a register file. The direct index now becomes an offset |     * a register file. The direct index now becomes an offset | ||||||
| @@ -1854,7 +1854,8 @@ exec_instruction( | |||||||
|    int *pc ) |    int *pc ) | ||||||
| { | { | ||||||
|    uint chan_index; |    uint chan_index; | ||||||
|    union tgsi_exec_channel r[10]; |    union tgsi_exec_channel r[3 * NUM_CHANNELS]; | ||||||
|  |    union tgsi_exec_channel d[8]; | ||||||
|  |  | ||||||
|    (*pc)++; |    (*pc)++; | ||||||
|  |  | ||||||
| @@ -1981,14 +1982,27 @@ exec_instruction( | |||||||
|       break; |       break; | ||||||
|  |  | ||||||
|    case TGSI_OPCODE_MUL: |    case TGSI_OPCODE_MUL: | ||||||
|       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) |       if (inst->Flags & SOA_DEPENDENCY_FLAG) { | ||||||
|       { |          FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) | ||||||
|          FETCH(&r[0], 0, chan_index); |          { | ||||||
|          FETCH(&r[1], 1, 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; |       break; | ||||||
|  |  | ||||||
| @@ -2255,11 +2269,7 @@ exec_instruction( | |||||||
|       FETCH(&r[4], 1, CHAN_Y); |       FETCH(&r[4], 1, CHAN_Y); | ||||||
|  |  | ||||||
|       micro_mul( &r[5], &r[3], &r[4] ); |       micro_mul( &r[5], &r[3], &r[4] ); | ||||||
|       micro_sub( &r[2], &r[2], &r[5] ); |       micro_sub(&d[CHAN_X], &r[2], &r[5]); | ||||||
|  |  | ||||||
|       if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { |  | ||||||
|          STORE( &r[2], 0, CHAN_X ); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       FETCH(&r[2], 1, CHAN_X); |       FETCH(&r[2], 1, CHAN_X); | ||||||
|  |  | ||||||
| @@ -2268,26 +2278,27 @@ exec_instruction( | |||||||
|       FETCH(&r[5], 0, CHAN_X); |       FETCH(&r[5], 0, CHAN_X); | ||||||
|  |  | ||||||
|       micro_mul( &r[1], &r[1], &r[5] ); |       micro_mul( &r[1], &r[1], &r[5] ); | ||||||
|       micro_sub( &r[3], &r[3], &r[1] ); |       micro_sub(&d[CHAN_Y], &r[3], &r[1]); | ||||||
|  |  | ||||||
|       if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { |  | ||||||
|          STORE( &r[3], 0, CHAN_Y ); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       micro_mul( &r[5], &r[5], &r[4] ); |       micro_mul( &r[5], &r[5], &r[4] ); | ||||||
|       micro_mul( &r[0], &r[0], &r[2] ); |       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 )) { |       if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) { | ||||||
|          STORE( &r[5], 0, CHAN_Z ); |          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 )) { |       if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { | ||||||
|          STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); |          STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     case TGSI_OPCODE_ABS: |    case TGSI_OPCODE_ABS: | ||||||
|        FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { |        FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { | ||||||
|           FETCH(&r[0], 0, chan_index); |           FETCH(&r[0], 0, chan_index); | ||||||
|  |  | ||||||
| @@ -2667,14 +2678,28 @@ exec_instruction( | |||||||
|       break; |       break; | ||||||
|  |  | ||||||
|    case TGSI_OPCODE_CMP: |    case TGSI_OPCODE_CMP: | ||||||
|       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { |       if (inst->Flags & SOA_DEPENDENCY_FLAG) { | ||||||
|          FETCH(&r[0], 0, chan_index); |          FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { | ||||||
|          FETCH(&r[1], 1, chan_index); |             FETCH(&r[chan_index], 0, chan_index); | ||||||
|          FETCH(&r[2], 2, 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; |       break; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -216,6 +216,9 @@ iter_instruction( | |||||||
|          inst->FullDstRegisters[i].DstRegister.Index, |          inst->FullDstRegisters[i].DstRegister.Index, | ||||||
|          "destination", |          "destination", | ||||||
|          FALSE ); |          FALSE ); | ||||||
|  |       if (!inst->FullDstRegisters[i].DstRegister.WriteMask) { | ||||||
|  |          report_error(ctx, "Destination register has empty writemask"); | ||||||
|  |       } | ||||||
|    } |    } | ||||||
|    for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { |    for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { | ||||||
|       check_register_usage( |       check_register_usage( | ||||||
|   | |||||||
| @@ -644,6 +644,57 @@ void debug_dump_image(const char *prefix, | |||||||
|    } |    } | ||||||
|        |        | ||||||
|    EngUnmapFile(iFile); |    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 | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -628,7 +628,8 @@ lp_build_abs(struct lp_build_context *bld, | |||||||
|    if(type.floating) { |    if(type.floating) { | ||||||
|       /* Mask out the sign bit */ |       /* Mask out the sign bit */ | ||||||
|       LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); |       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 = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); | ||||||
|       a = LLVMBuildAnd(bld->builder, a, mask, ""); |       a = LLVMBuildAnd(bld->builder, a, mask, ""); | ||||||
|       a = LLVMBuildBitCast(bld->builder, a, vec_type, ""); |       a = LLVMBuildBitCast(bld->builder, a, vec_type, ""); | ||||||
| @@ -1082,7 +1083,7 @@ lp_build_log(struct lp_build_context *bld, | |||||||
|              LLVMValueRef x) |              LLVMValueRef x) | ||||||
| { | { | ||||||
|    /* log(2) */ |    /* 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)); |    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. |  * Generate polynomial. | ||||||
|  * Ex:  x^2 * coeffs[0] + x * coeffs[1] + coeffs[2]. |  * Ex:  coeffs[0] + x * coeffs[1] + x^2 * coeffs[2]. | ||||||
|  */ |  */ | ||||||
| static LLVMValueRef | static LLVMValueRef | ||||||
| lp_build_polynomial(struct lp_build_context *bld, | 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 = (float) mantissa(x) */ | ||||||
|       mant = LLVMBuildAnd(bld->builder, i, mantmask, ""); |       mant = LLVMBuildAnd(bld->builder, i, mantmask, ""); | ||||||
|       mant = LLVMBuildOr(bld->builder, mant, one, ""); |       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, |       logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial, | ||||||
|                                     Elements(lp_build_log2_polynomial)); |                                     Elements(lp_build_log2_polynomial)); | ||||||
|  |  | ||||||
|       /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/ |       /* 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, ""); |       res = LLVMBuildAdd(bld->builder, logmant, logexp, ""); | ||||||
|    } |    } | ||||||
|   | |||||||
| @@ -766,7 +766,7 @@ emit_instruction( | |||||||
|       FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) { |       FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) { | ||||||
|          src0 = emit_fetch( bld, inst, 0, chan_index ); |          src0 = emit_fetch( bld, inst, 0, chan_index ); | ||||||
|          tmp0 = lp_build_floor(&bld->base, src0); |          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; |          dst0[chan_index] = tmp0; | ||||||
|       } |       } | ||||||
|       break; |       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); |    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++) { |    for (i = 0; i < lp->num_vertex_buffers; i++) { | ||||||
|       draw_set_mapped_vertex_buffer(draw, i, NULL); |       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); |       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 */ |    /* 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)) { |    if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) { | ||||||
|       _debug_printf("%s\n", error); |       _debug_printf("%s\n", error); | ||||||
|       LLVMDisposeMessage(error); |       LLVMDisposeMessage(error); | ||||||
|       abort(); |       assert(0); | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    screen->target = LLVMGetExecutionEngineTargetData(screen->engine); |    screen->target = LLVMGetExecutionEngineTargetData(screen->engine); | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| #include "util/u_memory.h" | #include "util/u_memory.h" | ||||||
|  | #include "util/u_format.h" | ||||||
| #include "pipe/p_defines.h" | #include "pipe/p_defines.h" | ||||||
| #include "pipe/p_screen.h" | #include "pipe/p_screen.h" | ||||||
|  |  | ||||||
| @@ -35,6 +36,24 @@ | |||||||
| #include "lp_winsys.h" | #include "lp_winsys.h" | ||||||
| #include "lp_jit.h" | #include "lp_jit.h" | ||||||
| #include "lp_screen.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 * | static const char * | ||||||
| @@ -131,17 +150,17 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, | |||||||
| { | { | ||||||
|    struct llvmpipe_screen *screen = llvmpipe_screen(_screen); |    struct llvmpipe_screen *screen = llvmpipe_screen(_screen); | ||||||
|    struct llvmpipe_winsys *winsys = screen->winsys; |    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 || |    assert(target == PIPE_TEXTURE_1D || | ||||||
|           target == PIPE_TEXTURE_2D || |           target == PIPE_TEXTURE_2D || | ||||||
|           target == PIPE_TEXTURE_3D || |           target == PIPE_TEXTURE_3D || | ||||||
|           target == PIPE_TEXTURE_CUBE); |           target == PIPE_TEXTURE_CUBE); | ||||||
|  |  | ||||||
|    if(format == PIPE_FORMAT_Z16_UNORM) |  | ||||||
|       return FALSE; |  | ||||||
|    if(format == PIPE_FORMAT_S8_UNORM) |  | ||||||
|       return FALSE; |  | ||||||
|  |  | ||||||
|    switch(format) { |    switch(format) { | ||||||
|    case PIPE_FORMAT_DXT1_RGB: |    case PIPE_FORMAT_DXT1_RGB: | ||||||
|    case PIPE_FORMAT_DXT1_RGBA: |    case PIPE_FORMAT_DXT1_RGBA: | ||||||
| @@ -152,8 +171,51 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, | |||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) |    if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { | ||||||
|       return winsys->is_displaytarget_format_supported(winsys, format); |       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; |    return TRUE; | ||||||
| } | } | ||||||
| @@ -213,6 +275,10 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys) | |||||||
| { | { | ||||||
|    struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen); |    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) |    if (!screen) | ||||||
|       return NULL; |       return NULL; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ | |||||||
| #include "util/u_memory.h" | #include "util/u_memory.h" | ||||||
| #include "util/u_math.h" | #include "util/u_math.h" | ||||||
| #include "util/u_debug_dump.h" | #include "util/u_debug_dump.h" | ||||||
|  | #include "draw/draw_context.h" | ||||||
| #include "lp_screen.h" | #include "lp_screen.h" | ||||||
| #include "lp_context.h" | #include "lp_context.h" | ||||||
| #include "lp_state.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); |    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); | ||||||
|  |  | ||||||
|  |    if (llvmpipe->blend == blend) | ||||||
|  |       return; | ||||||
|  |  | ||||||
|  |    draw_flush(llvmpipe->draw); | ||||||
|  |  | ||||||
|    llvmpipe->blend = blend; |    llvmpipe->blend = blend; | ||||||
|  |  | ||||||
|    llvmpipe->dirty |= LP_NEW_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); |    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); | ||||||
|    unsigned i, j; |    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); |    memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color); | ||||||
|  |  | ||||||
|    if(!llvmpipe->jit_context.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); |    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) |    if(llvmpipe->depth_stencil) | ||||||
|       llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value; |       llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value; | ||||||
|   | |||||||
| @@ -85,6 +85,7 @@ | |||||||
| #include "lp_buffer.h" | #include "lp_buffer.h" | ||||||
| #include "lp_state.h" | #include "lp_state.h" | ||||||
| #include "lp_tex_sample.h" | #include "lp_tex_sample.h" | ||||||
|  | #include "lp_debug.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| static const unsigned char quad_offset_x[4] = {0, 1, 0, 1}; | 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); |    format_desc = util_format_description(key->zsbuf_format); | ||||||
|    assert(format_desc); |    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. */ |    /* Pick the depth type. */ | ||||||
|    dst_type = lp_depth_type(format_desc, src_type.width*src_type.length); |    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.width == src_type.width); | ||||||
|    assert(dst_type.length == src_type.length); |    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); |    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, |    lp_build_depth_test(builder, | ||||||
|                        &key->depth, |                        &key->depth, | ||||||
| @@ -395,59 +407,58 @@ generate_fragment(struct llvmpipe_context *lp, | |||||||
|    unsigned i; |    unsigned i; | ||||||
|    unsigned chan; |    unsigned chan; | ||||||
|  |  | ||||||
| #ifdef DEBUG |    if (LP_DEBUG & DEBUG_JIT) { | ||||||
|    tgsi_dump(shader->base.tokens, 0); |       tgsi_dump(shader->base.tokens, 0); | ||||||
|    if(key->depth.enabled) { |       if(key->depth.enabled) { | ||||||
|       debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format)); |          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.func = %s\n", debug_dump_func(key->depth.func, TRUE)); | ||||||
|       debug_printf("depth.writemask = %u\n", key->depth.writemask); |          debug_printf("depth.writemask = %u\n", key->depth.writemask); | ||||||
|    } |       } | ||||||
|    if(key->alpha.enabled) { |       if(key->alpha.enabled) { | ||||||
|       debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE)); |          debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE)); | ||||||
|       debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); |          debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); | ||||||
|    } |       } | ||||||
|    if(key->blend.logicop_enable) { |       if(key->blend.logicop_enable) { | ||||||
|       debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func); |          debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func); | ||||||
|    } |       } | ||||||
|    else if(key->blend.blend_enable) { |       else if(key->blend.blend_enable) { | ||||||
|       debug_printf("blend.rgb_func = %s\n",   debug_dump_blend_func  (key->blend.rgb_func, TRUE)); |          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_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("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_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_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("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); |       debug_printf("blend.colormask = 0x%x\n", key->blend.colormask); | ||||||
|    for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { |       for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { | ||||||
|       if(key->sampler[i].format) { |          if(key->sampler[i].format) { | ||||||
|          debug_printf("sampler[%u] = \n", i); |             debug_printf("sampler[%u] = \n", i); | ||||||
|          debug_printf("  .format = %s\n", |             debug_printf("  .format = %s\n", | ||||||
|                       pf_name(key->sampler[i].format)); |                          pf_name(key->sampler[i].format)); | ||||||
|          debug_printf("  .target = %s\n", |             debug_printf("  .target = %s\n", | ||||||
|                       debug_dump_tex_target(key->sampler[i].target, TRUE)); |                          debug_dump_tex_target(key->sampler[i].target, TRUE)); | ||||||
|          debug_printf("  .pot = %u %u %u\n", |             debug_printf("  .pot = %u %u %u\n", | ||||||
|                       key->sampler[i].pot_width, |                          key->sampler[i].pot_width, | ||||||
|                       key->sampler[i].pot_height, |                          key->sampler[i].pot_height, | ||||||
|                       key->sampler[i].pot_depth); |                          key->sampler[i].pot_depth); | ||||||
|          debug_printf("  .wrap = %s %s %s\n", |             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_s, TRUE), | ||||||
|                       debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), |                          debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), | ||||||
|                       debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); |                          debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); | ||||||
|          debug_printf("  .min_img_filter = %s\n", |             debug_printf("  .min_img_filter = %s\n", | ||||||
|                       debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); |                          debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); | ||||||
|          debug_printf("  .min_mip_filter = %s\n", |             debug_printf("  .min_mip_filter = %s\n", | ||||||
|                       debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); |                          debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); | ||||||
|          debug_printf("  .mag_img_filter = %s\n", |             debug_printf("  .mag_img_filter = %s\n", | ||||||
|                       debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); |                          debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); | ||||||
|          if(key->sampler[i].compare_mode) |             if(key->sampler[i].compare_mode) | ||||||
|             debug_printf("  .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE)); |                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("  .normalized_coords = %u\n", key->sampler[i].normalized_coords); | ||||||
|          debug_printf("  .prefilter = %u\n", key->sampler[i].prefilter); |             debug_printf("  .prefilter = %u\n", key->sampler[i].prefilter); | ||||||
|  |          } | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|    variant = CALLOC_STRUCT(lp_fragment_shader_variant); |    variant = CALLOC_STRUCT(lp_fragment_shader_variant); | ||||||
|    if(!variant) |    if(!variant) | ||||||
|       return NULL; |       return NULL; | ||||||
| @@ -586,8 +597,8 @@ generate_fragment(struct llvmpipe_context *lp, | |||||||
|    } |    } | ||||||
|  |  | ||||||
|    lp_build_conv_mask(builder, fs_type, blend_type, |    lp_build_conv_mask(builder, fs_type, blend_type, | ||||||
|                                fs_mask, num_fs, |                       fs_mask, num_fs, | ||||||
|                                &blend_mask, 1); |                       &blend_mask, 1); | ||||||
|  |  | ||||||
|    /* |    /* | ||||||
|     * Blending. |     * Blending. | ||||||
| @@ -609,23 +620,24 @@ generate_fragment(struct llvmpipe_context *lp, | |||||||
|     * Translate the LLVM IR into machine code. |     * Translate the LLVM IR into machine code. | ||||||
|     */ |     */ | ||||||
|  |  | ||||||
|  | #ifdef DEBUG | ||||||
|    if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) { |    if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) { | ||||||
|       LLVMDumpValue(variant->function); |       LLVMDumpValue(variant->function); | ||||||
|       abort(); |       assert(0); | ||||||
|    } |    } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|    LLVMRunFunctionPassManager(screen->pass, variant->function); |    LLVMRunFunctionPassManager(screen->pass, variant->function); | ||||||
|  |  | ||||||
| #ifdef DEBUG |    if (LP_DEBUG & DEBUG_JIT) { | ||||||
|    LLVMDumpValue(variant->function); |       LLVMDumpValue(variant->function); | ||||||
|    debug_printf("\n"); |       debug_printf("\n"); | ||||||
| #endif |    } | ||||||
|  |  | ||||||
|    variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function); |    variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function); | ||||||
|  |  | ||||||
| #ifdef DEBUG |    if (LP_DEBUG & DEBUG_ASM) | ||||||
|    lp_disassemble(variant->jit_function); |       lp_disassemble(variant->jit_function); | ||||||
| #endif |  | ||||||
|  |  | ||||||
|    variant->next = shader->variants; |    variant->next = shader->variants; | ||||||
|    shader->variants = variant; |    shader->variants = variant; | ||||||
| @@ -659,7 +671,12 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs) | |||||||
| { | { | ||||||
|    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); |    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; |    llvmpipe->dirty |= LP_NEW_FS; | ||||||
| } | } | ||||||
| @@ -710,8 +727,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, | |||||||
|    assert(shader < PIPE_SHADER_TYPES); |    assert(shader < PIPE_SHADER_TYPES); | ||||||
|    assert(index == 0); |    assert(index == 0); | ||||||
|  |  | ||||||
|    if(shader == PIPE_SHADER_VERTEX) |    draw_flush(llvmpipe->draw); | ||||||
|       draw_flush(llvmpipe->draw); |  | ||||||
|  |  | ||||||
|    /* note: reference counting */ |    /* note: reference counting */ | ||||||
|    pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer); |    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 llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, | ||||||
|                                     void *setup) |                                     void *rasterizer) | ||||||
| { | { | ||||||
|    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); |    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); | ||||||
|  |  | ||||||
|    /* pass-through to draw module */ |    if (llvmpipe->rasterizer == rasterizer) | ||||||
|    draw_set_rasterizer_state(llvmpipe->draw, setup); |       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; |    llvmpipe->dirty |= LP_NEW_RASTERIZER; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -48,6 +48,8 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe, | |||||||
|    struct llvmpipe_context *lp = llvmpipe_context(pipe); |    struct llvmpipe_context *lp = llvmpipe_context(pipe); | ||||||
|    uint i; |    uint i; | ||||||
|  |  | ||||||
|  |    draw_flush(lp->draw); | ||||||
|  |  | ||||||
|    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { |    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { | ||||||
|       /* check if changing cbuf */ |       /* check if changing cbuf */ | ||||||
|       if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) { |       if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) { | ||||||
|   | |||||||
| @@ -70,14 +70,18 @@ fail: | |||||||
|  |  | ||||||
|  |  | ||||||
| void | 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); |    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,  |    draw_bind_vertex_shader(llvmpipe->draw,  | ||||||
|                            (llvmpipe->vs ? llvmpipe->vs->draw_data : NULL)); |                            vs ? vs->draw_data : NULL); | ||||||
|  |  | ||||||
|  |    llvmpipe->vs = vs; | ||||||
|  |  | ||||||
|    llvmpipe->dirty |= LP_NEW_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; |       (struct lp_vertex_shader *)vs; | ||||||
|  |  | ||||||
|    draw_delete_vertex_shader(llvmpipe->draw, state->draw_data); |    draw_delete_vertex_shader(llvmpipe->draw, state->draw_data); | ||||||
|  |    FREE( (void *)state->shader.tokens ); | ||||||
|    FREE( state ); |    FREE( state ); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -714,9 +714,14 @@ depth_test_quads_fallback(struct quad_stage *qs, | |||||||
|       qs->next->run(qs->next, quads, nr); |       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 | static void | ||||||
| depth_interp_z16_less_write(struct quad_stage *qs,  | 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; |    const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy; | ||||||
|    struct softpipe_cached_tile *tile; |    struct softpipe_cached_tile *tile; | ||||||
|    ushort (*depth16)[TILE_SIZE]; |    ushort (*depth16)[TILE_SIZE]; | ||||||
|    ushort idepth[4], depth_step; |    ushort init_idepth[4], idepth[4], depth_step; | ||||||
|    const float scale = 65535.0; |    const float scale = 65535.0; | ||||||
|  |  | ||||||
|    idepth[0] = (ushort)((z0) * scale); |    /* compute scaled depth of the four pixels in first quad */ | ||||||
|    idepth[1] = (ushort)((z0 + dzdx) * scale); |    init_idepth[0] = (ushort)((z0) * scale); | ||||||
|    idepth[2] = (ushort)((z0 + dzdy) * scale); |    init_idepth[1] = (ushort)((z0 + dzdx) * scale); | ||||||
|    idepth[3] = (ushort)((z0 + dzdx + dzdy) * 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); |    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++) { |    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; |       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]) { |       if ((outmask & 1) && idepth[0] < depth16[0][0]) { | ||||||
|          depth16[0][0] = idepth[0]; |          depth16[0][0] = idepth[0]; | ||||||
|          mask |= (1 << 0); |          mask |= (1 << 0); | ||||||
| @@ -772,13 +785,6 @@ depth_interp_z16_less_write(struct quad_stage *qs, | |||||||
|          mask |= (1 << 3); |          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; |       quads[i]->inout.mask = mask; | ||||||
|       if (quads[i]->inout.mask) |       if (quads[i]->inout.mask) | ||||||
|          quads[pass++] = quads[i]; |          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 | static void | ||||||
| depth_interp_z16_lequal_write(struct quad_stage *qs,  | depth_interp_z16_lequal_write(struct quad_stage *qs,  | ||||||
|                             struct quad_header *quads[], |                             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; |    const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy; | ||||||
|    struct softpipe_cached_tile *tile; |    struct softpipe_cached_tile *tile; | ||||||
|    ushort (*depth16)[TILE_SIZE]; |    ushort (*depth16)[TILE_SIZE]; | ||||||
|    ushort idepth[4], depth_step; |    ushort init_idepth[4], idepth[4], depth_step; | ||||||
|    const float scale = 65535.0; |    const float scale = 65535.0; | ||||||
|  |  | ||||||
|    idepth[0] = (ushort)((z0) * scale); |    /* compute scaled depth of the four pixels in first quad */ | ||||||
|    idepth[1] = (ushort)((z0 + dzdx) * scale); |    init_idepth[0] = (ushort)((z0) * scale); | ||||||
|    idepth[2] = (ushort)((z0 + dzdy) * scale); |    init_idepth[1] = (ushort)((z0 + dzdx) * scale); | ||||||
|    idepth[3] = (ushort)((z0 + dzdx + dzdy) * 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); |    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++) { |    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; |       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]) { |       if ((outmask & 1) && idepth[0] <= depth16[0][0]) { | ||||||
|          depth16[0][0] = idepth[0]; |          depth16[0][0] = idepth[0]; | ||||||
|          mask |= (1 << 0); |          mask |= (1 << 0); | ||||||
| @@ -844,11 +866,6 @@ depth_interp_z16_lequal_write(struct quad_stage *qs, | |||||||
|          mask |= (1 << 3); |          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]; |       depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2]; | ||||||
|  |  | ||||||
|       quads[i]->inout.mask = mask; |       quads[i]->inout.mask = mask; | ||||||
|   | |||||||
| @@ -805,7 +805,6 @@ line_persp_coeff(const struct setup_context *setup, | |||||||
|                  struct tgsi_interp_coef *coef, |                  struct tgsi_interp_coef *coef, | ||||||
|                  uint vertSlot, uint i) |                  uint vertSlot, uint i) | ||||||
| { | { | ||||||
|    /* XXX double-check/verify this arithmetic */ |  | ||||||
|    const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; |    const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; | ||||||
|    const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; |    const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; | ||||||
|    const float da = a1 - a0; |    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; |    const float dady = da * setup->emaj.dy * setup->oneoverarea; | ||||||
|    coef->dadx[i] = dadx; |    coef->dadx[i] = dadx; | ||||||
|    coef->dady[i] = dady; |    coef->dady[i] = dady; | ||||||
|    coef->a0[i] = (setup->vmin[vertSlot][i] - |    coef->a0[i] = (a0 - | ||||||
|                   (dadx * (setup->vmin[0][0] - setup->pixel_offset) + |                   (dadx * (setup->vmin[0][0] - setup->pixel_offset) + | ||||||
|                    dady * (setup->vmin[0][1] - setup->pixel_offset))); |                    dady * (setup->vmin[0][1] - setup->pixel_offset))); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "util/u_memory.h" | #include "util/u_memory.h" | ||||||
|  | #include "draw/draw_context.h" | ||||||
| #include "sp_context.h" | #include "sp_context.h" | ||||||
| #include "sp_state.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); |    struct softpipe_context *softpipe = softpipe_context(pipe); | ||||||
|  |  | ||||||
|  |    draw_flush(softpipe->draw); | ||||||
|  |  | ||||||
|    softpipe->blend = (struct pipe_blend_state *)blend; |    softpipe->blend = (struct pipe_blend_state *)blend; | ||||||
|  |  | ||||||
|    softpipe->dirty |= SP_NEW_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); |    struct softpipe_context *softpipe = softpipe_context(pipe); | ||||||
|  |  | ||||||
|  |    draw_flush(softpipe->draw); | ||||||
|  |  | ||||||
|    softpipe->blend_color = *blend_color; |    softpipe->blend_color = *blend_color; | ||||||
|  |  | ||||||
|    softpipe->dirty |= SP_NEW_BLEND; |    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); |    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; |    softpipe->dirty |= SP_NEW_FS; | ||||||
| } | } | ||||||
| @@ -159,6 +166,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, | |||||||
|    assert(shader < PIPE_SHADER_TYPES); |    assert(shader < PIPE_SHADER_TYPES); | ||||||
|    assert(index == 0); |    assert(index == 0); | ||||||
|  |  | ||||||
|  |    draw_flush(softpipe->draw); | ||||||
|  |  | ||||||
|    /* note: reference counting */ |    /* note: reference counting */ | ||||||
|    pipe_buffer_reference(&softpipe->constants[shader].buffer, |    pipe_buffer_reference(&softpipe->constants[shader].buffer, | ||||||
| 			 buf ? buf->buffer : NULL); | 			 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 softpipe_bind_rasterizer_state(struct pipe_context *pipe, | ||||||
|                                     void *setup) |                                     void *rasterizer) | ||||||
| { | { | ||||||
|    struct softpipe_context *softpipe = softpipe_context(pipe); |    struct softpipe_context *softpipe = softpipe_context(pipe); | ||||||
|  |  | ||||||
|    /* pass-through to draw module */ |    if (softpipe->rasterizer == rasterizer) | ||||||
|    draw_set_rasterizer_state(softpipe->draw, setup); |       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; |    softpipe->dirty |= SP_NEW_RASTERIZER; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -48,6 +48,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, | |||||||
|    struct softpipe_context *sp = softpipe_context(pipe); |    struct softpipe_context *sp = softpipe_context(pipe); | ||||||
|    uint i; |    uint i; | ||||||
|  |  | ||||||
|  |    draw_flush(sp->draw); | ||||||
|  |  | ||||||
|    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { |    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { | ||||||
|       /* check if changing cbuf */ |       /* check if changing cbuf */ | ||||||
|       if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) { |       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 | static void | ||||||
| mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, | mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, | ||||||
|                    const float s[QUAD_SIZE], |                    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 |  * Use 3D texcoords to choose a cube face, then sample the 2D cube faces. | ||||||
|  * info into the sampler faces[] array.  Then sample the cube faces |  * Put face info into the sampler faces[] array. | ||||||
|  */ |  */ | ||||||
| static void | static void | ||||||
| sample_cube(struct tgsi_sampler *tgsi_sampler, | 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); |    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); | ||||||
|    unsigned j; |    unsigned j; | ||||||
|    float ssss[4], tttt[4]; |    float ssss[4], tttt[4]; | ||||||
|  |    unsigned face; | ||||||
|  |  | ||||||
|    /* |    /* | ||||||
|      major axis |      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_POSITIVE_X_EXT    -rz    -ry   rx | ||||||
|      -rx          TEXTURE_CUBE_MAP_NEGATIVE_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 |      +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_POSITIVE_Z_EXT    +rx    -ry   rz | ||||||
|      -rz          TEXTURE_CUBE_MAP_NEGATIVE_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]; |    /* First choose the cube face. | ||||||
|       float ry = t[j]; |     * Use the same cube face for all four pixels in the quad. | ||||||
|       float rz = p[j]; |     * | ||||||
|  |     * 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); |       const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); | ||||||
|       unsigned face; |  | ||||||
|       float sc, tc, ma; |  | ||||||
|  |  | ||||||
|       if (arx >= ary && arx >= arz) { |       if (arx >= ary && arx >= arz) { | ||||||
|          if (rx >= 0.0F) { |          if (rx >= 0.0F) { | ||||||
|             face = PIPE_TEX_FACE_POS_X; |             face = PIPE_TEX_FACE_POS_X; | ||||||
|             sc = -rz; |  | ||||||
|             tc = -ry; |  | ||||||
|             ma = arx; |  | ||||||
|          } |          } | ||||||
|          else { |          else { | ||||||
|             face = PIPE_TEX_FACE_NEG_X; |             face = PIPE_TEX_FACE_NEG_X; | ||||||
|             sc = rz; |  | ||||||
|             tc = -ry; |  | ||||||
|             ma = arx; |  | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|       else if (ary >= arx && ary >= arz) { |       else if (ary >= arx && ary >= arz) { | ||||||
|          if (ry >= 0.0F) { |          if (ry >= 0.0F) { | ||||||
|             face = PIPE_TEX_FACE_POS_Y; |             face = PIPE_TEX_FACE_POS_Y; | ||||||
|             sc = rx; |  | ||||||
|             tc = rz; |  | ||||||
|             ma = ary; |  | ||||||
|          } |          } | ||||||
|          else { |          else { | ||||||
|             face = PIPE_TEX_FACE_NEG_Y; |             face = PIPE_TEX_FACE_NEG_Y; | ||||||
|             sc = rx; |  | ||||||
|             tc = -rz; |  | ||||||
|             ma = ary; |  | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|          if (rz > 0.0F) { |          if (rz > 0.0F) { | ||||||
|             face = PIPE_TEX_FACE_POS_Z; |             face = PIPE_TEX_FACE_POS_Z; | ||||||
|             sc = rx; |  | ||||||
|             tc = -ry; |  | ||||||
|             ma = arz; |  | ||||||
|          } |          } | ||||||
|          else { |          else { | ||||||
|             face = PIPE_TEX_FACE_NEG_Z; |             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; | 	 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, |                               x, y, TILE_SIZE, TILE_SIZE, | ||||||
|                               tc->tile.data.color32, 0/*STRIDE*/); |                               tc->tile.data.color32, 0/*STRIDE*/); | ||||||
|  |  | ||||||
|             /* do this? */ |  | ||||||
|             clear_clear_flag(tc->clear_flags, addr); |  | ||||||
|  |  | ||||||
|             numCleared++; |             numCleared++; | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|  |  | ||||||
|  |    /* reset all clear flags to zero */ | ||||||
|  |    memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); | ||||||
|  |  | ||||||
| #if 0 | #if 0 | ||||||
|    debug_printf("num cleared: %u\n", numCleared); |    debug_printf("num cleared: %u\n", numCleared); | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -478,7 +478,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc, | |||||||
|                  struct svga_winsys_surface *host, |                  struct svga_winsys_surface *host, | ||||||
|                  SVGA3dTransferType transfer,      // IN |                  SVGA3dTransferType transfer,      // IN | ||||||
|                  uint32 size,                      // IN |                  uint32 size,                      // IN | ||||||
|                  uint32 offset,                    // IN |                  uint32 guest_offset,              // IN | ||||||
|  |                  uint32 host_offset,               // IN | ||||||
|                  SVGA3dSurfaceDMAFlags flags)      // IN |                  SVGA3dSurfaceDMAFlags flags)      // IN | ||||||
| { | { | ||||||
|    SVGA3dCmdSurfaceDMA *cmd; |    SVGA3dCmdSurfaceDMA *cmd; | ||||||
| @@ -517,19 +518,19 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc, | |||||||
|    cmd->transfer = transfer; |    cmd->transfer = transfer; | ||||||
|  |  | ||||||
|    box = (SVGA3dCopyBox *)&cmd[1]; |    box = (SVGA3dCopyBox *)&cmd[1]; | ||||||
|    box->x = offset; |    box->x = host_offset; | ||||||
|    box->y = 0; |    box->y = 0; | ||||||
|    box->z = 0; |    box->z = 0; | ||||||
|    box->w = size; |    box->w = size; | ||||||
|    box->h = 1; |    box->h = 1; | ||||||
|    box->d = 1; |    box->d = 1; | ||||||
|    box->srcx = offset; |    box->srcx = guest_offset; | ||||||
|    box->srcy = 0; |    box->srcy = 0; | ||||||
|    box->srcz = 0; |    box->srcz = 0; | ||||||
|     |     | ||||||
|    pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box); |    pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box); | ||||||
|    pSuffix->suffixSize = sizeof *pSuffix; |    pSuffix->suffixSize = sizeof *pSuffix; | ||||||
|    pSuffix->maximumOffset = offset + size; |    pSuffix->maximumOffset = guest_offset + size; | ||||||
|    pSuffix->flags = flags; |    pSuffix->flags = flags; | ||||||
|  |  | ||||||
|    swc->commit(swc); |    swc->commit(swc); | ||||||
|   | |||||||
| @@ -111,7 +111,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc, | |||||||
|                  struct svga_winsys_surface *host, |                  struct svga_winsys_surface *host, | ||||||
|                  SVGA3dTransferType transfer, |                  SVGA3dTransferType transfer, | ||||||
|                  uint32 size, |                  uint32 size, | ||||||
|                  uint32 offset, |                  uint32 guest_offset, | ||||||
|  |                  uint32 host_offset, | ||||||
|                  SVGA3dSurfaceDMAFlags flags); |                  SVGA3dSurfaceDMAFlags flags); | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
| @@ -215,7 +215,6 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen ) | |||||||
|    svga->state.hw_draw.num_views = 0; |    svga->state.hw_draw.num_views = 0; | ||||||
|  |  | ||||||
|    svga->dirty = ~0; |    svga->dirty = ~0; | ||||||
|    svga->state.white_fs_id = SVGA3D_INVALID_ID; |  | ||||||
|  |  | ||||||
|    LIST_INITHEAD(&svga->dirty_buffers); |    LIST_INITHEAD(&svga->dirty_buffers); | ||||||
|  |  | ||||||
| @@ -285,3 +284,8 @@ void svga_hwtnl_flush_retry( struct svga_context *svga ) | |||||||
|    assert(ret == 0); |    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 multisampleantialias:1; | ||||||
|    unsigned antialiasedlineenable:1; |    unsigned antialiasedlineenable:1; | ||||||
|    unsigned lastpixel:1; |    unsigned lastpixel:1; | ||||||
|  |    unsigned pointspriteenable:1; | ||||||
|  |  | ||||||
|    unsigned linepattern; |    unsigned linepattern; | ||||||
|  |  | ||||||
| @@ -329,10 +330,6 @@ struct svga_context | |||||||
|  |  | ||||||
|       unsigned texture_timestamp; |       unsigned texture_timestamp; | ||||||
|  |  | ||||||
|       /* Internally generated shaders: |  | ||||||
|        */ |  | ||||||
|       unsigned white_fs_id; |  | ||||||
|  |  | ||||||
|       /*  |       /*  | ||||||
|        */ |        */ | ||||||
|       struct svga_sw_state          sw; |       struct svga_sw_state          sw; | ||||||
|   | |||||||
| @@ -253,7 +253,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, | |||||||
|          assert(index_bias >= 0); |          assert(index_bias >= 0); | ||||||
|          assert(min_index <= max_index); |          assert(min_index <= max_index); | ||||||
|          assert(offset + index_bias*stride < size); |          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) { |          switch (hwtnl->cmd.vdecl[i].identity.type) { | ||||||
|          case SVGA3D_DECLTYPE_FLOAT1: |          case SVGA3D_DECLTYPE_FLOAT1: | ||||||
| @@ -314,7 +316,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, | |||||||
|          } |          } | ||||||
|  |  | ||||||
|          assert(!stride || width <= stride); |          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); |       assert(range->indexWidth == range->indexArray.stride); | ||||||
|   | |||||||
| @@ -92,6 +92,7 @@ svga_create_blend_state(struct pipe_context *pipe, | |||||||
|       if (templ->logicop_enable) { |       if (templ->logicop_enable) { | ||||||
|          switch (templ->logicop_func) { |          switch (templ->logicop_func) { | ||||||
|          case PIPE_LOGICOP_XOR: |          case PIPE_LOGICOP_XOR: | ||||||
|  |          case PIPE_LOGICOP_INVERT: | ||||||
|             blend->need_white_fragments = TRUE; |             blend->need_white_fragments = TRUE; | ||||||
|             blend->rt[i].blend_enable = TRUE; |             blend->rt[i].blend_enable = TRUE; | ||||||
|             blend->rt[i].srcblend       = SVGA3D_BLENDOP_ONE; |             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].dstblend       = SVGA3D_BLENDOP_ONE; | ||||||
|             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM; |             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM; | ||||||
|             break; |             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: |          case PIPE_LOGICOP_AND: | ||||||
|             /* Approximate with minimum - works for the 0 & anything case: */ |             /* Approximate with minimum - works for the 0 & anything case: */ | ||||||
|             blend->rt[i].blend_enable = TRUE; |             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->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) { |    if (SVGA_DEBUG & DEBUG_FLUSH) { | ||||||
|       static unsigned id; |       static unsigned id; | ||||||
|       debug_printf("%s %d\n", __FUNCTION__, id++); |       debug_printf("%s %d\n", __FUNCTION__, id++); | ||||||
|       if (id > 1300) |  | ||||||
|          util_time_sleep( 2000 ); |  | ||||||
|  |  | ||||||
|       svga_hwtnl_flush_retry( svga ); |       svga_hwtnl_flush_retry( svga ); | ||||||
|       svga_context_flush(svga, NULL); |       svga_context_flush(svga, NULL); | ||||||
|    } |    } | ||||||
|   | |||||||
| @@ -70,7 +70,6 @@ svga_create_rasterizer_state(struct pipe_context *pipe, | |||||||
|    /* light_twoside          - XXX: need fragment shader varient */ |    /* light_twoside          - XXX: need fragment shader varient */ | ||||||
|    /* poly_smooth            - XXX: no fallback available */ |    /* poly_smooth            - XXX: no fallback available */ | ||||||
|    /* poly_stipple_enable    - draw module */ |    /* poly_stipple_enable    - draw module */ | ||||||
|    /* point_sprite           - ? */ |  | ||||||
|    /* point_size_per_vertex  - ? */ |    /* point_size_per_vertex  - ? */ | ||||||
|    /* sprite_coord_mode      - ??? */ |    /* sprite_coord_mode      - ??? */ | ||||||
|    /* bypass_vs_viewport_and_clip        - handled by viewport setup */ |    /* 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->multisampleantialias = templ->multisample; | ||||||
|    rast->antialiasedlineenable = templ->line_smooth; |    rast->antialiasedlineenable = templ->line_smooth; | ||||||
|    rast->lastpixel = templ->line_last_pixel; |    rast->lastpixel = templ->line_last_pixel; | ||||||
|  |    rast->pointspriteenable = templ->point_sprite; | ||||||
|    rast->pointsize = templ->point_size; |    rast->pointsize = templ->point_size; | ||||||
|    rast->pointsize_min = templ->point_size_min; |    rast->pointsize_min = templ->point_size_min; | ||||||
|    rast->pointsize_max = templ->point_size_max; |    rast->pointsize_max = templ->point_size_max; | ||||||
|   | |||||||
| @@ -27,7 +27,6 @@ | |||||||
| #include "pipe/p_defines.h" | #include "pipe/p_defines.h" | ||||||
| #include "util/u_math.h" | #include "util/u_math.h" | ||||||
| #include "util/u_memory.h" | #include "util/u_memory.h" | ||||||
| #include "util/u_pack_color.h" |  | ||||||
| #include "tgsi/tgsi_parse.h" | #include "tgsi/tgsi_parse.h" | ||||||
|  |  | ||||||
| #include "svga_context.h" | #include "svga_context.h" | ||||||
| @@ -112,14 +111,12 @@ svga_create_sampler_state(struct pipe_context *pipe, | |||||||
|    cso->compare_func = sampler->compare_func; |    cso->compare_func = sampler->compare_func; | ||||||
|  |  | ||||||
|    { |    { | ||||||
|       ubyte r = float_to_ubyte(sampler->border_color[0]); |       uint32 r = float_to_ubyte(sampler->border_color[0]); | ||||||
|       ubyte g = float_to_ubyte(sampler->border_color[1]); |       uint32 g = float_to_ubyte(sampler->border_color[1]); | ||||||
|       ubyte b = float_to_ubyte(sampler->border_color[2]); |       uint32 b = float_to_ubyte(sampler->border_color[2]); | ||||||
|       ubyte a = float_to_ubyte(sampler->border_color[3]); |       uint32 a = float_to_ubyte(sampler->border_color[3]); | ||||||
|  |  | ||||||
|       util_pack_color_ub( r, g, b, a, |       cso->bordercolor = (a << 24) | (r << 16) | (g << 8) | b; | ||||||
|                           PIPE_FORMAT_B8G8R8A8_UNORM, |  | ||||||
|                           &cso->bordercolor ); |  | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    /* No SVGA3D support for: |    /* No SVGA3D support for: | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe, | |||||||
|    /* Adjust refcounts */ |    /* Adjust refcounts */ | ||||||
|    for (i = 0; i < count; i++) { |    for (i = 0; i < count; i++) { | ||||||
|       pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer); |       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; |          any_user_buffer = TRUE; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -104,7 +104,9 @@ svga_get_paramf(struct pipe_screen *screen, int param) | |||||||
|       return 80.0; |       return 80.0; | ||||||
|  |  | ||||||
|    case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: |    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: |    case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: | ||||||
|       return 16.0; |       return 16.0; | ||||||
| @@ -131,12 +133,33 @@ svga_get_paramf(struct pipe_screen *screen, int param) | |||||||
|       return 1; |       return 1; | ||||||
|    case PIPE_CAP_TEXTURE_SHADOW_MAP: |    case PIPE_CAP_TEXTURE_SHADOW_MAP: | ||||||
|       return 1; |       return 1; | ||||||
|  |  | ||||||
|    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: |    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: |    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: |    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 */ |    case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */ | ||||||
|       return 1; |       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 |        * as svga_screen_surface_create might have passed a recycled host | ||||||
|        * buffer. |        * 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); |       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; |    struct svga_winsys_screen *sws = ss->sws; | ||||||
|  |  | ||||||
|    assert(!sbuf->map.count); |    assert(!sbuf->map.count); | ||||||
|    assert(sbuf->hw.buf); |    assert(sbuf->hwbuf); | ||||||
|    if(sbuf->hw.buf) { |    if(sbuf->hwbuf) { | ||||||
|       sws->buffer_destroy(sws, sbuf->hw.buf); |       sws->buffer_destroy(sws, sbuf->hwbuf); | ||||||
|       sbuf->hw.buf = NULL; |       sbuf->hwbuf = NULL; | ||||||
|    } |    } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -151,16 +151,18 @@ static INLINE enum pipe_error | |||||||
| svga_buffer_create_hw_storage(struct svga_screen *ss, | svga_buffer_create_hw_storage(struct svga_screen *ss, | ||||||
|                               struct svga_buffer *sbuf) |                               struct svga_buffer *sbuf) | ||||||
| { | { | ||||||
|    if(!sbuf->hw.buf) { |    assert(!sbuf->user); | ||||||
|  |  | ||||||
|  |    if(!sbuf->hwbuf) { | ||||||
|       unsigned alignment = sbuf->base.alignment; |       unsigned alignment = sbuf->base.alignment; | ||||||
|       unsigned usage = 0; |       unsigned usage = 0; | ||||||
|       unsigned size = sbuf->base.size; |       unsigned size = sbuf->base.size; | ||||||
|        |        | ||||||
|       sbuf->hw.buf = svga_winsys_buffer_create(ss, alignment, usage, size); |       sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size); | ||||||
|       if(!sbuf->hw.buf) |       if(!sbuf->hwbuf) | ||||||
|          return PIPE_ERROR_OUT_OF_MEMORY; |          return PIPE_ERROR_OUT_OF_MEMORY; | ||||||
|        |        | ||||||
|       assert(!sbuf->needs_flush); |       assert(!sbuf->dma.pending); | ||||||
|    } |    } | ||||||
|     |     | ||||||
|    return PIPE_OK; |    return PIPE_OK; | ||||||
| @@ -175,12 +177,11 @@ svga_buffer_upload_command(struct svga_context *svga, | |||||||
|                            struct svga_buffer *sbuf) |                            struct svga_buffer *sbuf) | ||||||
| { | { | ||||||
|    struct svga_winsys_context *swc = svga->swc; |    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; |    struct svga_winsys_surface *host = sbuf->handle; | ||||||
|    SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM; |    SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM; | ||||||
|    SVGA3dSurfaceDMAFlags flags = sbuf->hw.flags; |  | ||||||
|    SVGA3dCmdSurfaceDMA *cmd; |    SVGA3dCmdSurfaceDMA *cmd; | ||||||
|    uint32 numBoxes = sbuf->hw.num_ranges; |    uint32 numBoxes = sbuf->map.num_ranges; | ||||||
|    SVGA3dCopyBox *boxes; |    SVGA3dCopyBox *boxes; | ||||||
|    SVGA3dCmdSurfaceDMASuffix *pSuffix; |    SVGA3dCmdSurfaceDMASuffix *pSuffix; | ||||||
|    unsigned region_flags; |    unsigned region_flags; | ||||||
| @@ -218,8 +219,8 @@ svga_buffer_upload_command(struct svga_context *svga, | |||||||
|  |  | ||||||
|    cmd->transfer = transfer; |    cmd->transfer = transfer; | ||||||
|  |  | ||||||
|    sbuf->hw.boxes = (SVGA3dCopyBox *)&cmd[1]; |    sbuf->dma.boxes = (SVGA3dCopyBox *)&cmd[1]; | ||||||
|    sbuf->hw.svga = svga; |    sbuf->dma.svga = svga; | ||||||
|  |  | ||||||
|    /* Increment reference count */ |    /* Increment reference count */ | ||||||
|    dummy = NULL; |    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 = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes); | ||||||
|    pSuffix->suffixSize = sizeof *pSuffix; |    pSuffix->suffixSize = sizeof *pSuffix; | ||||||
|    pSuffix->maximumOffset = sbuf->base.size; |    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; |    return PIPE_OK; | ||||||
| } | } | ||||||
| @@ -248,10 +251,10 @@ svga_buffer_upload_flush(struct svga_context *svga, | |||||||
|    unsigned i; |    unsigned i; | ||||||
|  |  | ||||||
|    assert(sbuf->handle);  |    assert(sbuf->handle);  | ||||||
|    assert(sbuf->hw.buf); |    assert(sbuf->hwbuf); | ||||||
|    assert(sbuf->hw.num_ranges); |    assert(sbuf->map.num_ranges); | ||||||
|    assert(sbuf->hw.svga == svga); |    assert(sbuf->dma.svga == svga); | ||||||
|    assert(sbuf->hw.boxes); |    assert(sbuf->dma.boxes); | ||||||
|     |     | ||||||
|    /* |    /* | ||||||
|     * Patch the DMA command with the final copy box. |     * 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); |    SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle); | ||||||
|  |  | ||||||
|    boxes = sbuf->hw.boxes; |    boxes = sbuf->dma.boxes; | ||||||
|    for(i = 0; i < sbuf->hw.num_ranges; ++i) { |    for(i = 0; i < sbuf->map.num_ranges; ++i) { | ||||||
|       SVGA_DBG(DEBUG_DMA, "  bytes %u - %u\n", |       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].y = 0; | ||||||
|       boxes[i].z = 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].h = 1; | ||||||
|       boxes[i].d = 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].srcy = 0; | ||||||
|       boxes[i].srcz = 0; |       boxes[i].srcz = 0; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    sbuf->hw.num_ranges = 0; |    sbuf->map.num_ranges = 0; | ||||||
|    memset(&sbuf->hw.flags, 0, sizeof sbuf->hw.flags); |  | ||||||
|  |  | ||||||
|    assert(sbuf->head.prev && sbuf->head.next); |    assert(sbuf->head.prev && sbuf->head.next); | ||||||
|    LIST_DEL(&sbuf->head); |    LIST_DEL(&sbuf->head); | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
|    sbuf->head.next = sbuf->head.prev = NULL;  |    sbuf->head.next = sbuf->head.prev = NULL;  | ||||||
| #endif | #endif | ||||||
|    sbuf->needs_flush = FALSE; |    sbuf->dma.pending = FALSE; | ||||||
|  |  | ||||||
|    sbuf->hw.svga = NULL; |    sbuf->dma.svga = NULL; | ||||||
|    sbuf->hw.boxes = NULL; |    sbuf->dma.boxes = NULL; | ||||||
|  |  | ||||||
|    sbuf->host_written = TRUE; |  | ||||||
|  |  | ||||||
|    /* Decrement reference count */ |    /* Decrement reference count */ | ||||||
|    pipe_buffer_reference((struct pipe_buffer **)&sbuf, NULL); |    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 |  * 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 |  * 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. |  * We try to lump as many contiguous DMA transfers together as possible. | ||||||
|  */ |  */ | ||||||
| static void | static void | ||||||
| svga_buffer_upload_queue(struct svga_buffer *sbuf, | svga_buffer_add_range(struct svga_buffer *sbuf, | ||||||
|                          unsigned start, |                       unsigned start, | ||||||
|                          unsigned end) |                       unsigned end) | ||||||
| { | { | ||||||
|    unsigned i; |    unsigned i; | ||||||
|  |    unsigned nearest_range; | ||||||
|  |    unsigned nearest_dist; | ||||||
|  |  | ||||||
|    assert(sbuf->hw.buf); |  | ||||||
|    assert(end > start); |    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. |     * Try to grow one of the ranges. | ||||||
|     * |     * | ||||||
| @@ -324,12 +333,34 @@ svga_buffer_upload_queue(struct svga_buffer *sbuf, | |||||||
|     * buffer should be flushed. |     * buffer should be flushed. | ||||||
|     */ |     */ | ||||||
|  |  | ||||||
|    for(i = 0; i < sbuf->hw.num_ranges; ++i) { |    for(i = 0; i < sbuf->map.num_ranges; ++i) { | ||||||
|       if(start <= sbuf->hw.ranges[i].end && sbuf->hw.ranges[i].start <= end) { |       int left_dist; | ||||||
|          sbuf->hw.ranges[i].start = MIN2(sbuf->hw.ranges[i].start, start); |       int right_dist; | ||||||
|          sbuf->hw.ranges[i].end   = MAX2(sbuf->hw.ranges[i].end,    end); |       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; |          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. |     * pending DMA upload and start clean. | ||||||
|     */ |     */ | ||||||
|  |  | ||||||
|    if(sbuf->needs_flush) |    if(sbuf->dma.pending) | ||||||
|       svga_buffer_upload_flush(sbuf->hw.svga, sbuf); |       svga_buffer_upload_flush(sbuf->dma.svga, sbuf); | ||||||
|  |  | ||||||
|    assert(!sbuf->needs_flush); |    assert(!sbuf->dma.pending); | ||||||
|    assert(!sbuf->hw.svga); |    assert(!sbuf->dma.svga); | ||||||
|    assert(!sbuf->hw.boxes); |    assert(!sbuf->dma.boxes); | ||||||
|  |  | ||||||
|    /* |    if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) { | ||||||
|     * Add a new range. |       /* | ||||||
|     */ |        * Add a new range. | ||||||
|  |        */ | ||||||
|  |  | ||||||
|    sbuf->hw.ranges[sbuf->hw.num_ranges].start = start; |       sbuf->map.ranges[sbuf->map.num_ranges].start = start; | ||||||
|    sbuf->hw.ranges[sbuf->hw.num_ranges].end = end; |       sbuf->map.ranges[sbuf->map.num_ranges].end = end; | ||||||
|    ++sbuf->hw.num_ranges; |       ++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 ); |    struct svga_buffer *sbuf = svga_buffer( buf ); | ||||||
|    void *map; |    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 */ |       /* User/malloc buffer */ | ||||||
|       map = sbuf->swbuf; |       map = sbuf->swbuf; | ||||||
|    } |    } | ||||||
|  |    else if (sbuf->hwbuf) { | ||||||
|  |       map = sws->buffer_map(sws, sbuf->hwbuf, usage); | ||||||
|  |    } | ||||||
|    else { |    else { | ||||||
|       if(!sbuf->hw.buf) { |       map = NULL; | ||||||
|          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); |  | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    if(map) { |    if(map) { | ||||||
| @@ -446,8 +466,7 @@ svga_buffer_flush_mapped_range( struct pipe_screen *screen, | |||||||
|    assert(sbuf->map.writing); |    assert(sbuf->map.writing); | ||||||
|    if(sbuf->map.writing) { |    if(sbuf->map.writing) { | ||||||
|       assert(sbuf->map.flush_explicit); |       assert(sbuf->map.flush_explicit); | ||||||
|       if(sbuf->hw.buf) |       svga_buffer_add_range(sbuf, offset, offset + length); | ||||||
|          svga_buffer_upload_queue(sbuf, offset, offset + length); |  | ||||||
|    } |    } | ||||||
|    pipe_mutex_unlock(ss->swc_mutex); |    pipe_mutex_unlock(ss->swc_mutex); | ||||||
| } | } | ||||||
| @@ -466,16 +485,15 @@ svga_buffer_unmap( struct pipe_screen *screen, | |||||||
|    if(sbuf->map.count) |    if(sbuf->map.count) | ||||||
|       --sbuf->map.count; |       --sbuf->map.count; | ||||||
|  |  | ||||||
|    if(sbuf->hw.buf) |    if(sbuf->hwbuf) | ||||||
|       sws->buffer_unmap(sws, sbuf->hw.buf); |       sws->buffer_unmap(sws, sbuf->hwbuf); | ||||||
|  |  | ||||||
|    if(sbuf->map.writing) { |    if(sbuf->map.writing) { | ||||||
|       if(!sbuf->map.flush_explicit) { |       if(!sbuf->map.flush_explicit) { | ||||||
|          /* No mapped range was flushed -- flush the whole buffer */ |          /* No mapped range was flushed -- flush the whole buffer */ | ||||||
|          SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n"); |          SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n"); | ||||||
|     |     | ||||||
|          if(sbuf->hw.buf) |          svga_buffer_add_range(sbuf, 0, sbuf->base.size); | ||||||
|             svga_buffer_upload_queue(sbuf, 0, sbuf->base.size); |  | ||||||
|       } |       } | ||||||
|        |        | ||||||
|       sbuf->map.writing = FALSE; |       sbuf->map.writing = FALSE; | ||||||
| @@ -493,12 +511,15 @@ svga_buffer_destroy( struct pipe_buffer *buf ) | |||||||
|  |  | ||||||
|    assert(!p_atomic_read(&buf->reference.count)); |    assert(!p_atomic_read(&buf->reference.count)); | ||||||
|     |     | ||||||
|    assert(!sbuf->needs_flush); |    assert(!sbuf->dma.pending); | ||||||
|  |  | ||||||
|    if(sbuf->handle) |    if(sbuf->handle) | ||||||
|       svga_buffer_destroy_host_surface(ss, sbuf); |       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); |       svga_buffer_destroy_hw_storage(ss, sbuf); | ||||||
|     |     | ||||||
|    if(sbuf->swbuf && !sbuf->user) |    if(sbuf->swbuf && !sbuf->user) | ||||||
| @@ -596,12 +617,13 @@ 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 | static INLINE enum pipe_error | ||||||
| svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf) | 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; |       enum pipe_error ret; | ||||||
|       void *map; |       void *map; | ||||||
|        |        | ||||||
| @@ -610,20 +632,20 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf) | |||||||
|          return PIPE_ERROR; |          return PIPE_ERROR; | ||||||
|        |        | ||||||
|       ret = svga_buffer_create_hw_storage(ss, sbuf); |       ret = svga_buffer_create_hw_storage(ss, sbuf); | ||||||
|       assert(ret == PIPE_OK); |  | ||||||
|       if(ret != PIPE_OK) |       if(ret != PIPE_OK) | ||||||
|          return ret; |          return ret; | ||||||
|  |  | ||||||
|       pipe_mutex_lock(ss->swc_mutex); |       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); |       assert(map); | ||||||
|       if(!map) { |       if(!map) { | ||||||
| 	 pipe_mutex_unlock(ss->swc_mutex); | 	 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); |       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 */ |       /* This user/malloc buffer is now indistinguishable from a gpu buffer */ | ||||||
|       assert(!sbuf->map.count); |       assert(!sbuf->map.count); | ||||||
| @@ -635,10 +657,89 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf) | |||||||
|          sbuf->swbuf = NULL; |          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; |    return PIPE_OK; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -658,34 +759,74 @@ svga_buffer_handle(struct svga_context *svga, | |||||||
|    sbuf = svga_buffer(buf); |    sbuf = svga_buffer(buf); | ||||||
|     |     | ||||||
|    assert(!sbuf->map.count); |    assert(!sbuf->map.count); | ||||||
|  |    assert(!sbuf->user); | ||||||
|     |     | ||||||
|    if(!sbuf->handle) { |    if(!sbuf->handle) { | ||||||
|       ret = svga_buffer_create_host_surface(ss, sbuf); |       ret = svga_buffer_create_host_surface(ss, sbuf); | ||||||
|       if(ret != PIPE_OK) |       if(ret != PIPE_OK) | ||||||
| 	 return NULL; | 	 return NULL; | ||||||
|  |  | ||||||
|       ret = svga_buffer_update_hw(ss, sbuf); |  | ||||||
|       if(ret != PIPE_OK) |  | ||||||
| 	 return NULL; |  | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    if(!sbuf->needs_flush && sbuf->hw.num_ranges) { |    assert(sbuf->handle); | ||||||
|       /* 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->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); |           * Migrate the data from swbuf -> hwbuf if necessary. | ||||||
|       LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers); |           */ | ||||||
|  |          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; |    return sbuf->handle; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| struct pipe_buffer * | struct pipe_buffer * | ||||||
| svga_screen_buffer_wrap_surface(struct pipe_screen *screen, | svga_screen_buffer_wrap_surface(struct pipe_screen *screen, | ||||||
| 				enum SVGA3dSurfaceFormat format, | 				enum SVGA3dSurfaceFormat format, | ||||||
| @@ -738,7 +879,7 @@ svga_context_flush_buffers(struct svga_context *svga) | |||||||
|       sbuf = LIST_ENTRY(struct svga_buffer, curr, head); |       sbuf = LIST_ENTRY(struct svga_buffer, curr, head); | ||||||
|  |  | ||||||
|       assert(p_atomic_read(&sbuf->base.reference.count) != 0); |       assert(p_atomic_read(&sbuf->base.reference.count) != 0); | ||||||
|       assert(sbuf->needs_flush); |       assert(sbuf->dma.pending); | ||||||
|        |        | ||||||
|       svga_buffer_upload_flush(svga, sbuf); |       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. |  * SVGA pipe buffer. | ||||||
|  */ |  */ | ||||||
| @@ -110,14 +81,6 @@ struct svga_buffer | |||||||
|     */ |     */ | ||||||
|    boolean user; |    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. |     * Creation key for the host surface handle. | ||||||
|     *  |     *  | ||||||
| @@ -136,17 +99,92 @@ struct svga_buffer | |||||||
|    struct svga_winsys_surface *handle; |    struct svga_winsys_surface *handle; | ||||||
|  |  | ||||||
|    /** |    /** | ||||||
|     * Whether the host has been ever written. |     * Information about ongoing and past map operations. | ||||||
|     */ |     */ | ||||||
|    boolean host_written; |  | ||||||
|  |  | ||||||
|    struct { |    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; |       unsigned count; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Whether this buffer is currently mapped for writing. | ||||||
|  |        */ | ||||||
|       boolean writing; |       boolean writing; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Whether the application will tell us explicity which ranges it touched | ||||||
|  |        * or not. | ||||||
|  |        */ | ||||||
|       boolean flush_explicit; |       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; |    } 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; |    struct list_head head; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -176,6 +214,16 @@ svga_buffer_is_user_buffer( struct pipe_buffer *buffer ) | |||||||
| void | void | ||||||
| svga_screen_init_buffer_functions(struct pipe_screen *screen); | 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 * | struct svga_winsys_surface * | ||||||
| svga_buffer_handle(struct svga_context *svga, | svga_buffer_handle(struct svga_context *svga, | ||||||
|                    struct pipe_buffer *buf); |                    struct pipe_buffer *buf); | ||||||
|   | |||||||
| @@ -203,7 +203,7 @@ svga_transfer_dma(struct svga_transfer *st, | |||||||
|       if(transfer == SVGA3D_READ_HOST_VRAM) { |       if(transfer == SVGA3D_READ_HOST_VRAM) { | ||||||
|          svga_screen_flush(screen, &fence); |          svga_screen_flush(screen, &fence); | ||||||
|          sws->fence_finish(sws, fence, 0); |          sws->fence_finish(sws, fence, 0); | ||||||
|          //sws->fence_reference(sws, &fence, NULL); |          sws->fence_reference(sws, &fence, NULL); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|    else { |    else { | ||||||
| @@ -232,7 +232,7 @@ svga_transfer_dma(struct svga_transfer *st, | |||||||
|             if(y) { |             if(y) { | ||||||
|                svga_screen_flush(screen, &fence); |                svga_screen_flush(screen, &fence); | ||||||
|                sws->fence_finish(sws, fence, 0); |                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); |             hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE); | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ struct svga_winsys_surface; | |||||||
| enum SVGA3dSurfaceFormat; | enum SVGA3dSurfaceFormat; | ||||||
|  |  | ||||||
|  |  | ||||||
| #define SVGA_MAX_TEXTURE_LEVELS 12 /* 2048x2048 */ | #define SVGA_MAX_TEXTURE_LEVELS 16 | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -103,70 +103,6 @@ fail: | |||||||
|    return ret; |    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_TEXTURE_BINDING | ||||||
|  * SVGA_NEW_RAST |  * SVGA_NEW_RAST | ||||||
| @@ -194,6 +130,23 @@ static int make_fs_key( const struct svga_context *svga, | |||||||
|                        PIPE_WINDING_CW); |                        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 |    /* XXX: want to limit this to the textures that the shader actually | ||||||
|     * refers to. |     * refers to. | ||||||
| @@ -233,40 +186,29 @@ static int emit_hw_fs( struct svga_context *svga, | |||||||
|    unsigned id = SVGA3D_INVALID_ID; |    unsigned id = SVGA3D_INVALID_ID; | ||||||
|    int ret = 0; |    int ret = 0; | ||||||
|  |  | ||||||
|    /* SVGA_NEW_BLEND |    struct svga_fragment_shader *fs = svga->curr.fs; | ||||||
|     */ |    struct svga_fs_compile_key key; | ||||||
|    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; |  | ||||||
|  |  | ||||||
|       /* SVGA_NEW_TEXTURE_BINDING |    /* SVGA_NEW_BLEND | ||||||
|        * SVGA_NEW_RAST |     * SVGA_NEW_TEXTURE_BINDING | ||||||
|        * SVGA_NEW_NEED_SWTNL |     * SVGA_NEW_RAST | ||||||
|        * SVGA_NEW_SAMPLER |     * SVGA_NEW_NEED_SWTNL | ||||||
|        */ |     * SVGA_NEW_SAMPLER | ||||||
|       ret = make_fs_key( svga, &key ); |     */ | ||||||
|  |    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) |       if (ret) | ||||||
|          return 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); |    assert(id != SVGA3D_INVALID_ID); | ||||||
|  |  | ||||||
|    if (result != svga->state.hw_draw.fs) { |    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)) { |    if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) { | ||||||
|       const struct svga_depth_stencil_state *curr = svga->curr.depth;  |       const struct svga_depth_stencil_state *curr = svga->curr.depth;  | ||||||
|       const struct svga_rasterizer_state *rast = svga->curr.rast;  |       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;  |       const struct svga_rasterizer_state *curr = svga->curr.rast;  | ||||||
|  |       unsigned cullmode = curr->cullmode; | ||||||
|  |  | ||||||
|       /* Shademode: still need to rearrange index list to move |       /* Shademode: still need to rearrange index list to move | ||||||
|        * flat-shading PV first vertex. |        * flat-shading PV first vertex. | ||||||
|        */ |        */ | ||||||
|       EMIT_RS( svga, curr->shademode, SHADEMODE, fail ); |       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->scissortestenable, SCISSORTESTENABLE, fail ); | ||||||
|       EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail ); |       EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail ); | ||||||
|       EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail ); |       EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail ); | ||||||
|  |       EMIT_RS( svga, curr->pointspriteenable, POINTSPRITEENABLE, fail ); | ||||||
|       EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail ); |       EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail ); | ||||||
|       EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail ); |       EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail ); | ||||||
|       EMIT_RS_FLOAT( svga, curr->pointsize_min, POINTSIZEMIN, fail ); |       EMIT_RS_FLOAT( svga, curr->pointsize_min, POINTSIZEMIN, fail ); | ||||||
| @@ -234,9 +257,6 @@ static int emit_rss( struct svga_context *svga, | |||||||
|       SVGA_FIFOCommitAll( svga->swc ); |       SVGA_FIFOCommitAll( svga->swc ); | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    /* Also blend color: |  | ||||||
|     */ |  | ||||||
|  |  | ||||||
|    return 0; |    return 0; | ||||||
|  |  | ||||||
| fail: | fail: | ||||||
| @@ -256,6 +276,7 @@ struct svga_tracked_state svga_hw_rss = | |||||||
|    "hw rss state", |    "hw rss state", | ||||||
|  |  | ||||||
|    (SVGA_NEW_BLEND | |    (SVGA_NEW_BLEND | | ||||||
|  |     SVGA_NEW_BLEND_COLOR | | ||||||
|     SVGA_NEW_DEPTH_STENCIL | |     SVGA_NEW_DEPTH_STENCIL | | ||||||
|     SVGA_NEW_RAST | |     SVGA_NEW_RAST | | ||||||
|     SVGA_NEW_FRAME_BUFFER | |     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)) |       if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer)) | ||||||
|       { |       { | ||||||
|          struct pipe_buffer *upload_buffer = NULL; |          struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer); | ||||||
|          unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0; |  | ||||||
|          unsigned size = svga->curr.vb[i].buffer->size /*- offset*/; |  | ||||||
|          unsigned upload_offset; |  | ||||||
|  |  | ||||||
|          ret = u_upload_buffer( svga->upload_vb, |          if (!buffer->uploaded.buffer) { | ||||||
|                                 offset, |             ret = u_upload_buffer( svga->upload_vb, | ||||||
|                                 size, |                                    0, | ||||||
|                                 svga->curr.vb[i].buffer, |                                    buffer->base.size, | ||||||
|                                 &upload_offset, |                                    &buffer->base, | ||||||
|                                 &upload_buffer ); |                                    &buffer->uploaded.offset, | ||||||
|          if (ret) |                                    &buffer->uploaded.buffer ); | ||||||
|             return ret; |             if (ret) | ||||||
|  |                return ret; | ||||||
|  |  | ||||||
|          if (0) |             if (0) | ||||||
|             debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",  |                debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", | ||||||
|                          __FUNCTION__,  |                             __FUNCTION__, | ||||||
|                          i, |                             i, | ||||||
|                          svga->curr.vb[i].buffer, |                             buffer, | ||||||
|                          upload_buffer, upload_offset, size); |                             buffer->uploaded.buffer, | ||||||
|  |                             buffer->uploaded.offset, | ||||||
|  |                             buffer->base.size); | ||||||
|  |          } | ||||||
|  |  | ||||||
|          /* Make sure we release the old buffer and end up with the |          pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer ); | ||||||
|           * correct refcount on the uploaded buffer. |          svga->curr.vb[i].buffer_offset = buffer->uploaded.offset; | ||||||
|           */ |  | ||||||
|          pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL ); |  | ||||||
|          svga->curr.vb[i].buffer = upload_buffer; |  | ||||||
|          svga->curr.vb[i].buffer_offset = upload_offset; |  | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ struct svga_fs_compile_key | |||||||
| { | { | ||||||
|    boolean light_twoside:1; |    boolean light_twoside:1; | ||||||
|    boolean front_cw:1; |    boolean front_cw:1; | ||||||
|  |    boolean white_fragments:1; | ||||||
|    ubyte num_textures; |    ubyte num_textures; | ||||||
|    ubyte num_unnormalized_coords; |    ubyte num_unnormalized_coords; | ||||||
|    struct { |    struct { | ||||||
|   | |||||||
| @@ -194,8 +194,19 @@ static boolean ps30_output( struct svga_shader_emitter *emit, | |||||||
|  |  | ||||||
|    switch (semantic.SemanticName) { |    switch (semantic.SemanticName) { | ||||||
|    case TGSI_SEMANTIC_COLOR: |    case TGSI_SEMANTIC_COLOR: | ||||||
|       emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,  |       if (emit->unit == PIPE_SHADER_FRAGMENT && | ||||||
|                                             semantic.SemanticIndex ); |           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; |       break; | ||||||
|    case TGSI_SEMANTIC_POSITION: |    case TGSI_SEMANTIC_POSITION: | ||||||
|       emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, |       emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, | ||||||
|   | |||||||
| @@ -79,6 +79,8 @@ struct svga_shader_emitter | |||||||
|  |  | ||||||
|    int ps30_input_count; |    int ps30_input_count; | ||||||
|  |  | ||||||
|  |    int dynamic_branching_level; | ||||||
|  |  | ||||||
|    boolean in_main_func; |    boolean in_main_func; | ||||||
|  |  | ||||||
|    boolean created_zero_immediate; |    boolean created_zero_immediate; | ||||||
| @@ -136,6 +138,7 @@ static INLINE boolean emit_dst( struct svga_shader_emitter *emit, | |||||||
|                          SVGA3dShaderDestToken dest ) |                          SVGA3dShaderDestToken dest ) | ||||||
| { | { | ||||||
|    assert(dest.reserved0); |    assert(dest.reserved0); | ||||||
|  |    assert(dest.mask); | ||||||
|    return svga_shader_emit_dword( emit, dest.value ); |    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 TRANSLATE_SWIZZLE(x,y,z,w)  ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6)) | ||||||
| #define SWIZZLE_XYZW  \ | #define SWIZZLE_XYZW  \ | ||||||
|  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W) |  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W) | ||||||
| @@ -248,6 +268,7 @@ static INLINE SVGA3dShaderDestToken | |||||||
| writemask( SVGA3dShaderDestToken dest, | writemask( SVGA3dShaderDestToken dest, | ||||||
|            unsigned mask ) |            unsigned mask ) | ||||||
| { | { | ||||||
|  |    assert(dest.mask & mask); | ||||||
|    dest.mask &= mask; |    dest.mask &= mask; | ||||||
|    return dest; |    return dest; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -46,8 +46,6 @@ translate_opcode( | |||||||
|    case TGSI_OPCODE_ABS:        return SVGA3DOP_ABS; |    case TGSI_OPCODE_ABS:        return SVGA3DOP_ABS; | ||||||
|    case TGSI_OPCODE_ADD:        return SVGA3DOP_ADD; |    case TGSI_OPCODE_ADD:        return SVGA3DOP_ADD; | ||||||
|    case TGSI_OPCODE_BREAKC:     return SVGA3DOP_BREAKC; |    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_DP2A:       return SVGA3DOP_DP2ADD; | ||||||
|    case TGSI_OPCODE_DP3:        return SVGA3DOP_DP3; |    case TGSI_OPCODE_DP3:        return SVGA3DOP_DP3; | ||||||
|    case TGSI_OPCODE_DP4:        return SVGA3DOP_DP4; |    case TGSI_OPCODE_DP4:        return SVGA3DOP_DP4; | ||||||
| @@ -114,6 +112,7 @@ translate_dst_register( struct svga_shader_emitter *emit, | |||||||
|    } |    } | ||||||
|  |  | ||||||
|    dest.mask = reg->DstRegister.WriteMask; |    dest.mask = reg->DstRegister.WriteMask; | ||||||
|  |    assert(dest.mask); | ||||||
|  |  | ||||||
|    if (insn->Instruction.Saturate)  |    if (insn->Instruction.Saturate)  | ||||||
|       dest.dstMod = SVGA3DDSTMOD_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, | static boolean emit_def_const( struct svga_shader_emitter *emit, | ||||||
|                                SVGA3dShaderConstType type, |                                SVGA3dShaderConstType type, | ||||||
|                                unsigned idx, |                                unsigned idx, | ||||||
| @@ -660,6 +741,8 @@ static boolean emit_if(struct svga_shader_emitter *emit, | |||||||
|    if_token.control = SVGA3DOPCOMPC_NE; |    if_token.control = SVGA3DOPCOMPC_NE; | ||||||
|    zero = scalar(zero, TGSI_SWIZZLE_X); |    zero = scalar(zero, TGSI_SWIZZLE_X); | ||||||
|  |  | ||||||
|  |    emit->dynamic_branching_level++; | ||||||
|  |  | ||||||
|    return (emit_instruction( emit, if_token ) && |    return (emit_instruction( emit, if_token ) && | ||||||
|            emit_src( emit, src ) && |            emit_src( emit, src ) && | ||||||
|            emit_src( emit, zero ) ); |            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, | static boolean emit_endif(struct svga_shader_emitter *emit, | ||||||
|                        const struct tgsi_full_instruction *insn) |                        const struct tgsi_full_instruction *insn) | ||||||
| { | { | ||||||
|  |    emit->dynamic_branching_level--; | ||||||
|  |  | ||||||
|    return (emit_instruction( emit, |    return (emit_instruction( emit, | ||||||
|                              inst_token( SVGA3DOP_ENDIF ))); |                              inst_token( SVGA3DOP_ENDIF ))); | ||||||
| } | } | ||||||
| @@ -1011,10 +1096,10 @@ static boolean emit_kilp(struct svga_shader_emitter *emit, | |||||||
| { | { | ||||||
|    SVGA3dShaderInstToken inst; |    SVGA3dShaderInstToken inst; | ||||||
|    SVGA3dShaderDestToken temp; |    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 ); |    inst = inst_token( SVGA3DOP_TEXKILL ); | ||||||
|    one = scalar( one, TGSI_SWIZZLE_W ); |  | ||||||
|  |  | ||||||
|    /* texkill doesn't allow negation on the operand so lets move |    /* texkill doesn't allow negation on the operand so lets move | ||||||
|     * negation of {1} to a temp register */ |     * negation of {1} to a temp register */ | ||||||
| @@ -1169,41 +1254,79 @@ static boolean emit_tex2(struct svga_shader_emitter *emit, | |||||||
|                          SVGA3dShaderDestToken dst ) |                          SVGA3dShaderDestToken dst ) | ||||||
| { | { | ||||||
|    SVGA3dShaderInstToken inst; |    SVGA3dShaderInstToken inst; | ||||||
|    struct src_register src0; |    struct src_register texcoord; | ||||||
|    struct src_register src1; |    struct src_register sampler; | ||||||
|  |    SVGA3dShaderDestToken tmp; | ||||||
|     |     | ||||||
|    inst.value = 0; |    inst.value = 0; | ||||||
|    inst.op = SVGA3DOP_TEX; |  | ||||||
|  |  | ||||||
|    switch (insn->Instruction.Opcode) { |    switch (insn->Instruction.Opcode) { | ||||||
|    case TGSI_OPCODE_TEX: |    case TGSI_OPCODE_TEX: | ||||||
|  |       inst.op = SVGA3DOP_TEX; | ||||||
|       break; |       break; | ||||||
|    case TGSI_OPCODE_TXP: |    case TGSI_OPCODE_TXP: | ||||||
|  |       inst.op = SVGA3DOP_TEX; | ||||||
|       inst.control = SVGA3DOPCONT_PROJECT; |       inst.control = SVGA3DOPCONT_PROJECT; | ||||||
|       break; |       break; | ||||||
|    case TGSI_OPCODE_TXB: |    case TGSI_OPCODE_TXB: | ||||||
|  |       inst.op = SVGA3DOP_TEX; | ||||||
|       inst.control = SVGA3DOPCONT_BIAS; |       inst.control = SVGA3DOPCONT_BIAS; | ||||||
|       break; |       break; | ||||||
|  |    case TGSI_OPCODE_TXL: | ||||||
|  |       inst.op = SVGA3DOP_TEXLDL; | ||||||
|  |       break; | ||||||
|    default: |    default: | ||||||
|       assert(0); |       assert(0); | ||||||
|       return FALSE; |       return FALSE; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] ); |    texcoord = translate_src_register( emit, &insn->FullSrcRegisters[0] ); | ||||||
|    src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] ); |    sampler = translate_src_register( emit, &insn->FullSrcRegisters[1] ); | ||||||
|  |  | ||||||
|    if (emit->key.fkey.tex[src1.base.num].unnormalized) { |    if (emit->key.fkey.tex[sampler.base.num].unnormalized || | ||||||
|       struct src_register wh = get_tex_dimensions( emit, src1.base.num ); |        emit->dynamic_branching_level > 0) | ||||||
|       SVGA3dShaderDestToken tmp = get_temp( emit ); |       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 */ |       /* MUL  tmp, SRC0, WH */ | ||||||
|       if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), |       if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), | ||||||
|                        tmp, src0, wh )) |                        tmp, texcoord, wh )) | ||||||
|          return FALSE; |          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. | /* 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, |                          const struct tgsi_full_instruction *insn, | ||||||
|                          SVGA3dShaderDestToken dst ) |                          SVGA3dShaderDestToken dst ) | ||||||
| { | { | ||||||
|    SVGA3dShaderInstToken inst; |    SVGA3dShaderInstToken inst; | ||||||
|    struct src_register src0; |    struct src_register texcoord; | ||||||
|    struct src_register src1; |    struct src_register ddx; | ||||||
|    struct src_register src2; |    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; |    inst.value = 0; | ||||||
|  |  | ||||||
|    switch (insn->Instruction.Opcode) { |    switch (insn->Instruction.Opcode) { | ||||||
|    case TGSI_OPCODE_TXD:  |    case TGSI_OPCODE_TXD:  | ||||||
|       inst.op = SVGA3DOP_TEXLDD; |       inst.op = SVGA3DOP_TEXLDD; /* 4 args! */ | ||||||
|       break; |  | ||||||
|    case TGSI_OPCODE_TXL: |  | ||||||
|       inst.op = SVGA3DOP_TEXLDL; |  | ||||||
|       break; |       break; | ||||||
|  |    default: | ||||||
|  |       assert(0); | ||||||
|  |       return FALSE; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] ); |    return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy ); | ||||||
|    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 ); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1271,12 +1396,12 @@ static boolean emit_tex(struct svga_shader_emitter *emit, | |||||||
|    case TGSI_OPCODE_TEX: |    case TGSI_OPCODE_TEX: | ||||||
|    case TGSI_OPCODE_TXB: |    case TGSI_OPCODE_TXB: | ||||||
|    case TGSI_OPCODE_TXP: |    case TGSI_OPCODE_TXP: | ||||||
|  |    case TGSI_OPCODE_TXL: | ||||||
|       if (!emit_tex2( emit, insn, tex_result )) |       if (!emit_tex2( emit, insn, tex_result )) | ||||||
|          return FALSE; |          return FALSE; | ||||||
|       break; |       break; | ||||||
|    case TGSI_OPCODE_TXL: |  | ||||||
|    case TGSI_OPCODE_TXD: |    case TGSI_OPCODE_TXD: | ||||||
|       if (!emit_tex3( emit, insn, tex_result )) |       if (!emit_tex4( emit, insn, tex_result )) | ||||||
|          return FALSE; |          return FALSE; | ||||||
|       break; |       break; | ||||||
|    default: |    default: | ||||||
| @@ -1285,34 +1410,42 @@ static boolean emit_tex(struct svga_shader_emitter *emit, | |||||||
|  |  | ||||||
|  |  | ||||||
|    if (compare) { |    if (compare) { | ||||||
|       SVGA3dShaderDestToken src0_zdivw = get_temp( emit ); |       if (dst.mask & TGSI_WRITEMASK_XYZ) { | ||||||
|       struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y); |          SVGA3dShaderDestToken src0_zdivw = get_temp( emit ); | ||||||
|       struct src_register one = |          struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y); | ||||||
|          scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W ); |  | ||||||
|  |  | ||||||
|       /* Divide texcoord R by Q */ |          /* Divide texcoord R by Q */ | ||||||
|       if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ), |          if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ), | ||||||
|                        src0_zdivw, |                           writemask(src0_zdivw, TGSI_WRITEMASK_X), | ||||||
|                        scalar(src0, TGSI_SWIZZLE_W) )) |                           scalar(src0, TGSI_SWIZZLE_W) )) | ||||||
|          return FALSE; |             return FALSE; | ||||||
|  |  | ||||||
|       if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), |          if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), | ||||||
|                        src0_zdivw, |                           writemask(src0_zdivw, TGSI_WRITEMASK_X), | ||||||
|                        scalar(src0, TGSI_SWIZZLE_Z), |                           scalar(src0, TGSI_SWIZZLE_Z), | ||||||
|                        src(src0_zdivw) )) |                           scalar(src(src0_zdivw), TGSI_SWIZZLE_X) )) | ||||||
|          return FALSE; |             return FALSE; | ||||||
|  |  | ||||||
|       if (!emit_select( |          if (!emit_select( | ||||||
|              emit, |                 emit, | ||||||
|              emit->key.fkey.tex[src1.base.num].compare_func, |                 emit->key.fkey.tex[src1.base.num].compare_func, | ||||||
|              dst, |                 writemask( dst, TGSI_WRITEMASK_XYZ ), | ||||||
|              src(src0_zdivw), |                 scalar(src(src0_zdivw), TGSI_SWIZZLE_X), | ||||||
|              tex_src_x)) |                 tex_src_x)) | ||||||
|          return FALSE; |             return FALSE; | ||||||
|  |       } | ||||||
|  |  | ||||||
|       return submit_op1( emit, inst_token( SVGA3DOP_MOV ), |       if (dst.mask & TGSI_WRITEMASK_W) { | ||||||
|                          writemask( dst, TGSI_WRITEMASK_W), |          struct src_register one = | ||||||
|                          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)  |    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 loop_reg = src_register( SVGA3DREG_LOOP, 0 ); | ||||||
|    struct src_register const_int = get_loop_const( emit ); |    struct src_register const_int = get_loop_const( emit ); | ||||||
|  |  | ||||||
|  |    emit->dynamic_branching_level++; | ||||||
|  |  | ||||||
|    return (emit_instruction( emit, inst ) && |    return (emit_instruction( emit, inst ) && | ||||||
|            emit_src( emit, loop_reg ) && |            emit_src( emit, loop_reg ) && | ||||||
|            emit_src( emit, const_int ) ); |            emit_src( emit, const_int ) ); | ||||||
| @@ -1339,6 +1474,9 @@ static boolean emit_endloop2( struct svga_shader_emitter *emit, | |||||||
|                               const struct tgsi_full_instruction *insn ) |                               const struct tgsi_full_instruction *insn ) | ||||||
| { | { | ||||||
|    SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP ); |    SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP ); | ||||||
|  |  | ||||||
|  |    emit->dynamic_branching_level--; | ||||||
|  |  | ||||||
|    return emit_instruction( emit, inst ); |    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, | static boolean emit_arl(struct svga_shader_emitter *emit, | ||||||
|                         const struct tgsi_full_instruction *insn) |                         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 (dst.mask & TGSI_WRITEMASK_X) { | ||||||
|       if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), |       if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), | ||||||
|                        writemask( dst, dst.mask & TGSI_WRITEMASK_X ), |                        writemask( dst, TGSI_WRITEMASK_X ), | ||||||
|                        src0, |                        src0, | ||||||
|                        scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) ) |                        scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) ) | ||||||
|          return FALSE; |          return FALSE; | ||||||
|  |  | ||||||
|       if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ), |       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 ) ) ) |                        scalar( src( dst ), TGSI_SWIZZLE_X ) ) ) | ||||||
|          return FALSE; |          return FALSE; | ||||||
|  |  | ||||||
| @@ -1673,7 +1851,7 @@ static boolean emit_exp(struct svga_shader_emitter *emit, | |||||||
|     */ |     */ | ||||||
|    if (dst.mask & TGSI_WRITEMASK_Z) { |    if (dst.mask & TGSI_WRITEMASK_Z) { | ||||||
|       if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ), |       if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ), | ||||||
|                        writemask( dst, dst.mask & TGSI_WRITEMASK_Z ), |                        writemask( dst, TGSI_WRITEMASK_Z ), | ||||||
|                        src0 ) ) |                        src0 ) ) | ||||||
|          return FALSE; |          return FALSE; | ||||||
|    } |    } | ||||||
| @@ -2002,6 +2180,10 @@ static boolean svga_emit_instruction( struct svga_shader_emitter *emit, | |||||||
|    case TGSI_OPCODE_TXD: |    case TGSI_OPCODE_TXD: | ||||||
|       return emit_tex( emit, insn ); |       return emit_tex( emit, insn ); | ||||||
|  |  | ||||||
|  |    case TGSI_OPCODE_DDX: | ||||||
|  |    case TGSI_OPCODE_DDY: | ||||||
|  |       return emit_deriv( emit, insn ); | ||||||
|  |  | ||||||
|    case TGSI_OPCODE_BGNSUB: |    case TGSI_OPCODE_BGNSUB: | ||||||
|       return emit_bgnsub( emit, position, insn ); |       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++) { |    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { | ||||||
|       if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) { |       if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) { | ||||||
|  |  | ||||||
|          if (!submit_op1( emit, |          /* Potentially override output colors with white for XOR | ||||||
|                           inst_token(SVGA3DOP_MOV), |           * logicop workaround. | ||||||
|                           emit->true_col[i], |           */ | ||||||
|                           src(emit->temp_col[i]) )) |          if (emit->unit == PIPE_SHADER_FRAGMENT && | ||||||
|             return FALSE; |              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) |       if (emit->key.fkey.light_twoside) | ||||||
|          return TRUE; |          return TRUE; | ||||||
|  |  | ||||||
|  |       if (emit->key.fkey.white_fragments) | ||||||
|  |          return TRUE; | ||||||
|  |  | ||||||
|       if (emit->emit_frontface) |       if (emit->emit_frontface) | ||||||
|          return TRUE; |          return TRUE; | ||||||
|  |  | ||||||
| @@ -2476,6 +2678,10 @@ needs_to_create_zero( struct svga_shader_emitter *emit ) | |||||||
|    } |    } | ||||||
|  |  | ||||||
|    if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 || |    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_SGE] >= 1 || | ||||||
|        emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 || |        emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 || | ||||||
|        emit->info.opcode_count[TGSI_OPCODE_SLE] >= 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; |          goto done; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|  |    assert(emit->dynamic_branching_level == 0); | ||||||
|  |  | ||||||
|    /* Need to terminate the whole shader: |    /* Need to terminate the whole shader: | ||||||
|     */ |     */ | ||||||
|    ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) ); |    ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) ); | ||||||
|   | |||||||
| @@ -281,6 +281,9 @@ svga_screen_create(struct svga_winsys_screen *sws); | |||||||
| struct svga_winsys_screen * | struct svga_winsys_screen * | ||||||
| svga_winsys_screen(struct pipe_screen *screen); | svga_winsys_screen(struct pipe_screen *screen); | ||||||
|  |  | ||||||
|  | struct svga_winsys_context * | ||||||
|  | svga_winsys_context(struct pipe_context *context); | ||||||
|  |  | ||||||
| struct pipe_buffer * | struct pipe_buffer * | ||||||
| svga_screen_buffer_wrap_surface(struct pipe_screen *screen, | svga_screen_buffer_wrap_surface(struct pipe_screen *screen, | ||||||
| 				enum SVGA3dSurfaceFormat format, | 				enum SVGA3dSurfaceFormat format, | ||||||
|   | |||||||
| @@ -132,14 +132,22 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv) | |||||||
|    boolean have_depth = FALSE; |    boolean have_depth = FALSE; | ||||||
|    int i, count; |    int i, count; | ||||||
|  |  | ||||||
|    buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable, |    if ((dri_screen->dri2.loader | ||||||
| 						     &dri_drawable->w, |         && (dri_screen->dri2.loader->base.version > 2) | ||||||
| 						     &dri_drawable->h, |         && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) | ||||||
| 						     drawable->attachments, |       buffers = (*dri_screen->dri2.loader->getBuffersWithFormat) | ||||||
| 						     drawable-> |                 (dri_drawable, &dri_drawable->w, &dri_drawable->h, | ||||||
| 						     num_attachments, &count, |                  drawable->attachments, drawable->num_attachments, | ||||||
| 						     dri_drawable-> |                  &count, dri_drawable->loaderPrivate); | ||||||
| 						     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) { |    if (buffers == NULL) { | ||||||
|       return; |       return; | ||||||
| @@ -346,12 +354,12 @@ dri_create_buffer(__DRIscreenPrivate * sPriv, | |||||||
|    case 24: |    case 24: | ||||||
|       if (visual->stencilBits == 0) { |       if (visual->stencilBits == 0) { | ||||||
| 	 drawable->depth_stencil_format = (screen->d_depth_bits_last) ? | 	 drawable->depth_stencil_format = (screen->d_depth_bits_last) ? | ||||||
| 	    PIPE_FORMAT_X8Z24_UNORM: |                                           PIPE_FORMAT_X8Z24_UNORM: | ||||||
| 	    PIPE_FORMAT_Z24X8_UNORM; |                                           PIPE_FORMAT_Z24X8_UNORM; | ||||||
|       } else { |       } else { | ||||||
| 	 drawable->depth_stencil_format = (screen->sd_depth_bits_last) ? | 	 drawable->depth_stencil_format = (screen->sd_depth_bits_last) ? | ||||||
| 	    PIPE_FORMAT_S8Z24_UNORM: |                                           PIPE_FORMAT_S8Z24_UNORM: | ||||||
| 	    PIPE_FORMAT_Z24S8_UNORM; |                                           PIPE_FORMAT_Z24S8_UNORM; | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|    case 32: |    case 32: | ||||||
| @@ -375,23 +383,49 @@ dri_create_buffer(__DRIscreenPrivate * sPriv, | |||||||
|    /* setup dri2 buffers information */ |    /* setup dri2 buffers information */ | ||||||
|    /* TODO incase of double buffer visual, delay fake creation */ |    /* TODO incase of double buffer visual, delay fake creation */ | ||||||
|    i = 0; |    i = 0; | ||||||
|    drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; |    if (sPriv->dri2.loader | ||||||
|    if (!screen->auto_fake_front) |        && (sPriv->dri2.loader->base.version > 2) | ||||||
|       drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; |        && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) { | ||||||
|    if (visual->doubleBufferMode) |       drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; | ||||||
|       drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; |       drawable->attachments[i++] = visual->rgbBits; | ||||||
|    if (visual->depthBits && visual->stencilBits) |       if (!screen->auto_fake_front)  { | ||||||
|       drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; |          drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; | ||||||
|    else if (visual->depthBits) |          drawable->attachments[i++] = visual->rgbBits; | ||||||
|       drawable->attachments[i++] = __DRI_BUFFER_DEPTH; |       } | ||||||
|    else if (visual->stencilBits) |       if (visual->doubleBufferMode) { | ||||||
|       drawable->attachments[i++] = __DRI_BUFFER_STENCIL; |          drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; | ||||||
|    drawable->num_attachments = i; |          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; |    drawable->desired_fences = 2; | ||||||
|  |  | ||||||
|    return GL_TRUE; |    return GL_TRUE; | ||||||
|  fail: | fail: | ||||||
|    FREE(drawable); |    FREE(drawable); | ||||||
|    return GL_FALSE; |    return GL_FALSE; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -80,6 +80,9 @@ dri_fill_in_modes(struct dri_screen *screen, | |||||||
| 		  unsigned pixel_bits) | 		  unsigned pixel_bits) | ||||||
| { | { | ||||||
|    __DRIconfig **configs = NULL; |    __DRIconfig **configs = NULL; | ||||||
|  |    __DRIconfig **configs_r5g6b5 = NULL; | ||||||
|  |    __DRIconfig **configs_a8r8g8b8 = NULL; | ||||||
|  |    __DRIconfig **configs_x8r8g8b8 = NULL; | ||||||
|    unsigned num_modes; |    unsigned num_modes; | ||||||
|    uint8_t depth_bits_array[5]; |    uint8_t depth_bits_array[5]; | ||||||
|    uint8_t stencil_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; |    stencil_bits_array[0] = 0; | ||||||
|    depth_buffer_factor = 1; |    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, |    pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, | ||||||
| 					    PIPE_TEXTURE_2D, | 					    PIPE_TEXTURE_2D, | ||||||
| 					    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | 					    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, |    pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM, | ||||||
| 					    PIPE_TEXTURE_2D, | 					    PIPE_TEXTURE_2D, | ||||||
| 					    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | 					    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, |    pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM, | ||||||
| 					       PIPE_TEXTURE_2D, | 					       PIPE_TEXTURE_2D, | ||||||
| 					       PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); | 					       PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); | ||||||
|    pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8R8G8B8_UNORM, |    pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8R8G8B8_UNORM, | ||||||
| 					       PIPE_TEXTURE_2D, | 					       PIPE_TEXTURE_2D, | ||||||
| 					       PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); | 					       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) { |    if (pf_z16) { | ||||||
|       depth_bits_array[depth_buffer_factor] = 16; |       depth_bits_array[depth_buffer_factor] = 16; | ||||||
| @@ -153,41 +165,43 @@ dri_fill_in_modes(struct dri_screen *screen, | |||||||
|    num_modes = |    num_modes = | ||||||
|       depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4; |       depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4; | ||||||
|  |  | ||||||
|    if (pixel_bits == 16 && pf_r5g6b5) { |    if (pf_r5g6b5) | ||||||
|       configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, |       configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, | ||||||
| 				 depth_bits_array, stencil_bits_array, |                                         depth_bits_array, stencil_bits_array, | ||||||
| 				 depth_buffer_factor, back_buffer_modes, |                                         depth_buffer_factor, back_buffer_modes, | ||||||
| 				 back_buffer_factor, |                                         back_buffer_factor, | ||||||
| 				 msaa_samples_array, 1); |                                         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 { |    } else { | ||||||
|       __DRIconfig **configs_a8r8g8b8 = NULL; |       configs = configs_a8r8g8b8; | ||||||
|       __DRIconfig **configs_x8r8g8b8 = NULL; |       if (configs_x8r8g8b8) | ||||||
|  | 	 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8; | ||||||
|       if (pf_a8r8g8b8) |       if (configs_r5g6b5) | ||||||
| 	 configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, |          configs = configs ? driConcatConfigs(configs, configs_r5g6b5) : configs_r5g6b5; | ||||||
| 					     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; |  | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    if (configs == NULL) { |    if (configs == NULL) { | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ if 'python' in env['statetrackers']: | |||||||
|             'gdi32', |             'gdi32', | ||||||
|             'user32', |             'user32', | ||||||
|             'kernel32', |             'kernel32', | ||||||
|  |             'ws2_32', | ||||||
|         ]) |         ]) | ||||||
|     else: |     else: | ||||||
|         env.Append(LIBS = [ |         env.Append(LIBS = [ | ||||||
|   | |||||||
| @@ -531,6 +531,8 @@ class Context(Object): | |||||||
|                     gallium.PIPE_FORMAT_R32G32B32_FLOAT: '3f', |                     gallium.PIPE_FORMAT_R32G32B32_FLOAT: '3f', | ||||||
|                     gallium.PIPE_FORMAT_R32G32B32A32_FLOAT: '4f', |                     gallium.PIPE_FORMAT_R32G32B32A32_FLOAT: '4f', | ||||||
|                     gallium.PIPE_FORMAT_B8G8R8A8_UNORM: '4B', |                     gallium.PIPE_FORMAT_B8G8R8A8_UNORM: '4B', | ||||||
|  |                     gallium.PIPE_FORMAT_R8G8B8A8_UNORM: '4B', | ||||||
|  |                     gallium.PIPE_FORMAT_R16G16B16_SNORM: '3h', | ||||||
|                 }[velem.src_format] |                 }[velem.src_format] | ||||||
|  |  | ||||||
|                 data = vbuf.buffer.read() |                 data = vbuf.buffer.read() | ||||||
| @@ -557,7 +559,7 @@ class Context(Object): | |||||||
|  |  | ||||||
|         sys.stdout.write('\t{\n') |         sys.stdout.write('\t{\n') | ||||||
|         for i in range(start, start + count): |         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') |                 sys.stdout.write('\t...\n') | ||||||
|                 break |                 break | ||||||
|             offset = i*isize |             offset = i*isize | ||||||
|   | |||||||
| @@ -362,7 +362,7 @@ EXPORTS | |||||||
| 	wglShareLists | 	wglShareLists | ||||||
| 	wglSwapBuffers | 	wglSwapBuffers | ||||||
| 	wglSwapLayerBuffers | 	wglSwapLayerBuffers | ||||||
| ;	wglSwapMultipleBuffers | 	wglSwapMultipleBuffers | ||||||
| 	wglUseFontBitmapsA | 	wglUseFontBitmapsA | ||||||
| 	wglUseFontBitmapsW | 	wglUseFontBitmapsW | ||||||
| 	wglUseFontOutlinesA | 	wglUseFontOutlinesA | ||||||
|   | |||||||
| @@ -362,7 +362,7 @@ EXPORTS | |||||||
| 	wglShareLists = wglShareLists@8 | 	wglShareLists = wglShareLists@8 | ||||||
| 	wglSwapBuffers = wglSwapBuffers@4 | 	wglSwapBuffers = wglSwapBuffers@4 | ||||||
| 	wglSwapLayerBuffers = wglSwapLayerBuffers@8 | 	wglSwapLayerBuffers = wglSwapLayerBuffers@8 | ||||||
| ;	wglSwapMultipleBuffers = wglSwapMultipleBuffers@8 | 	wglSwapMultipleBuffers = wglSwapMultipleBuffers@8 | ||||||
| 	wglUseFontBitmapsA = wglUseFontBitmapsA@16 | 	wglUseFontBitmapsA = wglUseFontBitmapsA@16 | ||||||
| 	wglUseFontBitmapsW = wglUseFontBitmapsW@16 | 	wglUseFontBitmapsW = wglUseFontBitmapsW@16 | ||||||
| 	wglUseFontOutlinesA = wglUseFontOutlinesA@32 | 	wglUseFontOutlinesA = wglUseFontOutlinesA@32 | ||||||
|   | |||||||
| @@ -80,6 +80,9 @@ DrvCopyContext( | |||||||
|    struct stw_context *dst; |    struct stw_context *dst; | ||||||
|    BOOL ret = FALSE; |    BOOL ret = FALSE; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return FALSE; | ||||||
|  |  | ||||||
|    pipe_mutex_lock( stw_dev->ctx_mutex ); |    pipe_mutex_lock( stw_dev->ctx_mutex ); | ||||||
|     |     | ||||||
|    src = stw_lookup_context_locked( dhrcSource ); |    src = stw_lookup_context_locked( dhrcSource ); | ||||||
| @@ -107,13 +110,15 @@ DrvShareLists( | |||||||
|    struct stw_context *ctx2; |    struct stw_context *ctx2; | ||||||
|    BOOL ret = FALSE; |    BOOL ret = FALSE; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return FALSE; | ||||||
|  |  | ||||||
|    pipe_mutex_lock( stw_dev->ctx_mutex ); |    pipe_mutex_lock( stw_dev->ctx_mutex ); | ||||||
|     |     | ||||||
|    ctx1 = stw_lookup_context_locked( dhglrc1 ); |    ctx1 = stw_lookup_context_locked( dhglrc1 ); | ||||||
|    ctx2 = stw_lookup_context_locked( dhglrc2 ); |    ctx2 = stw_lookup_context_locked( dhglrc2 ); | ||||||
|  |  | ||||||
|    if (ctx1 && ctx2 && |    if (ctx1 && ctx2) { | ||||||
|        ctx1->iPixelFormat == ctx2->iPixelFormat) {  |  | ||||||
|       ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx); |       ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx); | ||||||
|    } |    } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -152,24 +152,27 @@ stw_cleanup_thread(void) | |||||||
| void | void | ||||||
| stw_cleanup(void) | stw_cleanup(void) | ||||||
| { | { | ||||||
|    unsigned i; |    DHGLRC dhglrc; | ||||||
|  |  | ||||||
|    debug_printf("%s\n", __FUNCTION__); |    debug_printf("%s\n", __FUNCTION__); | ||||||
|  |  | ||||||
|    if (!stw_dev) |    if (!stw_dev) | ||||||
|       return; |       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 ); |    pipe_mutex_lock( stw_dev->ctx_mutex ); | ||||||
|    { |    dhglrc = handle_table_get_first_handle(stw_dev->ctx_table); | ||||||
|       /* 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); |  | ||||||
|    } |  | ||||||
|    pipe_mutex_unlock( stw_dev->ctx_mutex ); |    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(); |    stw_framebuffer_cleanup(); | ||||||
|     |     | ||||||
|   | |||||||
| @@ -178,7 +178,7 @@ stw_call_window_proc( | |||||||
|    if(!tls_data) |    if(!tls_data) | ||||||
|       return 0; |       return 0; | ||||||
|     |     | ||||||
|    if (nCode < 0) |    if (nCode < 0 || !stw_dev) | ||||||
|        return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam); |        return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam); | ||||||
|  |  | ||||||
|    if (pParams->message == WM_WINDOWPOSCHANGED) { |    if (pParams->message == WM_WINDOWPOSCHANGED) { | ||||||
| @@ -333,6 +333,9 @@ stw_framebuffer_cleanup( void ) | |||||||
|    struct stw_framebuffer *fb; |    struct stw_framebuffer *fb; | ||||||
|    struct stw_framebuffer *next; |    struct stw_framebuffer *next; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return; | ||||||
|  |  | ||||||
|    pipe_mutex_lock( stw_dev->fb_mutex ); |    pipe_mutex_lock( stw_dev->fb_mutex ); | ||||||
|  |  | ||||||
|    fb = stw_dev->fb_head; |    fb = stw_dev->fb_head; | ||||||
| @@ -388,6 +391,9 @@ stw_framebuffer_from_hdc( | |||||||
| { | { | ||||||
|    struct stw_framebuffer *fb; |    struct stw_framebuffer *fb; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return NULL; | ||||||
|  |  | ||||||
|    pipe_mutex_lock( stw_dev->fb_mutex ); |    pipe_mutex_lock( stw_dev->fb_mutex ); | ||||||
|    fb = stw_framebuffer_from_hdc_locked(hdc); |    fb = stw_framebuffer_from_hdc_locked(hdc); | ||||||
|    pipe_mutex_unlock( stw_dev->fb_mutex ); |    pipe_mutex_unlock( stw_dev->fb_mutex ); | ||||||
| @@ -422,6 +428,9 @@ DrvSetPixelFormat( | |||||||
|    uint index; |    uint index; | ||||||
|    struct stw_framebuffer *fb; |    struct stw_framebuffer *fb; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return FALSE; | ||||||
|  |  | ||||||
|    index = (uint) iPixelFormat - 1; |    index = (uint) iPixelFormat - 1; | ||||||
|    count = stw_pixelformat_get_extended_count(); |    count = stw_pixelformat_get_extended_count(); | ||||||
|    if (index >= count) |    if (index >= count) | ||||||
| @@ -476,6 +485,9 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data) | |||||||
|    struct pipe_screen *screen; |    struct pipe_screen *screen; | ||||||
|    struct pipe_surface *surface; |    struct pipe_surface *surface; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return FALSE; | ||||||
|  |  | ||||||
|    fb = stw_framebuffer_from_hdc( hdc ); |    fb = stw_framebuffer_from_hdc( hdc ); | ||||||
|    if (fb == NULL) |    if (fb == NULL) | ||||||
|       return FALSE; |       return FALSE; | ||||||
| @@ -577,6 +589,9 @@ DrvSwapBuffers( | |||||||
|    struct stw_framebuffer *fb; |    struct stw_framebuffer *fb; | ||||||
|    struct pipe_surface *surface = NULL; |    struct pipe_surface *surface = NULL; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return FALSE; | ||||||
|  |  | ||||||
|    fb = stw_framebuffer_from_hdc( hdc ); |    fb = stw_framebuffer_from_hdc( hdc ); | ||||||
|    if (fb == NULL) |    if (fb == NULL) | ||||||
|       return FALSE; |       return FALSE; | ||||||
|   | |||||||
| @@ -34,6 +34,8 @@ | |||||||
|  |  | ||||||
| #include "glapi/glapi.h" | #include "glapi/glapi.h" | ||||||
| #include "stw_ext_gallium.h" | #include "stw_ext_gallium.h" | ||||||
|  | #include "stw_device.h" | ||||||
|  | #include "stw_icd.h" | ||||||
|  |  | ||||||
| struct stw_extension_entry | struct stw_extension_entry | ||||||
| { | { | ||||||
| @@ -73,6 +75,9 @@ DrvGetProcAddress( | |||||||
| { | { | ||||||
|    const struct stw_extension_entry *entry; |    const struct stw_extension_entry *entry; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return NULL; | ||||||
|  |  | ||||||
|    if (lpszProc[0] == 'w' && lpszProc[1] == 'g' && lpszProc[2] == 'l') |    if (lpszProc[0] == 'w' && lpszProc[1] == 'g' && lpszProc[2] == 'l') | ||||||
|       for (entry = stw_extension_entries; entry->name; entry++) |       for (entry = stw_extension_entries; entry->name; entry++) | ||||||
|          if (strcmp( lpszProc, entry->name ) == 0) |          if (strcmp( lpszProc, entry->name ) == 0) | ||||||
|   | |||||||
| @@ -303,6 +303,9 @@ DrvDescribePixelFormat( | |||||||
|  |  | ||||||
|    (void) hdc; |    (void) hdc; | ||||||
|  |  | ||||||
|  |    if (!stw_dev) | ||||||
|  |       return 0; | ||||||
|  |  | ||||||
|    count = stw_pixelformat_get_extended_count(); |    count = stw_pixelformat_get_extended_count(); | ||||||
|    index = (uint) iPixelFormat - 1; |    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 | WINGDIAPI BOOL APIENTRY | ||||||
| wglSwapLayerBuffers( | wglSwapLayerBuffers( | ||||||
|    HDC hdc, |    HDC hdc, | ||||||
|   | |||||||
| @@ -59,5 +59,21 @@ wglSetPixelFormat(HDC hdc, | |||||||
|                   int iPixelFormat, |                   int iPixelFormat, | ||||||
|                   CONST PIXELFORMATDESCRIPTOR *ppfd); |                   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_ */ | #endif /* STW_WGL_H_ */ | ||||||
|   | |||||||
| @@ -39,6 +39,7 @@ | |||||||
| #include <xf86.h> | #include <xf86.h> | ||||||
| #include <xf86i2c.h> | #include <xf86i2c.h> | ||||||
| #include <xf86Crtc.h> | #include <xf86Crtc.h> | ||||||
|  | #include <cursorstr.h> | ||||||
| #include "xorg_tracker.h" | #include "xorg_tracker.h" | ||||||
| #include "xf86Modes.h" | #include "xf86Modes.h" | ||||||
|  |  | ||||||
| @@ -146,6 +147,7 @@ crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, | |||||||
|     /* XXX: hockup */ |     /* XXX: hockup */ | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if 0 /* Implement and enable to enable rotation and reflection. */ | ||||||
| static void * | static void * | ||||||
| crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) | 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; */ |     /* ScrnInfoPtr pScrn = crtc->scrn; */ | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Cursor functions |  * Cursor functions | ||||||
|  */ |  */ | ||||||
| @@ -243,7 +247,11 @@ crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image) | |||||||
| 	unsigned attr[8]; | 	unsigned attr[8]; | ||||||
|  |  | ||||||
| 	attr[0] = KMS_BO_TYPE; | 	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; | 	attr[1] = KMS_BO_TYPE_CURSOR; | ||||||
|  | #endif | ||||||
| 	attr[2] = KMS_WIDTH; | 	attr[2] = KMS_WIDTH; | ||||||
| 	attr[3] = 64; | 	attr[3] = 64; | ||||||
| 	attr[4] = KMS_HEIGHT; | 	attr[4] = KMS_HEIGHT; | ||||||
| @@ -272,7 +280,21 @@ err_bo_destroy: | |||||||
| static void | static void | ||||||
| crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) | crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) | ||||||
| { | { | ||||||
|  |     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); | ||||||
|     modesettingPtr ms = modesettingPTR(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) |     if (ms->screen) | ||||||
| 	crtc_load_cursor_argb_ga3d(crtc, image); | 	crtc_load_cursor_argb_ga3d(crtc, image); | ||||||
| #ifdef HAVE_LIBKMS | #ifdef HAVE_LIBKMS | ||||||
| @@ -344,9 +366,9 @@ static const xf86CrtcFuncsRec crtc_funcs = { | |||||||
|     .hide_cursor = crtc_hide_cursor, |     .hide_cursor = crtc_hide_cursor, | ||||||
|     .load_cursor_argb = crtc_load_cursor_argb, |     .load_cursor_argb = crtc_load_cursor_argb, | ||||||
|  |  | ||||||
|     .shadow_create = crtc_shadow_create, |     .shadow_create = NULL, | ||||||
|     .shadow_allocate = crtc_shadow_allocate, |     .shadow_allocate = NULL, | ||||||
|     .shadow_destroy = crtc_shadow_destroy, |     .shadow_destroy = NULL, | ||||||
|  |  | ||||||
|     .gamma_set = crtc_gamma_set, |     .gamma_set = crtc_gamma_set, | ||||||
|     .destroy = crtc_destroy, |     .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); | 	    pipe_texture_reference(&tex, exa_priv->depth_stencil_tex); | ||||||
|         else { |         else { | ||||||
| 	    struct pipe_texture template; | 	    struct pipe_texture template; | ||||||
|  |             unsigned depthBits = (format != 0) ? format : pDraw->depth; | ||||||
| 	    memset(&template, 0, sizeof(template)); | 	    memset(&template, 0, sizeof(template)); | ||||||
| 	    template.target = PIPE_TEXTURE_2D; | 	    template.target = PIPE_TEXTURE_2D; | ||||||
| 	    if (buffer->attachment == DRI2BufferDepth) | 	    if (buffer->attachment == DRI2BufferDepth) { | ||||||
| 		template.format = ms->ds_depth_bits_last ? |                switch(depthBits) { | ||||||
| 		    PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM; |                case 16: | ||||||
| 	    else |                   template.format = PIPE_FORMAT_Z16_UNORM; | ||||||
| 		template.format = ms->ds_depth_bits_last ? |                   break; | ||||||
| 		    PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM; |                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); | 	    pf_get_block(template.format, &template.block); | ||||||
| 	    template.width[0] = pDraw->width; | 	    template.width[0] = pDraw->width; | ||||||
| 	    template.height[0] = pDraw->height; | 	    template.height[0] = pDraw->height; | ||||||
| @@ -283,6 +295,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, | |||||||
|     GCPtr gc; |     GCPtr gc; | ||||||
|     RegionPtr copy_clip; |     RegionPtr copy_clip; | ||||||
|     Bool save_accel; |     Bool save_accel; | ||||||
|  |     CustomizerPtr cust = ms->cust; | ||||||
|  |  | ||||||
|     /* |     /* | ||||||
|      * In driCreateBuffers we dewrap windows into the |      * In driCreateBuffers we dewrap windows into the | ||||||
| @@ -336,7 +349,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, | |||||||
|     ValidateGC(dst_draw, gc); |     ValidateGC(dst_draw, gc); | ||||||
|  |  | ||||||
|     /* If this is a full buffer swap, throttle on the previous one */ |     /* 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); | 	BoxPtr extents = REGION_EXTENTS(pScreen, pRegion); | ||||||
|  |  | ||||||
| 	if (extents->x1 == 0 && extents->y1 == 0 && | 	if (extents->x1 == 0 && extents->y1 == 0 && | ||||||
| @@ -358,6 +372,9 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, | |||||||
|     DamageRegionAppend(src_draw, pRegion); |     DamageRegionAppend(src_draw, pRegion); | ||||||
|     DamageRegionProcessPending(src_draw); |     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, |     (*gc->ops->CopyArea)(src_draw, dst_draw, gc, | ||||||
| 			 0, 0, pDraw->width, pDraw->height, 0, 0); | 			 0, 0, pDraw->width, pDraw->height, 0, 0); | ||||||
|     ms->exa->accel = save_accel; |     ms->exa->accel = save_accel; | ||||||
| @@ -365,8 +382,13 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, | |||||||
|     FreeScratchGC(gc); |     FreeScratchGC(gc); | ||||||
|  |  | ||||||
|     ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, |     ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, | ||||||
| 		   pDestBuffer->attachment == DRI2BufferFrontLeft ? | 		   (pDestBuffer->attachment == DRI2BufferFrontLeft | ||||||
|  | 		    && ms->swapThrottling) ? | ||||||
| 		   &dst_priv->fence : NULL); | 		   &dst_priv->fence : NULL); | ||||||
|  |  | ||||||
|  |    if (cust && cust->winsys_context_throttle) | ||||||
|  |        cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER); | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| Bool | Bool | ||||||
|   | |||||||
| @@ -79,12 +79,16 @@ typedef enum | |||||||
|     OPTION_SW_CURSOR, |     OPTION_SW_CURSOR, | ||||||
|     OPTION_2D_ACCEL, |     OPTION_2D_ACCEL, | ||||||
|     OPTION_DEBUG_FALLBACK, |     OPTION_DEBUG_FALLBACK, | ||||||
|  |     OPTION_THROTTLE_SWAP, | ||||||
|  |     OPTION_THROTTLE_DIRTY | ||||||
| } drv_option_enums; | } drv_option_enums; | ||||||
|  |  | ||||||
| static const OptionInfoRec drv_options[] = { | static const OptionInfoRec drv_options[] = { | ||||||
|     {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, |     {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, | ||||||
|     {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE}, |     {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE}, | ||||||
|     {OPTION_DEBUG_FALLBACK, "DebugFallback", 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} |     {-1, NULL, OPTV_NONE, {0}, FALSE} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -155,7 +159,7 @@ drv_get_rec(ScrnInfoPtr pScrn) | |||||||
|     if (pScrn->driverPrivate) |     if (pScrn->driverPrivate) | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
|  |  | ||||||
|     pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); |     pScrn->driverPrivate = xnfcalloc(1, sizeof(modesettingRec)); | ||||||
|  |  | ||||||
|     return TRUE; |     return TRUE; | ||||||
| } | } | ||||||
| @@ -183,31 +187,66 @@ drv_probe_ddc(ScrnInfoPtr pScrn, int index) | |||||||
| static Bool | static Bool | ||||||
| drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height) | drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height) | ||||||
| { | { | ||||||
|  |     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     modesettingPtr ms = modesettingPTR(pScrn); | ||||||
|     PixmapPtr rootPixmap; |  | ||||||
|     ScreenPtr pScreen = pScrn->pScreen; |     ScreenPtr pScreen = pScrn->pScreen; | ||||||
|  |     int old_width, old_height; | ||||||
|  |     PixmapPtr rootPixmap; | ||||||
|  |     int i; | ||||||
|  |  | ||||||
|     if (width == pScrn->virtualX && height == pScrn->virtualY) |     if (width == pScrn->virtualX && height == pScrn->virtualY) | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
|  |  | ||||||
|  |     old_width = pScrn->virtualX; | ||||||
|  |     old_height = pScrn->virtualY; | ||||||
|     pScrn->virtualX = width; |     pScrn->virtualX = width; | ||||||
|     pScrn->virtualY = height; |     pScrn->virtualY = height; | ||||||
|  |  | ||||||
|     /* |     /* ms->create_front_buffer will remove the old front buffer */ | ||||||
|      * Remove the old framebuffer & texture. |  | ||||||
|      */ |  | ||||||
|     drmModeRmFB(ms->fd, ms->fb_id); |  | ||||||
|     if (!ms->destroy_front_buffer(pScrn)) |  | ||||||
| 	FatalError("failed to destroy front buffer\n"); |  | ||||||
|  |  | ||||||
|     rootPixmap = pScreen->GetScreenPixmap(pScreen); |     rootPixmap = pScreen->GetScreenPixmap(pScreen); | ||||||
|     if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL)) |     if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL)) | ||||||
| 	return FALSE; | 	goto error_modify; | ||||||
|  |  | ||||||
|     pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8); |     pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8); | ||||||
|  |  | ||||||
|     /* now create new frontbuffer */ |     if (!ms->create_front_buffer(pScrn) || !ms->bind_front_buffer(pScrn)) | ||||||
|     return 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 = { | static const xf86CrtcConfigFuncsRec crtc_config_funcs = { | ||||||
| @@ -333,6 +372,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) | |||||||
|     EntityInfoPtr pEnt; |     EntityInfoPtr pEnt; | ||||||
|     EntPtr msEnt = NULL; |     EntPtr msEnt = NULL; | ||||||
|     int max_width, max_height; |     int max_width, max_height; | ||||||
|  |     CustomizerPtr cust; | ||||||
|  |  | ||||||
|     if (pScrn->numEntities != 1) |     if (pScrn->numEntities != 1) | ||||||
| 	return FALSE; | 	return FALSE; | ||||||
| @@ -344,6 +384,9 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) | |||||||
| 	return TRUE; | 	return TRUE; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     cust = (CustomizerPtr) pScrn->driverPrivate; | ||||||
|  |     pScrn->driverPrivate = NULL; | ||||||
|  |  | ||||||
|     /* Allocate driverPrivate */ |     /* Allocate driverPrivate */ | ||||||
|     if (!drv_get_rec(pScrn)) |     if (!drv_get_rec(pScrn)) | ||||||
| 	return FALSE; | 	return FALSE; | ||||||
| @@ -351,6 +394,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) | |||||||
|     ms = modesettingPTR(pScrn); |     ms = modesettingPTR(pScrn); | ||||||
|     ms->SaveGeneration = -1; |     ms->SaveGeneration = -1; | ||||||
|     ms->pEnt = pEnt; |     ms->pEnt = pEnt; | ||||||
|  |     ms->cust = cust; | ||||||
|  |  | ||||||
|     pScrn->displayWidth = 640;	       /* default it */ |     pScrn->displayWidth = 640;	       /* default it */ | ||||||
|  |  | ||||||
| @@ -423,8 +467,8 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) | |||||||
|     xf86CrtcConfigInit(pScrn, &crtc_config_funcs); |     xf86CrtcConfigInit(pScrn, &crtc_config_funcs); | ||||||
|     xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); |     xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); | ||||||
|  |  | ||||||
|     max_width = 8192; |     max_width = 2048;  /* A very low default */ | ||||||
|     max_height = 8192; |     max_height = 2048; /* see screen_init */ | ||||||
|     xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); |     xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); | ||||||
|  |  | ||||||
|     if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { |     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) { |     if (ms->ctx) { | ||||||
|        int j; |        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]) |        if (ms->dirtyThrottling) { | ||||||
|           ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0); | 	   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 | 	   /* The amount of rendering generated by a block handler can be | ||||||
|         * quite small.  Let us get a fair way ahead of hardware before | 	    * quite small.  Let us get a fair way ahead of hardware before | ||||||
|         * throttling. | 	    * throttling. | ||||||
|         */ | 	    */ | ||||||
|        for (j = 0; j < XORG_NR_FENCES - 1; j++) | 	   for (j = 0; j < XORG_NR_FENCES - 1; j++) | ||||||
|           ms->screen->fence_reference(ms->screen, | 	       ms->screen->fence_reference(ms->screen, | ||||||
|                                       &ms->fence[j], | 					   &ms->fence[j], | ||||||
|                                       ms->fence[j+1]); | 					   ms->fence[j+1]); | ||||||
|  |  | ||||||
|        ms->screen->fence_reference(ms->screen, | 	   ms->screen->fence_reference(ms->screen, | ||||||
|                                    &ms->fence[XORG_NR_FENCES-1], | 				       &ms->fence[XORG_NR_FENCES-1], | ||||||
|                                    NULL); | 				       NULL); | ||||||
|  |        } | ||||||
|     } |     } | ||||||
|          |          | ||||||
|  |  | ||||||
| @@ -607,7 +657,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) | |||||||
| { | { | ||||||
|     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; |     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     modesettingPtr ms = modesettingPTR(pScrn); | ||||||
|  |     unsigned max_width, max_height; | ||||||
|     VisualPtr visual; |     VisualPtr visual; | ||||||
|  |     CustomizerPtr cust = ms->cust; | ||||||
|  |     MessageType from_st; | ||||||
|  |     MessageType from_dt; | ||||||
|  |  | ||||||
|     if (!drv_init_drm(pScrn)) { |     if (!drv_init_drm(pScrn)) { | ||||||
| 	FatalError("Could not init DRM"); | 	FatalError("Could not init DRM"); | ||||||
| @@ -624,6 +678,26 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) | |||||||
| 	return FALSE; | 	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; |     pScrn->pScreen = pScreen; | ||||||
|  |  | ||||||
|     /* HW dependent - FIXME */ |     /* HW dependent - FIXME */ | ||||||
| @@ -673,7 +747,20 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) | |||||||
|     xf86SetBlackWhitePixels(pScreen); |     xf86SetBlackWhitePixels(pScreen); | ||||||
|  |  | ||||||
|     ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE); |     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) { |     if (ms->screen) { | ||||||
| 	ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d); | 	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 | #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", |     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n", | ||||||
| 	       ms->screen && ms->accelerate_2d ? "enabled" : "disabled"); | 	       ms->screen && ms->accelerate_2d ? "enabled" : "disabled"); | ||||||
|     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n", |     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 | #else | ||||||
|     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n"); |     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n"); | ||||||
| #endif | #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); |     miInitializeBackingStore(pScreen); | ||||||
|     xf86SetBackingStore(pScreen); |     xf86SetBackingStore(pScreen); | ||||||
| @@ -725,9 +823,6 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) | |||||||
|     if (serverGeneration == 1) |     if (serverGeneration == 1) | ||||||
| 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); | 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); | ||||||
|  |  | ||||||
|     if (ms->winsys_screen_init) |  | ||||||
| 	ms->winsys_screen_init(pScrn); |  | ||||||
|  |  | ||||||
|     return drv_enter_vt(scrnIndex, 1); |     return drv_enter_vt(scrnIndex, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -759,10 +854,11 @@ drv_leave_vt(int scrnIndex, int flags) | |||||||
|     ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; |     ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     modesettingPtr ms = modesettingPTR(pScrn); | ||||||
|     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); |     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); | ||||||
|  |     CustomizerPtr cust = ms->cust; | ||||||
|     int o; |     int o; | ||||||
|  |  | ||||||
|     if (ms->winsys_leave_vt) |     if (cust && cust->winsys_leave_vt) | ||||||
| 	ms->winsys_leave_vt(pScrn); | 	cust->winsys_leave_vt(cust); | ||||||
|  |  | ||||||
|     for (o = 0; o < config->num_crtc; o++) { |     for (o = 0; o < config->num_crtc; o++) { | ||||||
| 	xf86CrtcPtr crtc = config->crtc[o]; | 	xf86CrtcPtr crtc = config->crtc[o]; | ||||||
| @@ -778,6 +874,7 @@ drv_leave_vt(int scrnIndex, int flags) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     drmModeRmFB(ms->fd, ms->fb_id); |     drmModeRmFB(ms->fd, ms->fb_id); | ||||||
|  |     ms->fb_id = -1; | ||||||
|  |  | ||||||
|     drv_restore_hw_state(pScrn); |     drv_restore_hw_state(pScrn); | ||||||
|  |  | ||||||
| @@ -796,6 +893,7 @@ drv_enter_vt(int scrnIndex, int flags) | |||||||
| { | { | ||||||
|     ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; |     ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     modesettingPtr ms = modesettingPTR(pScrn); | ||||||
|  |     CustomizerPtr cust = ms->cust; | ||||||
|  |  | ||||||
|     if (drmSetMaster(ms->fd)) { |     if (drmSetMaster(ms->fd)) { | ||||||
| 	if (errno == EINVAL) { | 	if (errno == EINVAL) { | ||||||
| @@ -826,8 +924,8 @@ drv_enter_vt(int scrnIndex, int flags) | |||||||
|     if (!xf86SetDesiredModes(pScrn)) |     if (!xf86SetDesiredModes(pScrn)) | ||||||
| 	return FALSE; | 	return FALSE; | ||||||
|  |  | ||||||
|     if (ms->winsys_enter_vt) |     if (cust && cust->winsys_enter_vt) | ||||||
| 	ms->winsys_enter_vt(pScrn); | 	cust->winsys_enter_vt(cust); | ||||||
|  |  | ||||||
|     return TRUE; |     return TRUE; | ||||||
| } | } | ||||||
| @@ -845,13 +943,19 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen) | |||||||
| { | { | ||||||
|     ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; |     ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     modesettingPtr ms = modesettingPTR(pScrn); | ||||||
|  |     CustomizerPtr cust = ms->cust; | ||||||
|  |  | ||||||
|     if (pScrn->vtSema) { |     if (pScrn->vtSema) { | ||||||
| 	drv_leave_vt(scrnIndex, 0); | 	drv_leave_vt(scrnIndex, 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (ms->winsys_screen_close) |     if (ms->cursor) { | ||||||
| 	ms->winsys_screen_close(pScrn); |        FreeCursor(ms->cursor, None); | ||||||
|  |        ms->cursor = NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (cust && cust->winsys_screen_close) | ||||||
|  | 	cust->winsys_screen_close(cust); | ||||||
|  |  | ||||||
| #ifdef DRI2 | #ifdef DRI2 | ||||||
|     if (ms->screen) |     if (ms->screen) | ||||||
| @@ -900,6 +1004,15 @@ static Bool | |||||||
| drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn) | drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn) | ||||||
| { | { | ||||||
|     modesettingPtr ms = modesettingPTR(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); |     pipe_texture_reference(&ms->root_texture, NULL); | ||||||
|     return TRUE; |     return TRUE; | ||||||
| } | } | ||||||
| @@ -908,7 +1021,7 @@ static Bool | |||||||
| drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn) | drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn) | ||||||
| { | { | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     modesettingPtr ms = modesettingPTR(pScrn); | ||||||
|     unsigned handle, stride; |     unsigned handle, stride, fb_id; | ||||||
|     struct pipe_texture *tex; |     struct pipe_texture *tex; | ||||||
|     int ret; |     int ret; | ||||||
|  |  | ||||||
| @@ -933,19 +1046,23 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn) | |||||||
| 		       pScrn->bitsPerPixel, | 		       pScrn->bitsPerPixel, | ||||||
| 		       stride, | 		       stride, | ||||||
| 		       handle, | 		       handle, | ||||||
| 		       &ms->fb_id); | 		       &fb_id); | ||||||
|     if (ret) { |     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)); | 		     __func__, ret, strerror(-ret)); | ||||||
| 	goto err_destroy; | 	goto err_destroy; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (!drv_destroy_front_buffer_ga3d(pScrn)) | ||||||
|  | 	FatalError("%s: failed to take down old framebuffer\n", __func__); | ||||||
|  |  | ||||||
|     pScrn->frameX0 = 0; |     pScrn->frameX0 = 0; | ||||||
|     pScrn->frameY0 = 0; |     pScrn->frameY0 = 0; | ||||||
|     drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); |     drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); | ||||||
|  |  | ||||||
|     pipe_texture_reference(&ms->root_texture, tex); |     pipe_texture_reference(&ms->root_texture, tex); | ||||||
|     pipe_texture_reference(&tex, NULL); |     pipe_texture_reference(&tex, NULL); | ||||||
|  |     ms->fb_id = fb_id; | ||||||
|  |  | ||||||
|     return TRUE; |     return TRUE; | ||||||
|  |  | ||||||
| @@ -993,6 +1110,11 @@ drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn) | |||||||
|     if (!ms->root_bo) |     if (!ms->root_bo) | ||||||
| 	return TRUE; | 	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_unmap(ms->root_bo); | ||||||
|     kms_bo_destroy(&ms->root_bo); |     kms_bo_destroy(&ms->root_bo); | ||||||
|     return TRUE; |     return TRUE; | ||||||
| @@ -1005,10 +1127,15 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn) | |||||||
|     unsigned handle, stride; |     unsigned handle, stride; | ||||||
|     struct kms_bo *bo; |     struct kms_bo *bo; | ||||||
|     unsigned attr[8]; |     unsigned attr[8]; | ||||||
|  |     unsigned fb_id; | ||||||
|     int ret; |     int ret; | ||||||
|  |  | ||||||
|     attr[0] = KMS_BO_TYPE; |     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; |     attr[1] = KMS_BO_TYPE_SCANOUT; | ||||||
|  | #endif | ||||||
|     attr[2] = KMS_WIDTH; |     attr[2] = KMS_WIDTH; | ||||||
|     attr[3] = pScrn->virtualX; |     attr[3] = pScrn->virtualX; | ||||||
|     attr[4] = KMS_HEIGHT; |     attr[4] = KMS_HEIGHT; | ||||||
| @@ -1031,17 +1158,21 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn) | |||||||
| 		       pScrn->bitsPerPixel, | 		       pScrn->bitsPerPixel, | ||||||
| 		       stride, | 		       stride, | ||||||
| 		       handle, | 		       handle, | ||||||
| 		       &ms->fb_id); | 		       &fb_id); | ||||||
|     if (ret) { |     if (ret) { | ||||||
| 	debug_printf("%s: failed to create framebuffer (%i, %s)", | 	debug_printf("%s: failed to create framebuffer (%i, %s)", | ||||||
| 		     __func__, ret, strerror(-ret)); | 		     __func__, ret, strerror(-ret)); | ||||||
| 	goto err_destroy; | 	goto err_destroy; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (!drv_destroy_front_buffer_kms(pScrn)) | ||||||
|  | 	FatalError("%s: could not takedown old bo", __func__); | ||||||
|  |  | ||||||
|     pScrn->frameX0 = 0; |     pScrn->frameX0 = 0; | ||||||
|     pScrn->frameY0 = 0; |     pScrn->frameY0 = 0; | ||||||
|     drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); |     drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); | ||||||
|     ms->root_bo = bo; |     ms->root_bo = bo; | ||||||
|  |     ms->fb_id = fb_id; | ||||||
|  |  | ||||||
|     return TRUE; |     return TRUE; | ||||||
|  |  | ||||||
| @@ -1109,4 +1240,14 @@ static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn) | |||||||
|     return TRUE; |     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: */ | /* vim: set sw=4 ts=8 sts=4: */ | ||||||
|   | |||||||
| @@ -1035,6 +1035,7 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel) | |||||||
|    modesettingPtr ms = modesettingPTR(pScrn); |    modesettingPtr ms = modesettingPTR(pScrn); | ||||||
|    struct exa_context *exa; |    struct exa_context *exa; | ||||||
|    ExaDriverPtr pExa; |    ExaDriverPtr pExa; | ||||||
|  |    CustomizerPtr cust = ms->cust; | ||||||
|  |  | ||||||
|    exa = xcalloc(1, sizeof(struct exa_context)); |    exa = xcalloc(1, sizeof(struct exa_context)); | ||||||
|    if (!exa) |    if (!exa) | ||||||
| @@ -1093,6 +1094,8 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel) | |||||||
|    exa->pipe = ms->api->create_context(ms->api, exa->scrn); |    exa->pipe = ms->api->create_context(ms->api, exa->scrn); | ||||||
|    /* Share context with DRI */ |    /* Share context with DRI */ | ||||||
|    ms->ctx = exa->pipe; |    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->renderer = renderer_create(exa->pipe); | ||||||
|    exa->accel = accel; |    exa->accel = accel; | ||||||
|   | |||||||
| @@ -586,7 +586,7 @@ void renderer_copy_pixmap(struct xorg_renderer *r, | |||||||
|  |  | ||||||
|  |  | ||||||
| void renderer_draw_yuv(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, |                        int dst_x, int dst_y, int dst_w, int dst_h, | ||||||
|                        struct pipe_texture **textures) |                        struct pipe_texture **textures) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -53,7 +53,7 @@ void renderer_set_constants(struct xorg_renderer *r, | |||||||
|  |  | ||||||
|  |  | ||||||
| void renderer_draw_yuv(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, |                        int dst_x, int dst_y, int dst_w, int dst_h, | ||||||
|                        struct pipe_texture **textures); |                        struct pipe_texture **textures); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -65,6 +65,24 @@ typedef struct | |||||||
|  |  | ||||||
| #define XORG_NR_FENCES 3 | #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 | typedef struct _modesettingRec | ||||||
| { | { | ||||||
|     /* drm */ |     /* drm */ | ||||||
| @@ -80,6 +98,9 @@ typedef struct _modesettingRec | |||||||
|  |  | ||||||
|     Bool noAccel; |     Bool noAccel; | ||||||
|     Bool SWCursor; |     Bool SWCursor; | ||||||
|  |     CursorPtr cursor; | ||||||
|  |     Bool swapThrottling; | ||||||
|  |     Bool dirtyThrottling; | ||||||
|     CloseScreenProcPtr CloseScreen; |     CloseScreenProcPtr CloseScreen; | ||||||
|  |  | ||||||
|     /* Broken-out options. */ |     /* Broken-out options. */ | ||||||
| @@ -115,12 +136,7 @@ typedef struct _modesettingRec | |||||||
|     Bool accelerate_2d; |     Bool accelerate_2d; | ||||||
|     Bool debug_fallback; |     Bool debug_fallback; | ||||||
|  |  | ||||||
|     /* winsys hocks */ |     CustomizerPtr cust; | ||||||
|     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; |  | ||||||
|  |  | ||||||
| #ifdef DRM_MODE_FEATURE_DIRTYFB | #ifdef DRM_MODE_FEATURE_DIRTYFB | ||||||
|     DamagePtr damage; |     DamagePtr damage; | ||||||
| @@ -129,6 +145,9 @@ typedef struct _modesettingRec | |||||||
|  |  | ||||||
| #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) | #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) | ||||||
|  |  | ||||||
|  | CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn); | ||||||
|  |  | ||||||
|  | Bool xorg_has_gallium(ScrnInfoPtr pScrn); | ||||||
|  |  | ||||||
| /*********************************************************************** | /*********************************************************************** | ||||||
|  * xorg_exa.c |  * xorg_exa.c | ||||||
|   | |||||||
| @@ -384,11 +384,14 @@ setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv) | |||||||
|  |  | ||||||
| static void | static void | ||||||
| draw_yuv(struct xorg_xv_port_priv *port, | 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) |          int dst_x, int dst_y, int dst_w, int dst_h) | ||||||
| { | { | ||||||
|    struct pipe_texture **textures = port->yuv[port->current_set]; |    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, |    renderer_draw_yuv(port->r, | ||||||
|                      src_x, src_y, src_w, src_h, |                      src_x, src_y, src_w, src_h, | ||||||
|                      dst_x, dst_y, dst_w, dst_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); |    exaMoveInPixmap(pPixmap); | ||||||
|    dst = exaGetPixmapDriverPrivate(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) { |    if (dst && !dst->tex) { | ||||||
| 	xorg_exa_set_shared_usage(pPixmap); | 	xorg_exa_set_shared_usage(pPixmap); | ||||||
| 	pScrn->pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL); | 	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; |       int box_y2 = pbox->y2; | ||||||
|       float diff_x = (float)src_w / (float)dst_w; |       float diff_x = (float)src_w / (float)dst_w; | ||||||
|       float diff_y = (float)src_h / (float)dst_h; |       float diff_y = (float)src_h / (float)dst_h; | ||||||
|       int offset_x = box_x1 - dstX + pPixmap->screen_x; |       float offset_x = box_x1 - dstX + pPixmap->screen_x; | ||||||
|       int offset_y = box_y1 - dstY + pPixmap->screen_y; |       float offset_y = box_y1 - dstY + pPixmap->screen_y; | ||||||
|       int offset_w; |       float offset_w; | ||||||
|       int offset_h; |       float offset_h; | ||||||
|  |  | ||||||
|       x = box_x1; |       x = box_x1; | ||||||
|       y = box_y1; |       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_w = dst_w - w; | ||||||
|       offset_h = dst_h - h; |       offset_h = dst_h - h; | ||||||
|  |  | ||||||
|       draw_yuv(pPriv, src_x + offset_x*diff_x, src_y + offset_y*diff_y, |       draw_yuv(pPriv, | ||||||
|                src_w - offset_w*diff_x, src_h - offset_h*diff_x, |                (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); |                x, y, w, h); | ||||||
|  |  | ||||||
|       pbox++; |       pbox++; | ||||||
|   | |||||||
| @@ -103,6 +103,9 @@ struct vmw_svga_winsys_context | |||||||
|     * referred. |     * referred. | ||||||
|     */ |     */ | ||||||
|    boolean preemptive_flush; |    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; |    struct pipe_fence_handle *fence = NULL; | ||||||
|    unsigned i; |    unsigned i; | ||||||
|    enum pipe_error ret; |    enum pipe_error ret; | ||||||
|  |    uint32_t throttle_us; | ||||||
|  |  | ||||||
|    ret = pb_validate_validate(vswc->validate); |    ret = pb_validate_validate(vswc->validate); | ||||||
|    assert(ret == PIPE_OK); |    assert(ret == PIPE_OK); | ||||||
| @@ -140,8 +144,13 @@ vmw_swc_flush(struct svga_winsys_context *swc, | |||||||
|          *reloc->where = ptr; |          *reloc->where = ptr; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       throttle_us = vswc->throttle_set ? | ||||||
|  | 	 vswc->throttle_us : vswc->vws->default_throttle_us; | ||||||
|  |  | ||||||
|       if (vswc->command.used) |       if (vswc->command.used) | ||||||
|          vmw_ioctl_command(vswc->vws, |          vmw_ioctl_command(vswc->vws, | ||||||
|  | 			   vswc->base.cid, | ||||||
|  | 			   throttle_us, | ||||||
|                            vswc->command.buffer, |                            vswc->command.buffer, | ||||||
|                            vswc->command.used, |                            vswc->command.used, | ||||||
|                            &vswc->last_fence); |                            &vswc->last_fence); | ||||||
| @@ -385,3 +394,14 @@ vmw_svga_context_create(struct pipe_screen *screen) | |||||||
| { | { | ||||||
|    return svga_context_create(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 * | struct pipe_context * | ||||||
| vmw_svga_context_create(struct pipe_screen *screen); | 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_ */ | #endif /* VMW_CONTEXT_H_ */ | ||||||
|   | |||||||
| @@ -37,13 +37,16 @@ | |||||||
|  * module. |  * module. | ||||||
|  */ |  */ | ||||||
| struct vmw_winsys_screen * | 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); |    struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen); | ||||||
|    if (!vws) |    if (!vws) | ||||||
|       goto out_no_vws; |       goto out_no_vws; | ||||||
|  |  | ||||||
|    vws->ioctl.drm_fd = fd; |    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)) |    if (!vmw_ioctl_init(vws)) | ||||||
|       goto out_no_ioctl; |       goto out_no_ioctl; | ||||||
| @@ -72,3 +75,13 @@ vmw_winsys_destroy(struct vmw_winsys_screen *vws) | |||||||
|    vmw_ioctl_cleanup(vws); |    vmw_ioctl_cleanup(vws); | ||||||
|    FREE(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; |    struct svga_winsys_screen base; | ||||||
|  |  | ||||||
|  |    boolean use_old_scanout_flag; | ||||||
|  |    uint32_t default_throttle_us; | ||||||
|  |  | ||||||
|    struct { |    struct { | ||||||
|       volatile uint32_t *fifo_map; |       volatile uint32_t *fifo_map; | ||||||
|       uint64_t last_fence; |       uint64_t last_fence; | ||||||
| @@ -94,9 +97,11 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, | |||||||
|  |  | ||||||
| void | void | ||||||
| vmw_ioctl_command(struct vmw_winsys_screen *vws, | vmw_ioctl_command(struct vmw_winsys_screen *vws, | ||||||
|                        void *commands, | 		  int32_t cid, | ||||||
|                        uint32_t size, | 		  uint32_t throttle_us, | ||||||
|                        uint32_t *fence); | 		  void *commands, | ||||||
|  | 		  uint32_t size, | ||||||
|  | 		  uint32_t *fence); | ||||||
|  |  | ||||||
| struct vmw_region * | struct vmw_region * | ||||||
| vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size); | 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_ioctl_cleanup(struct vmw_winsys_screen *vws); | ||||||
| void vmw_pools_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_destroy(struct vmw_winsys_screen *sws); | ||||||
|  | void vmw_winsys_screen_set_throttling(struct pipe_screen *screen, | ||||||
|  | 				      uint32_t throttle_us); | ||||||
|  |  | ||||||
| #endif /* VMW_SCREEN_H_ */ | #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 ddx_compat = { 0, 0, 0 }; | ||||||
| static struct dri1_api_version dri_required = { 4, 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 dri_compat = { 4, 0, 0 }; | ||||||
| static struct dri1_api_version drm_required = { 0, 1, 0 }; | static struct dri1_api_version drm_required = { 1, 0, 0 }; | ||||||
| static struct dri1_api_version drm_compat = { 0, 0, 0 }; | static struct dri1_api_version drm_compat = { 1, 0, 0 }; | ||||||
|  | static struct dri1_api_version drm_scanout = { 0, 9, 0 }; | ||||||
|  |  | ||||||
| static boolean | static boolean | ||||||
| vmw_dri1_check_version(const struct dri1_api_version *cur, | 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 vmw_winsys_screen *vws; | ||||||
|    struct pipe_screen *screen; |    struct pipe_screen *screen; | ||||||
|    struct dri1_create_screen_arg *dri1; |    struct dri1_create_screen_arg *dri1; | ||||||
|  |    boolean use_old_scanout_flag = FALSE; | ||||||
|  |  | ||||||
|    if (!arg || arg->mode == DRM_CREATE_NORMAL) { |    if (!arg || arg->mode == DRM_CREATE_NORMAL) { | ||||||
|       struct dri1_api_version drm_ver; |       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.major = ver->version_major; | ||||||
|       drm_ver.minor = ver->version_minor; |       drm_ver.minor = ver->version_minor; | ||||||
|  |       drm_ver.patch_level = 0; /* ??? */ | ||||||
|  |  | ||||||
|       drmFreeVersion(ver); |       drmFreeVersion(ver); | ||||||
|       if (!vmw_dri1_check_version(&drm_ver, &drm_required, |       if (!vmw_dri1_check_version(&drm_ver, &drm_required, | ||||||
| 				  &drm_compat, "vmwgfx drm driver")) | 				  &drm_compat, "vmwgfx drm driver")) | ||||||
| 	 return NULL; | 	 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) { |    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, | 	 if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required, | ||||||
| 				     &drm_compat, "vmwgfx drm driver")) | 				     &drm_compat, "vmwgfx drm driver")) | ||||||
| 	    return NULL; | 	    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; | 	 dri1->api = &dri1_api_hooks; | ||||||
| 	 break; | 	 break; | ||||||
|       default: |       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) |    if (!vws) | ||||||
|       goto out_no_vws; |       goto out_no_vws; | ||||||
|  |  | ||||||
| @@ -228,7 +238,7 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe, | |||||||
| 		   cmd.rect.y, | 		   cmd.rect.y, | ||||||
| 		   cmd.rect.w, cmd.rect.h, cmd.rect.srcx, cmd.rect.srcy); | 		   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); |                         &fence_seq); | ||||||
|       visible = TRUE; |       visible = TRUE; | ||||||
|    } |    } | ||||||
|   | |||||||
| @@ -57,6 +57,12 @@ struct vmw_region | |||||||
|    uint32_t size; |    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 | static void | ||||||
| vmw_check_last_cmd(struct vmw_winsys_screen *vws) | 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); |    vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format); | ||||||
|  |  | ||||||
|    memset(&s_arg, 0, sizeof(s_arg)); |    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->format = (uint32_t) format; | ||||||
|    req->shareable = 1; |    req->shareable = 1; | ||||||
|  |  | ||||||
| @@ -225,8 +241,9 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size, | vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid, | ||||||
| 		       uint32_t * pfence) | 		  uint32_t throttle_us, void *commands, uint32_t size, | ||||||
|  | 		  uint32_t *pfence) | ||||||
| { | { | ||||||
|    struct drm_vmw_execbuf_arg arg; |    struct drm_vmw_execbuf_arg arg; | ||||||
|    struct drm_vmw_fence_rep rep; |    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.fence_rep = (unsigned long)&rep; | ||||||
|    arg.commands = (unsigned long)commands; |    arg.commands = (unsigned long)commands; | ||||||
|    arg.command_size = size; |    arg.command_size = size; | ||||||
|  |    arg.throttle_us = throttle_us; | ||||||
|  |  | ||||||
|    do { |    do { | ||||||
|        ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg)); |        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_NUM_FREE_STREAMS 1 | ||||||
| #define DRM_VMW_PARAM_3D               2 | #define DRM_VMW_PARAM_3D               2 | ||||||
| #define DRM_VMW_PARAM_FIFO_OFFSET      3 | #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 |  * struct drm_vmw_getparam_arg | ||||||
| @@ -85,49 +86,6 @@ struct drm_vmw_getparam_arg { | |||||||
| 	uint32_t pad64; | 	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. |  * 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. |  * The size of the array should equal the total number of mipmap levels. | ||||||
|  * @shareable: Boolean whether other clients (as identified by file descriptors) |  * @shareable: Boolean whether other clients (as identified by file descriptors) | ||||||
|  * may reference this surface. |  * 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. |  * Input data to the DRM_VMW_CREATE_SURFACE Ioctl. | ||||||
|  * Output data from the DRM_VMW_REF_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]; | 	uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES]; | ||||||
| 	uint64_t size_addr; | 	uint64_t size_addr; | ||||||
| 	int32_t shareable; | 	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. |  * @commands: User-space address of a command buffer cast to an uint64_t. | ||||||
|  * @command-size: Size in bytes of the command buffer. |  * @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 |  * @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an | ||||||
|  * uint64_t. |  * 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. |  * Argument to the DRM_VMW_EXECBUF Ioctl. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | #define DRM_VMW_EXECBUF_VERSION 0 | ||||||
|  |  | ||||||
| struct drm_vmw_execbuf_arg { | struct drm_vmw_execbuf_arg { | ||||||
| 	uint64_t commands; | 	uint64_t commands; | ||||||
| 	uint32_t command_size; | 	uint32_t command_size; | ||||||
| 	uint32_t pad64; | 	uint32_t throttle_us; | ||||||
| 	uint64_t fence_rep; | 	uint64_t fence_rep; | ||||||
|  | 	 uint32_t version; | ||||||
|  | 	 uint32_t flags; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -40,8 +40,11 @@ | |||||||
|  |  | ||||||
| struct vmw_dma_buffer; | struct vmw_dma_buffer; | ||||||
|  |  | ||||||
| struct vmw_driver | struct vmw_customizer | ||||||
| { | { | ||||||
|  |     CustomizerRec base; | ||||||
|  |     ScrnInfoPtr pScrn; | ||||||
|  |  | ||||||
|     int fd; |     int fd; | ||||||
|  |  | ||||||
|     void *cursor_priv; |     void *cursor_priv; | ||||||
| @@ -50,11 +53,10 @@ struct vmw_driver | |||||||
|     void *video_priv; |     void *video_priv; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static INLINE struct vmw_driver * | static INLINE struct vmw_customizer * | ||||||
| vmw_driver(ScrnInfoPtr pScrn) | vmw_customizer(CustomizerPtr cust) | ||||||
| { | { | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     return cust ? (struct vmw_customizer *) cust : NULL; | ||||||
|     return ms ? (struct vmw_driver *)ms->winsys_priv : NULL; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -62,40 +64,40 @@ vmw_driver(ScrnInfoPtr pScrn) | |||||||
|  * vmw_video.c |  * 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 |  * 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, | 						uint32_t size, | ||||||
| 						unsigned *handle); | 						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); | 			    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); | 			    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); | 			      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); | 			  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 | #endif | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ struct vmw_dma_buffer | |||||||
| }; | }; | ||||||
|  |  | ||||||
| static int | 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; |     struct drm_vmw_getparam_arg gp_arg; | ||||||
|     int ret; |     int ret; | ||||||
| @@ -75,7 +75,7 @@ vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out) | |||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| vmw_ioctl_supports_streams(struct vmw_driver *vmw) | vmw_ioctl_supports_streams(struct vmw_customizer *vmw) | ||||||
| { | { | ||||||
|     uint64_t value; |     uint64_t value; | ||||||
|     int ret; |     int ret; | ||||||
| @@ -88,7 +88,7 @@ vmw_ioctl_supports_streams(struct vmw_driver *vmw) | |||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| vmw_ioctl_num_streams(struct vmw_driver *vmw, | vmw_ioctl_num_streams(struct vmw_customizer *vmw, | ||||||
| 		      uint32_t *ntot, uint32_t *nfree) | 		      uint32_t *ntot, uint32_t *nfree) | ||||||
| { | { | ||||||
|     uint64_t v1, v2; |     uint64_t v1, v2; | ||||||
| @@ -109,7 +109,7 @@ vmw_ioctl_num_streams(struct vmw_driver *vmw, | |||||||
| } | } | ||||||
|  |  | ||||||
| int | 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; |     struct drm_vmw_stream_arg s_arg; | ||||||
|     int ret; |     int ret; | ||||||
| @@ -125,7 +125,7 @@ vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out) | |||||||
| } | } | ||||||
|  |  | ||||||
| int | 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; |     struct drm_vmw_stream_arg s_arg; | ||||||
|     int ret; |     int ret; | ||||||
| @@ -140,7 +140,7 @@ vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id) | |||||||
| } | } | ||||||
|  |  | ||||||
| int | 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; |     struct drm_vmw_cursor_bypass_arg arg; | ||||||
|     int ret; |     int ret; | ||||||
| @@ -157,7 +157,7 @@ vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot) | |||||||
| } | } | ||||||
|  |  | ||||||
| struct vmw_dma_buffer * | 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; |     struct vmw_dma_buffer *buf; | ||||||
|     union drm_vmw_alloc_dmabuf_arg arg; |     union drm_vmw_alloc_dmabuf_arg arg; | ||||||
| @@ -198,7 +198,7 @@ err: | |||||||
| } | } | ||||||
|  |  | ||||||
| void | 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;  |     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 * | 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; |     void *map; | ||||||
|  |  | ||||||
| @@ -236,7 +236,7 @@ vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | 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; |     --buf->map_count; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -32,16 +32,22 @@ | |||||||
|  |  | ||||||
| #include "vmw_hook.h" | #include "vmw_hook.h" | ||||||
| #include "vmw_driver.h" | #include "vmw_driver.h" | ||||||
|  | #include <pipe/p_context.h> | ||||||
|  |  | ||||||
| #include "cursorstr.h" | #include "cursorstr.h" | ||||||
|  |  | ||||||
|  | void vmw_winsys_screen_set_throttling(struct pipe_screen *screen, | ||||||
|  | 				      uint32_t throttle_us); | ||||||
|  |  | ||||||
|  |  | ||||||
| /* modified version of crtc functions */ | /* modified version of crtc functions */ | ||||||
| xf86CrtcFuncsRec vmw_screen_crtc_funcs; | xf86CrtcFuncsRec vmw_screen_crtc_funcs; | ||||||
|  |  | ||||||
| static void | static void | ||||||
| vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image) | 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); |     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); | ||||||
|     xf86CrtcFuncsPtr funcs = vmw->cursor_priv; |     xf86CrtcFuncsPtr funcs = vmw->cursor_priv; | ||||||
|     CursorPtr c = config->cursor; |     CursorPtr c = config->cursor; | ||||||
| @@ -53,8 +59,9 @@ vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image) | |||||||
| } | } | ||||||
|  |  | ||||||
| static void | 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); |     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); | ||||||
|     int i; |     int i; | ||||||
|  |  | ||||||
| @@ -70,9 +77,9 @@ vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw) | |||||||
| } | } | ||||||
|  |  | ||||||
| static void | 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; |     int i; | ||||||
|  |  | ||||||
|     vmw_ioctl_cursor_bypass(vmw, 0, 0); |     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; | 	config->crtc[i]->funcs = vmw->cursor_priv; | ||||||
| } | } | ||||||
|  |  | ||||||
| static Bool | static void | ||||||
| vmw_screen_init(ScrnInfoPtr pScrn) | vmw_context_throttle(CustomizerPtr cust, | ||||||
|  | 		     struct pipe_context *pipe, | ||||||
|  | 		     enum xorg_throttling_reason reason) | ||||||
| { | { | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     switch (reason) { | ||||||
|     struct vmw_driver *vmw; |     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); | static void | ||||||
|     if (!vmw) | vmw_context_no_throttle(CustomizerPtr cust, | ||||||
| 	return FALSE; | 		     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 gallium is used then we don't need to do anything more. */ | ||||||
|     if (ms->screen) |     if (xorg_has_gallium(vmw->pScrn)) | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
|  |  | ||||||
|     vmw_video_init(pScrn, vmw); |     vmw_video_init(vmw); | ||||||
|  |  | ||||||
|     return TRUE; |     return TRUE; | ||||||
| } | } | ||||||
|  |  | ||||||
| static Bool | static Bool | ||||||
| vmw_screen_close(ScrnInfoPtr pScrn) | vmw_screen_close(CustomizerPtr cust) | ||||||
| { | { | ||||||
|     modesettingPtr ms = modesettingPTR(pScrn); |     struct vmw_customizer *vmw = vmw_customizer(cust); | ||||||
|     struct vmw_driver *vmw = vmw_driver(pScrn); |  | ||||||
|  |  | ||||||
|     if (!vmw) |     if (!vmw) | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
|  |  | ||||||
|     vmw_screen_cursor_close(pScrn, vmw); |     vmw_screen_cursor_close(vmw); | ||||||
|  |  | ||||||
|     vmw_video_close(pScrn, vmw); |     vmw_video_close(vmw); | ||||||
|  |  | ||||||
|     ms->winsys_priv = NULL; |  | ||||||
|     xfree(vmw); |  | ||||||
|  |  | ||||||
|     return TRUE; |     return TRUE; | ||||||
| } | } | ||||||
|  |  | ||||||
| static Bool | static Bool | ||||||
| vmw_screen_enter_vt(ScrnInfoPtr pScrn) | vmw_screen_enter_vt(CustomizerPtr cust) | ||||||
| { | { | ||||||
|     debug_printf("%s: enter\n", __func__); |     debug_printf("%s: enter\n", __func__); | ||||||
|  |  | ||||||
| @@ -133,13 +170,13 @@ vmw_screen_enter_vt(ScrnInfoPtr pScrn) | |||||||
| } | } | ||||||
|  |  | ||||||
| static Bool | 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__); |     debug_printf("%s: enter\n", __func__); | ||||||
|  |  | ||||||
|     vmw_video_stop_all(pScrn, vmw); |     vmw_video_stop_all(vmw); | ||||||
|  |  | ||||||
|     return TRUE; |     return TRUE; | ||||||
| } | } | ||||||
| @@ -153,18 +190,27 @@ static Bool (*vmw_screen_pre_init_saved)(ScrnInfoPtr pScrn, int flags) = NULL; | |||||||
| static Bool | static Bool | ||||||
| vmw_screen_pre_init(ScrnInfoPtr pScrn, int flags) | 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; |     pScrn->PreInit = vmw_screen_pre_init_saved; | ||||||
|     if (!pScrn->PreInit(pScrn, flags)) |     if (!pScrn->PreInit(pScrn, flags)) | ||||||
| 	return FALSE; | 	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; |     return TRUE; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -226,7 +226,7 @@ static void vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion, | |||||||
| /* | /* | ||||||
|  * Local functions. |  * 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, | static int vmw_video_port_init(ScrnInfoPtr pScrn, | ||||||
|                                struct vmw_video_port *port, |                                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); |                                short height, RegionPtr clipBoxes); | ||||||
| static void vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port); | 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); |                                   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); |                                  struct vmw_video_buffer *out); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -267,8 +267,9 @@ static int vmw_video_buffer_free(struct vmw_driver *vmw, | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| Bool | 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; |     ScreenPtr pScreen = pScrn->pScreen; | ||||||
|     XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL; |     XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL; | ||||||
|     XF86VideoAdaptorPtr newAdaptor = NULL; |     XF86VideoAdaptorPtr newAdaptor = NULL; | ||||||
| @@ -345,8 +346,9 @@ vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw) | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| Bool | 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; |     struct vmw_video_private *video; | ||||||
|     int i; |     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; |     struct vmw_video_private *video = vmw->video_priv; | ||||||
|     int i; |     int i; | ||||||
|  |  | ||||||
| @@ -421,7 +424,7 @@ void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw) | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| static XF86VideoAdaptorPtr | static XF86VideoAdaptorPtr | ||||||
| vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw) | vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw) | ||||||
| { | { | ||||||
|     XF86VideoAdaptorPtr adaptor; |     XF86VideoAdaptorPtr adaptor; | ||||||
|     struct vmw_video_private *video; |     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, |                     unsigned char *buf, short width, | ||||||
|                     short height, RegionPtr clipBoxes) |                     short height, RegionPtr clipBoxes) | ||||||
| { | { | ||||||
|     struct vmw_driver *vmw = vmw_driver(pScrn); |     struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn)); | ||||||
|     unsigned short w, h; |     unsigned short w, h; | ||||||
|     int i, ret; |     int i, ret; | ||||||
|  |  | ||||||
| @@ -583,7 +586,7 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port, | |||||||
|                     unsigned char *buf, short width, |                     unsigned char *buf, short width, | ||||||
|                     short height, RegionPtr clipBoxes) |                     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; |     struct drm_vmw_control_stream_arg arg; | ||||||
|     unsigned short w, h; |     unsigned short w, h; | ||||||
|     int size; |     int size; | ||||||
| @@ -675,7 +678,7 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port, | |||||||
| static void | static void | ||||||
| vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port) | 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; |     uint32 id, colorKey, flags; | ||||||
|     Bool isAutoPaintColorkey; |     Bool isAutoPaintColorkey; | ||||||
|     int i; |     int i; | ||||||
| @@ -721,7 +724,7 @@ vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port) | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| static int | 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) |                        struct vmw_video_buffer *out) | ||||||
| { | { | ||||||
|     out->buf = vmw_ioctl_buffer_create(vmw, size, &out->handle); |     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 | static int | ||||||
| vmw_video_buffer_free(struct vmw_driver *vmw, | vmw_video_buffer_free(struct vmw_customizer *vmw, | ||||||
|                       struct vmw_video_buffer *out) |                       struct vmw_video_buffer *out) | ||||||
| { | { | ||||||
|     if (out->size == 0) |     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, |                  Bool sync, RegionPtr clipBoxes, pointer data, | ||||||
|                  DrawablePtr dst) |                  DrawablePtr dst) | ||||||
| { | { | ||||||
|     struct vmw_driver *vmw = vmw_driver(pScrn); |     struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn)); | ||||||
|     struct vmw_video_port *port = data; |     struct vmw_video_port *port = data; | ||||||
|  |  | ||||||
|     debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__, |     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 | static void | ||||||
| vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup) | 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 vmw_video_port *port = data; | ||||||
|     struct drm_vmw_control_stream_arg arg; |     struct drm_vmw_control_stream_arg arg; | ||||||
|     int ret; |     int ret; | ||||||
|   | |||||||
| @@ -33,12 +33,50 @@ | |||||||
|  |  | ||||||
| #include "vmw_hook.h" | #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); | static void vmw_xorg_identify(int flags); | ||||||
| _X_EXPORT Bool vmw_xorg_pci_probe(DriverPtr driver, | _X_EXPORT Bool vmw_xorg_pci_probe(DriverPtr driver, | ||||||
| 				  int entity_num, | 				  int entity_num, | ||||||
| 				  struct pci_device *device, | 				  struct pci_device *device, | ||||||
| 				  intptr_t match_data); | 				  intptr_t match_data); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Tables | ||||||
|  |  */ | ||||||
|  |  | ||||||
| static const struct pci_id_match vmw_xorg_device_match[] = { | static const struct pci_id_match vmw_xorg_device_match[] = { | ||||||
|     {0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0}, |     {0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0}, | ||||||
|     {0, 0, 0, 0, 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 = { | static XF86ModuleVersionInfo vmw_xorg_version = { | ||||||
|     "vmwgfx", |     VMWGFX_DRIVER_NAME, | ||||||
|     MODULEVENDORSTRING, |     MODULEVENDORSTRING, | ||||||
|     MODINFOSTRING1, |     MODINFOSTRING1, | ||||||
|     MODINFOSTRING2, |     MODINFOSTRING2, | ||||||
|     XORG_VERSION_CURRENT, |     XORG_VERSION_CURRENT, | ||||||
|     0, 1, 0, /* major, minor, patch */ |     VMWGFX_VERSION_MAJOR, VMWGFX_VERSION_MINOR, VMWGFX_VERSION_PATCH, | ||||||
|     ABI_CLASS_VIDEODRV, |     ABI_CLASS_VIDEODRV, | ||||||
|     ABI_VIDEODRV_VERSION, |     ABI_VIDEODRV_VERSION, | ||||||
|     MOD_CLASS_VIDEODRV, |     MOD_CLASS_VIDEODRV, | ||||||
| @@ -73,7 +111,7 @@ static XF86ModuleVersionInfo vmw_xorg_version = { | |||||||
|  |  | ||||||
| _X_EXPORT DriverRec vmwgfx = { | _X_EXPORT DriverRec vmwgfx = { | ||||||
|     1, |     1, | ||||||
|     "vmwgfx", |     VMWGFX_DRIVER_NAME, | ||||||
|     vmw_xorg_identify, |     vmw_xorg_identify, | ||||||
|     NULL, |     NULL, | ||||||
|     xorg_tracker_available_options, |     xorg_tracker_available_options, | ||||||
| @@ -92,6 +130,7 @@ _X_EXPORT XF86ModuleData vmwgfxModuleData = { | |||||||
|     NULL |     NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Xorg driver functions |  * Xorg driver functions | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -267,13 +267,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) | |||||||
| { | { | ||||||
|    switch (fdwReason) { |    switch (fdwReason) { | ||||||
|    case DLL_PROCESS_ATTACH: |    case DLL_PROCESS_ATTACH: | ||||||
|       if (!stw_init(&stw_winsys)) { |       stw_init(&stw_winsys); | ||||||
|          return FALSE; |       stw_init_thread(); | ||||||
|       } |       break; | ||||||
|       return stw_init_thread(); |  | ||||||
|  |  | ||||||
|    case DLL_THREAD_ATTACH: |    case DLL_THREAD_ATTACH: | ||||||
|       return stw_init_thread(); |       stw_init_thread(); | ||||||
|  |       break; | ||||||
|  |  | ||||||
|    case DLL_THREAD_DETACH: |    case DLL_THREAD_DETACH: | ||||||
|       stw_cleanup_thread(); |       stw_cleanup_thread(); | ||||||
|   | |||||||
| @@ -317,13 +317,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) | |||||||
| { | { | ||||||
|    switch (fdwReason) { |    switch (fdwReason) { | ||||||
|    case DLL_PROCESS_ATTACH: |    case DLL_PROCESS_ATTACH: | ||||||
|       if (!stw_init(&stw_winsys)) { |       stw_init(&stw_winsys); | ||||||
|          return FALSE; |       stw_init_thread(); | ||||||
|       } |       break; | ||||||
|       return stw_init_thread(); |  | ||||||
|  |  | ||||||
|    case DLL_THREAD_ATTACH: |    case DLL_THREAD_ATTACH: | ||||||
|       return stw_init_thread(); |       stw_init_thread(); | ||||||
|  |       break; | ||||||
|  |  | ||||||
|    case DLL_THREAD_DETACH: |    case DLL_THREAD_DETACH: | ||||||
|       stw_cleanup_thread(); |       stw_cleanup_thread(); | ||||||
|   | |||||||
| @@ -437,8 +437,10 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||||||
|    psc->ext_list_first_time = GL_TRUE; |    psc->ext_list_first_time = GL_TRUE; | ||||||
|  |  | ||||||
|    if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen), |    if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen), | ||||||
|                     &driverName, &deviceName)) |                     &driverName, &deviceName)) { | ||||||
|  |       XFree(psp); | ||||||
|       return NULL; |       return NULL; | ||||||
|  |    } | ||||||
|  |  | ||||||
|    psc->driver = driOpenDriver(driverName); |    psc->driver = driOpenDriver(driverName); | ||||||
|    if (psc->driver == NULL) { |    if (psc->driver == NULL) { | ||||||
| @@ -467,17 +469,17 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||||||
|    psc->fd = open(deviceName, O_RDWR); |    psc->fd = open(deviceName, O_RDWR); | ||||||
|    if (psc->fd < 0) { |    if (psc->fd < 0) { | ||||||
|       ErrorMessageF("failed to open drm device: %s\n", strerror(errno)); |       ErrorMessageF("failed to open drm device: %s\n", strerror(errno)); | ||||||
|       return NULL; |       goto handle_error; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    if (drmGetMagic(psc->fd, &magic)) { |    if (drmGetMagic(psc->fd, &magic)) { | ||||||
|       ErrorMessageF("failed to get magic\n"); |       ErrorMessageF("failed to get magic\n"); | ||||||
|       return NULL; |       goto handle_error; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) { |    if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) { | ||||||
|       ErrorMessageF("failed to authenticate magic %d\n", magic); |       ErrorMessageF("failed to authenticate magic %d\n", magic); | ||||||
|       return NULL; |       goto handle_error; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    /* If the server does not support the protocol for |    /* If the server does not support the protocol for | ||||||
| @@ -491,7 +493,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||||||
|  |  | ||||||
|    if (psc->__driScreen == NULL) { |    if (psc->__driScreen == NULL) { | ||||||
|       ErrorMessageF("failed to create dri screen\n"); |       ErrorMessageF("failed to create dri screen\n"); | ||||||
|       return NULL; |       goto handle_error; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    driBindExtensions(psc, 1); |    driBindExtensions(psc, 1); | ||||||
| @@ -521,6 +523,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||||||
|  handle_error: |  handle_error: | ||||||
|    Xfree(driverName); |    Xfree(driverName); | ||||||
|    Xfree(deviceName); |    Xfree(deviceName); | ||||||
|  |    XFree(psp); | ||||||
|  |  | ||||||
|    /* FIXME: clean up here */ |    /* FIXME: clean up here */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -385,7 +385,8 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig, | |||||||
|    req->glxwindow = (GLXWindow) XAllocID(dpy); |    req->glxwindow = (GLXWindow) XAllocID(dpy); | ||||||
|    req->numAttribs = (CARD32) i; |    req->numAttribs = (CARD32) i; | ||||||
|  |  | ||||||
|    memcpy(data, attrib_list, 8 * i); |    if (attrib_list) | ||||||
|  |       memcpy(data, attrib_list, 8 * i); | ||||||
|  |  | ||||||
|    UnlockDisplay(dpy); |    UnlockDisplay(dpy); | ||||||
|    SyncHandle(); |    SyncHandle(); | ||||||
|   | |||||||
| @@ -291,7 +291,8 @@ __glXInitVertexArrayState(__GLXcontext * gc) | |||||||
|  |  | ||||||
|    arrays->stack_index = 0; |    arrays->stack_index = 0; | ||||||
|    arrays->stack = malloc(sizeof(struct array_stack_state) |    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; |    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(cpp > 0); | ||||||
|    assert(pitch > 0); |    assert(pitch > 0); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -254,7 +254,7 @@ void intel_flush_prim(struct intel_context *intel) | |||||||
|       BEGIN_BATCH(5, LOOP_CLIPRECTS); |       BEGIN_BATCH(5, LOOP_CLIPRECTS); | ||||||
|       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | |       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | | ||||||
| 		I1_LOAD_S(0) | I1_LOAD_S(1) | 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_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, offset); | ||||||
|       OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) | |       OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) | | ||||||
| 		(intel->vertex_size << S1_VERTEX_PITCH_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 | |       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | | ||||||
| 		I1_LOAD_S(0) | I1_LOAD_S(2) | 1); | 		I1_LOAD_S(0) | I1_LOAD_S(2) | 1); | ||||||
|       /* S0 */ |       /* 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, |       OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, | ||||||
| 		offset | (intel->vertex_size << S0_VB_PITCH_SHIFT_830) | | 		offset | (intel->vertex_size << S0_VB_PITCH_SHIFT_830) | | ||||||
| 		S0_VB_ENABLE_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) { |    if (c->current_const[argIndex].index != src->Index || relAddr) { | ||||||
|       struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0]; |       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 | #if 0 | ||||||
|       printf("  fetch const[%d] for arg %d into reg %d\n", |       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; |       GLint cx, cy, cw, ch; | ||||||
|       drm_clip_rect_t clear; |       drm_clip_rect_t clear; | ||||||
|       int i; |       int i; | ||||||
|  |       drm_intel_bo *aper_array[2]; | ||||||
|  |  | ||||||
|       /* Get clear bounds after locking */ |       /* Get clear bounds after locking */ | ||||||
|       cx = fb->_Xmin; |       cx = fb->_Xmin; | ||||||
| @@ -526,6 +527,15 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) | |||||||
|                assert(x1 < x2); |                assert(x1 < x2); | ||||||
|                assert(y1 < y2); |                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); |                BEGIN_BATCH(6, REFERENCES_CLIPRECTS); | ||||||
|                OUT_BATCH(CMD); |                OUT_BATCH(CMD); | ||||||
|                OUT_BATCH(BR13); |                OUT_BATCH(BR13); | ||||||
|   | |||||||
| @@ -172,6 +172,8 @@ do_blit_readpixels(GLcontext * ctx, | |||||||
|    struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); |    struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); | ||||||
|    GLuint dst_offset; |    GLuint dst_offset; | ||||||
|    GLuint rowLength; |    GLuint rowLength; | ||||||
|  |    drm_intel_bo *dst_buffer; | ||||||
|  |    drm_clip_rect_t read_bounds, rect, src_rect; | ||||||
|  |  | ||||||
|    if (INTEL_DEBUG & DEBUG_PIXEL) |    if (INTEL_DEBUG & DEBUG_PIXEL) | ||||||
|       _mesa_printf("%s\n", __FUNCTION__); |       _mesa_printf("%s\n", __FUNCTION__); | ||||||
| @@ -212,58 +214,47 @@ do_blit_readpixels(GLcontext * ctx, | |||||||
|       return GL_FALSE; |       return GL_FALSE; | ||||||
|    } |    } | ||||||
|    else { |    else { | ||||||
|       rowLength = -rowLength; |       if (ctx->ReadBuffer->Name == 0) | ||||||
|  | 	 rowLength = -rowLength; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height, |    dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height, | ||||||
| 					       format, type, 0, 0, 0); | 					       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 |    dst_buffer = intel_bufferobj_buffer(intel, dst, | ||||||
|     * fire with lock held to guarentee cliprects are correct. | 					       all ? INTEL_WRITE_FULL : | ||||||
|     */ | 					       INTEL_WRITE_PART); | ||||||
|    intelFlush(&intel->ctx); |  | ||||||
|    LOCK_HARDWARE(intel); |  | ||||||
|  |  | ||||||
|    if (intel->driReadDrawable->numClipRects) { |    src_rect.x1 = x; | ||||||
|       GLboolean all = (width * height * src->cpp == dst->Base.Size && |    if (ctx->ReadBuffer->Name == 0) | ||||||
|                        x == 0 && dst_offset == 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, |    read_bounds.x1 = 0; | ||||||
| 						  all ? INTEL_WRITE_FULL : |    read_bounds.y1 = 0; | ||||||
| 						  INTEL_WRITE_PART); |    read_bounds.x2 = ctx->ReadBuffer->Width; | ||||||
|       __DRIdrawablePrivate *dPriv = intel->driReadDrawable; |    read_bounds.y2 = ctx->ReadBuffer->Height; | ||||||
|       int nbox = dPriv->numClipRects; |  | ||||||
|       drm_clip_rect_t *box = dPriv->pClipRects; |  | ||||||
|       drm_clip_rect_t rect; |  | ||||||
|       drm_clip_rect_t src_rect; |  | ||||||
|       int i; |  | ||||||
|  |  | ||||||
|       src_rect.x1 = dPriv->x + x; |    if (!intel_intersect_cliprects(&rect, &src_rect, &read_bounds)) | ||||||
|       src_rect.y1 = dPriv->y + dPriv->h - (y + height); |       return GL_TRUE; | ||||||
|       src_rect.x2 = src_rect.x1 + width; |  | ||||||
|       src_rect.y2 = src_rect.y1 + height; |  | ||||||
|  |  | ||||||
|  |    if (!intelEmitCopyBlit(intel, | ||||||
|  | 			  src->cpp, | ||||||
|       for (i = 0; i < nbox; i++) { | 			  src->pitch, src->buffer, 0, src->tiling, | ||||||
|          if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) | 			  rowLength, dst_buffer, dst_offset, GL_FALSE, | ||||||
|             continue; | 			  rect.x1, | ||||||
|  | 			  rect.y1, | ||||||
|          if (!intelEmitCopyBlit(intel, | 			  rect.x1 - src_rect.x1, | ||||||
| 				src->cpp, | 			  rect.y2 - src_rect.y2, | ||||||
| 				src->pitch, src->buffer, 0, src->tiling, | 			  rect.x2 - rect.x1, rect.y2 - rect.y1, | ||||||
| 				rowLength, dst_buffer, dst_offset, GL_FALSE, | 			  GL_COPY)) { | ||||||
| 				rect.x1, |       return GL_FALSE; | ||||||
| 				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; |  | ||||||
| 	 } |  | ||||||
|       } |  | ||||||
|    } |    } | ||||||
|    UNLOCK_HARDWARE(intel); |    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