Compare commits
	
		
			141 Commits
		
	
	
		
			mesa-25.0.
			...
			mesa_7_4_r
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 17db2db9dc | ||
|  | dba79af9bc | ||
|  | b009a32bf4 | ||
|  | 7122490982 | ||
|  | 6ada1d47d9 | ||
|  | 55865335f4 | ||
|  | 918e5221ef | ||
|  | 9feb26584a | ||
|  | a8528a2e86 | ||
|  | 119360cccd | ||
|  | ac2216542d | ||
|  | 37e5c057f1 | ||
|  | 4d9b8e0f93 | ||
|  | c1b71f46b5 | ||
|  | 4a25ac9564 | ||
|  | 35d965b39b | ||
|  | d0aab00609 | ||
|  | ef33d0f103 | ||
|  | 349b819768 | ||
|  | 50443db882 | ||
|  | c503cacb53 | ||
|  | e862b4e38f | ||
|  | e9dfc858fb | ||
|  | 5efbca1e21 | ||
|  | d6d8663a88 | ||
|  | 13990bd98a | ||
|  | def630d0a2 | ||
|  | ca2564f1e6 | ||
|  | 711a57f7c7 | ||
|  | 058cf2fff1 | ||
|  | 715f509c5d | ||
|  | e704e6c6f3 | ||
|  | 01f34e667a | ||
|  | 4d0a7b33c5 | ||
|  | fb1d2ed34c | ||
|  | 9395fedf98 | ||
|  | 9abc0d80af | ||
|  | 90e89c01df | ||
|  | 790d93e362 | ||
|  | e9f3783169 | ||
|  | e41780fedc | ||
|  | d0edbbb3f3 | ||
|  | e10119c23e | ||
|  | 208c087f39 | ||
|  | 0c8b40b42b | ||
|  | 5199f451bb | ||
|  | dd7cde5230 | ||
|  | ab5746e5d8 | ||
|  | 3bd446c0ab | ||
|  | 9b78402ee4 | ||
|  | cf1ef0f308 | ||
|  | fd1f65ba61 | ||
|  | 967345b497 | ||
|  | 41ad853a6a | ||
|  | 842baa29cb | ||
|  | 9556d870a1 | ||
|  | 42ce790086 | ||
|  | b17769af42 | ||
|  | 9030277b0d | ||
|  | a37a9bf769 | ||
|  | 8afb8a8145 | ||
|  | 801f933694 | ||
|  | 75ecd6ebbf | ||
|  | 1cd7317fdb | ||
|  | 1865291701 | ||
|  | 3edbcce7d5 | ||
|  | b1fb34d0ac | ||
|  | 606099f545 | ||
|  | 32e3142071 | ||
|  | 66eea4e104 | ||
|  | e428cf3afd | ||
|  | 842b5164d2 | ||
|  | a6f7e909a7 | ||
|  | ca87e5a7bd | ||
|  | 45c4b4dfbd | ||
|  | 2adaec1226 | ||
|  | 549586c319 | ||
|  | 463ac421a5 | ||
|  | 6801240205 | ||
|  | a22088b7d5 | ||
|  | e89c49147f | ||
|  | 67634240d1 | ||
|  | 819b028a8e | ||
|  | a43c30ef41 | ||
|  | b65bfde84d | ||
|  | c39e6917ac | ||
|  | c79079895f | ||
|  | 4480e631cd | ||
|  | c32661c3ce | ||
|  | d5c06bb812 | ||
|  | 9d5aa36239 | ||
|  | e3050c1777 | ||
|  | 06295ddbdd | ||
|  | e2092bb23c | ||
|  | 528836d0ad | ||
|  | 3511442e43 | ||
|  | d20c53b511 | ||
|  | 091cc122ad | ||
|  | c983abbb9e | ||
|  | a0a81204c2 | ||
|  | 409d4f839c | ||
|  | 0ab36958ea | ||
|  | c2445f43a3 | ||
|  | f3d1c136b7 | ||
|  | dd10a8b09d | ||
|  | dd312366da | ||
|  | d2fe466ef3 | ||
|  | fe5328bfad | ||
|  | c0891dde07 | ||
|  | 0e6d9c1a55 | ||
|  | 5f74a66132 | ||
|  | 46f8b62d5f | ||
|  | 3e3e80c431 | ||
|  | 0486d117e4 | ||
|  | 29981c14da | ||
|  | 98d5efb2c5 | ||
|  | 77a44aafaf | ||
|  | 8278c70716 | ||
|  | ac0955f5e2 | ||
|  | 4130c35ca8 | ||
|  | d440647eb8 | ||
|  | 7e8f2c56c0 | ||
|  | a0880a152f | ||
|  | 4608a9172f | ||
|  | d0e38f7ec0 | ||
|  | a69bdbbbdd | ||
|  | 88c97a2662 | ||
|  | ce9c69ddbc | ||
|  | e430fcb716 | ||
|  | 11a363e632 | ||
|  | 41e63fbdb2 | ||
|  | b543401a5c | ||
|  | 8c4f08fbad | ||
|  | f3081a34d2 | ||
|  | 7b1d3cf392 | ||
|  | 25515b557e | ||
|  | 51625ff86e | ||
|  | 4d8f661726 | ||
|  | efa69a2f66 | ||
|  | 30a6dd78d5 | ||
|  | 9f75836308 | 
							
								
								
									
										9
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								Makefile
									
									
									
									
									
								
							| @@ -174,10 +174,11 @@ ultrix-gcc: | ||||
|  | ||||
| # Rules for making release tarballs | ||||
|  | ||||
| DIRECTORY = Mesa-7.3 | ||||
| LIB_NAME = MesaLib-7.3 | ||||
| DEMO_NAME = MesaDemos-7.3 | ||||
| GLUT_NAME = MesaGLUT-7.3 | ||||
| VERSION=7.4-rc1 | ||||
| DIRECTORY = Mesa-$(VERSION) | ||||
| LIB_NAME = MesaLib-$(VERSION) | ||||
| DEMO_NAME = MesaDemos-$(VERSION) | ||||
| GLUT_NAME = MesaGLUT-$(VERSION) | ||||
|  | ||||
| MAIN_FILES = \ | ||||
| 	$(DIRECTORY)/Makefile*						\ | ||||
|   | ||||
							
								
								
									
										16
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -46,10 +46,14 @@ esac | ||||
| MKDEP_OPTIONS=-fdepend | ||||
| dnl Ask gcc where it's keeping its secret headers | ||||
| if test "x$GCC" = xyes; then | ||||
|     GCC_INCLUDES=`$CC -print-file-name=include` | ||||
|     if test "x$GCC_INCLUDES" != x; then | ||||
|         MKDEP_OPTIONS="$MKDEP_OPTIONS -I$GCC_INCLUDES" | ||||
|     fi | ||||
|     for dir in include include-fixed; do | ||||
|         GCC_INCLUDES=`$CC -print-file-name=$dir` | ||||
|         if test "x$GCC_INCLUDES" != x && \ | ||||
|            test "$GCC_INCLUDES" != "$dir" && \ | ||||
|            test -d "$GCC_INCLUDES"; then | ||||
|             MKDEP_OPTIONS="$MKDEP_OPTIONS -I$GCC_INCLUDES" | ||||
|         fi | ||||
|     done | ||||
| fi | ||||
| AC_SUBST([MKDEP_OPTIONS]) | ||||
|  | ||||
| @@ -83,7 +87,7 @@ dnl Compiler macros | ||||
| DEFINES="" | ||||
| AC_SUBST([DEFINES]) | ||||
| case "$host_os" in | ||||
| *-gnu*) | ||||
| linux*|*-gnu*) | ||||
|     DEFINES="$DEFINES -D_GNU_SOURCE -DPTHREADS" | ||||
|     ;; | ||||
| solaris*) | ||||
| @@ -362,7 +366,7 @@ default_driver="xlib" | ||||
| case "$host_os" in | ||||
| linux*) | ||||
|     case "$host_cpu" in | ||||
|     i*86|x86_64|powerpc*) default_driver="dri";; | ||||
|     i*86|x86_64|powerpc*|sparc*) default_driver="dri";; | ||||
|     esac | ||||
|     ;; | ||||
| *freebsd* | dragonfly*) | ||||
|   | ||||
| @@ -9,9 +9,9 @@ | ||||
| <H1>Downloading</H1> | ||||
|  | ||||
| <p> | ||||
| Current development release: <b>7.3</b> | ||||
| Current stable release: <b>7.4</b> | ||||
| <br> | ||||
| Last stable release: <b>7.2</b> | ||||
| Last unstable/development release: <b>7.3</b> | ||||
| </p> | ||||
|  | ||||
| <p> | ||||
|   | ||||
| @@ -11,6 +11,13 @@ | ||||
| <H1>News</H1> | ||||
|  | ||||
|  | ||||
| <h2>March ??, 2009</h2> | ||||
| <p> | ||||
| <a href="relnotes-7.4.html">Mesa 7.4</a> is released. | ||||
| This is a stable release fixing bugs since the 7.3 release. | ||||
| </p> | ||||
|  | ||||
|  | ||||
| <h2>January 22, 2009</h2> | ||||
| <p> | ||||
| <a href="relnotes-7.3.html">Mesa 7.3</a> is released. | ||||
|   | ||||
| @@ -22,7 +22,7 @@ Some drivers don't support all the features required in OpenGL 2.1. | ||||
| </p> | ||||
| <p> | ||||
| See the <a href="install.html">Compiling/Installing page</a> for prerequisites | ||||
| for DRI ardware acceleration. | ||||
| for DRI hardware acceleration. | ||||
| </p> | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -32,15 +32,27 @@ tbd | ||||
|  | ||||
| <h2>New features</h2> | ||||
| <ul> | ||||
| <li>Added MESA_GLX_FORCE_DIRECT env var for Xlib/software driver | ||||
| <li>GLSL version 1.20 is returnd by the GL_SHADING_LANGUAGE_VERSION query | ||||
| </ul> | ||||
|  | ||||
|  | ||||
| <h2>Bug fixes</h2> | ||||
| <ul> | ||||
| <li>glGetActiveUniform() returned wrong size for some array types | ||||
| <li>Fixed some error checking in glUniform() | ||||
| <li>Fixed a potential glTexImage('proxy target') segfault | ||||
| <li>Fixed bad reference counting for 1D/2D texture arrays | ||||
| <li>Fixed VBO + glPush/PopClientAttrib() bug #19835 | ||||
| <li>Assorted i965 driver bug fixes | ||||
| <li>Fixed a Windows compilation failure in s_triangle.c | ||||
| <li>Fixed a GLSL array indexing bug | ||||
| <li>Fixes for building on Haiku | ||||
| </ul> | ||||
|  | ||||
| <h2>Changes</h2> | ||||
| <ul> | ||||
| <li>Updated GL/glxext.h to version 46 | ||||
| </ul> | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -169,6 +169,20 @@ the Gamma FAQ</a> | ||||
| </p> | ||||
|  | ||||
|  | ||||
| <H2>Direct Rendering Flag</H2> | ||||
| <p> | ||||
| Some applications won't run with indirect rendering contexts (which is | ||||
| what the Xlib driver supports). | ||||
| To force the glXIsDirect() query to return True, set the MESA_GLX_FORCE_DIRECT | ||||
| environment variable. | ||||
| For example: | ||||
| </p> | ||||
| <pre> | ||||
| 	$ export MESA_GLX_FORCE_DIRECT=1 | ||||
| </pre> | ||||
|  | ||||
|  | ||||
|  | ||||
| <H2>Overlay Planes</H2> | ||||
| <p> | ||||
| Hardware overlay planes are supported by the Xlib driver.  To | ||||
| @@ -268,6 +282,8 @@ This extension was added in Mesa 2.6 | ||||
|    MESA_BACK_BUFFER - specifies how to implement the back color buffer (X only) | ||||
|    MESA_PRIVATE_CMAP - force aux/tk libraries to use private colormaps (X only) | ||||
|    MESA_GAMMA - gamma correction coefficients (X only) | ||||
|    MESA_GLX_FORCE_DIRECT - report that the driver is direct rendering, even | ||||
|       though it's not. | ||||
| </pre> | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  6.5.1 | ||||
|  * Version:  7.4 | ||||
|  * | ||||
|  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved. | ||||
|  * | ||||
|   | ||||
| @@ -46,9 +46,9 @@ extern "C" { | ||||
| /*************************************************************/ | ||||
|  | ||||
| /* Header file version number, required by OpenGL ABI for Linux */ | ||||
| /* glext.h last updated 2008/11/14 */ | ||||
| /* glext.h last updated 2009/03/04 */ | ||||
| /* Current version at http://www.opengl.org/registry/ */ | ||||
| #define GL_GLEXT_VERSION 44 | ||||
| #define GL_GLEXT_VERSION 46 | ||||
|  | ||||
| #ifndef GL_VERSION_1_2 | ||||
| #define GL_UNSIGNED_BYTE_3_3_2            0x8032 | ||||
| @@ -3862,6 +3862,22 @@ extern "C" { | ||||
| #define GL_TRANSFORM_FEEDBACK_BINDING_NV  0x8E25 | ||||
| #endif | ||||
|  | ||||
| #ifndef GL_ATI_meminfo | ||||
| #define GL_VBO_FREE_MEMORY_ATI            0x87FB | ||||
| #define GL_TEXTURE_FREE_MEMORY_ATI        0x87FC | ||||
| #define GL_RENDERBUFFER_FREE_MEMORY_ATI   0x87FD | ||||
| #endif | ||||
|  | ||||
| #ifndef GL_AMD_performance_monitor | ||||
| #define GL_COUNTER_TYPE_AMD               0x8BC0 | ||||
| #define GL_COUNTER_RANGE_AMD              0x8BC1 | ||||
| #define GL_UNSIGNED_INT64_AMD             0x8BC2 | ||||
| #define GL_PERCENTAGE_AMD                 0x8BC3 | ||||
| #define GL_PERFMON_RESULT_AVAILABLE_AMD   0x8BC4 | ||||
| #define GL_PERFMON_RESULT_SIZE_AMD        0x8BC5 | ||||
| #define GL_PERFMON_RESULT_AMD             0x8BC6 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /*************************************************************/ | ||||
|  | ||||
| @@ -5268,10 +5284,10 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divi | ||||
| #ifndef GL_ARB_map_buffer_range | ||||
| #define GL_ARB_map_buffer_range 1 | ||||
| #ifdef GL_GLEXT_PROTOTYPES | ||||
| GLAPI void APIENTRY glMapBufferRange (GLenum, GLintptr, GLsizeiptr, GLbitfield); | ||||
| GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum, GLintptr, GLsizeiptr, GLbitfield); | ||||
| GLAPI void APIENTRY glFlushMappedBufferRange (GLenum, GLintptr, GLsizeiptr); | ||||
| #endif /* GL_GLEXT_PROTOTYPES */ | ||||
| typedef void (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); | ||||
| typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); | ||||
| typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); | ||||
| #endif | ||||
|  | ||||
| @@ -8011,6 +8027,22 @@ typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); | ||||
|  | ||||
| #ifndef GL_NV_present_video | ||||
| #define GL_NV_present_video 1 | ||||
| #ifdef GL_GLEXT_PROTOTYPES | ||||
| GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint, GLuint64EXT, GLuint, GLuint, GLenum, GLenum, GLuint, GLuint, GLenum, GLuint, GLuint); | ||||
| GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint, GLuint64EXT, GLuint, GLuint, GLenum, GLenum, GLuint, GLenum, GLuint, GLenum, GLuint, GLenum, GLuint); | ||||
| GLAPI void APIENTRY glGetVideoivNV (GLuint, GLenum, GLint *); | ||||
| GLAPI void APIENTRY glGetVideouivNV (GLuint, GLenum, GLuint *); | ||||
| GLAPI void APIENTRY glGetVideoi64vNV (GLuint, GLenum, GLint64EXT *); | ||||
| GLAPI void APIENTRY glGetVideoui64vNV (GLuint, GLenum, GLuint64EXT *); | ||||
| GLAPI void APIENTRY glVideoParameterivNV (GLuint, GLenum, const GLint *); | ||||
| #endif /* GL_GLEXT_PROTOTYPES */ | ||||
| typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); | ||||
| typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); | ||||
| typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); | ||||
| typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); | ||||
| typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); | ||||
| typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); | ||||
| typedef void (APIENTRYP PFNGLVIDEOPARAMETERIVNVPROC) (GLuint video_slot, GLenum pname, const GLint *params); | ||||
| #endif | ||||
|  | ||||
| #ifndef GL_EXT_transform_feedback | ||||
| @@ -8451,6 +8483,38 @@ typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); | ||||
| typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); | ||||
| #endif | ||||
|  | ||||
| #ifndef GL_ATI_meminfo | ||||
| #define GL_ATI_meminfo 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef GL_AMD_performance_monitor | ||||
| #define GL_AMD_performance_monitor 1 | ||||
| #ifdef GL_GLEXT_PROTOTYPES | ||||
| GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *, GLsizei, GLuint *); | ||||
| GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint, GLint *, GLint *, GLsizei, GLuint *); | ||||
| GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint, GLsizei, GLsizei *, GLchar *); | ||||
| GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint, GLuint, GLsizei, GLsizei *, GLchar *); | ||||
| GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint, GLuint, GLenum, void *); | ||||
| GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei, GLuint *); | ||||
| GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei, GLuint *); | ||||
| GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint, GLboolean, GLuint, GLint, GLuint *); | ||||
| GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint); | ||||
| GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint); | ||||
| GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint, GLenum, GLsizei, GLuint *, GLint *); | ||||
| #endif /* GL_GLEXT_PROTOTYPES */ | ||||
| typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); | ||||
| typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); | ||||
| typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); | ||||
| typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); | ||||
| typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); | ||||
| typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); | ||||
| typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); | ||||
| typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); | ||||
| typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); | ||||
| typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); | ||||
| typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|   | ||||
| @@ -47,9 +47,12 @@ static const char *TexFiles[2] = | ||||
|  | ||||
| static GLuint Program; | ||||
|  | ||||
| static GLfloat Xrot = -90.0, Yrot = .0, Zrot = 0.0; | ||||
| static GLfloat Xrot = 0.0, Yrot = .0, Zrot = 0.0; | ||||
| static GLfloat EyeDist = 10; | ||||
| static GLboolean Anim = GL_TRUE; | ||||
| static GLboolean UseArrays = GL_TRUE; | ||||
|  | ||||
| static GLint VertCoord_attr = -1, TexCoord0_attr = -1, TexCoord1_attr = -1; | ||||
|  | ||||
|  | ||||
| /* value[0] = tex unit */ | ||||
| @@ -60,32 +63,62 @@ static struct uniform_info Uniforms[] = { | ||||
| }; | ||||
|  | ||||
|  | ||||
| static const GLfloat Tex0Coords[4][2] = { | ||||
|    { 0.0, 0.0 }, { 2.0, 0.0 }, { 2.0, 2.0 }, { 0.0, 2.0 } | ||||
| }; | ||||
|  | ||||
| static const GLfloat Tex1Coords[4][2] = { | ||||
|    { 0.0, 0.0 }, { 1.0, 0.0 }, { 1.0, 1.0 }, { 0.0, 1.0 } | ||||
| }; | ||||
|  | ||||
| static const GLfloat VertCoords[4][2] = { | ||||
|    { -3.0, -3.0 }, { 3.0, -3.0 }, { 3.0, 3.0 }, { -3.0, 3.0 } | ||||
| }; | ||||
|  | ||||
|  | ||||
| static void | ||||
| DrawPolygon(GLfloat size) | ||||
| DrawPolygonArray(void) | ||||
| { | ||||
|    glPushMatrix(); | ||||
|    glRotatef(90, 1, 0, 0); | ||||
|    glNormal3f(0, 0, 1); | ||||
|    glBegin(GL_POLYGON); | ||||
|    if (VertCoord_attr >= 0) { | ||||
|       glVertexAttribPointer_func(VertCoord_attr, 2, GL_FLOAT, GL_FALSE, | ||||
|                                  0, VertCoords); | ||||
|       glEnableVertexAttribArray_func(VertCoord_attr); | ||||
|    } | ||||
|    else { | ||||
|       glVertexPointer(2, GL_FLOAT, 0, VertCoords); | ||||
|       glEnable(GL_VERTEX_ARRAY); | ||||
|    } | ||||
|  | ||||
|    glMultiTexCoord2f(GL_TEXTURE0, 0, 0); | ||||
|    glMultiTexCoord2f(GL_TEXTURE1, 0, 0); | ||||
|    glVertex2f(-size, -size); | ||||
|    glVertexAttribPointer_func(TexCoord0_attr, 2, GL_FLOAT, GL_FALSE, | ||||
|                               0, Tex0Coords); | ||||
|    glEnableVertexAttribArray_func(TexCoord0_attr); | ||||
|  | ||||
|    glMultiTexCoord2f(GL_TEXTURE0, 2, 0); | ||||
|    glMultiTexCoord2f(GL_TEXTURE1, 1, 0); | ||||
|    glVertex2f( size, -size); | ||||
|    glVertexAttribPointer_func(TexCoord1_attr, 2, GL_FLOAT, GL_FALSE, | ||||
|                               0, Tex1Coords); | ||||
|    glEnableVertexAttribArray_func(TexCoord1_attr); | ||||
|  | ||||
|    glMultiTexCoord2f(GL_TEXTURE0, 2, 2); | ||||
|    glMultiTexCoord2f(GL_TEXTURE1, 1, 1); | ||||
|    glVertex2f( size,  size); | ||||
|    glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | ||||
| } | ||||
|  | ||||
|    glMultiTexCoord2f(GL_TEXTURE0, 0, 2); | ||||
|    glMultiTexCoord2f(GL_TEXTURE1, 0, 1); | ||||
|    glVertex2f(-size,  size); | ||||
|  | ||||
| static void | ||||
| DrawPolygonVert(void) | ||||
| { | ||||
|    GLuint i; | ||||
|  | ||||
|    glBegin(GL_TRIANGLE_FAN); | ||||
|  | ||||
|    for (i = 0; i < 4; i++) { | ||||
|       glVertexAttrib2fv_func(TexCoord0_attr, Tex0Coords[i]); | ||||
|       glVertexAttrib2fv_func(TexCoord1_attr, Tex1Coords[i]); | ||||
|  | ||||
|       if (VertCoord_attr >= 0) | ||||
|          glVertexAttrib2fv_func(VertCoord_attr, VertCoords[i]); | ||||
|       else | ||||
|          glVertex2fv(VertCoords[i]); | ||||
|    } | ||||
|  | ||||
|    glEnd(); | ||||
|    glPopMatrix(); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -100,7 +133,10 @@ draw(void) | ||||
|       glRotatef(Yrot, 0, 1, 0); | ||||
|       glRotatef(Xrot, 1, 0, 0); | ||||
|  | ||||
|       DrawPolygon(3.0); | ||||
|       if (UseArrays) | ||||
|          DrawPolygonArray(); | ||||
|       else | ||||
|          DrawPolygonVert(); | ||||
|  | ||||
|    glPopMatrix(); | ||||
|  | ||||
| @@ -123,8 +159,11 @@ key(unsigned char k, int x, int y) | ||||
|    (void) x; | ||||
|    (void) y; | ||||
|    switch (k) { | ||||
|    case ' ': | ||||
|    case 'a': | ||||
|       UseArrays = !UseArrays; | ||||
|       printf("Arrays: %d\n", UseArrays); | ||||
|       break; | ||||
|    case ' ': | ||||
|       Anim = !Anim; | ||||
|       if (Anim) | ||||
|          glutIdleFunc(idle); | ||||
| @@ -232,6 +271,13 @@ CreateProgram(const char *vertProgFile, const char *fragProgFile, | ||||
|  | ||||
|    InitUniforms(program, uniforms); | ||||
|  | ||||
|    TexCoord0_attr = glGetAttribLocation_func(program, "TexCoord0"); | ||||
|    TexCoord1_attr = glGetAttribLocation_func(program, "TexCoord1"); | ||||
|    VertCoord_attr = glGetAttribLocation_func(program, "VertCoord"); | ||||
|    printf("TexCoord0_attr = %d\n", TexCoord0_attr); | ||||
|    printf("TexCoord1_attr = %d\n", TexCoord1_attr); | ||||
|    printf("VertCoord_attr = %d\n", VertCoord_attr); | ||||
|  | ||||
|    return program; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,9 +2,13 @@ | ||||
| // Brian Paul | ||||
|  | ||||
|  | ||||
| attribute vec4 TexCoord0, TexCoord1; | ||||
| attribute vec4 VertCoord; | ||||
|  | ||||
| void main()  | ||||
| { | ||||
|    gl_TexCoord[0] = gl_MultiTexCoord0; | ||||
|    gl_TexCoord[1] = gl_MultiTexCoord1; | ||||
|    gl_Position = ftransform(); | ||||
|    gl_TexCoord[0] = TexCoord0; | ||||
|    gl_TexCoord[1] = TexCoord1; | ||||
|    // note: may use gl_Vertex or VertCoord here for testing: | ||||
|    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; | ||||
| } | ||||
|   | ||||
| @@ -46,6 +46,13 @@ static PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_func = NULL; | ||||
| static PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_func = NULL; | ||||
| static PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_func = NULL; | ||||
| static PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_func = NULL; | ||||
| static PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv_func = NULL; | ||||
| static PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv_func = NULL; | ||||
| static PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv_func = NULL; | ||||
| static PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv_func = NULL; | ||||
| static PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer_func = NULL; | ||||
| static PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray_func = NULL; | ||||
| static PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray_func = NULL; | ||||
|  | ||||
| /* OpenGL 2.1 */ | ||||
| static PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv_func = NULL; | ||||
| @@ -126,6 +133,14 @@ GetExtensionFuncs(void) | ||||
|    glVertexAttrib2f_func = (PFNGLVERTEXATTRIB2FPROC) glutGetProcAddress("glVertexAttrib2f"); | ||||
|    glVertexAttrib3f_func = (PFNGLVERTEXATTRIB3FPROC) glutGetProcAddress("glVertexAttrib3f"); | ||||
|    glVertexAttrib4f_func = (PFNGLVERTEXATTRIB4FPROC) glutGetProcAddress("glVertexAttrib4f"); | ||||
|    glVertexAttrib1fv_func = (PFNGLVERTEXATTRIB1FVPROC) glutGetProcAddress("glVertexAttrib1fv"); | ||||
|    glVertexAttrib2fv_func = (PFNGLVERTEXATTRIB2FVPROC) glutGetProcAddress("glVertexAttrib2fv"); | ||||
|    glVertexAttrib3fv_func = (PFNGLVERTEXATTRIB3FVPROC) glutGetProcAddress("glVertexAttrib3fv"); | ||||
|    glVertexAttrib4fv_func = (PFNGLVERTEXATTRIB4FVPROC) glutGetProcAddress("glVertexAttrib4fv"); | ||||
|  | ||||
|    glVertexAttribPointer_func = (PFNGLVERTEXATTRIBPOINTERPROC) glutGetProcAddress("glVertexAttribPointer"); | ||||
|    glEnableVertexAttribArray_func = (PFNGLENABLEVERTEXATTRIBARRAYPROC) glutGetProcAddress("glEnableVertexAttribArray"); | ||||
|    glDisableVertexAttribArray_func = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) glutGetProcAddress("glDisableVertexAttribArray"); | ||||
|  | ||||
|    /* OpenGL 2.1 */ | ||||
|    glUniformMatrix2x3fv_func = (PFNGLUNIFORMMATRIX2X3FVPROC) glutGetProcAddress("glUniformMatrix2x3fv"); | ||||
|   | ||||
| @@ -39,6 +39,9 @@ | ||||
| #include <GL/gl.h> | ||||
| #include <GL/glx.h> | ||||
|  | ||||
| static int is_glx_extension_supported(Display *dpy, const char *query); | ||||
|  | ||||
| static void query_vsync(Display *dpy); | ||||
|  | ||||
| #define BENCHMARK | ||||
|  | ||||
| @@ -560,6 +563,73 @@ make_window( Display *dpy, const char *name, | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Determine whether or not a GLX extension is supported. | ||||
|  */ | ||||
| int | ||||
| is_glx_extension_supported(Display *dpy, const char *query) | ||||
| { | ||||
|    const int scrnum = DefaultScreen(dpy); | ||||
|    const char *glx_extensions = NULL; | ||||
|    const size_t len = strlen(query); | ||||
|    const char *ptr; | ||||
|  | ||||
|    if (glx_extensions == NULL) { | ||||
|       glx_extensions = glXQueryExtensionsString(dpy, scrnum); | ||||
|    } | ||||
|  | ||||
|    ptr = strstr(glx_extensions, query); | ||||
|    return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0'))); | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Attempt to determine whether or not the display is synched to vblank. | ||||
|  */ | ||||
| void | ||||
| query_vsync(Display *dpy) | ||||
| { | ||||
|    int interval = 0; | ||||
|  | ||||
|  | ||||
| #ifdef GLX_MESA_swap_control | ||||
|    if ((interval <= 0) | ||||
|        && is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) { | ||||
|       PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA = | ||||
|           (PFNGLXGETSWAPINTERVALMESAPROC) | ||||
|           glXGetProcAddressARB((const GLubyte *) "glXGetSwapIntervalMESA"); | ||||
|  | ||||
|       interval = (*pglXGetSwapIntervalMESA)(); | ||||
|    } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef GLX_SGI_video_sync | ||||
|    if ((interval <= 0) | ||||
|        && is_glx_extension_supported(dpy, "GLX_SGI_video_sync")) { | ||||
|       PFNGLXGETVIDEOSYNCSGIPROC pglXGetVideoSyncSGI = | ||||
|           (PFNGLXGETVIDEOSYNCSGIPROC) | ||||
|           glXGetProcAddressARB((const GLubyte *) "glXGetVideoSyncSGI"); | ||||
|       unsigned count; | ||||
|  | ||||
|       if ((*pglXGetVideoSyncSGI)(& count) == 0) { | ||||
|          interval = (int) count; | ||||
|       } | ||||
|    } | ||||
| #endif | ||||
|  | ||||
|  | ||||
|    if (interval > 0) { | ||||
|       printf("Running synchronized to the vertical refresh.  The framerate should be\n"); | ||||
|       if (interval == 1) { | ||||
|          printf("approximately the same as the monitor refresh rate.\n"); | ||||
|       } else if (interval > 1) { | ||||
|          printf("approximately 1/%d the monitor refresh rate.\n", | ||||
|                 interval); | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Handle one X event. | ||||
|  * \return NOP, EXIT or DRAW | ||||
| @@ -567,6 +637,9 @@ make_window( Display *dpy, const char *name, | ||||
| static int | ||||
| handle_event(Display *dpy, Window win, XEvent *event) | ||||
| { | ||||
|    (void) dpy; | ||||
|    (void) win; | ||||
|  | ||||
|    switch (event->type) { | ||||
|    case Expose: | ||||
|       return DRAW; | ||||
| @@ -686,6 +759,7 @@ main(int argc, char *argv[]) | ||||
|    make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx); | ||||
|    XMapWindow(dpy, win); | ||||
|    glXMakeCurrent(dpy, win, ctx); | ||||
|    query_vsync(dpy); | ||||
|  | ||||
|    if (printInfo) { | ||||
|       printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER)); | ||||
|   | ||||
| @@ -178,6 +178,7 @@ int main( int argc, char *argv[] ) | ||||
|    glColor3f( 0.0, 1.0, 1.0 ); | ||||
|    glRectf( -0.75, -0.75, 0.75, 0.75 ); | ||||
|    glFlush(); | ||||
|    glXWaitGL(); | ||||
|  | ||||
|    XMapWindow( dpy, win ); | ||||
|  | ||||
|   | ||||
| @@ -286,7 +286,7 @@ EventLoop(void) | ||||
|                         XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat); | ||||
|                         switch (keySym) { | ||||
|                            case XK_Escape: | ||||
|                               exit(0); | ||||
|                               return; | ||||
|                               break; | ||||
|                            case XK_d: | ||||
|                            case XK_D: | ||||
|   | ||||
| @@ -60,6 +60,9 @@ struct __GLXDRIdisplayPrivateRec { | ||||
|     int driMajor; | ||||
|     int driMinor; | ||||
|     int driPatch; | ||||
|  | ||||
|     unsigned long configureSeqno; | ||||
|     Bool (*oldConfigProc)(Display *, XEvent *, xEvent *); | ||||
| }; | ||||
|  | ||||
| struct __GLXDRIcontextPrivateRec { | ||||
| @@ -73,6 +76,10 @@ struct __GLXDRIdrawablePrivateRec { | ||||
|     __DRIbuffer buffers[5]; | ||||
|     int bufferCount; | ||||
|     int width, height; | ||||
|     unsigned long configureSeqno; | ||||
|     int have_back; | ||||
|     int have_front; | ||||
|     int have_fake_front; | ||||
| }; | ||||
|  | ||||
| static void dri2DestroyContext(__GLXDRIcontext *context, | ||||
| @@ -166,6 +173,8 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc, | ||||
|     pdraw->base.xDrawable = xDrawable; | ||||
|     pdraw->base.drawable = drawable; | ||||
|     pdraw->base.psc = psc; | ||||
|     pdraw->bufferCount = 0; | ||||
|     pdraw->configureSeqno = ~0; | ||||
|  | ||||
|     DRI2CreateDrawable(psc->dpy, xDrawable); | ||||
|  | ||||
| @@ -190,6 +199,10 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, | ||||
|     XRectangle xrect; | ||||
|     XserverRegion region; | ||||
|  | ||||
|     /* Check we have the right attachments */ | ||||
|     if (!(priv->have_front && priv->have_back)) | ||||
|     	return; | ||||
|  | ||||
|     xrect.x = x; | ||||
|     xrect.y = priv->height - y - height; | ||||
|     xrect.width = width; | ||||
| @@ -208,6 +221,47 @@ static void dri2SwapBuffers(__GLXDRIdrawable *pdraw) | ||||
|     dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); | ||||
| } | ||||
|  | ||||
| static void dri2WaitX(__GLXDRIdrawable *pdraw) | ||||
| { | ||||
|     __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; | ||||
|     XRectangle xrect; | ||||
|     XserverRegion region; | ||||
|  | ||||
|     /* Check we have the right attachments */ | ||||
|     if (!(priv->have_fake_front && priv->have_front)) | ||||
|     	return; | ||||
|  | ||||
|     xrect.x = 0; | ||||
|     xrect.y = 0; | ||||
|     xrect.width = priv->width; | ||||
|     xrect.height = priv->height; | ||||
|  | ||||
|     region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1); | ||||
|     DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region, | ||||
| 		   DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); | ||||
|     XFixesDestroyRegion(pdraw->psc->dpy, region); | ||||
| } | ||||
|  | ||||
| static void dri2WaitGL(__GLXDRIdrawable *pdraw) | ||||
| { | ||||
|     __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; | ||||
|     XRectangle xrect; | ||||
|     XserverRegion region; | ||||
|  | ||||
|     if (!(priv->have_fake_front && priv->have_front)) | ||||
|     	return; | ||||
|  | ||||
|     xrect.x = 0; | ||||
|     xrect.y = 0; | ||||
|     xrect.width = priv->width; | ||||
|     xrect.height = priv->height; | ||||
|  | ||||
|     region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1); | ||||
|     DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region, | ||||
| 		   DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); | ||||
|     XFixesDestroyRegion(pdraw->psc->dpy, region); | ||||
| } | ||||
|  | ||||
| static void dri2DestroyScreen(__GLXscreenConfigs *psc) | ||||
| { | ||||
|     /* Free the direct rendering per screen data */ | ||||
| @@ -223,9 +277,30 @@ dri2GetBuffers(__DRIdrawable *driDrawable, | ||||
| 	       int *out_count, void *loaderPrivate) | ||||
| { | ||||
|     __GLXDRIdrawablePrivate *pdraw = loaderPrivate; | ||||
|     __GLXdisplayPrivate *dpyPriv = __glXInitialize(pdraw->base.psc->dpy); | ||||
|     __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display; | ||||
|     DRI2Buffer *buffers; | ||||
|     int i; | ||||
|  | ||||
|     /** | ||||
|      * Check if a ConfigureNotify has come in since we last asked for the | ||||
|      * buffers associated with this drawable.  If not, we can assume that they're | ||||
|      * the same set at glViewport time, and save a synchronous round-trip to the | ||||
|      * X Server. | ||||
|      */ | ||||
|     if (pdraw->configureSeqno == pdp->configureSeqno && | ||||
| 	count == pdraw->bufferCount) { | ||||
| 	for (i = 0; i < count; i++) { | ||||
| 	    if (pdraw->buffers[i].attachment != attachments[i]) | ||||
| 		break; | ||||
| 	} | ||||
| 	if (i == count) { | ||||
| 	    *out_count = pdraw->bufferCount; | ||||
| 	    return pdraw->buffers; | ||||
| 	} | ||||
|     } | ||||
|     pdraw->configureSeqno = pdp->configureSeqno; | ||||
|  | ||||
|     buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable, | ||||
| 			     width, height, attachments, count, out_count); | ||||
|     if (buffers == NULL) | ||||
| @@ -233,6 +308,10 @@ dri2GetBuffers(__DRIdrawable *driDrawable, | ||||
|  | ||||
|     pdraw->width = *width; | ||||
|     pdraw->height = *height; | ||||
|     pdraw->bufferCount = *out_count; | ||||
|     pdraw->have_front = 0; | ||||
|     pdraw->have_fake_front = 0; | ||||
|     pdraw->have_back = 0; | ||||
|  | ||||
|     /* This assumes the DRI2 buffer attachment tokens matches the | ||||
|      * __DRIbuffer tokens. */ | ||||
| @@ -242,6 +321,12 @@ dri2GetBuffers(__DRIdrawable *driDrawable, | ||||
| 	pdraw->buffers[i].pitch = buffers[i].pitch; | ||||
| 	pdraw->buffers[i].cpp = buffers[i].cpp; | ||||
| 	pdraw->buffers[i].flags = buffers[i].flags; | ||||
| 	if (pdraw->buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT) | ||||
| 	    pdraw->have_front = 1; | ||||
| 	if (pdraw->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT) | ||||
| 	    pdraw->have_fake_front = 1; | ||||
| 	if (pdraw->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) | ||||
| 	    pdraw->have_back = 1; | ||||
|     } | ||||
|  | ||||
|     Xfree(buffers); | ||||
| @@ -332,6 +417,8 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, | ||||
|     psp->createContext = dri2CreateContext; | ||||
|     psp->createDrawable = dri2CreateDrawable; | ||||
|     psp->swapBuffers = dri2SwapBuffers; | ||||
|     psp->waitGL = dri2WaitGL; | ||||
|     psp->waitX = dri2WaitX; | ||||
|  | ||||
|     /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always | ||||
|      * available.*/ | ||||
| @@ -359,6 +446,28 @@ static void dri2DestroyDisplay(__GLXDRIdisplay *dpy) | ||||
|     Xfree(dpy); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Makes a note on receiving ConfigureNotify that we need to re-check the | ||||
|  * DRI2 buffers, as window sizes may have resulted in reallocation. | ||||
|  */ | ||||
| static Bool dri2ConfigureNotifyProc(Display *dpy, XEvent *re, xEvent *event) | ||||
| { | ||||
|     __GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy); | ||||
|     __GLXDRIdisplayPrivate *pdp; | ||||
|     Bool ret; | ||||
|  | ||||
|     /* We should always be able to find our pdp, as it only gets torn down | ||||
|      * when the Display is torn down. | ||||
|      */ | ||||
|     pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display; | ||||
|  | ||||
|     ret = pdp->oldConfigProc(dpy, re, event); | ||||
|  | ||||
|     pdp->configureSeqno = re->xconfigure.serial; | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Allocate, initialize and return a __DRIdisplayPrivate object. | ||||
|  * This is called from __glXInitialize() when we are given a new | ||||
| @@ -381,7 +490,11 @@ _X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy) | ||||
| 	return NULL; | ||||
|     } | ||||
|  | ||||
|     pdp->oldConfigProc = XESetWireToEvent(dpy, ConfigureNotify, | ||||
| 					  dri2ConfigureNotifyProc); | ||||
|  | ||||
|     pdp->driPatch = 0; | ||||
|     pdp->configureSeqno = 0; | ||||
|  | ||||
|     pdp->base.destroyDisplay = dri2DestroyDisplay; | ||||
|     pdp->base.createScreen = dri2CreateScreen; | ||||
|   | ||||
| @@ -655,6 +655,8 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen, | ||||
|     psp->createContext = driCreateContext; | ||||
|     psp->createDrawable = driCreateDrawable; | ||||
|     psp->swapBuffers = driSwapBuffers; | ||||
|     psp->waitX = NULL; | ||||
|     psp->waitGL = NULL; | ||||
|  | ||||
|     return psp; | ||||
| } | ||||
|   | ||||
| @@ -139,6 +139,8 @@ struct __GLXDRIscreenRec { | ||||
|     void (*swapBuffers)(__GLXDRIdrawable *pdraw); | ||||
|     void (*copySubBuffer)(__GLXDRIdrawable *pdraw, | ||||
| 			  int x, int y, int width, int height); | ||||
|     void (*waitX)(__GLXDRIdrawable *pdraw); | ||||
|     void (*waitGL)(__GLXDRIdrawable *pdraw); | ||||
| }; | ||||
|  | ||||
| struct __GLXDRIcontextRec { | ||||
| @@ -602,6 +604,7 @@ extern void __glXSendLargeCommand(__GLXcontext *, const GLvoid *, GLint, | ||||
| 				  const GLvoid *, GLint); | ||||
|  | ||||
| /* Initialize the GLX extension for dpy */ | ||||
| extern __GLXdisplayPrivate * __glXGetPrivateFromDisplay(Display *dpy); | ||||
| extern __GLXdisplayPrivate *__glXInitialize(Display*); | ||||
|  | ||||
| /************************************************************************/ | ||||
|   | ||||
| @@ -611,11 +611,15 @@ PUBLIC void glXWaitGL(void) | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|     if (gc->driContext) { | ||||
| /* This bit of ugliness unwraps the glFinish function */ | ||||
| #ifdef glFinish | ||||
| #undef glFinish | ||||
| #endif | ||||
| 	glFinish(); | ||||
|     	int screen; | ||||
|     	__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen); | ||||
|  | ||||
|     	if ( pdraw != NULL ) { | ||||
| 	    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); | ||||
| 	    glFlush(); | ||||
| 	    if (psc->driScreen->waitGL != NULL) | ||||
| 	    	(*psc->driScreen->waitGL)(pdraw); | ||||
| 	} | ||||
| 	return; | ||||
|     } | ||||
| #endif | ||||
| @@ -647,7 +651,15 @@ PUBLIC void glXWaitX(void) | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|     if (gc->driContext) { | ||||
| 	XSync(dpy, False); | ||||
|     	int screen; | ||||
|     	__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen); | ||||
|  | ||||
|     	if ( pdraw != NULL ) { | ||||
| 	    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); | ||||
| 	    if (psc->driScreen->waitX != NULL) | ||||
| 	    	(*psc->driScreen->waitX)(pdraw); | ||||
| 	} else | ||||
| 	    XSync(dpy, False); | ||||
| 	return; | ||||
|     } | ||||
| #endif | ||||
|   | ||||
| @@ -1063,31 +1063,31 @@ void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped, | ||||
|       ctx->Texture.CurrentUnit = i; | ||||
|  | ||||
|       if ( (targets & DRI_TEXMGR_DO_TEXTURE_1D) != 0 ) { | ||||
| 	 texObj = ctx->Texture.Unit[i].Current1D; | ||||
| 	 texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_1D_INDEX]; | ||||
| 	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_1D, texObj ); | ||||
| 	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); | ||||
|       } | ||||
|  | ||||
|       if ( (targets & DRI_TEXMGR_DO_TEXTURE_2D) != 0 ) { | ||||
| 	 texObj = ctx->Texture.Unit[i].Current2D; | ||||
| 	 texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_2D_INDEX]; | ||||
| 	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_2D, texObj ); | ||||
| 	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); | ||||
|       } | ||||
|  | ||||
|       if ( (targets & DRI_TEXMGR_DO_TEXTURE_3D) != 0 ) { | ||||
| 	 texObj = ctx->Texture.Unit[i].Current3D; | ||||
| 	 texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_3D_INDEX]; | ||||
| 	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_3D, texObj ); | ||||
| 	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); | ||||
|       } | ||||
|  | ||||
|       if ( (targets & DRI_TEXMGR_DO_TEXTURE_CUBE) != 0 ) { | ||||
| 	 texObj = ctx->Texture.Unit[i].CurrentCubeMap; | ||||
| 	 texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_CUBE_INDEX]; | ||||
| 	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_CUBE_MAP_ARB, texObj ); | ||||
| 	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); | ||||
|       } | ||||
|  | ||||
|       if ( (targets & DRI_TEXMGR_DO_TEXTURE_RECT) != 0 ) { | ||||
| 	 texObj = ctx->Texture.Unit[i].CurrentRect; | ||||
| 	 texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_RECT_INDEX]; | ||||
| 	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_RECTANGLE_NV, texObj ); | ||||
| 	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); | ||||
|       } | ||||
|   | ||||
| @@ -400,19 +400,19 @@ void gammaInitTextureObjects( GLcontext *ctx ) | ||||
|  | ||||
|    ctx->Texture.CurrentUnit = 0; | ||||
|  | ||||
|    texObj = ctx->Texture.Unit[0].Current1D; | ||||
|    texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_1D_INDEX]; | ||||
|    gammaBindTexture( ctx, GL_TEXTURE_1D, texObj ); | ||||
|  | ||||
|    texObj = ctx->Texture.Unit[0].Current2D; | ||||
|    texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; | ||||
|    gammaBindTexture( ctx, GL_TEXTURE_2D, texObj ); | ||||
|  | ||||
| #if 0 | ||||
|    ctx->Texture.CurrentUnit = 1; | ||||
|  | ||||
|    texObj = ctx->Texture.Unit[1].Current1D; | ||||
|    texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_1D_INDEX]; | ||||
|    gammaBindTexture( ctx, GL_TEXTURE_1D, texObj ); | ||||
|  | ||||
|    texObj = ctx->Texture.Unit[1].Current2D; | ||||
|    texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_2D_INDEX]; | ||||
|    gammaBindTexture( ctx, GL_TEXTURE_2D, texObj ); | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -18,6 +18,7 @@ DRIVER_SOURCES = \ | ||||
| 	intel_regions.c \ | ||||
| 	intel_buffer_objects.c \ | ||||
| 	intel_batchbuffer.c \ | ||||
| 	intel_clear.c \ | ||||
| 	intel_mipmap_tree.c \ | ||||
| 	i915_tex_layout.c \ | ||||
| 	intel_tex_layout.c \ | ||||
| @@ -34,6 +35,7 @@ DRIVER_SOURCES = \ | ||||
| 	intel_pixel_read.c \ | ||||
| 	intel_buffers.c \ | ||||
| 	intel_blit.c \ | ||||
| 	intel_swapbuffers.c \ | ||||
| 	i915_tex.c \ | ||||
| 	i915_texstate.c \ | ||||
| 	i915_context.c \ | ||||
|   | ||||
| @@ -41,6 +41,7 @@ | ||||
| #include "intel_fbo.h" | ||||
| #include "intel_screen.h" | ||||
| #include "intel_batchbuffer.h" | ||||
| #include "intel_buffers.h" | ||||
|  | ||||
| #include "i915_context.h" | ||||
| #include "i915_reg.h" | ||||
| @@ -301,6 +302,74 @@ i915DepthMask(GLcontext * ctx, GLboolean flag) | ||||
|       i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Update the viewport transformation matrix.  Depends on: | ||||
|  *  - viewport pos/size | ||||
|  *  - depthrange | ||||
|  *  - window pos/size or FBO size | ||||
|  */ | ||||
| void | ||||
| intelCalcViewport(GLcontext * ctx) | ||||
| { | ||||
|    struct intel_context *intel = intel_context(ctx); | ||||
|    const GLfloat *v = ctx->Viewport._WindowMap.m; | ||||
|    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; | ||||
|    GLfloat *m = intel->ViewportMatrix.m; | ||||
|    GLfloat yScale, yBias; | ||||
|  | ||||
|    if (ctx->DrawBuffer->Name) { | ||||
|       /* User created FBO */ | ||||
|       struct intel_renderbuffer *irb | ||||
|          = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); | ||||
|       if (irb && !irb->RenderToTexture) { | ||||
|          /* y=0=top */ | ||||
|          yScale = -1.0; | ||||
|          yBias = irb->Base.Height; | ||||
|       } | ||||
|       else { | ||||
|          /* y=0=bottom */ | ||||
|          yScale = 1.0; | ||||
|          yBias = 0.0; | ||||
|       } | ||||
|    } | ||||
|    else { | ||||
|       /* window buffer, y=0=top */ | ||||
|       yScale = -1.0; | ||||
|       yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F; | ||||
|    } | ||||
|  | ||||
|    m[MAT_SX] = v[MAT_SX]; | ||||
|    m[MAT_TX] = v[MAT_TX]; | ||||
|  | ||||
|    m[MAT_SY] = v[MAT_SY] * yScale; | ||||
|    m[MAT_TY] = v[MAT_TY] * yScale + yBias; | ||||
|  | ||||
|    m[MAT_SZ] = v[MAT_SZ] * depthScale; | ||||
|    m[MAT_TZ] = v[MAT_TZ] * depthScale; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** Called from ctx->Driver.Viewport() */ | ||||
| static void | ||||
| intelViewport(GLcontext * ctx, | ||||
|               GLint x, GLint y, GLsizei width, GLsizei height) | ||||
| { | ||||
|    intelCalcViewport(ctx); | ||||
|  | ||||
|    intel_viewport(ctx, x, y, width, height); | ||||
| } | ||||
|  | ||||
|  | ||||
| /** Called from ctx->Driver.DepthRange() */ | ||||
| static void | ||||
| intelDepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) | ||||
| { | ||||
|    intelCalcViewport(ctx); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ============================================================= | ||||
|  * Polygon stipple | ||||
|  * | ||||
| @@ -964,6 +1033,8 @@ i915InitStateFunctions(struct dd_function_table *functions) | ||||
|    functions->StencilFuncSeparate = i915StencilFuncSeparate; | ||||
|    functions->StencilMaskSeparate = i915StencilMaskSeparate; | ||||
|    functions->StencilOpSeparate = i915StencilOpSeparate; | ||||
|    functions->DepthRange = intelDepthRange; | ||||
|    functions->Viewport = intelViewport; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/mesa/drivers/dri/i915/intel_clear.c
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								src/mesa/drivers/dri/i915/intel_clear.c
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ../intel/intel_clear.c | ||||
| @@ -35,7 +35,6 @@ | ||||
|  | ||||
| #include "intel_screen.h" | ||||
| #include "intel_context.h" | ||||
| #include "intel_fbo.h" | ||||
| #include "intel_regions.h" | ||||
| #include "swrast/swrast.h" | ||||
|  | ||||
| @@ -216,67 +215,6 @@ intelClearColor(GLcontext * ctx, const GLfloat color[4]) | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Update the viewport transformation matrix.  Depends on: | ||||
|  *  - viewport pos/size | ||||
|  *  - depthrange | ||||
|  *  - window pos/size or FBO size | ||||
|  */ | ||||
| static void | ||||
| intelCalcViewport(GLcontext * ctx) | ||||
| { | ||||
|    struct intel_context *intel = intel_context(ctx); | ||||
|    const GLfloat *v = ctx->Viewport._WindowMap.m; | ||||
|    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; | ||||
|    GLfloat *m = intel->ViewportMatrix.m; | ||||
|    GLfloat yScale, yBias; | ||||
|  | ||||
|    if (ctx->DrawBuffer->Name) { | ||||
|       /* User created FBO */ | ||||
|       struct intel_renderbuffer *irb | ||||
|          = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); | ||||
|       if (irb && !irb->RenderToTexture) { | ||||
|          /* y=0=top */ | ||||
|          yScale = -1.0; | ||||
|          yBias = irb->Base.Height; | ||||
|       } | ||||
|       else { | ||||
|          /* y=0=bottom */ | ||||
|          yScale = 1.0; | ||||
|          yBias = 0.0; | ||||
|       } | ||||
|    } | ||||
|    else { | ||||
|       /* window buffer, y=0=top */ | ||||
|       yScale = -1.0; | ||||
|       yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F; | ||||
|    } | ||||
|  | ||||
|    m[MAT_SX] = v[MAT_SX]; | ||||
|    m[MAT_TX] = v[MAT_TX]; | ||||
|  | ||||
|    m[MAT_SY] = v[MAT_SY] * yScale; | ||||
|    m[MAT_TY] = v[MAT_TY] * yScale + yBias; | ||||
|  | ||||
|    m[MAT_SZ] = v[MAT_SZ] * depthScale; | ||||
|    m[MAT_TZ] = v[MAT_TZ] * depthScale; | ||||
| } | ||||
|  | ||||
| static void | ||||
| intelViewport(GLcontext * ctx, | ||||
|               GLint x, GLint y, GLsizei width, GLsizei height) | ||||
| { | ||||
|    intelCalcViewport(ctx); | ||||
|  | ||||
|    intel_viewport(ctx, x, y, width, height); | ||||
| } | ||||
|  | ||||
| static void | ||||
| intelDepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) | ||||
| { | ||||
|    intelCalcViewport(ctx); | ||||
| } | ||||
|  | ||||
| /* Fallback to swrast for select and feedback. | ||||
|  */ | ||||
| static void | ||||
| @@ -291,7 +229,5 @@ void | ||||
| intelInitStateFuncs(struct dd_function_table *functions) | ||||
| { | ||||
|    functions->RenderMode = intelRenderMode; | ||||
|    functions->Viewport = intelViewport; | ||||
|    functions->DepthRange = intelDepthRange; | ||||
|    functions->ClearColor = intelClearColor; | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/mesa/drivers/dri/i915/intel_swapbuffers.c
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								src/mesa/drivers/dri/i915/intel_swapbuffers.c
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ../intel/intel_swapbuffers.c | ||||
| @@ -989,7 +989,7 @@ intelChooseRenderState(GLcontext * ctx) | ||||
|             intel->draw_tri = intel_fallback_tri; | ||||
|  | ||||
|          if (flags & DD_TRI_SMOOTH) { | ||||
| 	    if (intel->strict_conformance) | ||||
| 	    if (intel->conformance_mode > 0) | ||||
| 	       intel->draw_tri = intel_fallback_tri; | ||||
| 	 } | ||||
|  | ||||
| @@ -1001,7 +1001,7 @@ intelChooseRenderState(GLcontext * ctx) | ||||
| 	 } | ||||
|  | ||||
| 	 if (flags & DD_POINT_SMOOTH) { | ||||
| 	    if (intel->strict_conformance) | ||||
| 	    if (intel->conformance_mode > 0) | ||||
| 	       intel->draw_point = intel_fallback_point; | ||||
| 	 } | ||||
|  | ||||
|   | ||||
| @@ -9,6 +9,7 @@ DRIVER_SOURCES = \ | ||||
| 	intel_blit.c \ | ||||
| 	intel_buffer_objects.c \ | ||||
| 	intel_buffers.c \ | ||||
| 	intel_clear.c \ | ||||
| 	intel_context.c \ | ||||
| 	intel_decode.c \ | ||||
| 	intel_depthstencil.c \ | ||||
| @@ -22,6 +23,7 @@ DRIVER_SOURCES = \ | ||||
| 	intel_pixel_copy.c \ | ||||
| 	intel_pixel_draw.c \ | ||||
| 	intel_state.c \ | ||||
| 	intel_swapbuffers.c \ | ||||
| 	intel_tex.c \ | ||||
| 	intel_tex_copy.c \ | ||||
| 	intel_tex_format.c \ | ||||
| @@ -49,7 +51,6 @@ DRIVER_SOURCES = \ | ||||
| 	brw_gs.c \ | ||||
| 	brw_gs_emit.c \ | ||||
| 	brw_gs_state.c \ | ||||
| 	brw_metaops.c \ | ||||
| 	brw_misc_state.c \ | ||||
| 	brw_program.c \ | ||||
| 	brw_queryobj.c \ | ||||
|   | ||||
| @@ -83,59 +83,60 @@ struct brw_cc_unit_key { | ||||
| static void | ||||
| cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key) | ||||
| { | ||||
|    struct gl_stencil_attrib *stencil = brw->attribs.Stencil; | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    const unsigned back = ctx->Stencil._BackFace; | ||||
|  | ||||
|    memset(key, 0, sizeof(*key)); | ||||
|  | ||||
|    key->stencil = stencil->Enabled; | ||||
|    key->stencil_two_side = stencil->_TestTwoSide; | ||||
|    key->stencil = ctx->Stencil.Enabled; | ||||
|    key->stencil_two_side = ctx->Stencil._TestTwoSide; | ||||
|  | ||||
|    if (key->stencil) { | ||||
|       key->stencil_func[0] = stencil->Function[0]; | ||||
|       key->stencil_fail_op[0] = stencil->FailFunc[0]; | ||||
|       key->stencil_pass_depth_fail_op[0] = stencil->ZFailFunc[0]; | ||||
|       key->stencil_pass_depth_pass_op[0] = stencil->ZPassFunc[0]; | ||||
|       key->stencil_ref[0] = stencil->Ref[0]; | ||||
|       key->stencil_write_mask[0] = stencil->WriteMask[0]; | ||||
|       key->stencil_test_mask[0] = stencil->ValueMask[0]; | ||||
|       key->stencil_func[0] = ctx->Stencil.Function[0]; | ||||
|       key->stencil_fail_op[0] = ctx->Stencil.FailFunc[0]; | ||||
|       key->stencil_pass_depth_fail_op[0] = ctx->Stencil.ZFailFunc[0]; | ||||
|       key->stencil_pass_depth_pass_op[0] = ctx->Stencil.ZPassFunc[0]; | ||||
|       key->stencil_ref[0] = ctx->Stencil.Ref[0]; | ||||
|       key->stencil_write_mask[0] = ctx->Stencil.WriteMask[0]; | ||||
|       key->stencil_test_mask[0] = ctx->Stencil.ValueMask[0]; | ||||
|    } | ||||
|    if (key->stencil_two_side) { | ||||
|       key->stencil_func[1] = stencil->Function[1]; | ||||
|       key->stencil_fail_op[1] = stencil->FailFunc[1]; | ||||
|       key->stencil_pass_depth_fail_op[1] = stencil->ZFailFunc[1]; | ||||
|       key->stencil_pass_depth_pass_op[1] = stencil->ZPassFunc[1]; | ||||
|       key->stencil_ref[1] = stencil->Ref[1]; | ||||
|       key->stencil_write_mask[1] = stencil->WriteMask[1]; | ||||
|       key->stencil_test_mask[1] = stencil->ValueMask[1]; | ||||
|       key->stencil_func[1] = ctx->Stencil.Function[back]; | ||||
|       key->stencil_fail_op[1] = ctx->Stencil.FailFunc[back]; | ||||
|       key->stencil_pass_depth_fail_op[1] = ctx->Stencil.ZFailFunc[back]; | ||||
|       key->stencil_pass_depth_pass_op[1] = ctx->Stencil.ZPassFunc[back]; | ||||
|       key->stencil_ref[1] = ctx->Stencil.Ref[back]; | ||||
|       key->stencil_write_mask[1] = ctx->Stencil.WriteMask[back]; | ||||
|       key->stencil_test_mask[1] = ctx->Stencil.ValueMask[back]; | ||||
|    } | ||||
|  | ||||
|    if (brw->attribs.Color->_LogicOpEnabled) | ||||
|       key->logic_op = brw->attribs.Color->LogicOp; | ||||
|    if (ctx->Color._LogicOpEnabled) | ||||
|       key->logic_op = ctx->Color.LogicOp; | ||||
|    else | ||||
|       key->logic_op = GL_COPY; | ||||
|  | ||||
|    key->color_blend = brw->attribs.Color->BlendEnabled; | ||||
|    key->color_blend = ctx->Color.BlendEnabled; | ||||
|    if (key->color_blend) { | ||||
|       key->blend_eq_rgb = brw->attribs.Color->BlendEquationRGB; | ||||
|       key->blend_eq_a = brw->attribs.Color->BlendEquationA; | ||||
|       key->blend_src_rgb = brw->attribs.Color->BlendSrcRGB; | ||||
|       key->blend_dst_rgb = brw->attribs.Color->BlendDstRGB; | ||||
|       key->blend_src_a = brw->attribs.Color->BlendSrcA; | ||||
|       key->blend_dst_a = brw->attribs.Color->BlendDstA; | ||||
|       key->blend_eq_rgb = ctx->Color.BlendEquationRGB; | ||||
|       key->blend_eq_a = ctx->Color.BlendEquationA; | ||||
|       key->blend_src_rgb = ctx->Color.BlendSrcRGB; | ||||
|       key->blend_dst_rgb = ctx->Color.BlendDstRGB; | ||||
|       key->blend_src_a = ctx->Color.BlendSrcA; | ||||
|       key->blend_dst_a = ctx->Color.BlendDstA; | ||||
|    } | ||||
|  | ||||
|    key->alpha_enabled = brw->attribs.Color->AlphaEnabled; | ||||
|    key->alpha_enabled = ctx->Color.AlphaEnabled; | ||||
|    if (key->alpha_enabled) { | ||||
|       key->alpha_func = brw->attribs.Color->AlphaFunc; | ||||
|       key->alpha_ref = brw->attribs.Color->AlphaRef; | ||||
|       key->alpha_func = ctx->Color.AlphaFunc; | ||||
|       key->alpha_ref = ctx->Color.AlphaRef; | ||||
|    } | ||||
|  | ||||
|    key->dither = brw->attribs.Color->DitherFlag; | ||||
|    key->dither = ctx->Color.DitherFlag; | ||||
|  | ||||
|    key->depth_test = brw->attribs.Depth->Test; | ||||
|    key->depth_test = ctx->Depth.Test; | ||||
|    if (key->depth_test) { | ||||
|       key->depth_func = brw->attribs.Depth->Func; | ||||
|       key->depth_write = brw->attribs.Depth->Mask; | ||||
|       key->depth_func = ctx->Depth.Func; | ||||
|       key->depth_write = ctx->Depth.Mask; | ||||
|    } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -145,14 +145,14 @@ static void upload_clip_prog(struct brw_context *brw) | ||||
|    /* CACHE_NEW_VS_PROG */ | ||||
|    key.attrs = brw->vs.prog_data->outputs_written; | ||||
|    /* _NEW_LIGHT */ | ||||
|    key.do_flat_shading = (brw->attribs.Light->ShadeModel == GL_FLAT); | ||||
|    key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT); | ||||
|    /* _NEW_TRANSFORM */ | ||||
|    key.nr_userclip = brw_count_bits(brw->attribs.Transform->ClipPlanesEnabled); | ||||
|    key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled); | ||||
|    key.clip_mode = BRW_CLIPMODE_NORMAL; | ||||
|  | ||||
|    /* _NEW_POLYGON */ | ||||
|    if (key.primitive == GL_TRIANGLES) { | ||||
|       if (brw->attribs.Polygon->CullFaceMode == GL_FRONT_AND_BACK)  | ||||
|       if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)  | ||||
| 	 key.clip_mode = BRW_CLIPMODE_REJECT_ALL; | ||||
|       else { | ||||
| 	 GLuint fill_front = CLIP_CULL; | ||||
| @@ -160,44 +160,44 @@ static void upload_clip_prog(struct brw_context *brw) | ||||
| 	 GLuint offset_front = 0; | ||||
| 	 GLuint offset_back = 0; | ||||
|  | ||||
| 	 if (!brw->attribs.Polygon->CullFlag || | ||||
| 	     brw->attribs.Polygon->CullFaceMode != GL_FRONT) { | ||||
| 	    switch (brw->attribs.Polygon->FrontMode) { | ||||
| 	 if (!ctx->Polygon.CullFlag || | ||||
| 	     ctx->Polygon.CullFaceMode != GL_FRONT) { | ||||
| 	    switch (ctx->Polygon.FrontMode) { | ||||
| 	    case GL_FILL:  | ||||
| 	       fill_front = CLIP_FILL;  | ||||
| 	       offset_front = 0; | ||||
| 	       break; | ||||
| 	    case GL_LINE: | ||||
| 	       fill_front = CLIP_LINE; | ||||
| 	       offset_front = brw->attribs.Polygon->OffsetLine; | ||||
| 	       offset_front = ctx->Polygon.OffsetLine; | ||||
| 	       break; | ||||
| 	    case GL_POINT: | ||||
| 	       fill_front = CLIP_POINT; | ||||
| 	       offset_front = brw->attribs.Polygon->OffsetPoint; | ||||
| 	       offset_front = ctx->Polygon.OffsetPoint; | ||||
| 	       break; | ||||
| 	    } | ||||
| 	 } | ||||
|  | ||||
| 	 if (!brw->attribs.Polygon->CullFlag || | ||||
| 	     brw->attribs.Polygon->CullFaceMode != GL_BACK) { | ||||
| 	    switch (brw->attribs.Polygon->BackMode) { | ||||
| 	 if (!ctx->Polygon.CullFlag || | ||||
| 	     ctx->Polygon.CullFaceMode != GL_BACK) { | ||||
| 	    switch (ctx->Polygon.BackMode) { | ||||
| 	    case GL_FILL:  | ||||
| 	       fill_back = CLIP_FILL;  | ||||
| 	       offset_back = 0; | ||||
| 	       break; | ||||
| 	    case GL_LINE: | ||||
| 	       fill_back = CLIP_LINE; | ||||
| 	       offset_back = brw->attribs.Polygon->OffsetLine; | ||||
| 	       offset_back = ctx->Polygon.OffsetLine; | ||||
| 	       break; | ||||
| 	    case GL_POINT: | ||||
| 	       fill_back = CLIP_POINT; | ||||
| 	       offset_back = brw->attribs.Polygon->OffsetPoint; | ||||
| 	       offset_back = ctx->Polygon.OffsetPoint; | ||||
| 	       break; | ||||
| 	    } | ||||
| 	 } | ||||
|  | ||||
| 	 if (brw->attribs.Polygon->BackMode != GL_FILL || | ||||
| 	     brw->attribs.Polygon->FrontMode != GL_FILL) { | ||||
| 	 if (ctx->Polygon.BackMode != GL_FILL || | ||||
| 	     ctx->Polygon.FrontMode != GL_FILL) { | ||||
| 	    key.do_unfilled = 1; | ||||
|  | ||||
| 	    /* Most cases the fixed function units will handle.  Cases where | ||||
| @@ -207,17 +207,17 @@ static void upload_clip_prog(struct brw_context *brw) | ||||
|  | ||||
| 	    if (offset_back || offset_front) { | ||||
| 	       /* _NEW_POLYGON, _NEW_BUFFERS */ | ||||
| 	       key.offset_units = brw->attribs.Polygon->OffsetUnits * brw->intel.polygon_offset_scale; | ||||
| 	       key.offset_factor = brw->attribs.Polygon->OffsetFactor * ctx->DrawBuffer->_MRD; | ||||
| 	       key.offset_units = ctx->Polygon.OffsetUnits * brw->intel.polygon_offset_scale; | ||||
| 	       key.offset_factor = ctx->Polygon.OffsetFactor * ctx->DrawBuffer->_MRD; | ||||
| 	    } | ||||
|  | ||||
| 	    switch (brw->attribs.Polygon->FrontFace) { | ||||
| 	    switch (ctx->Polygon.FrontFace) { | ||||
| 	    case GL_CCW: | ||||
| 	       key.fill_ccw = fill_front; | ||||
| 	       key.fill_cw = fill_back; | ||||
| 	       key.offset_ccw = offset_front; | ||||
| 	       key.offset_cw = offset_back; | ||||
| 	       if (brw->attribs.Light->Model.TwoSide && | ||||
| 	       if (ctx->Light.Model.TwoSide && | ||||
| 		   key.fill_cw != CLIP_CULL)  | ||||
| 		  key.copy_bfc_cw = 1; | ||||
| 	       break; | ||||
| @@ -226,7 +226,7 @@ static void upload_clip_prog(struct brw_context *brw) | ||||
| 	       key.fill_ccw = fill_back; | ||||
| 	       key.offset_cw = offset_front; | ||||
| 	       key.offset_ccw = offset_back; | ||||
| 	       if (brw->attribs.Light->Model.TwoSide && | ||||
| 	       if (ctx->Light.Model.TwoSide && | ||||
| 		   key.fill_ccw != CLIP_CULL)  | ||||
| 		  key.copy_bfc_ccw = 1; | ||||
| 	       break; | ||||
|   | ||||
| @@ -181,34 +181,54 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) | ||||
| 	 brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation); | ||||
| 	 is_negative = brw_IF(p, BRW_EXECUTE_1); | ||||
| 	 { | ||||
| 	    brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0)); | ||||
| 	    brw_math_invert(p, c->reg.t, c->reg.t); | ||||
| 	    brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1); | ||||
|              /* | ||||
|               * Both can be negative on GM965/G965 due to RHW workaround | ||||
|               * if so, this object should be rejected. | ||||
|               */ | ||||
|              if (!BRW_IS_G4X(p->brw)) { | ||||
|                  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0)); | ||||
|                  is_neg2 = brw_IF(p, BRW_EXECUTE_1); | ||||
|                  { | ||||
|                      brw_clip_kill_thread(c); | ||||
|                  } | ||||
|                  brw_ENDIF(p, is_neg2); | ||||
|              } | ||||
|  | ||||
| 	    brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 ); | ||||
| 	    brw_MOV(p, c->reg.t1, c->reg.t); | ||||
| 	    brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|              brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0)); | ||||
|              brw_math_invert(p, c->reg.t, c->reg.t); | ||||
|              brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1); | ||||
|  | ||||
|              brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 ); | ||||
|              brw_MOV(p, c->reg.t1, c->reg.t); | ||||
|              brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
| 	 }  | ||||
| 	 is_negative = brw_ELSE(p, is_negative); | ||||
| 	 { | ||||
| 	    /* Coming back in.  We know that both cannot be negative | ||||
| 	     * because the line would have been culled in that case. | ||||
| 	     */ | ||||
|              /* Coming back in.  We know that both cannot be negative | ||||
|               * because the line would have been culled in that case. | ||||
|               */ | ||||
|  | ||||
|              /* If both are positive, do nothing */ | ||||
|              /* Only on GM965/G965 */ | ||||
|              if (!BRW_IS_G4X(p->brw)) { | ||||
|                  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); | ||||
|                  is_neg2 = brw_IF(p, BRW_EXECUTE_1); | ||||
|              } | ||||
|  | ||||
| 	    /* If both are positive, do nothing */ | ||||
|              brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); | ||||
|              is_neg2 = brw_IF(p, BRW_EXECUTE_1); | ||||
|              { | ||||
| 		brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); | ||||
| 		brw_math_invert(p, c->reg.t, c->reg.t); | ||||
| 		brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); | ||||
|                  brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); | ||||
|                  brw_math_invert(p, c->reg.t, c->reg.t); | ||||
|                  brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); | ||||
|  | ||||
| 		brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); | ||||
| 		brw_MOV(p, c->reg.t0, c->reg.t); | ||||
| 		brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
| 	     } | ||||
| 	     brw_ENDIF(p, is_neg2); | ||||
| 	 } | ||||
|                  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); | ||||
|                  brw_MOV(p, c->reg.t0, c->reg.t); | ||||
|                  brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|              } | ||||
|  | ||||
|              if (!BRW_IS_G4X(p->brw)) { | ||||
|                  brw_ENDIF(p, is_neg2); | ||||
|              } | ||||
|          } | ||||
| 	 brw_ENDIF(p, is_negative);	  | ||||
|       } | ||||
|       brw_ENDIF(p, plane_active); | ||||
|   | ||||
| @@ -455,6 +455,8 @@ static void brw_clip_test( struct brw_clip_compile *c ) | ||||
|     struct brw_indirect vt2 = brw_indirect(2, 0); | ||||
|  | ||||
|     struct brw_compile *p = &c->func; | ||||
|     struct brw_instruction *is_outside; | ||||
|     struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ | ||||
|  | ||||
|     brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0])); | ||||
|     brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1])); | ||||
| @@ -462,53 +464,87 @@ static void brw_clip_test( struct brw_clip_compile *c ) | ||||
|     brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS])); | ||||
|     brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS])); | ||||
|     brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS])); | ||||
|     brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f)); | ||||
|  | ||||
|     /* test nearz, xmin, ymin plane */ | ||||
|     brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3));  | ||||
|     /* clip.xyz < -clip.w */ | ||||
|     brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3)));  | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     brw_CMP(p, t2, BRW_CONDITIONAL_LE, negate(v1), get_element(v1, 3));  | ||||
|     brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3)));  | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     brw_CMP(p, t3, BRW_CONDITIONAL_LE, negate(v2), get_element(v2, 3));  | ||||
|     brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3)));  | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|  | ||||
|     /* All vertices are outside of a plane, rejected */ | ||||
|     brw_AND(p, t, t1, t2); | ||||
|     brw_AND(p, t, t, t3); | ||||
|     brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1)); | ||||
|     brw_OR(p, tmp0, tmp0, get_element(t, 2)); | ||||
|     brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); | ||||
|     brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1)); | ||||
|     is_outside = brw_IF(p, BRW_EXECUTE_1); | ||||
|     { | ||||
|         brw_clip_kill_thread(c); | ||||
|     } | ||||
|     brw_ENDIF(p, is_outside); | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|  | ||||
|     /* some vertices are inside a plane, some are outside,need to clip */ | ||||
|     brw_XOR(p, t, t1, t2); | ||||
|     brw_XOR(p, t1, t2, t3); | ||||
|     brw_OR(p, t, t, t1); | ||||
|  | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,  | ||||
| 	    get_element(t, 0), brw_imm_ud(0)); | ||||
|     brw_AND(p, t, t, brw_imm_ud(0x1)); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, | ||||
|             get_element(t, 0), brw_imm_ud(0)); | ||||
|     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5))); | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,  | ||||
| 	    get_element(t, 1), brw_imm_ud(0)); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, | ||||
|             get_element(t, 1), brw_imm_ud(0)); | ||||
|     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3))); | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,  | ||||
| 	    get_element(t, 2), brw_imm_ud(0)); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, | ||||
|             get_element(t, 2), brw_imm_ud(0)); | ||||
|     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1))); | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|  | ||||
|     /* test farz, xmax, ymax plane */ | ||||
|     brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, get_element(v0, 3));  | ||||
|     /* clip.xyz > clip.w */ | ||||
|     brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3));  | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, get_element(v1, 3));  | ||||
|     brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3));  | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, get_element(v2, 3));  | ||||
|     brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3));  | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|  | ||||
|     /* All vertices are outside of a plane, rejected */ | ||||
|     brw_AND(p, t, t1, t2); | ||||
|     brw_AND(p, t, t, t3); | ||||
|     brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1)); | ||||
|     brw_OR(p, tmp0, tmp0, get_element(t, 2)); | ||||
|     brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); | ||||
|     brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1)); | ||||
|     is_outside = brw_IF(p, BRW_EXECUTE_1); | ||||
|     { | ||||
|         brw_clip_kill_thread(c); | ||||
|     } | ||||
|     brw_ENDIF(p, is_outside); | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|  | ||||
|     /* some vertices are inside a plane, some are outside,need to clip */ | ||||
|     brw_XOR(p, t, t1, t2); | ||||
|     brw_XOR(p, t1, t2, t3); | ||||
|     brw_OR(p, t, t, t1); | ||||
|  | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,  | ||||
| 	    get_element(t, 0), brw_imm_ud(0)); | ||||
|     brw_AND(p, t, t, brw_imm_ud(0x1)); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, | ||||
|             get_element(t, 0), brw_imm_ud(0)); | ||||
|     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4))); | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,  | ||||
| 	    get_element(t, 1), brw_imm_ud(0)); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, | ||||
|             get_element(t, 1), brw_imm_ud(0)); | ||||
|     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2))); | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,  | ||||
| 	    get_element(t, 2), brw_imm_ud(0)); | ||||
|     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, | ||||
|             get_element(t, 2), brw_imm_ud(0)); | ||||
|     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0))); | ||||
|     brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|  | ||||
|   | ||||
| @@ -76,30 +76,6 @@ static void brwInitDriverFunctions( struct dd_function_table *functions ) | ||||
|    functions->Viewport = intel_viewport; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void brw_init_attribs( struct brw_context *brw ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|  | ||||
|    brw->attribs.Color = &ctx->Color; | ||||
|    brw->attribs.Depth = &ctx->Depth; | ||||
|    brw->attribs.Fog = &ctx->Fog; | ||||
|    brw->attribs.Hint = &ctx->Hint; | ||||
|    brw->attribs.Light = &ctx->Light; | ||||
|    brw->attribs.Line = &ctx->Line; | ||||
|    brw->attribs.Point = &ctx->Point; | ||||
|    brw->attribs.Polygon = &ctx->Polygon; | ||||
|    brw->attribs.Scissor = &ctx->Scissor; | ||||
|    brw->attribs.Stencil = &ctx->Stencil; | ||||
|    brw->attribs.Texture = &ctx->Texture; | ||||
|    brw->attribs.Transform = &ctx->Transform; | ||||
|    brw->attribs.Viewport = &ctx->Viewport; | ||||
|    brw->attribs.VertexProgram = &ctx->VertexProgram; | ||||
|    brw->attribs.FragmentProgram = &ctx->FragmentProgram; | ||||
|    brw->attribs.PolygonStipple = &ctx->PolygonStipple[0]; | ||||
| } | ||||
|  | ||||
|  | ||||
| GLboolean brwCreateContext( const __GLcontextModes *mesaVis, | ||||
| 			    __DRIcontextPrivate *driContextPriv, | ||||
| 			    void *sharedContextPrivate) | ||||
| @@ -146,10 +122,11 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, | ||||
|    /* if conformance mode is set, swrast can handle any size AA point */ | ||||
|    ctx->Const.MaxPointSizeAA = 255.0; | ||||
|  | ||||
|    /* We want the GLSL compiler to emit code that uses condition codes */ | ||||
|    ctx->Shader.EmitCondCodes = GL_TRUE; | ||||
|  | ||||
| /*    ctx->Const.MaxNativeVertexProgramTemps = 32; */ | ||||
|  | ||||
|    brw_init_attribs( brw ); | ||||
|    brw_init_metaops( brw ); | ||||
|    brw_init_state( brw ); | ||||
|  | ||||
|    brw->state.dirty.mesa = ~0; | ||||
|   | ||||
| @@ -131,7 +131,6 @@ struct brw_context; | ||||
| #define BRW_NEW_WM_INPUT_DIMENSIONS     0x100 | ||||
| #define BRW_NEW_INPUT_VARYING           0x200 | ||||
| #define BRW_NEW_PSP                     0x800 | ||||
| #define BRW_NEW_METAOPS                 0x1000 | ||||
| #define BRW_NEW_FENCE                   0x2000 | ||||
| #define BRW_NEW_INDICES			0x4000 | ||||
| #define BRW_NEW_VERTICES		0x8000 | ||||
| @@ -303,26 +302,6 @@ struct brw_cache { | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| struct brw_state_pointers { | ||||
|    struct gl_colorbuffer_attrib	*Color; | ||||
|    struct gl_depthbuffer_attrib	*Depth; | ||||
|    struct gl_fog_attrib		*Fog; | ||||
|    struct gl_hint_attrib	*Hint; | ||||
|    struct gl_light_attrib	*Light; | ||||
|    struct gl_line_attrib	*Line; | ||||
|    struct gl_point_attrib	*Point; | ||||
|    struct gl_polygon_attrib	*Polygon; | ||||
|    GLuint                       *PolygonStipple; | ||||
|    struct gl_scissor_attrib	*Scissor; | ||||
|    struct gl_stencil_attrib	*Stencil; | ||||
|    struct gl_texture_attrib	*Texture; | ||||
|    struct gl_transform_attrib	*Transform; | ||||
|    struct gl_viewport_attrib	*Viewport; | ||||
|    struct gl_vertex_program_state *VertexProgram;  | ||||
|    struct gl_fragment_program_state *FragmentProgram; | ||||
| }; | ||||
|  | ||||
| /* Considered adding a member to this struct to document which flags | ||||
|  * an update might raise so that ordering of the state atoms can be | ||||
|  * checked or derived at runtime.  Dropped the idea in favor of having | ||||
| @@ -457,7 +436,6 @@ struct brw_context | ||||
|       int validated_bo_count; | ||||
|    } state; | ||||
|  | ||||
|    struct brw_state_pointers attribs; | ||||
|    struct brw_cache cache; | ||||
|    struct brw_cached_batch_item *cached_batch_items; | ||||
|  | ||||
| @@ -491,28 +469,6 @@ struct brw_context | ||||
|       unsigned int offset; | ||||
|    } ib; | ||||
|  | ||||
|    struct { | ||||
|       /* Will be allocated on demand if needed.    | ||||
|        */ | ||||
|       struct brw_state_pointers attribs; | ||||
|       struct gl_vertex_program *vp; | ||||
|       struct gl_fragment_program *fp, *fp_tex; | ||||
|  | ||||
|       struct gl_buffer_object *vbo; | ||||
|  | ||||
|       struct intel_region *saved_draw_region; | ||||
|       GLuint saved_nr_draw_regions; | ||||
|       struct intel_region *saved_depth_region; | ||||
|  | ||||
|       GLuint restore_draw_buffers[MAX_DRAW_BUFFERS]; | ||||
|       GLuint restore_num_draw_buffers; | ||||
|  | ||||
|       struct gl_fragment_program *restore_fp; | ||||
|        | ||||
|       GLboolean active; | ||||
|    } metaops; | ||||
|  | ||||
|  | ||||
|    /* Active vertex program:  | ||||
|     */ | ||||
|    const struct gl_vertex_program *vertex_program; | ||||
| @@ -703,13 +659,6 @@ void brw_FrameBufferTexInit( struct brw_context *brw, | ||||
| void brw_FrameBufferTexDestroy( struct brw_context *brw ); | ||||
| void brw_validate_textures( struct brw_context *brw ); | ||||
|  | ||||
| /*====================================================================== | ||||
|  * brw_metaops.c | ||||
|  */ | ||||
|  | ||||
| void brw_init_metaops( struct brw_context *brw ); | ||||
| void brw_destroy_metaops( struct brw_context *brw ); | ||||
|  | ||||
|  | ||||
| /*====================================================================== | ||||
|  * brw_program.c | ||||
|   | ||||
| @@ -48,6 +48,7 @@ | ||||
|  */ | ||||
| static void calculate_curbe_offsets( struct brw_context *brw ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    /* CACHE_NEW_WM_PROG */ | ||||
|    GLuint nr_fp_regs = (brw->wm.prog_data->nr_params + 15) / 16; | ||||
|     | ||||
| @@ -58,8 +59,8 @@ static void calculate_curbe_offsets( struct brw_context *brw ) | ||||
|    GLuint total_regs; | ||||
|  | ||||
|    /* _NEW_TRANSFORM */ | ||||
|    if (brw->attribs.Transform->ClipPlanesEnabled) { | ||||
|       GLuint nr_planes = 6 + brw_count_bits(brw->attribs.Transform->ClipPlanesEnabled); | ||||
|    if (ctx->Transform.ClipPlanesEnabled) { | ||||
|       GLuint nr_planes = 6 + brw_count_bits(ctx->Transform.ClipPlanesEnabled); | ||||
|       nr_clip_regs = (nr_planes * 4 + 15) / 16; | ||||
|    } | ||||
|  | ||||
| @@ -233,11 +234,11 @@ static void prepare_constant_buffer(struct brw_context *brw) | ||||
|        */ | ||||
|       assert(MAX_CLIP_PLANES == 6); | ||||
|       for (j = 0; j < MAX_CLIP_PLANES; j++) { | ||||
| 	 if (brw->attribs.Transform->ClipPlanesEnabled & (1<<j)) { | ||||
| 	    buf[offset + i * 4 + 0] = brw->attribs.Transform->_ClipUserPlane[j][0]; | ||||
| 	    buf[offset + i * 4 + 1] = brw->attribs.Transform->_ClipUserPlane[j][1]; | ||||
| 	    buf[offset + i * 4 + 2] = brw->attribs.Transform->_ClipUserPlane[j][2]; | ||||
| 	    buf[offset + i * 4 + 3] = brw->attribs.Transform->_ClipUserPlane[j][3]; | ||||
| 	 if (ctx->Transform.ClipPlanesEnabled & (1<<j)) { | ||||
| 	    buf[offset + i * 4 + 0] = ctx->Transform._ClipUserPlane[j][0]; | ||||
| 	    buf[offset + i * 4 + 1] = ctx->Transform._ClipUserPlane[j][1]; | ||||
| 	    buf[offset + i * 4 + 2] = ctx->Transform._ClipUserPlane[j][2]; | ||||
| 	    buf[offset + i * 4 + 3] = ctx->Transform._ClipUserPlane[j][3]; | ||||
| 	    i++; | ||||
| 	 } | ||||
|       } | ||||
|   | ||||
| @@ -84,15 +84,17 @@ static const GLenum reduced_prim[GL_POLYGON+1] = { | ||||
|  */ | ||||
| static GLuint brw_set_prim(struct brw_context *brw, GLenum prim) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|  | ||||
|    if (INTEL_DEBUG & DEBUG_PRIMS) | ||||
|       _mesa_printf("PRIM: %s\n", _mesa_lookup_enum_by_nr(prim)); | ||||
|     | ||||
|    /* Slight optimization to avoid the GS program when not needed: | ||||
|     */ | ||||
|    if (prim == GL_QUAD_STRIP && | ||||
|        brw->attribs.Light->ShadeModel != GL_FLAT && | ||||
|        brw->attribs.Polygon->FrontMode == GL_FILL && | ||||
|        brw->attribs.Polygon->BackMode == GL_FILL) | ||||
|        ctx->Light.ShadeModel != GL_FLAT && | ||||
|        ctx->Polygon.FrontMode == GL_FILL && | ||||
|        ctx->Polygon.BackMode == GL_FILL) | ||||
|       prim = GL_TRIANGLE_STRIP; | ||||
|  | ||||
|    if (prim != brw->primitive) { | ||||
| @@ -166,14 +168,11 @@ static void brw_merge_inputs( struct brw_context *brw, | ||||
|    for (i = 0; i < VERT_ATTRIB_MAX; i++) { | ||||
|       brw->vb.inputs[i].glarray = arrays[i]; | ||||
|  | ||||
|       /* XXX: metaops passes null arrays */ | ||||
|       if (arrays[i]) { | ||||
| 	 if (arrays[i]->StrideB != 0) | ||||
| 	    brw->vb.info.varying |= 1 << i; | ||||
|       if (arrays[i]->StrideB != 0) | ||||
| 	 brw->vb.info.varying |= 1 << i; | ||||
|  | ||||
| 	 brw->vb.info.sizes[i/16] |= (brw->vb.inputs[i].glarray->Size - 1) << | ||||
| 	    ((i%16) * 2); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* Raise statechanges if input sizes and varying have changed:  | ||||
| @@ -192,12 +191,20 @@ static GLboolean check_fallbacks( struct brw_context *brw, | ||||
| 				  const struct _mesa_prim *prim, | ||||
| 				  GLuint nr_prims ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    GLuint i; | ||||
|  | ||||
|    if (!brw->intel.strict_conformance) | ||||
|    /* If we don't require strict OpenGL conformance, never  | ||||
|     * use fallbacks.  If we're forcing fallbacks, always | ||||
|     * use fallfacks. | ||||
|     */ | ||||
|    if (brw->intel.conformance_mode == 0) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    if (brw->attribs.Polygon->SmoothFlag) { | ||||
|    if (brw->intel.conformance_mode == 2) | ||||
|       return GL_TRUE; | ||||
|  | ||||
|    if (ctx->Polygon.SmoothFlag) { | ||||
|       for (i = 0; i < nr_prims; i++) | ||||
| 	 if (reduced_prim[prim[i].mode] == GL_TRIANGLES)  | ||||
| 	    return GL_TRUE; | ||||
| @@ -206,7 +213,7 @@ static GLboolean check_fallbacks( struct brw_context *brw, | ||||
|    /* BRW hardware will do AA lines, but they are non-conformant it | ||||
|     * seems.  TBD whether we keep this fallback: | ||||
|     */ | ||||
|    if (brw->attribs.Line->SmoothFlag) { | ||||
|    if (ctx->Line.SmoothFlag) { | ||||
|       for (i = 0; i < nr_prims; i++) | ||||
| 	 if (reduced_prim[prim[i].mode] == GL_LINES)  | ||||
| 	    return GL_TRUE; | ||||
| @@ -215,28 +222,61 @@ static GLboolean check_fallbacks( struct brw_context *brw, | ||||
|    /* Stipple -- these fallbacks could be resolved with a little | ||||
|     * bit of work? | ||||
|     */ | ||||
|    if (brw->attribs.Line->StippleFlag) { | ||||
|    if (ctx->Line.StippleFlag) { | ||||
|       for (i = 0; i < nr_prims; i++) { | ||||
| 	 /* GS doesn't get enough information to know when to reset | ||||
| 	  * the stipple counter?!? | ||||
| 	  */ | ||||
| 	 if (prim[i].mode == GL_LINE_LOOP)  | ||||
| 	 if (prim[i].mode == GL_LINE_LOOP || prim[i].mode == GL_LINE_STRIP)  | ||||
| 	    return GL_TRUE; | ||||
| 	     | ||||
| 	 if (prim[i].mode == GL_POLYGON && | ||||
| 	     (brw->attribs.Polygon->FrontMode == GL_LINE || | ||||
| 	      brw->attribs.Polygon->BackMode == GL_LINE)) | ||||
| 	     (ctx->Polygon.FrontMode == GL_LINE || | ||||
| 	      ctx->Polygon.BackMode == GL_LINE)) | ||||
| 	    return GL_TRUE; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|  | ||||
|    if (brw->attribs.Point->SmoothFlag) { | ||||
|    if (ctx->Point.SmoothFlag) { | ||||
|       for (i = 0; i < nr_prims; i++) | ||||
| 	 if (prim[i].mode == GL_POINTS)  | ||||
| 	    return GL_TRUE; | ||||
|    } | ||||
|  | ||||
|    /* BRW hardware doesn't handle GL_CLAMP texturing correctly; | ||||
|     * brw_wm_sampler_state:translate_wrap_mode() treats GL_CLAMP | ||||
|     * as GL_CLAMP_TO_EDGE instead.  If we're using GL_CLAMP, and | ||||
|     * we want strict conformance, force the fallback. | ||||
|     * Right now, we only do this for 2D textures. | ||||
|     */ | ||||
|    { | ||||
|       int u; | ||||
|       for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { | ||||
|          struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u]; | ||||
|          if (texUnit->Enabled) { | ||||
|             if (texUnit->Enabled & TEXTURE_1D_BIT) { | ||||
|                if (texUnit->CurrentTex[TEXTURE_1D_INDEX]->WrapS == GL_CLAMP) { | ||||
|                    return GL_TRUE; | ||||
|                } | ||||
|             } | ||||
|             if (texUnit->Enabled & TEXTURE_2D_BIT) { | ||||
|                if (texUnit->CurrentTex[TEXTURE_2D_INDEX]->WrapS == GL_CLAMP || | ||||
|                    texUnit->CurrentTex[TEXTURE_2D_INDEX]->WrapT == GL_CLAMP) { | ||||
|                    return GL_TRUE; | ||||
|                } | ||||
|             } | ||||
|             if (texUnit->Enabled & TEXTURE_3D_BIT) { | ||||
|                if (texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapS == GL_CLAMP || | ||||
|                    texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapT == GL_CLAMP || | ||||
|                    texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapR == GL_CLAMP) { | ||||
|                    return GL_TRUE; | ||||
|                } | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|        | ||||
|    /* Nothing stopping us from the fast path now */ | ||||
|    return GL_FALSE; | ||||
| } | ||||
|  | ||||
| @@ -261,11 +301,18 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, | ||||
|    if (ctx->NewState) | ||||
|       _mesa_update_state( ctx ); | ||||
|  | ||||
|    /* We have to validate the textures *before* checking for fallbacks; | ||||
|     * otherwise, the software fallback won't be able to rely on the | ||||
|     * texture state, the firstLevel and lastLevel fields won't be | ||||
|     * set in the intel texture object (they'll both be 0), and the  | ||||
|     * software fallback will segfault if it attempts to access any | ||||
|     * texture level other than level 0. | ||||
|     */ | ||||
|    brw_validate_textures( brw ); | ||||
|  | ||||
|    if (check_fallbacks(brw, prim, nr_prims)) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    brw_validate_textures( brw ); | ||||
|  | ||||
|    /* Bind all inputs, derive varying and size information: | ||||
|     */ | ||||
|    brw_merge_inputs( brw, arrays ); | ||||
|   | ||||
| @@ -129,3 +129,126 @@ const GLuint *brw_get_program( struct brw_compile *p, | ||||
|    return (const GLuint *)p->store; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Subroutine calls require special attention. | ||||
|  * Mesa instructions may be expanded into multiple hardware instructions | ||||
|  * so the prog_instruction::BranchTarget field can't be used as an index | ||||
|  * into the hardware instructions. | ||||
|  * | ||||
|  * The BranchTarget field isn't needed, however.  Mesa's GLSL compiler | ||||
|  * emits CAL and BGNSUB instructions with labels that can be used to map | ||||
|  * subroutine calls to actual subroutine code blocks. | ||||
|  * | ||||
|  * The structures and function here implement patching of CAL instructions | ||||
|  * so they jump to the right subroutine code... | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * For each OPCODE_BGNSUB we create one of these. | ||||
|  */ | ||||
| struct brw_glsl_label | ||||
| { | ||||
|    const char *name; /**< the label string */ | ||||
|    GLuint position;  /**< the position of the brw instruction for this label */ | ||||
|    struct brw_glsl_label *next;  /**< next in linked list */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * For each OPCODE_CAL we create one of these. | ||||
|  */ | ||||
| struct brw_glsl_call | ||||
| { | ||||
|    GLuint call_inst_pos;  /**< location of the CAL instruction */ | ||||
|    const char *sub_name;  /**< name of subroutine to call */ | ||||
|    struct brw_glsl_call *next;  /**< next in linked list */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Called for each OPCODE_BGNSUB. | ||||
|  */ | ||||
| void | ||||
| brw_save_label(struct brw_compile *c, const char *name, GLuint position) | ||||
| { | ||||
|    struct brw_glsl_label *label = CALLOC_STRUCT(brw_glsl_label); | ||||
|    label->name = name; | ||||
|    label->position = position; | ||||
|    label->next = c->first_label; | ||||
|    c->first_label = label; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Called for each OPCODE_CAL. | ||||
|  */ | ||||
| void | ||||
| brw_save_call(struct brw_compile *c, const char *name, GLuint call_pos) | ||||
| { | ||||
|    struct brw_glsl_call *call = CALLOC_STRUCT(brw_glsl_call); | ||||
|    call->call_inst_pos = call_pos; | ||||
|    call->sub_name = name; | ||||
|    call->next = c->first_call; | ||||
|    c->first_call = call; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Lookup a label, return label's position/offset. | ||||
|  */ | ||||
| static GLuint | ||||
| brw_lookup_label(struct brw_compile *c, const char *name) | ||||
| { | ||||
|    const struct brw_glsl_label *label; | ||||
|    for (label = c->first_label; label; label = label->next) { | ||||
|       if (strcmp(name, label->name) == 0) { | ||||
|          return label->position; | ||||
|       } | ||||
|    } | ||||
|    abort();  /* should never happen */ | ||||
|    return ~0; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * When we're done generating code, this function is called to resolve | ||||
|  * subroutine calls. | ||||
|  */ | ||||
| void | ||||
| brw_resolve_cals(struct brw_compile *c) | ||||
| { | ||||
|     const struct brw_glsl_call *call; | ||||
|  | ||||
|     for (call = c->first_call; call; call = call->next) { | ||||
|         const GLuint sub_loc = brw_lookup_label(c, call->sub_name); | ||||
| 	struct brw_instruction *brw_call_inst = &c->store[call->call_inst_pos]; | ||||
| 	struct brw_instruction *brw_sub_inst = &c->store[sub_loc]; | ||||
| 	GLint offset = brw_sub_inst - brw_call_inst; | ||||
|  | ||||
| 	/* patch brw_inst1 to point to brw_inst2 */ | ||||
| 	brw_set_src1(brw_call_inst, brw_imm_d(offset * 16)); | ||||
|     } | ||||
|  | ||||
|     /* free linked list of calls */ | ||||
|     { | ||||
|         struct brw_glsl_call *call, *next; | ||||
|         for (call = c->first_call; call; call = next) { | ||||
| 	    next = call->next; | ||||
| 	    _mesa_free(call); | ||||
| 	} | ||||
| 	c->first_call = NULL; | ||||
|     } | ||||
|  | ||||
|     /* free linked list of labels */ | ||||
|     { | ||||
|         struct brw_glsl_label *label, *next; | ||||
| 	for (label = c->first_label; label; label = next) { | ||||
| 	    next = label->next; | ||||
| 	    _mesa_free(label); | ||||
| 	} | ||||
| 	c->first_label = NULL; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -91,6 +91,11 @@ struct brw_indirect { | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct brw_glsl_label; | ||||
| struct brw_glsl_call; | ||||
|  | ||||
|  | ||||
|  | ||||
| #define BRW_EU_MAX_INSN_STACK 5 | ||||
| #define BRW_EU_MAX_INSN 1200 | ||||
|  | ||||
| @@ -106,9 +111,22 @@ struct brw_compile { | ||||
|    GLuint flag_value; | ||||
|    GLboolean single_program_flow; | ||||
|    struct brw_context *brw; | ||||
|  | ||||
|    struct brw_glsl_label *first_label;  /**< linked list of labels */ | ||||
|    struct brw_glsl_call *first_call;    /**< linked list of CALs */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| void | ||||
| brw_save_label(struct brw_compile *c, const char *name, GLuint position); | ||||
|  | ||||
| void | ||||
| brw_save_call(struct brw_compile *c, const char *name, GLuint call_pos); | ||||
|  | ||||
| void | ||||
| brw_resolve_cals(struct brw_compile *c); | ||||
|  | ||||
|  | ||||
|  | ||||
| static INLINE int type_sz( GLuint type ) | ||||
| { | ||||
|   | ||||
| @@ -47,20 +47,12 @@ static GLboolean do_check_fallback(struct brw_context *brw) | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    GLuint i; | ||||
|  | ||||
|    /* BRW_NEW_METAOPS | ||||
|     */ | ||||
|    if (brw->metaops.active) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    if (brw->intel.no_rast) { | ||||
|       DBG("FALLBACK: rasterization disabled\n"); | ||||
|       return GL_TRUE; | ||||
|    } | ||||
|  | ||||
|    /* _NEW_RENDERMODE | ||||
|     * | ||||
|     * XXX: need to save/restore RenderMode in metaops state, or | ||||
|     * somehow move to a new attribs pointer: | ||||
|     */ | ||||
|    if (ctx->RenderMode != GL_RENDER) { | ||||
|       DBG("FALLBACK: render mode\n"); | ||||
| @@ -70,7 +62,7 @@ static GLboolean do_check_fallback(struct brw_context *brw) | ||||
|    /* _NEW_TEXTURE: | ||||
|     */ | ||||
|    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { | ||||
|       struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i]; | ||||
|       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; | ||||
|       if (texUnit->_ReallyEnabled) { | ||||
| 	 struct intel_texture_object *intelObj = intel_texture_object(texUnit->_Current); | ||||
| 	 struct gl_texture_image *texImage = intelObj->base.Image[0][intelObj->firstLevel]; | ||||
| @@ -83,8 +75,8 @@ static GLboolean do_check_fallback(struct brw_context *brw) | ||||
|     | ||||
|    /* _NEW_STENCIL  | ||||
|     */ | ||||
|    if (brw->attribs.Stencil->Enabled &&  | ||||
|        !brw->intel.hw_stencil) { | ||||
|    if (ctx->Stencil.Enabled && | ||||
|        (ctx->DrawBuffer->Name == 0 && !brw->intel.hw_stencil)) { | ||||
|       DBG("FALLBACK: stencil\n"); | ||||
|       return GL_TRUE; | ||||
|    } | ||||
| @@ -101,7 +93,7 @@ static void check_fallback(struct brw_context *brw) | ||||
| const struct brw_tracked_state brw_check_fallback = { | ||||
|    .dirty = { | ||||
|       .mesa = _NEW_BUFFERS | _NEW_RENDERMODE | _NEW_TEXTURE | _NEW_STENCIL, | ||||
|       .brw  = BRW_NEW_METAOPS, | ||||
|       .brw  = 0, | ||||
|       .cache = 0 | ||||
|    }, | ||||
|    .prepare = check_fallback | ||||
|   | ||||
| @@ -1,583 +0,0 @@ | ||||
| /* | ||||
|  Copyright (C) Intel Corp.  2006.  All Rights Reserved. | ||||
|  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to | ||||
|  develop this 3D driver. | ||||
|   | ||||
|  Permission is hereby granted, free of charge, to any person obtaining | ||||
|  a copy of this software and associated documentation files (the | ||||
|  "Software"), to deal in the Software without restriction, including | ||||
|  without limitation the rights to use, copy, modify, merge, publish, | ||||
|  distribute, sublicense, and/or sell copies of the Software, and to | ||||
|  permit persons to whom the Software is furnished to do so, subject to | ||||
|  the following conditions: | ||||
|   | ||||
|  The above copyright notice and this permission notice (including the | ||||
|  next paragraph) shall be included in all copies or substantial | ||||
|  portions of the Software. | ||||
|   | ||||
|  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
|  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
|  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
|  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. | ||||
|   | ||||
|  **********************************************************************/ | ||||
|  /* | ||||
|   * Authors: | ||||
|   *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|   *   frame buffer texture by Gary Wong <gtw@gnu.org> | ||||
|   */ | ||||
|   | ||||
|  | ||||
|  | ||||
| #include "main/glheader.h" | ||||
| #include "main/context.h" | ||||
| #include "main/macros.h" | ||||
|  | ||||
| #include "shader/arbprogparse.h" | ||||
|  | ||||
| #include "intel_screen.h" | ||||
| #include "intel_batchbuffer.h" | ||||
| #include "intel_regions.h" | ||||
| #include "intel_buffers.h" | ||||
|  | ||||
| #include "brw_context.h" | ||||
| #include "brw_defines.h" | ||||
| #include "brw_draw.h" | ||||
| #include "brw_fallback.h" | ||||
|  | ||||
| #define INIT(brw, STRUCT, ATTRIB) 		\ | ||||
| do {						\ | ||||
|    brw->attribs.ATTRIB = &ctx->ATTRIB;		\ | ||||
| } while (0) | ||||
|  | ||||
| #define DUP(brw, STRUCT, ATTRIB) 		\ | ||||
| do {						\ | ||||
|    brw->metaops.attribs.ATTRIB = MALLOC_STRUCT(STRUCT);	\ | ||||
|    memcpy(brw->metaops.attribs.ATTRIB, 			\ | ||||
| 	  brw->attribs.ATTRIB,			\ | ||||
| 	  sizeof(struct STRUCT));		\ | ||||
| } while (0) | ||||
|  | ||||
|  | ||||
| #define INSTALL(brw, ATTRIB, STATE)		\ | ||||
| do {						\ | ||||
|    brw->attribs.ATTRIB = brw->metaops.attribs.ATTRIB;	\ | ||||
|    brw->state.dirty.mesa |= STATE;		\ | ||||
| } while (0) | ||||
|  | ||||
| #define RESTORE(brw, ATTRIB, STATE)			\ | ||||
| do {							\ | ||||
|    brw->attribs.ATTRIB = &brw->intel.ctx.ATTRIB;	\ | ||||
|    brw->state.dirty.mesa |= STATE;			\ | ||||
| } while (0) | ||||
|  | ||||
| static void init_attribs( struct brw_context *brw ) | ||||
| { | ||||
|    DUP(brw, gl_colorbuffer_attrib, Color); | ||||
|    DUP(brw, gl_depthbuffer_attrib, Depth); | ||||
|    DUP(brw, gl_fog_attrib, Fog); | ||||
|    DUP(brw, gl_hint_attrib, Hint); | ||||
|    DUP(brw, gl_light_attrib, Light); | ||||
|    DUP(brw, gl_line_attrib, Line); | ||||
|    DUP(brw, gl_point_attrib, Point); | ||||
|    DUP(brw, gl_polygon_attrib, Polygon); | ||||
|    DUP(brw, gl_scissor_attrib, Scissor); | ||||
|    DUP(brw, gl_stencil_attrib, Stencil); | ||||
|    DUP(brw, gl_texture_attrib, Texture); | ||||
|    DUP(brw, gl_transform_attrib, Transform); | ||||
|    DUP(brw, gl_viewport_attrib, Viewport); | ||||
|    DUP(brw, gl_vertex_program_state, VertexProgram); | ||||
|    DUP(brw, gl_fragment_program_state, FragmentProgram); | ||||
| } | ||||
|  | ||||
| static void install_attribs( struct brw_context *brw ) | ||||
| { | ||||
|    INSTALL(brw, Color, _NEW_COLOR); | ||||
|    INSTALL(brw, Depth, _NEW_DEPTH); | ||||
|    INSTALL(brw, Fog, _NEW_FOG); | ||||
|    INSTALL(brw, Hint, _NEW_HINT); | ||||
|    INSTALL(brw, Light, _NEW_LIGHT); | ||||
|    INSTALL(brw, Line, _NEW_LINE); | ||||
|    INSTALL(brw, Point, _NEW_POINT); | ||||
|    INSTALL(brw, Polygon, _NEW_POLYGON); | ||||
|    INSTALL(brw, Scissor, _NEW_SCISSOR); | ||||
|    INSTALL(brw, Stencil, _NEW_STENCIL); | ||||
|    INSTALL(brw, Texture, _NEW_TEXTURE); | ||||
|    INSTALL(brw, Transform, _NEW_TRANSFORM); | ||||
|    INSTALL(brw, Viewport, _NEW_VIEWPORT); | ||||
|    INSTALL(brw, VertexProgram, _NEW_PROGRAM); | ||||
|    INSTALL(brw, FragmentProgram, _NEW_PROGRAM); | ||||
| } | ||||
|  | ||||
| static void restore_attribs( struct brw_context *brw ) | ||||
| { | ||||
|    RESTORE(brw, Color, _NEW_COLOR); | ||||
|    RESTORE(brw, Depth, _NEW_DEPTH); | ||||
|    RESTORE(brw, Fog, _NEW_FOG); | ||||
|    RESTORE(brw, Hint, _NEW_HINT); | ||||
|    RESTORE(brw, Light, _NEW_LIGHT); | ||||
|    RESTORE(brw, Line, _NEW_LINE); | ||||
|    RESTORE(brw, Point, _NEW_POINT); | ||||
|    RESTORE(brw, Polygon, _NEW_POLYGON); | ||||
|    RESTORE(brw, Scissor, _NEW_SCISSOR); | ||||
|    RESTORE(brw, Stencil, _NEW_STENCIL); | ||||
|    RESTORE(brw, Texture, _NEW_TEXTURE); | ||||
|    RESTORE(brw, Transform, _NEW_TRANSFORM); | ||||
|    RESTORE(brw, Viewport, _NEW_VIEWPORT); | ||||
|    RESTORE(brw, VertexProgram, _NEW_PROGRAM); | ||||
|    RESTORE(brw, FragmentProgram, _NEW_PROGRAM); | ||||
| } | ||||
|  | ||||
|  | ||||
| static const char *vp_prog = | ||||
|       "!!ARBvp1.0\n" | ||||
|       "MOV  result.color, vertex.color;\n" | ||||
|       "MOV  result.position, vertex.position;\n" | ||||
|       "END\n"; | ||||
|  | ||||
| static const char *fp_prog = | ||||
|       "!!ARBfp1.0\n" | ||||
|       "MOV result.color, fragment.color;\n" | ||||
|       "END\n"; | ||||
|  | ||||
| static const char *fp_tex_prog = | ||||
|       "!!ARBfp1.0\n" | ||||
|       "TEMP a;\n" | ||||
|       "ADD a, fragment.position, program.local[0];\n" | ||||
|       "MUL a, a, program.local[1];\n" | ||||
|       "TEX result.color, a, texture[0], 2D;\n" | ||||
|       "MOV result.depth.z, fragment.position;\n" | ||||
|       "END\n"; | ||||
|  | ||||
| /* Derived values of importance: | ||||
|  * | ||||
|  *   FragmentProgram->_Current | ||||
|  *   VertexProgram->_Enabled | ||||
|  *   brw->vertex_program | ||||
|  *   DrawBuffer->_ColorDrawBufferIndexes[0] | ||||
|  *  | ||||
|  * | ||||
|  * More if drawpixels-through-texture is added.   | ||||
|  */ | ||||
| static void init_metaops_state( struct brw_context *brw ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|  | ||||
|    brw->metaops.vbo = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); | ||||
|  | ||||
|    ctx->Driver.BufferData(ctx, | ||||
| 			  GL_ARRAY_BUFFER_ARB, | ||||
| 			  4096, | ||||
| 			  NULL, | ||||
| 			  GL_DYNAMIC_DRAW_ARB, | ||||
| 			  brw->metaops.vbo); | ||||
|  | ||||
|    brw->metaops.fp = (struct gl_fragment_program *) | ||||
|       ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 ); | ||||
|  | ||||
|    brw->metaops.fp_tex = (struct gl_fragment_program *) | ||||
|       ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 ); | ||||
|  | ||||
|    brw->metaops.vp = (struct gl_vertex_program *) | ||||
|       ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 1 ); | ||||
|  | ||||
|    _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB,  | ||||
| 				    fp_prog, strlen(fp_prog), | ||||
| 				    brw->metaops.fp); | ||||
|  | ||||
|    _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB,  | ||||
| 				    fp_tex_prog, strlen(fp_tex_prog), | ||||
| 				    brw->metaops.fp_tex); | ||||
|  | ||||
|    _mesa_parse_arb_vertex_program(ctx, GL_VERTEX_PROGRAM_ARB,  | ||||
| 				  vp_prog, strlen(vp_prog), | ||||
| 				  brw->metaops.vp); | ||||
|  | ||||
|    brw->metaops.attribs.VertexProgram->_Current = brw->metaops.vp; | ||||
|    brw->metaops.attribs.VertexProgram->_Enabled = GL_TRUE; | ||||
|  | ||||
|    brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp; | ||||
| } | ||||
|  | ||||
| static void meta_flat_shade( struct intel_context *intel ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|  | ||||
|    brw->metaops.attribs.Light->ShadeModel = GL_FLAT; | ||||
|    brw->state.dirty.mesa |= _NEW_LIGHT; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void meta_no_stencil_write( struct intel_context *intel ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|  | ||||
|    brw->metaops.attribs.Stencil->Enabled = GL_FALSE; | ||||
|    brw->metaops.attribs.Stencil->WriteMask[0] = GL_FALSE;  | ||||
|    brw->state.dirty.mesa |= _NEW_STENCIL; | ||||
| } | ||||
|  | ||||
| static void meta_no_depth_write( struct intel_context *intel ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|  | ||||
|    brw->metaops.attribs.Depth->Test = GL_FALSE; | ||||
|    brw->metaops.attribs.Depth->Mask = GL_FALSE; | ||||
|    brw->state.dirty.mesa |= _NEW_DEPTH; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void meta_depth_replace( struct intel_context *intel ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|  | ||||
|    /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) | ||||
|     * ctx->Driver.DepthMask( ctx, GL_TRUE ) | ||||
|     */ | ||||
|    brw->metaops.attribs.Depth->Test = GL_TRUE; | ||||
|    brw->metaops.attribs.Depth->Mask = GL_TRUE; | ||||
|    brw->state.dirty.mesa |= _NEW_DEPTH; | ||||
|  | ||||
|    /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) | ||||
|     */ | ||||
|    brw->metaops.attribs.Depth->Func = GL_ALWAYS; | ||||
|  | ||||
|    brw->state.dirty.mesa |= _NEW_DEPTH; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void meta_stencil_replace( struct intel_context *intel, | ||||
| 				 GLuint s_mask, | ||||
| 				 GLuint s_clear) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|  | ||||
|    brw->metaops.attribs.Stencil->Enabled = GL_TRUE; | ||||
|    brw->metaops.attribs.Stencil->WriteMask[0] = s_mask; | ||||
|    brw->metaops.attribs.Stencil->ValueMask[0] = 0xff; | ||||
|    brw->metaops.attribs.Stencil->Ref[0] = s_clear; | ||||
|    brw->metaops.attribs.Stencil->Function[0] = GL_ALWAYS; | ||||
|    brw->metaops.attribs.Stencil->FailFunc[0] = GL_REPLACE; | ||||
|    brw->metaops.attribs.Stencil->ZPassFunc[0] = GL_REPLACE; | ||||
|    brw->metaops.attribs.Stencil->ZFailFunc[0] = GL_REPLACE; | ||||
|    brw->state.dirty.mesa |= _NEW_STENCIL; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void meta_color_mask( struct intel_context *intel, GLboolean state ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|  | ||||
|    if (state) | ||||
|       COPY_4V(brw->metaops.attribs.Color->ColorMask,  | ||||
| 	      brw->intel.ctx.Color.ColorMask);  | ||||
|    else | ||||
|       ASSIGN_4V(brw->metaops.attribs.Color->ColorMask, 0, 0, 0, 0); | ||||
|  | ||||
|    brw->state.dirty.mesa |= _NEW_COLOR; | ||||
| } | ||||
|  | ||||
| static void meta_no_texture( struct intel_context *intel ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|     | ||||
|    brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp; | ||||
|     | ||||
|    brw->metaops.attribs.Texture->CurrentUnit = 0; | ||||
|    brw->metaops.attribs.Texture->_EnabledUnits = 0; | ||||
|    brw->metaops.attribs.Texture->_EnabledCoordUnits = 0; | ||||
|    brw->metaops.attribs.Texture->Unit[ 0 ].Enabled = 0; | ||||
|    brw->metaops.attribs.Texture->Unit[ 0 ]._ReallyEnabled = 0; | ||||
|  | ||||
|    brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM; | ||||
| } | ||||
|  | ||||
| static void meta_texture_blend_replace(struct intel_context *intel) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|  | ||||
|    brw->metaops.attribs.Texture->CurrentUnit = 0; | ||||
|    brw->metaops.attribs.Texture->_EnabledUnits = 1; | ||||
|    brw->metaops.attribs.Texture->_EnabledCoordUnits = 1; | ||||
|    brw->metaops.attribs.Texture->Unit[ 0 ].Enabled = TEXTURE_2D_BIT; | ||||
|    brw->metaops.attribs.Texture->Unit[ 0 ]._ReallyEnabled = TEXTURE_2D_BIT; | ||||
|    brw->metaops.attribs.Texture->Unit[ 0 ].Current2D = | ||||
|       intel->frame_buffer_texobj; | ||||
|    brw->metaops.attribs.Texture->Unit[ 0 ]._Current = | ||||
|       intel->frame_buffer_texobj; | ||||
|  | ||||
|    brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM; | ||||
| } | ||||
|  | ||||
| static void meta_import_pixel_state(struct intel_context *intel) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|     | ||||
|    RESTORE(brw, Color, _NEW_COLOR); | ||||
|    RESTORE(brw, Depth, _NEW_DEPTH); | ||||
|    RESTORE(brw, Fog, _NEW_FOG); | ||||
|    RESTORE(brw, Scissor, _NEW_SCISSOR); | ||||
|    RESTORE(brw, Stencil, _NEW_STENCIL); | ||||
|    RESTORE(brw, Texture, _NEW_TEXTURE); | ||||
|    RESTORE(brw, FragmentProgram, _NEW_PROGRAM); | ||||
| } | ||||
|  | ||||
| static void meta_frame_buffer_texture( struct intel_context *intel, | ||||
| 				       GLint xoff, GLint yoff ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|    struct intel_region *region = intel_drawbuf_region( intel ); | ||||
|     | ||||
|    INSTALL(brw, FragmentProgram, _NEW_PROGRAM); | ||||
|  | ||||
|    brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp_tex; | ||||
|    /* This is unfortunate, but seems to be necessary, since later on we | ||||
|       will end up calling _mesa_load_state_parameters to lookup the | ||||
|       local params (below), and that will want to look in ctx.FragmentProgram | ||||
|       instead of brw->attribs.FragmentProgram. */ | ||||
|    intel->ctx.FragmentProgram.Current = brw->metaops.fp_tex; | ||||
|  | ||||
|    brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 0 ] = xoff; | ||||
|    brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 1 ] = yoff; | ||||
|    brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 2 ] = 0.0; | ||||
|    brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 3 ] = 0.0; | ||||
|    brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 0 ] = | ||||
|       1.0 / region->pitch; | ||||
|    brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 1 ] = | ||||
|       -1.0 / region->height; | ||||
|    brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 2 ] = 0.0; | ||||
|    brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 3 ] = 1.0; | ||||
|     | ||||
|    brw->state.dirty.mesa |= _NEW_PROGRAM; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void meta_draw_region( struct intel_context *intel, | ||||
| 			     struct intel_region *draw_region, | ||||
| 			     struct intel_region *depth_region ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|  | ||||
|    if (!brw->metaops.saved_draw_region) { | ||||
|       brw->metaops.saved_draw_region = brw->state.draw_regions[0]; | ||||
|       brw->metaops.saved_nr_draw_regions = brw->state.nr_draw_regions; | ||||
|       brw->metaops.saved_depth_region = brw->state.depth_region; | ||||
|    } | ||||
|  | ||||
|    brw->state.draw_regions[0] = draw_region; | ||||
|    brw->state.nr_draw_regions = 1; | ||||
|    brw->state.depth_region = depth_region; | ||||
|  | ||||
|    if (intel->frame_buffer_texobj != NULL) | ||||
|       brw_FrameBufferTexDestroy(brw); | ||||
|  | ||||
|    if (draw_region) | ||||
|        brw_FrameBufferTexInit(brw, draw_region); | ||||
|  | ||||
|    brw->state.dirty.mesa |= _NEW_BUFFERS; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void meta_draw_quad(struct intel_context *intel,  | ||||
| 			   GLfloat x0, GLfloat x1, | ||||
| 			   GLfloat y0, GLfloat y1,  | ||||
| 			   GLfloat z, | ||||
| 			   GLuint color, | ||||
| 			   GLfloat s0, GLfloat s1, | ||||
| 			   GLfloat t0, GLfloat t1) | ||||
| { | ||||
|    GLcontext *ctx = &intel->ctx; | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|    struct gl_client_array pos_array; | ||||
|    struct gl_client_array color_array; | ||||
|    struct gl_client_array *attribs[VERT_ATTRIB_MAX]; | ||||
|    struct _mesa_prim prim[1]; | ||||
|    GLfloat pos[4][3]; | ||||
|  | ||||
|    ctx->Driver.BufferData(ctx, | ||||
| 			  GL_ARRAY_BUFFER_ARB, | ||||
| 			  sizeof(pos) + sizeof(color), | ||||
| 			  NULL, | ||||
| 			  GL_DYNAMIC_DRAW_ARB, | ||||
| 			  brw->metaops.vbo); | ||||
|  | ||||
|    pos[0][0] = x0; | ||||
|    pos[0][1] = y0; | ||||
|    pos[0][2] = z; | ||||
|  | ||||
|    pos[1][0] = x1; | ||||
|    pos[1][1] = y0; | ||||
|    pos[1][2] = z; | ||||
|  | ||||
|    pos[2][0] = x1; | ||||
|    pos[2][1] = y1; | ||||
|    pos[2][2] = z; | ||||
|  | ||||
|    pos[3][0] = x0; | ||||
|    pos[3][1] = y1; | ||||
|    pos[3][2] = z; | ||||
|  | ||||
|    ctx->Driver.BufferSubData(ctx, | ||||
| 			     GL_ARRAY_BUFFER_ARB, | ||||
| 			     0, | ||||
| 			     sizeof(pos), | ||||
| 			     pos, | ||||
| 			     brw->metaops.vbo); | ||||
|  | ||||
|    /* Convert incoming ARGB to required RGBA */ | ||||
|    /* Note this color is stored as GL_UNSIGNED_BYTE */ | ||||
|    color = (color & 0xff00ff00) | (((color >> 16) | (color << 16)) & 0xff00ff); | ||||
|  | ||||
|    ctx->Driver.BufferSubData(ctx, | ||||
| 			     GL_ARRAY_BUFFER_ARB, | ||||
| 			     sizeof(pos), | ||||
| 			     sizeof(color), | ||||
| 			     &color, | ||||
| 			     brw->metaops.vbo); | ||||
|  | ||||
|    /* Ignoring texture coords.  | ||||
|     */ | ||||
|  | ||||
|    memset(attribs, 0, VERT_ATTRIB_MAX * sizeof(*attribs)); | ||||
|  | ||||
|    attribs[VERT_ATTRIB_POS] = &pos_array; | ||||
|    attribs[VERT_ATTRIB_POS]->Ptr = 0; | ||||
|    attribs[VERT_ATTRIB_POS]->Type = GL_FLOAT; | ||||
|    attribs[VERT_ATTRIB_POS]->Enabled = 1; | ||||
|    attribs[VERT_ATTRIB_POS]->Size = 3; | ||||
|    attribs[VERT_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat); | ||||
|    attribs[VERT_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat); | ||||
|    attribs[VERT_ATTRIB_POS]->_MaxElement = 4; | ||||
|    attribs[VERT_ATTRIB_POS]->Normalized = 0; | ||||
|    attribs[VERT_ATTRIB_POS]->BufferObj = brw->metaops.vbo; | ||||
|  | ||||
|    attribs[VERT_ATTRIB_COLOR0] = &color_array; | ||||
|    attribs[VERT_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos); | ||||
|    attribs[VERT_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE; | ||||
|    attribs[VERT_ATTRIB_COLOR0]->Enabled = 1; | ||||
|    attribs[VERT_ATTRIB_COLOR0]->Size = 4; | ||||
|    attribs[VERT_ATTRIB_COLOR0]->StrideB = 0; | ||||
|    attribs[VERT_ATTRIB_COLOR0]->Stride = 0; | ||||
|    attribs[VERT_ATTRIB_COLOR0]->_MaxElement = 1; | ||||
|    attribs[VERT_ATTRIB_COLOR0]->Normalized = 1; | ||||
|    attribs[VERT_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo; | ||||
|     | ||||
|    /* Just ignoring texture coordinates for now.  | ||||
|     */ | ||||
|  | ||||
|    memset(prim, 0, sizeof(*prim)); | ||||
|  | ||||
|    prim[0].mode = GL_TRIANGLE_FAN; | ||||
|    prim[0].begin = 1; | ||||
|    prim[0].end = 1; | ||||
|    prim[0].weak = 0; | ||||
|    prim[0].pad = 0; | ||||
|    prim[0].start = 0; | ||||
|    prim[0].count = 4; | ||||
|  | ||||
|    brw_draw_prims(&brw->intel.ctx,  | ||||
| 		  (const struct gl_client_array **)attribs, | ||||
| 		  prim, 1, | ||||
| 		  NULL, | ||||
| 		  0, | ||||
| 		  3 ); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void install_meta_state( struct intel_context *intel ) | ||||
| { | ||||
|    GLcontext *ctx = &intel->ctx; | ||||
|    struct brw_context *brw = brw_context(ctx); | ||||
|    GLuint i; | ||||
|  | ||||
|    if (!brw->metaops.vbo) { | ||||
|       init_metaops_state(brw); | ||||
|    } | ||||
|  | ||||
|    install_attribs(brw); | ||||
|     | ||||
|    meta_no_texture(&brw->intel); | ||||
|    meta_flat_shade(&brw->intel); | ||||
|    for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { | ||||
|       brw->metaops.restore_draw_buffers[i] | ||||
|          = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; | ||||
|    } | ||||
|    brw->metaops.restore_num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; | ||||
|  | ||||
|    brw->metaops.restore_fp = ctx->FragmentProgram.Current; | ||||
|  | ||||
|    /* This works without adjusting refcounts.  Fix later?  | ||||
|     */ | ||||
|    brw->metaops.saved_draw_region = brw->state.draw_regions[0]; | ||||
|    brw->metaops.saved_nr_draw_regions = brw->state.nr_draw_regions; | ||||
|    brw->metaops.saved_depth_region = brw->state.depth_region; | ||||
|    brw->metaops.active = 1; | ||||
|     | ||||
|    brw->state.dirty.brw |= BRW_NEW_METAOPS; | ||||
| } | ||||
|  | ||||
| static void leave_meta_state( struct intel_context *intel ) | ||||
| { | ||||
|    GLcontext *ctx = &intel->ctx; | ||||
|    struct brw_context *brw = brw_context(ctx); | ||||
|    GLuint i; | ||||
|  | ||||
|    restore_attribs(brw); | ||||
|  | ||||
|    for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { | ||||
|       ctx->DrawBuffer->_ColorDrawBufferIndexes[i] | ||||
|          = brw->metaops.restore_draw_buffers[i]; | ||||
|    } | ||||
|    ctx->DrawBuffer->_NumColorDrawBuffers = brw->metaops.restore_num_draw_buffers; | ||||
|  | ||||
|    ctx->FragmentProgram.Current = brw->metaops.restore_fp; | ||||
|  | ||||
|    brw->state.draw_regions[0] = brw->metaops.saved_draw_region; | ||||
|    brw->state.nr_draw_regions = brw->metaops.saved_nr_draw_regions; | ||||
|    brw->state.depth_region = brw->metaops.saved_depth_region; | ||||
|    brw->metaops.saved_draw_region = NULL; | ||||
|    brw->metaops.saved_depth_region = NULL; | ||||
|    brw->metaops.active = 0; | ||||
|  | ||||
|    brw->state.dirty.mesa |= _NEW_BUFFERS; | ||||
|    brw->state.dirty.brw |= BRW_NEW_METAOPS; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void brw_init_metaops( struct brw_context *brw ) | ||||
| { | ||||
|    init_attribs(brw); | ||||
|  | ||||
|  | ||||
|    brw->intel.vtbl.install_meta_state = install_meta_state; | ||||
|    brw->intel.vtbl.leave_meta_state = leave_meta_state; | ||||
|    brw->intel.vtbl.meta_no_depth_write = meta_no_depth_write; | ||||
|    brw->intel.vtbl.meta_no_stencil_write = meta_no_stencil_write; | ||||
|    brw->intel.vtbl.meta_stencil_replace = meta_stencil_replace; | ||||
|    brw->intel.vtbl.meta_depth_replace = meta_depth_replace; | ||||
|    brw->intel.vtbl.meta_color_mask = meta_color_mask; | ||||
|    brw->intel.vtbl.meta_no_texture = meta_no_texture; | ||||
|    brw->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; | ||||
|    brw->intel.vtbl.meta_frame_buffer_texture = meta_frame_buffer_texture; | ||||
|    brw->intel.vtbl.meta_draw_region = meta_draw_region; | ||||
|    brw->intel.vtbl.meta_draw_quad = meta_draw_quad; | ||||
|    brw->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; | ||||
| /*    brw->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; */ | ||||
| /*    brw->intel.vtbl.meta_draw_format = set_draw_format; */ | ||||
| } | ||||
|  | ||||
| void brw_destroy_metaops( struct brw_context *brw ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|  | ||||
|    if (brw->metaops.vbo) | ||||
|       ctx->Driver.DeleteBuffer( ctx, brw->metaops.vbo ); | ||||
|  | ||||
| /*    ctx->Driver.DeleteProgram( ctx, brw->metaops.fp ); */ | ||||
| /*    ctx->Driver.DeleteProgram( ctx, brw->metaops.fp_tex ); */ | ||||
| /*    ctx->Driver.DeleteProgram( ctx, brw->metaops.vp ); */ | ||||
| } | ||||
| @@ -48,15 +48,16 @@ | ||||
|  | ||||
| static void upload_blend_constant_color(struct brw_context *brw) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct brw_blend_constant_color bcc; | ||||
|  | ||||
|    memset(&bcc, 0, sizeof(bcc));       | ||||
|    bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR; | ||||
|    bcc.header.length = sizeof(bcc)/4-2; | ||||
|    bcc.blend_constant_color[0] = brw->attribs.Color->BlendColor[0]; | ||||
|    bcc.blend_constant_color[1] = brw->attribs.Color->BlendColor[1]; | ||||
|    bcc.blend_constant_color[2] = brw->attribs.Color->BlendColor[2]; | ||||
|    bcc.blend_constant_color[3] = brw->attribs.Color->BlendColor[3]; | ||||
|    bcc.blend_constant_color[0] = ctx->Color.BlendColor[0]; | ||||
|    bcc.blend_constant_color[1] = ctx->Color.BlendColor[1]; | ||||
|    bcc.blend_constant_color[2] = ctx->Color.BlendColor[2]; | ||||
|    bcc.blend_constant_color[3] = ctx->Color.BlendColor[3]; | ||||
|  | ||||
|    BRW_CACHED_BATCH_STRUCT(brw, &bcc); | ||||
| } | ||||
| @@ -154,10 +155,7 @@ static void upload_pipelined_state_pointers(struct brw_context *brw ) | ||||
|       OUT_RELOC(brw->gs.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); | ||||
|    else | ||||
|       OUT_BATCH(0); | ||||
|    if (!brw->metaops.active) | ||||
|       OUT_RELOC(brw->clip.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); | ||||
|    else | ||||
|       OUT_BATCH(0); | ||||
|    OUT_RELOC(brw->clip.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); | ||||
|    OUT_RELOC(brw->sf.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); | ||||
|    OUT_RELOC(brw->wm.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); | ||||
|    OUT_RELOC(brw->cc.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); | ||||
| @@ -186,7 +184,7 @@ static void upload_psp_urb_cbs(struct brw_context *brw ) | ||||
| const struct brw_tracked_state brw_psp_urb_cbs = { | ||||
|    .dirty = { | ||||
|       .mesa = 0, | ||||
|       .brw = BRW_NEW_URB_FENCE | BRW_NEW_METAOPS | BRW_NEW_BATCH, | ||||
|       .brw = BRW_NEW_URB_FENCE | BRW_NEW_BATCH, | ||||
|       .cache = (CACHE_NEW_VS_UNIT |  | ||||
| 		CACHE_NEW_GS_UNIT |  | ||||
| 		CACHE_NEW_GS_PROG |  | ||||
| @@ -284,6 +282,7 @@ const struct brw_tracked_state brw_depthbuffer = { | ||||
|  | ||||
| static void upload_polygon_stipple(struct brw_context *brw) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct brw_polygon_stipple bps; | ||||
|    GLuint i; | ||||
|  | ||||
| @@ -291,8 +290,21 @@ static void upload_polygon_stipple(struct brw_context *brw) | ||||
|    bps.header.opcode = CMD_POLY_STIPPLE_PATTERN; | ||||
|    bps.header.length = sizeof(bps)/4-2; | ||||
|  | ||||
|    for (i = 0; i < 32; i++) | ||||
|       bps.stipple[i] = brw->attribs.PolygonStipple[31 - i]; /* invert */ | ||||
|    /* Polygon stipple is provided in OpenGL order, i.e. bottom | ||||
|     * row first.  If we're rendering to a window (i.e. the | ||||
|     * default frame buffer object, 0), then we need to invert | ||||
|     * it to match our pixel layout.  But if we're rendering | ||||
|     * to a FBO (i.e. any named frame buffer object), we *don't* | ||||
|     * need to invert - we already match the layout. | ||||
|     */ | ||||
|    if (ctx->DrawBuffer->Name == 0) { | ||||
|       for (i = 0; i < 32; i++) | ||||
|          bps.stipple[i] = ctx->PolygonStipple[31 - i]; /* invert */ | ||||
|    } | ||||
|    else { | ||||
|       for (i = 0; i < 32; i++) | ||||
|          bps.stipple[i] = ctx->PolygonStipple[i]; /* don't invert */ | ||||
|    } | ||||
|  | ||||
|    BRW_CACHED_BATCH_STRUCT(brw, &bps); | ||||
| } | ||||
| @@ -320,8 +332,22 @@ static void upload_polygon_stipple_offset(struct brw_context *brw) | ||||
|    bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET; | ||||
|    bpso.header.length = sizeof(bpso)/4-2; | ||||
|  | ||||
|    bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31; | ||||
|    bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31; | ||||
|    /* If we're drawing to a system window (ctx->DrawBuffer->Name == 0), | ||||
|     * we have to invert the Y axis in order to match the OpenGL | ||||
|     * pixel coordinate system, and our offset must be matched | ||||
|     * to the window position.  If we're drawing to a FBO | ||||
|     * (ctx->DrawBuffer->Name != 0), then our native pixel coordinate | ||||
|     * system works just fine, and there's no window system to | ||||
|     * worry about. | ||||
|     */ | ||||
|    if (brw->intel.ctx.DrawBuffer->Name == 0) { | ||||
|       bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31; | ||||
|       bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31; | ||||
|    } | ||||
|    else { | ||||
|       bpso.bits0.y_offset = 0; | ||||
|       bpso.bits0.x_offset = 0; | ||||
|    } | ||||
|  | ||||
|    BRW_CACHED_BATCH_STRUCT(brw, &bpso); | ||||
| } | ||||
| @@ -370,6 +396,7 @@ const struct brw_tracked_state brw_aa_line_parameters = { | ||||
|  | ||||
| static void upload_line_stipple(struct brw_context *brw) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct brw_line_stipple bls; | ||||
|    GLfloat tmp; | ||||
|    GLint tmpi; | ||||
| @@ -378,10 +405,10 @@ static void upload_line_stipple(struct brw_context *brw) | ||||
|    bls.header.opcode = CMD_LINE_STIPPLE_PATTERN; | ||||
|    bls.header.length = sizeof(bls)/4 - 2; | ||||
|  | ||||
|    bls.bits0.pattern = brw->attribs.Line->StipplePattern; | ||||
|    bls.bits1.repeat_count = brw->attribs.Line->StippleFactor; | ||||
|    bls.bits0.pattern = ctx->Line.StipplePattern; | ||||
|    bls.bits1.repeat_count = ctx->Line.StippleFactor; | ||||
|  | ||||
|    tmp = 1.0 / (GLfloat) brw->attribs.Line->StippleFactor; | ||||
|    tmp = 1.0 / (GLfloat) ctx->Line.StippleFactor; | ||||
|    tmpi = tmp * (1<<13); | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -46,6 +46,7 @@ | ||||
| static void compile_sf_prog( struct brw_context *brw, | ||||
| 			     struct brw_sf_prog_key *key ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct brw_sf_compile c; | ||||
|    const GLuint *program; | ||||
|    GLuint program_size; | ||||
| @@ -74,7 +75,7 @@ static void compile_sf_prog( struct brw_context *brw, | ||||
| 	 c.idx_to_attr[idx] = i; | ||||
| 	 if (i >= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) { | ||||
|             c.point_attrs[i].CoordReplace =  | ||||
|                brw->attribs.Point->CoordReplace[i - VERT_RESULT_TEX0]; | ||||
|                ctx->Point.CoordReplace[i - VERT_RESULT_TEX0]; | ||||
| 	 } | ||||
|          else { | ||||
|             c.point_attrs[i].CoordReplace = GL_FALSE; | ||||
| @@ -128,6 +129,7 @@ static void compile_sf_prog( struct brw_context *brw, | ||||
|  */ | ||||
| static void upload_sf_prog(struct brw_context *brw) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct brw_sf_prog_key key; | ||||
|  | ||||
|    memset(&key, 0, sizeof(key)); | ||||
| @@ -158,15 +160,21 @@ static void upload_sf_prog(struct brw_context *brw) | ||||
|       break; | ||||
|    } | ||||
|  | ||||
|    key.do_point_sprite = brw->attribs.Point->PointSprite; | ||||
|    key.SpriteOrigin = brw->attribs.Point->SpriteOrigin; | ||||
|    key.do_point_sprite = ctx->Point.PointSprite; | ||||
|    key.SpriteOrigin = ctx->Point.SpriteOrigin; | ||||
|    /* _NEW_LIGHT */ | ||||
|    key.do_flat_shading = (brw->attribs.Light->ShadeModel == GL_FLAT); | ||||
|    key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide); | ||||
|    key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT); | ||||
|    key.do_twoside_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide); | ||||
|  | ||||
|    /* _NEW_POLYGON */ | ||||
|    if (key.do_twoside_color) | ||||
|       key.frontface_ccw = (brw->attribs.Polygon->FrontFace == GL_CCW); | ||||
|    if (key.do_twoside_color) { | ||||
|       /* If we're rendering to a FBO, we have to invert the polygon | ||||
|        * face orientation, just as we invert the viewport in | ||||
|        * sf_unit_create_from_key().  ctx->DrawBuffer->Name will be | ||||
|        * nonzero if we're rendering to such an FBO. | ||||
|        */ | ||||
|       key.frontface_ccw = (ctx->Polygon.FrontFace == GL_CCW) ^ (ctx->DrawBuffer->Name != 0); | ||||
|    } | ||||
|  | ||||
|    dri_bo_unreference(brw->sf.prog_bo); | ||||
|    brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG, | ||||
|   | ||||
| @@ -55,25 +55,16 @@ static void upload_sf_vp(struct brw_context *brw) | ||||
|       y_bias = ctx->DrawBuffer->Height; | ||||
|    } | ||||
|  | ||||
|    /* _NEW_VIEWPORT, BRW_NEW_METAOPS */ | ||||
|    /* _NEW_VIEWPORT */ | ||||
|  | ||||
|    if (!brw->metaops.active) { | ||||
|       const GLfloat *v = ctx->Viewport._WindowMap.m; | ||||
|    const GLfloat *v = ctx->Viewport._WindowMap.m; | ||||
|  | ||||
|       sfv.viewport.m00 = v[MAT_SX]; | ||||
|       sfv.viewport.m11 = v[MAT_SY] * y_scale; | ||||
|       sfv.viewport.m22 = v[MAT_SZ] * depth_scale; | ||||
|       sfv.viewport.m30 = v[MAT_TX]; | ||||
|       sfv.viewport.m31 = v[MAT_TY] * y_scale + y_bias; | ||||
|       sfv.viewport.m32 = v[MAT_TZ] * depth_scale; | ||||
|    } else { | ||||
|       sfv.viewport.m00 =   1; | ||||
|       sfv.viewport.m11 = - 1; | ||||
|       sfv.viewport.m22 =   1; | ||||
|       sfv.viewport.m30 =   0; | ||||
|       sfv.viewport.m31 =   ctx->DrawBuffer->Height; | ||||
|       sfv.viewport.m32 =   0; | ||||
|    } | ||||
|    sfv.viewport.m00 = v[MAT_SX]; | ||||
|    sfv.viewport.m11 = v[MAT_SY] * y_scale; | ||||
|    sfv.viewport.m22 = v[MAT_SZ] * depth_scale; | ||||
|    sfv.viewport.m30 = v[MAT_TX]; | ||||
|    sfv.viewport.m31 = v[MAT_TY] * y_scale + y_bias; | ||||
|    sfv.viewport.m32 = v[MAT_TZ] * depth_scale; | ||||
|  | ||||
|    /* _NEW_SCISSOR */ | ||||
|  | ||||
| @@ -84,10 +75,20 @@ static void upload_sf_vp(struct brw_context *brw) | ||||
|     * Note that the hardware's coordinates are inclusive, while Mesa's min is | ||||
|     * inclusive but max is exclusive. | ||||
|     */ | ||||
|    sfv.scissor.xmin = ctx->DrawBuffer->_Xmin; | ||||
|    sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1; | ||||
|    sfv.scissor.ymin = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax; | ||||
|    sfv.scissor.ymax = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin - 1; | ||||
|    if (intel_rendering_to_texture(ctx)) { | ||||
|       /* texmemory: Y=0=bottom */ | ||||
|       sfv.scissor.xmin = ctx->DrawBuffer->_Xmin; | ||||
|       sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1; | ||||
|       sfv.scissor.ymin = ctx->DrawBuffer->_Ymin; | ||||
|       sfv.scissor.ymax = ctx->DrawBuffer->_Ymax - 1; | ||||
|    } | ||||
|    else { | ||||
|       /* memory: Y=0=top */ | ||||
|       sfv.scissor.xmin = ctx->DrawBuffer->_Xmin; | ||||
|       sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1; | ||||
|       sfv.scissor.ymin = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax; | ||||
|       sfv.scissor.ymax = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin - 1; | ||||
|    } | ||||
|  | ||||
|    dri_bo_unreference(brw->sf.vp_bo); | ||||
|    brw->sf.vp_bo = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0 ); | ||||
| @@ -97,7 +98,7 @@ const struct brw_tracked_state brw_sf_vp = { | ||||
|    .dirty = { | ||||
|       .mesa  = (_NEW_VIEWPORT |  | ||||
| 		_NEW_SCISSOR), | ||||
|       .brw   = BRW_NEW_METAOPS, | ||||
|       .brw   = 0, | ||||
|       .cache = 0 | ||||
|    }, | ||||
|    .prepare = upload_sf_vp | ||||
| @@ -119,6 +120,7 @@ struct brw_sf_unit_key { | ||||
| static void | ||||
| sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    memset(key, 0, sizeof(*key)); | ||||
|  | ||||
|    /* CACHE_NEW_SF_PROG */ | ||||
| @@ -130,20 +132,20 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key) | ||||
|    key->urb_size = brw->urb.vsize; | ||||
|    key->sfsize = brw->urb.sfsize; | ||||
|  | ||||
|    key->scissor = brw->attribs.Scissor->Enabled; | ||||
|    key->front_face = brw->attribs.Polygon->FrontFace; | ||||
|    key->scissor = ctx->Scissor.Enabled; | ||||
|    key->front_face = ctx->Polygon.FrontFace; | ||||
|  | ||||
|    if (brw->attribs.Polygon->CullFlag) | ||||
|       key->cull_face = brw->attribs.Polygon->CullFaceMode; | ||||
|    if (ctx->Polygon.CullFlag) | ||||
|       key->cull_face = ctx->Polygon.CullFaceMode; | ||||
|    else | ||||
|       key->cull_face = GL_NONE; | ||||
|  | ||||
|    key->line_width = brw->attribs.Line->Width; | ||||
|    key->line_smooth = brw->attribs.Line->SmoothFlag; | ||||
|    key->line_width = ctx->Line.Width; | ||||
|    key->line_smooth = ctx->Line.SmoothFlag; | ||||
|  | ||||
|    key->point_sprite = brw->attribs.Point->PointSprite; | ||||
|    key->point_size = brw->attribs.Point->Size; | ||||
|    key->point_attenuated = brw->attribs.Point->_Attenuated; | ||||
|    key->point_sprite = ctx->Point.PointSprite; | ||||
|    key->point_size = ctx->Point.Size; | ||||
|    key->point_attenuated = ctx->Point._Attenuated; | ||||
|  | ||||
|    key->render_to_texture = intel_rendering_to_texture(&brw->intel.ctx); | ||||
| } | ||||
| @@ -295,8 +297,7 @@ const struct brw_tracked_state brw_sf_unit = { | ||||
| 		_NEW_LINE |  | ||||
| 		_NEW_POINT |  | ||||
| 		_NEW_SCISSOR), | ||||
|       .brw   = (BRW_NEW_URB_FENCE | | ||||
| 		BRW_NEW_METAOPS), | ||||
|       .brw   = BRW_NEW_URB_FENCE, | ||||
|       .cache = (CACHE_NEW_SF_VP | | ||||
| 		CACHE_NEW_SF_PROG) | ||||
|    }, | ||||
|   | ||||
| @@ -233,7 +233,6 @@ static struct dirty_bit_map brw_bits[] = { | ||||
|    DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS), | ||||
|    DEFINE_BIT(BRW_NEW_INPUT_VARYING), | ||||
|    DEFINE_BIT(BRW_NEW_PSP), | ||||
|    DEFINE_BIT(BRW_NEW_METAOPS), | ||||
|    DEFINE_BIT(BRW_NEW_FENCE), | ||||
|    DEFINE_BIT(BRW_NEW_INDICES), | ||||
|    DEFINE_BIT(BRW_NEW_VERTICES), | ||||
| @@ -298,6 +297,7 @@ brw_print_dirty_count(struct dirty_bit_map *bit_map, int32_t bits) | ||||
|  */ | ||||
| void brw_validate_state( struct brw_context *brw ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct intel_context *intel = &brw->intel; | ||||
|    struct brw_state_flags *state = &brw->state.dirty; | ||||
|    GLuint i; | ||||
| @@ -314,13 +314,13 @@ void brw_validate_state( struct brw_context *brw ) | ||||
|       state->brw |= ~0; | ||||
|    } | ||||
|  | ||||
|    if (brw->fragment_program != brw->attribs.FragmentProgram->_Current) { | ||||
|       brw->fragment_program = brw->attribs.FragmentProgram->_Current; | ||||
|    if (brw->fragment_program != ctx->FragmentProgram._Current) { | ||||
|       brw->fragment_program = ctx->FragmentProgram._Current; | ||||
|       brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; | ||||
|    } | ||||
|  | ||||
|    if (brw->vertex_program != brw->attribs.VertexProgram->_Current) { | ||||
|       brw->vertex_program = brw->attribs.VertexProgram->_Current; | ||||
|    if (brw->vertex_program != ctx->VertexProgram._Current) { | ||||
|       brw->vertex_program = ctx->VertexProgram._Current; | ||||
|       brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; | ||||
|    } | ||||
|  | ||||
|   | ||||
| @@ -86,11 +86,12 @@ void brw_FrameBufferTexDestroy( struct brw_context *brw ) | ||||
|  */ | ||||
| void brw_validate_textures( struct brw_context *brw ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct intel_context *intel = &brw->intel; | ||||
|    int i; | ||||
|  | ||||
|    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { | ||||
|       struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i]; | ||||
|       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; | ||||
|  | ||||
|       if (texUnit->_ReallyEnabled) { | ||||
| 	 intel_finalize_mipmap_tree(intel, i); | ||||
|   | ||||
| @@ -85,6 +85,7 @@ static void do_vs_prog( struct brw_context *brw, | ||||
|  | ||||
| static void brw_upload_vs_prog(struct brw_context *brw) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct brw_vs_prog_key key; | ||||
|    struct brw_vertex_program *vp =  | ||||
|       (struct brw_vertex_program *)brw->vertex_program; | ||||
| @@ -97,14 +98,9 @@ static void brw_upload_vs_prog(struct brw_context *brw) | ||||
|     * the inputs it asks for, whether they are varying or not. | ||||
|     */ | ||||
|    key.program_string_id = vp->id; | ||||
|    key.nr_userclip = brw_count_bits(brw->attribs.Transform->ClipPlanesEnabled); | ||||
|    key.copy_edgeflag = (brw->attribs.Polygon->FrontMode != GL_FILL || | ||||
| 			brw->attribs.Polygon->BackMode != GL_FILL); | ||||
|  | ||||
|    /* BRW_NEW_METAOPS | ||||
|     */ | ||||
|    if (brw->metaops.active) | ||||
|       key.know_w_is_one = 1; | ||||
|    key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled); | ||||
|    key.copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL || | ||||
| 			ctx->Polygon.BackMode != GL_FILL); | ||||
|  | ||||
|    /* Make an early check for the key. | ||||
|     */ | ||||
| @@ -123,7 +119,7 @@ static void brw_upload_vs_prog(struct brw_context *brw) | ||||
| const struct brw_tracked_state brw_vs_prog = { | ||||
|    .dirty = { | ||||
|       .mesa  = _NEW_TRANSFORM | _NEW_POLYGON, | ||||
|       .brw   = BRW_NEW_VERTEX_PROGRAM | BRW_NEW_METAOPS, | ||||
|       .brw   = BRW_NEW_VERTEX_PROGRAM, | ||||
|       .cache = 0 | ||||
|    }, | ||||
|    .prepare = brw_upload_vs_prog | ||||
|   | ||||
| @@ -43,7 +43,6 @@ struct brw_vs_prog_key { | ||||
|    GLuint program_string_id; | ||||
|    GLuint nr_userclip:4; | ||||
|    GLuint copy_edgeflag:1; | ||||
|    GLuint know_w_is_one:1; | ||||
|    GLuint pad:26; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -168,6 +168,7 @@ static GLuint get_input_size(struct brw_context *brw, | ||||
|  */ | ||||
| static void calc_wm_input_sizes( struct brw_context *brw ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    /* BRW_NEW_VERTEX_PROGRAM */ | ||||
|    struct brw_vertex_program *vp =  | ||||
|       (struct brw_vertex_program *)brw->vertex_program; | ||||
| @@ -179,7 +180,7 @@ static void calc_wm_input_sizes( struct brw_context *brw ) | ||||
|    memset(&t, 0, sizeof(t)); | ||||
|  | ||||
|    /* _NEW_LIGHT */ | ||||
|    if (brw->attribs.Light->Model.TwoSide) | ||||
|    if (ctx->Light.Model.TwoSide) | ||||
|       t.twoside = 1; | ||||
|  | ||||
|    for (i = 0; i < VERT_ATTRIB_MAX; i++)  | ||||
|   | ||||
| @@ -871,21 +871,15 @@ static void emit_vertex_write( struct brw_vs_compile *c) | ||||
|    } | ||||
|  | ||||
|    /* Build ndc coords */ | ||||
|    if (!c->key.know_w_is_one) { | ||||
|       ndc = get_tmp(c); | ||||
|       emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL); | ||||
|       brw_MUL(p, brw_writemask(ndc, WRITEMASK_XYZ), pos, ndc); | ||||
|    } | ||||
|    else { | ||||
|       ndc = pos; | ||||
|    } | ||||
|    ndc = get_tmp(c); | ||||
|    emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL); | ||||
|    brw_MUL(p, brw_writemask(ndc, WRITEMASK_XYZ), pos, ndc); | ||||
|  | ||||
|    /* Update the header for point size, user clipping flags, and -ve rhw | ||||
|     * workaround. | ||||
|     */ | ||||
|    if ((c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) || | ||||
|        c->key.nr_userclip || | ||||
|        (!BRW_IS_G4X(p->brw) && !c->key.know_w_is_one)) | ||||
|        c->key.nr_userclip || !BRW_IS_G4X(p->brw)) | ||||
|    { | ||||
|       struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); | ||||
|       GLuint i; | ||||
| @@ -916,7 +910,7 @@ static void emit_vertex_write( struct brw_vs_compile *c) | ||||
|        * Later, clipping will detect ucp[6] and ensure the primitive is | ||||
|        * clipped against all fixed planes. | ||||
|        */ | ||||
|       if (!BRW_IS_G4X(p->brw) && !c->key.know_w_is_one) { | ||||
|       if (!BRW_IS_G4X(p->brw)) { | ||||
| 	 brw_CMP(p, | ||||
| 		 vec8(brw_null_reg()), | ||||
| 		 BRW_CONDITIONAL_L, | ||||
| @@ -960,36 +954,27 @@ static void emit_vertex_write( struct brw_vs_compile *c) | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Called after code generation to resolve subroutine calls and the | ||||
|  * END instruction. | ||||
|  * \param end_inst  points to brw code for END instruction | ||||
|  * \param last_inst  points to last instruction emitted before vertex write | ||||
|  */ | ||||
| static void  | ||||
| post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst ) | ||||
| post_vs_emit( struct brw_vs_compile *c, | ||||
|               struct brw_instruction *end_inst, | ||||
|               struct brw_instruction *last_inst ) | ||||
| { | ||||
|    GLuint nr_insns = c->vp->program.Base.NumInstructions; | ||||
|    GLuint insn, target_insn; | ||||
|    struct prog_instruction *inst1, *inst2; | ||||
|    struct brw_instruction *brw_inst1, *brw_inst2; | ||||
|    int offset; | ||||
|    for (insn = 0; insn < nr_insns; insn++) { | ||||
|        inst1 = &c->vp->program.Base.Instructions[insn]; | ||||
|        brw_inst1 = inst1->Data; | ||||
|        switch (inst1->Opcode) { | ||||
| 	   case OPCODE_CAL: | ||||
| 	   case OPCODE_BRA: | ||||
| 	       target_insn = inst1->BranchTarget; | ||||
| 	       inst2 = &c->vp->program.Base.Instructions[target_insn]; | ||||
| 	       brw_inst2 = inst2->Data; | ||||
| 	       offset = brw_inst2 - brw_inst1; | ||||
| 	       brw_set_src1(brw_inst1, brw_imm_d(offset*16)); | ||||
| 	       break; | ||||
| 	   case OPCODE_END: | ||||
| 	       offset = end_inst - brw_inst1; | ||||
| 	       brw_set_src1(brw_inst1, brw_imm_d(offset*16)); | ||||
| 	       break; | ||||
| 	   default: | ||||
| 	       break; | ||||
|        } | ||||
|    } | ||||
|    GLint offset; | ||||
|  | ||||
|    brw_resolve_cals(&c->func); | ||||
|  | ||||
|    /* patch up the END code to jump past subroutines, etc */ | ||||
|    offset = last_inst - end_inst; | ||||
|    brw_set_src1(end_inst, brw_imm_d(offset * 16)); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Emit the fragment program instructions here. | ||||
|  */ | ||||
| void brw_vs_emit(struct brw_vs_compile *c ) | ||||
| @@ -998,7 +983,8 @@ void brw_vs_emit(struct brw_vs_compile *c ) | ||||
|    struct brw_compile *p = &c->func; | ||||
|    GLuint nr_insns = c->vp->program.Base.NumInstructions; | ||||
|    GLuint insn, if_insn = 0; | ||||
|    struct brw_instruction *end_inst; | ||||
|    GLuint end_offset = 0; | ||||
|    struct brw_instruction *end_inst, *last_inst; | ||||
|    struct brw_instruction *if_inst[MAX_IFSN]; | ||||
|    struct brw_indirect stack_index = brw_indirect(0, 0);    | ||||
|  | ||||
| @@ -1041,7 +1027,6 @@ void brw_vs_emit(struct brw_vs_compile *c ) | ||||
|        | ||||
|       /* Get argument regs.  SWZ is special and does this itself. | ||||
|        */ | ||||
|       inst->Data = &p->store[p->nr_insn]; | ||||
|       if (inst->Opcode != OPCODE_SWZ) | ||||
| 	  for (i = 0; i < 3; i++) { | ||||
| 	      struct prog_src_register *src = &inst->SrcReg[i]; | ||||
| @@ -1209,7 +1194,7 @@ void brw_vs_emit(struct brw_vs_compile *c ) | ||||
| 	 brw_set_access_mode(p, BRW_ALIGN_16); | ||||
| 	 brw_ADD(p, get_addr_reg(stack_index), | ||||
| 			 get_addr_reg(stack_index), brw_imm_d(4)); | ||||
| 	 inst->Data = &p->store[p->nr_insn]; | ||||
|          brw_save_call(p, inst->Comment, p->nr_insn); | ||||
| 	 brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); | ||||
|          break; | ||||
|       case OPCODE_RET: | ||||
| @@ -1218,14 +1203,23 @@ void brw_vs_emit(struct brw_vs_compile *c ) | ||||
| 	 brw_set_access_mode(p, BRW_ALIGN_1); | ||||
|          brw_MOV(p, brw_ip_reg(), deref_1d(stack_index, 0)); | ||||
| 	 brw_set_access_mode(p, BRW_ALIGN_16); | ||||
| 	 break; | ||||
|       case OPCODE_END:	 | ||||
|          end_offset = p->nr_insn; | ||||
|          /* this instruction will get patched later to jump past subroutine | ||||
|           * code, etc. | ||||
|           */ | ||||
|          brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); | ||||
|          break; | ||||
|       case OPCODE_PRINT: | ||||
|          /* no-op */ | ||||
|          break; | ||||
|       case OPCODE_BGNSUB: | ||||
|          brw_save_label(p, inst->Comment, p->nr_insn); | ||||
|          break; | ||||
|       case OPCODE_ENDSUB: | ||||
|          /* no-op instructions */ | ||||
| 	 break; | ||||
|          /* no-op */ | ||||
|          break; | ||||
|       default: | ||||
| 	 _mesa_problem(NULL, "Unsupported opcode %i (%s) in vertex shader", | ||||
|                        inst->Opcode, inst->Opcode < MAX_OPCODE ? | ||||
| @@ -1263,9 +1257,11 @@ void brw_vs_emit(struct brw_vs_compile *c ) | ||||
|       release_tmps(c); | ||||
|    } | ||||
|  | ||||
|    end_inst = &p->store[p->nr_insn]; | ||||
|    end_inst = &p->store[end_offset]; | ||||
|    last_inst = &p->store[p->nr_insn]; | ||||
|  | ||||
|    /* The END instruction will be patched to jump to this code */ | ||||
|    emit_vertex_write(c); | ||||
|    post_vs_emit(c, end_inst); | ||||
|    for (insn = 0; insn < nr_insns; insn++) | ||||
|        c->vp->program.Base.Instructions[insn].Data = NULL; | ||||
|  | ||||
|    post_vs_emit(c, end_inst, last_inst); | ||||
| } | ||||
|   | ||||
| @@ -49,6 +49,8 @@ struct brw_vs_unit_key { | ||||
| static void | ||||
| vs_unit_populate_key(struct brw_context *brw, struct brw_vs_unit_key *key) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|  | ||||
|    memset(key, 0, sizeof(*key)); | ||||
|  | ||||
|    /* CACHE_NEW_VS_PROG */ | ||||
| @@ -61,7 +63,7 @@ vs_unit_populate_key(struct brw_context *brw, struct brw_vs_unit_key *key) | ||||
|    key->urb_size = brw->urb.vsize; | ||||
|  | ||||
|    /* BRW_NEW_CURBE_OFFSETS, _NEW_TRANSFORM */ | ||||
|    if (brw->attribs.Transform->ClipPlanesEnabled) { | ||||
|    if (ctx->Transform.ClipPlanesEnabled) { | ||||
|       /* Note that we read in the userclip planes as well, hence | ||||
|        * clip_start: | ||||
|        */ | ||||
|   | ||||
| @@ -65,7 +65,6 @@ static void brw_destroy_context( struct intel_context *intel ) | ||||
|    struct brw_context *brw = brw_context(&intel->ctx); | ||||
|    int i; | ||||
|  | ||||
|    brw_destroy_metaops(brw); | ||||
|    brw_destroy_state(brw); | ||||
|    brw_draw_destroy( brw ); | ||||
|  | ||||
|   | ||||
| @@ -157,6 +157,7 @@ static void do_wm_prog( struct brw_context *brw, | ||||
| static void brw_wm_populate_key( struct brw_context *brw, | ||||
| 				 struct brw_wm_prog_key *key ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    /* BRW_NEW_FRAGMENT_PROGRAM */ | ||||
|    struct brw_fragment_program *fp =  | ||||
|       (struct brw_fragment_program *)brw->fragment_program; | ||||
| @@ -170,51 +171,50 @@ static void brw_wm_populate_key( struct brw_context *brw, | ||||
|     */ | ||||
|    /* _NEW_COLOR */ | ||||
|    if (fp->program.UsesKill || | ||||
|        brw->attribs.Color->AlphaEnabled) | ||||
|        ctx->Color.AlphaEnabled) | ||||
|       lookup |= IZ_PS_KILL_ALPHATEST_BIT; | ||||
|  | ||||
|    if (fp->program.Base.OutputsWritten & (1<<FRAG_RESULT_DEPR)) | ||||
|       lookup |= IZ_PS_COMPUTES_DEPTH_BIT; | ||||
|  | ||||
|    /* _NEW_DEPTH */ | ||||
|    if (brw->attribs.Depth->Test) | ||||
|    if (ctx->Depth.Test) | ||||
|       lookup |= IZ_DEPTH_TEST_ENABLE_BIT; | ||||
|  | ||||
|    if (brw->attribs.Depth->Test &&   | ||||
|        brw->attribs.Depth->Mask) /* ?? */ | ||||
|    if (ctx->Depth.Test &&   | ||||
|        ctx->Depth.Mask) /* ?? */ | ||||
|       lookup |= IZ_DEPTH_WRITE_ENABLE_BIT; | ||||
|  | ||||
|    /* _NEW_STENCIL */ | ||||
|    if (brw->attribs.Stencil->Enabled) { | ||||
|    if (ctx->Stencil.Enabled) { | ||||
|       lookup |= IZ_STENCIL_TEST_ENABLE_BIT; | ||||
|  | ||||
|       if (brw->attribs.Stencil->WriteMask[0] || | ||||
| 	  (brw->attribs.Stencil->_TestTwoSide && | ||||
| 	   brw->attribs.Stencil->WriteMask[1])) | ||||
|       if (ctx->Stencil.WriteMask[0] || | ||||
| 	  ctx->Stencil.WriteMask[ctx->Stencil._BackFace]) | ||||
| 	 lookup |= IZ_STENCIL_WRITE_ENABLE_BIT; | ||||
|    } | ||||
|  | ||||
|    line_aa = AA_NEVER; | ||||
|  | ||||
|    /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */ | ||||
|    if (brw->attribs.Line->SmoothFlag) { | ||||
|    if (ctx->Line.SmoothFlag) { | ||||
|       if (brw->intel.reduced_primitive == GL_LINES) { | ||||
| 	 line_aa = AA_ALWAYS; | ||||
|       } | ||||
|       else if (brw->intel.reduced_primitive == GL_TRIANGLES) { | ||||
| 	 if (brw->attribs.Polygon->FrontMode == GL_LINE) { | ||||
| 	 if (ctx->Polygon.FrontMode == GL_LINE) { | ||||
| 	    line_aa = AA_SOMETIMES; | ||||
|  | ||||
| 	    if (brw->attribs.Polygon->BackMode == GL_LINE || | ||||
| 		(brw->attribs.Polygon->CullFlag && | ||||
| 		 brw->attribs.Polygon->CullFaceMode == GL_BACK)) | ||||
| 	    if (ctx->Polygon.BackMode == GL_LINE || | ||||
| 		(ctx->Polygon.CullFlag && | ||||
| 		 ctx->Polygon.CullFaceMode == GL_BACK)) | ||||
| 	       line_aa = AA_ALWAYS; | ||||
| 	 } | ||||
| 	 else if (brw->attribs.Polygon->BackMode == GL_LINE) { | ||||
| 	 else if (ctx->Polygon.BackMode == GL_LINE) { | ||||
| 	    line_aa = AA_SOMETIMES; | ||||
|  | ||||
| 	    if ((brw->attribs.Polygon->CullFlag && | ||||
| 		 brw->attribs.Polygon->CullFaceMode == GL_FRONT)) | ||||
| 	    if ((ctx->Polygon.CullFlag && | ||||
| 		 ctx->Polygon.CullFaceMode == GL_FRONT)) | ||||
| 	       line_aa = AA_ALWAYS; | ||||
| 	 } | ||||
|       } | ||||
| @@ -229,19 +229,19 @@ static void brw_wm_populate_key( struct brw_context *brw, | ||||
|    key->projtex_mask = brw->wm.input_size_masks[4-1] >> (FRAG_ATTRIB_TEX0 - FRAG_ATTRIB_WPOS);  | ||||
|  | ||||
|    /* _NEW_LIGHT */ | ||||
|    key->flat_shade = (brw->attribs.Light->ShadeModel == GL_FLAT); | ||||
|    key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT); | ||||
|  | ||||
|    /* _NEW_TEXTURE */ | ||||
|    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { | ||||
|       const struct gl_texture_unit *unit = &brw->attribs.Texture->Unit[i]; | ||||
|       const struct gl_texture_object *t = unit->_Current; | ||||
|       const struct gl_texture_unit *unit = &ctx->Texture.Unit[i]; | ||||
|  | ||||
|       if (unit->_ReallyEnabled) { | ||||
| 	 if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) { | ||||
| 	    key->yuvtex_mask |= 1<<i; | ||||
| 	    if (t->Image[0][t->BaseLevel]->TexFormat->MesaFormat ==  | ||||
| 		    MESA_FORMAT_YCBCR) | ||||
| 		key->yuvtex_swap_mask |= 1<< i; | ||||
|          const struct gl_texture_object *t = unit->_Current; | ||||
|          const struct gl_texture_image *img = t->Image[0][t->BaseLevel]; | ||||
| 	 if (img->InternalFormat == GL_YCBCR_MESA) { | ||||
| 	    key->yuvtex_mask |= 1 << i; | ||||
| 	    if (img->TexFormat->MesaFormat == MESA_FORMAT_YCBCR) | ||||
| 		key->yuvtex_swap_mask |= 1 << i; | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
|   | ||||
| @@ -60,16 +60,16 @@ struct brw_wm_prog_key { | ||||
|    GLuint aa_dest_stencil_reg:3; | ||||
|    GLuint dest_depth_reg:3; | ||||
|    GLuint nr_depth_regs:3; | ||||
|    GLuint projtex_mask:8; | ||||
|    GLuint shadowtex_mask:8; | ||||
|    GLuint computes_depth:1;	/* could be derived from program string */ | ||||
|    GLuint source_depth_to_render_target:1; | ||||
|    GLuint flat_shade:1; | ||||
|    GLuint runtime_check_aads_emit:1; | ||||
|     | ||||
|    GLuint yuvtex_mask:8; | ||||
|    GLuint yuvtex_swap_mask:8;	/* UV swaped */ | ||||
|    GLuint pad1:16; | ||||
|    GLuint projtex_mask:16; | ||||
|    GLuint shadowtex_mask:16; | ||||
|    GLuint yuvtex_mask:16; | ||||
|    GLuint yuvtex_swap_mask:16;	/* UV swaped */ | ||||
|    //   GLuint pad1:16; | ||||
|  | ||||
|    GLuint program_string_id:32; | ||||
|    GLuint origin_x, origin_y; | ||||
| @@ -280,4 +280,6 @@ void brw_wm_lookup_iz( GLuint line_aa, | ||||
|  | ||||
| GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp); | ||||
| void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c); | ||||
|  | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -123,7 +123,7 @@ static struct prog_dst_register dst_reg(GLuint file, GLuint idx) | ||||
|    reg.Index = idx; | ||||
|    reg.WriteMask = WRITEMASK_XYZW; | ||||
|    reg.RelAddr = 0; | ||||
|    reg.CondMask = 0; | ||||
|    reg.CondMask = COND_TR; | ||||
|    reg.CondSwizzle = 0; | ||||
|    reg.CondSrc = 0; | ||||
|    reg.pad = 0; | ||||
| @@ -177,7 +177,6 @@ static struct prog_instruction *emit_insn(struct brw_wm_compile *c, | ||||
| { | ||||
|    struct prog_instruction *inst = get_fp_inst(c); | ||||
|    *inst = *inst0; | ||||
|    inst->Data = (void *)inst0; | ||||
|    return inst; | ||||
| } | ||||
|  | ||||
| @@ -902,8 +901,7 @@ static void print_insns( const struct prog_instruction *insn, | ||||
| 				     3); | ||||
|       } | ||||
|       else  | ||||
| 	 _mesa_printf("UNKNOWN\n"); | ||||
| 	    | ||||
| 	 _mesa_printf("965 Opcode %d\n", insn->Opcode); | ||||
|    } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -89,8 +89,14 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component, int nr, GL | ||||
| 	    break; | ||||
| 	case PROGRAM_UNDEFINED: | ||||
| 	    return brw_null_reg();	 | ||||
| 	default: | ||||
| 	case PROGRAM_TEMPORARY: | ||||
| 	case PROGRAM_INPUT: | ||||
| 	case PROGRAM_OUTPUT: | ||||
| 	case PROGRAM_PAYLOAD: | ||||
| 	    break; | ||||
| 	default: | ||||
| 	    _mesa_problem(NULL, "Unexpected file in get_reg()"); | ||||
| 	    return brw_null_reg(); | ||||
|     } | ||||
|  | ||||
|     if(c->wm_regs[file][index][component].inited) | ||||
| @@ -103,7 +109,20 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component, int nr, GL | ||||
| 	c->reg_index++; | ||||
|     } | ||||
|  | ||||
|     if (neg & (1<< component)) { | ||||
|     if (c->reg_index >= BRW_WM_MAX_GRF - 12) { | ||||
| 	/* ran out of temporary registers! */ | ||||
| #if 1 | ||||
|         /* This is a big hack for now. | ||||
|          * Return bad register index, but don't just crash hange the GPU. | ||||
|          */ | ||||
|         _mesa_fprintf(stderr, "out of regs %d\n", c->reg_index); | ||||
|         c->reg_index = BRW_WM_MAX_GRF - 13; | ||||
| #else | ||||
| 	return brw_null_reg(); | ||||
| #endif | ||||
|     } | ||||
|   | ||||
|     if (neg & (1 << component)) { | ||||
| 	reg = negate(reg); | ||||
|     } | ||||
|     if (abs) | ||||
| @@ -627,23 +646,46 @@ static void emit_dph(struct brw_wm_compile *c, | ||||
|     brw_set_saturate(p, 0); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Emit a scalar instruction, like RCP, RSQ, LOG, EXP. | ||||
|  * Note that the result of the function is smeared across the dest | ||||
|  * register's X, Y, Z and W channels (subject to writemasking of course). | ||||
|  */ | ||||
| static void emit_math1(struct brw_wm_compile *c, | ||||
| 		struct prog_instruction *inst, GLuint func) | ||||
| { | ||||
|     struct brw_compile *p = &c->func; | ||||
|     struct brw_reg src0, dst; | ||||
|     struct brw_reg src0, dst, tmp; | ||||
|     const int mark = mark_tmps( c ); | ||||
|     int i; | ||||
|  | ||||
|     tmp = alloc_tmp(c); | ||||
|  | ||||
|     /* Get first component of source register */ | ||||
|     src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); | ||||
|     dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1); | ||||
|  | ||||
|     /* tmp = func(src0) */ | ||||
|     brw_MOV(p, brw_message_reg(2), src0); | ||||
|     brw_math(p, | ||||
| 	    dst, | ||||
| 	    func, | ||||
| 	    (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE, | ||||
| 	    2, | ||||
| 	    brw_null_reg(), | ||||
| 	    BRW_MATH_DATA_VECTOR, | ||||
| 	    BRW_MATH_PRECISION_FULL); | ||||
|              tmp, | ||||
|              func, | ||||
|              (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE, | ||||
|              2, | ||||
|              brw_null_reg(), | ||||
|              BRW_MATH_DATA_VECTOR, | ||||
|              BRW_MATH_PRECISION_FULL); | ||||
|  | ||||
|     /*tmp.dw1.bits.swizzle = SWIZZLE_XXXX;*/ | ||||
|  | ||||
|     /* replicate tmp value across enabled dest channels */ | ||||
|     for (i = 0; i < 4; i++) { | ||||
|        if (inst->DstReg.WriteMask & (1 << i)) { | ||||
|           dst = get_dst_reg(c, inst, i, 1);     | ||||
|           brw_MOV(p, dst, tmp); | ||||
|        } | ||||
|     } | ||||
|  | ||||
|     release_tmps(c, mark); | ||||
| } | ||||
|  | ||||
| static void emit_rcp(struct brw_wm_compile *c, | ||||
| @@ -2244,28 +2286,12 @@ static void emit_tex(struct brw_wm_compile *c, | ||||
| 	brw_MOV(p, dst[3], brw_imm_f(1.0)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Resolve subroutine calls after code emit is done. | ||||
|  */ | ||||
| static void post_wm_emit( struct brw_wm_compile *c ) | ||||
| { | ||||
|     GLuint nr_insns = c->fp->program.Base.NumInstructions; | ||||
|     GLuint insn, target_insn; | ||||
|     struct prog_instruction *inst1, *inst2; | ||||
|     struct brw_instruction *brw_inst1, *brw_inst2; | ||||
|     int offset; | ||||
|     for (insn = 0; insn < nr_insns; insn++) { | ||||
| 	inst1 = &c->fp->program.Base.Instructions[insn]; | ||||
| 	brw_inst1 = inst1->Data; | ||||
| 	switch (inst1->Opcode) { | ||||
| 	    case OPCODE_CAL: | ||||
| 		target_insn = inst1->BranchTarget; | ||||
| 		inst2 = &c->fp->program.Base.Instructions[target_insn]; | ||||
| 		brw_inst2 = inst2->Data; | ||||
| 		offset = brw_inst2 - brw_inst1; | ||||
| 		brw_set_src1(brw_inst1, brw_imm_d(offset*16)); | ||||
| 		break; | ||||
| 	    default: | ||||
| 		break; | ||||
| 	} | ||||
|     } | ||||
|     brw_resolve_cals(&c->func); | ||||
| } | ||||
|  | ||||
| static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) | ||||
| @@ -2285,10 +2311,6 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) | ||||
|  | ||||
|     for (i = 0; i < c->nr_fp_insns; i++) { | ||||
| 	struct prog_instruction *inst = &c->prog_instructions[i]; | ||||
| 	struct prog_instruction *orig_inst; | ||||
|  | ||||
| 	if ((orig_inst = inst->Data) != 0) | ||||
| 	    orig_inst->Data = current_insn(p); | ||||
|  | ||||
| 	if (inst->CondUpdate) | ||||
| 	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); | ||||
| @@ -2446,7 +2468,10 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) | ||||
| 		brw_ENDIF(p, if_inst[--if_insn]); | ||||
| 		break; | ||||
| 	    case OPCODE_BGNSUB: | ||||
| 		brw_save_label(p, inst->Comment, p->nr_insn); | ||||
| 		break; | ||||
| 	    case OPCODE_ENDSUB: | ||||
| 		/* no-op */ | ||||
| 		break; | ||||
| 	    case OPCODE_CAL:  | ||||
| 		brw_push_insn_state(p); | ||||
| @@ -2456,8 +2481,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) | ||||
|                 brw_set_access_mode(p, BRW_ALIGN_16); | ||||
|                 brw_ADD(p, get_addr_reg(stack_index), | ||||
|                          get_addr_reg(stack_index), brw_imm_d(4)); | ||||
|                 orig_inst = inst->Data; | ||||
|                 orig_inst->Data = &p->store[p->nr_insn]; | ||||
| 		brw_save_call(&c->func, inst->Comment, p->nr_insn); | ||||
|                 brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); | ||||
|                 brw_pop_insn_state(p); | ||||
| 		break; | ||||
| @@ -2510,8 +2534,11 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) | ||||
| 	    brw_set_predicate_control(p, BRW_PREDICATE_NONE); | ||||
|     } | ||||
|     post_wm_emit(c); | ||||
|     for (i = 0; i < c->fp->program.Base.NumInstructions; i++) | ||||
| 	c->fp->program.Base.Instructions[i].Data = NULL; | ||||
|  | ||||
|     if (c->reg_index >= BRW_WM_MAX_GRF) { | ||||
|         _mesa_problem(NULL, "Ran out of registers in brw_wm_emit_glsl()"); | ||||
|         /* XXX we need to do some proper error recovery here */ | ||||
|     } | ||||
| } | ||||
|  | ||||
| void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c) | ||||
|   | ||||
| @@ -379,14 +379,22 @@ static void pass0_precalc_mov( struct brw_wm_compile *c, | ||||
| { | ||||
|    const struct prog_dst_register *dst = &inst->DstReg; | ||||
|    GLuint writemask = inst->DstReg.WriteMask; | ||||
|    struct brw_wm_ref *refs[4]; | ||||
|    GLuint i; | ||||
|  | ||||
|    /* Get the effect of a MOV by manipulating our register table: | ||||
|     * First get all refs, then assign refs.  This ensures that "in-place" | ||||
|     * swizzles such as: | ||||
|     *   MOV t, t.xxyx | ||||
|     * are handled correctly.  Previously, these two steps were done in | ||||
|     * one loop and the above case was incorrectly handled. | ||||
|     */ | ||||
|    for (i = 0; i < 4; i++) { | ||||
|       if (writemask & (1<<i)) {	     | ||||
| 	 pass0_set_fpreg_ref( c, dst->File, dst->Index, i,  | ||||
| 			      get_new_ref(c, inst->SrcReg[0], i, NULL)); | ||||
|       refs[i] = get_new_ref(c, inst->SrcReg[0], i, NULL); | ||||
|    } | ||||
|    for (i = 0; i < 4; i++) { | ||||
|       if (writemask & (1 << i)) {	     | ||||
|          pass0_set_fpreg_ref( c, dst->File, dst->Index, i, refs[i]); | ||||
|       } | ||||
|    } | ||||
| } | ||||
|   | ||||
| @@ -95,6 +95,7 @@ struct wm_sampler_key { | ||||
|    int sampler_count; | ||||
|  | ||||
|    struct wm_sampler_entry { | ||||
|       GLenum tex_target; | ||||
|       GLenum wrap_r, wrap_s, wrap_t; | ||||
|       float maxlod, minlod; | ||||
|       float lod_bias; | ||||
| @@ -168,19 +169,20 @@ static void brw_update_sampler_state(struct wm_sampler_entry *key, | ||||
|       }   | ||||
|    } | ||||
|  | ||||
|    sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r); | ||||
|    sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s); | ||||
|    sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t); | ||||
|  | ||||
|    /* Fulsim complains if I don't do this.  Hardware doesn't mind: | ||||
|     */ | ||||
| #if 0 | ||||
|    if (texObj->Target == GL_TEXTURE_CUBE_MAP_ARB) { | ||||
|    if (key->tex_target == GL_TEXTURE_CUBE_MAP && | ||||
|        (key->minfilter != GL_NEAREST || key->magfilter != GL_NEAREST)) { | ||||
|       /* If we're using anything but nearest sampling for a cube map, we | ||||
|        * need to set this wrap mode to avoid GPU lock-ups. | ||||
|        */ | ||||
|       sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE; | ||||
|       sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE; | ||||
|       sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE; | ||||
|    } | ||||
| #endif | ||||
|    else { | ||||
|       sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r); | ||||
|       sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s); | ||||
|       sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t); | ||||
|    } | ||||
|  | ||||
|    /* Set shadow function:  | ||||
|     */ | ||||
| @@ -220,19 +222,22 @@ static void | ||||
| brw_wm_sampler_populate_key(struct brw_context *brw, | ||||
| 			    struct wm_sampler_key *key) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    int unit; | ||||
|  | ||||
|    memset(key, 0, sizeof(*key)); | ||||
|  | ||||
|    for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) { | ||||
|       if (brw->attribs.Texture->Unit[unit]._ReallyEnabled) { | ||||
|       if (ctx->Texture.Unit[unit]._ReallyEnabled) { | ||||
| 	 struct wm_sampler_entry *entry = &key->sampler[unit]; | ||||
| 	 struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[unit]; | ||||
| 	 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; | ||||
| 	 struct gl_texture_object *texObj = texUnit->_Current; | ||||
| 	 struct intel_texture_object *intelObj = intel_texture_object(texObj); | ||||
| 	 struct gl_texture_image *firstImage = | ||||
| 	    texObj->Image[0][intelObj->firstLevel]; | ||||
|  | ||||
|          entry->tex_target = texObj->Target; | ||||
|  | ||||
| 	 entry->wrap_r = texObj->WrapR; | ||||
| 	 entry->wrap_s = texObj->WrapS; | ||||
| 	 entry->wrap_t = texObj->WrapT; | ||||
| @@ -274,6 +279,7 @@ brw_wm_sampler_populate_key(struct brw_context *brw, | ||||
|  */ | ||||
| static void upload_wm_samplers( struct brw_context *brw ) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    struct wm_sampler_key key; | ||||
|    int i; | ||||
|  | ||||
| @@ -317,7 +323,7 @@ static void upload_wm_samplers( struct brw_context *brw ) | ||||
|  | ||||
|       /* Emit SDC relocations */ | ||||
|       for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { | ||||
| 	 if (!brw->attribs.Texture->Unit[i]._ReallyEnabled) | ||||
| 	 if (!ctx->Texture.Unit[i]._ReallyEnabled) | ||||
| 	    continue; | ||||
|  | ||||
| 	 dri_bo_emit_reloc(brw->wm.sampler_bo, | ||||
|   | ||||
| @@ -60,6 +60,7 @@ struct brw_wm_unit_key { | ||||
| static void | ||||
| wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    const struct gl_fragment_program *fp = brw->fragment_program; | ||||
|    struct intel_context *intel = &brw->intel; | ||||
|  | ||||
| @@ -95,7 +96,7 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) | ||||
|    key->sampler_count = brw->wm.sampler_count; | ||||
|  | ||||
|    /* _NEW_POLYGONSTIPPLE */ | ||||
|    key->polygon_stipple = brw->attribs.Polygon->StippleFlag; | ||||
|    key->polygon_stipple = ctx->Polygon.StippleFlag; | ||||
|  | ||||
|    /* BRW_NEW_FRAGMENT_PROGRAM */ | ||||
|    key->uses_depth = (fp->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0; | ||||
| @@ -105,19 +106,19 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) | ||||
|       (fp->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) != 0; | ||||
|  | ||||
|    /* _NEW_COLOR */ | ||||
|    key->uses_kill = fp->UsesKill || brw->attribs.Color->AlphaEnabled; | ||||
|    key->uses_kill = fp->UsesKill || ctx->Color.AlphaEnabled; | ||||
|    key->is_glsl = brw_wm_is_glsl(fp); | ||||
|  | ||||
|    /* XXX: This needs a flag to indicate when it changes. */ | ||||
|    key->stats_wm = intel->stats_wm; | ||||
|  | ||||
|    /* _NEW_LINE */ | ||||
|    key->line_stipple = brw->attribs.Line->StippleFlag; | ||||
|    key->line_stipple = ctx->Line.StippleFlag; | ||||
|  | ||||
|    /* _NEW_POLYGON */ | ||||
|    key->offset_enable = brw->attribs.Polygon->OffsetFill; | ||||
|    key->offset_units = brw->attribs.Polygon->OffsetUnits; | ||||
|    key->offset_factor = brw->attribs.Polygon->OffsetFactor; | ||||
|    key->offset_enable = ctx->Polygon.OffsetFill; | ||||
|    key->offset_units = ctx->Polygon.OffsetUnits; | ||||
|    key->offset_factor = ctx->Polygon.OffsetFactor; | ||||
| } | ||||
|  | ||||
| static dri_bo * | ||||
|   | ||||
| @@ -253,7 +253,7 @@ static void | ||||
| brw_update_texture_surface( GLcontext *ctx, GLuint unit ) | ||||
| { | ||||
|    struct brw_context *brw = brw_context(ctx); | ||||
|    struct gl_texture_object *tObj = brw->attribs.Texture->Unit[unit]._Current; | ||||
|    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; | ||||
|    struct intel_texture_object *intelObj = intel_texture_object(tObj); | ||||
|    struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel]; | ||||
|    struct brw_wm_surface_key key; | ||||
| @@ -301,6 +301,7 @@ static void | ||||
| brw_update_region_surface(struct brw_context *brw, struct intel_region *region, | ||||
| 			  unsigned int unit, GLboolean cached) | ||||
| { | ||||
|    GLcontext *ctx = &brw->intel.ctx; | ||||
|    dri_bo *region_bo = NULL; | ||||
|    struct { | ||||
|       unsigned int surface_type; | ||||
| @@ -333,10 +334,10 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region, | ||||
|       key.height = 1; | ||||
|       key.cpp = 4; | ||||
|    } | ||||
|    memcpy(key.color_mask, brw->attribs.Color->ColorMask, | ||||
|    memcpy(key.color_mask, ctx->Color.ColorMask, | ||||
| 	  sizeof(key.color_mask)); | ||||
|    key.color_blend = (!brw->attribs.Color->_LogicOpEnabled && | ||||
| 		      brw->attribs.Color->BlendEnabled); | ||||
|    key.color_blend = (!ctx->Color._LogicOpEnabled && | ||||
| 		      ctx->Color.BlendEnabled); | ||||
|  | ||||
|    dri_bo_unreference(brw->wm.surf_bo[unit]); | ||||
|    brw->wm.surf_bo[unit] = NULL; | ||||
| @@ -380,8 +381,7 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region, | ||||
| 	  * a more restrictive relocation to emit. | ||||
| 	  */ | ||||
| 	 dri_bo_emit_reloc(brw->wm.surf_bo[unit], | ||||
| 			   I915_GEM_DOMAIN_RENDER | | ||||
| 			   I915_GEM_DOMAIN_SAMPLER, | ||||
| 			   I915_GEM_DOMAIN_RENDER, | ||||
| 			   I915_GEM_DOMAIN_RENDER, | ||||
| 			   0, | ||||
| 			   offsetof(struct brw_surface_state, ss1), | ||||
| @@ -459,7 +459,7 @@ static void prepare_wm_surfaces(struct brw_context *brw ) | ||||
|    brw->wm.nr_surfaces = MAX_DRAW_BUFFERS; | ||||
|  | ||||
|    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { | ||||
|       struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i]; | ||||
|       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; | ||||
|  | ||||
|       /* _NEW_TEXTURE, BRW_NEW_TEXDATA */ | ||||
|       if(texUnit->_ReallyEnabled) { | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/mesa/drivers/dri/i965/intel_clear.c
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								src/mesa/drivers/dri/i965/intel_clear.c
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ../intel/intel_clear.c | ||||
| @@ -38,7 +38,8 @@ | ||||
| #include "intel_regions.h" | ||||
| #include "swrast/swrast.h" | ||||
|  | ||||
| int intel_translate_shadow_compare_func( GLenum func ) | ||||
| int | ||||
| intel_translate_shadow_compare_func( GLenum func ) | ||||
| { | ||||
|    switch(func) { | ||||
|    case GL_NEVER:  | ||||
| @@ -63,7 +64,8 @@ int intel_translate_shadow_compare_func( GLenum func ) | ||||
|    return COMPAREFUNC_NEVER;  | ||||
| } | ||||
|  | ||||
| int intel_translate_compare_func( GLenum func ) | ||||
| int | ||||
| intel_translate_compare_func( GLenum func ) | ||||
| { | ||||
|    switch(func) { | ||||
|    case GL_NEVER:  | ||||
| @@ -88,7 +90,8 @@ int intel_translate_compare_func( GLenum func ) | ||||
|    return COMPAREFUNC_ALWAYS;  | ||||
| } | ||||
|  | ||||
| int intel_translate_stencil_op( GLenum op ) | ||||
| int | ||||
| intel_translate_stencil_op( GLenum op ) | ||||
| { | ||||
|    switch(op) { | ||||
|    case GL_KEEP:  | ||||
| @@ -112,7 +115,8 @@ int intel_translate_stencil_op( GLenum op ) | ||||
|    } | ||||
| } | ||||
|  | ||||
| int intel_translate_blend_factor( GLenum factor ) | ||||
| int | ||||
| intel_translate_blend_factor( GLenum factor ) | ||||
| { | ||||
|    switch(factor) { | ||||
|    case GL_ZERO:  | ||||
| @@ -151,7 +155,8 @@ int intel_translate_blend_factor( GLenum factor ) | ||||
|    return BLENDFACT_ZERO; | ||||
| } | ||||
|  | ||||
| int intel_translate_logic_op( GLenum opcode ) | ||||
| int | ||||
| intel_translate_logic_op( GLenum opcode ) | ||||
| { | ||||
|    switch(opcode) { | ||||
|    case GL_CLEAR:  | ||||
| @@ -192,33 +197,36 @@ int intel_translate_logic_op( GLenum opcode ) | ||||
| } | ||||
|  | ||||
|  | ||||
| static void intelClearColor(GLcontext *ctx, const GLfloat color[4]) | ||||
| static void | ||||
| intelClearColor(GLcontext *ctx, const GLfloat color[4]) | ||||
| { | ||||
|    struct intel_context *intel = intel_context(ctx); | ||||
|    GLubyte clear[4]; | ||||
|  | ||||
|    UNCLAMPED_FLOAT_TO_RGBA_CHAN(intel->clear_chan, color); | ||||
|    CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); | ||||
|    CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); | ||||
|    CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); | ||||
|    CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); | ||||
|  | ||||
|    intel->ClearColor8888 = INTEL_PACKCOLOR8888(intel->clear_chan[0], | ||||
| 					       intel->clear_chan[1], | ||||
| 					       intel->clear_chan[2], | ||||
| 					       intel->clear_chan[3]); | ||||
|    intel->ClearColor565 = INTEL_PACKCOLOR565(intel->clear_chan[0], | ||||
| 					     intel->clear_chan[1], | ||||
| 					     intel->clear_chan[2]); | ||||
|    /* compute both 32 and 16-bit clear values */ | ||||
|    intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], | ||||
|                                                clear[2], clear[3]); | ||||
|    intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Fallback to swrast for select and feedback. | ||||
|  */ | ||||
| static void intelRenderMode( GLcontext *ctx, GLenum mode ) | ||||
| static void | ||||
| intelRenderMode( GLcontext *ctx, GLenum mode ) | ||||
| { | ||||
|    struct intel_context *intel = intel_context(ctx); | ||||
|    FALLBACK( intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); | ||||
| } | ||||
|  | ||||
|  | ||||
| void intelInitStateFuncs( struct dd_function_table *functions ) | ||||
| void | ||||
| intelInitStateFuncs( struct dd_function_table *functions ) | ||||
| { | ||||
|    functions->RenderMode = intelRenderMode; | ||||
|    functions->ClearColor = intelClearColor; | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/mesa/drivers/dri/i965/intel_swapbuffers.c
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								src/mesa/drivers/dri/i965/intel_swapbuffers.c
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ../intel/intel_swapbuffers.c | ||||
| @@ -332,6 +332,8 @@ intelEmitCopyBlit(struct intel_context *intel, | ||||
|  | ||||
|    switch (cpp) { | ||||
|    case 1: | ||||
|       CMD = XY_SRC_COPY_BLT_CMD; | ||||
|       break; | ||||
|    case 2: | ||||
|    case 3: | ||||
|       BR13 |= (1 << 24); | ||||
|   | ||||
| @@ -25,25 +25,14 @@ | ||||
|  *  | ||||
|  **************************************************************************/ | ||||
|  | ||||
| #include "intel_screen.h" | ||||
| #include "intel_context.h" | ||||
| #include "intel_blit.h" | ||||
| #include "intel_buffers.h" | ||||
| #include "intel_chipset.h" | ||||
| #include "intel_depthstencil.h" | ||||
| #include "intel_fbo.h" | ||||
| #include "intel_regions.h" | ||||
| #include "intel_batchbuffer.h" | ||||
| #include "intel_reg.h" | ||||
| #include "main/context.h" | ||||
| #include "main/framebuffer.h" | ||||
| #include "swrast/swrast.h" | ||||
| #include "utils.h" | ||||
| #include "drirenderbuffer.h" | ||||
| #include "vblank.h" | ||||
| #include "i915_drm.h" | ||||
|  | ||||
| #define FILE_DEBUG_FLAG DEBUG_BLIT | ||||
|  | ||||
| /** | ||||
|  * XXX move this into a new dri/common/cliprects.c file. | ||||
| @@ -114,7 +103,6 @@ intel_get_cliprects(struct intel_context *intel, | ||||
| 		    int *x_off, int *y_off) | ||||
| { | ||||
|    __DRIdrawablePrivate *dPriv = intel->driDrawable; | ||||
|    struct intel_framebuffer *intel_fb = dPriv->driverPrivate; | ||||
|  | ||||
|    if (intel->constant_cliprect) { | ||||
|       /* FBO or DRI2 rendering, which can just use the fb's size. */ | ||||
| @@ -143,399 +131,6 @@ intel_get_cliprects(struct intel_context *intel, | ||||
|    } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * This will be called whenever the currently bound window is moved/resized. | ||||
|  * XXX: actually, it seems to NOT be called when the window is only moved (BP). | ||||
|  */ | ||||
| void | ||||
| intelWindowMoved(struct intel_context *intel) | ||||
| { | ||||
|    GLcontext *ctx = &intel->ctx; | ||||
|    __DRIdrawablePrivate *dPriv = intel->driDrawable; | ||||
|    struct intel_framebuffer *intel_fb = dPriv->driverPrivate; | ||||
|  | ||||
|    if (!intel->intelScreen->driScrnPriv->dri2.enabled && | ||||
|        intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { | ||||
|       volatile drm_i915_sarea_t *sarea = intel->sarea; | ||||
|       drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, | ||||
| 				   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; | ||||
|       drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, | ||||
| 				     .x2 = sarea->planeA_x + sarea->planeA_w, | ||||
| 				     .y2 = sarea->planeA_y + sarea->planeA_h }; | ||||
|       drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, | ||||
| 				     .x2 = sarea->planeB_x + sarea->planeB_w, | ||||
| 				     .y2 = sarea->planeB_y + sarea->planeB_h }; | ||||
|       GLint areaA = driIntersectArea( drw_rect, planeA_rect ); | ||||
|       GLint areaB = driIntersectArea( drw_rect, planeB_rect ); | ||||
|       GLuint flags = dPriv->vblFlags; | ||||
|  | ||||
|       /* Update vblank info | ||||
|        */ | ||||
|       if (areaB > areaA || (areaA == areaB && areaB > 0)) { | ||||
| 	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; | ||||
|       } else { | ||||
| 	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; | ||||
|       } | ||||
|  | ||||
|       /* Check to see if we changed pipes */ | ||||
|       if (flags != dPriv->vblFlags && dPriv->vblFlags && | ||||
| 	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { | ||||
| 	 int64_t count; | ||||
| 	 drmVBlank vbl; | ||||
| 	 int i; | ||||
|  | ||||
| 	 /* | ||||
| 	  * Deal with page flipping | ||||
| 	  */ | ||||
| 	 vbl.request.type = DRM_VBLANK_ABSOLUTE; | ||||
|  | ||||
| 	 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { | ||||
| 	    vbl.request.type |= DRM_VBLANK_SECONDARY; | ||||
| 	 } | ||||
|  | ||||
| 	 for (i = 0; i < 2; i++) { | ||||
| 	    if (!intel_fb->color_rb[i] || | ||||
| 		(intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <= | ||||
| 		(1<<23)) | ||||
| 	       continue; | ||||
|  | ||||
| 	    vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending; | ||||
| 	    drmWaitVBlank(intel->driFd, &vbl); | ||||
| 	 } | ||||
|  | ||||
| 	 /* | ||||
| 	  * Update msc_base from old pipe | ||||
| 	  */ | ||||
| 	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count); | ||||
| 	 dPriv->msc_base = count; | ||||
| 	 /* | ||||
| 	  * Then get new vblank_base and vblSeq values | ||||
| 	  */ | ||||
| 	 dPriv->vblFlags = flags; | ||||
| 	 driGetCurrentVBlank(dPriv); | ||||
| 	 dPriv->vblank_base = dPriv->vblSeq; | ||||
|  | ||||
| 	 intel_fb->vbl_waited = dPriv->vblSeq; | ||||
|  | ||||
| 	 for (i = 0; i < 2; i++) { | ||||
| 	    if (intel_fb->color_rb[i]) | ||||
| 	       intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited; | ||||
| 	 } | ||||
|       } | ||||
|    } else { | ||||
|       dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; | ||||
|    } | ||||
|  | ||||
|    /* Update Mesa's notion of window size */ | ||||
|    driUpdateFramebufferSize(ctx, dPriv); | ||||
|    intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */ | ||||
|  | ||||
|    /* Update hardware scissor */ | ||||
|    if (ctx->Driver.Scissor != NULL) { | ||||
|       ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, | ||||
| 			  ctx->Scissor.Width, ctx->Scissor.Height); | ||||
|    } | ||||
|  | ||||
|    /* Re-calculate viewport related state */ | ||||
|    if (ctx->Driver.DepthRange != NULL) | ||||
|       ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* A true meta version of this would be very simple and additionally | ||||
|  * machine independent.  Maybe we'll get there one day. | ||||
|  */ | ||||
| static void | ||||
| intelClearWithTris(struct intel_context *intel, GLbitfield mask) | ||||
| { | ||||
|    GLcontext *ctx = &intel->ctx; | ||||
|    struct gl_framebuffer *fb = ctx->DrawBuffer; | ||||
|    GLuint buf; | ||||
|  | ||||
|    intel->vtbl.install_meta_state(intel); | ||||
|  | ||||
|    /* Back and stencil cliprects are the same.  Try and do both | ||||
|     * buffers at once: | ||||
|     */ | ||||
|    if (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) { | ||||
|       struct intel_region *backRegion = | ||||
| 	 intel_get_rb_region(fb, BUFFER_BACK_LEFT); | ||||
|       struct intel_region *depthRegion = | ||||
| 	 intel_get_rb_region(fb, BUFFER_DEPTH); | ||||
|  | ||||
|       intel->vtbl.meta_draw_region(intel, backRegion, depthRegion); | ||||
|  | ||||
|       if (mask & BUFFER_BIT_BACK_LEFT) | ||||
| 	 intel->vtbl.meta_color_mask(intel, GL_TRUE); | ||||
|       else | ||||
| 	 intel->vtbl.meta_color_mask(intel, GL_FALSE); | ||||
|  | ||||
|       if (mask & BUFFER_BIT_STENCIL) | ||||
| 	 intel->vtbl.meta_stencil_replace(intel, | ||||
| 					  intel->ctx.Stencil.WriteMask[0], | ||||
| 					  intel->ctx.Stencil.Clear); | ||||
|       else | ||||
| 	 intel->vtbl.meta_no_stencil_write(intel); | ||||
|  | ||||
|       if (mask & BUFFER_BIT_DEPTH) | ||||
| 	 intel->vtbl.meta_depth_replace(intel); | ||||
|       else | ||||
| 	 intel->vtbl.meta_no_depth_write(intel); | ||||
|  | ||||
|       intel->vtbl.meta_draw_quad(intel, | ||||
| 				 fb->_Xmin, | ||||
| 				 fb->_Xmax, | ||||
| 				 fb->_Ymin, | ||||
| 				 fb->_Ymax, | ||||
| 				 intel->ctx.Depth.Clear, | ||||
| 				 intel->ClearColor8888, | ||||
| 				 0, 0, 0, 0);   /* texcoords */ | ||||
|  | ||||
|       mask &= ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH); | ||||
|    } | ||||
|  | ||||
|    /* clear the remaining (color) renderbuffers */ | ||||
|    for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { | ||||
|       const GLuint bufBit = 1 << buf; | ||||
|       if (mask & bufBit) { | ||||
| 	 struct intel_renderbuffer *irbColor = | ||||
| 	    intel_renderbuffer(fb->Attachment[buf].Renderbuffer); | ||||
|  | ||||
| 	 ASSERT(irbColor); | ||||
|  | ||||
| 	 intel->vtbl.meta_no_depth_write(intel); | ||||
| 	 intel->vtbl.meta_no_stencil_write(intel); | ||||
| 	 intel->vtbl.meta_color_mask(intel, GL_TRUE); | ||||
| 	 intel->vtbl.meta_draw_region(intel, irbColor->region, NULL); | ||||
|  | ||||
| 	 intel->vtbl.meta_draw_quad(intel, | ||||
| 				    fb->_Xmin, | ||||
| 				    fb->_Xmax, | ||||
| 				    fb->_Ymin, | ||||
| 				    fb->_Ymax, | ||||
| 				    0, intel->ClearColor8888, | ||||
| 				    0, 0, 0, 0);   /* texcoords */ | ||||
|  | ||||
| 	 mask &= ~bufBit; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    intel->vtbl.leave_meta_state(intel); | ||||
| } | ||||
|  | ||||
| static const char *buffer_names[] = { | ||||
|    [BUFFER_FRONT_LEFT] = "front", | ||||
|    [BUFFER_BACK_LEFT] = "back", | ||||
|    [BUFFER_FRONT_RIGHT] = "front right", | ||||
|    [BUFFER_BACK_RIGHT] = "back right", | ||||
|    [BUFFER_AUX0] = "aux0", | ||||
|    [BUFFER_AUX1] = "aux1", | ||||
|    [BUFFER_AUX2] = "aux2", | ||||
|    [BUFFER_AUX3] = "aux3", | ||||
|    [BUFFER_DEPTH] = "depth", | ||||
|    [BUFFER_STENCIL] = "stencil", | ||||
|    [BUFFER_ACCUM] = "accum", | ||||
|    [BUFFER_COLOR0] = "color0", | ||||
|    [BUFFER_COLOR1] = "color1", | ||||
|    [BUFFER_COLOR2] = "color2", | ||||
|    [BUFFER_COLOR3] = "color3", | ||||
|    [BUFFER_COLOR4] = "color4", | ||||
|    [BUFFER_COLOR5] = "color5", | ||||
|    [BUFFER_COLOR6] = "color6", | ||||
|    [BUFFER_COLOR7] = "color7", | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Called by ctx->Driver.Clear. | ||||
|  */ | ||||
| static void | ||||
| intelClear(GLcontext *ctx, GLbitfield mask) | ||||
| { | ||||
|    struct intel_context *intel = intel_context(ctx); | ||||
|    const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); | ||||
|    GLbitfield tri_mask = 0; | ||||
|    GLbitfield blit_mask = 0; | ||||
|    GLbitfield swrast_mask = 0; | ||||
|    struct gl_framebuffer *fb = ctx->DrawBuffer; | ||||
|    GLuint i; | ||||
|  | ||||
|    if (0) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    /* HW color buffers (front, back, aux, generic FBO, etc) */ | ||||
|    if (colorMask == ~0) { | ||||
|       /* clear all R,G,B,A */ | ||||
|       /* XXX FBO: need to check if colorbuffers are software RBOs! */ | ||||
|       blit_mask |= (mask & BUFFER_BITS_COLOR); | ||||
|    } | ||||
|    else { | ||||
|       /* glColorMask in effect */ | ||||
|       tri_mask |= (mask & BUFFER_BITS_COLOR); | ||||
|    } | ||||
|  | ||||
|    /* HW stencil */ | ||||
|    if (mask & BUFFER_BIT_STENCIL) { | ||||
|       const struct intel_region *stencilRegion | ||||
|          = intel_get_rb_region(fb, BUFFER_STENCIL); | ||||
|       if (stencilRegion) { | ||||
|          /* have hw stencil */ | ||||
|          if (IS_965(intel->intelScreen->deviceID) || | ||||
| 	     (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { | ||||
| 	    /* We have to use the 3D engine if we're clearing a partial mask | ||||
| 	     * of the stencil buffer, or if we're on a 965 which has a tiled | ||||
| 	     * depth/stencil buffer in a layout we can't blit to. | ||||
| 	     */ | ||||
|             tri_mask |= BUFFER_BIT_STENCIL; | ||||
|          } | ||||
|          else { | ||||
|             /* clearing all stencil bits, use blitting */ | ||||
|             blit_mask |= BUFFER_BIT_STENCIL; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* HW depth */ | ||||
|    if (mask & BUFFER_BIT_DEPTH) { | ||||
|       /* clear depth with whatever method is used for stencil (see above) */ | ||||
|       if (IS_965(intel->intelScreen->deviceID) || | ||||
| 	  tri_mask & BUFFER_BIT_STENCIL) | ||||
|          tri_mask |= BUFFER_BIT_DEPTH; | ||||
|       else | ||||
|          blit_mask |= BUFFER_BIT_DEPTH; | ||||
|    } | ||||
|  | ||||
|    /* SW fallback clearing */ | ||||
|    swrast_mask = mask & ~tri_mask & ~blit_mask; | ||||
|  | ||||
|    for (i = 0; i < BUFFER_COUNT; i++) { | ||||
|       GLuint bufBit = 1 << i; | ||||
|       if ((blit_mask | tri_mask) & bufBit) { | ||||
|          if (!fb->Attachment[i].Renderbuffer->ClassID) { | ||||
|             blit_mask &= ~bufBit; | ||||
|             tri_mask &= ~bufBit; | ||||
|             swrast_mask |= bufBit; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (blit_mask) { | ||||
|       if (INTEL_DEBUG & DEBUG_BLIT) { | ||||
| 	 DBG("blit clear:"); | ||||
| 	 for (i = 0; i < BUFFER_COUNT; i++) { | ||||
| 	    if (blit_mask & (1 << i)) | ||||
| 	       DBG(" %s", buffer_names[i]); | ||||
| 	 } | ||||
| 	 DBG("\n"); | ||||
|       } | ||||
|       intelClearWithBlit(ctx, blit_mask); | ||||
|    } | ||||
|  | ||||
|    if (tri_mask) { | ||||
|       if (INTEL_DEBUG & DEBUG_BLIT) { | ||||
| 	 DBG("tri clear:"); | ||||
| 	 for (i = 0; i < BUFFER_COUNT; i++) { | ||||
| 	    if (tri_mask & (1 << i)) | ||||
| 	       DBG(" %s", buffer_names[i]); | ||||
| 	 } | ||||
| 	 DBG("\n"); | ||||
|       } | ||||
|       intelClearWithTris(intel, tri_mask); | ||||
|    } | ||||
|  | ||||
|    if (swrast_mask) { | ||||
|       if (INTEL_DEBUG & DEBUG_BLIT) { | ||||
| 	 DBG("swrast clear:"); | ||||
| 	 for (i = 0; i < BUFFER_COUNT; i++) { | ||||
| 	    if (swrast_mask & (1 << i)) | ||||
| 	       DBG(" %s", buffer_names[i]); | ||||
| 	 } | ||||
| 	 DBG("\n"); | ||||
|       } | ||||
|       _swrast_Clear(ctx, swrast_mask); | ||||
|    } | ||||
| } | ||||
|  | ||||
| void | ||||
| intelSwapBuffers(__DRIdrawablePrivate * dPriv) | ||||
| { | ||||
|    __DRIscreenPrivate *psp = dPriv->driScreenPriv; | ||||
|  | ||||
|    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { | ||||
|       GET_CURRENT_CONTEXT(ctx); | ||||
|       struct intel_context *intel; | ||||
|  | ||||
|       if (ctx == NULL) | ||||
| 	 return; | ||||
|  | ||||
|       intel = intel_context(ctx); | ||||
|  | ||||
|       if (ctx->Visual.doubleBufferMode) { | ||||
| 	 GLboolean missed_target; | ||||
| 	 struct intel_framebuffer *intel_fb = dPriv->driverPrivate; | ||||
| 	 int64_t ust; | ||||
|           | ||||
| 	 _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */ | ||||
|  | ||||
| 	/* | ||||
| 	 * The old swapping ioctl was incredibly racy, just wait for vblank | ||||
| 	 * and do the swap ourselves. | ||||
| 	 */ | ||||
| 	 driWaitForVBlank(dPriv, &missed_target); | ||||
|  | ||||
| 	 /* | ||||
| 	  * Update each buffer's vbl_pending so we don't get too out of | ||||
| 	  * sync | ||||
| 	  */ | ||||
| 	 intel_get_renderbuffer(&intel_fb->Base, | ||||
| 		   		BUFFER_BACK_LEFT)->vbl_pending = dPriv->vblSeq; | ||||
|          intel_get_renderbuffer(&intel_fb->Base, | ||||
| 		   		BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq; | ||||
|  | ||||
| 	 intelCopyBuffer(dPriv, NULL); | ||||
|  | ||||
| 	 intel_fb->swap_count++; | ||||
| 	 (*psp->systemTime->getUST) (&ust); | ||||
| 	 if (missed_target) { | ||||
| 	    intel_fb->swap_missed_count++; | ||||
| 	    intel_fb->swap_missed_ust = ust - intel_fb->swap_ust; | ||||
| 	 } | ||||
|  | ||||
| 	 intel_fb->swap_ust = ust; | ||||
|       } | ||||
|       drmCommandNone(intel->driFd, DRM_I915_GEM_THROTTLE); | ||||
|  | ||||
|    } | ||||
|    else { | ||||
|       /* XXX this shouldn't be an error but we can't handle it for now */ | ||||
|       fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); | ||||
|    } | ||||
| } | ||||
|  | ||||
| void | ||||
| intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) | ||||
| { | ||||
|    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { | ||||
|       struct intel_context *intel = | ||||
|          (struct intel_context *) dPriv->driContextPriv->driverPrivate; | ||||
|       GLcontext *ctx = &intel->ctx; | ||||
|  | ||||
|       if (ctx->Visual.doubleBufferMode) { | ||||
|          drm_clip_rect_t rect; | ||||
|          rect.x1 = x + dPriv->x; | ||||
|          rect.y1 = (dPriv->h - y - h) + dPriv->y; | ||||
|          rect.x2 = rect.x1 + w; | ||||
|          rect.y2 = rect.y1 + h; | ||||
|          _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */ | ||||
|          intelCopyBuffer(dPriv, &rect); | ||||
|       } | ||||
|    } | ||||
|    else { | ||||
|       /* XXX this shouldn't be an error but we can't handle it for now */ | ||||
|       fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Update the hardware state for drawing into a window or framebuffer object. | ||||
| @@ -711,13 +306,11 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) | ||||
| 	fb->_NumColorDrawBuffers); | ||||
|  | ||||
|    /* update viewport since it depends on window size */ | ||||
|    if (ctx->Driver.Viewport) { | ||||
|       ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, | ||||
| 			   ctx->Viewport.Width, ctx->Viewport.Height); | ||||
|    } else { | ||||
|       ctx->NewState |= _NEW_VIEWPORT; | ||||
|    } | ||||
|  | ||||
| #ifdef I915 | ||||
|    intelCalcViewport(ctx); | ||||
| #else | ||||
|    ctx->NewState |= _NEW_VIEWPORT; | ||||
| #endif | ||||
|    /* Set state we know depends on drawable parameters: | ||||
|     */ | ||||
|    if (ctx->Driver.Scissor) | ||||
| @@ -759,7 +352,6 @@ intelReadBuffer(GLcontext * ctx, GLenum mode) | ||||
| void | ||||
| intelInitBufferFuncs(struct dd_function_table *functions) | ||||
| { | ||||
|    functions->Clear = intelClear; | ||||
|    functions->DrawBuffer = intelDrawBuffer; | ||||
|    functions->ReadBuffer = intelReadBuffer; | ||||
| } | ||||
|   | ||||
| @@ -45,10 +45,6 @@ extern struct intel_region *intel_readbuf_region(struct intel_context *intel); | ||||
|  | ||||
| extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); | ||||
|  | ||||
| extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); | ||||
|  | ||||
| extern void intelWindowMoved(struct intel_context *intel); | ||||
|  | ||||
| extern void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb); | ||||
|  | ||||
| extern void intelInitBufferFuncs(struct dd_function_table *functions); | ||||
| @@ -57,5 +53,8 @@ void intel_get_cliprects(struct intel_context *intel, | ||||
| 			 struct drm_clip_rect **cliprects, | ||||
| 			 unsigned int *num_cliprects, | ||||
| 			 int *x_off, int *y_off); | ||||
| #ifdef I915 | ||||
| void intelCalcViewport(GLcontext * ctx); | ||||
| #endif | ||||
|  | ||||
| #endif /* INTEL_BUFFERS_H */ | ||||
|   | ||||
| @@ -46,6 +46,13 @@ | ||||
| #define PCI_CHIP_G33_G			0x29C2 | ||||
| #define PCI_CHIP_Q33_G			0x29D2 | ||||
|  | ||||
| #define PCI_CHIP_IGD_GM			0xA011 | ||||
| #define PCI_CHIP_IGD_G			0xA001 | ||||
|  | ||||
| #define IS_IGDGM(devid)	(devid == PCI_CHIP_IGD_GM) | ||||
| #define IS_IGDG(devid)	(devid == PCI_CHIP_IGD_G) | ||||
| #define IS_IGD(devid) (IS_IGDG(devid) || IS_IGDGM(devid)) | ||||
|  | ||||
| #define PCI_CHIP_I965_G			0x29A2 | ||||
| #define PCI_CHIP_I965_Q			0x2992 | ||||
| #define PCI_CHIP_I965_G_1		0x2982 | ||||
| @@ -66,7 +73,7 @@ | ||||
| 				 devid == PCI_CHIP_I945_GME || \ | ||||
| 				 devid == PCI_CHIP_I965_GM || \ | ||||
| 				 devid == PCI_CHIP_I965_GME || \ | ||||
| 				 devid == PCI_CHIP_GM45_GM) | ||||
| 				 devid == PCI_CHIP_GM45_GM || IS_IGD(devid)) | ||||
|  | ||||
| #define IS_G45(devid)           (devid == PCI_CHIP_IGD_E_G || \ | ||||
|                                  devid == PCI_CHIP_Q45_G || \ | ||||
| @@ -84,7 +91,7 @@ | ||||
| 				 devid == PCI_CHIP_I945_GME || \ | ||||
| 				 devid == PCI_CHIP_G33_G || \ | ||||
| 				 devid == PCI_CHIP_Q33_G || \ | ||||
| 				 devid == PCI_CHIP_Q35_G) | ||||
| 				 devid == PCI_CHIP_Q35_G || IS_IGD(devid)) | ||||
|  | ||||
| #define IS_965(devid)		(devid == PCI_CHIP_I965_G || \ | ||||
| 				 devid == PCI_CHIP_I965_Q || \ | ||||
|   | ||||
							
								
								
									
										393
									
								
								src/mesa/drivers/dri/intel/intel_clear.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								src/mesa/drivers/dri/intel/intel_clear.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,393 @@ | ||||
| /************************************************************************** | ||||
|  *  | ||||
|  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | ||||
|  * Copyright 2009 Intel Corporation. | ||||
|  * 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. | ||||
|  *  | ||||
|  **************************************************************************/ | ||||
|  | ||||
| #include "main/glheader.h" | ||||
| #include "main/enums.h" | ||||
| #include "main/image.h" | ||||
| #include "main/mtypes.h" | ||||
| #include "main/attrib.h" | ||||
| #include "main/blend.h" | ||||
| #include "main/bufferobj.h" | ||||
| #include "main/buffers.h" | ||||
| #include "main/depth.h" | ||||
| #include "main/enable.h" | ||||
| #include "main/macros.h" | ||||
| #include "main/matrix.h" | ||||
| #include "main/texstate.h" | ||||
| #include "main/shaders.h" | ||||
| #include "main/stencil.h" | ||||
| #include "main/varray.h" | ||||
| #include "glapi/dispatch.h" | ||||
| #include "swrast/swrast.h" | ||||
|  | ||||
| #include "intel_context.h" | ||||
| #include "intel_blit.h" | ||||
| #include "intel_chipset.h" | ||||
| #include "intel_clear.h" | ||||
| #include "intel_fbo.h" | ||||
| #include "intel_pixel.h" | ||||
|  | ||||
| #define FILE_DEBUG_FLAG DEBUG_BLIT | ||||
|  | ||||
| #define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT |			\ | ||||
| 			      BUFFER_BIT_FRONT_LEFT |			\ | ||||
| 			      BUFFER_BIT_COLOR0 |			\ | ||||
| 			      BUFFER_BIT_COLOR1 |			\ | ||||
| 			      BUFFER_BIT_COLOR2 |			\ | ||||
| 			      BUFFER_BIT_COLOR3 |			\ | ||||
| 			      BUFFER_BIT_COLOR4 |			\ | ||||
| 			      BUFFER_BIT_COLOR5 |			\ | ||||
| 			      BUFFER_BIT_COLOR6 |			\ | ||||
| 			      BUFFER_BIT_COLOR7) | ||||
|  | ||||
| /** | ||||
|  * Perform glClear where mask contains only color, depth, and/or stencil. | ||||
|  * | ||||
|  * The implementation is based on calling into Mesa to set GL state and | ||||
|  * performing normal triangle rendering.  The intent of this path is to | ||||
|  * have as generic a path as possible, so that any driver could make use of | ||||
|  * it. | ||||
|  */ | ||||
| void | ||||
| intel_clear_tris(GLcontext *ctx, GLbitfield mask) | ||||
| { | ||||
|    struct intel_context *intel = intel_context(ctx); | ||||
|    GLfloat vertices[4][3]; | ||||
|    GLfloat color[4][4]; | ||||
|    GLfloat dst_z; | ||||
|    struct gl_framebuffer *fb = ctx->DrawBuffer; | ||||
|    int i; | ||||
|    GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; | ||||
|    GLuint saved_shader_program = 0; | ||||
|    unsigned int saved_active_texture; | ||||
|  | ||||
|    assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | | ||||
| 		    BUFFER_BIT_STENCIL)) == 0); | ||||
|  | ||||
|    _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | | ||||
| 		    GL_CURRENT_BIT | | ||||
| 		    GL_DEPTH_BUFFER_BIT | | ||||
| 		    GL_ENABLE_BIT | | ||||
| 		    GL_STENCIL_BUFFER_BIT | | ||||
| 		    GL_TRANSFORM_BIT | | ||||
| 		    GL_CURRENT_BIT); | ||||
|    _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); | ||||
|    saved_active_texture = ctx->Texture.CurrentUnit; | ||||
|  | ||||
|    /* Disable existing GL state we don't want to apply to a clear. */ | ||||
|    _mesa_Disable(GL_ALPHA_TEST); | ||||
|    _mesa_Disable(GL_BLEND); | ||||
|    _mesa_Disable(GL_CULL_FACE); | ||||
|    _mesa_Disable(GL_FOG); | ||||
|    _mesa_Disable(GL_POLYGON_SMOOTH); | ||||
|    _mesa_Disable(GL_POLYGON_STIPPLE); | ||||
|    _mesa_Disable(GL_POLYGON_OFFSET_FILL); | ||||
|    _mesa_Disable(GL_LIGHTING); | ||||
|    _mesa_Disable(GL_CLIP_PLANE0); | ||||
|    _mesa_Disable(GL_CLIP_PLANE1); | ||||
|    _mesa_Disable(GL_CLIP_PLANE2); | ||||
|    _mesa_Disable(GL_CLIP_PLANE3); | ||||
|    _mesa_Disable(GL_CLIP_PLANE4); | ||||
|    _mesa_Disable(GL_CLIP_PLANE5); | ||||
|    if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { | ||||
|       saved_fp_enable = GL_TRUE; | ||||
|       _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); | ||||
|    } | ||||
|    if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { | ||||
|       saved_vp_enable = GL_TRUE; | ||||
|       _mesa_Disable(GL_VERTEX_PROGRAM_ARB); | ||||
|    } | ||||
|    if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { | ||||
|       saved_shader_program = ctx->Shader.CurrentProgram->Name; | ||||
|       _mesa_UseProgramObjectARB(0); | ||||
|    } | ||||
|  | ||||
|    if (ctx->Texture._EnabledUnits != 0) { | ||||
|       int i; | ||||
|  | ||||
|       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { | ||||
| 	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i); | ||||
| 	 _mesa_Disable(GL_TEXTURE_1D); | ||||
| 	 _mesa_Disable(GL_TEXTURE_2D); | ||||
| 	 _mesa_Disable(GL_TEXTURE_3D); | ||||
| 	 if (ctx->Extensions.ARB_texture_cube_map) | ||||
| 	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); | ||||
| 	 if (ctx->Extensions.NV_texture_rectangle) | ||||
| 	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); | ||||
| 	 if (ctx->Extensions.MESA_texture_array) { | ||||
| 	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); | ||||
| 	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    intel_meta_set_passthrough_transform(intel); | ||||
|  | ||||
|    for (i = 0; i < 4; i++) { | ||||
|       color[i][0] = ctx->Color.ClearColor[0]; | ||||
|       color[i][1] = ctx->Color.ClearColor[1]; | ||||
|       color[i][2] = ctx->Color.ClearColor[2]; | ||||
|       color[i][3] = ctx->Color.ClearColor[3]; | ||||
|    } | ||||
|  | ||||
|    /* convert clear Z from [0,1] to NDC coord in [-1,1] */ | ||||
|    dst_z = -1.0 + 2.0 * ctx->Depth.Clear; | ||||
|  | ||||
|    /* Prepare the vertices, which are the same regardless of which buffer we're | ||||
|     * drawing to. | ||||
|     */ | ||||
|    vertices[0][0] = fb->_Xmin; | ||||
|    vertices[0][1] = fb->_Ymin; | ||||
|    vertices[0][2] = dst_z; | ||||
|    vertices[1][0] = fb->_Xmax; | ||||
|    vertices[1][1] = fb->_Ymin; | ||||
|    vertices[1][2] = dst_z; | ||||
|    vertices[2][0] = fb->_Xmax; | ||||
|    vertices[2][1] = fb->_Ymax; | ||||
|    vertices[2][2] = dst_z; | ||||
|    vertices[3][0] = fb->_Xmin; | ||||
|    vertices[3][1] = fb->_Ymax; | ||||
|    vertices[3][2] = dst_z; | ||||
|  | ||||
|    _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); | ||||
|    _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); | ||||
|    _mesa_Enable(GL_COLOR_ARRAY); | ||||
|    _mesa_Enable(GL_VERTEX_ARRAY); | ||||
|  | ||||
|    while (mask != 0) { | ||||
|       GLuint this_mask = 0; | ||||
|       GLuint color_bit; | ||||
|  | ||||
|       color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); | ||||
|       if (color_bit != 0) | ||||
| 	 this_mask |= (1 << (color_bit - 1)); | ||||
|  | ||||
|       /* Clear depth/stencil in the same pass as color. */ | ||||
|       this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); | ||||
|  | ||||
|       /* Select the current color buffer and use the color write mask if | ||||
|        * we have one, otherwise don't write any color channels. | ||||
|        */ | ||||
|       if (this_mask & BUFFER_BIT_FRONT_LEFT) | ||||
| 	 _mesa_DrawBuffer(GL_FRONT_LEFT); | ||||
|       else if (this_mask & BUFFER_BIT_BACK_LEFT) | ||||
| 	 _mesa_DrawBuffer(GL_BACK_LEFT); | ||||
|       else if (color_bit != 0) | ||||
| 	 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + | ||||
| 			  (color_bit - BUFFER_COLOR0 - 1)); | ||||
|       else | ||||
| 	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | ||||
|  | ||||
|       /* Control writing of the depth clear value to depth. */ | ||||
|       if (this_mask & BUFFER_BIT_DEPTH) { | ||||
| 	 _mesa_DepthFunc(GL_ALWAYS); | ||||
| 	 _mesa_Enable(GL_DEPTH_TEST); | ||||
|       } else { | ||||
| 	 _mesa_Disable(GL_DEPTH_TEST); | ||||
| 	 _mesa_DepthMask(GL_FALSE); | ||||
|       } | ||||
|  | ||||
|       /* Control writing of the stencil clear value to stencil. */ | ||||
|       if (this_mask & BUFFER_BIT_STENCIL) { | ||||
| 	 _mesa_Enable(GL_STENCIL_TEST); | ||||
| 	 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); | ||||
| 	 _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, | ||||
| 				   ctx->Stencil.WriteMask[0]); | ||||
|       } else { | ||||
| 	 _mesa_Disable(GL_STENCIL_TEST); | ||||
|       } | ||||
|  | ||||
|       CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); | ||||
|  | ||||
|       mask &= ~this_mask; | ||||
|    } | ||||
|  | ||||
|    intel_meta_restore_transform(intel); | ||||
|  | ||||
|    _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); | ||||
|    if (saved_fp_enable) | ||||
|       _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); | ||||
|    if (saved_vp_enable) | ||||
|       _mesa_Enable(GL_VERTEX_PROGRAM_ARB); | ||||
|  | ||||
|    if (saved_shader_program) | ||||
|       _mesa_UseProgramObjectARB(saved_shader_program); | ||||
|  | ||||
|    _mesa_PopClientAttrib(); | ||||
|    _mesa_PopAttrib(); | ||||
| } | ||||
|  | ||||
| static const char *buffer_names[] = { | ||||
|    [BUFFER_FRONT_LEFT] = "front", | ||||
|    [BUFFER_BACK_LEFT] = "back", | ||||
|    [BUFFER_FRONT_RIGHT] = "front right", | ||||
|    [BUFFER_BACK_RIGHT] = "back right", | ||||
|    [BUFFER_AUX0] = "aux0", | ||||
|    [BUFFER_AUX1] = "aux1", | ||||
|    [BUFFER_AUX2] = "aux2", | ||||
|    [BUFFER_AUX3] = "aux3", | ||||
|    [BUFFER_DEPTH] = "depth", | ||||
|    [BUFFER_STENCIL] = "stencil", | ||||
|    [BUFFER_ACCUM] = "accum", | ||||
|    [BUFFER_COLOR0] = "color0", | ||||
|    [BUFFER_COLOR1] = "color1", | ||||
|    [BUFFER_COLOR2] = "color2", | ||||
|    [BUFFER_COLOR3] = "color3", | ||||
|    [BUFFER_COLOR4] = "color4", | ||||
|    [BUFFER_COLOR5] = "color5", | ||||
|    [BUFFER_COLOR6] = "color6", | ||||
|    [BUFFER_COLOR7] = "color7", | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Called by ctx->Driver.Clear. | ||||
|  */ | ||||
| static void | ||||
| intelClear(GLcontext *ctx, GLbitfield mask) | ||||
| { | ||||
|    struct intel_context *intel = intel_context(ctx); | ||||
|    const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); | ||||
|    GLbitfield tri_mask = 0; | ||||
|    GLbitfield blit_mask = 0; | ||||
|    GLbitfield swrast_mask = 0; | ||||
|    struct gl_framebuffer *fb = ctx->DrawBuffer; | ||||
|    GLuint i; | ||||
|  | ||||
|    if (0) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    /* HW color buffers (front, back, aux, generic FBO, etc) */ | ||||
|    if (colorMask == ~0) { | ||||
|       /* clear all R,G,B,A */ | ||||
|       /* XXX FBO: need to check if colorbuffers are software RBOs! */ | ||||
|       blit_mask |= (mask & BUFFER_BITS_COLOR); | ||||
|    } | ||||
|    else { | ||||
|       /* glColorMask in effect */ | ||||
|       tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)); | ||||
|    } | ||||
|  | ||||
|    /* HW stencil */ | ||||
|    if (mask & BUFFER_BIT_STENCIL) { | ||||
|       const struct intel_region *stencilRegion | ||||
|          = intel_get_rb_region(fb, BUFFER_STENCIL); | ||||
|       if (stencilRegion) { | ||||
|          /* have hw stencil */ | ||||
|          if (IS_965(intel->intelScreen->deviceID) || | ||||
| 	     (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { | ||||
| 	    /* We have to use the 3D engine if we're clearing a partial mask | ||||
| 	     * of the stencil buffer, or if we're on a 965 which has a tiled | ||||
| 	     * depth/stencil buffer in a layout we can't blit to. | ||||
| 	     */ | ||||
|             tri_mask |= BUFFER_BIT_STENCIL; | ||||
|          } | ||||
|          else { | ||||
|             /* clearing all stencil bits, use blitting */ | ||||
|             blit_mask |= BUFFER_BIT_STENCIL; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* HW depth */ | ||||
|    if (mask & BUFFER_BIT_DEPTH) { | ||||
|       /* clear depth with whatever method is used for stencil (see above) */ | ||||
|       if (IS_965(intel->intelScreen->deviceID) || | ||||
| 	  tri_mask & BUFFER_BIT_STENCIL) | ||||
|          tri_mask |= BUFFER_BIT_DEPTH; | ||||
|       else | ||||
|          blit_mask |= BUFFER_BIT_DEPTH; | ||||
|    } | ||||
|  | ||||
|    /* If we're doing a tri pass for depth/stencil, include a likely color | ||||
|     * buffer with it. | ||||
|     */ | ||||
|    if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) { | ||||
|       int color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); | ||||
|       if (color_bit != 0) { | ||||
| 	 tri_mask |= blit_mask & (1 << (color_bit - 1)); | ||||
| 	 blit_mask &= ~(1 << (color_bit - 1)); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* SW fallback clearing */ | ||||
|    swrast_mask = mask & ~tri_mask & ~blit_mask; | ||||
|  | ||||
|    for (i = 0; i < BUFFER_COUNT; i++) { | ||||
|       GLuint bufBit = 1 << i; | ||||
|       if ((blit_mask | tri_mask) & bufBit) { | ||||
|          if (!fb->Attachment[i].Renderbuffer->ClassID) { | ||||
|             blit_mask &= ~bufBit; | ||||
|             tri_mask &= ~bufBit; | ||||
|             swrast_mask |= bufBit; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (blit_mask) { | ||||
|       if (INTEL_DEBUG & DEBUG_BLIT) { | ||||
| 	 DBG("blit clear:"); | ||||
| 	 for (i = 0; i < BUFFER_COUNT; i++) { | ||||
| 	    if (blit_mask & (1 << i)) | ||||
| 	       DBG(" %s", buffer_names[i]); | ||||
| 	 } | ||||
| 	 DBG("\n"); | ||||
|       } | ||||
|       intelClearWithBlit(ctx, blit_mask); | ||||
|    } | ||||
|  | ||||
|    if (tri_mask) { | ||||
|       if (INTEL_DEBUG & DEBUG_BLIT) { | ||||
| 	 DBG("tri clear:"); | ||||
| 	 for (i = 0; i < BUFFER_COUNT; i++) { | ||||
| 	    if (tri_mask & (1 << i)) | ||||
| 	       DBG(" %s", buffer_names[i]); | ||||
| 	 } | ||||
| 	 DBG("\n"); | ||||
|       } | ||||
|       intel_clear_tris(ctx, tri_mask); | ||||
|    } | ||||
|  | ||||
|    if (swrast_mask) { | ||||
|       if (INTEL_DEBUG & DEBUG_BLIT) { | ||||
| 	 DBG("swrast clear:"); | ||||
| 	 for (i = 0; i < BUFFER_COUNT; i++) { | ||||
| 	    if (swrast_mask & (1 << i)) | ||||
| 	       DBG(" %s", buffer_names[i]); | ||||
| 	 } | ||||
| 	 DBG("\n"); | ||||
|       } | ||||
|       _swrast_Clear(ctx, swrast_mask); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| intelInitClearFuncs(struct dd_function_table *functions) | ||||
| { | ||||
|    functions->Clear = intelClear; | ||||
| } | ||||
							
								
								
									
										38
									
								
								src/mesa/drivers/dri/intel/intel_clear.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/mesa/drivers/dri/intel/intel_clear.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
|  | ||||
| /************************************************************************** | ||||
|  *  | ||||
|  * Copyright 2006 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 INTEL_CLEAR_H | ||||
| #define INTEL_CLEAR_H | ||||
|  | ||||
| struct dd_function_table; | ||||
|  | ||||
| extern void | ||||
| intelInitClearFuncs(struct dd_function_table *functions); | ||||
|  | ||||
|  | ||||
| #endif /* INTEL_CLEAR_H */ | ||||
| @@ -53,12 +53,14 @@ | ||||
| #include "intel_tex.h" | ||||
| #include "intel_batchbuffer.h" | ||||
| #include "intel_blit.h" | ||||
| #include "intel_clear.h" | ||||
| #include "intel_pixel.h" | ||||
| #include "intel_regions.h" | ||||
| #include "intel_buffer_objects.h" | ||||
| #include "intel_fbo.h" | ||||
| #include "intel_decode.h" | ||||
| #include "intel_bufmgr.h" | ||||
| #include "intel_swapbuffers.h" | ||||
|  | ||||
| #include "drirenderbuffer.h" | ||||
| #include "vblank.h" | ||||
| @@ -95,7 +97,7 @@ int INTEL_DEBUG = (0); | ||||
|  | ||||
| #include "extension_helper.h" | ||||
|  | ||||
| #define DRIVER_DATE                     "20090114" | ||||
| #define DRIVER_DATE                     "20090316 2009Q1 RC1" | ||||
| #define DRIVER_DATE_GEM                 "GEM " DRIVER_DATE | ||||
|  | ||||
| static const GLubyte * | ||||
| @@ -151,6 +153,10 @@ intelGetString(GLcontext * ctx, GLenum name) | ||||
|       case PCI_CHIP_Q33_G: | ||||
| 	 chipset = "Intel(R) Q33"; | ||||
| 	 break; | ||||
|       case PCI_CHIP_IGD_GM: | ||||
|       case PCI_CHIP_IGD_G: | ||||
| 	 chipset = "Intel(R) IGD"; | ||||
| 	 break; | ||||
|       case PCI_CHIP_I965_Q: | ||||
| 	 chipset = "Intel(R) 965Q"; | ||||
| 	 break; | ||||
| @@ -282,6 +288,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) | ||||
| 	   return; | ||||
|        } | ||||
|  | ||||
|        if (rb == NULL) | ||||
| 	  continue; | ||||
|  | ||||
|        if (rb->region) { | ||||
| 	  dri_bo_flink(rb->region->buffer, &name); | ||||
| 	  if (name == buffers[i].name) | ||||
| @@ -496,9 +505,8 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state) | ||||
|       intel->vtbl.invalidate_state( intel, new_state ); | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| intelFlush(GLcontext * ctx) | ||||
| static void | ||||
| intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) | ||||
| { | ||||
|    struct intel_context *intel = intel_context(ctx); | ||||
|  | ||||
| @@ -512,12 +520,25 @@ intelFlush(GLcontext * ctx) | ||||
|     * lands onscreen in a timely manner, even if the X Server doesn't trigger | ||||
|     * a flush for us. | ||||
|     */ | ||||
|    intel_batchbuffer_emit_mi_flush(intel->batch); | ||||
|    if (needs_mi_flush) | ||||
|       intel_batchbuffer_emit_mi_flush(intel->batch); | ||||
|  | ||||
|    if (intel->batch->map != intel->batch->ptr) | ||||
|       intel_batchbuffer_flush(intel->batch); | ||||
| } | ||||
|  | ||||
| void | ||||
| intelFlush(GLcontext * ctx) | ||||
| { | ||||
|    intel_flush(ctx, GL_FALSE); | ||||
| } | ||||
|  | ||||
| static void | ||||
| intel_glFlush(GLcontext *ctx) | ||||
| { | ||||
|    intel_flush(ctx, GL_TRUE); | ||||
| } | ||||
|  | ||||
| void | ||||
| intelFinish(GLcontext * ctx) | ||||
| { | ||||
| @@ -544,7 +565,7 @@ intelInitDriverFunctions(struct dd_function_table *functions) | ||||
| { | ||||
|    _mesa_init_driver_functions(functions); | ||||
|  | ||||
|    functions->Flush = intelFlush; | ||||
|    functions->Flush = intel_glFlush; | ||||
|    functions->Finish = intelFinish; | ||||
|    functions->GetString = intelGetString; | ||||
|    functions->UpdateState = intelInvalidateState; | ||||
| @@ -556,6 +577,7 @@ intelInitDriverFunctions(struct dd_function_table *functions) | ||||
|  | ||||
|    intelInitTextureFuncs(functions); | ||||
|    intelInitStateFuncs(functions); | ||||
|    intelInitClearFuncs(functions); | ||||
|    intelInitBufferFuncs(functions); | ||||
|    intelInitPixelFuncs(functions); | ||||
| } | ||||
| @@ -620,10 +642,16 @@ intelInitContext(struct intel_context *intel, | ||||
|     * start. | ||||
|     */ | ||||
|    if (getenv("INTEL_STRICT_CONFORMANCE")) { | ||||
|       intel->strict_conformance = 1; | ||||
|       unsigned int value = atoi(getenv("INTEL_STRICT_CONFORMANCE")); | ||||
|       if (value > 0) { | ||||
|          intel->conformance_mode = value; | ||||
|       } | ||||
|       else { | ||||
|          intel->conformance_mode = 1; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (intel->strict_conformance) { | ||||
|    if (intel->conformance_mode > 0) { | ||||
|       ctx->Const.MinLineWidth = 1.0; | ||||
|       ctx->Const.MinLineWidthAA = 1.0; | ||||
|       ctx->Const.MaxLineWidth = 1.0; | ||||
| @@ -858,6 +886,11 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, | ||||
| 		  ? driGetDefaultVBlankFlags(&intel->optionCache) | ||||
| 		 : VBLANK_FLAG_NO_IRQ; | ||||
|  | ||||
| 	       /* Prevent error printf if one crtc is disabled, this will | ||||
| 		* be properly calculated in intelWindowMoved() next. | ||||
| 		*/ | ||||
| 		driDrawPriv->vblFlags = intelFixupVblank(intel, driDrawPriv); | ||||
|  | ||||
| 	       (*psp->systemTime->getUST) (&intel_fb->swap_ust); | ||||
| 	       driDrawableInitVBlank(driDrawPriv); | ||||
| 	       intel_fb->vbl_waited = driDrawPriv->vblSeq; | ||||
|   | ||||
| @@ -168,6 +168,7 @@ struct intel_context | ||||
|  | ||||
|       GLint saved_vp_x, saved_vp_y; | ||||
|       GLsizei saved_vp_width, saved_vp_height; | ||||
|       GLenum saved_matrix_mode; | ||||
|    } meta; | ||||
|  | ||||
|    GLint refcount; | ||||
| @@ -209,7 +210,6 @@ struct intel_context | ||||
|    char *prevLockFile; | ||||
|    int prevLockLine; | ||||
|  | ||||
|    GLubyte clear_chan[4]; | ||||
|    GLuint ClearColor565; | ||||
|    GLuint ClearColor8888; | ||||
|  | ||||
| @@ -229,7 +229,12 @@ struct intel_context | ||||
|    GLboolean hw_stipple; | ||||
|    GLboolean depth_buffer_is_float; | ||||
|    GLboolean no_rast; | ||||
|    GLboolean strict_conformance; | ||||
|  | ||||
|    /* 0 - nonconformant, best performance; | ||||
|     * 1 - fallback to sw for known conformance bugs | ||||
|     * 2 - always fallback to sw | ||||
|     */ | ||||
|    GLuint conformance_mode; | ||||
|  | ||||
|    /* State for intelvb.c and inteltris.c. | ||||
|     */ | ||||
|   | ||||
| @@ -87,27 +87,28 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) | ||||
|  | ||||
|     struct { | ||||
| 	uint32_t opcode; | ||||
| 	int len_mask; | ||||
| 	int min_len; | ||||
| 	int max_len; | ||||
| 	char *name; | ||||
|     } opcodes_mi[] = { | ||||
| 	{ 0x08, 1, 1, "MI_ARB_ON_OFF" }, | ||||
| 	{ 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, | ||||
| 	{ 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, | ||||
| 	{ 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, | ||||
| 	{ 0x04, 1, 1, "MI_FLUSH" }, | ||||
| 	{ 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, | ||||
| 	{ 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, | ||||
| 	{ 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, | ||||
| 	{ 0x00, 1, 1, "MI_NOOP" }, | ||||
| 	{ 0x11, 2, 2, "MI_OVERLAY_FLIP" }, | ||||
| 	{ 0x07, 1, 1, "MI_REPORT_HEAD" }, | ||||
| 	{ 0x18, 2, 2, "MI_SET_CONTEXT" }, | ||||
| 	{ 0x20, 3, 4, "MI_STORE_DATA_IMM" }, | ||||
| 	{ 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, | ||||
| 	{ 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, | ||||
| 	{ 0x02, 1, 1, "MI_USER_INTERRUPT" }, | ||||
| 	{ 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, | ||||
| 	{ 0x08, 0, 1, 1, "MI_ARB_ON_OFF" }, | ||||
| 	{ 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" }, | ||||
| 	{ 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" }, | ||||
| 	{ 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, | ||||
| 	{ 0x04, 0, 1, 1, "MI_FLUSH" }, | ||||
| 	{ 0x22, 0, 3, 3, "MI_LOAD_REGISTER_IMM" }, | ||||
| 	{ 0x13, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, | ||||
| 	{ 0x12, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, | ||||
| 	{ 0x00, 0, 1, 1, "MI_NOOP" }, | ||||
| 	{ 0x11, 0x3f, 2, 2, "MI_OVERLAY_FLIP" }, | ||||
| 	{ 0x07, 0, 1, 1, "MI_REPORT_HEAD" }, | ||||
| 	{ 0x18, 0x3f, 2, 2, "MI_SET_CONTEXT" }, | ||||
| 	{ 0x20, 0x3f, 3, 4, "MI_STORE_DATA_IMM" }, | ||||
| 	{ 0x21, 0x3f, 3, 4, "MI_STORE_DATA_INDEX" }, | ||||
| 	{ 0x24, 0x3f, 3, 3, "MI_STORE_REGISTER_MEM" }, | ||||
| 	{ 0x02, 0, 1, 1, "MI_USER_INTERRUPT" }, | ||||
| 	{ 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT" }, | ||||
|     }; | ||||
|  | ||||
|  | ||||
| @@ -118,12 +119,14 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) | ||||
|  | ||||
| 	    instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); | ||||
| 	    if (opcodes_mi[opcode].max_len > 1) { | ||||
| 		len = (data[0] & 0x000000ff) + 2; | ||||
| 		len = (data[0] & opcodes_mi[opcode].len_mask) + 2; | ||||
| 		if (len < opcodes_mi[opcode].min_len || | ||||
| 		    len > opcodes_mi[opcode].max_len) | ||||
| 		{ | ||||
| 		    fprintf(out, "Bad length in %s\n", | ||||
| 			    opcodes_mi[opcode].name); | ||||
| 		    fprintf(out, "Bad length (%d) in %s, [%d, %d]\n", | ||||
| 			    len, opcodes_mi[opcode].name, | ||||
| 			    opcodes_mi[opcode].min_len, | ||||
| 			    opcodes_mi[opcode].max_len); | ||||
| 		} | ||||
| 	    } | ||||
|  | ||||
| @@ -932,7 +935,7 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i | ||||
| 	instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); | ||||
| 	len = (data[0] & 0x000000ff) + 2; | ||||
|  | ||||
| 	i = 1; | ||||
| 	i = 2; | ||||
| 	for (c = 0; c <= 31; c++) { | ||||
| 	    if (data[1] & (1 << c)) { | ||||
| 		if (i + 4 >= count) | ||||
| @@ -952,7 +955,7 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i | ||||
| 	    } | ||||
| 	} | ||||
| 	if (len != i) { | ||||
| 	    fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); | ||||
| 	    fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_CONSTANTS\n"); | ||||
| 	    (*failures)++; | ||||
| 	} | ||||
| 	return len; | ||||
|   | ||||
| @@ -266,7 +266,8 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, | ||||
|       DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width, | ||||
| 	  height, pitch); | ||||
|  | ||||
|       irb->region = intel_region_alloc(intel, cpp, width, height, pitch); | ||||
|       irb->region = intel_region_alloc(intel, cpp, width, height, pitch, | ||||
| 				       GL_TRUE); | ||||
|       if (!irb->region) | ||||
|          return GL_FALSE;       /* out of memory? */ | ||||
|  | ||||
|   | ||||
| @@ -103,7 +103,8 @@ intel_miptree_create(struct intel_context *intel, | ||||
| 		     GLuint last_level, | ||||
| 		     GLuint width0, | ||||
| 		     GLuint height0, | ||||
| 		     GLuint depth0, GLuint cpp, GLuint compress_byte) | ||||
| 		     GLuint depth0, GLuint cpp, GLuint compress_byte, | ||||
| 		     GLboolean expect_accelerated_upload) | ||||
| { | ||||
|    struct intel_mipmap_tree *mt; | ||||
|  | ||||
| @@ -120,7 +121,8 @@ intel_miptree_create(struct intel_context *intel, | ||||
| 				   mt->cpp, | ||||
| 				   mt->pitch, | ||||
| 				   mt->total_height, | ||||
| 				   mt->pitch); | ||||
| 				   mt->pitch, | ||||
| 				   expect_accelerated_upload); | ||||
|  | ||||
|    if (!mt->region) { | ||||
|        free(mt); | ||||
|   | ||||
| @@ -133,7 +133,8 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, | ||||
|                                                GLuint height0, | ||||
|                                                GLuint depth0, | ||||
|                                                GLuint cpp, | ||||
|                                                GLuint compress_byte); | ||||
|                                                GLuint compress_byte, | ||||
| 					       GLboolean expect_accelerated_upload); | ||||
|  | ||||
| struct intel_mipmap_tree * | ||||
| intel_miptree_create_for_region(struct intel_context *intel, | ||||
|   | ||||
| @@ -181,8 +181,9 @@ intel_meta_set_passthrough_transform(struct intel_context *intel) | ||||
|    intel->meta.saved_vp_y = ctx->Viewport.Y; | ||||
|    intel->meta.saved_vp_width = ctx->Viewport.Width; | ||||
|    intel->meta.saved_vp_height = ctx->Viewport.Height; | ||||
|    intel->meta.saved_matrix_mode = ctx->Transform.MatrixMode; | ||||
|  | ||||
|    _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); | ||||
|    /*   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);*/ | ||||
|  | ||||
|    _mesa_MatrixMode(GL_PROJECTION); | ||||
|    _mesa_PushMatrix(); | ||||
| @@ -202,8 +203,10 @@ intel_meta_restore_transform(struct intel_context *intel) | ||||
|    _mesa_MatrixMode(GL_MODELVIEW); | ||||
|    _mesa_PopMatrix(); | ||||
|  | ||||
|    _mesa_Viewport(intel->meta.saved_vp_x, intel->meta.saved_vp_y, | ||||
| 		  intel->meta.saved_vp_width, intel->meta.saved_vp_height); | ||||
|    _mesa_MatrixMode(intel->meta.saved_matrix_mode); | ||||
|  | ||||
|    /*   _mesa_Viewport(intel->meta.saved_vp_x, intel->meta.saved_vp_y, | ||||
| 	intel->meta.saved_vp_width, intel->meta.saved_vp_height);*/ | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -76,4 +76,6 @@ void intelBitmap(GLcontext * ctx, | ||||
| 		 const struct gl_pixelstore_attrib *unpack, | ||||
| 		 const GLubyte * pixels); | ||||
|  | ||||
| void intel_clear_tris(GLcontext *ctx, GLbitfield mask); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -495,6 +495,7 @@ intel_texture_bitmap(GLcontext * ctx, | ||||
|    texcoords[3][1] = 1.0; | ||||
|  | ||||
|    _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); | ||||
|    _mesa_ClientActiveTextureARB(GL_TEXTURE0); | ||||
|    _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); | ||||
|    _mesa_Enable(GL_VERTEX_ARRAY); | ||||
|    _mesa_Enable(GL_TEXTURE_COORD_ARRAY); | ||||
|   | ||||
| @@ -72,6 +72,8 @@ intel_texture_drawpixels(GLcontext * ctx, | ||||
|    GLfloat vertices[4][4]; | ||||
|    GLfloat texcoords[4][2]; | ||||
|    GLfloat z; | ||||
|    GLint old_active_texture; | ||||
|    GLenum internalFormat; | ||||
|  | ||||
|    /* We're going to mess with texturing with no regard to existing texture | ||||
|     * state, so if there is some set up we have to bail. | ||||
| @@ -92,7 +94,7 @@ intel_texture_drawpixels(GLcontext * ctx, | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|  | ||||
|    /* We don't have a way to generate fragments with stencil values which * | ||||
|    /* We don't have a way to generate fragments with stencil values which | ||||
|     * will set the resulting stencil value. | ||||
|     */ | ||||
|    if (format == GL_STENCIL_INDEX) | ||||
| @@ -125,6 +127,7 @@ intel_texture_drawpixels(GLcontext * ctx, | ||||
|    /* XXX: pixel store stuff */ | ||||
|    _mesa_Disable(GL_POLYGON_STIPPLE); | ||||
|  | ||||
|    old_active_texture = ctx->Texture.CurrentUnit; | ||||
|    _mesa_ActiveTextureARB(GL_TEXTURE0_ARB); | ||||
|    _mesa_Enable(GL_TEXTURE_2D); | ||||
|    _mesa_GenTextures(1, &texname); | ||||
| @@ -132,11 +135,11 @@ intel_texture_drawpixels(GLcontext * ctx, | ||||
|    _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|    _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
|    _mesa_TexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | ||||
|    /* | ||||
|    _mesa_TexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); | ||||
|    _mesa_TexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); | ||||
|    */ | ||||
|    _mesa_TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, | ||||
|    if (type == GL_ALPHA) | ||||
|       internalFormat = GL_ALPHA; | ||||
|    else | ||||
|       internalFormat = GL_RGBA; | ||||
|    _mesa_TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, | ||||
| 		    type, pixels); | ||||
|  | ||||
|    intel_meta_set_passthrough_transform(intel); | ||||
| @@ -176,12 +179,15 @@ intel_texture_drawpixels(GLcontext * ctx, | ||||
|    texcoords[3][1] = 1.0; | ||||
|  | ||||
|    _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); | ||||
|    _mesa_ClientActiveTextureARB(GL_TEXTURE0); | ||||
|    _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); | ||||
|    _mesa_Enable(GL_VERTEX_ARRAY); | ||||
|    _mesa_Enable(GL_TEXTURE_COORD_ARRAY); | ||||
|    CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); | ||||
|  | ||||
|    intel_meta_restore_transform(intel); | ||||
|  | ||||
|    _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); | ||||
|    _mesa_PopClientAttrib(); | ||||
|    _mesa_PopAttrib(); | ||||
|  | ||||
| @@ -209,6 +215,7 @@ intel_stencil_drawpixels(GLcontext * ctx, | ||||
|    struct gl_pixelstore_attrib old_unpack; | ||||
|    GLstencil *stencil_pixels; | ||||
|    int row; | ||||
|    GLint old_active_texture; | ||||
|  | ||||
|    if (format != GL_STENCIL_INDEX) | ||||
|       return GL_FALSE; | ||||
| @@ -225,6 +232,10 @@ intel_stencil_drawpixels(GLcontext * ctx, | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|  | ||||
|    /* We don't support stencil testing/ops here */ | ||||
|    if (ctx->Stencil.Enabled) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    /* We use FBOs for our wrapping of the depthbuffer into a color | ||||
|     * destination. | ||||
|     */ | ||||
| @@ -266,6 +277,7 @@ intel_stencil_drawpixels(GLcontext * ctx, | ||||
| 		    GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
|    _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); | ||||
|    old_fb_name = ctx->DrawBuffer->Name; | ||||
|    old_active_texture = ctx->Texture.CurrentUnit; | ||||
|  | ||||
|    _mesa_Disable(GL_POLYGON_STIPPLE); | ||||
|    _mesa_Disable(GL_DEPTH_TEST); | ||||
| @@ -351,6 +363,7 @@ intel_stencil_drawpixels(GLcontext * ctx, | ||||
|    texcoords[3][1] = 1.0; | ||||
|  | ||||
|    _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); | ||||
|    _mesa_ClientActiveTextureARB(GL_TEXTURE0); | ||||
|    _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); | ||||
|    _mesa_Enable(GL_VERTEX_ARRAY); | ||||
|    _mesa_Enable(GL_TEXTURE_COORD_ARRAY); | ||||
| @@ -358,6 +371,7 @@ intel_stencil_drawpixels(GLcontext * ctx, | ||||
|  | ||||
|    intel_meta_restore_transform(intel); | ||||
|  | ||||
|    _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); | ||||
|    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fb_name); | ||||
|  | ||||
|    _mesa_PopClientAttrib(); | ||||
|   | ||||
| @@ -109,12 +109,18 @@ intel_region_alloc_internal(struct intel_context *intel, | ||||
|  | ||||
| struct intel_region * | ||||
| intel_region_alloc(struct intel_context *intel, | ||||
|                    GLuint cpp, GLuint width, GLuint height, GLuint pitch) | ||||
|                    GLuint cpp, GLuint width, GLuint height, GLuint pitch, | ||||
| 		   GLboolean expect_accelerated_upload) | ||||
| { | ||||
|    dri_bo *buffer; | ||||
|  | ||||
|    buffer = dri_bo_alloc(intel->bufmgr, "region", | ||||
| 			 pitch * cpp * height, 64); | ||||
|    if (expect_accelerated_upload) { | ||||
|       buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region", | ||||
| 					     pitch * cpp * height, 64); | ||||
|    } else { | ||||
|       buffer = drm_intel_bo_alloc(intel->bufmgr, "region", | ||||
| 				  pitch * cpp * height, 64); | ||||
|    } | ||||
|  | ||||
|    return intel_region_alloc_internal(intel, cpp, width, height, pitch, buffer); | ||||
| } | ||||
|   | ||||
| @@ -74,7 +74,8 @@ struct intel_region | ||||
|  */ | ||||
| struct intel_region *intel_region_alloc(struct intel_context *intel, | ||||
|                                         GLuint cpp, GLuint width, | ||||
|                                         GLuint height, GLuint pitch); | ||||
|                                         GLuint height, GLuint pitch, | ||||
| 					GLboolean expect_accelerated_upload); | ||||
|  | ||||
| struct intel_region * | ||||
| intel_region_alloc_for_handle(struct intel_context *intel, | ||||
|   | ||||
| @@ -43,6 +43,7 @@ | ||||
| #include "intel_span.h" | ||||
| #include "intel_fbo.h" | ||||
| #include "intel_chipset.h" | ||||
| #include "intel_swapbuffers.h" | ||||
|  | ||||
| #include "i915_drm.h" | ||||
| #include "i830_dri.h" | ||||
| @@ -159,7 +160,7 @@ intelPrintSAREA(const drm_i915_sarea_t * sarea) | ||||
|  * A number of the screen parameters are obtained/computed from | ||||
|  * information in the SAREA.  This function updates those parameters. | ||||
|  */ | ||||
| void | ||||
| static void | ||||
| intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, | ||||
|                            drm_i915_sarea_t * sarea) | ||||
| { | ||||
| @@ -316,8 +317,6 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, | ||||
|                   __DRIdrawablePrivate * driDrawPriv, | ||||
|                   const __GLcontextModes * mesaVis, GLboolean isPixmap) | ||||
| { | ||||
|    intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private; | ||||
|  | ||||
|    if (isPixmap) { | ||||
|       return GL_FALSE;          /* not implemented */ | ||||
|    } | ||||
|   | ||||
| @@ -92,10 +92,6 @@ extern GLboolean intelMapScreenRegions(__DRIscreenPrivate * sPriv); | ||||
|  | ||||
| extern void intelUnmapScreenRegions(intelScreenPrivate * intelScreen); | ||||
|  | ||||
| extern void | ||||
| intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, | ||||
|                            drm_i915_sarea_t * sarea); | ||||
|  | ||||
| extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); | ||||
|  | ||||
| extern GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); | ||||
| @@ -105,11 +101,6 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, | ||||
|                  __DRIdrawablePrivate * driDrawPriv, | ||||
|                  __DRIdrawablePrivate * driReadPriv); | ||||
|  | ||||
| extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); | ||||
|  | ||||
| extern void | ||||
| intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); | ||||
|  | ||||
| extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										243
									
								
								src/mesa/drivers/dri/intel/intel_swapbuffers.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								src/mesa/drivers/dri/intel/intel_swapbuffers.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,243 @@ | ||||
| /************************************************************************** | ||||
|  *  | ||||
|  * Copyright 2003 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. | ||||
|  *  | ||||
|  **************************************************************************/ | ||||
|  | ||||
| #include "intel_blit.h" | ||||
| #include "intel_buffers.h" | ||||
| #include "intel_swapbuffers.h" | ||||
| #include "intel_fbo.h" | ||||
| #include "intel_batchbuffer.h" | ||||
| #include "drirenderbuffer.h" | ||||
| #include "vblank.h" | ||||
| #include "i915_drm.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Correct a drawablePrivate's set of vblank flags WRT the current context. | ||||
|  * When considering multiple crtcs. | ||||
|  */ | ||||
| GLuint | ||||
| intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv) | ||||
| { | ||||
|  | ||||
|    if (!intel->intelScreen->driScrnPriv->dri2.enabled && | ||||
|        intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { | ||||
|       volatile drm_i915_sarea_t *sarea = intel->sarea; | ||||
|       drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, | ||||
| 				   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; | ||||
|       drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, | ||||
| 				     .x2 = sarea->planeA_x + sarea->planeA_w, | ||||
| 				     .y2 = sarea->planeA_y + sarea->planeA_h }; | ||||
|       drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, | ||||
| 				     .x2 = sarea->planeB_x + sarea->planeB_w, | ||||
| 				     .y2 = sarea->planeB_y + sarea->planeB_h }; | ||||
|       GLint areaA = driIntersectArea( drw_rect, planeA_rect ); | ||||
|       GLint areaB = driIntersectArea( drw_rect, planeB_rect ); | ||||
|       GLuint flags = dPriv->vblFlags; | ||||
|  | ||||
|       /* Update vblank info | ||||
|        */ | ||||
|       if (areaB > areaA || (areaA == areaB && areaB > 0)) { | ||||
| 	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; | ||||
|       } else { | ||||
| 	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; | ||||
|       } | ||||
|  | ||||
|       /* Do the stupid test: Is one of them actually disabled? | ||||
|        */ | ||||
|       if (sarea->planeA_w == 0 || sarea->planeA_h == 0) { | ||||
| 	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; | ||||
|       } else if (sarea->planeB_w == 0 || sarea->planeB_h == 0) { | ||||
| 	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; | ||||
|       } | ||||
|  | ||||
|       return flags; | ||||
|    } else { | ||||
| 	return dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| intelSwapBuffers(__DRIdrawablePrivate * dPriv) | ||||
| { | ||||
|    __DRIscreenPrivate *psp = dPriv->driScreenPriv; | ||||
|  | ||||
|    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { | ||||
|       GET_CURRENT_CONTEXT(ctx); | ||||
|       struct intel_context *intel; | ||||
|  | ||||
|       if (ctx == NULL) | ||||
| 	 return; | ||||
|  | ||||
|       intel = intel_context(ctx); | ||||
|  | ||||
|       if (ctx->Visual.doubleBufferMode) { | ||||
| 	 GLboolean missed_target; | ||||
| 	 struct intel_framebuffer *intel_fb = dPriv->driverPrivate; | ||||
| 	 int64_t ust; | ||||
|           | ||||
| 	 _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */ | ||||
|  | ||||
| 	/* | ||||
| 	 * The old swapping ioctl was incredibly racy, just wait for vblank | ||||
| 	 * and do the swap ourselves. | ||||
| 	 */ | ||||
| 	 driWaitForVBlank(dPriv, &missed_target); | ||||
|  | ||||
| 	 /* | ||||
| 	  * Update each buffer's vbl_pending so we don't get too out of | ||||
| 	  * sync | ||||
| 	  */ | ||||
| 	 intel_get_renderbuffer(&intel_fb->Base, | ||||
| 		   		BUFFER_BACK_LEFT)->vbl_pending = dPriv->vblSeq; | ||||
|          intel_get_renderbuffer(&intel_fb->Base, | ||||
| 		   		BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq; | ||||
|  | ||||
| 	 intelCopyBuffer(dPriv, NULL); | ||||
|  | ||||
| 	 intel_fb->swap_count++; | ||||
| 	 (*psp->systemTime->getUST) (&ust); | ||||
| 	 if (missed_target) { | ||||
| 	    intel_fb->swap_missed_count++; | ||||
| 	    intel_fb->swap_missed_ust = ust - intel_fb->swap_ust; | ||||
| 	 } | ||||
|  | ||||
| 	 intel_fb->swap_ust = ust; | ||||
|       } | ||||
|       drmCommandNone(intel->driFd, DRM_I915_GEM_THROTTLE); | ||||
|  | ||||
|    } | ||||
|    else { | ||||
|       /* XXX this shouldn't be an error but we can't handle it for now */ | ||||
|       fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); | ||||
|    } | ||||
| } | ||||
|  | ||||
| void | ||||
| intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) | ||||
| { | ||||
|    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { | ||||
|       struct intel_context *intel = | ||||
|          (struct intel_context *) dPriv->driContextPriv->driverPrivate; | ||||
|       GLcontext *ctx = &intel->ctx; | ||||
|  | ||||
|       if (ctx->Visual.doubleBufferMode) { | ||||
|          drm_clip_rect_t rect; | ||||
|          rect.x1 = x + dPriv->x; | ||||
|          rect.y1 = (dPriv->h - y - h) + dPriv->y; | ||||
|          rect.x2 = rect.x1 + w; | ||||
|          rect.y2 = rect.y1 + h; | ||||
|          _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */ | ||||
|          intelCopyBuffer(dPriv, &rect); | ||||
|       } | ||||
|    } | ||||
|    else { | ||||
|       /* XXX this shouldn't be an error but we can't handle it for now */ | ||||
|       fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * This will be called whenever the currently bound window is moved/resized. | ||||
|  * XXX: actually, it seems to NOT be called when the window is only moved (BP). | ||||
|  */ | ||||
| void | ||||
| intelWindowMoved(struct intel_context *intel) | ||||
| { | ||||
|    GLcontext *ctx = &intel->ctx; | ||||
|    __DRIdrawablePrivate *dPriv = intel->driDrawable; | ||||
|    struct intel_framebuffer *intel_fb = dPriv->driverPrivate; | ||||
|  | ||||
|    if (!intel->intelScreen->driScrnPriv->dri2.enabled && | ||||
|        intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { | ||||
|       GLuint flags = intelFixupVblank(intel, dPriv); | ||||
|  | ||||
|       /* Check to see if we changed pipes */ | ||||
|       if (flags != dPriv->vblFlags && dPriv->vblFlags && | ||||
| 	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { | ||||
| 	 int64_t count; | ||||
| 	 drmVBlank vbl; | ||||
| 	 int i; | ||||
|  | ||||
| 	 /* | ||||
| 	  * Deal with page flipping | ||||
| 	  */ | ||||
| 	 vbl.request.type = DRM_VBLANK_ABSOLUTE; | ||||
|  | ||||
| 	 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { | ||||
| 	    vbl.request.type |= DRM_VBLANK_SECONDARY; | ||||
| 	 } | ||||
|  | ||||
| 	 for (i = 0; i < 2; i++) { | ||||
| 	    if (!intel_fb->color_rb[i] || | ||||
| 		(intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <= | ||||
| 		(1<<23)) | ||||
| 	       continue; | ||||
|  | ||||
| 	    vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending; | ||||
| 	    drmWaitVBlank(intel->driFd, &vbl); | ||||
| 	 } | ||||
|  | ||||
| 	 /* | ||||
| 	  * Update msc_base from old pipe | ||||
| 	  */ | ||||
| 	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count); | ||||
| 	 dPriv->msc_base = count; | ||||
| 	 /* | ||||
| 	  * Then get new vblank_base and vblSeq values | ||||
| 	  */ | ||||
| 	 dPriv->vblFlags = flags; | ||||
| 	 driGetCurrentVBlank(dPriv); | ||||
| 	 dPriv->vblank_base = dPriv->vblSeq; | ||||
|  | ||||
| 	 intel_fb->vbl_waited = dPriv->vblSeq; | ||||
|  | ||||
| 	 for (i = 0; i < 2; i++) { | ||||
| 	    if (intel_fb->color_rb[i]) | ||||
| 	       intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited; | ||||
| 	 } | ||||
|       } | ||||
|    } else { | ||||
|       dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; | ||||
|    } | ||||
|  | ||||
|    /* Update Mesa's notion of window size */ | ||||
|    driUpdateFramebufferSize(ctx, dPriv); | ||||
|    intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */ | ||||
|  | ||||
|    /* Update hardware scissor */ | ||||
|    if (ctx->Driver.Scissor != NULL) { | ||||
|       ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, | ||||
| 			  ctx->Scissor.Width, ctx->Scissor.Height); | ||||
|    } | ||||
|  | ||||
|    /* Re-calculate viewport related state */ | ||||
|    if (ctx->Driver.DepthRange != NULL) | ||||
|       ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); | ||||
| } | ||||
							
								
								
									
										52
									
								
								src/mesa/drivers/dri/intel/intel_swapbuffers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/mesa/drivers/dri/intel/intel_swapbuffers.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
|  | ||||
| /************************************************************************** | ||||
|  *  | ||||
|  * Copyright 2006 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 INTEL_SWAPBUFFERS_H | ||||
| #define INTEL_SWAPBUFFERS_H | ||||
|  | ||||
| #include "dri_util.h" | ||||
| #include "drm.h" | ||||
|  | ||||
| struct intel_context; | ||||
| struct intel_framebuffer; | ||||
|  | ||||
|  | ||||
| extern void | ||||
| intelSwapBuffers(__DRIdrawablePrivate * dPriv); | ||||
|  | ||||
| extern void | ||||
| intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); | ||||
|  | ||||
| extern GLuint | ||||
| intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv); | ||||
|  | ||||
| extern void | ||||
| intelWindowMoved(struct intel_context *intel); | ||||
|  | ||||
|  | ||||
| #endif /* INTEL_SWAPBUFFERS_H */ | ||||
| @@ -62,7 +62,8 @@ logbase2(int n) | ||||
| static void | ||||
| guess_and_alloc_mipmap_tree(struct intel_context *intel, | ||||
|                             struct intel_texture_object *intelObj, | ||||
|                             struct intel_texture_image *intelImage) | ||||
|                             struct intel_texture_image *intelImage, | ||||
| 			    GLboolean expect_accelerated_upload) | ||||
| { | ||||
|    GLuint firstLevel; | ||||
|    GLuint lastLevel; | ||||
| @@ -136,7 +137,8 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel, | ||||
|                                        height, | ||||
|                                        depth, | ||||
|                                        intelImage->base.TexFormat->TexelBytes, | ||||
|                                        comp_byte); | ||||
|                                        comp_byte, | ||||
| 				       expect_accelerated_upload); | ||||
|  | ||||
|    DBG("%s - success\n", __FUNCTION__); | ||||
| } | ||||
| @@ -383,7 +385,7 @@ intelTexImage(GLcontext * ctx, | ||||
|    } | ||||
|  | ||||
|    if (!intelObj->mt) { | ||||
|       guess_and_alloc_mipmap_tree(intel, intelObj, intelImage); | ||||
|       guess_and_alloc_mipmap_tree(intel, intelObj, intelImage, pixels == NULL); | ||||
|       if (!intelObj->mt) { | ||||
| 	 DBG("guess_and_alloc_mipmap_tree: failed\n"); | ||||
|       } | ||||
| @@ -413,7 +415,7 @@ intelTexImage(GLcontext * ctx, | ||||
| 					    level, level, | ||||
| 					    width, height, depth, | ||||
| 					    intelImage->base.TexFormat->TexelBytes, | ||||
| 					    comp_byte); | ||||
| 					    comp_byte, pixels == NULL); | ||||
|  | ||||
|    } | ||||
|  | ||||
| @@ -751,16 +753,21 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) | ||||
|  | ||||
|    _mesa_lock_texture(&intel->ctx, texObj); | ||||
|  | ||||
|    texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level); | ||||
|    intelImage = intel_texture_image(texImage); | ||||
|  | ||||
|    if (intelImage->mt) { | ||||
|       intel_miptree_release(intel, &intelImage->mt); | ||||
|       assert(!texImage->Data); | ||||
|    } | ||||
|    if (intelObj->mt) | ||||
|       intel_miptree_release(intel, &intelObj->mt); | ||||
|  | ||||
|    intelObj->mt = mt; | ||||
|    texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level); | ||||
|    _mesa_init_teximage_fields(&intel->ctx, target, texImage, | ||||
| 			      rb->region->width, rb->region->height, 1, | ||||
| 			      0, internalFormat); | ||||
|  | ||||
|    intelImage = intel_texture_image(texImage); | ||||
|    intelImage->face = target_to_face(target); | ||||
|    intelImage->level = level; | ||||
|    texImage->TexFormat = intelChooseTextureFormat(&intel->ctx, internalFormat, | ||||
|   | ||||
| @@ -206,7 +206,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) | ||||
|                                           firstImage->base.Height, | ||||
|                                           firstImage->base.Depth, | ||||
|                                           cpp, | ||||
|                                           comp_byte); | ||||
|                                           comp_byte, | ||||
| 					  GL_TRUE); | ||||
|    } | ||||
|  | ||||
|    /* Pull in any images not in the object's tree: | ||||
|   | ||||
| @@ -206,8 +206,8 @@ static void mgaUpdateTextureEnvG200( GLcontext *ctx, GLuint unit ) | ||||
|    mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; | ||||
|    GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; | ||||
|  | ||||
|    if (tObj != ctx->Texture.Unit[0].Current2D && | ||||
|        tObj != ctx->Texture.Unit[0].CurrentRect) | ||||
|    if (tObj != ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX] && | ||||
|        tObj != ctx->Texture.Unit[0].CurrentTex[TEXTURE_RECT_INDEX]) | ||||
|       return; | ||||
|  | ||||
|  | ||||
| @@ -635,8 +635,8 @@ static void mgaUpdateTextureEnvG400( GLcontext *ctx, GLuint unit ) | ||||
|    mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; | ||||
|    GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; | ||||
|  | ||||
|    if (tObj != ctx->Texture.Unit[source].Current2D && | ||||
|        tObj != ctx->Texture.Unit[source].CurrentRect) | ||||
|    if (tObj != ctx->Texture.Unit[source].CurrentTex[TEXTURE_2D_INDEX] && | ||||
|        tObj != ctx->Texture.Unit[source].CurrentTex[TEXTURE_RECT_INDEX]) | ||||
|       return; | ||||
|  | ||||
|    switch (ctx->Texture.Unit[source].EnvMode) { | ||||
|   | ||||
| @@ -347,6 +347,8 @@ static GLboolean r300RunRender(GLcontext * ctx, | ||||
| static int r300Fallback(GLcontext * ctx) | ||||
| { | ||||
| 	r300ContextPtr r300 = R300_CONTEXT(ctx); | ||||
| 	const unsigned back = ctx->Stencil._BackFace; | ||||
|  | ||||
| 	/* Do we need to use new-style shaders? | ||||
| 	 * Also is there a better way to do this? */ | ||||
| 	if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { | ||||
| @@ -371,12 +373,14 @@ static int r300Fallback(GLcontext * ctx) | ||||
|  | ||||
| 	FALLBACK_IF(ctx->RenderMode != GL_RENDER); | ||||
|  | ||||
| 	FALLBACK_IF(ctx->Stencil._TestTwoSide | ||||
| 		    && (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] | ||||
| 			|| ctx->Stencil.ValueMask[0] != | ||||
| 			ctx->Stencil.ValueMask[1] | ||||
| 			|| ctx->Stencil.WriteMask[0] != | ||||
| 			ctx->Stencil.WriteMask[1])); | ||||
| 	/* If GL_EXT_stencil_two_side is disabled, this fallback check can | ||||
| 	 * be removed. | ||||
| 	 */ | ||||
| 	FALLBACK_IF(ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back] | ||||
| 		    || ctx->Stencil.ValueMask[0] != | ||||
| 		    ctx->Stencil.ValueMask[back] | ||||
| 		    || ctx->Stencil.WriteMask[0] != | ||||
| 		    ctx->Stencil.WriteMask[back]); | ||||
|  | ||||
| 	if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) | ||||
| 		FALLBACK_IF(ctx->Point.PointSprite); | ||||
|   | ||||
| @@ -974,15 +974,9 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, | ||||
| { | ||||
| 	r300ContextPtr rmesa = R300_CONTEXT(ctx); | ||||
| 	GLuint refmask = | ||||
| 	    (((ctx->Stencil. | ||||
| 	       Ref[0] & 0xff) << R300_STENCILREF_SHIFT) | ((ctx-> | ||||
| 							    Stencil. | ||||
| 							    ValueMask | ||||
| 							    [0] & | ||||
| 							    0xff) | ||||
| 							   << | ||||
| 							   R300_STENCILMASK_SHIFT)); | ||||
|  | ||||
| 	    ((ctx->Stencil.Ref[0] & 0xff) << R300_STENCILREF_SHIFT) | ||||
| 	     | ((ctx->Stencil.ValueMask[0] & 0xff) << R300_STENCILMASK_SHIFT); | ||||
| 	const unsigned back = ctx->Stencil._BackFace; | ||||
| 	GLuint flag; | ||||
|  | ||||
| 	R300_STATECHANGE(rmesa, zs); | ||||
| @@ -1000,8 +994,7 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, | ||||
| 	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= | ||||
| 	    (flag << R300_S_FRONT_FUNC_SHIFT); | ||||
|  | ||||
| 	if (ctx->Stencil._TestTwoSide) | ||||
| 		flag = translate_func(ctx->Stencil.Function[1]); | ||||
| 	flag = translate_func(ctx->Stencil.Function[back]); | ||||
|  | ||||
| 	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= | ||||
| 	    (flag << R300_S_BACK_FUNC_SHIFT); | ||||
| @@ -1026,6 +1019,7 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, | ||||
| 				  GLenum fail, GLenum zfail, GLenum zpass) | ||||
| { | ||||
| 	r300ContextPtr rmesa = R300_CONTEXT(ctx); | ||||
| 	const unsigned back = ctx->Stencil._BackFace; | ||||
|  | ||||
| 	R300_STATECHANGE(rmesa, zs); | ||||
| 	/* It is easier to mask what's left.. */ | ||||
| @@ -1042,23 +1036,13 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, | ||||
| 	    | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << | ||||
| 	       R300_S_FRONT_ZPASS_OP_SHIFT); | ||||
|  | ||||
| 	if (ctx->Stencil._TestTwoSide) { | ||||
| 		rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= | ||||
| 		    (translate_stencil_op(ctx->Stencil.FailFunc[1]) << | ||||
| 		     R300_S_BACK_SFAIL_OP_SHIFT) | ||||
| 		    | (translate_stencil_op(ctx->Stencil.ZFailFunc[1]) << | ||||
| 		       R300_S_BACK_ZFAIL_OP_SHIFT) | ||||
| 		    | (translate_stencil_op(ctx->Stencil.ZPassFunc[1]) << | ||||
| 		       R300_S_BACK_ZPASS_OP_SHIFT); | ||||
| 	} else { | ||||
| 		rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= | ||||
| 		    (translate_stencil_op(ctx->Stencil.FailFunc[0]) << | ||||
| 		     R300_S_BACK_SFAIL_OP_SHIFT) | ||||
| 		    | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << | ||||
| 		       R300_S_BACK_ZFAIL_OP_SHIFT) | ||||
| 		    | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << | ||||
| 		       R300_S_BACK_ZPASS_OP_SHIFT); | ||||
| 	} | ||||
| 	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= | ||||
| 	    (translate_stencil_op(ctx->Stencil.FailFunc[back]) << | ||||
| 	     R300_S_BACK_SFAIL_OP_SHIFT) | ||||
| 	    | (translate_stencil_op(ctx->Stencil.ZFailFunc[back]) << | ||||
| 	       R300_S_BACK_ZFAIL_OP_SHIFT) | ||||
| 	    | (translate_stencil_op(ctx->Stencil.ZPassFunc[back]) << | ||||
| 	       R300_S_BACK_ZPASS_OP_SHIFT); | ||||
| } | ||||
|  | ||||
| /* ============================================================= | ||||
| @@ -1214,7 +1198,7 @@ r300FetchStateParameter(GLcontext * ctx, | ||||
|  | ||||
| 		case STATE_R300_TEXRECT_FACTOR:{ | ||||
| 				struct gl_texture_object *t = | ||||
| 				    ctx->Texture.Unit[state[2]].CurrentRect; | ||||
| 				    ctx->Texture.Unit[state[2]].CurrentTex[TEXTURE_RECT_INDEX]; | ||||
|  | ||||
| 				if (t && t->Image[0][t->BaseLevel]) { | ||||
| 					struct gl_texture_image *image = | ||||
|   | ||||
| @@ -129,13 +129,13 @@ static void r300SetVertexFormat( GLcontext *ctx ) | ||||
| 		offset = 4; | ||||
| 		EMIT_PAD(4 * sizeof(float)); | ||||
| 	} | ||||
|  | ||||
| /* | ||||
| 	if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) { | ||||
| 		EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F ); | ||||
| 		vap_fmt_0 |=  R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; | ||||
| 		offset += 1; | ||||
| 	} | ||||
|  | ||||
| */ | ||||
| 	if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR0)) { | ||||
| 		sz = VB->AttribPtr[VERT_ATTRIB_COLOR0]->size; | ||||
| 	        rmesa->swtcl.coloroffset = offset; | ||||
|   | ||||
| @@ -247,6 +247,9 @@ | ||||
| #define PCI_CHIP_RS350_7835		0x7835 | ||||
| #define PCI_CHIP_RS690_791E             0x791E | ||||
| #define PCI_CHIP_RS690_791F             0x791F | ||||
| #define PCI_CHIP_RS600_793F             0x793F | ||||
| #define PCI_CHIP_RS600_7941             0x7941 | ||||
| #define PCI_CHIP_RS600_7942             0x7942 | ||||
| #define PCI_CHIP_RS740_796C             0x796C | ||||
| #define PCI_CHIP_RS740_796D             0x796D | ||||
| #define PCI_CHIP_RS740_796E             0x796E | ||||
| @@ -270,6 +273,7 @@ enum { | ||||
|    CHIP_FAMILY_R420, | ||||
|    CHIP_FAMILY_RV410, | ||||
|    CHIP_FAMILY_RS400, | ||||
|    CHIP_FAMILY_RS600, | ||||
|    CHIP_FAMILY_RS690, | ||||
|    CHIP_FAMILY_RS740, | ||||
|    CHIP_FAMILY_RV515, | ||||
|   | ||||
| @@ -680,6 +680,12 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) | ||||
|       screen->chip_family = CHIP_FAMILY_RS400; | ||||
|       break; | ||||
|  | ||||
|    case PCI_CHIP_RS600_793F: | ||||
|    case PCI_CHIP_RS600_7941: | ||||
|    case PCI_CHIP_RS600_7942: | ||||
|       screen->chip_family = CHIP_FAMILY_RS600; | ||||
|       break; | ||||
|  | ||||
|    case PCI_CHIP_RS690_791E: | ||||
|    case PCI_CHIP_RS690_791F: | ||||
|       screen->chip_family = CHIP_FAMILY_RS690; | ||||
| @@ -838,7 +844,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) | ||||
|    ret = radeonGetParam( sPriv->fd, RADEON_PARAM_FB_LOCATION, | ||||
|                          &temp); | ||||
|    if (ret) { | ||||
|        if (screen->chip_family < CHIP_FAMILY_RS690) | ||||
|        if (screen->chip_family < CHIP_FAMILY_RS600) | ||||
| 	   screen->fbLocation      = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff) << 16; | ||||
|        else { | ||||
|            FREE( screen ); | ||||
| @@ -849,7 +855,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) | ||||
|        screen->fbLocation = (temp & 0xffff) << 16; | ||||
|    } | ||||
|  | ||||
|    if (screen->chip_family >= CHIP_FAMILY_RV515) { | ||||
|    if (screen->chip_family >= CHIP_FAMILY_R300) { | ||||
|        ret = radeonGetParam( sPriv->fd, RADEON_PARAM_NUM_GB_PIPES, | ||||
| 			     &temp); | ||||
|        if (ret) { | ||||
|   | ||||
| @@ -502,20 +502,20 @@ static void s3vInitTextureObjects( GLcontext *ctx ) | ||||
| #if 1 | ||||
| 	ctx->Texture.CurrentUnit = 0; | ||||
|  | ||||
| 	texObj = ctx->Texture.Unit[0].Current1D; | ||||
| 	texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_1D_INDEX]; | ||||
| 	s3vBindTexture( ctx, GL_TEXTURE_1D, texObj ); | ||||
|  | ||||
| 	texObj = ctx->Texture.Unit[0].Current2D; | ||||
| 	texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; | ||||
| 	s3vBindTexture( ctx, GL_TEXTURE_2D, texObj ); | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| 	ctx->Texture.CurrentUnit = 1; | ||||
|  | ||||
| 	texObj = ctx->Texture.Unit[1].Current1D; | ||||
| 	texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_1D_INDEX]; | ||||
| 	s3vBindTexture( ctx, GL_TEXTURE_1D, texObj ); | ||||
|  | ||||
| 	texObj = ctx->Texture.Unit[1].Current2D; | ||||
| 	texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_2D_INDEX]; | ||||
| 	s3vBindTexture( ctx, GL_TEXTURE_2D, texObj ); | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -72,6 +72,7 @@ | ||||
| #define need_GL_EXT_framebuffer_blit | ||||
| #define need_GL_EXT_gpu_program_parameters | ||||
| #define need_GL_EXT_paletted_texture | ||||
| #define need_GL_EXT_stencil_two_side | ||||
| #define need_GL_IBM_multimode_draw_arrays | ||||
| #define need_GL_MESA_resize_buffers | ||||
| #define need_GL_NV_vertex_program | ||||
| @@ -103,6 +104,7 @@ const struct dri_extension card_extensions[] = | ||||
|     { "GL_EXT_framebuffer_blit",	GL_EXT_framebuffer_blit_functions }, | ||||
|     { "GL_EXT_gpu_program_parameters",	GL_EXT_gpu_program_parameters_functions }, | ||||
|     { "GL_EXT_paletted_texture",	GL_EXT_paletted_texture_functions }, | ||||
|     { "GL_EXT_stencil_two_side",	GL_EXT_stencil_two_side_functions }, | ||||
|     { "GL_IBM_multimode_draw_arrays",	GL_IBM_multimode_draw_arrays_functions }, | ||||
|     { "GL_MESA_resize_buffers",		GL_MESA_resize_buffers_functions }, | ||||
|     { "GL_NV_vertex_program",		GL_NV_vertex_program_functions }, | ||||
|   | ||||
| @@ -110,13 +110,13 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name ) | ||||
|  | ||||
|  | ||||
| static void | ||||
| tdfxBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) | ||||
| tdfxBeginQuery(GLcontext *ctx, struct gl_query_object *q) | ||||
| { | ||||
|    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | ||||
|  | ||||
|    (void) q; | ||||
|  | ||||
|    if (target == GL_SAMPLES_PASSED_ARB) { | ||||
|    if (q->Target == GL_SAMPLES_PASSED_ARB) { | ||||
|       LOCK_HARDWARE(fxMesa); | ||||
|       fxMesa->Glide.grFinish(); | ||||
|       fxMesa->Glide.grReset(GR_STATS_PIXELS); | ||||
| @@ -126,14 +126,14 @@ tdfxBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) | ||||
|  | ||||
|  | ||||
| static void | ||||
| tdfxEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) | ||||
| tdfxEndQuery(GLcontext *ctx, struct gl_query_object *q) | ||||
| { | ||||
|    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | ||||
|    FxI32 total_pixels; | ||||
|    FxI32 z_fail_pixels; | ||||
|  | ||||
|  | ||||
|    if (target == GL_SAMPLES_PASSED_ARB) { | ||||
|    if (q->Target == GL_SAMPLES_PASSED_ARB) { | ||||
|       LOCK_HARDWARE(fxMesa); | ||||
|       fxMesa->Glide.grFinish(); | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  7.1 | ||||
|  * Version:  7.5 | ||||
|  * | ||||
|  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved. | ||||
|  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved. | ||||
|  * Copyright (C) 2009  VMware, Inc.   All Rights Reserved. | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
| @@ -1392,6 +1393,25 @@ Fake_glXChooseVisual( Display *dpy, int screen, int *list ) | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Init basic fields of a new fake_glx_context. | ||||
|  * If the MESA_GLX_FORCE_DIRECT env var is set, the context will be marked as | ||||
|  * a direct rendering context.  Some apps won't run without this. | ||||
|  */ | ||||
| static void | ||||
| init_glx_context(struct fake_glx_context *glxCtx, Display *dpy) | ||||
| { | ||||
|    GLboolean direct = _mesa_getenv("MESA_GLX_FORCE_DIRECT") ? GL_TRUE : GL_FALSE; | ||||
|    glxCtx->xmesaContext->direct = direct; | ||||
|    glxCtx->glxContext.isDirect = direct; | ||||
|    glxCtx->glxContext.currentDpy = dpy; | ||||
|    glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */ | ||||
|  | ||||
|    assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static GLXContext | ||||
| Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, | ||||
|                        GLXContext share_list, Bool direct ) | ||||
| @@ -1430,12 +1450,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    glxCtx->xmesaContext->direct = GL_FALSE; | ||||
|    glxCtx->glxContext.isDirect = GL_FALSE; | ||||
|    glxCtx->glxContext.currentDpy = dpy; | ||||
|    glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */ | ||||
|  | ||||
|    assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); | ||||
|    init_glx_context(glxCtx, dpy); | ||||
|  | ||||
|    return (GLXContext) glxCtx; | ||||
| } | ||||
| @@ -2441,12 +2456,7 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    glxCtx->xmesaContext->direct = GL_FALSE; | ||||
|    glxCtx->glxContext.isDirect = GL_FALSE; | ||||
|    glxCtx->glxContext.currentDpy = dpy; | ||||
|    glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */ | ||||
|  | ||||
|    assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); | ||||
|    init_glx_context(glxCtx, dpy); | ||||
|  | ||||
|    return (GLXContext) glxCtx; | ||||
| } | ||||
| @@ -2664,12 +2674,7 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    glxCtx->xmesaContext->direct = GL_FALSE; | ||||
|    glxCtx->glxContext.isDirect = GL_FALSE; | ||||
|    glxCtx->glxContext.currentDpy = dpy; | ||||
|    glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */ | ||||
|  | ||||
|    assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); | ||||
|    init_glx_context(glxCtx, dpy); | ||||
|  | ||||
|    return (GLXContext) glxCtx; | ||||
| } | ||||
|   | ||||
| @@ -2463,13 +2463,13 @@ XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer, | ||||
| #if 0 | ||||
|    switch (drawable->TextureTarget) { | ||||
|    case GLX_TEXTURE_1D_EXT: | ||||
|       texObj = texUnit->Current1D; | ||||
|       texObj = texUnit->CurrentTex[TEXTURE_1D_INDEX]; | ||||
|       break; | ||||
|    case GLX_TEXTURE_2D_EXT: | ||||
|       texObj = texUnit->Current2D; | ||||
|       texObj = texUnit->CurrentTex[TEXTURE_2D_INDEX]; | ||||
|       break; | ||||
|    case GLX_TEXTURE_RECTANGLE_EXT: | ||||
|       texObj = texUnit->CurrentRect; | ||||
|       texObj = texUnit->CurrentTex[TEXTURE_RECT_INDEX]; | ||||
|       break; | ||||
|    default: | ||||
|       return; /* BadMatch error */ | ||||
|   | ||||
| @@ -229,6 +229,7 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height) | ||||
|       } | ||||
|  | ||||
|       b->backxrb->ximage = NULL; | ||||
|       b->backxrb->drawable = b->backxrb->pixmap; | ||||
|    } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -225,9 +225,21 @@ typedef xmutex_rec _glthread_Mutex; | ||||
|  */ | ||||
| #ifdef BEOS_THREADS | ||||
|  | ||||
| /* Problem with OS.h and this file on haiku */ | ||||
| #ifndef __HAIKU__ | ||||
| #include <kernel/OS.h> | ||||
| #endif | ||||
|  | ||||
| #include <support/TLS.h> | ||||
|  | ||||
| /* The only two typedefs required here | ||||
|  * this is cause of the OS.h problem | ||||
|  */ | ||||
| #ifdef __HAIKU__ | ||||
| typedef int32 thread_id; | ||||
| typedef int32 sem_id; | ||||
| #endif | ||||
|  | ||||
| typedef struct { | ||||
|    int32        key; | ||||
|    int          initMagic; | ||||
|   | ||||
| @@ -87,11 +87,20 @@ check_valid_to_render(GLcontext *ctx, char *function) | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|  | ||||
|    /* Always need vertex positions, unless a vertex program is in use */ | ||||
|    if (!ctx->VertexProgram._Current && | ||||
|        !ctx->Array.ArrayObj->Vertex.Enabled && | ||||
| #if FEATURE_es2_glsl | ||||
|    /* For ES2, we can draw if any vertex array is enabled (and we should | ||||
|     * always have a vertex program/shader). | ||||
|     */ | ||||
|    if (ctx->Array.ArrayObj->_Enabled == 0x0 || !ctx->VertexProgram._Current) | ||||
|       return GL_FALSE; | ||||
| #else | ||||
|    /* For regular OpenGL, only draw if we have vertex positions (regardless | ||||
|     * of whether or not we have a vertex program/shader). | ||||
|     */ | ||||
|    if (!ctx->Array.ArrayObj->Vertex.Enabled && | ||||
|        !ctx->Array.ArrayObj->VertexAttrib[0].Enabled) | ||||
|       return GL_FALSE; | ||||
| #endif | ||||
|  | ||||
|    return GL_TRUE; | ||||
| } | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user