summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configs/linux-solo3
-rw-r--r--include/GL/xmesa_xf86.h1
-rw-r--r--progs/demos/shadowtex.c311
-rw-r--r--progs/tests/drawbuffers.c21
-rw-r--r--progs/xdemos/texture_from_pixmap.c19
-rw-r--r--src/glx/mini/miniglx.c1
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr_fake.c39
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr_ttm.c15
-rw-r--r--src/mesa/drivers/dri/i915/i915_texstate.c19
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c8
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.h4
-rw-r--r--src/mesa/drivers/dri/i915/intel_pixel.c22
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.c4
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex.c6
-rw-r--r--src/mesa/drivers/dri/i915tex/Makefile1
-rw-r--r--src/mesa/drivers/dri/i915tex/i830_vtbl.c12
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_disasm.c740
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_disasm.h29
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_vtbl.c2
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_batchbuffer.c23
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.c15
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.h4
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c4
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_pixel_draw.c17
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_screen.c24
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex_image.c6
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex_validate.c2
-rw-r--r--src/mesa/drivers/dri/i965/intel_context.c13
-rw-r--r--src/mesa/drivers/dri/i965/intel_context.h1
-rw-r--r--src/mesa/drivers/dri/i965/intel_tex_validate.c2
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_swtcl.c45
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c73
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h10
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.c344
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.h17
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c26
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h23
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c101
-rw-r--r--src/mesa/drivers/dri/r300/r300_shader.c3
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c126
-rw-r--r--src/mesa/drivers/dri/r300/r300_tex.c74
-rw-r--r--src/mesa/drivers/dri/r300/r300_texmem.c23
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c17
-rw-r--r--src/mesa/drivers/x11/glxapi.c4
-rw-r--r--src/mesa/drivers/x11/xm_api.c1
-rw-r--r--src/mesa/glapi/gl_x86_asm.py15
-rw-r--r--src/mesa/glapi/glapi.c20
-rw-r--r--src/mesa/main/buffers.c51
-rw-r--r--src/mesa/main/config.h9
-rw-r--r--src/mesa/main/context.c11
-rw-r--r--src/mesa/main/depth.c34
-rw-r--r--src/mesa/main/extensions.c2
-rw-r--r--src/mesa/main/mtypes.h32
-rw-r--r--src/mesa/main/teximage.c16
-rw-r--r--src/mesa/main/texobj.c42
-rw-r--r--src/mesa/main/texstate.c77
-rw-r--r--src/mesa/main/texstate.h5
-rw-r--r--src/mesa/shader/arbprogparse.c42
-rw-r--r--src/mesa/shader/arbprogram.syn33
-rw-r--r--src/mesa/shader/arbprogram_syn.h20
-rw-r--r--src/mesa/swrast/s_aalinetemp.h18
-rw-r--r--src/mesa/swrast/s_context.c19
-rw-r--r--src/mesa/swrast/s_copypix.c14
-rw-r--r--src/mesa/swrast/s_drawpix.c17
-rw-r--r--src/mesa/swrast/s_fragprog.c1
-rw-r--r--src/mesa/swrast/s_span.c11
-rw-r--r--src/mesa/swrast/s_texfilter.c22
-rw-r--r--src/mesa/swrast/s_zoom.c6
-rw-r--r--src/mesa/x86/common_x86.c9
-rw-r--r--src/mesa/x86/glapi_x86.S14
70 files changed, 1958 insertions, 837 deletions
diff --git a/configs/linux-solo b/configs/linux-solo
index a6cab8c9b3b..2d0817dfb75 100644
--- a/configs/linux-solo
+++ b/configs/linux-solo
@@ -24,7 +24,8 @@ PCIACCESS_LIB = `pkg-config --libs pciaccess`
DEFINES = -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE \
-D_BSD_SOURCE -D_GNU_SOURCE -DHAVE_POSIX_MEMALIGN \
- -DPTHREADS -DUSE_EXTERNAL_DXTN_LIB=1 -DDRM_USE_MALLOC -DIN_DRI_DRIVER
+ -DPTHREADS -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER \
+ -DHAVE_ALIAS
CFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) \
$(ASM_FLAGS) -std=c99 -ffast-math
diff --git a/include/GL/xmesa_xf86.h b/include/GL/xmesa_xf86.h
index 18908a133fa..4d69d4d930d 100644
--- a/include/GL/xmesa_xf86.h
+++ b/include/GL/xmesa_xf86.h
@@ -39,6 +39,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef _XMESA_XF86_H_
#define _XMESA_XF86_H_
+#include "GL/glxtokens.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "gcstruct.h"
diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
index b11c6f53630..59253e8c1e3 100644
--- a/progs/demos/shadowtex.c
+++ b/progs/demos/shadowtex.c
@@ -9,6 +9,7 @@
* Added GL_EXT_packed_depth_stencil support on 15 March 2006.
* Added GL_EXT_framebuffer_object support on 27 March 2006.
* Removed old SGIX extension support on 5 April 2006.
+ * Added vertex / fragment program support on 7 June 2007 (Ian Romanick).
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
@@ -34,6 +35,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <math.h>
#include <GL/glut.h>
#include "showbuffer.h"
@@ -67,8 +69,27 @@ static GLboolean NeedNewShadowMap = GL_FALSE;
static GLuint ShadowTexture, GrayTexture;
static GLuint ShadowFBO;
+static GLfloat lightModelview[16];
+static GLfloat lightProjection[16];
+
+static GLuint vert_prog;
+static GLuint frag_progs[3];
+static GLuint curr_frag = 0;
+static GLuint max_frag = 1;
+
+#define NUM_FRAG_MODES 3
+static const char *FragProgNames[] = {
+ "fixed-function",
+ "program without \"OPTION ARB_fragment_program_shadow\"",
+ "program with \"OPTION ARB_fragment_program_shadow\"",
+};
+
static GLboolean HaveFBO = GL_FALSE;
static GLboolean UseFBO = GL_FALSE;
+static GLboolean HaveVP = GL_FALSE;
+static GLboolean HaveFP = GL_FALSE;
+static GLboolean HaveFP_Shadow = GL_FALSE;
+static GLboolean UseVP = GL_FALSE;
static GLboolean HavePackedDepthStencil = GL_FALSE;
static GLboolean UsePackedDepthStencil = GL_FALSE;
static GLboolean HaveEXTshadowFuncs = GL_FALSE;
@@ -91,6 +112,103 @@ static GLuint DisplayMode;
+#define MAT4_MUL(dest_vec, src_mat, src_vec) \
+ "DP4 " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
+ "DP4 " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
+ "DP4 " dest_vec ".z, " src_mat "[2], " src_vec ";\n" \
+ "DP4 " dest_vec ".w, " src_mat "[3], " src_vec ";\n"
+
+#define MAT3_MUL(dest_vec, src_mat, src_vec) \
+ "DP3 " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
+ "DP3 " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
+ "DP3 " dest_vec ".z, " src_mat "[2], " src_vec ";\n"
+
+#define NORMALIZE(dest, src) \
+ "DP3 " dest ".w, " src ", " src ";\n" \
+ "RSQ " dest ".w, " dest ".w;\n" \
+ "MUL " dest ", " src ", " dest ".w;\n"
+
+/**
+ * Vertex program for shadow mapping.
+ */
+static const char vert_code[] =
+ "!!ARBvp1.0\n"
+ "ATTRIB iPos = vertex.position;\n"
+ "ATTRIB iNorm = vertex.normal;\n"
+
+ "PARAM mvinv[4] = { state.matrix.modelview.invtrans };\n"
+ "PARAM mvp[4] = { state.matrix.mvp };\n"
+ "PARAM mv[4] = { state.matrix.modelview };\n"
+ "PARAM texmat[4] = { state.matrix.texture[0] };\n"
+ "PARAM lightPos = state.light[0].position;\n"
+ "PARAM ambientCol = state.lightprod[0].ambient;\n"
+ "PARAM diffuseCol = state.lightprod[0].diffuse;\n"
+
+ "TEMP n, lightVec;\n"
+ "ALIAS V = lightVec;\n"
+ "ALIAS NdotL = n;\n"
+
+ "OUTPUT oPos = result.position;\n"
+ "OUTPUT oColor = result.color;\n"
+ "OUTPUT oTex = result.texcoord[0];\n"
+
+ /* Transform the vertex to clip coordinates. */
+ MAT4_MUL("oPos", "mvp", "iPos")
+
+ /* Transform the vertex to eye coordinates. */
+ MAT4_MUL("V", "mv", "iPos")
+
+ /* Transform the vertex to projected light coordinates. */
+ MAT4_MUL("oTex", "texmat", "iPos")
+
+ /* Transform the normal to eye coordinates. */
+ MAT3_MUL("n", "mvinv", "iNorm")
+
+ /* Calculate the vector from the vertex to the light in eye
+ * coordinates.
+ */
+ "SUB lightVec, lightPos, V;\n"
+ NORMALIZE("lightVec", "lightVec")
+
+ /* Compute diffuse lighting coefficient.
+ */
+ "DP3 NdotL.x, n, lightVec;\n"
+ "MAX NdotL.x, NdotL.x, {0.0};\n"
+ "MIN NdotL.x, NdotL.x, {1.0};\n"
+
+ /* Accumulate color contributions.
+ */
+ "MOV oColor, diffuseCol;\n"
+ "MAD oColor.xyz, NdotL.x, diffuseCol, ambientCol;\n"
+ "END\n"
+ ;
+
+static const char frag_code[] =
+ "!!ARBfp1.0\n"
+
+ "TEMP shadow, temp;\n"
+
+ "TXP shadow, fragment.texcoord[0], texture[0], 2D;\n"
+ "RCP temp.x, fragment.texcoord[0].w;\n"
+ "MUL temp.x, temp.x, fragment.texcoord[0].z;\n"
+ "SGE shadow, shadow.x, temp.x;\n"
+ "MUL result.color.rgb, fragment.color, shadow.x;\n"
+ "MOV result.color.a, fragment.color;\n"
+ "END\n"
+ ;
+
+static const char frag_shadow_code[] =
+ "!!ARBfp1.0\n"
+ "OPTION ARB_fragment_program_shadow;\n"
+
+ "TEMP shadow;\n"
+
+ "TXP shadow, fragment.texcoord[0], texture[0], SHADOW2D;\n"
+ "MUL result.color.rgb, fragment.color, shadow.x;\n"
+ "MOV result.color.a, fragment.color.a;\n"
+ "END\n"
+ ;
+
static void
DrawScene(void)
{
@@ -134,27 +252,56 @@ DrawScene(void)
}
-/*
- * Load the GL_TEXTURE matrix with the projection from the light
- * source's point of view.
+/**
+ * Calculate modelview and project matrices for the light
+ *
+ * Stores the results in \c lightProjection (projection matrix) and
+ * \c lightModelview (modelview matrix).
*/
static void
MakeShadowMatrix(const GLfloat lightPos[4], const GLfloat spotDir[3],
GLfloat spotAngle, GLfloat shadowNear, GLfloat shadowFar)
{
- GLfloat d;
-
- glMatrixMode(GL_TEXTURE);
+ /* compute frustum to enclose spot light cone */
+ const GLfloat d = shadowNear * tan(spotAngle);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
glLoadIdentity();
- glTranslatef(0.5, 0.5, 0.5 + Bias);
- glScalef(0.5, 0.5, 0.5);
- d = shadowNear * tan(spotAngle);
glFrustum(-d, d, -d, d, shadowNear, shadowFar);
+ glGetFloatv(GL_PROJECTION_MATRIX, lightProjection);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
gluLookAt(lightPos[0], lightPos[1], lightPos[2],
lightPos[0] + spotDir[0],
lightPos[1] + spotDir[1],
lightPos[2] + spotDir[2],
- 0, 1, 0);
+ 0.0, 1.0, 0.0);
+ glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview);
+ glPopMatrix();
+}
+
+
+/**
+ * Load \c GL_TEXTURE matrix with light's MVP matrix.
+ */
+static void SetShadowTextureMatrix(void)
+{
+ static const GLfloat biasMatrix[16] = {
+ 0.5, 0.0, 0.0, 0.0,
+ 0.0, 0.5, 0.0, 0.0,
+ 0.0, 0.0, 0.5, 0.0,
+ 0.5, 0.5, 0.5, 1.0,
+ };
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadMatrixf(biasMatrix);
+ glTranslatef(0.0, 0.0, Bias);
+ glMultMatrixf(lightProjection);
+ glMultMatrixf(lightModelview);
glMatrixMode(GL_MODELVIEW);
}
@@ -258,7 +405,6 @@ RenderShadowMap(void)
{
GLenum depthFormat; /* GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT */
GLenum depthType; /* GL_UNSIGNED_INT_24_8_EXT or GL_UNSIGNED_INT */
- float d;
if (WindowWidth >= 1024 && WindowHeight >= 1024) {
ShadowTexWidth = ShadowTexHeight = 1024;
@@ -283,17 +429,11 @@ RenderShadowMap(void)
depthType = GL_UNSIGNED_INT;
}
- /* compute frustum to enclose spot light cone */
- d = ShadowNear * tan(SpotAngle);
-
glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-d, d, -d, d, ShadowNear, ShadowFar);
+ glLoadMatrixf(lightProjection);
+
glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(LightPos[0], LightPos[1], LightPos[2], /* from */
- 0, 0, 0, /* target */
- 0, 1, 0); /* up */
+ glLoadMatrixf(lightModelview);
if (UseFBO) {
GLenum fbo_status;
@@ -389,10 +529,8 @@ ShowShadowMap(void)
DisableTexgen();
/* interpret texture's depth values as luminance values */
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
-#endif
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_POLYGON);
@@ -420,6 +558,7 @@ Display(void)
LightPos, SpotDir);
if (NeedNewShadowMap) {
+ MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
RenderShadowMap();
NeedNewShadowMap = GL_FALSE;
}
@@ -457,12 +596,11 @@ Display(void)
}
if (DisplayMode == SHOW_DEPTH_MAPPING) {
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
-#endif
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_2D);
- MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
+
+ SetShadowTextureMatrix();
EnableIdentityTexgen();
}
else if (DisplayMode == SHOW_DISTANCE) {
@@ -476,20 +614,42 @@ Display(void)
}
else {
assert(DisplayMode == SHOW_SHADOWS);
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
-#endif
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ if (curr_frag > 0) {
+ glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ }
+ else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ }
glEnable(GL_TEXTURE_2D);
- MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
- EnableIdentityTexgen();
+
+ SetShadowTextureMatrix();
+
+ if (UseVP) {
+ glEnable(GL_VERTEX_PROGRAM_ARB);
+ }
+ else {
+ glEnable(GL_LIGHTING);
+ EnableIdentityTexgen();
+ }
}
DrawScene();
- DisableTexgen();
- glDisable(GL_TEXTURE_1D);
+ if (UseVP) {
+ glDisable(GL_VERTEX_PROGRAM_ARB);
+ }
+ else {
+ DisableTexgen();
+ glDisable(GL_LIGHTING);
+ }
+
+ if (curr_frag > 0) {
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ }
+
glDisable(GL_TEXTURE_2D);
}
@@ -561,6 +721,14 @@ Key(unsigned char key, int x, int y)
case 'm':
DisplayMode = SHOW_DEPTH_MAPPING;
break;
+ case 'M':
+ curr_frag = (1 + curr_frag) % max_frag;
+ printf("Using fragment %s\n", FragProgNames[curr_frag]);
+
+ if (HaveFP) {
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]);
+ }
+ break;
case 'n':
case 's':
case ' ':
@@ -572,10 +740,8 @@ Key(unsigned char key, int x, int y)
if (Operator >= 8)
Operator = 0;
printf("Operator: %s\n", OperatorName[Operator]);
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
OperatorFunc[Operator]);
-#endif
}
break;
case 'p':
@@ -592,6 +758,11 @@ Key(unsigned char key, int x, int y)
NeedNewShadowMap = GL_TRUE;
}
break;
+ case 'v':
+ UseVP = !UseVP && HaveVP;
+ printf("Using vertex %s mode.\n",
+ UseVP ? "program" : "fixed-function");
+ break;
case 'z':
Zrot -= step;
break;
@@ -646,28 +817,62 @@ SpecialKey(int key, int x, int y)
}
+/* A helper for finding errors in program strings */
+static int FindLine( const char *program, int position )
+{
+ int i, line = 1;
+ for (i = 0; i < position; i++) {
+ if (program[i] == '\n')
+ line++;
+ }
+ return line;
+}
+
+
+static GLuint
+compile_program(GLenum target, const char *code)
+{
+ GLuint p;
+ GLint errorPos;
+
+
+ glGenProgramsARB(1, & p);
+
+ glBindProgramARB(target, p);
+ glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(code), code);
+ glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
+ if (glGetError() != GL_NO_ERROR || errorPos != -1) {
+ int l = FindLine(code, errorPos);
+ printf("Fragment Program Error (pos=%d line=%d): %s\n", errorPos, l,
+ (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
+ exit(0);
+ }
+
+ glBindProgramARB(target, 0);
+ return p;
+}
+
static void
Init(void)
{
static const GLfloat borderColor[4] = {1.0, 0.0, 0.0, 0.0};
-#if defined(GL_ARB_depth_texture) && defined(GL_ARB_shadow)
if (!glutExtensionSupported("GL_ARB_depth_texture") ||
!glutExtensionSupported("GL_ARB_shadow")) {
-#else
- if (1) {
-#endif
printf("Sorry, this demo requires the GL_ARB_depth_texture and GL_ARB_shadow extensions\n");
exit(1);
}
printf("Using GL_ARB_depth_texture and GL_ARB_shadow\n");
-#if defined(GL_ARB_shadow_ambient)
+ HaveVP = glutExtensionSupported("GL_ARB_vertex_program");
+ HaveFP = glutExtensionSupported("GL_ARB_fragment_program");
+ HaveFP_Shadow = glutExtensionSupported("GL_ARB_fragment_program_shadow");
+
HaveShadowAmbient = glutExtensionSupported("GL_ARB_shadow_ambient");
if (HaveShadowAmbient) {
printf("and GL_ARB_shadow_ambient\n");
}
-#endif
HaveEXTshadowFuncs = glutExtensionSupported("GL_EXT_shadow_funcs");
@@ -690,15 +895,12 @@ Init(void)
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
-#endif
+
if (HaveShadowAmbient) {
-#if defined(GL_ARB_shadow_ambient)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.3);
-#endif
}
#if defined(GL_EXT_framebuffer_object)
@@ -733,6 +935,25 @@ Init(void)
256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
}
+ if (HaveVP) {
+ vert_prog = compile_program(GL_VERTEX_PROGRAM_ARB, vert_code);
+ glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vert_prog);
+ }
+
+ max_frag = 1;
+ frag_progs[0] = 0;
+
+ if (HaveFP) {
+ frag_progs[1] = compile_program(GL_FRAGMENT_PROGRAM_ARB, frag_code);
+ max_frag = 2;
+ }
+
+ if (HaveFP && HaveFP_Shadow) {
+ frag_progs[2] = compile_program(GL_FRAGMENT_PROGRAM_ARB,
+ frag_shadow_code);
+ max_frag = 3;
+ }
+
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
@@ -751,6 +972,8 @@ PrintHelp(void)
printf(" f = toggle nearest/bilinear texture filtering\n");
printf(" b/B = decrease/increase shadow map Z bias\n");
printf(" p = toggle use of packed depth/stencil\n");
+ printf(" M = cycle through fragment program modes\n");
+ printf(" v = toggle vertex program modes\n");
printf(" cursor keys = rotate scene\n");
printf(" <shift> + cursor keys = rotate light source\n");
if (HaveEXTshadowFuncs)
diff --git a/progs/tests/drawbuffers.c b/progs/tests/drawbuffers.c
index 8583bac0ddf..5e89569380a 100644
--- a/progs/tests/drawbuffers.c
+++ b/progs/tests/drawbuffers.c
@@ -19,6 +19,7 @@ static int Win;
static int Width = 400, Height = 400;
static GLuint FBobject, RBobjects[3];
static GLfloat Xrot = 0.0, Yrot = 0.0;
+static GLuint Program;
static void
@@ -40,6 +41,8 @@ Display(void)
GL_COLOR_ATTACHMENT1_EXT
};
+ glUseProgram_func(Program);
+
/* draw to user framebuffer */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject);
@@ -71,10 +74,12 @@ Display(void)
buffer);
/* top half = colorbuffer 1 */
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
- glReadPixels(0, Height/2, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE,
- buffer + Width * Height / 2 * 4);
+ glReadPixels(0, Height/2, Width, Height - Height / 2,
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ buffer + Width * (Height / 2) * 4);
/* draw to window */
+ glUseProgram_func(0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glWindowPos2iARB(0, 0);
glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
@@ -243,15 +248,15 @@ SetupShaders(void)
" gl_FragData[1] = vec4(1.0) - gl_Color; \n"
"}\n";
- GLuint fragShader, program;
+ GLuint fragShader;
fragShader = LoadAndCompileShader(GL_FRAGMENT_SHADER, fragShaderText);
- program = glCreateProgram_func();
+ Program = glCreateProgram_func();
- glAttachShader_func(program, fragShader);
- glLinkProgram_func(program);
- CheckLink(program);
- glUseProgram_func(program);
+ glAttachShader_func(Program, fragShader);
+ glLinkProgram_func(Program);
+ CheckLink(Program);
+ glUseProgram_func(Program);
}
diff --git a/progs/xdemos/texture_from_pixmap.c b/progs/xdemos/texture_from_pixmap.c
index 50870c4df4a..ab215b0ac30 100644
--- a/progs/xdemos/texture_from_pixmap.c
+++ b/progs/xdemos/texture_from_pixmap.c
@@ -43,6 +43,9 @@
static float top, bottom;
+static PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT_func = NULL;
+static PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT_func = NULL;
+
static Display *
OpenDisplay(void)
@@ -60,10 +63,20 @@ OpenDisplay(void)
screen = DefaultScreen(dpy);
ext = glXQueryExtensionsString(dpy, screen);
if (!strstr(ext, "GLX_EXT_texture_from_pixmap")) {
- printf("GLX_EXT_texture_from_pixmap not supported by GLX\n");
+ fprintf(stderr, "GLX_EXT_texture_from_pixmap not supported.\n");
exit(1);
}
+ glXBindTexImageEXT_func = (PFNGLXBINDTEXIMAGEEXTPROC)
+ glXGetProcAddress((GLubyte *) "glXBindTexImageEXT");
+ glXReleaseTexImageEXT_func = (PFNGLXRELEASETEXIMAGEEXTPROC)
+ glXGetProcAddress((GLubyte*) "glXReleaseTexImageEXT");
+
+ if (!glXBindTexImageEXT_func || !glXReleaseTexImageEXT_func) {
+ fprintf(stderr, "glXGetProcAddress failed!\n");
+ exit(1);
+ }
+
return dpy;
}
@@ -241,14 +254,14 @@ BindPixmapTexture(Display *dpy, GLXPixmap gp)
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
- glXBindTexImageEXT(dpy, gp, GLX_FRONT_LEFT_EXT, NULL);
+ glXBindTexImageEXT_func(dpy, gp, GLX_FRONT_LEFT_EXT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
/*
- glXReleaseTexImageEXT (display, glxpixmap, GLX_FRONT_LEFT_EXT);
+ glXReleaseTexImageEXT_func(display, glxpixmap, GLX_FRONT_LEFT_EXT);
*/
}
diff --git a/src/glx/mini/miniglx.c b/src/glx/mini/miniglx.c
index 71a0658eae3..874b88bc497 100644
--- a/src/glx/mini/miniglx.c
+++ b/src/glx/mini/miniglx.c
@@ -2434,6 +2434,7 @@ void (*glXGetProcAddress(const GLubyte *procname))( void )
return _glapi_get_proc_address((const char *) procname);
}
+void (*glXGetProcAddressARB(const GLubyte *procName))( void ) __attribute__ ((alias ("glXGetProcAddress")));
/**
* \brief Query the Mini GLX version.
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c
index c6202d969cc..e08b5b3c7fb 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c
+++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c
@@ -41,7 +41,11 @@
#include "mm.h"
#include "imports.h"
+#if 0
+#define DBG(...) _mesa_printf(__VA_ARGS__)
+#else
#define DBG(...)
+#endif
/* Internal flags:
*/
@@ -570,6 +574,9 @@ dri_fake_bo_alloc(dri_bufmgr *bufmgr, const char *name,
bo_fake->flags = 0;
bo_fake->is_static = GL_FALSE;
+ DBG("drm_bo_alloc: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name,
+ bo_fake->bo.size / 1024);
+
return &bo_fake->bo;
}
@@ -592,10 +599,14 @@ dri_fake_bo_alloc_static(dri_bufmgr *bufmgr, const char *name,
bo_fake->bo.virtual = virtual;
bo_fake->bo.bufmgr = bufmgr;
bo_fake->refcount = 1;
+ bo_fake->id = ++bufmgr_fake->buf_nr;
bo_fake->name = name;
bo_fake->flags = DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE;
bo_fake->is_static = GL_TRUE;
+ DBG("drm_bo_alloc_static: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name,
+ bo_fake->bo.size / 1024);
+
return &bo_fake->bo;
}
@@ -648,7 +659,8 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable)
_glthread_LOCK_MUTEX(bufmgr_fake->mutex);
{
- DBG("bmMapBuffer %d\n", bo_fake->id);
+ DBG("drm_bo_map: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name,
+ bo_fake->bo.size / 1024);
if (bo->virtual != NULL) {
_mesa_printf("%s: already mapped\n", __FUNCTION__);
@@ -698,6 +710,9 @@ dri_fake_bo_unmap(dri_bo *bo)
if (bo == NULL)
return 0;
+ DBG("drm_bo_unmap: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name,
+ bo_fake->bo.size / 1024);
+
bo->virtual = NULL;
return 0;
@@ -713,22 +728,32 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags)
* different flags. See drmAddValidateItem().
*/
+ DBG("drm_bo_validate: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name,
+ bo_fake->bo.size / 1024);
bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
_glthread_LOCK_MUTEX(bufmgr_fake->mutex);
{
+ if (bo_fake->is_static) {
+ /* Add it to the needs-fence list */
+ bufmgr_fake->need_fence = 1;
+ _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex);
+ return 0;
+ }
+
/* Allocate the card memory */
if (!bo_fake->block && !evict_and_alloc_block(bo)) {
bufmgr_fake->fail = 1;
_glthread_UNLOCK_MUTEX(bufmgr_fake->mutex);
+ DBG("Failed to validate buf %d:%s\n", bo_fake->id, bo_fake->name);
return -1;
}
assert(bo_fake->block);
assert(bo_fake->block->bo == &bo_fake->bo);
- DBG("Add buf %d (block %p, dirty %d) to referenced list\n",
- bo_fake->id, bo_fake->block, bo_fake->dirty);
+ DBG("Add buf %d:%s (block %p, dirty %d) to referenced list\n",
+ bo_fake->id, bo_fake->name, bo_fake->block, bo_fake->dirty);
move_to_tail(&bufmgr_fake->referenced, bo_fake->block);
bo_fake->block->referenced = 1;
@@ -737,8 +762,8 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags)
/* Upload the buffer contents if necessary */
if (bo_fake->dirty) {
- DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", bo_fake->id,
- bo_fake->name, bo->size, block->mem->ofs);
+ DBG("Upload dirty buf %d:%s, sz %d offset 0x%x\n", bo_fake->id,
+ bo_fake->name, bo->size, bo_fake->block->mem->ofs);
assert(!(bo_fake->flags &
(BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT)));
@@ -786,6 +811,8 @@ dri_fake_fence_validated(dri_bufmgr *bufmgr, const char *name,
fence_blocks(bufmgr_fake, cookie);
_glthread_UNLOCK_MUTEX(bufmgr_fake->mutex);
+ DBG("drm_fence_validated: 0x%08x cookie\n", fence_fake->fence_cookie);
+
return &fence_fake->fence;
}
@@ -824,6 +851,8 @@ dri_fake_fence_wait(dri_fence *fence)
dri_fence_fake *fence_fake = (dri_fence_fake *)fence;
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr;
+ DBG("drm_fence_wait: 0x%08x cookie\n", fence_fake->fence_cookie);
+
_glthread_LOCK_MUTEX(bufmgr_fake->mutex);
_fence_wait_internal(bufmgr_fake, fence_fake->fence_cookie);
_glthread_UNLOCK_MUTEX(bufmgr_fake->mutex);
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
index 64248a1d871..fd432ba3f72 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
+++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
@@ -150,7 +150,7 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
* pass all of the allocation class flags.
*/
flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
- DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE;
+ DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_MOVE;
/* No hints we want to use. */
hint = 0;
@@ -362,6 +362,7 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
unsigned int fence_type_flush)
{
dri_bufmgr_ttm *bufmgr_ttm;
+ dri_bo *test_alloc;
bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
bufmgr_ttm->fd = fd;
@@ -381,5 +382,17 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference;
bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait;
+ /* Attempt an allocation to make sure that the DRM was actually set up for
+ * TTM.
+ */
+ test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation",
+ 4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT);
+ if (test_alloc == NULL) {
+ _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
+ free(bufmgr_ttm);
+ return NULL;
+ }
+ dri_bo_unreference(test_alloc);
+
return &bufmgr_ttm->bufmgr;
}
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index 9f0c9491b22..a19d4b65840 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -491,12 +491,19 @@ static void i915SetTexImages( i915ContextPtr i915,
abort();
}
-
- if (i915->intel.intelScreen->deviceID == PCI_CHIP_I945_G ||
- i915->intel.intelScreen->deviceID == PCI_CHIP_I945_GM)
- i945LayoutTextureImages( i915, tObj );
- else
- i915LayoutTextureImages( i915, tObj );
+ switch (i915->intel.intelScreen->deviceID) {
+ case PCI_CHIP_I945_G:
+ case PCI_CHIP_I945_GM:
+ case PCI_CHIP_I945_GME:
+ case PCI_CHIP_G33_G:
+ case PCI_CHIP_Q33_G:
+ case PCI_CHIP_Q35_G:
+ i945LayoutTextureImages( i915, tObj );
+ break;
+ default:
+ i915LayoutTextureImages( i915, tObj );
+ break;
+ }
t->Setup[I915_TEXREG_MS3] =
(((tObj->Image[0][t->intel.base.firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) |
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index e747fc6991b..11c23f24a1b 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -123,6 +123,14 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
chipset = "Intel(R) 945G"; break;
case PCI_CHIP_I945_GM:
chipset = "Intel(R) 945GM"; break;
+ case PCI_CHIP_I945_GME:
+ chipset = "Intel(R) 945GME"; break;
+ case PCI_CHIP_G33_G:
+ chipset = "Intel(R) G33"; break;
+ case PCI_CHIP_Q35_G:
+ chipset = "Intel(R) Q35"; break;
+ case PCI_CHIP_Q33_G:
+ chipset = "Intel(R) Q33"; break;
default:
chipset = "Unknown Intel Chipset"; break;
}
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index c48b074cc51..3b50107d73f 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -454,6 +454,10 @@ extern int INTEL_DEBUG;
#define PCI_CHIP_I915_GM 0x2592
#define PCI_CHIP_I945_G 0x2772
#define PCI_CHIP_I945_GM 0x27A2
+#define PCI_CHIP_I945_GME 0x27AE
+#define PCI_CHIP_G33_G 0x29C2
+#define PCI_CHIP_Q35_G 0x29B2
+#define PCI_CHIP_Q33_G 0x29D2
/* ================================================================
diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c
index 535cbfcb26e..d175870a0c5 100644
--- a/src/mesa/drivers/dri/i915/intel_pixel.c
+++ b/src/mesa/drivers/dri/i915/intel_pixel.c
@@ -439,10 +439,26 @@ intelDrawPixels( GLcontext *ctx,
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
- if (!intelTryDrawPixels( ctx, x, y, width, height, format, type,
- unpack, pixels ))
+ if (intelTryDrawPixels( ctx, x, y, width, height, format, type,
+ unpack, pixels ))
+ return;
+
+ if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) {
+ /*
+ * We don't want the i915 texenv program to be applied to DrawPixels.
+ * This is really just a performance optimization (mesa will other-
+ * wise happily run the fragment program on each pixel in the image).
+ */
+ struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current;
+ ctx->FragmentProgram._Current = NULL;
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ unpack, pixels );
+ ctx->FragmentProgram._Current = fpSave;
+ }
+ else {
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
- unpack, pixels );
+ unpack, pixels );
+ }
}
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 67e176a1c6f..ca8610b4965 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -514,6 +514,10 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
case PCI_CHIP_I915_GM:
case PCI_CHIP_I945_G:
case PCI_CHIP_I945_GM:
+ case PCI_CHIP_I945_GME:
+ case PCI_CHIP_G33_G:
+ case PCI_CHIP_Q35_G:
+ case PCI_CHIP_Q33_G:
return i915CreateContext( mesaVis, driContextPriv,
sharedContextPrivate );
diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c
index 98ddc796724..5bd280652af 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.c
+++ b/src/mesa/drivers/dri/i915/intel_tex.c
@@ -677,7 +677,11 @@ static void intelUploadTexImage( intelContextPtr intel,
/* Time for another vtbl entry:
*/
else if (intel->intelScreen->deviceID == PCI_CHIP_I945_G ||
- intel->intelScreen->deviceID == PCI_CHIP_I945_GM) {
+ intel->intelScreen->deviceID == PCI_CHIP_I945_GM ||
+ intel->intelScreen->deviceID == PCI_CHIP_I945_GME ||
+ intel->intelScreen->deviceID == PCI_CHIP_G33_G ||
+ intel->intelScreen->deviceID == PCI_CHIP_Q33_G ||
+ intel->intelScreen->deviceID == PCI_CHIP_Q35_G) {
GLuint row_len = image->Width * image->TexFormat->TexelBytes;
GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
GLubyte *src = (GLubyte *)image->Data;
diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile
index c6a29149c77..eb704e1538b 100644
--- a/src/mesa/drivers/dri/i915tex/Makefile
+++ b/src/mesa/drivers/dri/i915tex/Makefile
@@ -33,6 +33,7 @@ DRIVER_SOURCES = \
intel_pixel_draw.c \
intel_buffers.c \
intel_blit.c \
+ i915_disasm.c \
i915_tex.c \
i915_texstate.c \
i915_context.c \
diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c
index 441dc660acb..dc91af71815 100644
--- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c
@@ -487,11 +487,13 @@ i830_emit_state(struct intel_context *intel)
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
state->tex_offset[i] | TM0S0_USE_FENCE);
}
- else {
- assert(i == 0);
- assert(state == &i830->meta);
- OUT_BATCH(0);
- }
+ else if (state == &i830->meta) {
+ assert(i == 0);
+ OUT_BATCH(0);
+ }
+ else {
+ OUT_BATCH(state->tex_offset[i]);
+ }
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]);
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]);
diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c
new file mode 100644
index 00000000000..6ac34a14804
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c
@@ -0,0 +1,740 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <[email protected]>
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <inttypes.h>
+
+#include "i915_disasm.h"
+#include "i915_reg.h"
+
+#define BUFFER_FAIL(_count, _len, _name) do { \
+ fprintf(out, "Buffer size too small in %s (%d < %d)\n", \
+ (_name), (_count), (_len)); \
+ (*failures)++; \
+ return count; \
+} while (0)
+
+static FILE *out;
+static uint32_t saved_s2 = 0, saved_s4 = 0;
+static char saved_s2_set = 0, saved_s4_set = 0;
+
+static float
+int_as_float(uint32_t intval)
+{
+ union intfloat {
+ uint32_t i;
+ float f;
+ } uval;
+
+ uval.i = intval;
+ return uval.f;
+}
+
+static void
+instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index,
+ char *fmt, ...)
+{
+ va_list va;
+
+ fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]);
+ va_start(va, fmt);
+ vfprintf(out, fmt, va);
+ va_end(va);
+}
+
+
+static int
+decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+ unsigned int opcode;
+
+ struct {
+ uint32_t opcode;
+ 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" },
+ };
+
+
+ for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]);
+ opcode++) {
+ if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) {
+ unsigned int len = 1, i;
+
+ instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name);
+ if (opcodes_mi[opcode].max_len > 1) {
+ len = (data[0] & 0x000000ff) + 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);
+ }
+ }
+
+ for (i = 1; i < len; i++) {
+ if (i >= count)
+ BUFFER_FAIL(count, len, opcodes_mi[opcode].name);
+ instr_out(data, hw_offset, i, "dword %d\n", i);
+ }
+
+ return len;
+ }
+ }
+
+ instr_out(data, hw_offset, 0, "MI UNKNOWN\n");
+ (*failures)++;
+ return 1;
+}
+
+static int
+decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+ unsigned int opcode;
+
+ struct {
+ uint32_t opcode;
+ int min_len;
+ int max_len;
+ char *name;
+ } opcodes_2d[] = {
+ { 0x40, 5, 5, "COLOR_BLT" },
+ { 0x43, 6, 6, "SRC_COPY_BLT" },
+ { 0x01, 8, 8, "XY_SETUP_BLT" },
+ { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" },
+ { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" },
+ { 0x24, 2, 2, "XY_PIXEL_BLT" },
+ { 0x25, 3, 3, "XY_SCANLINES_BLT" },
+ { 0x26, 4, 4, "Y_TEXT_BLT" },
+ { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" },
+ { 0x50, 6, 6, "XY_COLOR_BLT" },
+ { 0x51, 6, 6, "XY_PAT_BLT" },
+ { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" },
+ { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" },
+ { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" },
+ { 0x52, 9, 9, "XY_MONO_PAT_BLT" },
+ { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" },
+ { 0x53, 8, 8, "XY_SRC_COPY_BLT" },
+ { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" },
+ { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" },
+ { 0x55, 9, 9, "XY_FULL_BLT" },
+ { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" },
+ { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" },
+ { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" },
+ { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" },
+ { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" },
+ };
+
+ for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]);
+ opcode++) {
+ if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) {
+ unsigned int len = 1, i;
+
+ instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name);
+ if (opcodes_2d[opcode].max_len > 1) {
+ len = (data[0] & 0x000000ff) + 2;
+ if (len < opcodes_2d[opcode].min_len ||
+ len > opcodes_2d[opcode].max_len)
+ {
+ fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name);
+ }
+ }
+
+ for (i = 1; i < len; i++) {
+ if (i >= count)
+ BUFFER_FAIL(count, len, opcodes_2d[opcode].name);
+ instr_out(data, hw_offset, i, "dword %d\n", i);
+ }
+
+ return len;
+ }
+ }
+
+ instr_out(data, hw_offset, 0, "2D UNKNOWN\n");
+ (*failures)++;
+ return 1;
+}
+
+static int
+decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+ switch ((data[0] & 0x00f80000) >> 19) {
+ case 0x11:
+ instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n");
+ return 1;
+ case 0x10:
+ instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n");
+ return 1;
+ }
+
+ instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+ (*failures)++;
+ return 1;
+}
+
+static int
+decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+ unsigned int len, i, c, opcode, word, map, sampler, instr;
+
+ struct {
+ uint32_t opcode;
+ int min_len;
+ int max_len;
+ char *name;
+ } opcodes_3d_1d[] = {
+ { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" },
+ { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" },
+ { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" },
+ { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },
+ { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },
+ { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" },
+ { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" },
+ { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },
+ { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" },
+ { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" },
+ { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" },
+ { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },
+ { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" },
+ { 0x89, 4, 4, "3DSTATE_FOG_MODE" },
+ { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" },
+ { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" },
+ { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" },
+ };
+
+ switch ((data[0] & 0x00ff0000) >> 16) {
+ case 0x07:
+ /* This instruction is unusual. A 0 length means just 1 DWORD instead of
+ * 2. The 0 length is specified in one place to be unsupported, but
+ * stated to be required in another, and 0 length LOAD_INDIRECTs appear
+ * to cause no harm at least.
+ */
+ instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n");
+ len = (data[0] & 0x000000ff) + 1;
+ i = 1;
+ if (data[0] & (0x01 << 8)) {
+ if (i + 2 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+ instr_out(data, hw_offset, i++, "SIS.0\n");
+ instr_out(data, hw_offset, i++, "SIS.1\n");
+ }
+ if (data[0] & (0x02 << 8)) {
+ if (i + 1 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+ instr_out(data, hw_offset, i++, "DIS.0\n");
+ }
+ if (data[0] & (0x04 << 8)) {
+ if (i + 2 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+ instr_out(data, hw_offset, i++, "SSB.0\n");
+ instr_out(data, hw_offset, i++, "SSB.1\n");
+ }
+ if (data[0] & (0x08 << 8)) {
+ if (i + 2 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+ instr_out(data, hw_offset, i++, "MSB.0\n");
+ instr_out(data, hw_offset, i++, "MSB.1\n");
+ }
+ if (data[0] & (0x10 << 8)) {
+ if (i + 2 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+ instr_out(data, hw_offset, i++, "PSP.0\n");
+ instr_out(data, hw_offset, i++, "PSP.1\n");
+ }
+ if (data[0] & (0x20 << 8)) {
+ if (i + 2 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+ instr_out(data, hw_offset, i++, "PSC.0\n");
+ instr_out(data, hw_offset, i++, "PSC.1\n");
+ }
+ if (len != i) {
+ fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n");
+ (*failures)++;
+ return len;
+ }
+ return len;
+ case 0x04:
+ instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n");
+ len = (data[0] & 0x0000000f) + 2;
+ i = 1;
+ for (word = 0; word <= 7; word++) {
+ if (data[0] & (1 << (4 + word))) {
+ if (i >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1");
+
+ /* save vertex state for decode */
+ if (word == 2) {
+ saved_s2_set = 1;
+ saved_s2 = data[i];
+ }
+ if (word == 4) {
+ saved_s4_set = 1;
+ saved_s4 = data[i];
+ }
+
+ instr_out(data, hw_offset, i++, "S%d\n", word);
+ }
+ }
+ if (len != i) {
+ fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n");
+ (*failures)++;
+ }
+ return len;
+ case 0x00:
+ instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n");
+ len = (data[0] & 0x0000003f) + 2;
+
+ i = 1;
+ for (map = 0; map <= 15; map++) {
+ if (data[1] & (1 << map)) {
+ if (i + 3 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE");
+ instr_out(data, hw_offset, i++, "map %d MS2\n", map);
+ instr_out(data, hw_offset, i++, "map %d MS3\n", map);
+ instr_out(data, hw_offset, i++, "map %d MS4\n", map);
+ }
+ }
+ if (len != i) {
+ fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n");
+ (*failures)++;
+ return len;
+ }
+ return len;
+ case 0x06:
+ instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n");
+ len = (data[0] & 0x000000ff) + 2;
+
+ i = 1;
+ for (c = 0; c <= 31; c++) {
+ if (data[1] & (1 << c)) {
+ if (i + 4 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS");
+ instr_out(data, hw_offset, i, "C%d.X = %f\n",
+ c, int_as_float(data[i]));
+ i++;
+ instr_out(data, hw_offset, i, "C%d.Y = %f\n",
+ c, int_as_float(data[i]));
+ i++;
+ instr_out(data, hw_offset, i, "C%d.Z = %f\n",
+ c, int_as_float(data[i]));
+ i++;
+ instr_out(data, hw_offset, i, "C%d.W = %f\n",
+ c, int_as_float(data[i]));
+ i++;
+ }
+ }
+ if (len != i) {
+ fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n");
+ (*failures)++;
+ }
+ return len;
+ case 0x05:
+ instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n");
+ len = (data[0] & 0x000000ff) + 2;
+ if ((len - 1) % 3 != 0 || len > 370) {
+ fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n");
+ (*failures)++;
+ }
+ i = 1;
+ for (instr = 0; instr < (len - 1) / 3; instr++) {
+ if (i + 3 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE");
+ instr_out(data, hw_offset, i++, "PS%03x\n", instr);
+ instr_out(data, hw_offset, i++, "PS%03x\n", instr);
+ instr_out(data, hw_offset, i++, "PS%03x\n", instr);
+ }
+ return len;
+ case 0x01:
+ instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n");
+ len = (data[0] & 0x0000003f) + 2;
+ i = 1;
+ for (sampler = 0; sampler <= 15; sampler++) {
+ if (data[1] & (1 << sampler)) {
+ if (i + 3 >= count)
+ BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE");
+ instr_out(data, hw_offset, i++, "sampler %d SS2\n",
+ sampler);
+ instr_out(data, hw_offset, i++, "sampler %d SS3\n",
+ sampler);
+ instr_out(data, hw_offset, i++, "sampler %d SS4\n",
+ sampler);
+ }
+ }
+ if (len != i) {
+ fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n");
+ (*failures)++;
+ }
+ return len;
+ }
+
+ for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]);
+ opcode++)
+ {
+ if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) {
+ len = 1;
+
+ instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name);
+ if (opcodes_3d_1d[opcode].max_len > 1) {
+ len = (data[0] & 0x0000ffff) + 2;
+ if (len < opcodes_3d_1d[opcode].min_len ||
+ len > opcodes_3d_1d[opcode].max_len)
+ {
+ fprintf(out, "Bad count in %s\n",
+ opcodes_3d_1d[opcode].name);
+ (*failures)++;
+ }
+ }
+
+ for (i = 1; i < len; i++) {
+ if (i >= count)
+ BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name);
+ instr_out(data, hw_offset, i, "dword %d\n", i);
+ }
+
+ return len;
+ }
+ }
+
+ instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+ (*failures)++;
+ return 1;
+}
+
+static int
+decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
+ int *failures)
+{
+ char immediate = (data[0] & (1 << 23)) == 0;
+ unsigned int len, i;
+ char *primtype;
+
+ switch ((data[0] >> 18) & 0xf) {
+ case 0x0: primtype = "TRILIST"; break;
+ case 0x1: primtype = "TRISTRIP"; break;
+ case 0x2: primtype = "TRISTRIP_REVERSE"; break;
+ case 0x3: primtype = "TRIFAN"; break;
+ case 0x4: primtype = "POLYGON"; break;
+ case 0x5: primtype = "LINELIST"; break;
+ case 0x6: primtype = "LINESTRIP"; break;
+ case 0x7: primtype = "RECTLIST"; break;
+ case 0x8: primtype = "POINTLIST"; break;
+ case 0x9: primtype = "DIB"; break;
+ case 0xa: primtype = "CLEAR_RECT"; break;
+ default: primtype = "unknown"; break;
+ }
+
+ /* XXX: 3DPRIM_DIB not supported */
+ if (immediate) {
+ len = (data[0] & 0x0003ffff) + 2;
+ instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype);
+ if (count < len)
+ BUFFER_FAIL(count, len, "3DPRIMITIVE inline");
+ if (!saved_s2_set || !saved_s4_set) {
+ fprintf(out, "unknown vertex format\n");
+ for (i = 1; i < len; i++) {
+ instr_out(data, hw_offset, i,
+ " vertex data (%f float)\n",
+ int_as_float(data[i]));
+ }
+ } else {
+ unsigned int vertex = 0;
+ for (i = 1; i < len;) {
+ unsigned int tc;
+
+#define VERTEX_OUT(fmt, ...) do { \
+ if (i < len) \
+ instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \
+ else \
+ fprintf(out, " missing data in V%d\n", vertex); \
+ i++; \
+} while (0)
+
+ VERTEX_OUT("X = %f", int_as_float(data[i]));
+ VERTEX_OUT("Y = %f", int_as_float(data[i]));
+ switch (saved_s4 >> 6 & 0x7) {
+ case 0x1:
+ VERTEX_OUT("Z = %f", int_as_float(data[i]));
+ break;
+ case 0x2:
+ VERTEX_OUT("Z = %f", int_as_float(data[i]));
+ VERTEX_OUT("W = %f", int_as_float(data[i]));
+ break;
+ case 0x3:
+ break;
+ case 0x4:
+ VERTEX_OUT("W = %f", int_as_float(data[i]));
+ break;
+ default:
+ fprintf(out, "bad S4 position mask\n");
+ }
+
+ if (saved_s4 & (1 << 10)) {
+ VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, "
+ "B=0x%02x)",
+ data[i] >> 24,
+ (data[i] >> 16) & 0xff,
+ (data[i] >> 8) & 0xff,
+ data[i] & 0xff);
+ }
+ if (saved_s4 & (1 << 11)) {
+ VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, "
+ "B=0x%02x)",
+ data[i] >> 24,
+ (data[i] >> 16) & 0xff,
+ (data[i] >> 8) & 0xff,
+ data[i] & 0xff);
+ }
+ if (saved_s4 & (1 << 12))
+ VERTEX_OUT("width = 0x%08x)", data[i]);
+
+ for (tc = 0; tc <= 7; tc++) {
+ switch ((saved_s2 >> (tc * 4)) & 0xf) {
+ case 0x0:
+ VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
+ VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
+ break;
+ case 0x1:
+ VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
+ VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
+ VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i]));
+ break;
+ case 0x2:
+ VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
+ VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
+ VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i]));
+ VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i]));
+ break;
+ case 0x3:
+ VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
+ break;
+ case 0x4:
+ VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]);
+ break;
+ case 0x5:
+ VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]);
+ VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]);
+ break;
+ case 0xf:
+ break;
+ default:
+ fprintf(out, "bad S2.T%d format\n", tc);
+ }
+ }
+ vertex++;
+ }
+ }
+ } else {
+ /* indirect vertices */
+ len = data[0] & 0x0000ffff; /* index count */
+ if (data[0] & (1 << 17)) {
+ /* random vertex access */
+ if (count < (len + 1) / 2 + 1) {
+ BUFFER_FAIL(count, (len + 1) / 2 + 1,
+ "3DPRIMITIVE random indirect");
+ }
+ instr_out(data, hw_offset, 0,
+ "3DPRIMITIVE random indirect %s (%d)\n", primtype, len);
+ if (len == 0) {
+ /* vertex indices continue until 0xffff is found */
+ for (i = 1; i < count; i++) {
+ if ((data[i] & 0xffff) == 0xffff) {
+ instr_out(data, hw_offset, i,
+ " indices: (terminator)\n");
+ return i;
+ } else if ((data[i] >> 16) == 0xffff) {
+ instr_out(data, hw_offset, i,
+ " indices: 0x%04x, "
+ "(terminator)\n",
+ data[i] & 0xffff);
+ return i;
+ } else {
+ instr_out(data, hw_offset, i,
+ " indices: 0x%04x, 0x%04x\n",
+ data[i] & 0xffff, data[i] >> 16);
+ }
+ }
+ fprintf(out,
+ "3DPRIMITIVE: no terminator found in index buffer\n");
+ (*failures)++;
+ return count;
+ } else {
+ /* fixed size vertex index buffer */
+ for (i = 0; i < len; i += 2) {
+ if (i * 2 == len - 1) {
+ instr_out(data, hw_offset, i,
+ " indices: 0x%04x\n",
+ data[i] & 0xffff);
+ } else {
+ instr_out(data, hw_offset, i,
+ " indices: 0x%04x, 0x%04x\n",
+ data[i] & 0xffff, data[i] >> 16);
+ }
+ }
+ }
+ return (len + 1) / 2 + 1;
+ } else {
+ /* sequential vertex access */
+ if (count < 2)
+ BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect");
+ instr_out(data, hw_offset, 0,
+ "3DPRIMITIVE sequential indirect %s, %d starting from "
+ "%d\n", primtype, len, data[1] & 0xffff);
+ instr_out(data, hw_offset, 1, " start\n");
+ return 2;
+ }
+ }
+
+ return len;
+}
+
+static int
+decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+ unsigned int opcode;
+
+ struct {
+ uint32_t opcode;
+ int min_len;
+ int max_len;
+ char *name;
+ } opcodes_3d[] = {
+ { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" },
+ { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" },
+ { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" },
+ { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" },
+ { 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
+ { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" },
+ { 0x0d, 1, 1, "3DSTATE_MODES_4" },
+ { 0x0c, 1, 1, "3DSTATE_MODES_5" },
+ { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
+ };
+
+ switch ((data[0] & 0x1f000000) >> 24) {
+ case 0x1f:
+ return decode_3d_primitive(data, count, hw_offset, failures);
+ case 0x1d:
+ return decode_3d_1d(data, count, hw_offset, failures);
+ case 0x1c:
+ return decode_3d_1c(data, count, hw_offset, failures);
+ }
+
+ for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
+ opcode++) {
+ if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) {
+ unsigned int len = 1, i;
+
+ instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
+ if (opcodes_3d[opcode].max_len > 1) {
+ len = (data[0] & 0xff) + 2;
+ if (len < opcodes_3d[opcode].min_len ||
+ len > opcodes_3d[opcode].max_len)
+ {
+ fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
+ }
+ }
+
+ for (i = 1; i < len; i++) {
+ if (i >= count)
+ BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
+ instr_out(data, hw_offset, i, "dword %d\n", i);
+ }
+ return len;
+ }
+ }
+
+ instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+ (*failures)++;
+ return 1;
+}
+
+/**
+ * Decodes an i830-i915 batch buffer, writing the output to stdout.
+ *
+ * \param data batch buffer contents
+ * \param count number of DWORDs to decode in the batch buffer
+ * \param hw_offset hardware address for the buffer
+ */
+int
+i915_disasm(uint32_t *data, int count, uint32_t hw_offset)
+{
+ int index = 0;
+ int failures = 0;
+
+ out = stdout;
+
+ while (index < count) {
+ switch ((data[index] & 0xe0000000) >> 29) {
+ case 0x0:
+ index += decode_mi(data + index, count - index,
+ hw_offset + index * 4, &failures);
+ break;
+ case 0x2:
+ index += decode_2d(data + index, count - index,
+ hw_offset + index * 4, &failures);
+ break;
+ case 0x3:
+ index += decode_3d(data + index, count - index,
+ hw_offset + index * 4, &failures);
+ break;
+ default:
+ instr_out(data, hw_offset, index, "UNKNOWN\n");
+ failures++;
+ index++;
+ break;
+ }
+ fflush(out);
+ }
+
+ return failures;
+}
+
+void i915_disasm_context_reset()
+{
+ saved_s2_set = 0;
+ saved_s4_set = 1;
+}
+
diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.h b/src/mesa/drivers/dri/i915tex/i915_disasm.h
new file mode 100644
index 00000000000..5eb620f9a4e
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_disasm.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <[email protected]>
+ *
+ */
+
+int i915_disasm(uint32_t *data, int count, uint32_t hw_offset);
+void i915_disasm_context_reset();
diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
index 2a3ccd01a05..5d6ad8d86cf 100644
--- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
@@ -197,7 +197,7 @@ i915_emit_invarient_state(struct intel_context *intel)
/* Need to initialize this to zero.
*/
- OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (1));
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0);
OUT_BATCH(0);
/* XXX: Use this */
diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
index 26eecb94409..1edbb618d34 100644
--- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
@@ -66,27 +66,6 @@
* modifying cliprects ???
*/
-static void
-intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint size)
-{
- int i;
- fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", size / 4);
- for (i = 0; i < size / 4; i += 4) {
- char dw1[11], dw2[11] = "", dw3[11] = "", dw4[11] = "";
-
- sprintf(dw1, "0x%08x", ptr[i]);
- if (i + 1 < size / 4)
- sprintf(dw2, "0x%08x", ptr[i + 1]);
- if (i + 2 < size / 4)
- sprintf(dw3, "0x%08x", ptr[i + 2]);
- if (i + 3 < size / 4)
- sprintf(dw4, "0x%08x", ptr[i + 3]);
- fprintf(stderr, "0x%x:\t%s %s %s %s\n", offset + i * 4,
- dw1, dw2, dw3, dw4);
- }
- fprintf(stderr, "END BATCH\n\n\n");
-}
-
/*======================================================================
* Public functions
*/
@@ -166,7 +145,7 @@ do_flush_locked(struct intel_batchbuffer *batch,
}
if (INTEL_DEBUG & DEBUG_BATCH)
- intel_dump_batchbuffer(0, ptr, used);
+ i915_disasm(ptr, used / 4, 0);
dri_bo_unmap(batch->buf);
batch->map = NULL;
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c
index 696845a7fc9..cd4333d0d34 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.c
+++ b/src/mesa/drivers/dri/i915tex/intel_context.c
@@ -59,6 +59,7 @@
#include "intel_regions.h"
#include "intel_buffer_objects.h"
#include "intel_fbo.h"
+#include "i915_disasm.h"
#include "drirenderbuffer.h"
#include "vblank.h"
@@ -130,6 +131,18 @@ intelGetString(GLcontext * ctx, GLenum name)
case PCI_CHIP_I945_GM:
chipset = "Intel(R) 945GM";
break;
+ case PCI_CHIP_I945_GME:
+ chipset = "Intel(R) 945GME";
+ break;
+ case PCI_CHIP_G33_G:
+ chipset = "Intel(R) G33";
+ break;
+ case PCI_CHIP_Q35_G:
+ chipset = "Intel(R) Q35";
+ break;
+ case PCI_CHIP_Q33_G:
+ chipset = "Intel(R) Q33";
+ break;
default:
chipset = "Unknown Intel Chipset";
break;
@@ -646,6 +659,8 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
if (!intel->intelScreen->ttm && sarea->texAge != intel->hHWContext) {
sarea->texAge = intel->hHWContext;
dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr);
+ if (INTEL_DEBUG & DEBUG_BATCH)
+ i915_disasm_context_reset();
}
if (sarea->width != intelScreen->width ||
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index a55f7d984e3..8755f5703dc 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -378,6 +378,10 @@ extern int INTEL_DEBUG;
#define PCI_CHIP_I915_GM 0x2592
#define PCI_CHIP_I945_G 0x2772
#define PCI_CHIP_I945_GM 0x27A2
+#define PCI_CHIP_I945_GME 0x27AE
+#define PCI_CHIP_G33_G 0x29C2
+#define PCI_CHIP_Q35_G 0x29B2
+#define PCI_CHIP_Q33_G 0x29D2
/* ================================================================
diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
index 8e83028b26c..843a78eb82b 100644
--- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
@@ -79,6 +79,10 @@ intel_miptree_create(struct intel_context *intel,
switch (intel->intelScreen->deviceID) {
case PCI_CHIP_I945_G:
case PCI_CHIP_I945_GM:
+ case PCI_CHIP_I945_GME:
+ case PCI_CHIP_G33_G:
+ case PCI_CHIP_Q33_G:
+ case PCI_CHIP_Q35_G:
ok = i945_miptree_layout(mt);
break;
case PCI_CHIP_I915_G:
diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c
index cbb583d3a20..6d9fc6144a2 100644
--- a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c
@@ -363,5 +363,20 @@ intelDrawPixels(GLcontext * ctx,
if (INTEL_DEBUG & DEBUG_PIXEL)
_mesa_printf("%s: fallback to swrast\n", __FUNCTION__);
- _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels);
+ if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) {
+ /*
+ * We don't want the i915 texenv program to be applied to DrawPixels.
+ * This is really just a performance optimization (mesa will other-
+ * wise happily run the fragment program on each pixel in the image).
+ */
+ struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current;
+ ctx->FragmentProgram._Current = NULL;
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ unpack, pixels );
+ ctx->FragmentProgram._Current = fpSave;
+ }
+ else {
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ unpack, pixels );
+ }
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c
index e3a631b6961..89cf3ea9139 100644
--- a/src/mesa/drivers/dri/i915tex/intel_screen.c
+++ b/src/mesa/drivers/dri/i915tex/intel_screen.c
@@ -123,8 +123,6 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv)
if (0)
_mesa_printf("TEX 0x%08x ", intelScreen->tex.handle);
if (intelScreen->tex.size != 0) {
- intelScreen->ttm = GL_FALSE;
-
if (drmMap(sPriv->fd,
intelScreen->tex.handle,
intelScreen->tex.size,
@@ -132,8 +130,6 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv)
intelUnmapScreenRegions(intelScreen);
return GL_FALSE;
}
- } else {
- intelScreen->ttm = GL_TRUE;
}
if (0)
@@ -530,12 +526,16 @@ intelInitDriver(__DRIscreenPrivate * sPriv)
(*glx_enable_extension) (psc, "GLX_SGI_make_current_read");
}
- if (intelScreen->ttm) {
- intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd,
- DRM_FENCE_TYPE_EXE,
- DRM_FENCE_TYPE_EXE |
- DRM_I915_FENCE_TYPE_RW);
- } else {
+ intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd,
+ DRM_FENCE_TYPE_EXE,
+ DRM_FENCE_TYPE_EXE |
+ DRM_I915_FENCE_TYPE_RW);
+ if (intelScreen->bufmgr == NULL) {
+ if (intelScreen->tex.size == 0) {
+ fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
+ __func__, __LINE__);
+ return GL_FALSE;
+ }
intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset,
intelScreen->tex.map,
intelScreen->tex.size,
@@ -740,6 +740,10 @@ intelCreateContext(const __GLcontextModes * mesaVis,
case PCI_CHIP_I915_GM:
case PCI_CHIP_I945_G:
case PCI_CHIP_I945_GM:
+ case PCI_CHIP_I945_GME:
+ case PCI_CHIP_G33_G:
+ case PCI_CHIP_Q35_G:
+ case PCI_CHIP_Q33_G:
return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
default:
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c
index b15569681a5..197cf35ebe6 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c
@@ -377,9 +377,6 @@ intelTexImage(GLcontext * ctx,
assert(!intelObj->mt);
}
- if (!pixels)
- return;
-
if (!intelObj->mt) {
guess_and_alloc_mipmap_tree(intel, intelObj, intelImage);
if (!intelObj->mt) {
@@ -681,6 +678,9 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
if (!intelObj)
return;
+ if (intelObj->mt)
+ intel_miptree_release(intel, &intelObj->mt);
+
intelObj->imageOverride = GL_TRUE;
intelObj->depthOverride = depth;
intelObj->pitchOverride = pitch;
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
index 0ae4fee1ba0..af18c26d55c 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
@@ -116,7 +116,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
/* We know/require this is true by now:
*/
- assert(intelObj->base.Complete);
+ assert(intelObj->base._Complete);
/* What levels must the tree include at a minimum?
*/
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index 422eb960979..9617cbebbfd 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -106,20 +106,23 @@ static const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
case GL_RENDERER:
switch (intel_context(ctx)->intelScreen->deviceID) {
case PCI_CHIP_I965_Q:
- chipset = "Intel(R) 965Q"; break;
+ chipset = "Intel(R) 965Q";
break;
case PCI_CHIP_I965_G:
case PCI_CHIP_I965_G_1:
- chipset = "Intel(R) 965G"; break;
+ chipset = "Intel(R) 965G";
break;
case PCI_CHIP_I946_GZ:
- chipset = "Intel(R) 946GZ"; break;
+ chipset = "Intel(R) 946GZ";
break;
case PCI_CHIP_I965_GM:
- chipset = "Intel(R) 965GM"; break;
+ chipset = "Intel(R) 965GM";
+ break;
+ case PCI_CHIP_I965_GME:
+ chipset = "Intel(R) 965GME/GLE";
break;
default:
- chipset = "Unknown Intel Chipset"; break;
+ chipset = "Unknown Intel Chipset";
}
(void) driGetRendererString( buffer, chipset, DRIVER_VERSION, 0 );
diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h
index a3c65b66e08..406f8483dce 100644
--- a/src/mesa/drivers/dri/i965/intel_context.h
+++ b/src/mesa/drivers/dri/i965/intel_context.h
@@ -385,6 +385,7 @@ extern int INTEL_DEBUG;
#define PCI_CHIP_I965_G_1 0x2982
#define PCI_CHIP_I946_GZ 0x2972
#define PCI_CHIP_I965_GM 0x2A02
+#define PCI_CHIP_I965_GME 0x2A12
/* ================================================================
diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c
index cb23b9dd879..44ee94614d5 100644
--- a/src/mesa/drivers/dri/i965/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c
@@ -138,7 +138,7 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel,
/* We know/require this is true by now:
*/
- assert(intelObj->base.Complete);
+ assert(intelObj->base._Complete);
/* What levels must the tree include at a minimum?
*/
diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
index 3bc84d862d3..4576c1ede4d 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
@@ -392,15 +392,6 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
int i;
int slots=0;
int total_size=0;
- /* t_vertex_generic dereferences a NULL pointer if we
- * pass NULL as the vp transform...
- */
- const GLfloat ident_vp[16] = {
- 1.0, 0.0, 0.0, 0.0,
- 0.0, 1.0, 0.0, 0.0,
- 0.0, 0.0, 1.0, 0.0,
- 0.0, 0.0, 0.0, 1.0
- };
nmesa->vertex_attr_count = 0;
RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
@@ -431,28 +422,20 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
if (RENDERINPUTS_TEST(index, i))
{
slots=i+1;
- if (i==_TNL_ATTRIB_POS)
- {
- /* special-case POS */
- EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_3F_VIEWPORT);
- }
- else
+ switch(attr_size[i])
{
- switch(attr_size[i])
- {
- case 1:
- EMIT_ATTR(i,EMIT_1F);
- break;
- case 2:
- EMIT_ATTR(i,EMIT_2F);
- break;
- case 3:
- EMIT_ATTR(i,EMIT_3F);
- break;
- case 4:
- EMIT_ATTR(i,EMIT_4F);
- break;
- }
+ case 1:
+ EMIT_ATTR(i,EMIT_1F);
+ break;
+ case 2:
+ EMIT_ATTR(i,EMIT_2F);
+ break;
+ case 3:
+ EMIT_ATTR(i,EMIT_3F);
+ break;
+ case 4:
+ EMIT_ATTR(i,EMIT_4F);
+ break;
}
if (i==_TNL_ATTRIB_COLOR0)
nmesa->color_offset=total_size;
@@ -465,7 +448,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
nmesa->vertex_size=_tnl_install_attrs( ctx,
nmesa->vertex_attrs,
nmesa->vertex_attr_count,
- ident_vp, 0 );
+ NULL, 0 );
assert(nmesa->vertex_size==total_size*4);
/*
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 0351989b2e4..7055286ba95 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -133,13 +133,15 @@ static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *stat
int i;
int dwords = (*state->check) (r300, state);
- fprintf(stderr, " emit %s/%d/%d\n", state->name, dwords,
+ fprintf(stderr, " emit %s %d/%d\n", state->name, dwords,
state->cmd_size);
- if (RADEON_DEBUG & DEBUG_VERBOSE)
- for (i = 0; i < dwords; i++)
- fprintf(stderr, " %s[%d]: %08X\n",
+ if (RADEON_DEBUG & DEBUG_VERBOSE) {
+ for (i = 0; i < dwords; i++) {
+ fprintf(stderr, " %s[%d]: %08x\n",
state->name, i, state->cmd[i]);
+ }
+ }
}
/**
@@ -152,24 +154,10 @@ static inline void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
{
struct r300_state_atom *atom;
uint32_t *dest;
+ int dwords;
dest = r300->cmdbuf.cmd_buf + r300->cmdbuf.count_used;
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
- foreach(atom, &r300->hw.atomlist) {
- if ((atom->dirty || r300->hw.all_dirty) == dirty) {
- int dwords = (*atom->check) (r300, atom);
-
- if (dwords)
- r300PrintStateAtom(r300, atom);
- else
- fprintf(stderr,
- " skip state %s\n",
- atom->name);
- }
- }
- }
-
/* Emit WAIT */
*dest = cmdwait(R300_WAIT_3D | R300_WAIT_3D_CLEAN);
dest++;
@@ -193,13 +181,20 @@ static inline void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
foreach(atom, &r300->hw.atomlist) {
if ((atom->dirty || r300->hw.all_dirty) == dirty) {
- int dwords = (*atom->check) (r300, atom);
-
+ dwords = (*atom->check) (r300, atom);
if (dwords) {
+ if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
+ r300PrintStateAtom(r300, atom);
+ }
memcpy(dest, atom->cmd, dwords * 4);
dest += dwords;
r300->cmdbuf.count_used += dwords;
atom->dirty = GL_FALSE;
+ } else {
+ if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
+ fprintf(stderr, " skip state %s\n",
+ atom->name);
+ }
}
}
}
@@ -245,22 +240,28 @@ void r300EmitState(r300ContextPtr r300)
r300->hw.all_dirty = GL_FALSE;
}
-#define CHECK( NM, COUNT ) \
-static int check_##NM( r300ContextPtr r300, \
- struct r300_state_atom* atom ) \
-{ \
- (void) atom; (void) r300; \
- return (COUNT); \
-}
-
#define packet0_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->packet0.count)
#define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
-CHECK(always, atom->cmd_size)
- CHECK(variable, packet0_count(atom->cmd) ? (1 + packet0_count(atom->cmd)) : 0)
- CHECK(vpu, vpu_count(atom->cmd) ? (1 + vpu_count(atom->cmd) * 4) : 0)
-#undef packet0_count
-#undef vpu_count
+static int check_always(r300ContextPtr r300, struct r300_state_atom *atom)
+{
+ return atom->cmd_size;
+}
+
+static int check_variable(r300ContextPtr r300, struct r300_state_atom *atom)
+{
+ int cnt;
+ cnt = packet0_count(atom->cmd);
+ return cnt ? cnt + 1 : 0;
+}
+
+static int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom)
+{
+ int cnt;
+ cnt = vpu_count(atom->cmd);
+ return cnt ? (cnt * 4) + 1 : 0;
+}
+
#define ALLOC_STATE( ATOM, CHK, SZ, IDX ) \
do { \
r300->hw.ATOM.cmd_size = (SZ); \
@@ -318,8 +319,8 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.unk21DC.cmd[0] = cmdpacket0(0x21DC, 1);
ALLOC_STATE(unk221C, always, 2, 0);
r300->hw.unk221C.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_221C, 1);
- ALLOC_STATE(unk2220, always, 5, 0);
- r300->hw.unk2220.cmd[0] = cmdpacket0(0x2220, 4);
+ ALLOC_STATE(vap_clip, always, 5, 0);
+ r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_CLIP_X_0, 4);
ALLOC_STATE(unk2288, always, 2, 0);
r300->hw.unk2288.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_2288, 1);
ALLOC_STATE(vof, always, R300_VOF_CMDSIZE, 0);
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 01caa617667..076bb49a006 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -49,8 +49,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define USER_BUFFERS
-//#define OPTIMIZE_ELTS
-
struct r300_context;
typedef struct r300_context r300ContextRec;
typedef struct r300_context *r300ContextPtr;
@@ -149,7 +147,6 @@ struct r300_dma_region {
int aos_offset; /* address in GART memory */
int aos_stride; /* distance between elements, in dwords */
int aos_size; /* number of components (1-4) */
- int aos_reg; /* VAP register assignment */
};
struct r300_dma {
@@ -455,7 +452,7 @@ struct r300_hw_state {
struct r300_state_atom vic; /* vap input control (2180) */
struct r300_state_atom unk21DC; /* (21DC) */
struct r300_state_atom unk221C; /* (221C) */
- struct r300_state_atom unk2220; /* (2220) */
+ struct r300_state_atom vap_clip;
struct r300_state_atom unk2288; /* (2288) */
struct r300_state_atom pvs; /* pvs_cntl (22D0) */
struct r300_state_atom gb_enable; /* (4008) */
@@ -783,11 +780,6 @@ struct r300_fragment_program {
#define R300_MAX_AOS_ARRAYS 16
-#define AOS_FORMAT_USHORT 0
-#define AOS_FORMAT_FLOAT 1
-#define AOS_FORMAT_UBYTE 2
-#define AOS_FORMAT_FLOAT_COLOR 3
-
#define REG_COORDS 0
#define REG_COLOR0 1
#define REG_TEX0 2
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
index 9fb712f7b8f..4670c28a02f 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -86,16 +86,15 @@ do { \
} while (0)
#endif
-static void r300EmitVec4(GLcontext * ctx,
- struct r300_dma_region *rvb,
+static void r300EmitVec4(GLcontext * ctx, struct r300_dma_region *rvb,
GLvoid * data, int stride, int count)
{
int i;
int *out = (int *)(rvb->address + rvb->start);
if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf(stderr, "%s count %d stride %d\n",
- __FUNCTION__, count, stride);
+ fprintf(stderr, "%s count %d stride %d out %p data %p\n",
+ __FUNCTION__, count, stride, (void *)out, (void *)data);
if (stride == 4)
COPY_DWORDS(out, data, count);
@@ -107,16 +106,15 @@ static void r300EmitVec4(GLcontext * ctx,
}
}
-static void r300EmitVec8(GLcontext * ctx,
- struct r300_dma_region *rvb,
+static void r300EmitVec8(GLcontext * ctx, struct r300_dma_region *rvb,
GLvoid * data, int stride, int count)
{
int i;
int *out = (int *)(rvb->address + rvb->start);
if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf(stderr, "%s count %d stride %d\n",
- __FUNCTION__, count, stride);
+ fprintf(stderr, "%s count %d stride %d out %p data %p\n",
+ __FUNCTION__, count, stride, (void *)out, (void *)data);
if (stride == 8)
COPY_DWORDS(out, data, count * 2);
@@ -129,8 +127,7 @@ static void r300EmitVec8(GLcontext * ctx,
}
}
-static void r300EmitVec12(GLcontext * ctx,
- struct r300_dma_region *rvb,
+static void r300EmitVec12(GLcontext * ctx, struct r300_dma_region *rvb,
GLvoid * data, int stride, int count)
{
int i;
@@ -152,16 +149,15 @@ static void r300EmitVec12(GLcontext * ctx,
}
}
-static void r300EmitVec16(GLcontext * ctx,
- struct r300_dma_region *rvb,
+static void r300EmitVec16(GLcontext * ctx, struct r300_dma_region *rvb,
GLvoid * data, int stride, int count)
{
int i;
int *out = (int *)(rvb->address + rvb->start);
if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf(stderr, "%s count %d stride %d\n",
- __FUNCTION__, count, stride);
+ fprintf(stderr, "%s count %d stride %d out %p data %p\n",
+ __FUNCTION__, count, stride, (void *)out, (void *)data);
if (stride == 16)
COPY_DWORDS(out, data, count * 4);
@@ -176,32 +172,22 @@ static void r300EmitVec16(GLcontext * ctx,
}
}
-static void r300EmitVec(GLcontext * ctx,
- struct r300_dma_region *rvb,
+static void r300EmitVec(GLcontext * ctx, struct r300_dma_region *rvb,
GLvoid * data, int size, int stride, int count)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf(stderr, "%s count %d size %d stride %d\n",
- __FUNCTION__, count, size, stride);
-
- /* Gets triggered when playing with future_hw_tcl_on ... */
- //assert(!rvb->buf);
-
if (stride == 0) {
r300AllocDmaRegion(rmesa, rvb, size * 4, 4);
count = 1;
rvb->aos_offset = GET_START(rvb);
rvb->aos_stride = 0;
} else {
- r300AllocDmaRegion(rmesa, rvb, size * count * 4, 4); /* alignment? */
+ r300AllocDmaRegion(rmesa, rvb, size * count * 4, 4);
rvb->aos_offset = GET_START(rvb);
rvb->aos_stride = size;
}
- /* Emit the data
- */
switch (size) {
case 1:
r300EmitVec4(ctx, rvb, data, stride, count);
@@ -217,57 +203,35 @@ static void r300EmitVec(GLcontext * ctx,
break;
default:
assert(0);
- _mesa_exit(-1);
break;
}
-
-}
-
-#define R300_VIR0_AOS_SIZE_SHIFT 0
-#define R300_VIR0_AOS_INPUT_SHIFT 8
-#define R300_VIR0_AOS_STOP_SHIFT 13
-#define R300_VIR0_AOS_TYPE_SHIFT 14
-#define R300_VIR0_HIGH_SHIFT 16
-
-// Pack 4 elemets in a 16 bit (aos_size first 8, input next 5, 1 stop bit(Whild gues), aos_type last 2);
-static inline GLuint t_vir_pack(GLvector4f ** dt, int *inputs, int i)
-{
- GLuint dw;
- dw = (dt[i]->size - 1) << R300_VIR0_AOS_SIZE_SHIFT;
- dw |= inputs[i] << R300_VIR0_AOS_INPUT_SHIFT;
- //dw |= t_type(&dt[i]) << R300_VIR0_AOS_TYPE_SHIFT;
- return dw;
}
-static GLuint t_vir0(uint32_t * dst, GLvector4f ** dt, int *inputs,
- GLint * tab, GLuint nr)
+static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr,
+ int *inputs, GLint * tab, GLuint nr)
{
- GLuint i, dw, dwInternel;
+ GLuint i, dw;
+ /* type, inputs, stop bit, size */
for (i = 0; i + 1 < nr; i += 2) {
- dw = t_vir_pack(dt, inputs, tab[i]);
- dwInternel = t_vir_pack(dt, inputs, tab[i + 1]);
- dw |= dwInternel << R300_VIR0_HIGH_SHIFT;
-
+ dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[i]] << 8) | (attribptr[tab[i]]->size - 1);
+ dw |= (R300_INPUT_ROUTE_FLOAT | (inputs[tab[i + 1]] << 8) | (attribptr[tab[i + 1]]->size - 1)) << 16;
if (i + 2 == nr) {
- dw |=
- (1 <<
- (R300_VIR0_AOS_STOP_SHIFT + R300_VIR0_HIGH_SHIFT));
+ dw |= (1 << (13 + 16));
}
- dst[i >> 1] = dw; // Is the same as i/2
+ dst[i >> 1] = dw;
}
if (nr & 1) {
- dw = t_vir_pack(dt, inputs, tab[nr - 1]);
- dw |= 1 << R300_VIR0_AOS_STOP_SHIFT;
-
+ dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[nr - 1]] << 8) | (attribptr[tab[nr - 1]]->size - 1);
+ dw |= 1 << 13;
dst[nr >> 1] = dw;
}
- return (nr + 1) >> 1; // Is the same as (nr+1)/2
+ return (nr + 1) >> 1;
}
-static GLuint t_swizzle(int swizzle[4])
+static GLuint r300VAPInputRoute1Swizzle(int swizzle[4])
{
return (swizzle[0] << R300_INPUT_ROUTE_X_SHIFT) |
(swizzle[1] << R300_INPUT_ROUTE_Y_SHIFT) |
@@ -275,27 +239,32 @@ static GLuint t_swizzle(int swizzle[4])
(swizzle[3] << R300_INPUT_ROUTE_W_SHIFT);
}
-static GLuint t_vir1(uint32_t * dst, int swizzle[][4], GLuint nr)
+static GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr)
{
GLuint i;
for (i = 0; i + 1 < nr; i += 2) {
- dst[i >> 1] = t_swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE;
- dst[i >> 1] |=
- (t_swizzle(swizzle[i + 1]) | R300_INPUT_ROUTE_ENABLE)
- << 16;
+ dst[i >> 1] = r300VAPInputRoute1Swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE;
+ dst[i >> 1] |= (r300VAPInputRoute1Swizzle(swizzle[i + 1]) | R300_INPUT_ROUTE_ENABLE) << 16;
}
- if (nr & 1)
- dst[nr >> 1] =
- t_swizzle(swizzle[nr - 1]) | R300_INPUT_ROUTE_ENABLE;
+ if (nr & 1) {
+ dst[nr >> 1] = r300VAPInputRoute1Swizzle(swizzle[nr - 1]) | R300_INPUT_ROUTE_ENABLE;
+ }
return (nr + 1) >> 1;
}
-static GLuint t_vic(GLcontext * ctx, GLuint InputsRead)
+static GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead)
+{
+ /* No idea what this value means. I have seen other values written to
+ * this register... */
+ return 0x5555;
+}
+
+static GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead)
{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
GLuint i, vic_1 = 0;
if (InputsRead & (1 << VERT_ATTRIB_POS))
@@ -307,25 +276,65 @@ static GLuint t_vic(GLcontext * ctx, GLuint InputsRead)
if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
vic_1 |= R300_INPUT_CNTL_COLOR;
- r300->state.texture.tc_count = 0;
+ rmesa->state.texture.tc_count = 0;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
if (InputsRead & (1 << (VERT_ATTRIB_TEX0 + i))) {
- r300->state.texture.tc_count++;
+ rmesa->state.texture.tc_count++;
vic_1 |= R300_INPUT_CNTL_TC0 << i;
}
return vic_1;
}
+static GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten)
+{
+ GLuint ret = 0;
+
+ if (OutputsWritten & (1 << VERT_RESULT_HPOS))
+ ret |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+
+ if (OutputsWritten & (1 << VERT_RESULT_COL0))
+ ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
+
+ if (OutputsWritten & (1 << VERT_RESULT_COL1))
+ ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
+
+#if 0
+ if (OutputsWritten & (1 << VERT_RESULT_BFC0))
+ ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
+
+ if (OutputsWritten & (1 << VERT_RESULT_BFC1))
+ ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;
+
+ if (OutputsWritten & (1 << VERT_RESULT_FOGC)) ;
+#endif
+
+ if (OutputsWritten & (1 << VERT_RESULT_PSIZ))
+ ret |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+
+ return ret;
+}
+
+static GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten)
+{
+ GLuint i, ret = 0;
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (OutputsWritten & (1 << (VERT_RESULT_TEX0 + i))) {
+ ret |= (4 << (3 * i));
+ }
+ }
+
+ return ret;
+}
+
/* Emit vertex data to GART memory
* Route inputs to the vertex processor
* This function should never return R300_FALLBACK_TCL when using software tcl.
*/
-
int r300EmitArrays(GLcontext * ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- r300ContextPtr r300 = rmesa;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
GLuint nr;
@@ -336,114 +345,105 @@ int r300EmitArrays(GLcontext * ctx)
int vir_inputs[VERT_ATTRIB_MAX];
GLint tab[VERT_ATTRIB_MAX];
int swizzle[VERT_ATTRIB_MAX][4];
+ struct r300_vertex_program *prog =
+ (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
if (hw_tcl_on) {
- struct r300_vertex_program *prog =
- (struct r300_vertex_program *)
- CURRENT_VERTEX_SHADER(ctx);
inputs = prog->inputs;
- InputsRead = CURRENT_VERTEX_SHADER(ctx)->key.InputsRead;
- OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
+ InputsRead = prog->key.InputsRead;
+ OutputsWritten = prog->key.OutputsWritten;
} else {
- DECLARE_RENDERINPUTS(inputs_bitset);
- inputs = r300->state.sw_tcl_inputs;
+ inputs = rmesa->state.sw_tcl_inputs;
- RENDERINPUTS_COPY(inputs_bitset,
- TNL_CONTEXT(ctx)->render_inputs_bitset);
+ DECLARE_RENDERINPUTS(render_inputs_bitset);
+ RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset);
- assert(RENDERINPUTS_TEST(inputs_bitset, _TNL_ATTRIB_POS));
- InputsRead |= 1 << VERT_ATTRIB_POS;
- OutputsWritten |= 1 << VERT_RESULT_HPOS;
+ assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS));
+ assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_NORMAL) == 0);
+ assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0));
- assert(RENDERINPUTS_TEST(inputs_bitset, _TNL_ATTRIB_NORMAL)
- == 0);
+ if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)) {
+ InputsRead |= 1 << VERT_ATTRIB_POS;
+ OutputsWritten |= 1 << VERT_RESULT_HPOS;
+ }
- assert(RENDERINPUTS_TEST(inputs_bitset, _TNL_ATTRIB_COLOR0));
- InputsRead |= 1 << VERT_ATTRIB_COLOR0;
- OutputsWritten |= 1 << VERT_RESULT_COL0;
+ if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0)) {
+ InputsRead |= 1 << VERT_ATTRIB_COLOR0;
+ OutputsWritten |= 1 << VERT_RESULT_COL0;
+ }
- if (RENDERINPUTS_TEST(inputs_bitset, _TNL_ATTRIB_COLOR1)) {
+ if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR1)) {
InputsRead |= 1 << VERT_ATTRIB_COLOR1;
OutputsWritten |= 1 << VERT_RESULT_COL1;
}
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
- if (RENDERINPUTS_TEST
- (inputs_bitset, _TNL_ATTRIB_TEX(i))) {
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_TEX(i))) {
InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
}
+ }
- for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++)
- if (InputsRead & (1 << i))
+ for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) {
+ if (InputsRead & (1 << i)) {
inputs[i] = nr++;
- else
+ } else {
inputs[i] = -1;
+ }
+ }
- if (!
- (r300->radeon.radeonScreen->
- chip_flags & RADEON_CHIPSET_TCL)) {
+ if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
/* Fixed, apply to vir0 only */
- memcpy(vir_inputs, inputs,
- VERT_ATTRIB_MAX * sizeof(int));
+ memcpy(vir_inputs, inputs, VERT_ATTRIB_MAX * sizeof(int));
inputs = vir_inputs;
-
if (InputsRead & VERT_ATTRIB_POS)
inputs[VERT_ATTRIB_POS] = 0;
-
if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
inputs[VERT_ATTRIB_COLOR0] = 2;
-
if (InputsRead & (1 << VERT_ATTRIB_COLOR1))
inputs[VERT_ATTRIB_COLOR1] = 3;
-
for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++)
if (InputsRead & (1 << i))
inputs[i] = 6 + (i - VERT_ATTRIB_TEX0);
}
- RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset,
- inputs_bitset);
+ RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset);
}
+
assert(InputsRead);
assert(OutputsWritten);
- for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++)
- if (InputsRead & (1 << i))
+ for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) {
+ if (InputsRead & (1 << i)) {
tab[nr++] = i;
+ }
+ }
- if (nr > R300_MAX_AOS_ARRAYS)
+ if (nr > R300_MAX_AOS_ARRAYS) {
return R300_FALLBACK_TCL;
+ }
for (i = 0; i < nr; i++) {
- int ci;
- int comp_size, fix, found = 0;
+ int ci, fix, found = 0;
swizzle[i][0] = SWIZZLE_ZERO;
swizzle[i][1] = SWIZZLE_ZERO;
swizzle[i][2] = SWIZZLE_ZERO;
swizzle[i][3] = SWIZZLE_ONE;
- for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++)
+ for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++) {
swizzle[i][ci] = ci;
+ }
- if (r300IsGartMemory(rmesa, vb->AttribPtr[tab[i]]->data,
- /*(count-1)*stride */ 4)) {
- if (vb->AttribPtr[tab[i]]->stride % 4)
+ if (r300IsGartMemory(rmesa, vb->AttribPtr[tab[i]]->data, 4)) {
+ if (vb->AttribPtr[tab[i]]->stride % 4) {
return R300_FALLBACK_TCL;
-
- rmesa->state.aos[i].address =
- (void *)(vb->AttribPtr[tab[i]]->data);
+ }
+ rmesa->state.aos[i].address = (void *)(vb->AttribPtr[tab[i]]->data);
rmesa->state.aos[i].start = 0;
- rmesa->state.aos[i].aos_offset =
- r300GartOffsetFromVirtual(rmesa,
- vb->
- AttribPtr[tab[i]]->data);
- rmesa->state.aos[i].aos_stride =
- vb->AttribPtr[tab[i]]->stride / 4;
-
- rmesa->state.aos[i].aos_size =
- vb->AttribPtr[tab[i]]->size;
+ rmesa->state.aos[i].aos_offset = r300GartOffsetFromVirtual(rmesa, vb->AttribPtr[tab[i]]->data);
+ rmesa->state.aos[i].aos_stride = vb->AttribPtr[tab[i]]->stride / 4;
+ rmesa->state.aos[i].aos_size = vb->AttribPtr[tab[i]]->size;
} else {
r300EmitVec(ctx, &rmesa->state.aos[i],
vb->AttribPtr[tab[i]]->data,
@@ -453,13 +453,10 @@ int r300EmitArrays(GLcontext * ctx)
rmesa->state.aos[i].aos_size = vb->AttribPtr[tab[i]]->size;
- comp_size = _mesa_sizeof_type(GL_FLOAT);
-
for (fix = 0; fix <= 4 - vb->AttribPtr[tab[i]]->size; fix++) {
- if ((rmesa->state.aos[i].aos_offset -
- comp_size * fix) % 4)
+ if ((rmesa->state.aos[i].aos_offset - _mesa_sizeof_type(GL_FLOAT) * fix) % 4) {
continue;
-
+ }
found = 1;
break;
}
@@ -468,11 +465,10 @@ int r300EmitArrays(GLcontext * ctx)
if (fix > 0) {
WARN_ONCE("Feeling lucky?\n");
}
-
- rmesa->state.aos[i].aos_offset -= comp_size * fix;
-
- for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++)
+ rmesa->state.aos[i].aos_offset -= _mesa_sizeof_type(GL_FLOAT) * fix;
+ for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++) {
swizzle[i][ci] += fix;
+ }
} else {
WARN_ONCE
("Cannot handle offset %x with stride %d, comp %d\n",
@@ -483,55 +479,27 @@ int r300EmitArrays(GLcontext * ctx)
}
}
- /* setup INPUT_ROUTE */
- R300_STATECHANGE(r300, vir[0]);
- ((drm_r300_cmd_header_t *) r300->hw.vir[0].cmd)->packet0.count =
- t_vir0(&r300->hw.vir[0].cmd[R300_VIR_CNTL_0], vb->AttribPtr,
- inputs, tab, nr);
-
- R300_STATECHANGE(r300, vir[1]);
- ((drm_r300_cmd_header_t *) r300->hw.vir[1].cmd)->packet0.count =
- t_vir1(&r300->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, nr);
-
- /* Set up input_cntl */
- /* I don't think this is needed for vertex buffers, but it doesn't hurt anything */
- R300_STATECHANGE(r300, vic);
- r300->hw.vic.cmd[R300_VIC_CNTL_0] = 0x5555; /* Hard coded value, no idea what it means */
- r300->hw.vic.cmd[R300_VIC_CNTL_1] = t_vic(ctx, InputsRead);
-
- /* Stage 3: VAP output */
-
- R300_STATECHANGE(r300, vof);
-
- r300->hw.vof.cmd[R300_VOF_CNTL_0] = 0;
- r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0;
-
- if (OutputsWritten & (1 << VERT_RESULT_HPOS))
- r300->hw.vof.cmd[R300_VOF_CNTL_0] |=
- R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
-
- if (OutputsWritten & (1 << VERT_RESULT_COL0))
- r300->hw.vof.cmd[R300_VOF_CNTL_0] |=
- R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
-
- if (OutputsWritten & (1 << VERT_RESULT_COL1))
- r300->hw.vof.cmd[R300_VOF_CNTL_0] |=
- R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
-
- /*if(OutputsWritten & (1 << VERT_RESULT_BFC0))
- r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
-
- if(OutputsWritten & (1 << VERT_RESULT_BFC1))
- r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT; */
- //if(OutputsWritten & (1 << VERT_RESULT_FOGC))
-
- if (OutputsWritten & (1 << VERT_RESULT_PSIZ))
- r300->hw.vof.cmd[R300_VOF_CNTL_0] |=
- R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
-
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
- if (OutputsWritten & (1 << (VERT_RESULT_TEX0 + i)))
- r300->hw.vof.cmd[R300_VOF_CNTL_1] |= (4 << (3 * i));
+ /* Setup INPUT_ROUTE. */
+ R300_STATECHANGE(rmesa, vir[0]);
+ ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count =
+ r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0],
+ vb->AttribPtr, inputs, tab, nr);
+ R300_STATECHANGE(rmesa, vir[1]);
+ ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count =
+ r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle,
+ nr);
+
+ /* Setup INPUT_CNTL. */
+ R300_STATECHANGE(rmesa, vic);
+ rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
+ rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
+
+ /* Setup OUTPUT_VTX_FMT. */
+ R300_STATECHANGE(rmesa, vof);
+ rmesa->hw.vof.cmd[R300_VOF_CNTL_0] =
+ r300VAPOutputCntl0(ctx, OutputsWritten);
+ rmesa->hw.vof.cmd[R300_VOF_CNTL_1] =
+ r300VAPOutputCntl1(ctx, OutputsWritten);
rmesa->state.aos_count = nr;
diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h
index 4f841a54139..2f79ee3a23a 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.h
+++ b/src/mesa/drivers/dri/r300/r300_emit.h
@@ -44,20 +44,11 @@
#include "r300_cmdbuf.h"
#include "radeon_reg.h"
-/*
- * CP type-3 packets
- */
-#define RADEON_CP_PACKET3_UNK1B 0xC0001B00
-#define RADEON_CP_PACKET3_INDX_BUFFER 0xC0003300
-#define RADEON_CP_PACKET3_3D_DRAW_VBUF_2 0xC0003400
-#define RADEON_CP_PACKET3_3D_DRAW_IMMD_2 0xC0003500
-#define RADEON_CP_PACKET3_3D_DRAW_INDX_2 0xC0003600
-#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00
-#define RADEON_CP_PACKET3_3D_CLEAR_ZMASK 0xC0003202
-#define RADEON_CP_PACKET3_3D_CLEAR_CMASK 0xC0003802
-#define RADEON_CP_PACKET3_3D_CLEAR_HIZ 0xC0003702
-
+/* TODO: move these defines (and the ones from DRM) into r300_reg.h and sync up
+ * with DRM */
#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2))
+#define CP_PACKET3( pkt, n ) \
+ (RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
static inline uint32_t cmdpacket0(int reg, int count)
{
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index 416ea7f231d..15c2cf3ad7b 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -224,25 +224,23 @@ static void r300EmitClearState(GLcontext * ctx)
e32(R300_INPUT_CNTL_0_COLOR);
e32(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0);
- if (!has_tcl) {
- R300_STATECHANGE(r300, vte);
- /* comes from fglrx startup of clear */
- reg_start(R300_SE_VTE_CNTL, 1);
- e32(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
- R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
- R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
- R300_VPORT_Z_OFFSET_ENA);
- e32(0x8);
-
- reg_start(0x21dc, 0);
- e32(0xaaaaaaaa);
- }
+ R300_STATECHANGE(r300, vte);
+ /* comes from fglrx startup of clear */
+ reg_start(R300_SE_VTE_CNTL, 1);
+ e32(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
+ R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
+ R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
+ R300_VPORT_Z_OFFSET_ENA);
+ e32(0x8);
+
+ reg_start(0x21dc, 0);
+ e32(0xaaaaaaaa);
R300_STATECHANGE(r300, vof);
reg_start(R300_VAP_OUTPUT_VTX_FMT_0, 1);
e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT);
- e32(0x0); /* no textures */
+ e32(0x0); /* no textures */
R300_STATECHANGE(r300, txe);
reg_start(R300_TX_ENABLE, 0);
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index e64f5095bc5..3ce09c16d3f 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -116,6 +116,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094
+ /* each of the following is 3 bits wide, specifies number
+ of components */
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
@@ -299,6 +301,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_221C_NORMAL 0x00000000
# define R300_221C_CLEAR 0x0001C000
+/* These seem to be per-pixel and per-vertex X and Y clipping planes. The first
+ * plane is per-pixel and the second plane is per-vertex.
+ *
+ * This was determined by experimentation alone but I believe it is correct.
+ *
+ * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest.
+ */
+#define R300_VAP_CLIP_X_0 0x2220
+#define R300_VAP_CLIP_X_1 0x2224
+#define R300_VAP_CLIP_Y_0 0x2228
+#define R300_VAP_CLIP_Y_1 0x2230
+
/* gap */
/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between
@@ -628,11 +642,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* Set INTERP_USED on all interpolators that produce data used by
* the fragment program. INTERP_USED looks like a swizzling mask,
* but I haven't seen it used that way.
+ *
+ * Note: The _UNKNOWN constants are always set in their respective
+ * register. I don't know if this is necessary.
*/
#define R300_RS_INTERP_0 0x4310
#define R300_RS_INTERP_1 0x4314
+# define R300_RS_INTERP_1_UNKNOWN 0x40
#define R300_RS_INTERP_2 0x4318
+# define R300_RS_INTERP_2_UNKNOWN 0x80
#define R300_RS_INTERP_3 0x431C
+# define R300_RS_INTERP_3_UNKNOWN 0xC0
#define R300_RS_INTERP_4 0x4320
#define R300_RS_INTERP_5 0x4324
#define R300_RS_INTERP_6 0x4328
@@ -961,7 +981,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* first node is stored in NODE_2, the second node is stored in NODE_3.
*
* Offsets are relative to the master offset from PFS_CNTL_2.
- * LAST_NODE is set for the last node, and only for the last node.
*/
#define R300_PFS_NODE_0 0x4610
#define R300_PFS_NODE_1 0x4614
@@ -975,7 +994,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12)
# define R300_PFS_NODE_TEX_END_SHIFT 17
# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
-/*# define R300_PFS_NODE_LAST_NODE (1 << 22) */
# define R300_PFS_NODE_OUTPUT_COLOR (1 << 22)
# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23)
@@ -1585,6 +1603,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_EB_UNK1_SHIFT 24
# define R300_EB_UNK1 (0x80<<24)
# define R300_EB_UNK2 0x0810
+#define R300_PACKET3_3D_DRAW_VBUF_2 0x00003400
#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600
/* END: Packet 3 commands */
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 143fe9fd35d..83999307b56 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -171,16 +171,13 @@ static int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim)
return num_verts - verts_off;
}
-static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts,
- int elt_size)
+static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_dma_region *rvb = &rmesa->state.elt_dma;
void *out;
- assert(elt_size == 2 || elt_size == 4);
-
- if (r300IsGartMemory(rmesa, elts, n_elts * elt_size)) {
+ if (r300IsGartMemory(rmesa, elts, n_elts * 4)) {
rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
rvb->start = ((char *)elts) - rvb->address;
rvb->aos_offset =
@@ -192,66 +189,27 @@ static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts,
_mesa_exit(-1);
}
- r300AllocDmaRegion(rmesa, rvb, n_elts * elt_size, elt_size);
+ r300AllocDmaRegion(rmesa, rvb, n_elts * 4, 4);
rvb->aos_offset = GET_START(rvb);
out = rvb->address + rvb->start;
- memcpy(out, elts, n_elts * elt_size);
+ memcpy(out, elts, n_elts * 4);
}
static void r300FireEB(r300ContextPtr rmesa, unsigned long addr,
- int vertex_count, int type, int elt_size)
+ int vertex_count, int type)
{
int cmd_reserved = 0;
int cmd_written = 0;
drm_radeon_cmd_header_t *cmd = NULL;
- unsigned long t_addr;
- unsigned long magic_1, magic_2;
-
- assert(elt_size == 2 || elt_size == 4);
-
- if (addr & (elt_size - 1)) {
- WARN_ONCE("Badly aligned buffer\n");
- return;
- }
- magic_1 = (addr % 32) / 4;
- t_addr = addr & ~0x1d;
- magic_2 = (vertex_count + 1 + (t_addr & 0x2)) / 2 + magic_1;
+ start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0), 0);
+ e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count << 16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
- start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
- if (elt_size == 4) {
- e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES |
- (vertex_count << 16) | type |
- R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
- } else {
- e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES |
- (vertex_count << 16) | type);
- }
-
- start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
-#ifdef OPTIMIZE_ELTS
- if (elt_size == 4) {
- e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
- e32(addr);
- } else {
- e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2);
- e32(t_addr);
- }
-#else
+ start_packet3(CP_PACKET3(R300_PACKET3_INDX_BUFFER, 2), 2);
e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
e32(addr);
-#endif
-
- if (elt_size == 4) {
- e32(vertex_count);
- } else {
-#ifdef OPTIMIZE_ELTS
- e32(magic_2);
-#else
- e32((vertex_count + 1) / 2);
-#endif
- }
+ e32(vertex_count);
}
static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
@@ -266,26 +224,23 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr,
offset);
- start_packet3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, sz - 1);
+ start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1), sz - 1);
e32(nr);
+
for (i = 0; i + 1 < nr; i += 2) {
- e32((rmesa->state.aos[i].aos_size << 0)
- | (rmesa->state.aos[i].aos_stride << 8)
- | (rmesa->state.aos[i + 1].aos_size << 16)
- | (rmesa->state.aos[i + 1].aos_stride << 24)
- );
- e32(rmesa->state.aos[i].aos_offset +
- offset * 4 * rmesa->state.aos[i].aos_stride);
- e32(rmesa->state.aos[i + 1].aos_offset +
- offset * 4 * rmesa->state.aos[i + 1].aos_stride);
+ e32((rmesa->state.aos[i].aos_size << 0) |
+ (rmesa->state.aos[i].aos_stride << 8) |
+ (rmesa->state.aos[i + 1].aos_size << 16) |
+ (rmesa->state.aos[i + 1].aos_stride << 24));
+
+ e32(rmesa->state.aos[i].aos_offset + offset * 4 * rmesa->state.aos[i].aos_stride);
+ e32(rmesa->state.aos[i + 1].aos_offset + offset * 4 * rmesa->state.aos[i + 1].aos_stride);
}
if (nr & 1) {
- e32((rmesa->state.aos[nr - 1].aos_size << 0)
- | (rmesa->state.aos[nr - 1].aos_stride << 8)
- );
- e32(rmesa->state.aos[nr - 1].aos_offset +
- offset * 4 * rmesa->state.aos[nr - 1].aos_stride);
+ e32((rmesa->state.aos[nr - 1].aos_size << 0) |
+ (rmesa->state.aos[nr - 1].aos_stride << 8));
+ e32(rmesa->state.aos[nr - 1].aos_offset + offset * 4 * rmesa->state.aos[nr - 1].aos_stride);
}
}
@@ -295,9 +250,8 @@ static void r300FireAOS(r300ContextPtr rmesa, int vertex_count, int type)
int cmd_written = 0;
drm_radeon_cmd_header_t *cmd = NULL;
- start_packet3(RADEON_CP_PACKET3_3D_DRAW_VBUF_2, 0);
- e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16)
- | type);
+ start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0);
+ e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type);
}
static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx,
@@ -320,9 +274,8 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx,
WARN_ONCE("Too many elts\n");
return;
}
- r300EmitElts(ctx, vb->Elts, num_verts, 4);
- r300FireEB(rmesa, rmesa->state.elt_dma.aos_offset,
- num_verts, type, 4);
+ r300EmitElts(ctx, vb->Elts, num_verts);
+ r300FireEB(rmesa, rmesa->state.elt_dma.aos_offset, num_verts, type);
} else {
r300EmitAOS(rmesa, rmesa->state.aos_count, start);
r300FireAOS(rmesa, num_verts, type);
@@ -343,6 +296,8 @@ static GLboolean r300RunRender(GLcontext * ctx,
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
+ if (hw_tcl_on == GL_FALSE)
+ vb->AttribPtr[VERT_ATTRIB_POS] = vb->ClipPtr;
r300UpdateShaders(rmesa);
if (r300EmitArrays(ctx))
return GL_TRUE;
@@ -416,8 +371,6 @@ static int r300Fallback(GLcontext * ctx)
FALLBACK_IF(ctx->Point.PointSprite);
if (!r300->disable_lowimpact_fallback) {
- FALLBACK_IF(ctx->Polygon.OffsetPoint);
- FALLBACK_IF(ctx->Polygon.OffsetLine);
FALLBACK_IF(ctx->Polygon.StippleFlag);
FALLBACK_IF(ctx->Multisample.Enabled);
FALLBACK_IF(ctx->Line.StippleFlag);
diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c
index 59fe17ba10e..5f5ac7c4c71 100644
--- a/src/mesa/drivers/dri/r300/r300_shader.c
+++ b/src/mesa/drivers/dri/r300/r300_shader.c
@@ -54,6 +54,7 @@ r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
fp->translated = GL_FALSE;
break;
}
+
/* need this for tcl fallbacks */
_tnl_program_string(ctx, target, prog);
}
@@ -61,7 +62,7 @@ r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
static GLboolean
r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
{
- return 1;
+ return GL_TRUE;
}
void r300InitShaderFuncs(struct dd_function_table *functions)
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index b235baaf10f..bdd6855802b 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -715,8 +715,8 @@ static void r300LineWidth(GLcontext * ctx, GLfloat widthf)
widthf = ctx->Line._Width;
R300_STATECHANGE(r300, lcntl);
- r300->hw.lcntl.cmd[1] = (int)(widthf * 6.0);
- r300->hw.lcntl.cmd[1] |= R300_LINE_CNT_VE;
+ r300->hw.lcntl.cmd[1] =
+ R300_LINE_CNT_HO | R300_LINE_CNT_VE | (int)(widthf * 6.0);
}
static void r300PolygonMode(GLcontext * ctx, GLenum face, GLenum mode)
@@ -1354,6 +1354,17 @@ union r300_outputs_written {
static void r300SetupRSUnit(GLcontext * ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
+ /* I'm still unsure if these are needed */
+ GLuint interp_magic[8] = {
+ 0x00,
+ R300_RS_INTERP_1_UNKNOWN,
+ R300_RS_INTERP_2_UNKNOWN,
+ R300_RS_INTERP_3_UNKNOWN,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+ };
union r300_outputs_written OutputsWritten;
GLuint InputsRead;
int fp_reg, high_rr;
@@ -1361,11 +1372,9 @@ static void r300SetupRSUnit(GLcontext * ctx)
int i;
if (hw_tcl_on)
- OutputsWritten.vp_outputs =
- CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
+ OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
else
- RENDERINPUTS_COPY(OutputsWritten.index_bitset,
- r300->state.render_inputs_bitset);
+ RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset);
if (ctx->FragmentProgram._Current)
InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
@@ -1397,9 +1406,8 @@ static void r300SetupRSUnit(GLcontext * ctx)
}
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0
- | R300_RS_INTERP_USED
- | (in_texcoords << R300_RS_INTERP_SRC_SHIFT);
+ r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0 | R300_RS_INTERP_USED | (in_texcoords << R300_RS_INTERP_SRC_SHIFT)
+ | interp_magic[i];
r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] = 0;
if (InputsRead & (FRAG_BIT_TEX0 << i)) {
@@ -1408,65 +1416,45 @@ static void r300SetupRSUnit(GLcontext * ctx)
| (fp_reg << R300_RS_ROUTE_DEST_SHIFT);
high_rr = fp_reg;
- if (!R300_OUTPUTS_WRITTEN_TEST
- (OutputsWritten, VERT_RESULT_TEX0 + i,
- _TNL_ATTRIB_TEX(i))) {
- /* Passing invalid data here can lock the GPU. */
- WARN_ONCE
- ("fragprog wants coords for tex%d, vp doesn't provide them!\n",
- i);
- //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
- //_mesa_exit(-1);
+ /* Passing invalid data here can lock the GPU. */
+ if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) {
+ InputsRead &= ~(FRAG_BIT_TEX0 << i);
+ fp_reg++;
+ } else {
+ WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i);
}
- InputsRead &= ~(FRAG_BIT_TEX0 << i);
- fp_reg++;
}
/* Need to count all coords enabled at vof */
- if (R300_OUTPUTS_WRITTEN_TEST
- (OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i)))
+ if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) {
in_texcoords++;
+ }
}
if (InputsRead & FRAG_BIT_COL0) {
- if (!R300_OUTPUTS_WRITTEN_TEST
- (OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) {
- WARN_ONCE
- ("fragprog wants col0, vp doesn't provide it\n");
- goto out; /* FIXME */
- //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
- //_mesa_exit(-1);
+ if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) {
+ r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
+ InputsRead &= ~FRAG_BIT_COL0;
+ col_interp_nr++;
+ } else {
+ WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
}
-
- r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0
- | R300_RS_ROUTE_0_COLOR
- | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
- InputsRead &= ~FRAG_BIT_COL0;
- col_interp_nr++;
}
- out:
if (InputsRead & FRAG_BIT_COL1) {
- if (!R300_OUTPUTS_WRITTEN_TEST
- (OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) {
- WARN_ONCE
- ("fragprog wants col1, vp doesn't provide it\n");
- //_mesa_exit(-1);
+ if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) {
+ r300->hw.rr.cmd[R300_RR_ROUTE_1] |= R300_RS_ROUTE_1_UNKNOWN11 | R300_RS_ROUTE_1_COLOR1 | (fp_reg++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT);
+ InputsRead &= ~FRAG_BIT_COL1;
+ if (high_rr < 1)
+ high_rr = 1;
+ col_interp_nr++;
+ } else {
+ WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
}
-
- r300->hw.rr.cmd[R300_RR_ROUTE_1] |=
- R300_RS_ROUTE_1_UNKNOWN11 | R300_RS_ROUTE_1_COLOR1 |
- (fp_reg++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT);
- InputsRead &= ~FRAG_BIT_COL1;
- if (high_rr < 1)
- high_rr = 1;
- col_interp_nr++;
}
/* Need at least one. This might still lock as the values are undefined... */
if (in_texcoords == 0 && col_interp_nr == 0) {
- r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0
- | R300_RS_ROUTE_0_COLOR
- | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
+ r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
col_interp_nr++;
}
@@ -1475,17 +1463,13 @@ static void r300SetupRSUnit(GLcontext * ctx)
| R300_RS_CNTL_0_UNKNOWN_18;
assert(high_rr >= 0);
- r300->hw.rr.cmd[R300_RR_CMD_0] =
- cmdpacket0(R300_RS_ROUTE_0, high_rr + 1);
+ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_ROUTE_0, high_rr + 1);
r300->hw.rc.cmd[2] = 0xC0 | high_rr;
if (InputsRead)
- WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n",
- InputsRead);
+ WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead);
}
-#define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
-
#define bump_vpu_count(ptr, new_count) do{\
drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
int _nc=(new_count)/4; \
@@ -1785,8 +1769,6 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
case GL_POLYGON_OFFSET_POINT:
case GL_POLYGON_OFFSET_LINE:
- break;
-
case GL_POLYGON_OFFSET_FILL:
R300_STATECHANGE(r300, occlusion_cntl);
if (state) {
@@ -1859,10 +1841,12 @@ static void r300ResetHwState(r300ContextPtr r300)
r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
r300->hw.unk2134.cmd[2] = 0x00000000;
- if (_mesa_little_endian())
- r300->hw.vap_cntl_status.cmd[1] = R300_VC_NO_SWAP;
- else
- r300->hw.vap_cntl_status.cmd[1] = R300_VC_32BIT_SWAP;
+
+#ifdef MESA_LITTLE_ENDIAN
+ r300->hw.vap_cntl_status.cmd[1] = R300_VC_NO_SWAP;
+#else
+ r300->hw.vap_cntl_status.cmd[1] = R300_VC_32BIT_SWAP;
+#endif
/* disable VAP/TCL on non-TCL capable chips */
if (!has_tcl)
@@ -1872,10 +1856,10 @@ static void r300ResetHwState(r300ContextPtr r300)
r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
- r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
- r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
- r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
- r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
+ r300->hw.vap_clip.cmd[1] = r300PackFloat32(1.0); /* X */
+ r300->hw.vap_clip.cmd[2] = r300PackFloat32(1.0); /* X */
+ r300->hw.vap_clip.cmd[3] = r300PackFloat32(1.0); /* Y */
+ r300->hw.vap_clip.cmd[4] = r300PackFloat32(1.0); /* Y */
/* XXX: Other families? */
switch (r300->radeon.radeonScreen->chip_family) {
@@ -1930,13 +1914,13 @@ static void r300ResetHwState(r300ContextPtr r300)
r300->hw.unk4214.cmd[1] = 0x00050005;
- r300PointSize(ctx, 0.0);
+ r300PointSize(ctx, 1.0);
r300->hw.unk4230.cmd[1] = 0x18000006;
r300->hw.unk4230.cmd[2] = 0x00020006;
r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
- r300LineWidth(ctx, 0.0);
+ r300LineWidth(ctx, 1.0);
r300->hw.unk4260.cmd[1] = 0;
r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
@@ -2152,7 +2136,7 @@ static void r300SetupPixelShader(r300ContextPtr rmesa)
tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT)
| (fp->node[i].
tex_end << R300_PFS_NODE_TEX_END_SHIFT)
- | fp->node[i].flags; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
+ | fp->node[i].flags;
} else {
rmesa->hw.fp.cmd[R300_FP_NODE0 + (3 - i)] = 0;
}
diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c
index 2a21c611629..1805cecd0af 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.c
+++ b/src/mesa/drivers/dri/r300/r300_tex.c
@@ -294,27 +294,20 @@ static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat,
const GLubyte littleEndian = *((const GLubyte *)&ui);
if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE
- && !littleEndian) || (srcFormat == GL_ABGR_EXT
- && srcType == GL_UNSIGNED_INT_8_8_8_8_REV)
- || (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE
- && littleEndian)) {
+ (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
return &_mesa_texformat_rgba8888;
- } else
- if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV)
- || (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE
- && littleEndian) || (srcFormat == GL_ABGR_EXT
- && srcType == GL_UNSIGNED_INT_8_8_8_8)
- || (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE
- && !littleEndian)) {
+ } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
+ (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
return &_mesa_texformat_rgba8888_rev;
- } else if (srcFormat == GL_BGRA &&
- ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
- srcType == GL_UNSIGNED_INT_8_8_8_8)) {
+ } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8)) {
return &_mesa_texformat_argb8888_rev;
- } else if (srcFormat == GL_BGRA &&
- ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
- srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
+ } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
return &_mesa_texformat_argb8888;
} else
return _dri_texformat_argb8888;
@@ -563,34 +556,31 @@ r300ValidateClientStorage(GLcontext * ctx, GLenum target,
return 0;
}
- {
- GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
- format, type);
+ GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
+ format, type);
- if (RADEON_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: srcRowStride %d/%x\n",
- __FUNCTION__, srcRowStride, srcRowStride);
+ if (RADEON_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s: srcRowStride %d/%x\n",
+ __FUNCTION__, srcRowStride, srcRowStride);
- /* Could check this later in upload, pitch restrictions could be
- * relaxed, but would need to store the image pitch somewhere,
- * as packing details might change before image is uploaded:
- */
- if (!r300IsGartMemory(rmesa, pixels, srcHeight * srcRowStride)
- || (srcRowStride & 63))
- return 0;
+ /* Could check this later in upload, pitch restrictions could be
+ * relaxed, but would need to store the image pitch somewhere,
+ * as packing details might change before image is uploaded:
+ */
+ if (!r300IsGartMemory(rmesa, pixels, srcHeight * srcRowStride)
+ || (srcRowStride & 63))
+ return 0;
- /* Have validated that _mesa_transfer_teximage would be a straight
- * memcpy at this point. NOTE: future calls to TexSubImage will
- * overwrite the client data. This is explicitly mentioned in the
- * extension spec.
- */
- texImage->Data = (void *)pixels;
- texImage->IsClientData = GL_TRUE;
- texImage->RowStride =
- srcRowStride / texImage->TexFormat->TexelBytes;
+ /* Have validated that _mesa_transfer_teximage would be a straight
+ * memcpy at this point. NOTE: future calls to TexSubImage will
+ * overwrite the client data. This is explicitly mentioned in the
+ * extension spec.
+ */
+ texImage->Data = (void *)pixels;
+ texImage->IsClientData = GL_TRUE;
+ texImage->RowStride = srcRowStride / texImage->TexFormat->TexelBytes;
- return 1;
- }
+ return 1;
}
static void r300TexImage1D(GLcontext * ctx, GLenum target, GLint level,
diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c
index e2e8355d275..38f0da8b7c0 100644
--- a/src/mesa/drivers/dri/r300/r300_texmem.c
+++ b/src/mesa/drivers/dri/r300/r300_texmem.c
@@ -63,29 +63,16 @@ SOFTWARE.
*/
void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t)
{
+ int i;
+
if (RADEON_DEBUG & DEBUG_TEXTURE) {
fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__,
(void *)t, (void *)t->base.tObj);
}
- if (rmesa != NULL) {
- unsigned i;
-
- for (i = 0; i < rmesa->radeon.glCtx->Const.MaxTextureUnits; i++) {
- if (t == rmesa->state.texture.unit[i].texobj) {
- rmesa->state.texture.unit[i].texobj = NULL;
- /* This code below is meant to shorten state
- pushed to the hardware by not programming
- unneeded units.
-
- This does not appear to be worthwhile on R300 */
-#if 0
- remove_from_list(&rmesa->hw.tex[i]);
- make_empty_list(&rmesa->hw.tex[i]);
- remove_from_list(&rmesa->hw.cube[i]);
- make_empty_list(&rmesa->hw.cube[i]);
-#endif
- }
+ for (i = 0; i < rmesa->radeon.glCtx->Const.MaxTextureUnits; i++) {
+ if (rmesa->state.texture.unit[i].texobj == t) {
+ rmesa->state.texture.unit[i].texobj = NULL;
}
}
}
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index eeaba584df8..1d2909fd214 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -480,11 +480,11 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
*/
rmesa->state.texture.unit[unit].texobj->base.bound &=
- ~(1UL << unit);
+ ~(1 << unit);
}
rmesa->state.texture.unit[unit].texobj = t;
- t->base.bound |= (1UL << unit);
+ t->base.bound |= (1 << unit);
t->dirty_state |= 1 << unit;
driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */
}
@@ -501,7 +501,6 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
struct gl_texture_object *tObj =
_mesa_lookup_texture(rmesa->radeon.glCtx, texname);
r300TexObjPtr t;
- int idx;
if (!tObj)
return;
@@ -518,24 +517,24 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
switch (depth) {
case 32:
- idx = 2;
+ t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
+ t->filter |= tx_table[2].filter;
t->pitch_reg /= 4;
break;
case 24:
default:
- idx = 4;
+ t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
+ t->filter |= tx_table[4].filter;
t->pitch_reg /= 4;
break;
case 16:
- idx = 5;
+ t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
+ t->filter |= tx_table[5].filter;
t->pitch_reg /= 2;
break;
}
t->pitch_reg--;
-
- t->format = tx_table[idx].format;
- t->filter |= tx_table[idx].filter;
}
static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c
index 5f11c90c13c..309a0008d76 100644
--- a/src/mesa/drivers/x11/glxapi.c
+++ b/src/mesa/drivers/x11/glxapi.c
@@ -141,7 +141,7 @@ static void
SetCurrentContext(GLXContext c)
{
#if defined(GLX_USE_TLS)
- CurrentContext = context;
+ CurrentContext = c;
#elif defined(THREADS)
_glthread_SetTSD(&ContextTSD, c);
#else
@@ -1169,7 +1169,7 @@ _glxapi_get_extensions(void)
#ifdef GLX_SGIX_pbuffer
"GLX_SGIX_pbuffer",
#endif
-#ifdef GLX_EXT_texture_from_pixmap,
+#ifdef GLX_EXT_texture_from_pixmap
"GLX_EXT_texture_from_pixmap",
#endif
NULL
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index cff64d17ade..eaa277db4ad 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -63,7 +63,6 @@
#endif
#include "glxheader.h"
-#include "GL/glxtokens.h"
#include "GL/xmesa.h"
#include "xmesaP.h"
#include "context.h"
diff --git a/src/mesa/glapi/gl_x86_asm.py b/src/mesa/glapi/gl_x86_asm.py
index 650331a0c5a..403e87261b0 100644
--- a/src/mesa/glapi/gl_x86_asm.py
+++ b/src/mesa/glapi/gl_x86_asm.py
@@ -82,12 +82,18 @@ class PrintGenericStubs(gl_XML.gl_print_base):
print ''
print '#ifdef GLX_USE_TLS'
print ''
+ print '#ifdef GLX_X86_READONLY_TEXT'
+ print '# define CTX_INSNS MOV_L(GS:(EAX), EAX)'
+ print '#else'
+ print '# define CTX_INSNS NOP /* Pad for init_glapi_relocs() */'
+ print '#endif'
+ print ''
print '# define GL_STUB(fn,off,fn_alt)\t\t\t\\'
print 'ALIGNTEXT16;\t\t\t\t\t\t\\'
print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\'
print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\'
print '\tCALL(_x86_get_dispatch) ;\t\t\t\\'
- print '\tNOP ;\t\t\t\t\t\t\\'
+ print '\tCTX_INSNS ; \\'
print '\tJMP(GL_OFFSET(off))'
print ''
print '#elif defined(PTHREADS)'
@@ -138,7 +144,10 @@ class PrintGenericStubs(gl_XML.gl_print_base):
print '\tHIDDEN(GLNAME(_x86_get_dispatch))'
print 'ALIGNTEXT16'
print 'GLNAME(_x86_get_dispatch):'
- print '\tmovl\t%gs:_glapi_tls_Dispatch@NTPOFF, %eax'
+ print '\tcall 1f'
+ print '1:\tpopl %eax'
+ print '\taddl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax'
+ print '\tmovl _glapi_tls_Dispatch@GOTNTPOFF(%eax), %eax'
print '\tret'
print ''
print '#elif defined(PTHREADS)'
@@ -158,7 +167,7 @@ class PrintGenericStubs(gl_XML.gl_print_base):
print '#endif'
print ''
- print '#if defined( GLX_USE_TLS )'
+ print '#if defined( GLX_USE_TLS ) && !defined( GLX_X86_READONLY_TEXT )'
print '\t\t.section\twtext, "awx", @progbits'
print '#endif /* defined( GLX_USE_TLS ) */'
diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c
index 5815dbff842..47c57822732 100644
--- a/src/mesa/glapi/glapi.c
+++ b/src/mesa/glapi/glapi.c
@@ -1028,22 +1028,24 @@ _glapi_check_table(const struct _glapi_table *table)
#if defined(PTHREADS) || defined(GLX_USE_TLS)
/**
* Perform platform-specific GL API entry-point fixups.
- *
- *
*/
static void
init_glapi_relocs( void )
{
-#if defined( USE_X86_ASM ) && defined( GLX_USE_TLS )
- extern void * _x86_get_dispatch(void);
- const GLubyte * const get_disp = (const GLubyte *) _x86_get_dispatch;
+#if defined(USE_X86_ASM) && defined(GLX_USE_TLS) && !defined(GLX_X86_READONLY_TEXT)
+ extern unsigned long _x86_get_dispatch(void);
+ char run_time_patch[] = {
+ 0x65, 0xa1, 0, 0, 0, 0 /* movl %gs:0,%eax */
+ };
+ GLuint *offset = (GLuint *) &run_time_patch[2]; /* 32-bits for x86/32 */
+ const GLubyte * const get_disp = (const GLubyte *) run_time_patch;
GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start;
-
+ *offset = _x86_get_dispatch();
while ( curr_func != (GLubyte *) gl_dispatch_functions_end ) {
- (void) memcpy( curr_func, get_disp, 6 );
+ (void) memcpy( curr_func, get_disp, sizeof(run_time_patch));
curr_func += DISPATCH_FUNCTION_SIZE;
}
-#endif /* defined( USE_X86_ASM ) && defined( GLX_USE_TLS ) */
-}
#endif
+}
+#endif /* defined(PTHREADS) || defined(GLX_USE_TLS) */
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 11bd173e35c..c280f89e1d1 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul 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"),
@@ -184,17 +184,19 @@ _mesa_Clear( GLbitfield mask )
/**
* Return bitmask of BUFFER_BIT_* flags indicating which color buffers are
- * available to the rendering context.
- * This depends on the framebuffer we're writing to. For window system
- * framebuffers we look at the framebuffer's visual. But for user-
- * create framebuffers we look at the number of supported color attachments.
+ * available to the rendering context (for drawing or reading).
+ * This depends on the type of framebuffer. For window system framebuffers
+ * we look at the framebuffer's visual. But for user-create framebuffers we
+ * look at the number of supported color attachments.
+ * \param fb the framebuffer to draw to, or read from
+ * \return bitmask of BUFFER_BIT_* flags
*/
static GLbitfield
-supported_buffer_bitmask(const GLcontext *ctx, GLuint framebufferID)
+supported_buffer_bitmask(const GLcontext *ctx, const struct gl_framebuffer *fb)
{
GLbitfield mask = 0x0;
- if (framebufferID > 0) {
+ if (fb->Name > 0) {
/* A user-created renderbuffer */
GLuint i;
ASSERT(ctx->Extensions.EXT_framebuffer_object);
@@ -203,20 +205,20 @@ supported_buffer_bitmask(const GLcontext *ctx, GLuint framebufferID)
}
}
else {
- /* A window system renderbuffer */
+ /* A window system framebuffer */
GLint i;
mask = BUFFER_BIT_FRONT_LEFT; /* always have this */
- if (ctx->Visual.stereoMode) {
+ if (fb->Visual.stereoMode) {
mask |= BUFFER_BIT_FRONT_RIGHT;
- if (ctx->Visual.doubleBufferMode) {
+ if (fb->Visual.doubleBufferMode) {
mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
}
}
- else if (ctx->Visual.doubleBufferMode) {
+ else if (fb->Visual.doubleBufferMode) {
mask |= BUFFER_BIT_BACK_LEFT;
}
- for (i = 0; i < ctx->Visual.numAuxBuffers; i++) {
+ for (i = 0; i < fb->Visual.numAuxBuffers; i++) {
mask |= (BUFFER_BIT_AUX0 << i);
}
}
@@ -338,7 +340,6 @@ read_buffer_enum_to_index(GLenum buffer)
void GLAPIENTRY
_mesa_DrawBuffer(GLenum buffer)
{
- GLuint bufferID;
GLbitfield destMask;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */
@@ -347,13 +348,12 @@ _mesa_DrawBuffer(GLenum buffer)
_mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
}
- bufferID = ctx->DrawBuffer->Name;
-
if (buffer == GL_NONE) {
destMask = 0x0;
}
else {
- const GLbitfield supportedMask = supported_buffer_bitmask(ctx, bufferID);
+ const GLbitfield supportedMask
+ = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
destMask = draw_buffer_enum_to_bitmask(buffer);
if (destMask == BAD_MASK) {
/* totally bogus buffer */
@@ -386,7 +386,6 @@ void GLAPIENTRY
_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
{
GLint output;
- GLuint bufferID;
GLbitfield usedBufferMask, supportedMask;
GLbitfield destMask[MAX_DRAW_BUFFERS];
GET_CURRENT_CONTEXT(ctx);
@@ -401,9 +400,7 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
return;
}
- bufferID = ctx->DrawBuffer->Name;
-
- supportedMask = supported_buffer_bitmask(ctx, bufferID);
+ supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
usedBufferMask = 0x0;
/* complicated error checking... */
@@ -492,8 +489,8 @@ _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers,
if (!destMask) {
/* compute destMask values now */
- const GLuint bufferID = ctx->DrawBuffer->Name;
- const GLbitfield supportedMask = supported_buffer_bitmask(ctx, bufferID);
+ const GLbitfield supportedMask
+ = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
for (output = 0; output < n; output++) {
mask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
ASSERT(mask[output] != BAD_MASK);
@@ -534,17 +531,15 @@ _mesa_ReadBuffer(GLenum buffer)
struct gl_framebuffer *fb;
GLbitfield supportedMask;
GLint srcBuffer;
- GLuint bufferID;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
fb = ctx->ReadBuffer;
- bufferID = fb->Name;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
- if (bufferID > 0 && buffer == GL_NONE) {
+ if (fb->Name > 0 && buffer == GL_NONE) {
/* This is legal for user-created framebuffer objects */
srcBuffer = -1;
}
@@ -555,14 +550,14 @@ _mesa_ReadBuffer(GLenum buffer)
_mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(buffer=0x%x)", buffer);
return;
}
- supportedMask = supported_buffer_bitmask(ctx, bufferID);
+ supportedMask = supported_buffer_bitmask(ctx, fb);
if (((1 << srcBuffer) & supportedMask) == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(buffer=0x%x)", buffer);
return;
}
}
- if (bufferID == 0) {
+ if (fb->Name == 0) {
ctx->Pixel.ReadBuffer = buffer;
}
fb->ColorReadBuffer = buffer;
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 9e4d1838ade..55199245568 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -5,9 +5,9 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul 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"),
@@ -243,10 +243,7 @@
/**
- * Bits per depth buffer value.
- *
- * Any reasonable value up to 31 will work. 32 doesn't work because of integer
- * overflow problems in the rasterizer code.
+ * Bits per depth buffer value (max is 32).
*/
#ifndef DEFAULT_SOFTWARE_DEPTH_BITS
#define DEFAULT_SOFTWARE_DEPTH_BITS 16
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index ccaf6f64280..255023c0fa9 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -978,7 +978,7 @@ init_attrib_groups(GLcontext *ctx)
static int
generic_nop(void)
{
- _mesa_problem(NULL, "User called no-op dispatch function (an unsupported extension function?)");
+ _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)");
return 0;
}
@@ -1357,9 +1357,9 @@ _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
* Check if the given context can render into the given framebuffer
* by checking visual attributes.
*
- * XXX this may go away someday because we're moving toward more freedom
- * in binding contexts to drawables with different visual attributes.
- * The GL_EXT_f_b_o extension is prompting some of that.
+ * Most of these tests could go away because Mesa is now pretty flexible
+ * in terms of mixing rendering contexts with framebuffers. As long
+ * as RGB vs. CI mode agree, we're probably good.
*
* \return GL_TRUE if compatible, GL_FALSE otherwise.
*/
@@ -1393,8 +1393,11 @@ check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
return GL_FALSE;
if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
return GL_FALSE;
+#if 0
+ /* disabled (see bug 11161) */
if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
return GL_FALSE;
+#endif
if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
return GL_FALSE;
diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c
index f5511ce2fbf..91c036ef968 100644
--- a/src/mesa/main/depth.c
+++ b/src/mesa/main/depth.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.1
*
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul 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"),
@@ -28,7 +28,6 @@
#include "context.h"
#include "depth.h"
#include "enums.h"
-#include "hash.h"
#include "macros.h"
#include "mtypes.h"
@@ -153,36 +152,11 @@ _mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax )
/**
* Initialize the depth buffer attribute group in the given context.
*/
-void _mesa_init_depth( GLcontext * ctx )
+void
+_mesa_init_depth(GLcontext *ctx)
{
- /* Depth buffer group */
ctx->Depth.Test = GL_FALSE;
ctx->Depth.Clear = 1.0;
ctx->Depth.Func = GL_LESS;
ctx->Depth.Mask = GL_TRUE;
-
- /* XXX this is now per-framebuffer state */
-#if 00
- /* Z buffer stuff */
- if (ctx->Visual.depthBits == 0) {
- /* Special case. Even if we don't have a depth buffer we need
- * good values for DepthMax for Z vertex transformation purposes
- * and for per-fragment fog computation.
- */
- ctx->DepthMax = (1 << 16) - 1;
- ctx->DepthMaxF = (GLfloat) ctx->DepthMax;
- }
- else if (ctx->Visual.depthBits < 32) {
- ctx->DepthMax = (1 << ctx->Visual.depthBits) - 1;
- ctx->DepthMaxF = (GLfloat) ctx->DepthMax;
- }
- else {
- /* Special case since shift values greater than or equal to the
- * number of bits in the left hand expression's type are undefined.
- */
- ctx->DepthMax = 0xffffffff;
- ctx->DepthMaxF = (GLfloat) ctx->DepthMax;
- }
- ctx->MRD = 1.0; /* Minimum resolvable depth value, for polygon offset */
-#endif
}
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index a4a6cdae366..80dce56c0c1 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -47,6 +47,7 @@ static const struct {
{ OFF, "GL_ARB_depth_texture", F(ARB_depth_texture) },
{ OFF, "GL_ARB_draw_buffers", F(ARB_draw_buffers) },
{ OFF, "GL_ARB_fragment_program", F(ARB_fragment_program) },
+ { OFF, "GL_ARB_fragment_program_shadow", F(ARB_fragment_program_shadow) },
{ OFF, "GL_ARB_fragment_shader", F(ARB_fragment_shader) },
{ OFF, "GL_ARB_half_float_pixel", F(ARB_half_float_pixel) },
{ OFF, "GL_ARB_imaging", F(ARB_imaging) },
@@ -184,6 +185,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
ctx->Extensions.ARB_draw_buffers = GL_TRUE;
#if FEATURE_ARB_fragment_program
ctx->Extensions.ARB_fragment_program = GL_TRUE;
+ ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
#endif
#if FEATURE_ARB_fragment_shader
ctx->Extensions.ARB_fragment_shader = GL_TRUE;
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index fc712def576..05c08c19fec 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1290,15 +1290,22 @@ struct gl_texture_format
* GL_DEPTH_COMPONENT.
*/
GLenum DataType; /**< GL_FLOAT or GL_UNSIGNED_NORMALIZED_ARB */
- GLubyte RedBits; /**< Bits per texel component */
- GLubyte GreenBits; /**< These are just rough approximations for */
- GLubyte BlueBits; /**< compressed texture formats. */
+
+ /**
+ * Bits per texel component. These are just rough approximations
+ * for compressed texture formats.
+ */
+ /*@{*/
+ GLubyte RedBits;
+ GLubyte GreenBits;
+ GLubyte BlueBits;
GLubyte AlphaBits;
GLubyte LuminanceBits;
GLubyte IntensityBits;
GLubyte IndexBits;
GLubyte DepthBits;
GLubyte StencilBits; /**< GL_EXT_packed_depth_stencil */
+ /*@}*/
GLuint TexelBytes; /**< Bytes per texel, 0 if compressed format */
@@ -1419,11 +1426,15 @@ struct gl_texture_object
GLfloat ShadowAmbient; /**< GL_ARB_shadow_ambient */
GLenum CompareMode; /**< GL_ARB_shadow */
GLenum CompareFunc; /**< GL_ARB_shadow */
+ GLenum _Function; /**< Comparison function derived from
+ * \c CompareOperator, \c CompareMode, and
+ * \c CompareFunc.
+ */
GLenum DepthMode; /**< GL_ARB_depth_texture */
GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */
GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLboolean Complete; /**< Is texture object complete? */
+ GLboolean _Complete; /**< Is texture object complete? */
/** Actual texture images, indexed by [cube face] and [mipmap level] */
struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
@@ -1490,7 +1501,7 @@ struct gl_texture_unit
GLbitfield _GenBitT;
GLbitfield _GenBitR;
GLbitfield _GenBitQ;
- GLbitfield _GenFlags; /**< bitwise or of GenBit[STRQ] */
+ GLbitfield _GenFlags; /**< bitwise or of _GenBit[STRQ] */
GLfloat ObjectPlaneS[4];
GLfloat ObjectPlaneT[4];
GLfloat ObjectPlaneR[4];
@@ -1528,18 +1539,23 @@ struct gl_texture_unit
struct gl_texture_object *_Current; /**< Points to really enabled tex obj */
- struct gl_texture_object Saved1D; /**< only used by glPush/PopAttrib */
+ /** These are used for glPush/PopAttrib */
+ /*@{*/
+ struct gl_texture_object Saved1D;
struct gl_texture_object Saved2D;
struct gl_texture_object Saved3D;
struct gl_texture_object SavedCubeMap;
struct gl_texture_object SavedRect;
struct gl_texture_object Saved1DArray;
struct gl_texture_object Saved2DArray;
+ /*@}*/
- /* GL_SGI_texture_color_table */
+ /** GL_SGI_texture_color_table */
+ /*@{*/
struct gl_color_table ColorTable;
struct gl_color_table ProxyColorTable;
GLboolean ColorTableEnabled;
+ /*@}*/
};
struct texenvprog_cache_item {
@@ -1887,6 +1903,7 @@ struct gl_program
GLbitfield InputsRead; /**< Bitmask of which input regs are read */
GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */
GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
+ GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
/** Named parameters, constants, etc. from program text */
struct gl_program_parameter_list *Parameters;
@@ -2516,6 +2533,7 @@ struct gl_extensions
GLboolean ARB_depth_texture;
GLboolean ARB_draw_buffers;
GLboolean ARB_fragment_program;
+ GLboolean ARB_fragment_program_shadow;
GLboolean ARB_fragment_shader;
GLboolean ARB_half_float_pixel;
GLboolean ARB_imaging;
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 1f4c9f4722c..f315c3de74e 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2463,7 +2463,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -2566,7 +2566,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -2667,7 +2667,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -2938,7 +2938,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -3004,7 +3004,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -3398,7 +3398,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
texObj, texImage);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -3495,7 +3495,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
texObj, texImage);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -3591,7 +3591,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
texObj, texImage);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 0d2946e95a7..df64002f994 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -209,7 +209,7 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
dest->_MaxLambda = src->_MaxLambda;
dest->GenerateMipmap = src->GenerateMipmap;
dest->Palette = src->Palette;
- dest->Complete = src->Complete;
+ dest->_Complete = src->_Complete;
}
@@ -251,7 +251,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
const GLint baseLevel = t->BaseLevel;
GLint maxLog2 = 0, maxLevels = 0;
- t->Complete = GL_TRUE; /* be optimistic */
+ t->_Complete = GL_TRUE; /* be optimistic */
/* Always need the base level image */
if (!t->Image[0][baseLevel]) {
@@ -259,7 +259,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
_mesa_sprintf(s, "obj %p (%d) Image[baseLevel=%d] == NULL",
(void *) t, t->Name, baseLevel);
incomplete(t, s);
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
return;
}
@@ -268,7 +268,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
t->Image[0][baseLevel]->Height == 0 ||
t->Image[0][baseLevel]->Depth == 0) {
incomplete(t, "texture width = 0");
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
return;
}
@@ -322,7 +322,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
if (t->Image[face][baseLevel] == NULL ||
t->Image[face][baseLevel]->Width2 != w ||
t->Image[face][baseLevel]->Height2 != h) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "Non-quare cubemap image");
return;
}
@@ -339,7 +339,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
GLint maxLevel = t->_MaxLevel;
if (minLevel > maxLevel) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "minLevel > maxLevel");
return;
}
@@ -348,12 +348,12 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
for (i = minLevel; i <= maxLevel; i++) {
if (t->Image[0][i]) {
if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "Format[i] != Format[baseLevel]");
return;
}
if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "Border[i] != Border[baseLevel]");
return;
}
@@ -371,12 +371,12 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
if (i >= minLevel && i <= maxLevel) {
if (!t->Image[0][i]) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "1D Image[0][i] == NULL");
return;
}
if (t->Image[0][i]->Width2 != width ) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "1D Image[0][i] bad width");
return;
}
@@ -400,17 +400,17 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
if (i >= minLevel && i <= maxLevel) {
if (!t->Image[0][i]) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "2D Image[0][i] == NULL");
return;
}
if (t->Image[0][i]->Width2 != width) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "2D Image[0][i] bad width");
return;
}
if (t->Image[0][i]->Height2 != height) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "2D Image[0][i] bad height");
return;
}
@@ -438,26 +438,26 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
if (i >= minLevel && i <= maxLevel) {
if (!t->Image[0][i]) {
incomplete(t, "3D Image[0][i] == NULL");
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
return;
}
if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
return;
}
if (t->Image[0][i]->Width2 != width) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "3D Image[0][i] bad width");
return;
}
if (t->Image[0][i]->Height2 != height) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "3D Image[0][i] bad height");
return;
}
if (t->Image[0][i]->Depth2 != depth) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "3D Image[0][i] bad depth");
return;
}
@@ -483,20 +483,20 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
for (face = 0; face < 6; face++) {
/* check that we have images defined */
if (!t->Image[face][i]) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "CubeMap Image[n][i] == NULL");
return;
}
/* Don't support GL_DEPTH_COMPONENT for cube maps */
if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
return;
}
/* check that all six images have same size */
if (t->Image[face][i]->Width2!=width ||
t->Image[face][i]->Height2!=height) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "CubeMap Image[n][i] bad size");
return;
}
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index d15af22b7db..c9f8a0656e8 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -1141,26 +1141,29 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
/* Texture Parameters */
/**********************************************************************/
+/**
+ * Check if a coordinate wrap mode is supported for the texture target.
+ * \return GL_TRUE if legal, GL_FALSE otherwise
+ */
static GLboolean
-_mesa_validate_texture_wrap_mode(GLcontext * ctx,
- GLenum target, GLenum eparam)
+validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
{
const struct gl_extensions * const e = & ctx->Extensions;
- if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
- (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
+ if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
+ (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
/* any texture target */
return GL_TRUE;
}
else if (target != GL_TEXTURE_RECTANGLE_NV &&
- (eparam == GL_REPEAT ||
- (eparam == GL_MIRRORED_REPEAT &&
+ (wrap == GL_REPEAT ||
+ (wrap == GL_MIRRORED_REPEAT &&
e->ARB_texture_mirrored_repeat) ||
- (eparam == GL_MIRROR_CLAMP_EXT &&
+ (wrap == GL_MIRROR_CLAMP_EXT &&
(e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
- (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
+ (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
(e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
- (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
+ (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
(e->EXT_texture_mirror_clamp)))) {
/* non-rectangle texture */
return GL_TRUE;
@@ -1283,7 +1286,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
case GL_TEXTURE_WRAP_S:
if (texObj->WrapS == eparam)
return;
- if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texObj->WrapS = eparam;
}
@@ -1294,7 +1297,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
case GL_TEXTURE_WRAP_T:
if (texObj->WrapT == eparam)
return;
- if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texObj->WrapT = eparam;
}
@@ -1305,7 +1308,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
case GL_TEXTURE_WRAP_R:
if (texObj->WrapR == eparam)
return;
- if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texObj->WrapR = eparam;
}
@@ -1515,7 +1518,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
return;
}
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
if (ctx->Driver.TexParameter) {
(*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
@@ -2793,6 +2796,47 @@ update_texture_matrices( GLcontext *ctx )
/**
+ * Update texture object's _Function field. We need to do this
+ * whenever any of the texture object's shadow-related fields change
+ * or when we start/stop using a fragment program.
+ *
+ * This function could be expanded someday to update additional per-object
+ * fields that depend on assorted state changes.
+ */
+static void
+update_texture_compare_function(GLcontext *ctx,
+ struct gl_texture_object *tObj)
+{
+ /* XXX temporarily disable this test since it breaks the GLSL
+ * shadow2D(), etc. functions.
+ */
+ if (0 /*ctx->FragmentProgram._Current*/) {
+ /* Texel/coordinate comparison is ignored for programs.
+ * See GL_ARB_fragment_program/shader spec for details.
+ */
+ tObj->_Function = GL_NONE;
+ }
+ else if (tObj->CompareFlag) {
+ /* GL_SGIX_shadow */
+ if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
+ tObj->_Function = GL_LEQUAL;
+ }
+ else {
+ ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
+ tObj->_Function = GL_GEQUAL;
+ }
+ }
+ else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+ /* GL_ARB_shadow */
+ tObj->_Function = tObj->CompareFunc;
+ }
+ else {
+ tObj->_Function = GL_NONE; /* pass depth through as grayscale */
+ }
+}
+
+
+/**
* Helper function for determining which texture object (1D, 2D, cube, etc)
* should actually be used.
*/
@@ -2802,12 +2846,13 @@ texture_override(GLcontext *ctx,
struct gl_texture_object *texObj, GLuint textureBit)
{
if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) {
- if (!texObj->Complete) {
+ if (!texObj->_Complete) {
_mesa_test_texobj_completeness(ctx, texObj);
}
- if (texObj->Complete) {
+ if (texObj->_Complete) {
texUnit->_ReallyEnabled = textureBit;
texUnit->_Current = texObj;
+ update_texture_compare_function(ctx, texObj);
}
}
}
diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h
index ca29c6a23ff..60145691b8c 100644
--- a/src/mesa/main/texstate.h
+++ b/src/mesa/main/texstate.h
@@ -5,9 +5,9 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.1
*
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul 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"),
@@ -42,6 +42,7 @@ extern void
_mesa_print_texunit_state( GLcontext *ctx, GLuint unit );
+
/**
* \name Called from API
*/
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 7da3c19a89a..5d8f763741f 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -71,6 +71,7 @@ struct arb_program
/* ARB_fragment_program specifics */
GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS];
+ GLbitfield ShadowSamplers;
GLuint NumAluInstructions;
GLuint NumTexInstructions;
GLuint NumTexIndirections;
@@ -374,6 +375,8 @@ LONGSTRING static char arb_grammar_text[] =
/* GL_MESA_texture_array */
#define TEXTARGET_1D_ARRAY 0x09
#define TEXTARGET_2D_ARRAY 0x0a
+#define TEXTARGET_SHADOW1D_ARRAY 0x0b
+#define TEXTARGET_SHADOW2D_ARRAY 0x0c
/* face type */
#define FACE_FRONT 0x00
@@ -2659,6 +2662,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
GLuint texcoord;
GLubyte instClass, type, code;
GLboolean rel;
+ GLuint shadow_tex = 0;
_mesa_init_instructions(fp, 1);
@@ -2976,33 +2980,54 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
/* texTarget */
switch (*(*inst)++) {
+ case TEXTARGET_SHADOW1D:
+ shadow_tex = 1 << texcoord;
+ /* FALLTHROUGH */
case TEXTARGET_1D:
fp->TexSrcTarget = TEXTURE_1D_INDEX;
break;
+ case TEXTARGET_SHADOW2D:
+ shadow_tex = 1 << texcoord;
+ /* FALLTHROUGH */
case TEXTARGET_2D:
fp->TexSrcTarget = TEXTURE_2D_INDEX;
break;
case TEXTARGET_3D:
fp->TexSrcTarget = TEXTURE_3D_INDEX;
break;
+ case TEXTARGET_SHADOWRECT:
+ shadow_tex = 1 << texcoord;
+ /* FALLTHROUGH */
case TEXTARGET_RECT:
fp->TexSrcTarget = TEXTURE_RECT_INDEX;
break;
case TEXTARGET_CUBE:
fp->TexSrcTarget = TEXTURE_CUBE_INDEX;
break;
- case TEXTARGET_SHADOW1D:
- case TEXTARGET_SHADOW2D:
- case TEXTARGET_SHADOWRECT:
- /* TODO ARB_fragment_program_shadow code */
- break;
+ case TEXTARGET_SHADOW1D_ARRAY:
+ shadow_tex = 1 << texcoord;
+ /* FALLTHROUGH */
case TEXTARGET_1D_ARRAY:
fp->TexSrcTarget = TEXTURE_1D_ARRAY_INDEX;
break;
+ case TEXTARGET_SHADOW2D_ARRAY:
+ shadow_tex = 1 << texcoord;
+ /* FALLTHROUGH */
case TEXTARGET_2D_ARRAY:
fp->TexSrcTarget = TEXTURE_2D_ARRAY_INDEX;
break;
}
+
+ /* Don't test the first time a particular sampler is seen. Each time
+ * after that, make sure the shadow state is the same.
+ */
+ if ((_mesa_bitcount(Program->TexturesUsed[texcoord]) > 0)
+ && ((Program->ShadowSamplers & (1 << texcoord)) != shadow_tex)) {
+ program_error(ctx, Program->Position,
+ "texture image unit used for shadow sampling and non-shadow sampling");
+ return 1;
+ }
+
Program->TexturesUsed[texcoord] |= (1 << fp->TexSrcTarget);
/* Check that both "2D" and "CUBE" (for example) aren't both used */
if (_mesa_bitcount(Program->TexturesUsed[texcoord]) > 1) {
@@ -3010,6 +3035,9 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
"multiple targets used on one texture image unit");
return 1;
}
+
+
+ Program->ShadowSamplers |= shadow_tex;
break;
case OP_TEX_KIL:
@@ -3600,10 +3628,10 @@ enable_parser_extensions(GLcontext *ctx, grammar id)
if (ctx->Extensions.ARB_matrix_palette
&& !enable_ext(ctx, id, "matrix_palette"))
return GL_FALSE;
+#endif
if (ctx->Extensions.ARB_fragment_program_shadow
&& !enable_ext(ctx, id, "fragment_program_shadow"))
return GL_FALSE;
-#endif
if (ctx->Extensions.EXT_point_parameters
&& !enable_ext(ctx, id, "point_parameters"))
return GL_FALSE;
@@ -3800,6 +3828,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target,
program->HintPositionInvariant = GL_FALSE;
for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
program->TexturesUsed[a] = 0x0;
+ program->ShadowSamplers = 0x0;
program->NumAluInstructions =
program->NumTexInstructions =
program->NumTexIndirections = 0;
@@ -3880,6 +3909,7 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
program->Base.OutputsWritten = ap.Base.OutputsWritten;
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
program->Base.TexturesUsed[i] = ap.TexturesUsed[i];
+ program->Base.ShadowSamplers = ap.ShadowSamplers;
program->FogOption = ap.FogOption;
program->UsesKill = ap.UsesKill;
diff --git a/src/mesa/shader/arbprogram.syn b/src/mesa/shader/arbprogram.syn
index 4f82717873e..1746a876c30 100644
--- a/src/mesa/shader/arbprogram.syn
+++ b/src/mesa/shader/arbprogram.syn
@@ -21,13 +21,13 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
+
/**
* \file arbprogram.syn
* ARB_fragment/vertex_program syntax
* \author Michal Krol
*/
-
+
.syntax program;
/*
@@ -226,8 +226,11 @@
.emtcode TEXTARGET_SHADOW1D 0x06
.emtcode TEXTARGET_SHADOW2D 0x07
.emtcode TEXTARGET_SHADOWRECT 0x08
+/* GL_MESA_texture_array */
.emtcode TEXTARGET_1D_ARRAY 0x09
.emtcode TEXTARGET_2D_ARRAY 0x0a
+.emtcode TEXTARGET_SHADOW1D_ARRAY 0x0b
+.emtcode TEXTARGET_SHADOW2D_ARRAY 0x0c
/* face type */
.emtcode FACE_FRONT 0x00
@@ -912,6 +915,7 @@ fragment program
| "CUBE"
| "RECT"
| <shadowTarget> (if option ARB_fragment_program_shadow present)
+ | <arrayTarget> (if option MESA_texture_array present)
*/
texTarget
"1D" .emit TEXTARGET_1D .or
@@ -920,19 +924,38 @@ texTarget
.if (texture_rectangle != 0x00) "RECT" .emit TEXTARGET_RECT .or
"CUBE" .emit TEXTARGET_CUBE .or
.if (ARB_fragment_program_shadow != 0x00) shadowTarget .or
- .if (MESA_texture_array != 0x00) "ARRAY1D" .emit TEXTARGET_1D_ARRAY .or
- .if (MESA_texture_array != 0x00) "ARRAY2D" .emit TEXTARGET_2D_ARRAY;
+ .if (MESA_texture_array != 0x00) arrayTarget;
/*
GL_ARB_fragment_program_shadow
<shadowTarget> ::= "SHADOW1D"
| "SHADOW2D"
| "SHADOWRECT"
+ | <shadowArrayTarget> (if option MESA_texture_array present)
*/
shadowTarget
"SHADOW1D" .emit TEXTARGET_SHADOW1D .or
"SHADOW2D" .emit TEXTARGET_SHADOW2D .or
- .if (texture_rectangle != 0x00) "SHADOWRECT" .emit TEXTARGET_SHADOWRECT;
+ .if (texture_rectangle != 0x00) "SHADOWRECT" .emit TEXTARGET_SHADOWRECT .or
+ .if (MESA_texture_array != 0x00) shadowArrayTarget;
+
+/*
+GL_MESA_texture_array
+
+ <arrayTarget> ::= "ARRAY1D"
+ | "ARRAY2D"
+
+ <shadowArrayTarget> ::= "SHADOWARRAY1D"
+ | "SHADOWARRAY2D"
+*/
+
+arrayTarget
+ "ARRAY1D" .emit TEXTARGET_1D_ARRAY .or
+ "ARRAY2D" .emit TEXTARGET_2D_ARRAY;
+
+shadowArrayTarget
+ "SHADOWARRAY1D" .emit TEXTARGET_SHADOW1D_ARRAY .or
+ "SHADOWARRAY2D" .emit TEXTARGET_SHADOW2D_ARRAY;
/*
fragment program
diff --git a/src/mesa/shader/arbprogram_syn.h b/src/mesa/shader/arbprogram_syn.h
index 30dc9f4594e..5f3f7d6cf46 100644
--- a/src/mesa/shader/arbprogram_syn.h
+++ b/src/mesa/shader/arbprogram_syn.h
@@ -1,3 +1,7 @@
+
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE .syn FILE */
+
+" \n"
".syntax program;\n"
".emtcode REVISION 0x0a\n"
".emtcode FRAGMENT_PROGRAM 0x01\n"
@@ -122,7 +126,9 @@
".emtcode TEXTARGET_SHADOW2D 0x07\n"
".emtcode TEXTARGET_SHADOWRECT 0x08\n"
".emtcode TEXTARGET_1D_ARRAY 0x09\n"
-".emtcode TEXTARGET_2D_ARRAY 0x0A\n"
+".emtcode TEXTARGET_2D_ARRAY 0x0a\n"
+".emtcode TEXTARGET_SHADOW1D_ARRAY 0x0b\n"
+".emtcode TEXTARGET_SHADOW2D_ARRAY 0x0c\n"
".emtcode FACE_FRONT 0x00\n"
".emtcode FACE_BACK 0x01\n"
".emtcode COLOR_PRIMARY 0x00\n"
@@ -479,12 +485,18 @@
" .if (texture_rectangle != 0x00) \"RECT\" .emit TEXTARGET_RECT .or\n"
" \"CUBE\" .emit TEXTARGET_CUBE .or\n"
" .if (ARB_fragment_program_shadow != 0x00) shadowTarget .or\n"
-" .if (MESA_texture_array != 0x00) \"ARRAY1D\" .emit TEXTARGET_1D_ARRAY .or\n"
-" .if (MESA_texture_array != 0x00) \"ARRAY2D\" .emit TEXTARGET_2D_ARRAY;\n"
+" .if (MESA_texture_array != 0x00) arrayTarget;\n"
"shadowTarget\n"
" \"SHADOW1D\" .emit TEXTARGET_SHADOW1D .or\n"
" \"SHADOW2D\" .emit TEXTARGET_SHADOW2D .or\n"
-" .if (texture_rectangle != 0x00) \"SHADOWRECT\" .emit TEXTARGET_SHADOWRECT;\n"
+" .if (texture_rectangle != 0x00) \"SHADOWRECT\" .emit TEXTARGET_SHADOWRECT .or\n"
+" .if (MESA_texture_array != 0x00) shadowArrayTarget;\n"
+"arrayTarget\n"
+" \"ARRAY1D\" .emit TEXTARGET_1D_ARRAY .or\n"
+" \"ARRAY2D\" .emit TEXTARGET_2D_ARRAY;\n"
+"shadowArrayTarget\n"
+" \"SHADOWARRAY1D\" .emit TEXTARGET_SHADOW1D_ARRAY .or\n"
+" \"SHADOWARRAY2D\" .emit TEXTARGET_SHADOW2D_ARRAY;\n"
"optTexImageUnitNum\n"
" optTexImageUnitNum_1 .or .true .emit 0x00;\n"
"optTexImageUnitNum_1\n"
diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h
index 8756f122d09..3d3511823d7 100644
--- a/src/mesa/swrast/s_aalinetemp.h
+++ b/src/mesa/swrast/s_aalinetemp.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -185,10 +185,18 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane);
ATTRIB_LOOP_BEGIN
GLuint c;
- for (c = 0; c < 4; c++) {
- const GLfloat a0 = v0->attrib[attr][c] * invW0;
- const GLfloat a1 = v1->attrib[attr][c] * invW1;
- compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1, line.attrPlane[attr][c]);
+ if (swrast->_InterpMode[attr] == GL_FLAT) {
+ for (c = 0; c < 4; c++) {
+ constant_plane(v1->attrib[attr][c], line.attrPlane[attr][c]);
+ }
+ }
+ else {
+ for (c = 0; c < 4; c++) {
+ const GLfloat a0 = v0->attrib[attr][c] * invW0;
+ const GLfloat a1 = v1->attrib[attr][c] * invW1;
+ compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1,
+ line.attrPlane[attr][c]);
+ }
}
line.span.arrayAttribs |= (1 << attr);
if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index f373fde781b..791850cb502 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -535,10 +535,11 @@ _swrast_update_texture_samplers(GLcontext *ctx)
/**
- * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, swrast->_ActiveAtttribMask.
+ * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs,
+ * swrast->_ActiveAtttribMask.
*/
static void
-_swrast_update_fragment_attribs(GLcontext *ctx)
+_swrast_update_active_attribs(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint attribsMask;
@@ -663,16 +664,14 @@ _swrast_validate_derived( GLcontext *ctx )
_NEW_PROGRAM))
_swrast_update_fragment_program( ctx, swrast->NewState );
- if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
- _swrast_update_texture_samplers( ctx );
-
if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) {
+ _swrast_update_texture_samplers( ctx );
_swrast_validate_texture_images(ctx);
- if (swrast->NewState & (_NEW_COLOR)) {
- _swrast_update_deferred_texture(ctx);
- }
}
+ if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM))
+ _swrast_update_deferred_texture(ctx);
+
if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
_swrast_update_rasterflags( ctx );
@@ -681,7 +680,7 @@ _swrast_validate_derived( GLcontext *ctx )
_NEW_LIGHT |
_NEW_PROGRAM |
_NEW_TEXTURE))
- _swrast_update_fragment_attribs(ctx);
+ _swrast_update_active_attribs(ctx);
if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS))
_swrast_update_color_outputs(ctx);
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index 53e584b3b6b..2383015000a 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -188,6 +188,8 @@ static void
copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height, GLint destx, GLint desty)
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLbitfield prevActiveAttribs = swrast->_ActiveAttribMask;
GLfloat *tmpImage, *p;
GLint sy, dy, stepy, row;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
@@ -197,12 +199,15 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
if (!ctx->ReadBuffer->_ColorReadBuffer) {
/* no readbuffer - OK */
- return;
+ goto end;
}
+ /* don't interpolate COL0 and overwrite the glDrawPixel colors! */
+ swrast->_ActiveAttribMask &= ~FRAG_BIT_COL0;
+
if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty);
- return;
+ goto end;
}
else if (ctx->Pixel.Convolution1DEnabled) {
/* make sure we don't apply 1D convolution */
@@ -239,7 +244,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat) * 4);
if (!tmpImage) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
- return;
+ goto end;
}
/* read the source image as RGBA/float */
p = tmpImage;
@@ -294,6 +299,9 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
if (overlapping)
_mesa_free(tmpImage);
+
+end:
+ swrast->_ActiveAttribMask = prevActiveAttribs;
}
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index d971d90fb9a..925358d77eb 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -532,16 +532,22 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLbitfield prevActiveAttribs = swrast->_ActiveAttribMask;
const GLint imgX = x, imgY = y;
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
GLfloat *convImage = NULL;
GLbitfield transferOps = ctx->_ImageTransferState;
SWspan span;
+ /* don't interpolate COL0 and overwrite the glDrawPixel colors! */
+ swrast->_ActiveAttribMask &= ~FRAG_BIT_COL0;
+
/* Try an optimized glDrawPixels first */
if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type,
- unpack, pixels))
- return;
+ unpack, pixels)) {
+ goto end;
+ }
INIT_SPAN(span, GL_BITMAP, 0, 0x0, SPAN_RGBA);
_swrast_span_default_attribs(ctx, &span);
@@ -559,13 +565,13 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
if (!tmpImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
- return;
+ goto end;
}
convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
if (!convImage) {
_mesa_free(tmpImage);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
- return;
+ goto end;
}
/* Unpack the image and apply transfer ops up to convolution */
@@ -669,6 +675,9 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
if (convImage) {
_mesa_free(convImage);
}
+
+end:
+ swrast->_ActiveAttribMask = prevActiveAttribs;
}
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index e47dbbdaf35..923b67e78e6 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -26,6 +26,7 @@
#include "colormac.h"
#include "context.h"
#include "prog_instruction.h"
+#include "texstate.h"
#include "s_fragprog.h"
#include "s_span.h"
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index 90a3d5545f8..431629efb1f 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -171,6 +171,11 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask)
{
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ /* for glDraw/CopyPixels() we may have turned off some bits in
+ * the _ActiveAttribMask - be sure to obey that mask now.
+ */
+ attrMask &= swrast->_ActiveAttribMask;
+
ATTRIB_LOOP_BEGIN
if (attrMask & (1 << attr)) {
const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
@@ -1169,9 +1174,11 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
if (ctx->FragmentProgram._Current ||
ctx->ATIFragmentShader._Enabled) {
/* programmable shading */
- span->array->ChanType = GL_FLOAT;
-
+ if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
+ convert_color_type(span, GL_FLOAT, 0);
+ }
interpolate_active_attribs(ctx, span, ~0);
+ span->array->ChanType = GL_FLOAT;
if (!(span->arrayMask & SPAN_Z))
_swrast_span_interpolate_z (ctx, span);
diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c
index 2c8e443daf9..c2a7512388e 100644
--- a/src/mesa/swrast/s_texfilter.c
+++ b/src/mesa/swrast/s_texfilter.c
@@ -2893,25 +2893,7 @@ sample_depth_texture( GLcontext *ctx,
/* XXXX if tObj->MinFilter != tObj->MagFilter, we're ignoring lambda */
- /* XXX this could be precomputed and saved in the texture object */
- if (tObj->CompareFlag) {
- /* GL_SGIX_shadow */
- if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
- function = GL_LEQUAL;
- }
- else {
- ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
- function = GL_GEQUAL;
- }
- }
- else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
- /* GL_ARB_shadow */
- function = tObj->CompareFunc;
- }
- else {
- function = GL_NONE; /* pass depth through as grayscale */
- }
-
+ function = tObj->_Function;
if (tObj->MagFilter == GL_NEAREST) {
GLuint i;
for (i = 0; i < n; i++) {
@@ -3365,7 +3347,7 @@ texture_sample_func
_swrast_choose_texture_sample_func( GLcontext *ctx,
const struct gl_texture_object *t )
{
- if (!t || !t->Complete) {
+ if (!t || !t->_Complete) {
return &null_sample_func;
}
else {
diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c
index 78fa137d3fd..1ab5911f2f1 100644
--- a/src/mesa/swrast/s_zoom.c
+++ b/src/mesa/swrast/s_zoom.c
@@ -162,12 +162,14 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
zoomed_arrays.rgba = zoomed_arrays.attribs[FRAG_ATTRIB_COL0];
#endif
+ /* copy attribute info (XXX copy all attribs?) */
+ COPY_4V(zoomed.attrStart[FRAG_ATTRIB_WPOS], span->attrStart[FRAG_ATTRIB_WPOS]);
+ COPY_4V(zoomed.attrStepX[FRAG_ATTRIB_WPOS], span->attrStepX[FRAG_ATTRIB_WPOS]);
+ COPY_4V(zoomed.attrStepY[FRAG_ATTRIB_WPOS], span->attrStepY[FRAG_ATTRIB_WPOS]);
- /* copy fog interp info */
zoomed.attrStart[FRAG_ATTRIB_FOGC][0] = span->attrStart[FRAG_ATTRIB_FOGC][0];
zoomed.attrStepX[FRAG_ATTRIB_FOGC][0] = span->attrStepX[FRAG_ATTRIB_FOGC][0];
zoomed.attrStepY[FRAG_ATTRIB_FOGC][0] = span->attrStepY[FRAG_ATTRIB_FOGC][0];
- /* XXX copy texcoord info? */
if (format == GL_RGBA || format == GL_RGB) {
/* copy Z info */
diff --git a/src/mesa/x86/common_x86.c b/src/mesa/x86/common_x86.c
index 889b40a89f2..0b2af0a3706 100644
--- a/src/mesa/x86/common_x86.c
+++ b/src/mesa/x86/common_x86.c
@@ -104,12 +104,7 @@ static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS exp)
static void check_os_sse_support( void )
{
-#if defined(__linux__)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
- _mesa_debug(NULL, "Cannot safely enable SSE on pre-2.4 kernels.\n");
- _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
-#endif
-#elif defined(__FreeBSD__)
+#if defined(__FreeBSD__)
{
int ret, enabled;
unsigned int len;
@@ -160,7 +155,7 @@ static void check_os_sse_support( void )
/* Do nothing on other platforms for now.
*/
_mesa_debug(NULL, "Not testing OS support for SSE, leaving enabled.\n");
-#endif /* __linux__ */
+#endif /* __FreeBSD__ */
}
#endif /* USE_SSE_ASM */
diff --git a/src/mesa/x86/glapi_x86.S b/src/mesa/x86/glapi_x86.S
index bdf42ac0887..74e93721bc3 100644
--- a/src/mesa/x86/glapi_x86.S
+++ b/src/mesa/x86/glapi_x86.S
@@ -58,12 +58,17 @@
#ifdef GLX_USE_TLS
+#ifdef GLX_X86_READONLY_TEXT
+# define CTX_INSNS MOV_L(GS:(EAX), EAX)
+#else
+# define CTX_INSNS NOP /* Pad for init_glapi_relocs() */
+#endif
# define GL_STUB(fn,off,fn_alt) \
ALIGNTEXT16; \
GLOBL_FN(GL_PREFIX(fn, fn_alt)); \
GL_PREFIX(fn, fn_alt): \
CALL(_x86_get_dispatch) ; \
- NOP ; \
+ CTX_INSNS ; \
JMP(GL_OFFSET(off))
#elif defined(PTHREADS)
@@ -114,7 +119,10 @@ SEG_TEXT
HIDDEN(GLNAME(_x86_get_dispatch))
ALIGNTEXT16
GLNAME(_x86_get_dispatch):
- movl %gs:_glapi_tls_Dispatch@NTPOFF, %eax
+ call 1f
+1: popl %eax
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax
+ movl _glapi_tls_Dispatch@GOTNTPOFF(%eax), %eax
ret
#elif defined(PTHREADS)
@@ -133,7 +141,7 @@ GLNAME(_x86_get_dispatch):
EXTERN GLNAME(_glapi_get_dispatch)
#endif
-#if defined( GLX_USE_TLS )
+#if defined( GLX_USE_TLS ) && !defined( GLX_X86_READONLY_TEXT )
.section wtext, "awx", @progbits
#endif /* defined( GLX_USE_TLS ) */