summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
authorDavid Nusinow <dnusinow@debian.org>2006-09-24 21:11:46 +0000
committerDavid Nusinow <dnusinow@debian.org>2006-09-24 21:11:46 +0000
commiteadb76b3f8e0e9b82da762bd29e53895bf9e6351 (patch)
treeb9f68fc763f9ea055287c366e61de84191b200ce /src/mesa/drivers/dri
parentb3f7313ae4f4cd418522595e90e7d06ef6992f0a (diff)
Bump to latest mesa in Debian
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/Makefile.template18
-rw-r--r--src/mesa/drivers/dri/common/glcontextmodes.c38
-rw-r--r--src/mesa/drivers/dri/common/texmem.c1
-rw-r--r--src/mesa/drivers/dri/common/utils.c15
-rw-r--r--src/mesa/drivers/dri/common/xmlpool/Makefile96
-rw-r--r--src/mesa/drivers/dri/common/xmlpool/gen_xmlpool.py191
-rw-r--r--src/mesa/drivers/dri/dri_client/Makefile60
-rw-r--r--src/mesa/drivers/dri/dri_client/imports/xf86drm.h636
-rw-r--r--src/mesa/drivers/dri/dri_client/xf86drm.c2333
-rw-r--r--src/mesa/drivers/dri/dri_client/xf86drmHash.c433
-rw-r--r--src/mesa/drivers/dri/dri_client/xf86drmRandom.c217
-rw-r--r--src/mesa/drivers/dri/dri_client/xf86drmSL.c488
-rw-r--r--src/mesa/drivers/dri/ffb/ffb_vtxfmt.c13
-rw-r--r--src/mesa/drivers/dri/i810/i810context.c1
-rw-r--r--src/mesa/drivers/dri/i810/i810state.c1
-rw-r--r--src/mesa/drivers/dri/i810/i810texstate.c166
-rw-r--r--src/mesa/drivers/dri/i915/Makefile3
-rw-r--r--src/mesa/drivers/dri/i915/i830_context.c2
-rw-r--r--src/mesa/drivers/dri/i915/i830_context.h2
-rw-r--r--src/mesa/drivers/dri/i915/i830_vtbl.c45
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.h1
-rw-r--r--src/mesa/drivers/dri/i915/i915_texprog.c21
-rw-r--r--src/mesa/drivers/dri/i915/i915_texstate.c4
-rw-r--r--src/mesa/drivers/dri/i915/intel_batchbuffer.c7
-rw-r--r--src/mesa/drivers/dri/i915/intel_batchbuffer.h5
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.h2
-rw-r--r--src/mesa/drivers/dri/i915/intel_ioctl.c4
-rw-r--r--src/mesa/drivers/dri/i915/intel_pixel.c8
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.c2
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex.c5
-rw-r--r--src/mesa/drivers/dri/i915/intel_tris.c2
-rw-r--r--src/mesa/drivers/dri/i915/server/intel.h44
-rw-r--r--src/mesa/drivers/dri/i915/server/intel_dri.c397
-rw-r--r--src/mesa/drivers/dri/mga/README26
-rw-r--r--src/mesa/drivers/dri/mga/mgaioctl.c4
-rw-r--r--src/mesa/drivers/dri/r128/r128_context.c10
-rw-r--r--src/mesa/drivers/dri/r128/r128_context.h2
-rw-r--r--src/mesa/drivers/dri/r128/r128_lock.c2
-rw-r--r--src/mesa/drivers/dri/r128/r128_state.c12
-rw-r--r--src/mesa/drivers/dri/r128/r128_tris.c25
-rw-r--r--src/mesa/drivers/dri/r200/Makefile2
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c10
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h2
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c10
-rw-r--r--src/mesa/drivers/dri/r200/r200_swtcl.c31
-rw-r--r--src/mesa/drivers/dri/r200/r200_vtxfmt.c16
-rw-r--r--src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S4
-rw-r--r--src/mesa/drivers/dri/r300/Makefile4
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c23
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c60
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h33
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c8
-rw-r--r--src/mesa/drivers/dri/r300/r300_maos.c133
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h16
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c6
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c172
-rw-r--r--src/mesa/drivers/dri/r300/r300_texmem.c18
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertexprog.c10
-rw-r--r--src/mesa/drivers/dri/r300/radeon_context.c2
-rw-r--r--src/mesa/drivers/dri/r300/radeon_span.c29
-rw-r--r--src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c87
-rw-r--r--src/mesa/drivers/dri/radeon/Makefile2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c10
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c84
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c10
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_swtcl.c31
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxfmt.c13
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S4
-rw-r--r--src/mesa/drivers/dri/radeon/server/radeon_dri.c1
-rw-r--r--src/mesa/drivers/dri/savage/savagestate.c8
-rw-r--r--src/mesa/drivers/dri/savage/savagetex.c148
-rw-r--r--src/mesa/drivers/dri/savage/savagetris.c42
-rw-r--r--src/mesa/drivers/dri/sis/sis_clear.c7
-rw-r--r--src/mesa/drivers/dri/sis/sis_context.h2
-rw-r--r--src/mesa/drivers/dri/sis/sis_state.c2
-rw-r--r--src/mesa/drivers/dri/sis/sis_stencil.c5
-rw-r--r--src/mesa/drivers/dri/sis/sis_tris.c19
-rw-r--r--src/mesa/drivers/dri/tdfx/BUGS64
-rw-r--r--src/mesa/drivers/dri/tdfx/X86/fx_3dnow_fastpath.S84
-rw-r--r--src/mesa/drivers/dri/tdfx/X86/fx_3dnow_fasttmp.h314
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_render.c28
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_state.c6
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_tex.c84
-rw-r--r--src/mesa/drivers/dri/unichrome/via_ioctl.c2
-rw-r--r--src/mesa/drivers/dri/unichrome/via_tex.c15
-rw-r--r--src/mesa/drivers/dri/unichrome/via_tris.c27
90 files changed, 6375 insertions, 663 deletions
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template
index 9e1b36252ff..4a7a6552ac0 100644
--- a/src/mesa/drivers/dri/Makefile.template
+++ b/src/mesa/drivers/dri/Makefile.template
@@ -14,8 +14,7 @@ COMMON_SOURCES = \
ifeq ($(WINDOW_SYSTEM),dri)
WINOBJ=
WINLIB=
-INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) \
- `pkg-config --cflags libdrm`
+INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES)
OBJECTS = $(C_SOURCES:.c=.o) \
$(ASM_SOURCES:.S=.o)
@@ -25,8 +24,6 @@ WINOBJ=
WINLIB=-L$(MESA)/src/glx/mini
MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini
INCLUDES = $(MINIGLX_INCLUDES) \
- -I$(DRM_SOURCE_PATH)/shared-core \
- -I$(DRM_SOURCE_PATH)/libdrm \
$(SHARED_INCLUDES)
OBJECTS = $(C_SOURCES:.c=.o) \
@@ -40,7 +37,6 @@ SHARED_INCLUDES = \
-I. \
-I$(TOP)/src/mesa/drivers/dri/common \
-Iserver \
- -I$(DRM_SOURCE_PATH)/shared-core \
-I$(TOP)/include \
-I$(TOP)/include/GL/internal \
-I$(TOP)/src/mesa \
@@ -52,15 +48,16 @@ SHARED_INCLUDES = \
-I$(TOP)/src/mesa/swrast \
-I$(TOP)/src/mesa/swrast_setup \
-I$(TOP)/src/egl/main \
- -I$(TOP)/src/egl/drivers/dri
+ -I$(TOP)/src/egl/drivers/dri \
+ `pkg-config --cflags libdrm`
##### RULES #####
.c.o:
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
.S.o:
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
##### TARGETS #####
@@ -85,11 +82,10 @@ $(LIB_DIR)/$(LIBNAME): $(LIBNAME)
# Run 'make depend' to update the dependencies if you change
# what's included by any source file.
-.PHONY: depend
depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
touch depend
- $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(C_SOURCES) $(ASM_SOURCES) \
- >& /dev/null
+ $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \
+ $(ASM_SOURCES) > /dev/null
# Emacs tags
diff --git a/src/mesa/drivers/dri/common/glcontextmodes.c b/src/mesa/drivers/dri/common/glcontextmodes.c
index d1297991497..edb04463f61 100644
--- a/src/mesa/drivers/dri/common/glcontextmodes.c
+++ b/src/mesa/drivers/dri/common/glcontextmodes.c
@@ -104,7 +104,7 @@ _gl_convert_to_x_visual_type( int visualType )
GrayScale, StaticGray
};
- return ( (unsigned) (visualType - GLX_TRUE_COLOR) <= NUM_VISUAL_TYPES )
+ return ( (unsigned) (visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES )
? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
}
@@ -182,6 +182,15 @@ _gl_copy_visual_to_context_mode( __GLcontextModes * mode,
mode->transparentIndex = config->transparentIndex;
mode->swapMethod = GLX_SWAP_UNDEFINED_OML;
+
+ mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE;
+ mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ?
+ GL_TRUE : GL_FALSE;
+ mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE;
+ mode->bindToTextureTargets = mode->rgbMode ?
+ GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT |
+ GLX_TEXTURE_RECTANGLE_BIT_EXT : 0;
+ mode->yInverted = GL_FALSE;
}
@@ -313,6 +322,21 @@ _gl_get_context_mode_data(const __GLcontextModes *mode, int attribute,
case GLX_SAMPLES_SGIS:
*value_return = mode->samples;
return 0;
+ case GLX_BIND_TO_TEXTURE_RGB_EXT:
+ *value_return = mode->bindToTextureRgb;
+ return 0;
+ case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+ *value_return = mode->bindToTextureRgba;
+ return 0;
+ case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+ *value_return = mode->bindToMipmapTexture;
+ return 0;
+ case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+ *value_return = mode->bindToTextureTargets;
+ return 0;
+ case GLX_Y_INVERTED_EXT:
+ *value_return = mode->yInverted;
+ return 0;
/* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX.
* It is ONLY for communication between the GLX client and the GLX
@@ -383,6 +407,11 @@ _gl_context_modes_create( unsigned count, size_t minimum_size )
(*next)->xRenderable = GLX_DONT_CARE;
(*next)->fbconfigID = GLX_DONT_CARE;
(*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
+ (*next)->bindToTextureRgb = GLX_DONT_CARE;
+ (*next)->bindToTextureRgba = GLX_DONT_CARE;
+ (*next)->bindToMipmapTexture = GLX_DONT_CARE;
+ (*next)->bindToTextureTargets = 0;
+ (*next)->yInverted = GLX_DONT_CARE;
next = & ((*next)->next);
}
@@ -495,5 +524,10 @@ _gl_context_modes_are_same( const __GLcontextModes * a,
(a->maxPbufferPixels == b->maxPbufferPixels) &&
(a->optimalPbufferWidth == b->optimalPbufferWidth) &&
(a->optimalPbufferHeight == b->optimalPbufferHeight) &&
- (a->swapMethod == b->swapMethod) );
+ (a->swapMethod == b->swapMethod) &&
+ (a->bindToTextureRgb == b->bindToTextureRgb) &&
+ (a->bindToTextureRgba == b->bindToTextureRgba) &&
+ (a->bindToMipmapTexture == b->bindToMipmapTexture) &&
+ (a->bindToTextureTargets == b->bindToTextureTargets) &&
+ (a->yInverted == b->yInverted) );
}
diff --git a/src/mesa/drivers/dri/common/texmem.c b/src/mesa/drivers/dri/common/texmem.c
index 41316de1fc4..b0e8c4c1c28 100644
--- a/src/mesa/drivers/dri/common/texmem.c
+++ b/src/mesa/drivers/dri/common/texmem.c
@@ -410,6 +410,7 @@ static void driTexturesGone( driTexHeap * heap, int offset, int size,
fprintf( stderr, "Couldn't alloc placeholder: heap %u sz %x ofs %x\n", heap->heapId,
(int)size, (int)offset );
mmDumpMemInfo( heap->memory_heap );
+ FREE(t);
return;
}
t->heap = heap;
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index fbe1991fa5d..e3eca86da1b 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -361,25 +361,26 @@ driCheckDriDdxDrmVersions3(const char * driver_name,
const __DRIversion * drmExpected)
{
static const char format[] = "%s DRI driver expected %s version %d.%d.x "
- "but got version %d.%d.%d";
+ "but got version %d.%d.%d\n";
static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x "
- "but got version %d.%d.%d";
+ "but got version %d.%d.%d\n";
/* Check the DRI version */
if ( (driActual->major != driExpected->major)
|| (driActual->minor < driExpected->minor) ) {
- __driUtilMessage(format, driver_name, "DRI",
+ fprintf(stderr, format, driver_name, "DRI",
driExpected->major, driExpected->minor,
driActual->major, driActual->minor, driActual->patch);
return GL_FALSE;
}
/* Check that the DDX driver version is compatible */
- if ( (ddxActual->major < ddxExpected->major_min)
+ /* for miniglx we pass in -1 so we can ignore the DDX version */
+ if ( (ddxActual->major != -1) && ((ddxActual->major < ddxExpected->major_min)
|| (ddxActual->major > ddxExpected->major_max)
- || (ddxActual->minor < ddxExpected->minor) ) {
- __driUtilMessage(format2, driver_name, "DDX",
+ || (ddxActual->minor < ddxExpected->minor)) ) {
+ fprintf(stderr, format2, driver_name, "DDX",
ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
ddxActual->major, ddxActual->minor, ddxActual->patch);
return GL_FALSE;
@@ -388,7 +389,7 @@ driCheckDriDdxDrmVersions3(const char * driver_name,
/* Check that the DRM driver version is compatible */
if ( (drmActual->major != drmExpected->major)
|| (drmActual->minor < drmExpected->minor) ) {
- __driUtilMessage(format, driver_name, "DRM",
+ fprintf(stderr, format, driver_name, "DRM",
drmExpected->major, drmExpected->minor,
drmActual->major, drmActual->minor, drmActual->patch);
return GL_FALSE;
diff --git a/src/mesa/drivers/dri/common/xmlpool/Makefile b/src/mesa/drivers/dri/common/xmlpool/Makefile
new file mode 100644
index 00000000000..ef94541c374
--- /dev/null
+++ b/src/mesa/drivers/dri/common/xmlpool/Makefile
@@ -0,0 +1,96 @@
+# Convenient makefile for managing translations.
+
+# Prerequisites:
+# - GNU gettext
+# - Python
+
+# Adding new translations
+# -----------------------
+
+# To start working on a new translation edit the POS=... line
+# below. If you want to add for example a french translation, add
+# fr.po.
+
+# Then run "make po" to generate a fresh .po file from translatable
+# strings in t_options.h. Now you can edit the new .po file (fr.po in
+# the example above) to translate the strings. Please make sure that
+# your editor encodes the file in UTF-8.
+
+# Updating existing translations
+# ------------------------------
+
+# Run "make po" to update .po files with new translatable strings from
+# t_options.h. Now you can edit the .po files you're interested
+# in. Please make sure that your editor encodes the file in UTF-8.
+
+# Updating options.h
+# ------------------
+
+# Finally run "make" to generate options.h from t_options.h with all
+# translations. Now you can rebuild the drivers. Any common options
+# used by the drivers will have option descriptions with the latest
+# translations.
+
+# Publishing translations
+# -----------------------
+
+# To get your translation(s) into Mesa CVS, please send me your
+# <lang>.po file.
+
+# More information:
+# - info gettext
+
+# The set of supported languages. Add languages as needed.
+POS=de.po es.po nl.po fr.po
+
+#
+# Don't change anything below, unless you know what you're doing.
+#
+LANGS=$(POS:%.po=%)
+MOS=$(POS:%.po=%/LC_MESSAGES/options.mo)
+POT=xmlpool.pot
+
+.PHONY: all clean pot po mo
+
+all: options.h
+
+# Only intermediate files are cleaned up. options.h is not deleted because
+# it's in CVS.
+clean:
+ rm -f $(POT) *~
+ rm -rf $(LANGS)
+
+# Default target options.h
+options.h: t_options.h mo
+ python gen_xmlpool.py $(LANGS) > options.h
+
+# Update .mo files from the corresponding .po files.
+mo:
+ @for mo in $(MOS); do \
+ lang=$${mo%%/*}; \
+ echo "Updating $$mo from $$lang.po."; \
+ mkdir -p $${mo%/*}; \
+ msgfmt -o $$mo $$lang.po; \
+ done
+
+# Use this target to create or update .po files with new messages in
+# driconf.py.
+po: $(POS)
+
+pot: $(POT)
+
+# Extract message catalog from driconf.py.
+$(POT): t_options.h
+ xgettext -L C --from-code utf-8 -o $(POT) t_options.h
+
+# Create or update a .po file for a specific language.
+%.po: $(POT)
+ @if [ -f $@ ]; then \
+ echo "Merging new strings from $(POT) into $@."; \
+ mv $@ $@~; \
+ msgmerge -o $@ $@~ $(POT); \
+ else \
+ echo "Initializing $@ from $(POT)."; \
+ msginit -i $(POT) -o $@~ --locale=$*; \
+ sed -e 's/charset=.*\\n/charset=UTF-8\\n/' $@~ > $@; \
+ fi
diff --git a/src/mesa/drivers/dri/common/xmlpool/gen_xmlpool.py b/src/mesa/drivers/dri/common/xmlpool/gen_xmlpool.py
new file mode 100644
index 00000000000..7398c4cd0b2
--- /dev/null
+++ b/src/mesa/drivers/dri/common/xmlpool/gen_xmlpool.py
@@ -0,0 +1,191 @@
+#!/usr/bin/python
+
+import sys
+import gettext
+import re
+
+# List of supported languages
+languages = sys.argv[1:]
+
+# Escape special characters in C strings
+def escapeCString (s):
+ escapeSeqs = {'\a' : '\\a', '\b' : '\\b', '\f' : '\\f', '\n' : '\\n',
+ '\r' : '\\r', '\t' : '\\t', '\v' : '\\v', '\\' : '\\\\'}
+ # " -> '' is a hack. Quotes (") aren't possible in XML attributes.
+ # Better use Unicode characters for typographic quotes in option
+ # descriptions and translations.
+ i = 0
+ r = ''
+ while i < len(s):
+ # Special case: escape double quote with \u201c or \u201d, depending
+ # on whether it's an open or close quote. This is needed because plain
+ # double quotes are not possible in XML attributes.
+ if s[i] == '"':
+ if i == len(s)-1 or s[i+1].isspace():
+ # close quote
+ q = u'\u201c'
+ else:
+ # open quote
+ q = u'\u201d'
+ r = r + q
+ elif escapeSeqs.has_key(s[i]):
+ r = r + escapeSeqs[s[i]]
+ else:
+ r = r + s[i]
+ i = i + 1
+ return r
+
+# Expand escape sequences in C strings (needed for gettext lookup)
+def expandCString (s):
+ escapeSeqs = {'a' : '\a', 'b' : '\b', 'f' : '\f', 'n' : '\n',
+ 'r' : '\r', 't' : '\t', 'v' : '\v',
+ '"' : '"', '\\' : '\\'}
+ i = 0
+ escape = False
+ hexa = False
+ octa = False
+ num = 0
+ digits = 0
+ r = ''
+ while i < len(s):
+ if not escape:
+ if s[i] == '\\':
+ escape = True
+ else:
+ r = r + s[i]
+ elif hexa:
+ if (s[i] >= '0' and s[i] <= '9') or \
+ (s[i] >= 'a' and s[i] <= 'f') or \
+ (s[i] >= 'A' and s[i] <= 'F'):
+ num = num * 16 + int(s[i],16)
+ digits = digits + 1
+ else:
+ digits = 2
+ if digits >= 2:
+ hexa = False
+ escape = False
+ r = r + chr(num)
+ elif octa:
+ if s[i] >= '0' and s[i] <= '7':
+ num = num * 8 + int(s[i],8)
+ digits = digits + 1
+ else:
+ digits = 3
+ if digits >= 3:
+ octa = False
+ escape = False
+ r = r + chr(num)
+ else:
+ if escapeSeqs.has_key(s[i]):
+ r = r + escapeSeqs[s[i]]
+ escape = False
+ elif s[i] >= '0' and s[i] <= '7':
+ octa = True
+ num = int(s[i],8)
+ if num <= 3:
+ digits = 1
+ else:
+ digits = 2
+ elif s[i] == 'x' or s[i] == 'X':
+ hexa = True
+ num = 0
+ digits = 0
+ else:
+ r = r + s[i]
+ escape = False
+ i = i + 1
+ return r
+
+# Expand matches. The first match is always a DESC or DESC_BEGIN match.
+# Subsequent matches are ENUM matches.
+#
+# DESC, DESC_BEGIN format: \1 \2=<lang> \3 \4=gettext(" \5=<text> \6=") \7
+# ENUM format: \1 \2=gettext(" \3=<text> \4=") \5
+def expandMatches (matches, translations, end=None):
+ assert len(matches) > 0
+ nTranslations = len(translations)
+ i = 0
+ # Expand the description+enums for all translations
+ for lang,trans in translations:
+ i = i + 1
+ # Make sure that all but the last line of a simple description
+ # are extended with a backslash.
+ suffix = ''
+ if len(matches) == 1 and i < len(translations) and \
+ not matches[0].expand (r'\7').endswith('\\'):
+ suffix = ' \\'
+ # Expand the description line. Need to use ugettext in order to allow
+ # non-ascii unicode chars in the original English descriptions.
+ text = escapeCString (trans.ugettext (unicode (expandCString (
+ matches[0].expand (r'\5')), "utf-8"))).encode("utf-8")
+ print matches[0].expand (r'\1' + lang + r'\3"' + text + r'"\7') + suffix
+ # Expand any subsequent enum lines
+ for match in matches[1:]:
+ text = escapeCString (trans.ugettext (unicode (expandCString (
+ match.expand (r'\3')), "utf-8"))).encode("utf-8")
+ print match.expand (r'\1"' + text + r'"\5')
+
+ # Expand description end
+ if end:
+ print end,
+
+# Compile a list of translation classes to all supported languages.
+# The first translation is always a NullTranslations.
+translations = [("en", gettext.NullTranslations())]
+for lang in languages:
+ try:
+ trans = gettext.translation ("options", ".", [lang])
+ except IOError:
+ sys.stderr.write ("Warning: language '%s' not found.\n" % lang)
+ continue
+ translations.append ((lang, trans))
+
+# Regular expressions:
+reLibintl_h = re.compile (r'#\s*include\s*<libintl.h>')
+reDESC = re.compile (r'(\s*DRI_CONF_DESC\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
+reDESC_BEGIN = re.compile (r'(\s*DRI_CONF_DESC_BEGIN\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
+reENUM = re.compile (r'(\s*DRI_CONF_ENUM\s*\([^,]+,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
+reDESC_END = re.compile (r'\s*DRI_CONF_DESC_END')
+
+# Print a header
+print \
+"/***********************************************************************\n" \
+" *** THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT! ***\n" \
+" ***********************************************************************/"
+
+# Process the options template and generate options.h with all
+# translations.
+template = file ("t_options.h", "r")
+descMatches = []
+for line in template:
+ if len(descMatches) > 0:
+ matchENUM = reENUM .match (line)
+ matchDESC_END = reDESC_END.match (line)
+ if matchENUM:
+ descMatches.append (matchENUM)
+ elif matchDESC_END:
+ expandMatches (descMatches, translations, line)
+ descMatches = []
+ else:
+ sys.stderr.write (
+ "Warning: unexpected line inside description dropped:\n%s\n" \
+ % line)
+ continue
+ if reLibintl_h.search (line):
+ # Ignore (comment out) #include <libintl.h>
+ print "/* %s * commented out by gen_xmlpool.py */" % line
+ continue
+ matchDESC = reDESC .match (line)
+ matchDESC_BEGIN = reDESC_BEGIN.match (line)
+ if matchDESC:
+ assert len(descMatches) == 0
+ expandMatches ([matchDESC], translations)
+ elif matchDESC_BEGIN:
+ assert len(descMatches) == 0
+ descMatches = [matchDESC_BEGIN]
+ else:
+ print line,
+
+if len(descMatches) > 0:
+ sys.stderr.write ("Warning: unterminated description at end of file.\n")
+ expandMatches (descMatches, translations)
diff --git a/src/mesa/drivers/dri/dri_client/Makefile b/src/mesa/drivers/dri/dri_client/Makefile
new file mode 100644
index 00000000000..9ab60cdaf80
--- /dev/null
+++ b/src/mesa/drivers/dri/dri_client/Makefile
@@ -0,0 +1,60 @@
+# src/mesa/drivers/dri/gamma/Makefile
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+# Get rid of this:
+#
+DEFINES += -DGLX_DIRECT_RENDERING
+
+C_SOURCES = \
+ xf86drm.c \
+ xf86drmHash.c \
+ xf86drmRandom.c \
+ xf86drmSL.c \
+
+
+
+OBJECTS = $(C_SOURCES:.c=.o)
+
+INCLUDES = \
+ -I$(TOP)/include \
+ -I$(DRM_SOURCE_PATH)/shared-core \
+ -I$(TOP)/include/GL/internal \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mesa/main \
+ -I$(TOP)/src/mesa/glapi \
+ -Iimports
+
+
+##### RULES #####
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+
+##### TARGETS #####
+
+default: depend dri.a
+
+
+# Run 'make dep' to update the dependencies if you change
+# what's included by any source file.
+depend: $(C_SOURCES) $(ASM_SOURCES)
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) \
+ $(C_SOURCES) $(ASM_SOURCES)
+
+
+dri.a: $(OBJECTS)
+ rm -f $@
+ ar rcv $@ $(OBJECTS)
+ ranlib $@
+
+# Remove .o and backup files
+clean:
+ -rm -f *.o */*.o *~ *.so *.a depend depend.bak
+
+install:
+
+include depend
diff --git a/src/mesa/drivers/dri/dri_client/imports/xf86drm.h b/src/mesa/drivers/dri/dri_client/imports/xf86drm.h
new file mode 100644
index 00000000000..d3d78eb84e8
--- /dev/null
+++ b/src/mesa/drivers/dri/dri_client/imports/xf86drm.h
@@ -0,0 +1,636 @@
+/**
+ * \file xf86drm.h
+ * OS-independent header for DRM user-level library interface.
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ */
+
+/*
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.26 2003/08/16 19:26:37 dawes Exp $ */
+
+#ifndef _XF86DRM_H_
+#define _XF86DRM_H_
+
+#include <drm.h>
+
+ /* Defaults, if nothing set in xf86config */
+#define DRM_DEV_UID 0
+#define DRM_DEV_GID 0
+/* Default /dev/dri directory permissions 0755 */
+#define DRM_DEV_DIRMODE \
+ (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
+#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
+
+#define DRM_DIR_NAME "/dev/dri"
+#define DRM_DEV_NAME "%s/card%d"
+#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
+
+#define DRM_ERR_NO_DEVICE (-1001)
+#define DRM_ERR_NO_ACCESS (-1002)
+#define DRM_ERR_NOT_ROOT (-1003)
+#define DRM_ERR_INVALID (-1004)
+#define DRM_ERR_NO_FD (-1005)
+
+#define DRM_AGP_NO_HANDLE 0
+
+typedef unsigned int drmSize, *drmSizePtr; /**< For mapped regions */
+typedef void *drmAddress, **drmAddressPtr; /**< For mapped regions */
+
+/**
+ * Driver version information.
+ *
+ * \sa drmGetVersion() and drmSetVersion().
+ */
+typedef struct _drmVersion {
+ int version_major; /**< Major version */
+ int version_minor; /**< Minor version */
+ int version_patchlevel; /**< Patch level */
+ int name_len; /**< Length of name buffer */
+ char *name; /**< Name of driver */
+ int date_len; /**< Length of date buffer */
+ char *date; /**< User-space buffer to hold date */
+ int desc_len; /**< Length of desc buffer */
+ char *desc; /**< User-space buffer to hold desc */
+} drmVersion, *drmVersionPtr;
+
+typedef struct _drmStats {
+ unsigned long count; /**< Number of data */
+ struct {
+ unsigned long value; /**< Value from kernel */
+ const char *long_format; /**< Suggested format for long_name */
+ const char *long_name; /**< Long name for value */
+ const char *rate_format; /**< Suggested format for rate_name */
+ const char *rate_name; /**< Short name for value per second */
+ int isvalue; /**< True if value (vs. counter) */
+ const char *mult_names; /**< Multiplier names (e.g., "KGM") */
+ int mult; /**< Multiplier value (e.g., 1024) */
+ int verbose; /**< Suggest only in verbose output */
+ } data[15];
+} drmStatsT;
+
+
+ /* All of these enums *MUST* match with the
+ kernel implementation -- so do *NOT*
+ change them! (The drmlib implementation
+ will just copy the flags instead of
+ translating them.) */
+typedef enum {
+ DRM_FRAME_BUFFER = 0, /**< WC, no caching, no core dump */
+ DRM_REGISTERS = 1, /**< no caching, no core dump */
+ DRM_SHM = 2, /**< shared, cached */
+ DRM_AGP = 3, /**< AGP/GART */
+ DRM_SCATTER_GATHER = 4 /**< PCI scatter/gather */
+} drmMapType;
+
+typedef enum {
+ DRM_RESTRICTED = 0x0001, /**< Cannot be mapped to client-virtual */
+ DRM_READ_ONLY = 0x0002, /**< Read-only in client-virtual */
+ DRM_LOCKED = 0x0004, /**< Physical pages locked */
+ DRM_KERNEL = 0x0008, /**< Kernel requires access */
+ DRM_WRITE_COMBINING = 0x0010, /**< Use write-combining, if available */
+ DRM_CONTAINS_LOCK = 0x0020, /**< SHM page that contains lock */
+ DRM_REMOVABLE = 0x0040 /**< Removable mapping */
+} drmMapFlags;
+
+/**
+ * \warning These values *MUST* match drm.h
+ */
+typedef enum {
+ /** \name Flags for DMA buffer dispatch */
+ /*@{*/
+ DRM_DMA_BLOCK = 0x01, /**<
+ * Block until buffer dispatched.
+ *
+ * \note the buffer may not yet have been
+ * processed by the hardware -- getting a
+ * hardware lock with the hardware quiescent
+ * will ensure that the buffer has been
+ * processed.
+ */
+ DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
+ DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
+ /*@}*/
+
+ /** \name Flags for DMA buffer request */
+ /*@{*/
+ DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
+ DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
+ DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
+ /*@}*/
+} drmDMAFlags;
+
+typedef enum {
+ DRM_PAGE_ALIGN = 0x01,
+ DRM_AGP_BUFFER = 0x02,
+ DRM_SG_BUFFER = 0x04
+} drmBufDescFlags;
+
+typedef enum {
+ DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
+ DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
+ DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
+ DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
+ /* These *HALT* flags aren't supported yet
+ -- they will be used to support the
+ full-screen DGA-like mode. */
+ DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
+ DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
+} drmLockFlags;
+
+typedef enum {
+ DRM_CONTEXT_PRESERVED = 0x01, /**< This context is preserved and
+ never swapped. */
+ DRM_CONTEXT_2DONLY = 0x02 /**< This context is for 2D rendering only. */
+} drm_context_tFlags, *drm_context_tFlagsPtr;
+
+typedef struct _drmBufDesc {
+ int count; /**< Number of buffers of this size */
+ int size; /**< Size in bytes */
+ int low_mark; /**< Low water mark */
+ int high_mark; /**< High water mark */
+} drmBufDesc, *drmBufDescPtr;
+
+typedef struct _drmBufInfo {
+ int count; /**< Number of buffers described in list */
+ drmBufDescPtr list; /**< List of buffer descriptions */
+} drmBufInfo, *drmBufInfoPtr;
+
+typedef struct _drmBuf {
+ int idx; /**< Index into the master buffer list */
+ int total; /**< Buffer size */
+ int used; /**< Amount of buffer in use (for DMA) */
+ drmAddress address; /**< Address */
+} drmBuf, *drmBufPtr;
+
+/**
+ * Buffer mapping information.
+ *
+ * Used by drmMapBufs() and drmUnmapBufs() to store information about the
+ * mapped buffers.
+ */
+typedef struct _drmBufMap {
+ int count; /**< Number of buffers mapped */
+ drmBufPtr list; /**< Buffers */
+} drmBufMap, *drmBufMapPtr;
+
+typedef struct _drmLock {
+ volatile unsigned int lock;
+ char padding[60];
+ /* This is big enough for most current (and future?) architectures:
+ DEC Alpha: 32 bytes
+ Intel Merced: ?
+ Intel P5/PPro/PII/PIII: 32 bytes
+ Intel StrongARM: 32 bytes
+ Intel i386/i486: 16 bytes
+ MIPS: 32 bytes (?)
+ Motorola 68k: 16 bytes
+ Motorola PowerPC: 32 bytes
+ Sun SPARC: 32 bytes
+ */
+} drmLock, *drmLockPtr;
+
+/**
+ * Indices here refer to the offset into
+ * list in drmBufInfo
+ */
+typedef struct _drmDMAReq {
+ drm_context_t context; /**< Context handle */
+ int send_count; /**< Number of buffers to send */
+ int *send_list; /**< List of handles to buffers */
+ int *send_sizes; /**< Lengths of data to send, in bytes */
+ drmDMAFlags flags; /**< Flags */
+ int request_count; /**< Number of buffers requested */
+ int request_size; /**< Desired size of buffers requested */
+ int *request_list; /**< Buffer information */
+ int *request_sizes; /**< Minimum acceptable sizes */
+ int granted_count; /**< Number of buffers granted at this size */
+} drmDMAReq, *drmDMAReqPtr;
+
+typedef struct _drmRegion {
+ drm_handle_t handle;
+ unsigned int offset;
+ drmSize size;
+ drmAddress map;
+} drmRegion, *drmRegionPtr;
+
+typedef struct _drmTextureRegion {
+ unsigned char next;
+ unsigned char prev;
+ unsigned char in_use;
+ unsigned char padding; /**< Explicitly pad this out */
+ unsigned int age;
+} drmTextureRegion, *drmTextureRegionPtr;
+
+
+typedef enum {
+ DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
+ DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
+ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
+} drmVBlankSeqType;
+
+typedef struct _drmVBlankReq {
+ drmVBlankSeqType type;
+ unsigned int sequence;
+ unsigned long signal;
+} drmVBlankReq, *drmVBlankReqPtr;
+
+typedef struct _drmVBlankReply {
+ drmVBlankSeqType type;
+ unsigned int sequence;
+ long tval_sec;
+ long tval_usec;
+} drmVBlankReply, *drmVBlankReplyPtr;
+
+typedef union _drmVBlank {
+ drmVBlankReq request;
+ drmVBlankReply reply;
+} drmVBlank, *drmVBlankPtr;
+
+typedef struct _drmSetVersion {
+ int drm_di_major;
+ int drm_di_minor;
+ int drm_dd_major;
+ int drm_dd_minor;
+} drmSetVersion, *drmSetVersionPtr;
+
+
+#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
+
+#define DRM_LOCK_HELD 0x80000000 /**< Hardware lock is held */
+#define DRM_LOCK_CONT 0x40000000 /**< Hardware lock is contended */
+
+#if defined(__GNUC__) && (__GNUC__ >= 2)
+# if defined(__i386) || defined(__amd64__)
+ /* Reflect changes here to drmP.h */
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ int __dummy; /* Can't mark eax as clobbered */ \
+ __asm__ __volatile__( \
+ "lock ; cmpxchg %4,%1\n\t" \
+ "setnz %0" \
+ : "=d" (__ret), \
+ "=m" (__drm_dummy_lock(lock)), \
+ "=a" (__dummy) \
+ : "2" (old), \
+ "r" (new)); \
+ } while (0)
+
+#elif defined(__alpha__)
+
+#define DRM_CAS(lock, old, new, ret) \
+ do { \
+ int old32; \
+ int cur32; \
+ __asm__ __volatile__( \
+ " mb\n" \
+ " zap %4, 0xF0, %0\n" \
+ " ldl_l %1, %2\n" \
+ " zap %1, 0xF0, %1\n" \
+ " cmpeq %0, %1, %1\n" \
+ " beq %1, 1f\n" \
+ " bis %5, %5, %1\n" \
+ " stl_c %1, %2\n" \
+ "1: xor %1, 1, %1\n" \
+ " stl %1, %3" \
+ : "+r" (old32), \
+ "+&r" (cur32), \
+ "=m" (__drm_dummy_lock(lock)),\
+ "=m" (ret) \
+ : "r" (old), \
+ "r" (new)); \
+ } while(0)
+
+#elif defined(__sparc__)
+
+#define DRM_CAS(lock,old,new,__ret) \
+do { register unsigned int __old __asm("o0"); \
+ register unsigned int __new __asm("o1"); \
+ register volatile unsigned int *__lock __asm("o2"); \
+ __old = old; \
+ __new = new; \
+ __lock = (volatile unsigned int *)lock; \
+ __asm__ __volatile__( \
+ /*"cas [%2], %3, %0"*/ \
+ ".word 0xd3e29008\n\t" \
+ /*"membar #StoreStore | #StoreLoad"*/ \
+ ".word 0x8143e00a" \
+ : "=&r" (__new) \
+ : "0" (__new), \
+ "r" (__lock), \
+ "r" (__old) \
+ : "memory"); \
+ __ret = (__new != __old); \
+} while(0)
+
+#elif defined(__ia64__)
+
+#ifdef __INTEL_COMPILER
+/* this currently generates bad code (missing stop bits)... */
+#include <ia64intrin.h>
+
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ unsigned long __result, __old = (old) & 0xffffffff; \
+ __mf(); \
+ __result = _InterlockedCompareExchange_acq(&__drm_dummy_lock(lock), (new), __old);\
+ __ret = (__result) != (__old); \
+/* __ret = (__sync_val_compare_and_swap(&__drm_dummy_lock(lock), \
+ (old), (new)) \
+ != (old)); */\
+ } while (0)
+
+#else
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ unsigned int __result, __old = (old); \
+ __asm__ __volatile__( \
+ "mf\n" \
+ "mov ar.ccv=%2\n" \
+ ";;\n" \
+ "cmpxchg4.acq %0=%1,%3,ar.ccv" \
+ : "=r" (__result), "=m" (__drm_dummy_lock(lock)) \
+ : "r" ((unsigned long)__old), "r" (new) \
+ : "memory"); \
+ __ret = (__result) != (__old); \
+ } while (0)
+
+#endif
+
+#elif defined(__powerpc__)
+
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ __asm__ __volatile__( \
+ "sync;" \
+ "0: lwarx %0,0,%1;" \
+ " xor. %0,%3,%0;" \
+ " bne 1f;" \
+ " stwcx. %2,0,%1;" \
+ " bne- 0b;" \
+ "1: " \
+ "sync;" \
+ : "=&r"(__ret) \
+ : "r"(lock), "r"(new), "r"(old) \
+ : "cr0", "memory"); \
+ } while (0)
+
+#endif /* architecture */
+#endif /* __GNUC__ >= 2 */
+
+#ifndef DRM_CAS
+#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */
+#endif
+
+#if defined(__alpha__) || defined(__powerpc__)
+#define DRM_CAS_RESULT(_result) int _result
+#else
+#define DRM_CAS_RESULT(_result) char _result
+#endif
+
+#define DRM_LIGHT_LOCK(fd,lock,context) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
+ if (__ret) drmGetLock(fd,context,0); \
+ } while(0)
+
+ /* This one counts fast locks -- for
+ benchmarking only. */
+#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
+ if (__ret) drmGetLock(fd,context,0); \
+ else ++count; \
+ } while(0)
+
+#define DRM_LOCK(fd,lock,context,flags) \
+ do { \
+ if (flags) drmGetLock(fd,context,flags); \
+ else DRM_LIGHT_LOCK(fd,lock,context); \
+ } while(0)
+
+#define DRM_UNLOCK(fd,lock,context) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \
+ if (__ret) drmUnlock(fd,context); \
+ } while(0)
+
+ /* Simple spin locks */
+#define DRM_SPINLOCK(spin,val) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ do { \
+ DRM_CAS(spin,0,val,__ret); \
+ if (__ret) while ((spin)->lock); \
+ } while (__ret); \
+ } while(0)
+
+#define DRM_SPINLOCK_TAKE(spin,val) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ int cur; \
+ do { \
+ cur = (*spin).lock; \
+ DRM_CAS(spin,cur,val,__ret); \
+ } while (__ret); \
+ } while(0)
+
+#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \
+ do { \
+ int __i; \
+ __ret = 1; \
+ for (__i = 0; __ret && __i < count; __i++) { \
+ DRM_CAS(spin,0,val,__ret); \
+ if (__ret) for (;__i < count && (spin)->lock; __i++); \
+ } \
+ } while(0)
+
+#define DRM_SPINUNLOCK(spin,val) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ if ((*spin).lock == val) { /* else server stole lock */ \
+ do { \
+ DRM_CAS(spin,val,0,__ret); \
+ } while (__ret); \
+ } \
+ } while(0)
+
+/* General user-level programmer's API: unprivileged */
+extern int drmAvailable(void);
+extern int drmOpen(const char *name, const char *busid);
+extern int drmClose(int fd);
+extern drmVersionPtr drmGetVersion(int fd);
+extern drmVersionPtr drmGetLibVersion(int fd);
+extern void drmFreeVersion(drmVersionPtr);
+extern int drmGetMagic(int fd, drm_magic_t * magic);
+extern char *drmGetBusid(int fd);
+extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum,
+ int funcnum);
+extern int drmGetMap(int fd, int idx, drm_handle_t *offset,
+ drmSize *size, drmMapType *type,
+ drmMapFlags *flags, drm_handle_t *handle,
+ int *mtrr);
+extern int drmGetClient(int fd, int idx, int *auth, int *pid,
+ int *uid, unsigned long *magic,
+ unsigned long *iocs);
+extern int drmGetStats(int fd, drmStatsT *stats);
+extern int drmSetInterfaceVersion(int fd, drmSetVersion *version);
+extern int drmCommandNone(int fd, unsigned long drmCommandIndex);
+extern int drmCommandRead(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size);
+extern int drmCommandWrite(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size);
+extern int drmCommandWriteRead(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size);
+
+/* General user-level programmer's API: X server (root) only */
+extern void drmFreeBusid(const char *busid);
+extern int drmSetBusid(int fd, const char *busid);
+extern int drmAuthMagic(int fd, drm_magic_t magic);
+extern int drmAddMap(int fd,
+ drm_handle_t offset,
+ drmSize size,
+ drmMapType type,
+ drmMapFlags flags,
+ drm_handle_t * handle);
+extern int drmRmMap(int fd, drm_handle_t handle);
+extern int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
+ drm_handle_t handle);
+
+extern int drmAddBufs(int fd, int count, int size,
+ drmBufDescFlags flags,
+ int agp_offset);
+extern int drmMarkBufs(int fd, double low, double high);
+extern int drmCreateContext(int fd, drm_context_t * handle);
+extern int drmSetContextFlags(int fd, drm_context_t context,
+ drm_context_tFlags flags);
+extern int drmGetContextFlags(int fd, drm_context_t context,
+ drm_context_tFlagsPtr flags);
+extern int drmAddContextTag(int fd, drm_context_t context, void *tag);
+extern int drmDelContextTag(int fd, drm_context_t context);
+extern void *drmGetContextTag(int fd, drm_context_t context);
+extern drm_context_t * drmGetReservedContextList(int fd, int *count);
+extern void drmFreeReservedContextList(drm_context_t *);
+extern int drmSwitchToContext(int fd, drm_context_t context);
+extern int drmDestroyContext(int fd, drm_context_t handle);
+extern int drmCreateDrawable(int fd, drm_drawable_t * handle);
+extern int drmDestroyDrawable(int fd, drm_drawable_t handle);
+extern int drmCtlInstHandler(int fd, int irq);
+extern int drmCtlUninstHandler(int fd);
+extern int drmInstallSIGIOHandler(int fd,
+ void (*f)(int fd,
+ void *oldctx,
+ void *newctx));
+extern int drmRemoveSIGIOHandler(int fd);
+
+/* General user-level programmer's API: authenticated client and/or X */
+extern int drmMap(int fd,
+ drm_handle_t handle,
+ drmSize size,
+ drmAddressPtr address);
+extern int drmUnmap(drmAddress address, drmSize size);
+extern drmBufInfoPtr drmGetBufInfo(int fd);
+extern drmBufMapPtr drmMapBufs(int fd);
+extern int drmUnmapBufs(drmBufMapPtr bufs);
+extern int drmDMA(int fd, drmDMAReqPtr request);
+extern int drmFreeBufs(int fd, int count, int *list);
+extern int drmGetLock(int fd,
+ drm_context_t context,
+ drmLockFlags flags);
+extern int drmUnlock(int fd, drm_context_t context);
+extern int drmFinish(int fd, int context, drmLockFlags flags);
+extern int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
+ drm_handle_t * handle);
+
+/* AGP/GART support: X server (root) only */
+extern int drmAgpAcquire(int fd);
+extern int drmAgpRelease(int fd);
+extern int drmAgpEnable(int fd, unsigned long mode);
+extern int drmAgpAlloc(int fd, unsigned long size,
+ unsigned long type, unsigned long *address,
+ unsigned long *handle);
+extern int drmAgpFree(int fd, unsigned long handle);
+extern int drmAgpBind(int fd, unsigned long handle,
+ unsigned long offset);
+extern int drmAgpUnbind(int fd, unsigned long handle);
+
+/* AGP/GART info: authenticated client and/or X */
+extern int drmAgpVersionMajor(int fd);
+extern int drmAgpVersionMinor(int fd);
+extern unsigned long drmAgpGetMode(int fd);
+extern unsigned long drmAgpBase(int fd); /* Physical location */
+extern unsigned long drmAgpSize(int fd); /* Bytes */
+extern unsigned long drmAgpMemoryUsed(int fd);
+extern unsigned long drmAgpMemoryAvail(int fd);
+extern unsigned int drmAgpVendorId(int fd);
+extern unsigned int drmAgpDeviceId(int fd);
+
+/* PCI scatter/gather support: X server (root) only */
+extern int drmScatterGatherAlloc(int fd, unsigned long size,
+ unsigned long *handle);
+extern int drmScatterGatherFree(int fd, unsigned long handle);
+
+extern int drmWaitVBlank(int fd, drmVBlankPtr vbl);
+
+/* Support routines */
+extern int drmError(int err, const char *label);
+extern void *drmMalloc(int size);
+extern void drmFree(void *pt);
+
+/* Hash table routines */
+extern void *drmHashCreate(void);
+extern int drmHashDestroy(void *t);
+extern int drmHashLookup(void *t, unsigned long key, void **value);
+extern int drmHashInsert(void *t, unsigned long key, void *value);
+extern int drmHashDelete(void *t, unsigned long key);
+extern int drmHashFirst(void *t, unsigned long *key, void **value);
+extern int drmHashNext(void *t, unsigned long *key, void **value);
+
+/* PRNG routines */
+extern void *drmRandomCreate(unsigned long seed);
+extern int drmRandomDestroy(void *state);
+extern unsigned long drmRandom(void *state);
+extern double drmRandomDouble(void *state);
+
+/* Skip list routines */
+
+extern void *drmSLCreate(void);
+extern int drmSLDestroy(void *l);
+extern int drmSLLookup(void *l, unsigned long key, void **value);
+extern int drmSLInsert(void *l, unsigned long key, void *value);
+extern int drmSLDelete(void *l, unsigned long key);
+extern int drmSLNext(void *l, unsigned long *key, void **value);
+extern int drmSLFirst(void *l, unsigned long *key, void **value);
+extern void drmSLDump(void *l);
+extern int drmSLLookupNeighbors(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value);
+
+#endif
diff --git a/src/mesa/drivers/dri/dri_client/xf86drm.c b/src/mesa/drivers/dri/dri_client/xf86drm.c
new file mode 100644
index 00000000000..dba0f98deba
--- /dev/null
+++ b/src/mesa/drivers/dri/dri_client/xf86drm.c
@@ -0,0 +1,2333 @@
+/**
+ * \file xf86drm.c
+ * User-level interface to DRM device
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Kevin E. Martin <martin@valinux.com>
+ */
+
+/*
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.36 2003/08/24 17:35:35 tsi Exp $ */
+
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "drm.h"
+# include "xf86_ansic.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# define stat_t struct stat
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# include <stdarg.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+# else
+# include <X11/Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+# include "drm.h"
+#endif
+
+/* No longer needed with CVS kernel modules on alpha
+#if defined(__alpha__) && defined(__linux__)
+extern unsigned long _bus_base(void);
+#define BUS_BASE _bus_base()
+#endif
+*/
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include "xf86drm.h"
+
+#ifdef __FreeBSD__
+#define DRM_MAJOR 145
+#endif
+
+#ifdef __NetBSD__
+#define DRM_MAJOR 34
+#endif
+
+# ifdef __OpenBSD__
+# define DRM_MAJOR 81
+# endif
+
+#ifndef DRM_MAJOR
+#define DRM_MAJOR 226 /* Linux */
+#endif
+
+#ifndef DRM_MAX_MINOR
+#define DRM_MAX_MINOR 16
+#endif
+
+#ifdef __linux__
+#include <sys/sysmacros.h> /* for makedev() */
+#endif
+
+#ifndef makedev
+ /* This definition needs to be changed on
+ some systems if dev_t is a structure.
+ If there is a header file we can get it
+ from, there would be best. */
+#define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
+#endif
+
+#define DRM_MSG_VERBOSITY 3
+
+/**
+ * Output a message to stderr.
+ *
+ * \param format printf() like format string.
+ *
+ * \internal
+ * This function is a wrapper around vfprintf().
+ */
+static void
+drmMsg(const char *format, ...)
+{
+ va_list ap;
+
+#ifndef XFree86Server
+ const char *env;
+ if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose"))
+#endif
+ {
+ va_start(ap, format);
+#ifdef XFree86Server
+ xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap);
+#else
+ vfprintf(stderr, format, ap);
+#endif
+ va_end(ap);
+ }
+}
+
+static void *drmHashTable = NULL; /* Context switch callbacks */
+
+typedef struct drmHashEntry {
+ int fd;
+ void (*f)(int, void *, void *);
+ void *tagTable;
+} drmHashEntry;
+
+void *drmMalloc(int size)
+{
+ void *pt;
+ if ((pt = _DRM_MALLOC(size))) memset(pt, 0, size);
+ return pt;
+}
+
+void drmFree(void *pt)
+{
+ if (pt) _DRM_FREE(pt);
+}
+
+/* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
+static char *drmStrdup(const char *s)
+{
+ char *retval = NULL;
+
+ if (s) {
+ retval = _DRM_MALLOC(strlen(s)+1);
+ strcpy(retval, s);
+ }
+ return retval;
+}
+
+
+static unsigned long drmGetKeyFromFd(int fd)
+{
+ stat_t st;
+
+ st.st_rdev = 0;
+ fstat(fd, &st);
+ return st.st_rdev;
+}
+
+static drmHashEntry *drmGetEntry(int fd)
+{
+ unsigned long key = drmGetKeyFromFd(fd);
+ void *value;
+ drmHashEntry *entry;
+
+ if (!drmHashTable) drmHashTable = drmHashCreate();
+
+ if (drmHashLookup(drmHashTable, key, &value)) {
+ entry = drmMalloc(sizeof(*entry));
+ entry->fd = fd;
+ entry->f = NULL;
+ entry->tagTable = drmHashCreate();
+ drmHashInsert(drmHashTable, key, entry);
+ } else {
+ entry = value;
+ }
+ return entry;
+}
+
+/**
+ * Compare two busid strings
+ *
+ * \param first
+ * \param second
+ *
+ * \return 1 if matched.
+ *
+ * \internal
+ * This function compares two bus ID strings. It understands the older
+ * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format. In the format, o is
+ * domain, b is bus, d is device, f is function.
+ */
+static int drmMatchBusID(const char *id1, const char *id2)
+{
+ /* First, check if the IDs are exactly the same */
+ if (strcasecmp(id1, id2) == 0)
+ return 1;
+
+ /* Try to match old/new-style PCI bus IDs. */
+ if (strncasecmp(id1, "pci", 3) == 0) {
+ int o1, b1, d1, f1;
+ int o2, b2, d2, f2;
+ int ret;
+
+ ret = sscanf(id1, "pci:%04x:%02x:%02x.%d", &o1, &b1, &d1, &f1);
+ if (ret != 4) {
+ o1 = 0;
+ ret = sscanf(id1, "PCI:%d:%d:%d", &b1, &d1, &f1);
+ if (ret != 3)
+ return 0;
+ }
+
+ ret = sscanf(id2, "pci:%04x:%02x:%02x.%d", &o2, &b2, &d2, &f2);
+ if (ret != 4) {
+ o2 = 0;
+ ret = sscanf(id2, "PCI:%d:%d:%d", &b2, &d2, &f2);
+ if (ret != 3)
+ return 0;
+ }
+
+ if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
+ return 0;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Open the DRM device, creating it if necessary.
+ *
+ * \param dev major and minor numbers of the device.
+ * \param minor minor number of the device.
+ *
+ * \return a file descriptor on success, or a negative value on error.
+ *
+ * \internal
+ * Assembles the device name from \p minor and opens it, creating the device
+ * special file node with the major and minor numbers specified by \p dev and
+ * parent directory if necessary and was called by root.
+ */
+static int drmOpenDevice(long dev, int minor)
+{
+ stat_t st;
+ char buf[64];
+ int fd;
+ mode_t devmode = DRM_DEV_MODE;
+ int isroot = !geteuid();
+#if defined(XFree86Server)
+ uid_t user = DRM_DEV_UID;
+ gid_t group = DRM_DEV_GID;
+#endif
+
+ sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+ drmMsg("drmOpenDevice: node name is %s\n", buf);
+
+#if defined(XFree86Server)
+ devmode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE;
+ devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
+ group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID;
+#endif
+
+ if (stat(DRM_DIR_NAME, &st)) {
+ if (!isroot) return DRM_ERR_NOT_ROOT;
+ mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
+ chown(DRM_DIR_NAME, 0, 0); /* root:root */
+ chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
+ }
+
+ /* Check if the device node exists and create it if necessary. */
+ if (stat(buf, &st)) {
+ if (!isroot) return DRM_ERR_NOT_ROOT;
+ remove(buf);
+ mknod(buf, S_IFCHR | devmode, dev);
+ }
+#if defined(XFree86Server)
+ chown(buf, user, group);
+ chmod(buf, devmode);
+#endif
+
+ fd = open(buf, O_RDWR, 0);
+ drmMsg("drmOpenDevice: open result is %d, (%s)\n",
+ fd, fd < 0 ? strerror(errno) : "OK");
+ if (fd >= 0) return fd;
+
+ /* Check if the device node is not what we expect it to be, and recreate it
+ * and try again if so.
+ */
+ if (st.st_rdev != dev) {
+ if (!isroot) return DRM_ERR_NOT_ROOT;
+ remove(buf);
+ mknod(buf, S_IFCHR | devmode, dev);
+#if defined(XFree86Server)
+ chown(buf, user, group);
+ chmod(buf, devmode);
+#endif
+ }
+ fd = open(buf, O_RDWR, 0);
+ drmMsg("drmOpenDevice: open result is %d, (%s)\n",
+ fd, fd < 0 ? strerror(errno) : "OK");
+ if (fd >= 0) return fd;
+
+ drmMsg("drmOpenDevice: Open failed\n");
+ remove(buf);
+ return -errno;
+}
+
+
+/**
+ * Open the DRM device
+ *
+ * \param minor device minor number.
+ * \param create allow to create the device if set.
+ *
+ * \return a file descriptor on success, or a negative value on error.
+ *
+ * \internal
+ * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
+ * name from \p minor and opens it.
+ */
+static int drmOpenMinor(int minor, int create)
+{
+ int fd;
+ char buf[64];
+
+ if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
+
+ sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+ if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
+ return -errno;
+}
+
+
+/**
+ * Determine whether the DRM kernel driver has been loaded.
+ *
+ * \return 1 if the DRM driver is loaded, 0 otherwise.
+ *
+ * \internal
+ * Determine the presence of the kernel driver by attempting to open the 0
+ * minor and get version information. For backward compatibility with older
+ * Linux implementations, /proc/dri is also checked.
+ */
+int drmAvailable(void)
+{
+ drmVersionPtr version;
+ int retval = 0;
+ int fd;
+
+ if ((fd = drmOpenMinor(0, 1)) < 0) {
+#ifdef __linux__
+ /* Try proc for backward Linux compatibility */
+ if (!access("/proc/dri/0", R_OK)) return 1;
+#endif
+ return 0;
+ }
+
+ if ((version = drmGetVersion(fd))) {
+ retval = 1;
+ drmFreeVersion(version);
+ }
+ close(fd);
+
+ return retval;
+}
+
+
+/**
+ * Open the device by bus ID.
+ *
+ * \param busid bus ID.
+ *
+ * \return a file descriptor on success, or a negative value on error.
+ *
+ * \internal
+ * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
+ * comparing the device bus ID with the one supplied.
+ *
+ * \sa drmOpenMinor() and drmGetBusid().
+ */
+static int drmOpenByBusid(const char *busid)
+{
+ int i;
+ int fd;
+ const char *buf;
+ drmSetVersion sv;
+
+ drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
+ for (i = 0; i < DRM_MAX_MINOR; i++) {
+ fd = drmOpenMinor(i, 1);
+ drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
+ if (fd >= 0) {
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 1;
+ sv.drm_dd_major = -1; /* Don't care */
+ drmSetInterfaceVersion(fd, &sv);
+ buf = drmGetBusid(fd);
+ drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
+ if (buf && drmMatchBusID(buf, busid)) {
+ drmFreeBusid(buf);
+ return fd;
+ }
+ if (buf) drmFreeBusid(buf);
+ close(fd);
+ }
+ }
+ return -1;
+}
+
+
+/**
+ * Open the device by name.
+ *
+ * \param name driver name.
+ *
+ * \return a file descriptor on success, or a negative value on error.
+ *
+ * \internal
+ * This function opens the first minor number that matches the driver name and
+ * isn't already in use. If it's in use it then it will already have a bus ID
+ * assigned.
+ *
+ * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
+ */
+static int drmOpenByName(const char *name)
+{
+ int i;
+ int fd;
+ drmVersionPtr version;
+ char * id;
+
+ if (!drmAvailable()) {
+#if !defined(XFree86Server)
+ return -1;
+#else
+ /* try to load the kernel module now */
+ if (!xf86LoadKernelModule(name)) {
+ ErrorF("[drm] failed to load kernel module \"%s\"\n",
+ name);
+ return -1;
+ }
+#endif
+ }
+
+ /*
+ * Open the first minor number that matches the driver name and isn't
+ * already in use. If it's in use it will have a busid assigned already.
+ */
+ for (i = 0; i < DRM_MAX_MINOR; i++) {
+ if ((fd = drmOpenMinor(i, 1)) >= 0) {
+ if ((version = drmGetVersion(fd))) {
+ if (!strcmp(version->name, name)) {
+ drmFreeVersion(version);
+ id = drmGetBusid(fd);
+ drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
+ if (!id || !*id) {
+ if (id) {
+ drmFreeBusid(id);
+ }
+ return fd;
+ } else {
+ drmFreeBusid(id);
+ }
+ } else {
+ drmFreeVersion(version);
+ }
+ }
+ close(fd);
+ }
+ }
+
+#ifdef __linux__
+ /* Backward-compatibility /proc support */
+ for (i = 0; i < 8; i++) {
+ char proc_name[64], buf[512];
+ char *driver, *pt, *devstring;
+ int retcode;
+
+ sprintf(proc_name, "/proc/dri/%d/name", i);
+ if ((fd = open(proc_name, 0, 0)) >= 0) {
+ retcode = read(fd, buf, sizeof(buf)-1);
+ close(fd);
+ if (retcode) {
+ buf[retcode-1] = '\0';
+ for (driver = pt = buf; *pt && *pt != ' '; ++pt)
+ ;
+ if (*pt) { /* Device is next */
+ *pt = '\0';
+ if (!strcmp(driver, name)) { /* Match */
+ for (devstring = ++pt; *pt && *pt != ' '; ++pt)
+ ;
+ if (*pt) { /* Found busid */
+ return drmOpenByBusid(++pt);
+ } else { /* No busid */
+ return drmOpenDevice(strtol(devstring, NULL, 0),i);
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ return -1;
+}
+
+
+/**
+ * Open the DRM device.
+ *
+ * Looks up the specified name and bus ID, and opens the device found. The
+ * entry in /dev/dri is created if necessary and if called by root.
+ *
+ * \param name driver name. Not referenced if bus ID is supplied.
+ * \param busid bus ID. Zero if not known.
+ *
+ * \return a file descriptor on success, or a negative value on error.
+ *
+ * \internal
+ * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
+ * otherwise.
+ */
+int drmOpen(const char *name, const char *busid)
+{
+#ifdef XFree86Server
+ if (!drmAvailable() && name != NULL) {
+ /* try to load the kernel */
+ if (!xf86LoadKernelModule(name)) {
+ ErrorF("[drm] failed to load kernel module \"%s\"\n",
+ name);
+ return -1;
+ }
+ }
+#endif
+
+ if (busid) {
+ int fd;
+
+ fd = drmOpenByBusid(busid);
+ if (fd >= 0)
+ return fd;
+ }
+ if (name)
+ return drmOpenByName(name);
+ return -1;
+}
+
+
+/**
+ * Free the version information returned by drmGetVersion().
+ *
+ * \param v pointer to the version information.
+ *
+ * \internal
+ * It frees the memory pointed by \p %v as well as all the non-null strings
+ * pointers in it.
+ */
+void drmFreeVersion(drmVersionPtr v)
+{
+ if (!v) return;
+ if (v->name) drmFree(v->name);
+ if (v->date) drmFree(v->date);
+ if (v->desc) drmFree(v->desc);
+ drmFree(v);
+}
+
+
+/**
+ * Free the non-public version information returned by the kernel.
+ *
+ * \param v pointer to the version information.
+ *
+ * \internal
+ * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
+ * the non-null strings pointers in it.
+ */
+static void drmFreeKernelVersion(drm_version_t *v)
+{
+ if (!v) return;
+ if (v->name) drmFree(v->name);
+ if (v->date) drmFree(v->date);
+ if (v->desc) drmFree(v->desc);
+ drmFree(v);
+}
+
+
+/**
+ * Copy version information.
+ *
+ * \param d destination pointer.
+ * \param s source pointer.
+ *
+ * \internal
+ * Used by drmGetVersion() to translate the information returned by the ioctl
+ * interface in a private structure into the public structure counterpart.
+ */
+static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
+{
+ d->version_major = s->version_major;
+ d->version_minor = s->version_minor;
+ d->version_patchlevel = s->version_patchlevel;
+ d->name_len = s->name_len;
+ d->name = drmStrdup(s->name);
+ d->date_len = s->date_len;
+ d->date = drmStrdup(s->date);
+ d->desc_len = s->desc_len;
+ d->desc = drmStrdup(s->desc);
+}
+
+
+/**
+ * Query the driver version information.
+ *
+ * \param fd file descriptor.
+ *
+ * \return pointer to a drmVersion structure which should be freed with
+ * drmFreeVersion().
+ *
+ * \note Similar information is available via /proc/dri.
+ *
+ * \internal
+ * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
+ * first with zeros to get the string lengths, and then the actually strings.
+ * It also null-terminates them since they might not be already.
+ */
+drmVersionPtr drmGetVersion(int fd)
+{
+ drmVersionPtr retval;
+ drm_version_t *version = drmMalloc(sizeof(*version));
+
+ /* First, get the lengths */
+ version->name_len = 0;
+ version->name = NULL;
+ version->date_len = 0;
+ version->date = NULL;
+ version->desc_len = 0;
+ version->desc = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
+ drmFreeKernelVersion(version);
+ return NULL;
+ }
+
+ /* Now, allocate space and get the data */
+ if (version->name_len)
+ version->name = drmMalloc(version->name_len + 1);
+ if (version->date_len)
+ version->date = drmMalloc(version->date_len + 1);
+ if (version->desc_len)
+ version->desc = drmMalloc(version->desc_len + 1);
+
+ if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
+ drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
+ drmFreeKernelVersion(version);
+ return NULL;
+ }
+
+ /* The results might not be null-terminated
+ strings, so terminate them. */
+
+ if (version->name_len) version->name[version->name_len] = '\0';
+ if (version->date_len) version->date[version->date_len] = '\0';
+ if (version->desc_len) version->desc[version->desc_len] = '\0';
+
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ drmCopyVersion(retval, version);
+ drmFreeKernelVersion(version);
+ return retval;
+}
+
+
+/**
+ * Get version information for the DRM user space library.
+ *
+ * This version number is driver independent.
+ *
+ * \param fd file descriptor.
+ *
+ * \return version information.
+ *
+ * \internal
+ * This function allocates and fills a drm_version structure with a hard coded
+ * version number.
+ */
+drmVersionPtr drmGetLibVersion(int fd)
+{
+ drm_version_t *version = drmMalloc(sizeof(*version));
+
+ /* Version history:
+ * revision 1.0.x = original DRM interface with no drmGetLibVersion
+ * entry point and many drm<Device> extensions
+ * revision 1.1.x = added drmCommand entry points for device extensions
+ * added drmGetLibVersion to identify libdrm.a version
+ * revision 1.2.x = added drmSetInterfaceVersion
+ * modified drmOpen to handle both busid and name
+ */
+ version->version_major = 1;
+ version->version_minor = 2;
+ version->version_patchlevel = 0;
+
+ return (drmVersionPtr)version;
+}
+
+
+/**
+ * Free the bus ID information.
+ *
+ * \param busid bus ID information string as given by drmGetBusid().
+ *
+ * \internal
+ * This function is just frees the memory pointed by \p busid.
+ */
+void drmFreeBusid(const char *busid)
+{
+ drmFree((void *)busid);
+}
+
+
+/**
+ * Get the bus ID of the device.
+ *
+ * \param fd file descriptor.
+ *
+ * \return bus ID string.
+ *
+ * \internal
+ * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
+ * get the string length and data, passing the arguments in a drm_unique
+ * structure.
+ */
+char *drmGetBusid(int fd)
+{
+ drm_unique_t u;
+
+ u.unique_len = 0;
+ u.unique = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+ u.unique = drmMalloc(u.unique_len + 1);
+ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+ u.unique[u.unique_len] = '\0';
+
+ return u.unique;
+}
+
+
+/**
+ * Set the bus ID of the device.
+ *
+ * \param fd file descriptor.
+ * \param busid bus ID string.
+ *
+ * \return zero on success, negative on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
+ * the arguments in a drm_unique structure.
+ */
+int drmSetBusid(int fd, const char *busid)
+{
+ drm_unique_t u;
+
+ u.unique = (char *)busid;
+ u.unique_len = strlen(busid);
+
+ if (ioctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) {
+ return -errno;
+ }
+ return 0;
+}
+
+int drmGetMagic(int fd, drm_magic_t * magic)
+{
+ drm_auth_t auth;
+
+ *magic = 0;
+ if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -errno;
+ *magic = auth.magic;
+ return 0;
+}
+
+int drmAuthMagic(int fd, drm_magic_t magic)
+{
+ drm_auth_t auth;
+
+ auth.magic = magic;
+ if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) return -errno;
+ return 0;
+}
+
+/**
+ * Specifies a range of memory that is available for mapping by a
+ * non-root process.
+ *
+ * \param fd file descriptor.
+ * \param offset usually the physical address. The actual meaning depends of
+ * the \p type parameter. See below.
+ * \param size of the memory in bytes.
+ * \param type type of the memory to be mapped.
+ * \param flags combination of several flags to modify the function actions.
+ * \param handle will be set to a value that may be used as the offset
+ * parameter for mmap().
+ *
+ * \return zero on success or a negative value on error.
+ *
+ * \par Mapping the frame buffer
+ * For the frame buffer
+ * - \p offset will be the physical address of the start of the frame buffer,
+ * - \p size will be the size of the frame buffer in bytes, and
+ * - \p type will be DRM_FRAME_BUFFER.
+ *
+ * \par
+ * The area mapped will be uncached. If MTRR support is available in the
+ * kernel, the frame buffer area will be set to write combining.
+ *
+ * \par Mapping the MMIO register area
+ * For the MMIO register area,
+ * - \p offset will be the physical address of the start of the register area,
+ * - \p size will be the size of the register area bytes, and
+ * - \p type will be DRM_REGISTERS.
+ * \par
+ * The area mapped will be uncached.
+ *
+ * \par Mapping the SAREA
+ * For the SAREA,
+ * - \p offset will be ignored and should be set to zero,
+ * - \p size will be the desired size of the SAREA in bytes,
+ * - \p type will be DRM_SHM.
+ *
+ * \par
+ * A shared memory area of the requested size will be created and locked in
+ * kernel memory. This area may be mapped into client-space by using the handle
+ * returned.
+ *
+ * \note May only be called by root.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
+ * the arguments in a drm_map structure.
+ */
+int drmAddMap(int fd,
+ drm_handle_t offset,
+ drmSize size,
+ drmMapType type,
+ drmMapFlags flags,
+ drm_handle_t * handle)
+{
+ drm_map_t map;
+
+ map.offset = offset;
+/* No longer needed with CVS kernel modules on alpha
+#ifdef __alpha__
+ if (type != DRM_SHM)
+ map.offset += BUS_BASE;
+#endif
+*/
+ map.size = size;
+ map.handle = 0;
+ map.type = type;
+ map.flags = flags;
+ if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map)) return -errno;
+ if (handle) *handle = (drm_handle_t)map.handle;
+ return 0;
+}
+
+int drmRmMap(int fd, drm_handle_t handle)
+{
+ drm_map_t map;
+
+ map.handle = (void *)handle;
+
+ if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno;
+ return 0;
+}
+
+/**
+ * Make buffers available for DMA transfers.
+ *
+ * \param fd file descriptor.
+ * \param count number of buffers.
+ * \param size size of each buffer.
+ * \param flags buffer allocation flags.
+ * \param agp_offset offset in the AGP aperture
+ *
+ * \return number of buffers allocated, negative on error.
+ *
+ * \internal
+ * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
+ *
+ * \sa drm_buf_desc.
+ */
+int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
+ int agp_offset)
+{
+ drm_buf_desc_t request;
+
+ request.count = count;
+ request.size = size;
+ request.low_mark = 0;
+ request.high_mark = 0;
+ request.flags = flags;
+ request.agp_start = agp_offset;
+
+ if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno;
+ return request.count;
+}
+
+int drmMarkBufs(int fd, double low, double high)
+{
+ drm_buf_info_t info;
+ int i;
+
+ info.count = 0;
+ info.list = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL;
+
+ if (!info.count) return -EINVAL;
+
+ if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
+ return -ENOMEM;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
+ int retval = -errno;
+ drmFree(info.list);
+ return retval;
+ }
+
+ for (i = 0; i < info.count; i++) {
+ info.list[i].low_mark = low * info.list[i].count;
+ info.list[i].high_mark = high * info.list[i].count;
+ if (ioctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
+ int retval = -errno;
+ drmFree(info.list);
+ return retval;
+ }
+ }
+ drmFree(info.list);
+
+ return 0;
+}
+
+/**
+ * Free buffers.
+ *
+ * \param fd file descriptor.
+ * \param count number of buffers to free.
+ * \param list list of buffers to be freed.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \note This function is primarily used for debugging.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
+ * the arguments in a drm_buf_free structure.
+ */
+int drmFreeBufs(int fd, int count, int *list)
+{
+ drm_buf_free_t request;
+
+ request.count = count;
+ request.list = list;
+ if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request)) return -errno;
+ return 0;
+}
+
+
+/**
+ * Close the device.
+ *
+ * \param fd file descriptor.
+ *
+ * \internal
+ * This function closes the file descriptor.
+ */
+int drmClose(int fd)
+{
+ unsigned long key = drmGetKeyFromFd(fd);
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ drmHashDestroy(entry->tagTable);
+ entry->fd = 0;
+ entry->f = NULL;
+ entry->tagTable = NULL;
+
+ drmHashDelete(drmHashTable, key);
+ drmFree(entry);
+
+ return close(fd);
+}
+
+
+/**
+ * Map a region of memory.
+ *
+ * \param fd file descriptor.
+ * \param handle handle returned by drmAddMap().
+ * \param size size in bytes. Must match the size used by drmAddMap().
+ * \param address will contain the user-space virtual address where the mapping
+ * begins.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper for mmap().
+ */
+int drmMap(int fd,
+ drm_handle_t handle,
+ drmSize size,
+ drmAddressPtr address)
+{
+ static unsigned long pagesize_mask = 0;
+
+ if (fd < 0) return -EINVAL;
+
+ if (!pagesize_mask)
+ pagesize_mask = getpagesize() - 1;
+
+ size = (size + pagesize_mask) & ~pagesize_mask;
+
+ *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
+ if (*address == MAP_FAILED) return -errno;
+ return 0;
+}
+
+
+/**
+ * Unmap mappings obtained with drmMap().
+ *
+ * \param address address as given by drmMap().
+ * \param size size in bytes. Must match the size used by drmMap().
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper for unmap().
+ */
+int drmUnmap(drmAddress address, drmSize size)
+{
+ return munmap(address, size);
+}
+
+drmBufInfoPtr drmGetBufInfo(int fd)
+{
+ drm_buf_info_t info;
+ drmBufInfoPtr retval;
+ int i;
+
+ info.count = 0;
+ info.list = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return NULL;
+
+ if (info.count) {
+ if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
+ return NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
+ drmFree(info.list);
+ return NULL;
+ }
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ retval->count = info.count;
+ retval->list = drmMalloc(info.count * sizeof(*retval->list));
+ for (i = 0; i < info.count; i++) {
+ retval->list[i].count = info.list[i].count;
+ retval->list[i].size = info.list[i].size;
+ retval->list[i].low_mark = info.list[i].low_mark;
+ retval->list[i].high_mark = info.list[i].high_mark;
+ }
+ drmFree(info.list);
+ return retval;
+ }
+ return NULL;
+}
+
+/**
+ * Map all DMA buffers into client-virtual space.
+ *
+ * \param fd file descriptor.
+ *
+ * \return a pointer to a ::drmBufMap structure.
+ *
+ * \note The client may not use these buffers until obtaining buffer indices
+ * with drmDMA().
+ *
+ * \internal
+ * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
+ * information about the buffers in a drm_buf_map structure into the
+ * client-visible data structures.
+ */
+drmBufMapPtr drmMapBufs(int fd)
+{
+ drm_buf_map_t bufs;
+ drmBufMapPtr retval;
+ int i;
+
+ bufs.count = 0;
+ bufs.list = NULL;
+ bufs.virtual = NULL;
+ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL;
+
+ if (!bufs.count) return NULL;
+
+ if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
+ return NULL;
+
+ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
+ drmFree(bufs.list);
+ return NULL;
+ }
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ retval->count = bufs.count;
+ retval->list = drmMalloc(bufs.count * sizeof(*retval->list));
+ for (i = 0; i < bufs.count; i++) {
+ retval->list[i].idx = bufs.list[i].idx;
+ retval->list[i].total = bufs.list[i].total;
+ retval->list[i].used = 0;
+ retval->list[i].address = bufs.list[i].address;
+ }
+
+ drmFree(bufs.list);
+
+ return retval;
+}
+
+
+/**
+ * Unmap buffers allocated with drmMapBufs().
+ *
+ * \return zero on success, or negative value on failure.
+ *
+ * \internal
+ * Calls munmap() for every buffer stored in \p bufs and frees the
+ * memory allocated by drmMapBufs().
+ */
+int drmUnmapBufs(drmBufMapPtr bufs)
+{
+ int i;
+
+ for (i = 0; i < bufs->count; i++) {
+ munmap(bufs->list[i].address, bufs->list[i].total);
+ }
+
+ drmFree(bufs->list);
+ drmFree(bufs);
+
+ return 0;
+}
+
+
+#define DRM_DMA_RETRY 16
+
+/**
+ * Reserve DMA buffers.
+ *
+ * \param fd file descriptor.
+ * \param request
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * Assemble the arguments into a drm_dma structure and keeps issuing the
+ * DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
+ */
+int drmDMA(int fd, drmDMAReqPtr request)
+{
+ drm_dma_t dma;
+ int ret, i = 0;
+
+ /* Copy to hidden structure */
+ dma.context = request->context;
+ dma.send_count = request->send_count;
+ dma.send_indices = request->send_list;
+ dma.send_sizes = request->send_sizes;
+ dma.flags = request->flags;
+ dma.request_count = request->request_count;
+ dma.request_size = request->request_size;
+ dma.request_indices = request->request_list;
+ dma.request_sizes = request->request_sizes;
+ dma.granted_count = 0;
+
+ do {
+ ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
+ } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
+
+ if ( ret == 0 ) {
+ request->granted_count = dma.granted_count;
+ return 0;
+ } else {
+ return -errno;
+ }
+}
+
+
+/**
+ * Obtain heavyweight hardware lock.
+ *
+ * \param fd file descriptor.
+ * \param context context.
+ * \param flags flags that determine the sate of the hardware when the function
+ * returns.
+ *
+ * \return always zero.
+ *
+ * \internal
+ * This function translates the arguments into a drm_lock structure and issue
+ * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
+ */
+int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
+ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+ if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
+ if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
+
+ while (ioctl(fd, DRM_IOCTL_LOCK, &lock))
+ ;
+ return 0;
+}
+
+/**
+ * Release the hardware lock.
+ *
+ * \param fd file descriptor.
+ * \param context context.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
+ * argument in a drm_lock structure.
+ */
+int drmUnlock(int fd, drm_context_t context)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ return ioctl(fd, DRM_IOCTL_UNLOCK, &lock);
+}
+
+drm_context_t * drmGetReservedContextList(int fd, int *count)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t *list;
+ drm_context_t * retval;
+ int i;
+
+ res.count = 0;
+ res.contexts = NULL;
+ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+
+ if (!res.count) return NULL;
+
+ if (!(list = drmMalloc(res.count * sizeof(*list)))) return NULL;
+ if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
+ drmFree(list);
+ return NULL;
+ }
+
+ res.contexts = list;
+ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+
+ for (i = 0; i < res.count; i++) retval[i] = list[i].handle;
+ drmFree(list);
+
+ *count = res.count;
+ return retval;
+}
+
+void drmFreeReservedContextList(drm_context_t * pt)
+{
+ drmFree(pt);
+}
+
+/**
+ * Create context.
+ *
+ * Used by the X server during GLXContext initialization. This causes
+ * per-context kernel-level resources to be allocated.
+ *
+ * \param fd file descriptor.
+ * \param handle is set on success. To be used by the client when requesting DMA
+ * dispatch with drmDMA().
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \note May only be called by root.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
+ * argument in a drm_ctx structure.
+ */
+int drmCreateContext(int fd, drm_context_t * handle)
+{
+ drm_ctx_t ctx;
+
+ ctx.flags = 0; /* Modified with functions below */
+ if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) return -errno;
+ *handle = ctx.handle;
+ return 0;
+}
+
+int drmSwitchToContext(int fd, drm_context_t context)
+{
+ drm_ctx_t ctx;
+
+ ctx.handle = context;
+ if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
+{
+ drm_ctx_t ctx;
+
+ /* Context preserving means that no context
+ switched are done between DMA buffers
+ from one context and the next. This is
+ suitable for use in the X server (which
+ promises to maintain hardware context,
+ or in the client-side library when
+ buffers are swapped on behalf of two
+ threads. */
+ ctx.handle = context;
+ ctx.flags = 0;
+ if (flags & DRM_CONTEXT_PRESERVED) ctx.flags |= _DRM_CONTEXT_PRESERVED;
+ if (flags & DRM_CONTEXT_2DONLY) ctx.flags |= _DRM_CONTEXT_2DONLY;
+ if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmGetContextFlags(int fd, drm_context_t context, drm_context_tFlagsPtr flags)
+{
+ drm_ctx_t ctx;
+
+ ctx.handle = context;
+ if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx)) return -errno;
+ *flags = 0;
+ if (ctx.flags & _DRM_CONTEXT_PRESERVED) *flags |= DRM_CONTEXT_PRESERVED;
+ if (ctx.flags & _DRM_CONTEXT_2DONLY) *flags |= DRM_CONTEXT_2DONLY;
+ return 0;
+}
+
+/**
+ * Destroy context.
+ *
+ * Free any kernel-level resources allocated with drmCreateContext() associated
+ * with the context.
+ *
+ * \param fd file descriptor.
+ * \param handle handle given by drmCreateContext().
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \note May only be called by root.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
+ * argument in a drm_ctx structure.
+ */
+int drmDestroyContext(int fd, drm_context_t handle)
+{
+ drm_ctx_t ctx;
+ ctx.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmCreateDrawable(int fd, drm_drawable_t * handle)
+{
+ drm_draw_t draw;
+ if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) return -errno;
+ *handle = draw.handle;
+ return 0;
+}
+
+int drmDestroyDrawable(int fd, drm_drawable_t handle)
+{
+ drm_draw_t draw;
+ draw.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw)) return -errno;
+ return 0;
+}
+
+/**
+ * Acquire the AGP device.
+ *
+ * Must be called before any of the other AGP related calls.
+ *
+ * \param fd file descriptor.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
+ */
+int drmAgpAcquire(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno;
+ return 0;
+}
+
+
+/**
+ * Release the AGP device.
+ *
+ * \param fd file descriptor.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
+ */
+int drmAgpRelease(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno;
+ return 0;
+}
+
+
+/**
+ * Set the AGP mode.
+ *
+ * \param fd file descriptor.
+ * \param mode AGP mode.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
+ * argument in a drm_agp_mode structure.
+ */
+int drmAgpEnable(int fd, unsigned long mode)
+{
+ drm_agp_mode_t m;
+
+ m.mode = mode;
+ if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno;
+ return 0;
+}
+
+
+/**
+ * Allocate a chunk of AGP memory.
+ *
+ * \param fd file descriptor.
+ * \param size requested memory size in bytes. Will be rounded to page boundary.
+ * \param type type of memory to allocate.
+ * \param address if not zero, will be set to the physical address of the
+ * allocated memory.
+ * \param handle on success will be set to a handle of the allocated memory.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
+ * arguments in a drm_agp_buffer structure.
+ */
+int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
+ unsigned long *address, unsigned long *handle)
+{
+ drm_agp_buffer_t b;
+
+ *handle = DRM_AGP_NO_HANDLE;
+ b.size = size;
+ b.handle = 0;
+ b.type = type;
+ if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno;
+ if (address != 0UL) *address = b.physical;
+ *handle = b.handle;
+ return 0;
+}
+
+
+/**
+ * Free a chunk of AGP memory.
+ *
+ * \param fd file descriptor.
+ * \param handle handle to the allocated memory, as given by drmAgpAllocate().
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
+ * argument in a drm_agp_buffer structure.
+ */
+int drmAgpFree(int fd, unsigned long handle)
+{
+ drm_agp_buffer_t b;
+
+ b.size = 0;
+ b.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno;
+ return 0;
+}
+
+
+/**
+ * Bind a chunk of AGP memory.
+ *
+ * \param fd file descriptor.
+ * \param handle handle to the allocated memory, as given by drmAgpAllocate().
+ * \param offset offset in bytes. It will round to page boundary.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
+ * argument in a drm_agp_binding structure.
+ */
+int drmAgpBind(int fd, unsigned long handle, unsigned long offset)
+{
+ drm_agp_binding_t b;
+
+ b.handle = handle;
+ b.offset = offset;
+ if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno;
+ return 0;
+}
+
+
+/**
+ * Unbind a chunk of AGP memory.
+ *
+ * \param fd file descriptor.
+ * \param handle handle to the allocated memory, as given by drmAgpAllocate().
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
+ * the argument in a drm_agp_binding structure.
+ */
+int drmAgpUnbind(int fd, unsigned long handle)
+{
+ drm_agp_binding_t b;
+
+ b.handle = handle;
+ b.offset = 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno;
+ return 0;
+}
+
+
+/**
+ * Get AGP driver major version number.
+ *
+ * \param fd file descriptor.
+ *
+ * \return major version number on success, or a negative value on failure..
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+int drmAgpVersionMajor(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+ return i.agp_version_major;
+}
+
+
+/**
+ * Get AGP driver minor version number.
+ *
+ * \param fd file descriptor.
+ *
+ * \return minor version number on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+int drmAgpVersionMinor(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+ return i.agp_version_minor;
+}
+
+
+/**
+ * Get AGP mode.
+ *
+ * \param fd file descriptor.
+ *
+ * \return mode on success, or zero on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+unsigned long drmAgpGetMode(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.mode;
+}
+
+
+/**
+ * Get AGP aperture base.
+ *
+ * \param fd file descriptor.
+ *
+ * \return aperture base on success, zero on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+unsigned long drmAgpBase(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.aperture_base;
+}
+
+
+/**
+ * Get AGP aperture size.
+ *
+ * \param fd file descriptor.
+ *
+ * \return aperture size on success, zero on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+unsigned long drmAgpSize(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.aperture_size;
+}
+
+
+/**
+ * Get used AGP memory.
+ *
+ * \param fd file descriptor.
+ *
+ * \return memory used on success, or zero on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+unsigned long drmAgpMemoryUsed(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.memory_used;
+}
+
+
+/**
+ * Get available AGP memory.
+ *
+ * \param fd file descriptor.
+ *
+ * \return memory available on success, or zero on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+unsigned long drmAgpMemoryAvail(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.memory_allowed;
+}
+
+
+/**
+ * Get hardware vendor ID.
+ *
+ * \param fd file descriptor.
+ *
+ * \return vendor ID on success, or zero on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+unsigned int drmAgpVendorId(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.id_vendor;
+}
+
+
+/**
+ * Get hardware device ID.
+ *
+ * \param fd file descriptor.
+ *
+ * \return zero on success, or zero on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
+ * necessary information in a drm_agp_info structure.
+ */
+unsigned int drmAgpDeviceId(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.id_device;
+}
+
+int drmScatterGatherAlloc(int fd, unsigned long size, unsigned long *handle)
+{
+ drm_scatter_gather_t sg;
+
+ *handle = 0;
+ sg.size = size;
+ sg.handle = 0;
+ if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) return -errno;
+ *handle = sg.handle;
+ return 0;
+}
+
+int drmScatterGatherFree(int fd, unsigned long handle)
+{
+ drm_scatter_gather_t sg;
+
+ sg.size = 0;
+ sg.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg)) return -errno;
+ return 0;
+}
+
+/**
+ * Wait for VBLANK.
+ *
+ * \param fd file descriptor.
+ * \param vbl pointer to a drmVBlank structure.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
+ */
+int drmWaitVBlank(int fd, drmVBlankPtr vbl)
+{
+ int ret;
+
+ do {
+ ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
+ vbl->request.type &= ~DRM_VBLANK_RELATIVE;
+ } while (ret && errno == EINTR);
+
+ return ret;
+}
+
+int drmError(int err, const char *label)
+{
+ switch (err) {
+ case DRM_ERR_NO_DEVICE: fprintf(stderr, "%s: no device\n", label); break;
+ case DRM_ERR_NO_ACCESS: fprintf(stderr, "%s: no access\n", label); break;
+ case DRM_ERR_NOT_ROOT: fprintf(stderr, "%s: not root\n", label); break;
+ case DRM_ERR_INVALID: fprintf(stderr, "%s: invalid args\n", label);break;
+ default:
+ if (err < 0) err = -err;
+ fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
+ break;
+ }
+
+ return 1;
+}
+
+/**
+ * Install IRQ handler.
+ *
+ * \param fd file descriptor.
+ * \param irq IRQ number.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
+ * argument in a drm_control structure.
+ */
+int drmCtlInstHandler(int fd, int irq)
+{
+ drm_control_t ctl;
+
+ ctl.func = DRM_INST_HANDLER;
+ ctl.irq = irq;
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ return 0;
+}
+
+
+/**
+ * Uninstall IRQ handler.
+ *
+ * \param fd file descriptor.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
+ * argument in a drm_control structure.
+ */
+int drmCtlUninstHandler(int fd)
+{
+ drm_control_t ctl;
+
+ ctl.func = DRM_UNINST_HANDLER;
+ ctl.irq = 0;
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ return 0;
+}
+
+int drmFinish(int fd, int context, drmLockFlags flags)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
+ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+ if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
+ if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
+ if (ioctl(fd, DRM_IOCTL_FINISH, &lock)) return -errno;
+ return 0;
+}
+
+/**
+ * Get IRQ from bus ID.
+ *
+ * \param fd file descriptor.
+ * \param busnum bus number.
+ * \param devnum device number.
+ * \param funcnum function number.
+ *
+ * \return IRQ number on success, or a negative value on failure.
+ *
+ * \internal
+ * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
+ * arguments in a drm_irq_busid structure.
+ */
+int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
+{
+ drm_irq_busid_t p;
+
+ p.busnum = busnum;
+ p.devnum = devnum;
+ p.funcnum = funcnum;
+ if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) return -errno;
+ return p.irq;
+}
+
+int drmAddContextTag(int fd, drm_context_t context, void *tag)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ if (drmHashInsert(entry->tagTable, context, tag)) {
+ drmHashDelete(entry->tagTable, context);
+ drmHashInsert(entry->tagTable, context, tag);
+ }
+ return 0;
+}
+
+int drmDelContextTag(int fd, drm_context_t context)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ return drmHashDelete(entry->tagTable, context);
+}
+
+void *drmGetContextTag(int fd, drm_context_t context)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+ void *value;
+
+ if (drmHashLookup(entry->tagTable, context, &value)) return NULL;
+
+ return value;
+}
+
+int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id, drm_handle_t handle)
+{
+ drm_ctx_priv_map_t map;
+
+ map.ctx_id = ctx_id;
+ map.handle = (void *)handle;
+
+ if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) return -errno;
+ return 0;
+}
+
+int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id, drm_handle_t * handle)
+{
+ drm_ctx_priv_map_t map;
+
+ map.ctx_id = ctx_id;
+
+ if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) return -errno;
+ if (handle) *handle = (drm_handle_t)map.handle;
+
+ return 0;
+}
+
+int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
+ drmMapType *type, drmMapFlags *flags, drm_handle_t *handle,
+ int *mtrr)
+{
+ drm_map_t map;
+
+ map.offset = idx;
+ if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno;
+ *offset = map.offset;
+ *size = map.size;
+ *type = map.type;
+ *flags = map.flags;
+ *handle = (unsigned long)map.handle;
+ *mtrr = map.mtrr;
+ return 0;
+}
+
+int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
+ unsigned long *magic, unsigned long *iocs)
+{
+ drm_client_t client;
+
+ client.idx = idx;
+ if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno;
+ *auth = client.auth;
+ *pid = client.pid;
+ *uid = client.uid;
+ *magic = client.magic;
+ *iocs = client.iocs;
+ return 0;
+}
+
+int drmGetStats(int fd, drmStatsT *stats)
+{
+ drm_stats_t s;
+ int i;
+
+ if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno;
+
+ stats->count = 0;
+ memset(stats, 0, sizeof(*stats));
+ if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
+ return -1;
+
+#define SET_VALUE \
+ stats->data[i].long_format = "%-20.20s"; \
+ stats->data[i].rate_format = "%8.8s"; \
+ stats->data[i].isvalue = 1; \
+ stats->data[i].verbose = 0
+
+#define SET_COUNT \
+ stats->data[i].long_format = "%-20.20s"; \
+ stats->data[i].rate_format = "%5.5s"; \
+ stats->data[i].isvalue = 0; \
+ stats->data[i].mult_names = "kgm"; \
+ stats->data[i].mult = 1000; \
+ stats->data[i].verbose = 0
+
+#define SET_BYTE \
+ stats->data[i].long_format = "%-20.20s"; \
+ stats->data[i].rate_format = "%5.5s"; \
+ stats->data[i].isvalue = 0; \
+ stats->data[i].mult_names = "KGM"; \
+ stats->data[i].mult = 1024; \
+ stats->data[i].verbose = 0
+
+
+ stats->count = s.count;
+ for (i = 0; i < s.count; i++) {
+ stats->data[i].value = s.data[i].value;
+ switch (s.data[i].type) {
+ case _DRM_STAT_LOCK:
+ stats->data[i].long_name = "Lock";
+ stats->data[i].rate_name = "Lock";
+ SET_VALUE;
+ break;
+ case _DRM_STAT_OPENS:
+ stats->data[i].long_name = "Opens";
+ stats->data[i].rate_name = "O";
+ SET_COUNT;
+ stats->data[i].verbose = 1;
+ break;
+ case _DRM_STAT_CLOSES:
+ stats->data[i].long_name = "Closes";
+ stats->data[i].rate_name = "Lock";
+ SET_COUNT;
+ stats->data[i].verbose = 1;
+ break;
+ case _DRM_STAT_IOCTLS:
+ stats->data[i].long_name = "Ioctls";
+ stats->data[i].rate_name = "Ioc/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_LOCKS:
+ stats->data[i].long_name = "Locks";
+ stats->data[i].rate_name = "Lck/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_UNLOCKS:
+ stats->data[i].long_name = "Unlocks";
+ stats->data[i].rate_name = "Unl/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_IRQ:
+ stats->data[i].long_name = "IRQs";
+ stats->data[i].rate_name = "IRQ/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_PRIMARY:
+ stats->data[i].long_name = "Primary Bytes";
+ stats->data[i].rate_name = "PB/s";
+ SET_BYTE;
+ break;
+ case _DRM_STAT_SECONDARY:
+ stats->data[i].long_name = "Secondary Bytes";
+ stats->data[i].rate_name = "SB/s";
+ SET_BYTE;
+ break;
+ case _DRM_STAT_DMA:
+ stats->data[i].long_name = "DMA";
+ stats->data[i].rate_name = "DMA/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_SPECIAL:
+ stats->data[i].long_name = "Special DMA";
+ stats->data[i].rate_name = "dma/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_MISSED:
+ stats->data[i].long_name = "Miss";
+ stats->data[i].rate_name = "Ms/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_VALUE:
+ stats->data[i].long_name = "Value";
+ stats->data[i].rate_name = "Value";
+ SET_VALUE;
+ break;
+ case _DRM_STAT_BYTE:
+ stats->data[i].long_name = "Bytes";
+ stats->data[i].rate_name = "B/s";
+ SET_BYTE;
+ break;
+ case _DRM_STAT_COUNT:
+ default:
+ stats->data[i].long_name = "Count";
+ stats->data[i].rate_name = "Cnt/s";
+ SET_COUNT;
+ break;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Issue a set-version ioctl.
+ *
+ * \param fd file descriptor.
+ * \param drmCommandIndex command index
+ * \param data source pointer of the data to be read and written.
+ * \param size size of the data to be read and written.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * It issues a read-write ioctl given by
+ * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
+ */
+int drmSetInterfaceVersion(int fd, drmSetVersion *version )
+{
+ int retcode = 0;
+ drm_set_version_t sv;
+
+ sv.drm_di_major = version->drm_di_major;
+ sv.drm_di_minor = version->drm_di_minor;
+ sv.drm_dd_major = version->drm_dd_major;
+ sv.drm_dd_minor = version->drm_dd_minor;
+
+ if (ioctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {
+ retcode = -errno;
+ }
+
+ version->drm_di_major = sv.drm_di_major;
+ version->drm_di_minor = sv.drm_di_minor;
+ version->drm_dd_major = sv.drm_dd_major;
+ version->drm_dd_minor = sv.drm_dd_minor;
+
+ return retcode;
+}
+
+/**
+ * Send a device-specific command.
+ *
+ * \param fd file descriptor.
+ * \param drmCommandIndex command index
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * It issues a ioctl given by
+ * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
+ */
+int drmCommandNone(int fd, unsigned long drmCommandIndex)
+{
+ void *data = NULL; /* dummy */
+ unsigned long request;
+
+ request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
+
+ if (ioctl(fd, request, data)) {
+ return -errno;
+ }
+ return 0;
+}
+
+
+/**
+ * Send a device-specific read command.
+ *
+ * \param fd file descriptor.
+ * \param drmCommandIndex command index
+ * \param data destination pointer of the data to be read.
+ * \param size size of the data to be read.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * It issues a read ioctl given by
+ * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
+ */
+int drmCommandRead(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size )
+{
+ unsigned long request;
+
+ request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE,
+ DRM_COMMAND_BASE + drmCommandIndex, size);
+
+ if (ioctl(fd, request, data)) {
+ return -errno;
+ }
+ return 0;
+}
+
+
+/**
+ * Send a device-specific write command.
+ *
+ * \param fd file descriptor.
+ * \param drmCommandIndex command index
+ * \param data source pointer of the data to be written.
+ * \param size size of the data to be written.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * It issues a write ioctl given by
+ * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
+ */
+int drmCommandWrite(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size )
+{
+ unsigned long request;
+
+ request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE,
+ DRM_COMMAND_BASE + drmCommandIndex, size);
+
+ if (ioctl(fd, request, data)) {
+ return -errno;
+ }
+ return 0;
+}
+
+
+/**
+ * Send a device-specific read-write command.
+ *
+ * \param fd file descriptor.
+ * \param drmCommandIndex command index
+ * \param data source pointer of the data to be read and written.
+ * \param size size of the data to be read and written.
+ *
+ * \return zero on success, or a negative value on failure.
+ *
+ * \internal
+ * It issues a read-write ioctl given by
+ * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
+ */
+int drmCommandWriteRead(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size )
+{
+ unsigned long request;
+
+ request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE,
+ DRM_COMMAND_BASE + drmCommandIndex, size);
+
+ if (ioctl(fd, request, data)) {
+ return -errno;
+ }
+ return 0;
+}
+
+#if defined(XFree86Server)
+static void drmSIGIOHandler(int interrupt, void *closure)
+{
+ unsigned long key;
+ void *value;
+ ssize_t count;
+ drm_ctx_t ctx;
+ typedef void (*_drmCallback)(int, void *, void *);
+ char buf[256];
+ drm_context_t old;
+ drm_context_t new;
+ void *oldctx;
+ void *newctx;
+ char *pt;
+ drmHashEntry *entry;
+
+ if (!drmHashTable) return;
+ if (drmHashFirst(drmHashTable, &key, &value)) {
+ entry = value;
+ do {
+#if 0
+ fprintf(stderr, "Trying %d\n", entry->fd);
+#endif
+ if ((count = read(entry->fd, buf, sizeof(buf))) > 0) {
+ buf[count] = '\0';
+#if 0
+ fprintf(stderr, "Got %s\n", buf);
+#endif
+
+ for (pt = buf; *pt != ' '; ++pt); /* Find first space */
+ ++pt;
+ old = strtol(pt, &pt, 0);
+ new = strtol(pt, NULL, 0);
+ oldctx = drmGetContextTag(entry->fd, old);
+ newctx = drmGetContextTag(entry->fd, new);
+#if 0
+ fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
+#endif
+ ((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
+ ctx.handle = new;
+ ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
+ }
+ } while (drmHashNext(drmHashTable, &key, &value));
+ }
+}
+
+int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
+{
+ drmHashEntry *entry;
+
+ entry = drmGetEntry(fd);
+ entry->f = f;
+
+ return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0);
+}
+
+int drmRemoveSIGIOHandler(int fd)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ entry->f = NULL;
+
+ return xf86RemoveSIGIOHandler(fd);
+}
+#endif
diff --git a/src/mesa/drivers/dri/dri_client/xf86drmHash.c b/src/mesa/drivers/dri/dri_client/xf86drmHash.c
new file mode 100644
index 00000000000..5f89d540dc2
--- /dev/null
+++ b/src/mesa/drivers/dri/dri_client/xf86drmHash.c
@@ -0,0 +1,433 @@
+/* xf86drmHash.c -- Small hash table support for integer -> integer mapping
+ * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.4 2001/03/21 18:08:54 dawes Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a straightforward implementation of a fixed-sized
+ * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for
+ * collision resolution. There are two potentially interesting things
+ * about this implementation:
+ *
+ * 1) The table is power-of-two sized. Prime sized tables are more
+ * traditional, but do not have a significant advantage over power-of-two
+ * sized table, especially when double hashing is not used for collision
+ * resolution.
+ *
+ * 2) The hash computation uses a table of random integers [Hanson97,
+ * pp. 39-41].
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * With a table size of 512, the current implementation is sufficient for a
+ * few hundred keys. Since this is well above the expected size of the
+ * tables for which this implementation was designed, the implementation of
+ * dynamic hash tables was postponed until the need arises. A common (and
+ * naive) approach to dynamic hash table implementation simply creates a
+ * new hash table when necessary, rehashes all the data into the new table,
+ * and destroys the old table. The approach in [Larson88] is superior in
+ * two ways: 1) only a portion of the table is expanded when needed,
+ * distributing the expansion cost over several insertions, and 2) portions
+ * of the table can be locked, enabling a scalable thread-safe
+ * implementation.
+ *
+ * REFERENCES
+ *
+ * [Hanson97] David R. Hanson. C Interfaces and Implementations:
+ * Techniques for Creating Reusable Software. Reading, Massachusetts:
+ * Addison-Wesley, 1997.
+ *
+ * [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3:
+ * Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973.
+ *
+ * [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April
+ * 1988, pp. 446-457.
+ *
+ */
+
+#define HASH_MAIN 0
+
+#if HASH_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define HASH_MAGIC 0xdeadbeef
+#define HASH_DEBUG 0
+#define HASH_SIZE 512 /* Good for about 100 entries */
+ /* If you change this value, you probably
+ have to change the HashHash hashing
+ function! */
+
+#if HASH_MAIN
+#define HASH_ALLOC malloc
+#define HASH_FREE free
+#define HASH_RANDOM_DECL
+#define HASH_RANDOM_INIT(seed) srandom(seed)
+#define HASH_RANDOM random()
+#else
+#define HASH_ALLOC drmMalloc
+#define HASH_FREE drmFree
+#define HASH_RANDOM_DECL void *state
+#define HASH_RANDOM_INIT(seed) state = drmRandomCreate(seed)
+#define HASH_RANDOM drmRandom(state)
+
+#endif
+
+typedef struct HashBucket {
+ unsigned long key;
+ void *value;
+ struct HashBucket *next;
+} HashBucket, *HashBucketPtr;
+
+typedef struct HashTable {
+ unsigned long magic;
+ unsigned long entries;
+ unsigned long hits; /* At top of linked list */
+ unsigned long partials; /* Not at top of linked list */
+ unsigned long misses; /* Not in table */
+ HashBucketPtr buckets[HASH_SIZE];
+ int p0;
+ HashBucketPtr p1;
+} HashTable, *HashTablePtr;
+
+#if HASH_MAIN
+extern void *drmHashCreate(void);
+extern int drmHashDestroy(void *t);
+extern int drmHashLookup(void *t, unsigned long key, unsigned long *value);
+extern int drmHashInsert(void *t, unsigned long key, unsigned long value);
+extern int drmHashDelete(void *t, unsigned long key);
+#endif
+
+static unsigned long HashHash(unsigned long key)
+{
+ unsigned long hash = 0;
+ unsigned long tmp = key;
+ static int init = 0;
+ static unsigned long scatter[256];
+ int i;
+
+ if (!init) {
+ HASH_RANDOM_DECL;
+ HASH_RANDOM_INIT(37);
+ for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
+ ++init;
+ }
+
+ while (tmp) {
+ hash = (hash << 1) + scatter[tmp & 0xff];
+ tmp >>= 8;
+ }
+
+ hash %= HASH_SIZE;
+#if HASH_DEBUG
+ printf( "Hash(%d) = %d\n", key, hash);
+#endif
+ return hash;
+}
+
+void *drmHashCreate(void)
+{
+ HashTablePtr table;
+ int i;
+
+ table = HASH_ALLOC(sizeof(*table));
+ if (!table) return NULL;
+ table->magic = HASH_MAGIC;
+ table->entries = 0;
+ table->hits = 0;
+ table->partials = 0;
+ table->misses = 0;
+
+ for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
+ return table;
+}
+
+int drmHashDestroy(void *t)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+ HashBucketPtr next;
+ int i;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ for (i = 0; i < HASH_SIZE; i++) {
+ for (bucket = table->buckets[i]; bucket;) {
+ next = bucket->next;
+ HASH_FREE(bucket);
+ bucket = next;
+ }
+ }
+ HASH_FREE(table);
+ return 0;
+}
+
+/* Find the bucket and organize the list so that this bucket is at the
+ top. */
+
+static HashBucketPtr HashFind(HashTablePtr table,
+ unsigned long key, unsigned long *h)
+{
+ unsigned long hash = HashHash(key);
+ HashBucketPtr prev = NULL;
+ HashBucketPtr bucket;
+
+ if (h) *h = hash;
+
+ for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
+ if (bucket->key == key) {
+ if (prev) {
+ /* Organize */
+ prev->next = bucket->next;
+ bucket->next = table->buckets[hash];
+ table->buckets[hash] = bucket;
+ ++table->partials;
+ } else {
+ ++table->hits;
+ }
+ return bucket;
+ }
+ prev = bucket;
+ }
+ ++table->misses;
+ return NULL;
+}
+
+int drmHashLookup(void *t, unsigned long key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+
+ if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ bucket = HashFind(table, key, NULL);
+ if (!bucket) return 1; /* Not found */
+ *value = bucket->value;
+ return 0; /* Found */
+}
+
+int drmHashInsert(void *t, unsigned long key, void *value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+ unsigned long hash;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ if (HashFind(table, key, &hash)) return 1; /* Already in table */
+
+ bucket = HASH_ALLOC(sizeof(*bucket));
+ if (!bucket) return -1; /* Error */
+ bucket->key = key;
+ bucket->value = value;
+ bucket->next = table->buckets[hash];
+ table->buckets[hash] = bucket;
+#if HASH_DEBUG
+ printf("Inserted %d at %d/%p\n", key, hash, bucket);
+#endif
+ return 0; /* Added to table */
+}
+
+int drmHashDelete(void *t, unsigned long key)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ unsigned long hash;
+ HashBucketPtr bucket;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ bucket = HashFind(table, key, &hash);
+
+ if (!bucket) return 1; /* Not found */
+
+ table->buckets[hash] = bucket->next;
+ HASH_FREE(bucket);
+ return 0;
+}
+
+int drmHashNext(void *t, unsigned long *key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+
+ for (; table->p0 < HASH_SIZE;
+ ++table->p0, table->p1 = table->buckets[table->p0]) {
+ if (table->p1) {
+ *key = table->p1->key;
+ *value = table->p1->value;
+ table->p1 = table->p1->next;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int drmHashFirst(void *t, unsigned long *key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ table->p0 = 0;
+ table->p1 = table->buckets[0];
+ return drmHashNext(table, key, value);
+}
+
+#if HASH_MAIN
+#define DIST_LIMIT 10
+static int dist[DIST_LIMIT];
+
+static void clear_dist(void) {
+ int i;
+
+ for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
+}
+
+static int count_entries(HashBucketPtr bucket)
+{
+ int count = 0;
+
+ for (; bucket; bucket = bucket->next) ++count;
+ return count;
+}
+
+static void update_dist(int count)
+{
+ if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
+ else ++dist[count];
+}
+
+static void compute_dist(HashTablePtr table)
+{
+ int i;
+ HashBucketPtr bucket;
+
+ printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
+ table->entries, table->hits, table->partials, table->misses);
+ clear_dist();
+ for (i = 0; i < HASH_SIZE; i++) {
+ bucket = table->buckets[i];
+ update_dist(count_entries(bucket));
+ }
+ for (i = 0; i < DIST_LIMIT; i++) {
+ if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
+ else printf("other %10d\n", dist[i]);
+ }
+}
+
+static void check_table(HashTablePtr table,
+ unsigned long key, unsigned long value)
+{
+ unsigned long retval = 0;
+ int retcode = drmHashLookup(table, key, &retval);
+
+ switch (retcode) {
+ case -1:
+ printf("Bad magic = 0x%08lx:"
+ " key = %lu, expected = %lu, returned = %lu\n",
+ table->magic, key, value, retval);
+ break;
+ case 1:
+ printf("Not found: key = %lu, expected = %lu returned = %lu\n",
+ key, value, retval);
+ break;
+ case 0:
+ if (value != retval)
+ printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
+ key, value, retval);
+ break;
+ default:
+ printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
+ retcode, key, value, retval);
+ break;
+ }
+}
+
+int main(void)
+{
+ HashTablePtr table;
+ int i;
+
+ printf("\n***** 256 consecutive integers ****\n");
+ table = drmHashCreate();
+ for (i = 0; i < 256; i++) drmHashInsert(table, i, i);
+ for (i = 0; i < 256; i++) check_table(table, i, i);
+ for (i = 256; i >= 0; i--) check_table(table, i, i);
+ compute_dist(table);
+ drmHashDestroy(table);
+
+ printf("\n***** 1024 consecutive integers ****\n");
+ table = drmHashCreate();
+ for (i = 0; i < 1024; i++) drmHashInsert(table, i, i);
+ for (i = 0; i < 1024; i++) check_table(table, i, i);
+ for (i = 1024; i >= 0; i--) check_table(table, i, i);
+ compute_dist(table);
+ drmHashDestroy(table);
+
+ printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
+ table = drmHashCreate();
+ for (i = 0; i < 1024; i++) drmHashInsert(table, i*4096, i);
+ for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
+ for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
+ compute_dist(table);
+ drmHashDestroy(table);
+
+ printf("\n***** 1024 random integers ****\n");
+ table = drmHashCreate();
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) drmHashInsert(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) check_table(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) check_table(table, random(), i);
+ compute_dist(table);
+ drmHashDestroy(table);
+
+ printf("\n***** 5000 random integers ****\n");
+ table = drmHashCreate();
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) drmHashInsert(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) check_table(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) check_table(table, random(), i);
+ compute_dist(table);
+ drmHashDestroy(table);
+
+ return 0;
+}
+#endif
diff --git a/src/mesa/drivers/dri/dri_client/xf86drmRandom.c b/src/mesa/drivers/dri/dri_client/xf86drmRandom.c
new file mode 100644
index 00000000000..cca831d7517
--- /dev/null
+++ b/src/mesa/drivers/dri/dri_client/xf86drmRandom.c
@@ -0,0 +1,217 @@
+/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation
+ * Created: Mon Apr 19 08:28:13 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.4 2000/06/17 00:03:34 martin Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a simple, straightforward implementation of the Park
+ * & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer
+ * multiplicative linear congruential generator (MLCG) with a period of
+ * 2^31-1.
+ *
+ * This implementation is intended to provide a reliable, portable PRNG
+ * that is suitable for testing a hash table implementation and for
+ * implementing skip lists.
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * If initial seeds are not selected randomly, two instances of the PRNG
+ * can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique
+ * that can eliminate this problem.
+ *
+ * If PRNGs are used for simulation, the period of the current
+ * implementation may be too short. [LE88] discusses methods of combining
+ * MLCGs to produce much longer periods, and suggests some alternative
+ * values for A and M. [LE90 and Sch92] also provide information on
+ * long-period PRNGs.
+ *
+ * REFERENCES
+ *
+ * [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2:
+ * Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981.
+ *
+ * [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number
+ * Generators". CACM 31(6), June 1988, pp. 742-774.
+ *
+ * [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10,
+ * October 1990, pp. 85-97.
+ *
+ * [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators:
+ * Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201.
+ *
+ * [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit
+ * CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40.
+ *
+ * [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In
+ * "Technical Correspondence: Remarks on Choosing and Implementing Random
+ * Number Generators". CACM 36(7), July 1993, pp. 105-110.
+ *
+ */
+
+#define RANDOM_MAIN 0
+
+#if RANDOM_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define RANDOM_MAGIC 0xfeedbeef
+#define RANDOM_DEBUG 0
+
+#if RANDOM_MAIN
+#define RANDOM_ALLOC malloc
+#define RANDOM_FREE free
+#else
+#define RANDOM_ALLOC drmMalloc
+#define RANDOM_FREE drmFree
+#endif
+
+typedef struct RandomState {
+ unsigned long magic;
+ unsigned long a;
+ unsigned long m;
+ unsigned long q; /* m div a */
+ unsigned long r; /* m mod a */
+ unsigned long check;
+ long seed;
+} RandomState;
+
+#if RANDOM_MAIN
+extern void *drmRandomCreate(unsigned long seed);
+extern int drmRandomDestroy(void *state);
+extern unsigned long drmRandom(void *state);
+extern double drmRandomDouble(void *state);
+#endif
+
+void *drmRandomCreate(unsigned long seed)
+{
+ RandomState *state;
+
+ state = RANDOM_ALLOC(sizeof(*state));
+ if (!state) return NULL;
+ state->magic = RANDOM_MAGIC;
+#if 0
+ /* Park & Miller, October 1988 */
+ state->a = 16807;
+ state->m = 2147483647;
+ state->check = 1043618065; /* After 10000 iterations */
+#else
+ /* Park, Miller, and Stockmeyer, July 1993 */
+ state->a = 48271;
+ state->m = 2147483647;
+ state->check = 399268537; /* After 10000 iterations */
+#endif
+ state->q = state->m / state->a;
+ state->r = state->m % state->a;
+
+ state->seed = seed;
+ /* Check for illegal boundary conditions,
+ and choose closest legal value. */
+ if (state->seed <= 0) state->seed = 1;
+ if (state->seed >= state->m) state->seed = state->m - 1;
+
+ return state;
+}
+
+int drmRandomDestroy(void *state)
+{
+ RANDOM_FREE(state);
+ return 0;
+}
+
+unsigned long drmRandom(void *state)
+{
+ RandomState *s = (RandomState *)state;
+ long hi;
+ long lo;
+
+ hi = s->seed / s->q;
+ lo = s->seed % s->q;
+ s->seed = s->a * lo - s->r * hi;
+ if (s->seed <= 0) s->seed += s->m;
+
+ return s->seed;
+}
+
+double drmRandomDouble(void *state)
+{
+ RandomState *s = (RandomState *)state;
+
+ return (double)drmRandom(state)/(double)s->m;
+}
+
+#if RANDOM_MAIN
+static void check_period(long seed)
+{
+ unsigned long count = 0;
+ unsigned long initial;
+ void *state;
+
+ state = drmRandomCreate(seed);
+ initial = drmRandom(state);
+ ++count;
+ while (initial != drmRandom(state)) {
+ if (!++count) break;
+ }
+ printf("With seed of %10ld, period = %10lu (0x%08lx)\n",
+ seed, count, count);
+ drmRandomDestroy(state);
+}
+
+int main(void)
+{
+ RandomState *state;
+ int i;
+ unsigned long rand;
+
+ state = drmRandomCreate(1);
+ for (i = 0; i < 10000; i++) {
+ rand = drmRandom(state);
+ }
+ printf("After 10000 iterations: %lu (%lu expected): %s\n",
+ rand, state->check,
+ rand - state->check ? "*INCORRECT*" : "CORRECT");
+ drmRandomDestroy(state);
+
+ printf("Checking periods...\n");
+ check_period(1);
+ check_period(2);
+ check_period(31415926);
+
+ return 0;
+}
+#endif
diff --git a/src/mesa/drivers/dri/dri_client/xf86drmSL.c b/src/mesa/drivers/dri/dri_client/xf86drmSL.c
new file mode 100644
index 00000000000..a9d64c920f0
--- /dev/null
+++ b/src/mesa/drivers/dri/dri_client/xf86drmSL.c
@@ -0,0 +1,488 @@
+/* xf86drmSL.c -- Skip list support
+ * Created: Mon May 10 09:28:13 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.3 2000/06/17 00:03:34 martin Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a straightforward skip list implementation.n
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * REFERENCES
+ *
+ * [Pugh90] William Pugh. Skip Lists: A Probabilistic Alternative to
+ * Balanced Trees. CACM 33(6), June 1990, pp. 668-676.
+ *
+ */
+
+#define SL_MAIN 0
+
+#if SL_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+# include <sys/time.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define SL_LIST_MAGIC 0xfacade00LU
+#define SL_ENTRY_MAGIC 0x00fab1edLU
+#define SL_FREED_MAGIC 0xdecea5edLU
+#define SL_MAX_LEVEL 16
+#define SL_DEBUG 0
+#define SL_RANDOM_SEED 0xc01055a1LU
+
+#if SL_MAIN
+#define SL_ALLOC malloc
+#define SL_FREE free
+#define SL_RANDOM_DECL static int state = 0;
+#define SL_RANDOM_INIT(seed) if (!state) { srandom(seed); ++state; }
+#define SL_RANDOM random()
+#else
+#define SL_ALLOC drmMalloc
+#define SL_FREE drmFree
+#define SL_RANDOM_DECL static void *state = NULL
+#define SL_RANDOM_INIT(seed) if (!state) state = drmRandomCreate(seed)
+#define SL_RANDOM drmRandom(state)
+
+#endif
+
+typedef struct SLEntry {
+ unsigned long magic; /* SL_ENTRY_MAGIC */
+ unsigned long key;
+ void *value;
+ int levels;
+ struct SLEntry *forward[1]; /* variable sized array */
+} SLEntry, *SLEntryPtr;
+
+typedef struct SkipList {
+ unsigned long magic; /* SL_LIST_MAGIC */
+ int level;
+ int count;
+ SLEntryPtr head;
+ SLEntryPtr p0; /* Position for iteration */
+} SkipList, *SkipListPtr;
+
+#if SL_MAIN
+extern void *drmSLCreate(void);
+extern int drmSLDestroy(void *l);
+extern int drmSLLookup(void *l, unsigned long key, void **value);
+extern int drmSLInsert(void *l, unsigned long key, void *value);
+extern int drmSLDelete(void *l, unsigned long key);
+extern int drmSLNext(void *l, unsigned long *key, void **value);
+extern int drmSLFirst(void *l, unsigned long *key, void **value);
+extern void drmSLDump(void *l);
+extern int drmSLLookupNeighbors(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value);
+#endif
+
+static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value)
+{
+ SLEntryPtr entry;
+
+ if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL;
+
+ entry = SL_ALLOC(sizeof(*entry)
+ + (max_level + 1) * sizeof(entry->forward[0]));
+ if (!entry) return NULL;
+ entry->magic = SL_ENTRY_MAGIC;
+ entry->key = key;
+ entry->value = value;
+ entry->levels = max_level + 1;
+
+ return entry;
+}
+
+static int SLRandomLevel(void)
+{
+ int level = 1;
+ SL_RANDOM_DECL;
+
+ SL_RANDOM_INIT(SL_RANDOM_SEED);
+
+ while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level;
+ return level;
+}
+
+void *drmSLCreate(void)
+{
+ SkipListPtr list;
+ int i;
+
+ list = SL_ALLOC(sizeof(*list));
+ if (!list) return NULL;
+ list->magic = SL_LIST_MAGIC;
+ list->level = 0;
+ list->head = SLCreateEntry(SL_MAX_LEVEL, 0, NULL);
+ list->count = 0;
+
+ for (i = 0; i <= SL_MAX_LEVEL; i++) list->head->forward[i] = NULL;
+
+ return list;
+}
+
+int drmSLDestroy(void *l)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ SLEntryPtr next;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ for (entry = list->head; entry; entry = next) {
+ if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */
+ next = entry->forward[0];
+ entry->magic = SL_FREED_MAGIC;
+ SL_FREE(entry);
+ }
+
+ list->magic = SL_FREED_MAGIC;
+ SL_FREE(list);
+ return 0;
+}
+
+static SLEntryPtr SLLocate(void *l, unsigned long key, SLEntryPtr *update)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return NULL;
+
+ for (i = list->level, entry = list->head; i >= 0; i--) {
+ while (entry->forward[i] && entry->forward[i]->key < key)
+ entry = entry->forward[i];
+ update[i] = entry;
+ }
+
+ return entry->forward[0];
+}
+
+int drmSLInsert(void *l, unsigned long key, void *value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ int level;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = SLLocate(list, key, update);
+
+ if (entry && entry->key == key) return 1; /* Already in list */
+
+
+ level = SLRandomLevel();
+ if (level > list->level) {
+ level = ++list->level;
+ update[level] = list->head;
+ }
+
+ entry = SLCreateEntry(level, key, value);
+
+ /* Fix up forward pointers */
+ for (i = 0; i <= level; i++) {
+ entry->forward[i] = update[i]->forward[i];
+ update[i]->forward[i] = entry;
+ }
+
+ ++list->count;
+ return 0; /* Added to table */
+}
+
+int drmSLDelete(void *l, unsigned long key)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = SLLocate(list, key, update);
+
+ if (!entry || entry->key != key) return 1; /* Not found */
+
+ /* Fix up forward pointers */
+ for (i = 0; i <= list->level; i++) {
+ if (update[i]->forward[i] == entry)
+ update[i]->forward[i] = entry->forward[i];
+ }
+
+ entry->magic = SL_FREED_MAGIC;
+ SL_FREE(entry);
+
+ while (list->level && !list->head->forward[list->level]) --list->level;
+ --list->count;
+ return 0;
+}
+
+int drmSLLookup(void *l, unsigned long key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+
+ entry = SLLocate(list, key, update);
+
+ if (entry && entry->key == key) {
+ *value = entry;
+ return 0;
+ }
+ *value = NULL;
+ return -1;
+}
+
+int drmSLLookupNeighbors(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+ int retcode = 0;
+
+ entry = SLLocate(list, key, update);
+
+ *prev_key = *next_key = key;
+ *prev_value = *next_value = NULL;
+
+ if (update[0]) {
+ *prev_key = update[0]->key;
+ *prev_value = update[0]->value;
+ ++retcode;
+ if (update[0]->forward[0]) {
+ *next_key = update[0]->forward[0]->key;
+ *next_value = update[0]->forward[0]->value;
+ ++retcode;
+ }
+ }
+ return retcode;
+}
+
+int drmSLNext(void *l, unsigned long *key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = list->p0;
+
+ if (entry) {
+ list->p0 = entry->forward[0];
+ *key = entry->key;
+ *value = entry->value;
+ return 1;
+ }
+ list->p0 = NULL;
+ return 0;
+}
+
+int drmSLFirst(void *l, unsigned long *key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ list->p0 = list->head->forward[0];
+ return drmSLNext(list, key, value);
+}
+
+/* Dump internal data structures for debugging. */
+void drmSLDump(void *l)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) {
+ printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
+ list->magic, SL_LIST_MAGIC);
+ return;
+ }
+
+ printf("Level = %d, count = %d\n", list->level, list->count);
+ for (entry = list->head; entry; entry = entry->forward[0]) {
+ if (entry->magic != SL_ENTRY_MAGIC) {
+ printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
+ list->magic, SL_ENTRY_MAGIC);
+ }
+ printf("\nEntry %p <0x%08lx, %p> has %2d levels\n",
+ entry, entry->key, entry->value, entry->levels);
+ for (i = 0; i < entry->levels; i++) {
+ if (entry->forward[i]) {
+ printf(" %2d: %p <0x%08lx, %p>\n",
+ i,
+ entry->forward[i],
+ entry->forward[i]->key,
+ entry->forward[i]->value);
+ } else {
+ printf(" %2d: %p\n", i, entry->forward[i]);
+ }
+ }
+ }
+}
+
+#if SL_MAIN
+static void print(SkipListPtr list)
+{
+ unsigned long key;
+ void *value;
+
+ if (drmSLFirst(list, &key, &value)) {
+ do {
+ printf("key = %5lu, value = %p\n", key, value);
+ } while (drmSLNext(list, &key, &value));
+ }
+}
+
+static double do_time(int size, int iter)
+{
+ SkipListPtr list;
+ int i, j;
+ unsigned long keys[1000000];
+ unsigned long previous;
+ unsigned long key;
+ void *value;
+ struct timeval start, stop;
+ double usec;
+ SL_RANDOM_DECL;
+
+ SL_RANDOM_INIT(12345);
+
+ list = drmSLCreate();
+
+ for (i = 0; i < size; i++) {
+ keys[i] = SL_RANDOM;
+ drmSLInsert(list, keys[i], NULL);
+ }
+
+ previous = 0;
+ if (drmSLFirst(list, &key, &value)) {
+ do {
+ if (key <= previous) {
+ printf( "%lu !< %lu\n", previous, key);
+ }
+ previous = key;
+ } while (drmSLNext(list, &key, &value));
+ }
+
+ gettimeofday(&start, NULL);
+ for (j = 0; j < iter; j++) {
+ for (i = 0; i < size; i++) {
+ if (drmSLLookup(list, keys[i], &value))
+ printf("Error %lu %d\n", keys[i], i);
+ }
+ }
+ gettimeofday(&stop, NULL);
+
+ usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
+ - start.tv_sec * 1000000 - start.tv_usec) / (size * iter);
+
+ printf("%0.2f microseconds for list length %d\n", usec, size);
+
+ drmSLDestroy(list);
+
+ return usec;
+}
+
+static void print_neighbors(void *list, unsigned long key)
+{
+ unsigned long prev_key = 0;
+ unsigned long next_key = 0;
+ void *prev_value;
+ void *next_value;
+ int retval;
+
+ retval = drmSLLookupNeighbors(list, key,
+ &prev_key, &prev_value,
+ &next_key, &next_value);
+ printf("Neighbors of %5lu: %d %5lu %5lu\n",
+ key, retval, prev_key, next_key);
+}
+
+int main(void)
+{
+ SkipListPtr list;
+ double usec, usec2, usec3, usec4;
+
+ list = drmSLCreate();
+ printf( "list at %p\n", list);
+
+ print(list);
+ printf("\n==============================\n\n");
+
+ drmSLInsert(list, 123, NULL);
+ drmSLInsert(list, 213, NULL);
+ drmSLInsert(list, 50, NULL);
+ print(list);
+ printf("\n==============================\n\n");
+
+ print_neighbors(list, 0);
+ print_neighbors(list, 50);
+ print_neighbors(list, 51);
+ print_neighbors(list, 123);
+ print_neighbors(list, 200);
+ print_neighbors(list, 213);
+ print_neighbors(list, 256);
+ printf("\n==============================\n\n");
+
+ drmSLDelete(list, 50);
+ print(list);
+ printf("\n==============================\n\n");
+
+ drmSLDump(list);
+ drmSLDestroy(list);
+ printf("\n==============================\n\n");
+
+ usec = do_time(100, 10000);
+ usec2 = do_time(1000, 500);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 1000.0/100.0, usec2 / usec);
+
+ usec3 = do_time(10000, 50);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 10000.0/100.0, usec3 / usec);
+
+ usec4 = do_time(100000, 4);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 100000.0/100.0, usec4 / usec);
+
+ return 0;
+}
+#endif
diff --git a/src/mesa/drivers/dri/ffb/ffb_vtxfmt.c b/src/mesa/drivers/dri/ffb/ffb_vtxfmt.c
index d6a61d98e52..9c1b770fbd1 100644
--- a/src/mesa/drivers/dri/ffb/ffb_vtxfmt.c
+++ b/src/mesa/drivers/dri/ffb/ffb_vtxfmt.c
@@ -341,7 +341,8 @@ void ffbInitTnlModule(GLcontext *ctx)
ffb_init_norm_funcs();
ffb_init_vert_funcs();
- MEMSET(vfmt, 0, sizeof(GLvertexformat));
+ /* start by initializing to no-op functions */
+ _mesa_noop_vtxfmt_init(vfmt);
/* Handled fully in supported states: */
vfmt->ArrayElement = NULL; /* FIXME: ... */
@@ -389,18 +390,8 @@ void ffbInitTnlModule(GLcontext *ctx)
vfmt->Begin = ffb_Begin;
vfmt->End = ffb_End;
- vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
-
vfmt->DrawArrays = NULL;
vfmt->DrawElements = NULL;
- vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements; /* discard range */
-
-
- /* Not active in supported states; just keep ctx->Current uptodate: */
- vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
- vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
- vfmt->Indexi = _mesa_noop_Indexi;
- vfmt->Indexiv = _mesa_noop_Indexiv;
/* Active but unsupported -- fallback if we receive these:
*
diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c
index a622051eddf..23373ef73b1 100644
--- a/src/mesa/drivers/dri/i810/i810context.c
+++ b/src/mesa/drivers/dri/i810/i810context.c
@@ -133,6 +133,7 @@ const struct dri_extension card_extensions[] =
{ "GL_EXT_texture_edge_clamp", NULL },
{ "GL_EXT_texture_env_combine", NULL },
{ "GL_EXT_texture_lod_bias", NULL },
+ { "GL_EXT_texture_rectangle", NULL },
{ "GL_MESA_ycbcr_texture", NULL },
{ "GL_NV_blend_square", NULL },
{ "GL_SGIS_generate_mipmap", NULL },
diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c
index a79c3a3e4df..680b818d286 100644
--- a/src/mesa/drivers/dri/i810/i810state.c
+++ b/src/mesa/drivers/dri/i810/i810state.c
@@ -597,6 +597,7 @@ static void i810Enable(GLcontext *ctx, GLenum cap, GLboolean state)
imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
break;
case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_NV:
I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
if (ctx->Texture.CurrentUnit == 0) {
imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE;
diff --git a/src/mesa/drivers/dri/i810/i810texstate.c b/src/mesa/drivers/dri/i810/i810texstate.c
index 5133ea44d4b..558aef9eee4 100644
--- a/src/mesa/drivers/dri/i810/i810texstate.c
+++ b/src/mesa/drivers/dri/i810/i810texstate.c
@@ -115,8 +115,6 @@ static void i810SetTexImages( i810ContextPtr imesa,
t->max_level = i-1;
t->dirty = I810_UPLOAD_TEX0 | I810_UPLOAD_TEX1;
t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 | textureFormat | log_pitch);
- t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 |
- (log2Height << 16) | log2Width);
t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |
MLL_MAP_0 |
MLL_UPDATE_MAX_MIP |
@@ -537,6 +535,92 @@ i810UpdateTexEnvCombine( GLcontext *ctx, GLuint unit,
return GL_TRUE;
}
+static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *tObj = texUnit->_Current;
+ i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+
+ if (tObj->Image[0][tObj->BaseLevel]->Border > 0) {
+ return GL_FALSE;
+ }
+
+ /* Upload teximages (not pipelined)
+ */
+ if (t->base.dirty_images[0]) {
+ I810_FIREVERTICES(imesa);
+ i810SetTexImages( imesa, tObj );
+ if (!t->base.memBlock) {
+ return GL_FALSE;
+ }
+ }
+
+ /* Update state if this is a different texture object to last
+ * time.
+ */
+ if (imesa->CurrentTexObj[unit] != t) {
+ I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
+ imesa->CurrentTexObj[unit] = t;
+ t->base.bound |= (1U << unit);
+
+ /* XXX: should be locked */
+ driUpdateTextureLRU( (driTextureObject *) t );
+ }
+
+ imesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
+ return GL_TRUE;
+}
+
+static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *tObj = texUnit->_Current;
+ i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+ GLint Width, Height;
+
+ Width = tObj->Image[0][t->base.firstLevel]->Width - 1;
+ Height = tObj->Image[0][t->base.firstLevel]->Height - 1;
+
+ I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
+ t->Setup[I810_TEXREG_MCS] &= ~MCS_NORMALIZED_COORDS;
+ t->Setup[I810_TEXREG_MCS] |= MCS_UPDATE_NORMALIZED;
+ t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_EXACT |
+ (Height << MI2_HEIGHT_SHIFT) | Width);
+
+ return GL_TRUE;
+}
+
+static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *tObj = texUnit->_Current;
+ i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+ GLint log2Width, log2Height;
+
+
+ log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
+ log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
+
+ I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
+ t->Setup[I810_TEXREG_MCS] |= MCS_NORMALIZED_COORDS | MCS_UPDATE_NORMALIZED;
+ t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 |
+ (log2Height << MI2_HEIGHT_SHIFT) | log2Width);
+
+ return GL_TRUE;
+}
+
+static void disable_tex( GLcontext *ctx, GLuint unit )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ imesa->CurrentTexObj[unit] = 0;
+ imesa->TexEnvImageFmt[unit] = 0;
+ imesa->dirty &= ~(I810_UPLOAD_TEX0<<unit);
+
+}
/**
* Update hardware state for a texture unit.
@@ -550,62 +634,32 @@ static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit,
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLboolean ret;
+
+ switch(texUnit->_ReallyEnabled) {
+ case TEXTURE_2D_BIT:
+ ret = enable_tex_common( ctx, unit);
+ ret &= enable_tex_2d(ctx, unit);
+ if (ret == GL_FALSE) {
+ FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+ }
+ break;
+ case TEXTURE_RECT_BIT:
+ ret = enable_tex_common( ctx, unit);
+ ret &= enable_tex_rect(ctx, unit);
+ if (ret == GL_FALSE) {
+ FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+ }
+ break;
+ case 0:
+ disable_tex(ctx, unit);
+ break;
+ }
- if ( (texUnit->_ReallyEnabled == TEXTURE_2D_BIT)
- || (texUnit->_ReallyEnabled == 0) ) {
- if (texUnit->_ReallyEnabled != 0) {
- struct gl_texture_object *tObj = texUnit->_Current;
- i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
-
- if (tObj->Image[0][tObj->BaseLevel]->Border > 0) {
- FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
- return;
- }
-
-
- /* Upload teximages (not pipelined)
- */
- if (t->base.dirty_images[0]) {
- I810_FIREVERTICES(imesa);
- i810SetTexImages( imesa, tObj );
- if (!t->base.memBlock) {
- FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
- return;
- }
- }
-
-
- /* Update state if this is a different texture object to last
- * time.
- */
- if (imesa->CurrentTexObj[unit] != t) {
- I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
- imesa->CurrentTexObj[unit] = t;
- t->base.bound |= (1U << unit);
-
- /* XXX: should be locked */
- driUpdateTextureLRU( (driTextureObject *) t );
- }
-
- /* Update texture environment if texture object image format or
- * texture environment state has changed.
- */
- imesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
- }
- else {
- imesa->CurrentTexObj[unit] = 0;
- imesa->TexEnvImageFmt[unit] = 0;
- imesa->dirty &= ~(I810_UPLOAD_TEX0<<unit);
- }
-
- if (!i810UpdateTexEnvCombine( ctx, unit,
- next_color_stage, next_alpha_stage )) {
- FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
- }
- }
- else if (texUnit->_ReallyEnabled) {
- FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+ if (!i810UpdateTexEnvCombine( ctx, unit,
+ next_color_stage, next_alpha_stage )) {
+ FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
}
return;
diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile
index 53349364d04..805abf75e08 100644
--- a/src/mesa/drivers/dri/i915/Makefile
+++ b/src/mesa/drivers/dri/i915/Makefile
@@ -4,6 +4,8 @@ include $(TOP)/configs/current
LIBNAME = i915_dri.so
+MINIGLX_SOURCES = server/intel_dri.c
+
DRIVER_SOURCES = \
i915_context.c \
i915_debug.c \
@@ -37,7 +39,6 @@ DRIVER_SOURCES = \
C_SOURCES = \
$(COMMON_SOURCES) \
- $(MINIGLX_SOURCES) \
$(DRIVER_SOURCES)
ASM_SOURCES =
diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c
index 7a251ac6e89..d16b153fac2 100644
--- a/src/mesa/drivers/dri/i915/i830_context.c
+++ b/src/mesa/drivers/dri/i915/i830_context.c
@@ -84,7 +84,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis,
12,
I830_NR_TEX_REGIONS,
intel->sarea->texList,
- & intel->sarea->texAge,
+ (unsigned *) & intel->sarea->texAge,
& intel->swapped,
sizeof( struct i830_texture_object ),
(destroy_texture_object_t *)intelDestroyTexObj );
diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h
index 5bdcc21c5ab..d5811e6c349 100644
--- a/src/mesa/drivers/dri/i915/i830_context.h
+++ b/src/mesa/drivers/dri/i915/i830_context.h
@@ -118,7 +118,7 @@ struct i830_context
{
struct intel_context intel;
- GLuint last_index;
+ DECLARE_RENDERINPUTS(last_index_bitset);
struct i830_hw_state meta, initial, state, *current;
};
diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index e8913e8063c..9e71b111091 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -65,11 +65,13 @@ static void i830_render_start( intelContextPtr intel )
i830ContextPtr i830 = I830_CONTEXT(intel);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
GLuint v0 = _3DSTATE_VFT0_CMD;
GLuint v2 = _3DSTATE_VFT1_CMD;
GLuint mcsb1 = 0;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
/* Important:
*/
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
@@ -78,7 +80,7 @@ static void i830_render_start( intelContextPtr intel )
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
* build up a hardware vertex.
*/
- if (index & _TNL_BITS_TEX_ANY) {
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW );
intel->coloroffset = 4;
}
@@ -87,36 +89,37 @@ static void i830_render_start( intelContextPtr intel )
intel->coloroffset = 3;
}
- if (index & _TNL_BIT_POINTSIZE) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH );
}
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE );
intel->specoffset = 0;
- if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
- if (index & _TNL_BIT_COLOR1) {
- intel->specoffset = intel->coloroffset + 1;
- EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC );
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
+ intel->specoffset = intel->coloroffset + 1;
+ EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC );
}
- else
- EMIT_PAD( 3 );
-
- if (index & _TNL_BIT_FOG)
- EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC );
else
- EMIT_PAD( 1 );
+ EMIT_PAD( 3 );
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
+ EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC );
+ else
+ EMIT_PAD( 1 );
}
- if (index & _TNL_BITS_TEX_ANY) {
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
int i, count = 0;
for (i = 0; i < I830_TEX_UNITS; i++) {
- if (index & _TNL_BIT_TEX(i)) {
- GLuint sz = VB->TexCoordPtr[i]->size;
- GLuint emit;
- GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] &
- ~TEXCOORDTYPE_MASK);
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
+ GLuint sz = VB->TexCoordPtr[i]->size;
+ GLuint emit;
+ GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] &
+ ~TEXCOORDTYPE_MASK);
switch (sz) {
case 1:
@@ -162,7 +165,7 @@ static void i830_render_start( intelContextPtr intel )
if (v0 != i830->state.Ctx[I830_CTXREG_VF] ||
v2 != i830->state.Ctx[I830_CTXREG_VF2] ||
mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] ||
- index != i830->last_index) {
+ !RENDERINPUTS_EQUAL( index_bitset, i830->last_index_bitset )) {
I830_STATECHANGE( i830, I830_UPLOAD_CTX );
@@ -180,7 +183,7 @@ static void i830_render_start( intelContextPtr intel )
i830->state.Ctx[I830_CTXREG_VF] = v0;
i830->state.Ctx[I830_CTXREG_VF2] = v2;
i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1;
- i830->last_index = index;
+ RENDERINPUTS_COPY( i830->last_index_bitset, index_bitset );
assert(i830_check_vertex_size( intel, intel->vertex_size ));
}
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index b5c3f58d458..783bbc2ab89 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -127,7 +127,7 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
12,
I830_NR_TEX_REGIONS,
intel->sarea->texList,
- & intel->sarea->texAge,
+ (unsigned *) & intel->sarea->texAge,
& intel->swapped,
sizeof( struct i915_texture_object ),
(destroy_texture_object_t *)intelDestroyTexObj );
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index 26b8c69be9e..a088c087b65 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -311,6 +311,7 @@ extern void i915_print_ureg( const char *msg, GLuint ureg );
*/
extern void i915InitStateFunctions( struct dd_function_table *functions );
extern void i915InitState( i915ContextPtr i915 );
+extern void i915_update_fog(GLcontext *ctxx);
/*======================================================================
diff --git a/src/mesa/drivers/dri/i915/i915_texprog.c b/src/mesa/drivers/dri/i915/i915_texprog.c
index 74ece96f8b7..4fbce34ba21 100644
--- a/src/mesa/drivers/dri/i915/i915_texprog.c
+++ b/src/mesa/drivers/dri/i915/i915_texprog.c
@@ -576,11 +576,13 @@ void i915ValidateTextureProgram( i915ContextPtr i915 )
GLcontext *ctx = &intel->ctx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
int i, offset;
GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
GLuint s2 = S2_TEXCOORD_NONE;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
/* Important:
*/
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
@@ -591,9 +593,9 @@ void i915ValidateTextureProgram( i915ContextPtr i915 )
if (i915->vertex_fog == I915_FOG_PIXEL) {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 );
- index &= ~_TNL_BIT_FOG;
+ RENDERINPUTS_CLEAR( index_bitset, _TNL_ATTRIB_FOG );
}
- else if (index & _TNL_BITS_TEX_ANY) {
+ else if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 );
}
else {
@@ -601,29 +603,30 @@ void i915ValidateTextureProgram( i915ContextPtr i915 )
}
/* How undefined is undefined? */
- if (index & _TNL_BIT_POINTSIZE) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, S4_VFMT_POINT_WIDTH, 4 );
}
intel->coloroffset = offset / 4;
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4 );
- if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
- if (index & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
intel->specoffset = offset / 4;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3 );
} else
EMIT_PAD( 3 );
- if (index & _TNL_BIT_FOG)
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1 );
else
EMIT_PAD( 1 );
}
- if (index & _TNL_BITS_TEX_ANY) {
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
for (i = 0; i < 8; i++) {
- if (index & _TNL_BIT_TEX(i)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
int sz = VB->TexCoordPtr[i]->size;
s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index 87eddfecdef..3b639e71443 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -456,7 +456,7 @@ static void i915SetTexImages( i915ContextPtr i915,
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
break;
- case MESA_FORMAT_DEPTH_COMPONENT16:
+ case MESA_FORMAT_Z16:
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_16BIT | MT_16BIT_L16);
break;
@@ -483,7 +483,7 @@ static void i915SetTexImages( i915ContextPtr i915,
break;
#if 0
- case MESA_FORMAT_DEPTH_COMPONENT_X8Z24:
+ case MESA_FORMAT_Z24_S8:
t->intel.texelBytes = 4;
textureFormat = (MAPSURF_32BIT | MT_32BIT_xL824);
break;
diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
index 5979e236bcd..06312372776 100644
--- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
@@ -216,7 +216,7 @@ void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
}
#if 1
- if (((int)intel->batch.ptr) & 0x4) {
+ if (((unsigned long)intel->batch.ptr) & 0x4) {
BEGIN_BATCH(1);
OUT_BATCH(0);
ADVANCE_BATCH();
@@ -762,11 +762,6 @@ void intelInitBatchBuffer( GLcontext *ctx )
break;
}
- /* KW: temporary - this make crashes & lockups more frequent, so
- * leave in until they are solved.
- */
- intel->alloc.size = 8 * 1024;
-
intel->alloc.ptr = intelAllocateAGP( intel, intel->alloc.size );
if (intel->alloc.ptr)
intel->alloc.offset =
diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h
index b0aed89af55..577d07137ff 100644
--- a/src/mesa/drivers/dri/i915/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.h
@@ -43,8 +43,9 @@ extern int VERBOSE;
#define BEGIN_BATCH(n) \
do { \
if (VERBOSE) fprintf(stderr, \
- "BEGIN_BATCH(%d) in %s, %d dwords free\n", \
- (n), __FUNCTION__, intel->batch.space/4); \
+ "BEGIN_BATCH(%ld) in %s, %d dwords free\n", \
+ ((unsigned long)n), __FUNCTION__, \
+ intel->batch.space/4); \
if (intel->batch.space < (n)*4) \
intelFlushBatch(intel, GL_TRUE); \
if (intel->batch.space == intel->batch.size) intel->batch.func = __FUNCTION__; \
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index 2f362f9c2fb..19213b7bc55 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -207,7 +207,7 @@ struct intel_context
GLenum render_primitive;
GLenum reduced_primitive;
GLuint vertex_size;
- char *verts; /* points to tnl->clipspace.vertex_buf */
+ unsigned char *verts; /* points to tnl->clipspace.vertex_buf */
/* Fallback rasterization functions
diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c
index 82ad14ca114..d8530367664 100644
--- a/src/mesa/drivers/dri/i915/intel_ioctl.c
+++ b/src/mesa/drivers/dri/i915/intel_ioctl.c
@@ -140,7 +140,7 @@ void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock )
fprintf(stderr, "%s: now using half %d\n", __FUNCTION__, buf);
intel->batch.start_offset = intel->alloc.offset + buf * half;
- intel->batch.ptr = (char *)intel->alloc.ptr + buf * half;
+ intel->batch.ptr = (unsigned char *)intel->alloc.ptr + buf * half;
intel->batch.size = half - 8;
intel->batch.space = half - 8;
assert(intel->batch.space >= 0);
@@ -418,7 +418,7 @@ void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
if (!intel->hw_stencil) {
swrast_mask |= BUFFER_BIT_STENCIL;
}
- else if (ctx->Stencil.WriteMask[0] != 0xff) {
+ else if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
tri_mask |= BUFFER_BIT_STENCIL;
}
else {
diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c
index aaafe84a6a0..2af38541d9c 100644
--- a/src/mesa/drivers/dri/i915/intel_pixel.c
+++ b/src/mesa/drivers/dri/i915/intel_pixel.c
@@ -157,13 +157,15 @@ intersect_region(const drm_clip_rect_t *box,
if (by < y) bh -= y - by, by = y;
if (bx + bw > x + width) bw = x + width - bx;
if (by + bh > y + height) bh = y + height - by;
- if (bw <= 0) return GL_FALSE;
- if (bh <= 0) return GL_FALSE;
*xOut = bx;
*yOut = by;
*wOut = bw;
*hOut = bh;
+
+ if (bw <= 0) return GL_FALSE;
+ if (bh <= 0) return GL_FALSE;
+
return GL_TRUE;
}
@@ -423,6 +425,8 @@ intelTryDrawPixels( GLcontext *ctx,
}
else
return GL_FALSE;
+
+ return GL_FALSE;
}
static void
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index c8649d8243a..a87de17304f 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -666,7 +666,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc
*driver_modes = intelFillInModes( dri_priv->cpp * 8,
(dri_priv->cpp == 2) ? 16 : 24,
(dri_priv->cpp == 2) ? 0 : 8,
- (dri_priv->backOffset != dri_priv->depthOffset) );
+ 1 );
/* Calling driInitExtensions here, with a NULL context pointer, does not actually
* enable the extensions. It just makes sure that all the dispatch offsets for all
diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c
index 4bd7f92db0a..6012d3e7999 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.c
+++ b/src/mesa/drivers/dri/i915/intel_tex.c
@@ -572,7 +572,7 @@ intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
- return &_mesa_texformat_depth_component16;
+ return &_mesa_texformat_z16;
default:
fprintf(stderr, "unexpected texture format %s in %s\n",
@@ -787,7 +787,8 @@ int intelUploadTexImages( intelContextPtr intel,
}
/* Set the base offset of the texture image */
- t->BufAddr = intel->intelScreen->tex.map + t->base.memBlock->ofs;
+ t->BufAddr = (GLubyte *) (intel->intelScreen->tex.map +
+ t->base.memBlock->ofs);
t->TextureOffset = intel->intelScreen->tex.offset + t->base.memBlock->ofs;
t->dirty = ~0;
}
diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c
index cef6db7a195..e1a53212a51 100644
--- a/src/mesa/drivers/dri/i915/intel_tris.c
+++ b/src/mesa/drivers/dri/i915/intel_tris.c
@@ -642,7 +642,7 @@ void intelChooseRenderState(GLcontext *ctx)
TNLcontext *tnl = TNL_CONTEXT(ctx);
intelContextPtr intel = INTEL_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
- struct fragment_program *fprog = ctx->FragmentProgram._Current;
+ const struct fragment_program *fprog = ctx->FragmentProgram._Current;
GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS));
GLuint index = 0;
diff --git a/src/mesa/drivers/dri/i915/server/intel.h b/src/mesa/drivers/dri/i915/server/intel.h
index 606db974b1c..d7858a20c8d 100644
--- a/src/mesa/drivers/dri/i915/server/intel.h
+++ b/src/mesa/drivers/dri/i915/server/intel.h
@@ -137,11 +137,6 @@ typedef struct {
int space;
} I830RingBuffer;
-typedef struct {
- unsigned int Fence[8];
-} I830RegRec, *I830RegPtr;
-
-
typedef struct _I830Rec {
unsigned char *MMIOBase;
unsigned char *FbBase;
@@ -194,6 +189,7 @@ typedef struct _I830Rec {
int GttBound;
drm_handle_t ring_map;
+ unsigned int Fence[8];
} I830Rec;
@@ -271,6 +267,44 @@ typedef struct _I830Rec {
#define RING_INVALID 0x00000000
+/* Fence/Tiling ranges [0..7]
+ */
+#define FENCE 0x2000
+#define FENCE_NR 8
+
+#define I915G_FENCE_START_MASK 0x0ff00000
+
+#define I830_FENCE_START_MASK 0x07f80000
+
+#define FENCE_START_MASK 0x03F80000
+#define FENCE_X_MAJOR 0x00000000
+#define FENCE_Y_MAJOR 0x00001000
+#define FENCE_SIZE_MASK 0x00000700
+#define FENCE_SIZE_512K 0x00000000
+#define FENCE_SIZE_1M 0x00000100
+#define FENCE_SIZE_2M 0x00000200
+#define FENCE_SIZE_4M 0x00000300
+#define FENCE_SIZE_8M 0x00000400
+#define FENCE_SIZE_16M 0x00000500
+#define FENCE_SIZE_32M 0x00000600
+#define FENCE_SIZE_64M 0x00000700
+#define I915G_FENCE_SIZE_1M 0x00000000
+#define I915G_FENCE_SIZE_2M 0x00000100
+#define I915G_FENCE_SIZE_4M 0x00000200
+#define I915G_FENCE_SIZE_8M 0x00000300
+#define I915G_FENCE_SIZE_16M 0x00000400
+#define I915G_FENCE_SIZE_32M 0x00000500
+#define I915G_FENCE_SIZE_64M 0x00000600
+#define I915G_FENCE_SIZE_128M 0x00000700
+#define FENCE_PITCH_1 0x00000000
+#define FENCE_PITCH_2 0x00000010
+#define FENCE_PITCH_4 0x00000020
+#define FENCE_PITCH_8 0x00000030
+#define FENCE_PITCH_16 0x00000040
+#define FENCE_PITCH_32 0x00000050
+#define FENCE_PITCH_64 0x00000060
+#define FENCE_VALID 0x00000001
+
#include <mmio.h>
# define MMIO_IN8(base, offset) \
diff --git a/src/mesa/drivers/dri/i915/server/intel_dri.c b/src/mesa/drivers/dri/i915/server/intel_dri.c
index 2fd4a13052f..169fdbece30 100644
--- a/src/mesa/drivers/dri/i915/server/intel_dri.c
+++ b/src/mesa/drivers/dri/i915/server/intel_dri.c
@@ -46,10 +46,250 @@
#include "pciaccess.h"
static size_t drm_page_size;
+static int nextTile = 0;
#define xf86DrvMsg(...) do {} while(0)
+static const int pitches[] = {
+ 128 * 8,
+ 128 * 16,
+ 128 * 32,
+ 128 * 64,
+ 0
+};
+
static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea);
+static unsigned long
+GetBestTileAlignment(unsigned long size)
+{
+ unsigned long i;
+
+ for (i = KB(512); i < size; i <<= 1)
+ ;
+
+ if (i > MB(64))
+ i = MB(64);
+
+ return i;
+}
+
+static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ int i;
+ unsigned char *MMIO = ctx->MMIOAddress;
+
+ for (i = 0; i < 8; i++) {
+ OUTREG(FENCE + i * 4, pI830->Fence[i]);
+ // if (I810_DEBUG & DEBUG_VERBOSE_VGA)
+ fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]);
+ }
+}
+
+/* Tiled memory is good... really, really good...
+ *
+ * Need to make it less likely that we miss out on this - probably
+ * need to move the frontbuffer away from the 'guarenteed' alignment
+ * of the first memory segment, or perhaps allocate a discontigous
+ * framebuffer to get more alignment 'sweet spots'.
+ */
+static void
+SetFence(const DRIDriverContext *ctx, I830Rec *pI830,
+ int nr, unsigned int start, unsigned int pitch,
+ unsigned int size)
+{
+ unsigned int val;
+ unsigned int fence_mask = 0;
+ unsigned int fence_pitch;
+
+ if (nr < 0 || nr > 7) {
+ fprintf(stderr,
+ "SetFence: fence %d out of range\n",nr);
+ return;
+ }
+
+ pI830->Fence[nr] = 0;
+
+ if (IS_I9XX(pI830))
+ fence_mask = ~I915G_FENCE_START_MASK;
+ else
+ fence_mask = ~I830_FENCE_START_MASK;
+
+ if (start & fence_mask) {
+ fprintf(stderr,
+ "SetFence: %d: start (0x%08x) is not %s aligned\n",
+ nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k");
+ return;
+ }
+
+ if (start % size) {
+ fprintf(stderr,
+ "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n",
+ nr, start, size / 1024);
+ return;
+ }
+
+ if (pitch & 127) {
+ fprintf(stderr,
+ "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n",
+ nr, pitch);
+ return;
+ }
+
+ val = (start | FENCE_X_MAJOR | FENCE_VALID);
+
+ if (IS_I9XX(pI830)) {
+ switch (size) {
+ case MB(1):
+ val |= I915G_FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= I915G_FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= I915G_FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= I915G_FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= I915G_FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= I915G_FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= I915G_FENCE_SIZE_64M;
+ break;
+ default:
+ fprintf(stderr,
+ "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
+ return;
+ }
+ } else {
+ switch (size) {
+ case KB(512):
+ val |= FENCE_SIZE_512K;
+ break;
+ case MB(1):
+ val |= FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= FENCE_SIZE_64M;
+ break;
+ default:
+ fprintf(stderr,
+ "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
+ return;
+ }
+ }
+
+ if (IS_I9XX(pI830))
+ fence_pitch = pitch / 512;
+ else
+ fence_pitch = pitch / 128;
+
+ switch (fence_pitch) {
+ case 1:
+ val |= FENCE_PITCH_1;
+ break;
+ case 2:
+ val |= FENCE_PITCH_2;
+ break;
+ case 4:
+ val |= FENCE_PITCH_4;
+ break;
+ case 8:
+ val |= FENCE_PITCH_8;
+ break;
+ case 16:
+ val |= FENCE_PITCH_16;
+ break;
+ case 32:
+ val |= FENCE_PITCH_32;
+ break;
+ case 64:
+ val |= FENCE_PITCH_64;
+ break;
+ default:
+ fprintf(stderr,
+ "SetFence: %d: illegal pitch (%d)\n", nr, pitch);
+ return;
+ }
+
+ pI830->Fence[nr] = val;
+}
+
+static Bool
+MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem)
+{
+ int pitch, ntiles, i;
+
+ pitch = pMem->Pitch * ctx->cpp;
+ /*
+ * Simply try to break the region up into at most four pieces of size
+ * equal to the alignment.
+ */
+ ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment;
+ if (ntiles >= 4) {
+ return FALSE;
+ }
+
+ for (i = 0; i < ntiles; i++, nextTile++) {
+ SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment,
+ pitch, pMem->Alignment);
+ }
+ return TRUE;
+}
+
+static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ int i;
+
+ /* Clear out */
+ for (i = 0; i < 8; i++)
+ pI830->Fence[i] = 0;
+
+ nextTile = 0;
+
+ if (pI830->BackBuffer.Alignment >= KB(512)) {
+ if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) {
+ fprintf(stderr,
+ "Activating tiled memory for the back buffer.\n");
+ } else {
+ fprintf(stderr,
+ "MakeTiles failed for the back buffer.\n");
+ pI830->allowPageFlip = FALSE;
+ }
+ }
+
+ if (pI830->DepthBuffer.Alignment >= KB(512)) {
+ if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) {
+ fprintf(stderr,
+ "Activating tiled memory for the depth buffer.\n");
+ } else {
+ fprintf(stderr,
+ "MakeTiles failed for the depth buffer.\n");
+ }
+ }
+
+ return;
+}
+
static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830)
{
struct pci_device host_bridge;
@@ -139,6 +379,43 @@ static int AgpInit(const DRIDriverContext *ctx, I830Rec *info)
return 1;
}
+/*
+ * Allocate memory from the given pool. Grow the pool if needed and if
+ * possible.
+ */
+static unsigned long
+AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830,
+ I830MemRange *result, I830MemPool *pool,
+ long size, unsigned long alignment, int flags)
+{
+ long needed, start, end;
+
+ if (!result || !pool || !size)
+ return 0;
+
+ /* Calculate how much space is needed. */
+ if (alignment <= GTT_PAGE_SIZE)
+ needed = size;
+ else {
+ start = ROUND_TO(pool->Free.Start, alignment);
+ end = ROUND_TO(start + size, alignment);
+ needed = end - pool->Free.Start;
+ }
+ if (needed > pool->Free.Size) {
+ return 0;
+ }
+
+ result->Start = ROUND_TO(pool->Free.Start, alignment);
+ pool->Free.Start += needed;
+ result->End = pool->Free.Start;
+
+ pool->Free.Size = pool->Free.End - pool->Free.Start;
+ result->Size = result->End - result->Start;
+ result->Pool = pool;
+ result->Alignment = alignment;
+ return needed;
+}
+
static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result)
{
unsigned long start, end;
@@ -166,7 +443,7 @@ static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, l
pI830->MemoryAperture.Start = newApStart;
pI830->MemoryAperture.End = newApEnd;
pI830->MemoryAperture.Size = newApEnd - newApStart;
- pI830->FreeMemory -= size;
+ // pI830->FreeMemory -= size;
result->Start = start;
result->End = start + size;
result->Size = size;
@@ -177,6 +454,34 @@ static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, l
return size;
}
+unsigned long
+I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *result, I830MemPool *pool, long size, unsigned long alignment, int flags)
+{
+ int ret;
+
+ if (!result)
+ return 0;
+
+ /* Make sure these are initialised. */
+ result->Size = 0;
+ result->Key = -1;
+
+ if (!size) {
+ return 0;
+ }
+
+ if (pool->Free.Size < size)
+ return AllocFromAGP(ctx, pI830, size, alignment, result);
+ else
+ {
+ ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags);
+
+ if (ret==0)
+ return AllocFromAGP(ctx, pI830, size, alignment, result);
+ return ret;
+ }
+}
+
static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem)
{
if (!mem)
@@ -185,7 +490,7 @@ static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem)
if (mem->Key == -1)
return TRUE;
- return drmAgpBind(ctx->drmFD, mem->Key, mem->Offset);
+ return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset);
}
/* simple memory allocation routines needed */
@@ -207,7 +512,7 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
size = PRIMARY_RINGBUFFER_SIZE;
- ret = AllocFromAGP(ctx, pI830, size, 0x1000, &pI830->LpRing->mem);
+ ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0);
if (ret != size)
{
@@ -230,8 +535,10 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
size = lineSize * lines;
size = ROUND_TO_PAGE(size);
- ret = AllocFromAGP(ctx, pI830, size, align, &pI830->FrontBuffer);
- if (ret != size)
+ align = GetBestTileAlignment(size);
+
+ ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0);
+ if (ret < size)
{
fprintf(stderr,"unable to allocate front buffer %ld\n", ret);
return FALSE;
@@ -241,8 +548,8 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
pI830->BackBuffer.Key = -1;
pI830->BackBuffer.Pitch = ctx->shared.virtualWidth;
- ret = AllocFromAGP(ctx, pI830, size, align, &pI830->BackBuffer);
- if (ret != size)
+ ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0);
+ if (ret < size)
{
fprintf(stderr,"unable to allocate back buffer %ld\n", ret);
return FALSE;
@@ -252,8 +559,8 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
pI830->DepthBuffer.Key = -1;
pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth;
- ret = AllocFromAGP(ctx, pI830, size, align, &pI830->DepthBuffer);
- if (ret != size)
+ ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0);
+ if (ret < size)
{
fprintf(stderr,"unable to allocate depth buffer %ld\n", ret);
return FALSE;
@@ -263,10 +570,10 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
pI830->ContextMem.Key = -1;
size = KB(32);
- ret = AllocFromAGP(ctx, pI830, size, align, &pI830->ContextMem);
- if (ret != size)
+ ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0);
+ if (ret < size)
{
- fprintf(stderr,"unable to allocate back buffer %ld\n", ret);
+ fprintf(stderr,"unable to allocate context buffer %ld\n", ret);
return FALSE;
}
@@ -275,7 +582,7 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
size = 32768 * 1024;
ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem);
- if (ret != size)
+ if (ret < size)
{
fprintf(stderr,"unable to allocate texture memory %ld\n", ret);
return FALSE;
@@ -287,17 +594,17 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
static Bool
I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830)
{
- if (BindAgpRange(ctx, &pI830->LpRing->mem))
+ if (!BindAgpRange(ctx, &pI830->LpRing->mem))
return FALSE;
- if (BindAgpRange(ctx, &pI830->FrontBuffer))
+ if (!BindAgpRange(ctx, &pI830->FrontBuffer))
return FALSE;
- if (BindAgpRange(ctx, &pI830->BackBuffer))
+ if (!BindAgpRange(ctx, &pI830->BackBuffer))
return FALSE;
- if (BindAgpRange(ctx, &pI830->DepthBuffer))
+ if (!BindAgpRange(ctx, &pI830->DepthBuffer))
return FALSE;
- if (BindAgpRange(ctx, &pI830->ContextMem))
+ if (!BindAgpRange(ctx, &pI830->ContextMem))
return FALSE;
- if (BindAgpRange(ctx, &pI830->TexMem))
+ if (!BindAgpRange(ctx, &pI830->TexMem))
return FALSE;
return TRUE;
@@ -313,7 +620,7 @@ I830CleanupDma(const DRIDriverContext *ctx)
if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
&info, sizeof(drmI830Init))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Dma Cleanup Failed\n");
+ fprintf(stderr, "I830 Dma Cleanup Failed\n");
return FALSE;
}
@@ -345,11 +652,11 @@ I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830)
info.pitch = ctx->shared.virtualWidth;
info.back_pitch = pI830->BackBuffer.Pitch;
info.depth_pitch = pI830->DepthBuffer.Pitch;
- info.cpp = pI830->cpp;
+ info.cpp = ctx->cpp;
if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
&info, sizeof(drmI830Init))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ fprintf(stderr,
"I830 Dma Initialization Failed\n");
return FALSE;
}
@@ -408,7 +715,7 @@ I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830)
if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) !=
pI830->LpRing->mem.Start) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ fprintf(stderr,
"I830SetRingRegs: Ring buffer start (%lx) violates its "
"mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK);
}
@@ -418,7 +725,7 @@ I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830)
if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) !=
pI830->LpRing->mem.Size - 4096) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ fprintf(stderr,
"I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
"mask (%x)\n", pI830->LpRing->mem.Size - 4096,
I830_RING_NR_PAGES);
@@ -433,6 +740,8 @@ I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830)
pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
if (pI830->LpRing->space < 0)
pI830->LpRing->space += pI830->LpRing->mem.Size;
+
+ SetFenceRegs(ctx, pI830);
/* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky
hacky hacky */
@@ -450,7 +759,7 @@ I830SetParam(const DRIDriverContext *ctx, int param, int value)
sp.value = value;
if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 SetParam Failed\n");
+ fprintf(stderr, "I830 SetParam Failed\n");
return FALSE;
}
@@ -482,7 +791,7 @@ I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sar
(drm_handle_t)(sarea->back_offset),
sarea->back_size, DRM_AGP, 0,
&sarea->back_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ fprintf(stderr,
"[drm] drmAddMap(back_handle) failed. Disabling DRI\n");
return FALSE;
}
@@ -493,7 +802,7 @@ I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sar
(drm_handle_t)sarea->depth_offset,
sarea->depth_size, DRM_AGP, 0,
&sarea->depth_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ fprintf(stderr,
"[drm] drmAddMap(depth_handle) failed. Disabling DRI\n");
return FALSE;
}
@@ -504,7 +813,7 @@ I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sar
(drm_handle_t)sarea->tex_offset,
sarea->tex_size, DRM_AGP, 0,
&sarea->tex_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ fprintf(stderr,
"[drm] drmAddMap(tex_handle) failed. Disabling DRI\n");
return FALSE;
}
@@ -549,10 +858,10 @@ I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *s
if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT_HEAP,
&drmHeap, sizeof(drmHeap))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ fprintf(stderr,
"[drm] Failed to initialized agp heap manager\n");
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ fprintf(stderr,
"[drm] Initialized kernel agp heap manager, %d\n",
sarea->tex_size);
@@ -597,18 +906,18 @@ I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
ctx->pciFunc);
if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ fprintf(stderr,
"[drm] failure adding irq handler\n");
pI830->irq = 0;
return FALSE;
}
else
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ fprintf(stderr,
"[drm] dma control initialized, using IRQ %d\n",
- pI830DRI->irq);
+ pI830->irq);
}
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n");
+ fprintf(stderr, "[dri] visual configs initialized\n");
return TRUE;
}
@@ -663,7 +972,6 @@ I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
I830DRIPtr pI830DRI;
drmI830Sarea *pSAREAPriv;
int err;
-
drm_page_size = getpagesize();
@@ -675,7 +983,7 @@ I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
*/
ctx->shared.SAREASize = SAREA_MAX;
- /* Note that drmOpen will try to load the kernel module, if needed. */
+ /* Note that drmOpen will try to load the kernel module, if needed. */
ctx->drmFD = drmOpen("i915", NULL );
if (ctx->drmFD < 0) {
fprintf(stderr, "[drm] drmOpen failed\n");
@@ -757,6 +1065,11 @@ I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
pI830->MemoryAperture.End = KB(40000);
pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start;
+ pI830->StolenPool.Fixed = pI830->StolenMemory;
+ pI830->StolenPool.Total = pI830->StolenMemory;
+ pI830->StolenPool.Free = pI830->StolenPool.Total;
+ pI830->FreeMemory = pI830->StolenPool.Total.Size;
+
if (!AgpInit(ctx, pI830))
return FALSE;
@@ -810,6 +1123,8 @@ I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
if (err == FALSE)
return FALSE;
+ I830SetupMemoryTiling(ctx, pI830);
+
/* Quick hack to clear the front & back buffers. Could also use
* the clear ioctl to do this, but would need to setup hw state
* first.
@@ -873,6 +1188,7 @@ static int i830PostValidateMode( const DRIDriverContext *ctx )
static int i830InitFBDev( DRIDriverContext *ctx )
{
I830Rec *pI830 = calloc(1, sizeof(I830Rec));
+ int i;
{
int dummy = ctx->shared.virtualWidth;
@@ -885,6 +1201,15 @@ static int i830InitFBDev( DRIDriverContext *ctx )
}
ctx->shared.virtualWidth = dummy;
+ ctx->shared.Width = ctx->shared.virtualWidth;
+ }
+
+
+ for (i = 0; pitches[i] != 0; i++) {
+ if (pitches[i] >= ctx->shared.virtualWidth) {
+ ctx->shared.virtualWidth = pitches[i];
+ break;
+ }
}
ctx->driverPrivate = (void *)pI830;
diff --git a/src/mesa/drivers/dri/mga/README b/src/mesa/drivers/dri/mga/README
new file mode 100644
index 00000000000..a7133fa66f4
--- /dev/null
+++ b/src/mesa/drivers/dri/mga/README
@@ -0,0 +1,26 @@
+MGA DRI driver ported from XF86DRI to FBDRI
+by Denis Oliver Kropp <dok@directfb.org>
+
+
+INFO
+
+This driver has been ported from the head branch of XFree86 to
+the embedded-1-branch of Mesa.
+
+
+STATUS
+
+Already working very well as far as I've tested it (16/32 bit).
+glxgears runs at 935 fps (G550 32MB AGP 4x, Athlon 1.33) vs 744 fps with XFree.
+Other demos (terrain, fire, etc.) have been successfully tested as well.
+
+
+TODO
+
+- mgaEngineShutdown
+- mgaEngineRestore
+- SGRAM detection
+- remove some unused bits from server/*
+- subset driver support
+- mgaWaitForVBlank
+- deinitialization (from MGADRICloseScreen) a la radeonDestroyScreen
diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c
index df253d15934..6e653f8c73d 100644
--- a/src/mesa/drivers/dri/mga/mgaioctl.c
+++ b/src/mesa/drivers/dri/mga/mgaioctl.c
@@ -50,7 +50,7 @@
#include "vblank.h"
-int
+static int
mgaSetFence( mgaContextPtr mmesa, uint32_t * fence )
{
int ret = ENOSYS;
@@ -68,7 +68,7 @@ mgaSetFence( mgaContextPtr mmesa, uint32_t * fence )
}
-int
+static int
mgaWaitFence( mgaContextPtr mmesa, uint32_t fence, uint32_t * curr_fence )
{
int ret = ENOSYS;
diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c
index 75f618ad37a..2f30bd253bf 100644
--- a/src/mesa/drivers/dri/r128/r128_context.c
+++ b/src/mesa/drivers/dri/r128/r128_context.c
@@ -190,7 +190,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual,
rmesa->RenderIndex = -1; /* Impossible value */
rmesa->vert_buf = NULL;
rmesa->num_verts = 0;
- rmesa->tnl_state = ~0;
+ RENDERINPUTS_ONES( rmesa->tnl_state_bitset );
/* Set the maximum texture size small enough that we can guarentee that
* all texture units can bind a maximal texture and have them both in
@@ -296,10 +296,6 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv )
_ac_DestroyContext( rmesa->glCtx );
_swrast_DestroyContext( rmesa->glCtx );
- /* free the Mesa context */
- rmesa->glCtx->DriverCtx = NULL;
- _mesa_destroy_context(rmesa->glCtx);
-
if ( release_texture_heaps ) {
/* This share group is about to go away, free our private
* texture object data.
@@ -314,6 +310,10 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv )
assert( is_empty_list( & rmesa->swapped ) );
}
+ /* free the Mesa context */
+ rmesa->glCtx->DriverCtx = NULL;
+ _mesa_destroy_context(rmesa->glCtx);
+
/* free the option cache */
driDestroyOptionCache (&rmesa->optionCache);
diff --git a/src/mesa/drivers/dri/r128/r128_context.h b/src/mesa/drivers/dri/r128/r128_context.h
index b3552ac7639..c51dd7fa58d 100644
--- a/src/mesa/drivers/dri/r128/r128_context.h
+++ b/src/mesa/drivers/dri/r128/r128_context.h
@@ -130,7 +130,7 @@ struct r128_context {
char *verts; /* points to tnl->clipspace.vertex_buf */
GLuint num_verts;
int coloroffset, specoffset;
- int tnl_state; /* tnl->render_inputs for this _tnl_install_attrs */
+ DECLARE_RENDERINPUTS(tnl_state_bitset); /* tnl->render_inputs for this _tnl_install_attrs */
GLuint NewGLState;
GLuint Fallback;
diff --git a/src/mesa/drivers/dri/r128/r128_lock.c b/src/mesa/drivers/dri/r128/r128_lock.c
index ef67bc6a43a..393dd1ed74c 100644
--- a/src/mesa/drivers/dri/r128/r128_lock.c
+++ b/src/mesa/drivers/dri/r128/r128_lock.c
@@ -89,7 +89,7 @@ void r128GetLock( r128ContextPtr rmesa, GLuint flags )
driUpdateFramebufferSize(rmesa->glCtx, dPriv);
rmesa->lastStamp = dPriv->lastStamp;
rmesa->new_state |= R128_NEW_CLIP;
- rmesa->tnl_state = ~0;
+ RENDERINPUTS_ONES( rmesa->tnl_state_bitset );
}
rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_CLIPRECTS;
diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c
index e9149306d87..1b2c2a5284e 100644
--- a/src/mesa/drivers/dri/r128/r128_state.c
+++ b/src/mesa/drivers/dri/r128/r128_state.c
@@ -260,9 +260,9 @@ r128DDStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
GLint ref, GLuint mask )
{
r128ContextPtr rmesa = R128_CONTEXT(ctx);
- GLuint refmask = ((ctx->Stencil.Ref[0] << 0) |
- (ctx->Stencil.ValueMask[0] << 16) |
- (ctx->Stencil.WriteMask[0] << 24));
+ GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << 0) |
+ ((ctx->Stencil.ValueMask[0] & 0xff) << 16) |
+ ((ctx->Stencil.WriteMask[0] & 0xff) << 24));
GLuint z = rmesa->setup.z_sten_cntl_c;
z &= ~R128_STENCIL_TEST_MASK;
@@ -307,9 +307,9 @@ static void
r128DDStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
{
r128ContextPtr rmesa = R128_CONTEXT(ctx);
- GLuint refmask = ((ctx->Stencil.Ref[0] << 0) |
- (ctx->Stencil.ValueMask[0] << 16) |
- (ctx->Stencil.WriteMask[0] << 24));
+ GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << 0) |
+ ((ctx->Stencil.ValueMask[0] & 0xff) << 16) |
+ ((ctx->Stencil.WriteMask[0] & 0xff) << 24));
if ( rmesa->setup.sten_ref_mask_c != refmask ) {
rmesa->setup.sten_ref_mask_c = refmask;
diff --git a/src/mesa/drivers/dri/r128/r128_tris.c b/src/mesa/drivers/dri/r128/r128_tris.c
index 64f54682b6e..46315225165 100644
--- a/src/mesa/drivers/dri/r128/r128_tris.c
+++ b/src/mesa/drivers/dri/r128/r128_tris.c
@@ -564,11 +564,13 @@ static void r128RenderStart( GLcontext *ctx )
r128ContextPtr rmesa = R128_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
GLuint vc_frmt = 0;
GLboolean fallback_projtex = GL_FALSE;
GLuint offset = 0;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
/* Important: */
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
rmesa->vertex_attr_count = 0;
@@ -577,7 +579,7 @@ static void r128RenderStart( GLcontext *ctx )
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
* build up a hardware vertex.
*/
- if ( index & _TNL_BITS_TEX_ANY )
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ))
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, R128_CCE_VC_FRMT_RHW, 16 );
else
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 12 );
@@ -591,28 +593,29 @@ static void r128RenderStart( GLcontext *ctx )
R128_CCE_VC_FRMT_DIFFUSE_ARGB, 4 );
#endif
- if ( index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG) ) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
#if MESA_LITTLE_ENDIAN
- if ( index & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
rmesa->specoffset = offset;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR,
R128_CCE_VC_FRMT_SPEC_FRGB, 3 );
} else
EMIT_PAD( 3 );
- if (index & _TNL_BIT_FOG)
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, R128_CCE_VC_FRMT_SPEC_FRGB,
1 );
else
EMIT_PAD( 1 );
#else
- if (index & _TNL_BIT_FOG)
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, R128_CCE_VC_FRMT_SPEC_FRGB,
1 );
else
EMIT_PAD( 1 );
- if ( index & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
rmesa->specoffset = offset;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB,
R128_CCE_VC_FRMT_SPEC_FRGB, 3 );
@@ -621,12 +624,12 @@ static void r128RenderStart( GLcontext *ctx )
#endif
}
- if ( index & _TNL_BIT_TEX(rmesa->tmu_source[0]) ) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(rmesa->tmu_source[0]) )) {
if ( VB->TexCoordPtr[rmesa->tmu_source[0]]->size > 2 )
fallback_projtex = GL_TRUE;
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, R128_CCE_VC_FRMT_S_T, 8 );
}
- if ( index & _TNL_BIT_TEX(rmesa->tmu_source[1]) ) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(rmesa->tmu_source[1]) )) {
if ( VB->TexCoordPtr[rmesa->tmu_source[1]]->size > 2 )
fallback_projtex = GL_TRUE;
EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, R128_CCE_VC_FRMT_S2_T2, 8 );
@@ -638,7 +641,7 @@ static void r128RenderStart( GLcontext *ctx )
/* Only need to change the vertex emit code if there has been a
* statechange to a TNL index.
*/
- if ( index != rmesa->tnl_state ) {
+ if (!RENDERINPUTS_EQUAL( index_bitset, rmesa->tnl_state_bitset )) {
FLUSH_BATCH( rmesa );
rmesa->dirty |= R128_UPLOAD_CONTEXT;
@@ -763,7 +766,7 @@ void r128InitTriFuncs( GLcontext *ctx )
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
(6 + 2 * ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
rmesa->verts = (char *)tnl->clipspace.vertex_buf;
- rmesa->tnl_state = -1;
+ RENDERINPUTS_ONES( rmesa->tnl_state_bitset );
rmesa->NewGLState |= _R128_NEW_RENDER_STATE;
}
diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile
index 7d8a170a650..2084d52132e 100644
--- a/src/mesa/drivers/dri/r200/Makefile
+++ b/src/mesa/drivers/dri/r200/Makefile
@@ -38,7 +38,7 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
X86_SOURCES = r200_vtxtmp_x86.S
-DEFINES += -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200
+DRIVER_DEFINES = -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200
SYMLINKS = \
server/radeon_egl.c \
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index e4d9e264bf9..aaaaa5a95bf 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -107,7 +107,7 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
r200ContextPtr rmesa = R200_CONTEXT(ctx);
static char buffer[128];
unsigned offset;
- GLuint agp_mode = rmesa->r200Screen->IsPCI ? 0 :
+ GLuint agp_mode = (rmesa->r200Screen->card_type == RADEON_CARD_PCI)? 0 :
rmesa->r200Screen->AGPMode;
switch ( name ) {
@@ -590,10 +590,6 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
r200VtxfmtDestroy( rmesa->glCtx );
}
- /* free the Mesa context */
- rmesa->glCtx->DriverCtx = NULL;
- _mesa_destroy_context( rmesa->glCtx );
-
if (rmesa->state.scissor.pClipRects) {
FREE(rmesa->state.scissor.pClipRects);
rmesa->state.scissor.pClipRects = NULL;
@@ -613,6 +609,10 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
assert( is_empty_list( & rmesa->swapped ) );
}
+ /* free the Mesa context */
+ rmesa->glCtx->DriverCtx = NULL;
+ _mesa_destroy_context( rmesa->glCtx );
+
/* free the option cache */
driDestroyOptionCache (&rmesa->optionCache);
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index faf1b96a2b8..f6709d3d7fd 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -897,7 +897,7 @@ struct r200_context {
GLuint TclFallback;
GLuint Fallback;
GLuint NewGLState;
- GLuint tnl_index; /* index of bits for last tnl_install_attrs */
+ DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */
/* Vertex buffers
*/
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index 43ae7b66780..6ffb48c1505 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -1452,8 +1452,8 @@ r200StencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
GLint ref, GLuint mask )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLuint refmask = ((ctx->Stencil.Ref[0] << R200_STENCIL_REF_SHIFT) |
- (ctx->Stencil.ValueMask[0] << R200_STENCIL_MASK_SHIFT));
+ GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << R200_STENCIL_REF_SHIFT) |
+ ((ctx->Stencil.ValueMask[0] & 0xff) << R200_STENCIL_MASK_SHIFT));
R200_STATECHANGE( rmesa, ctx );
R200_STATECHANGE( rmesa, msk );
@@ -1500,7 +1500,7 @@ r200StencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
R200_STATECHANGE( rmesa, msk );
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~R200_STENCIL_WRITE_MASK;
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
- (ctx->Stencil.WriteMask[0] << R200_STENCIL_WRITEMASK_SHIFT);
+ ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT);
}
static void
@@ -1601,9 +1601,9 @@ static void r200ClearStencil( GLcontext *ctx, GLint s )
r200ContextPtr rmesa = R200_CONTEXT(ctx);
rmesa->state.stencil.clear =
- ((GLuint) ctx->Stencil.Clear |
+ ((GLuint) (ctx->Stencil.Clear & 0xff) |
(0xff << R200_STENCIL_MASK_SHIFT) |
- (ctx->Stencil.WriteMask[0] << R200_STENCIL_WRITEMASK_SHIFT));
+ ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT));
}
diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c
index 7ab3f7cd032..aa78f382868 100644
--- a/src/mesa/drivers/dri/r200/r200_swtcl.c
+++ b/src/mesa/drivers/dri/r200/r200_swtcl.c
@@ -85,11 +85,12 @@ static void r200SetVertexFormat( GLcontext *ctx )
r200ContextPtr rmesa = R200_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
int fmt_0 = 0;
int fmt_1 = 0;
int offset = 0;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
/* Important:
*/
@@ -106,7 +107,8 @@ static void r200SetVertexFormat( GLcontext *ctx )
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
* build up a hardware vertex.
*/
- if ( !rmesa->swtcl.needproj || (index & _TNL_BITS_TEX_ANY)) { /* need w coord for projected textures */
+ if ( !rmesa->swtcl.needproj ||
+ RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { /* need w coord for projected textures */
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F, R200_VTX_XY | R200_VTX_Z0 | R200_VTX_W0 );
offset = 4;
}
@@ -124,10 +126,11 @@ static void r200SetVertexFormat( GLcontext *ctx )
offset += 1;
rmesa->swtcl.specoffset = 0;
- if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
#if MESA_LITTLE_ENDIAN
- if (index & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
rmesa->swtcl.specoffset = offset;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
}
@@ -135,21 +138,21 @@ static void r200SetVertexFormat( GLcontext *ctx )
EMIT_PAD( 3 );
}
- if (index & _TNL_BIT_FOG) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
}
else {
EMIT_PAD( 1 );
}
#else
- if (index & _TNL_BIT_FOG) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
}
else {
EMIT_PAD( 1 );
}
- if (index & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
rmesa->swtcl.specoffset = offset;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
}
@@ -159,11 +162,11 @@ static void r200SetVertexFormat( GLcontext *ctx )
#endif
}
- if (index & _TNL_BITS_TEX_ANY) {
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
int i;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- if (index & _TNL_BIT_TEX(i)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
GLuint sz = VB->TexCoordPtr[i]->size;
fmt_1 |= sz << (3 * i);
@@ -179,7 +182,7 @@ static void r200SetVertexFormat( GLcontext *ctx )
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_SPEC_ALPHA;
}
- if ( rmesa->tnl_index != index ||
+ if (!RENDERINPUTS_EQUAL( rmesa->tnl_index_bitset, index_bitset ) ||
(rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) ||
(rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) {
R200_NEWPRIM(rmesa);
@@ -193,7 +196,7 @@ static void r200SetVertexFormat( GLcontext *ctx )
rmesa->swtcl.vertex_attr_count,
NULL, 0 );
rmesa->swtcl.vertex_size /= 4;
- rmesa->tnl_index = index;
+ RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset );
}
}
@@ -235,12 +238,12 @@ void r200ChooseVertexState( GLcontext *ctx )
/* HW perspective divide is a win, but tiny vertex formats are a
* bigger one.
*/
- if ( ((tnl->render_inputs & _TNL_BITS_TEX_ANY) == 0)
+ if (!RENDERINPUTS_TEST_RANGE( tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )
|| (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
rmesa->swtcl.needproj = GL_TRUE;
vte |= R200_VTX_XY_FMT | R200_VTX_Z_FMT;
vte &= ~R200_VTX_W0_FMT;
- if (tnl->render_inputs & _TNL_BITS_TEX_ANY) {
+ if (RENDERINPUTS_TEST_RANGE( tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
vap &= ~R200_VAP_FORCE_W_TO_ONE;
}
else {
@@ -719,7 +722,7 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
*/
_tnl_invalidate_vertex_state( ctx, ~0 );
_tnl_invalidate_vertices( ctx, ~0 );
- rmesa->tnl_index = 0;
+ RENDERINPUTS_ZERO( rmesa->tnl_index_bitset );
r200ChooseVertexState( ctx );
r200ChooseRenderState( ctx );
}
diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.c b/src/mesa/drivers/dri/r200/r200_vtxfmt.c
index f42a046c00d..673076d0605 100644
--- a/src/mesa/drivers/dri/r200/r200_vtxfmt.c
+++ b/src/mesa/drivers/dri/r200/r200_vtxfmt.c
@@ -1056,12 +1056,16 @@ static void r200VtxFmtFlushVertices( GLcontext *ctx, GLuint flags )
*/
+/**
+ * Called once during context creation.
+ */
void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
{
r200ContextPtr rmesa = R200_CONTEXT( ctx );
GLvertexformat *vfmt = &(rmesa->vb.vtxfmt);
- MEMSET( vfmt, 0, sizeof(GLvertexformat) );
+ /* start by initializing to no-op functions */
+ _mesa_noop_vtxfmt_init(vfmt);
/* Hook in chooser functions for codegen, etc:
*/
@@ -1071,7 +1075,6 @@ void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
*/
vfmt->Materialfv = r200_Materialfv;
vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
- vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
vfmt->Begin = r200_Begin;
vfmt->End = r200_End;
@@ -1085,15 +1088,6 @@ void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
vfmt->DrawElements = r200_fallback_DrawElements;
vfmt->DrawRangeElements = r200_fallback_DrawRangeElements;
-
- /* Not active in supported states; just keep ctx->Current uptodate:
- */
- vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
- vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
- vfmt->Indexf = _mesa_noop_Indexf;
- vfmt->Indexfv = _mesa_noop_Indexfv;
-
-
/* Active but unsupported -- fallback if we receive these:
*/
vfmt->CallList = r200_fallback_CallList;
diff --git a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S b/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
index 57a35c657b8..5e33c7bdeea 100644
--- a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
+++ b/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
@@ -493,3 +493,7 @@ GLOBL( _sse_MultiTexCoord2f_2 )
ret
GLOBL( _sse_MultiTexCoord2f_2_end )
#endif
+
+#if defined (__ELF__) && defined (__linux__)
+ .section .note.GNU-stack,"",%progbits
+#endif
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index 3158ac8412b..5abb91d9876 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -5,7 +5,6 @@ TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = r300_dri.so
-DEFINES += -DCOMPILE_R300 -DGLX_DIRECT_RENDERING -DR200_MERGED=0
MINIGLX_SOURCES = server/radeon_dri.c
@@ -70,7 +69,8 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
X86_SOURCES =
#r200_vtxtmp_x86.S
-DEFINES += -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300
+DRIVER_DEFINES = -DCOMPILE_R300 -DGLX_DIRECT_RENDERING -DR200_MERGED=0 \
+ -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300
SYMLINKS = \
server/radeon_dri.c \
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 09f7669bd71..f39f71584ce 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -337,8 +337,10 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.unk4260.cmd[0] = cmdpacket0(0x4260, 3);
ALLOC_STATE( unk4274, always, 5, "unk4274", 0 );
r300->hw.unk4274.cmd[0] = cmdpacket0(0x4274, 4);
- ALLOC_STATE( unk4288, always, 6, "unk4288", 0 );
- r300->hw.unk4288.cmd[0] = cmdpacket0(0x4288, 5);
+ ALLOC_STATE( unk4288, always, 4, "unk4288", 0 );
+ r300->hw.unk4288.cmd[0] = cmdpacket0(0x4288, 3);
+ ALLOC_STATE( fogp, always, 3, "fogp", 0 );
+ r300->hw.fogp.cmd[0] = cmdpacket0(R300_RE_FOG_SCALE, 2);
ALLOC_STATE( unk42A0, always, 2, "unk42A0", 0 );
r300->hw.unk42A0.cmd[0] = cmdpacket0(0x42A0, 1);
ALLOC_STATE( zbs, always, R300_ZBS_CMDSIZE, "zbs", 0 );
@@ -374,10 +376,10 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR2_0, 1);
ALLOC_STATE( fpi[3], variable, R300_FPI_CMDSIZE, "fpi/3", 3 );
r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR3_0, 1);
- ALLOC_STATE( unk4BC0, always, 2, "unk4BC0", 0 );
- r300->hw.unk4BC0.cmd[0] = cmdpacket0(0x4BC0, 1);
- ALLOC_STATE( unk4BC8, always, 4, "unk4BC8", 0 );
- r300->hw.unk4BC8.cmd[0] = cmdpacket0(0x4BC8, 3);
+ ALLOC_STATE( fogs, always, R300_FOGS_CMDSIZE, "fogs", 0 );
+ r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(R300_RE_FOG_STATE, 1);
+ ALLOC_STATE( fogc, always, R300_FOGC_CMDSIZE, "fogc", 0 );
+ r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(R300_FOG_COLOR_R, 3);
ALLOC_STATE( at, always, R300_AT_CMDSIZE, "at", 0 );
r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(R300_PP_ALPHA_TEST, 2);
ALLOC_STATE( unk4BD8, always, 2, "unk4BD8", 0 );
@@ -478,6 +480,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4260);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4274);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4288);
+ insert_at_tail(&r300->hw.atomlist, &r300->hw.fogp);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42A0);
insert_at_tail(&r300->hw.atomlist, &r300->hw.zbs);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42B4);
@@ -495,8 +498,8 @@ void r300InitCmdBuf(r300ContextPtr r300)
insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[1]);
insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[2]);
insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[3]);
- insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BC0);
- insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BC8);
+ insert_at_tail(&r300->hw.atomlist, &r300->hw.fogs);
+ insert_at_tail(&r300->hw.atomlist, &r300->hw.fogc);
insert_at_tail(&r300->hw.atomlist, &r300->hw.at);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BD8);
insert_at_tail(&r300->hw.atomlist, &r300->hw.fpp);
@@ -541,9 +544,9 @@ void r300InitCmdBuf(r300ContextPtr r300)
size = 64*256;
if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) {
- fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%d\n",
+ fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%ld\n",
sizeof(drm_r300_cmd_header_t));
- fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%d\n",
+ fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%ld\n",
sizeof(drm_radeon_cmd_buffer_t));
fprintf(stderr,
"Allocating %d bytes command buffer (max state is %d bytes)\n",
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 4943d549973..cadb27ba8b9 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -372,6 +372,61 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
return GL_TRUE;
}
+static void r300FreeGartAllocations(r300ContextPtr r300)
+{
+ int i, ret, tries=0, done_age;
+ drm_radeon_mem_free_t memfree;
+
+ memfree.region = RADEON_MEM_REGION_GART;
+
+#ifdef USER_BUFFERS
+ done_age = radeonGetAge((radeonContextPtr)r300);
+
+ for (i = r300->rmm->u_last; i > 0; i--) {
+ if (r300->rmm->u_list[i].ptr == NULL) {
+ continue;
+ }
+
+ assert(r300->rmm->u_list[i].pending);
+ assert(r300->rmm->u_list[i].h_pending == 0);
+
+ tries = 0;
+ while(r300->rmm->u_list[i].age > done_age && tries++ < 1000) {
+ usleep(10);
+ done_age = radeonGetAge((radeonContextPtr)r300);
+ }
+ if (tries >= 1000) {
+ WARN_ONCE("Failed to idle region!");
+ }
+
+ memfree.region_offset = (char *)r300->rmm->u_list[i].ptr -
+ (char *)r300->radeon.radeonScreen->gartTextures.map;
+
+ ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd,
+ DRM_RADEON_FREE, &memfree, sizeof(memfree));
+ if (ret) {
+ fprintf(stderr, "Failed to free at %p\nret = %s\n",
+ r300->rmm->u_list[i].ptr, strerror(-ret));
+ } else {
+ if (i == r300->rmm->u_last)
+ r300->rmm->u_last--;
+
+ r300->rmm->u_list[i].pending = 0;
+ r300->rmm->u_list[i].ptr = NULL;
+ if (r300->rmm->u_list[i].fb) {
+ LOCK_HARDWARE(&(r300->radeon));
+ ret = mmFreeMem(r300->rmm->u_list[i].fb);
+ UNLOCK_HARDWARE(&(r300->radeon));
+ if (ret) fprintf(stderr, "failed to free!\n");
+ r300->rmm->u_list[i].fb = NULL;
+ }
+ r300->rmm->u_list[i].ref_count = 0;
+ }
+ }
+ r300->rmm->u_head = i;
+#endif /* USER_BUFFERS */
+}
+
/* Destroy the device specific context.
*/
void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
@@ -403,12 +458,11 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
_ac_DestroyContext(r300->radeon.glCtx);
_swrast_DestroyContext(r300->radeon.glCtx);
- r300ReleaseArrays(r300->radeon.glCtx);
if (r300->dma.current.buf) {
r300ReleaseDmaRegion(r300, &r300->dma.current, __FUNCTION__ );
- r300FlushCmdBuf(r300, __FUNCTION__ );
}
-
+ r300FlushCmdBuf(r300, __FUNCTION__);
+ r300FreeGartAllocations(r300);
r300DestroyCmdBuf(r300);
if (radeon->state.scissor.pClipRects) {
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 176341d7715..7ff805fd5d3 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -47,11 +47,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "colormac.h"
#include "radeon_context.h"
-/* PPC doesnt support 16 bit elts ... */
-#ifndef MESA_BIG_ENDIAN
#define USER_BUFFERS
#define RADEON_VTXFMT_A
#define HW_VBOS
+
+/* We don't handle 16 bits elts swapping yet */
+#ifdef MESA_BIG_ENDIAN
+#define FORCE_32BITS_ELTS
#endif
//#define OPTIMIZE_ELTS
@@ -346,6 +348,21 @@ struct r300_state_atom {
#define R300_FPP_PARAM_0 1
#define R300_FPP_CMDSIZE (32*4+1)
+#define R300_FOGS_CMD_0 0
+#define R300_FOGS_STATE 1
+#define R300_FOGS_CMDSIZE 2
+
+#define R300_FOGC_CMD_0 0
+#define R300_FOGC_R 1
+#define R300_FOGC_G 2
+#define R300_FOGC_B 3
+#define R300_FOGC_CMDSIZE 4
+
+#define R300_FOGP_CMD_0 0
+#define R300_FOGP_SCALE 1
+#define R300_FOGP_START 2
+#define R300_FOGP_CMDSIZE 3
+
#define R300_AT_CMD_0 0
#define R300_AT_ALPHA_TEST 1
#define R300_AT_UNKNOWN 2
@@ -432,6 +449,8 @@ struct r300_hw_state {
struct r300_state_atom unk4260; /* (4260) */
struct r300_state_atom unk4274; /* (4274) */
struct r300_state_atom unk4288; /* (4288) */
+ struct r300_state_atom fogp; /* fog parameters (4294) */
+ struct r300_state_atom unk429C; /* (429C) */
struct r300_state_atom unk42A0; /* (42A0) */
struct r300_state_atom zbs; /* zbias (42A4) */
struct r300_state_atom unk42B4; /* (42B4) */
@@ -446,8 +465,8 @@ struct r300_hw_state {
struct r300_state_atom fpt; /* texi - (4620) */
struct r300_state_atom unk46A4; /* (46A4) */
struct r300_state_atom fpi[4]; /* fp instructions (46C0/47C0/48C0/49C0) */
- struct r300_state_atom unk4BC0; /* (4BC0) */
- struct r300_state_atom unk4BC8; /* (4BC8) */
+ struct r300_state_atom fogs; /* fog state (4BC0) */
+ struct r300_state_atom fogc; /* fog color (4BC8) */
struct r300_state_atom at; /* alpha test (4BD4) */
struct r300_state_atom unk4BD8; /* (4BD8) */
struct r300_state_atom fpp; /* 0x4C00 and following */
@@ -532,7 +551,8 @@ struct r300_vap_reg_state {
/* Vertex shader state */
/* Perhaps more if we store programs in vmem? */
-#define VSF_MAX_FRAGMENT_LENGTH (256*4)
+/* drm_r300_cmd_header_t->vpu->count is unsigned char */
+#define VSF_MAX_FRAGMENT_LENGTH (255*4)
/* Can be tested with colormat currently. */
#define VSF_MAX_FRAGMENT_TEMPS (14)
@@ -759,7 +779,7 @@ struct r300_state {
GLuint *Elts;
struct r300_dma_region elt_dma;
- GLuint render_inputs; /* actual render inputs that R300 was configured for.
+ DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for.
They are the same as tnl->render_inputs for fixed pipeline */
struct {
@@ -810,6 +830,7 @@ struct r300_context {
#endif
GLboolean texmicrotile;
+ GLboolean span_dlocking;
};
struct r300_buffer_object {
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index db509059dd7..e045f0c6a1e 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -1039,7 +1039,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
const struct prog_instruction *inst = mp->Base.Instructions;
struct prog_instruction *fpi;
pfs_reg_t src[3], dest, temp;
- int flags, mask;
+ int flags, mask = 0;
if (!inst || inst[0].Opcode == OPCODE_END) {
ERROR("empty program?\n");
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index 0115d622a99..159285962d2 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -380,10 +380,16 @@ static void r300EmitClearState(GLcontext * ctx)
int i;
LOCAL_VARS;
+
R300_STATECHANGE(r300, vir[0]);
reg_start(R300_VAP_INPUT_ROUTE_0_0, 0);
e32(0x21030003);
+ /* disable fog */
+ R300_STATECHANGE(r300, fogs);
+ reg_start(R300_RE_FOG_STATE, 0);
+ e32(0x0);
+
R300_STATECHANGE(r300, vir[1]);
reg_start(R300_VAP_INPUT_ROUTE_1_0, 0);
e32(0xF688F688);
@@ -553,7 +559,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
#ifdef CB_DPATH
/* Make sure it fits there. */
- r300EnsureCmdBufSpace(r300, 419*3, __FUNCTION__);
+ r300EnsureCmdBufSpace(r300, 421*3, __FUNCTION__);
if(flags || bits)
r300EmitClearState(ctx);
#endif
diff --git a/src/mesa/drivers/dri/r300/r300_maos.c b/src/mesa/drivers/dri/r300/r300_maos.c
index 1aa005c7207..6b8365e6d9e 100644
--- a/src/mesa/drivers/dri/r300/r300_maos.c
+++ b/src/mesa/drivers/dri/r300/r300_maos.c
@@ -252,6 +252,43 @@ void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts, int elt_siz
memcpy(out, elts, n_elts * elt_size);
}
+ /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
+#define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
+
+#define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
+
+
+static GLuint t_comps(GLuint aos_size)
+{
+ GLuint mask;
+ mask = (1 << (aos_size*3)) - 1;
+ return (ALL_COMPONENTS & mask) | (ALL_DEFAULT & ~mask);
+}
+
+static GLuint fix_comps(GLuint dw, int fmt)
+{
+#ifdef MESA_BIG_ENDIAN
+ if (fmt == 2) {
+ GLuint dw_temp = 0;
+
+ dw_temp |= ((dw >> R300_INPUT_ROUTE_X_SHIFT) & R300_INPUT_ROUTE_SELECT_MASK) << R300_INPUT_ROUTE_W_SHIFT;
+ dw_temp |= ((dw >> R300_INPUT_ROUTE_Y_SHIFT) & R300_INPUT_ROUTE_SELECT_MASK) << R300_INPUT_ROUTE_Z_SHIFT;
+ dw_temp |= ((dw >> R300_INPUT_ROUTE_Z_SHIFT) & R300_INPUT_ROUTE_SELECT_MASK) << R300_INPUT_ROUTE_Y_SHIFT;
+ dw_temp |= ((dw >> R300_INPUT_ROUTE_W_SHIFT) & R300_INPUT_ROUTE_SELECT_MASK) << R300_INPUT_ROUTE_X_SHIFT;
+
+ return dw_temp;
+ }
+#endif /* MESA_BIG_ENDIAN */
+ return dw;
+
+}
+
/* Emit vertex data to GART memory (unless immediate mode)
* Route inputs to the vertex processor
*/
@@ -264,12 +301,14 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
//struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLuint nr = 0;
GLuint count = VB->Count;
- GLuint dw,mask;
+ GLuint dw;
GLuint vic_1 = 0; /* R300_VAP_INPUT_CNTL_1 */
GLuint aa_vap_reg = 0; /* VAP register assignment */
GLuint i;
- GLuint inputs = 0;
-
+ DECLARE_RENDERINPUTS(inputs_bitset);
+
+ RENDERINPUTS_ZERO( inputs_bitset );
+
#define CONFIGURE_AOS(r, f, v, sz, cn) { \
if (RADEON_DEBUG & DEBUG_STATE) \
fprintf(stderr, "Enabling "#v "\n"); \
@@ -300,23 +339,23 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
GLuint InputsRead = CURRENT_VERTEX_SHADER(ctx)->Base.InputsRead;
struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
if (InputsRead & (1<<VERT_ATTRIB_POS)) {
- inputs |= _TNL_BIT_POS;
+ RENDERINPUTS_SET( inputs_bitset, _TNL_ATTRIB_POS );
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_POS];
}
if (InputsRead & (1<<VERT_ATTRIB_NORMAL)) {
- inputs |= _TNL_BIT_NORMAL;
+ RENDERINPUTS_SET( inputs_bitset, _TNL_ATTRIB_NORMAL );
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_NORMAL];
}
if (InputsRead & (1<<VERT_ATTRIB_COLOR0)) {
- inputs |= _TNL_BIT_COLOR0;
+ RENDERINPUTS_SET( inputs_bitset, _TNL_ATTRIB_COLOR0 );
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR0];
}
if (InputsRead & (1<<VERT_ATTRIB_COLOR1)) {
- inputs |= _TNL_BIT_COLOR1;
+ RENDERINPUTS_SET( inputs_bitset, _TNL_ATTRIB_COLOR1 );
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR1];
}
if (InputsRead & (1<<VERT_ATTRIB_FOG)) {
- inputs |= _TNL_BIT_FOG;
+ RENDERINPUTS_SET( inputs_bitset, _TNL_ATTRIB_FOG );
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_FOG];
}
if(ctx->Const.MaxTextureUnits > 8) { /* Not sure if this can even happen... */
@@ -325,17 +364,17 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
}
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
if (InputsRead & (1<<(VERT_ATTRIB_TEX0+i))) {
- inputs |= _TNL_BIT_TEX0<<i;
+ RENDERINPUTS_SET( inputs_bitset, _TNL_ATTRIB_TEX(i) );
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_TEX0+i];
}
}
nr = 0;
} else {
- inputs = TNL_CONTEXT(ctx)->render_inputs;
+ RENDERINPUTS_COPY( inputs_bitset, TNL_CONTEXT(ctx)->render_inputs_bitset );
}
- rmesa->state.render_inputs = inputs;
+ RENDERINPUTS_COPY( rmesa->state.render_inputs_bitset, inputs_bitset );
- if (inputs & _TNL_BIT_POS) {
+ if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_POS )) {
CONFIGURE_AOS(i_coords, AOS_FORMAT_FLOAT,
VB->AttribPtr[VERT_ATTRIB_POS],
immd ? 4 : VB->AttribPtr[VERT_ATTRIB_POS].size,
@@ -344,7 +383,7 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
vic_1 |= R300_INPUT_CNTL_POS;
}
- if (inputs & _TNL_BIT_NORMAL) {
+ if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_NORMAL )) {
CONFIGURE_AOS(i_normal, AOS_FORMAT_FLOAT,
VB->AttribPtr[VERT_ATTRIB_NORMAL],
immd ? 4 : VB->AttribPtr[VERT_ATTRIB_NORMAL].size,
@@ -353,7 +392,7 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
vic_1 |= R300_INPUT_CNTL_NORMAL;
}
- if (inputs & _TNL_BIT_COLOR0) {
+ if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_COLOR0 )) {
int emitsize=4;
if (!immd) {
@@ -376,7 +415,7 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
vic_1 |= R300_INPUT_CNTL_COLOR;
}
- if (inputs & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_COLOR1 )) {
int emitsize=4;
if (!immd) {
@@ -398,7 +437,7 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
}
#if 0
- if (inputs & _TNL_BIT_FOG) {
+ if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_FOG )) {
CONFIGURE_AOS( AOS_FORMAT_FLOAT,
VB->FogCoordPtr,
immd ? 4 : VB->FogCoordPtr->size,
@@ -408,7 +447,7 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
r300->state.texture.tc_count = 0;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- if (inputs & (_TNL_BIT_TEX0 << i)) {
+ if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
CONFIGURE_AOS(i_tex[i], AOS_FORMAT_FLOAT,
VB->AttribPtr[VERT_ATTRIB_TEX0+i],
immd ? 4 : VB->AttribPtr[VERT_ATTRIB_TEX0+i].size,
@@ -467,17 +506,6 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->packet0.count = (nr+1)>>1;
- /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
-#define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
- | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
- | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
- | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
-
-#define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
- | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
- | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
- | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
-
R300_STATECHANGE(r300, vir[1]);
for(i=0; i < nr; i++)
@@ -486,33 +514,22 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
r300->state.aos[i].aos_size=/*3*/4; /* XXX */
}
-
- for(i=0;i+1<nr;i+=2){
+ for (i=0;i+1<nr;i+=2) {
/* do i first.. */
- mask=(1<<(r300->state.aos[i].aos_size*3))-1;
- dw=(ALL_COMPONENTS & mask)
- | (ALL_DEFAULT & ~mask)
- | R300_INPUT_ROUTE_ENABLE;
-
+ dw = fix_comps(t_comps(r300->state.aos[i].aos_size), r300->state.aos[i].aos_format) | R300_INPUT_ROUTE_ENABLE;
/* i+1 */
- mask=(1<<(r300->state.aos[i+1].aos_size*3))-1;
- dw|=(
- (ALL_COMPONENTS & mask)
- | (ALL_DEFAULT & ~mask)
- | R300_INPUT_ROUTE_ENABLE
- )<<16;
-
+ dw |= (fix_comps(t_comps(r300->state.aos[i+1].aos_size), r300->state.aos[i+1].aos_format) | R300_INPUT_ROUTE_ENABLE) << 16;
+
//fprintf(stderr, "vir1 dw=%08x\n", dw);
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
- }
- if(nr & 1){
- mask=(1<<(r300->state.aos[nr-1].aos_size*3))-1;
- dw=(ALL_COMPONENTS & mask)
- | (ALL_DEFAULT & ~mask)
- | R300_INPUT_ROUTE_ENABLE;
- r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(nr>>1)]=dw;
+ }
+ if (nr & 1) {
+ dw = fix_comps(t_comps(r300->state.aos[nr-1].aos_size), r300->state.aos[nr-1].aos_format) | R300_INPUT_ROUTE_ENABLE;
+
//fprintf(stderr, "vir1 dw=%08x\n", dw);
- }
+ r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(nr>>1)]=dw;
+ }
+
/* Set the rest of INPUT_ROUTE_1 to 0 */
//for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->packet0.count = (nr+1)>>1;
@@ -531,17 +548,17 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
#if 0
r300->hw.vic.cmd[R300_VIC_CNTL_1]=0;
- if(r300->state.render_inputs & _TNL_BIT_POS)
+ if(RENDERINPUTS_TEST( r300->state.render_inputs_bitset, _TNL_ATTRIB_POS ))
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_POS;
- if(r300->state.render_inputs & _TNL_BIT_NORMAL)
+ if(RENDERINPUTS_TEST( r300->state.render_inputs_bitset, _TNL_ATTRIB_NORMAL ))
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_NORMAL;
- if(r300->state.render_inputs & _TNL_BIT_COLOR0)
+ if(RENDERINPUTS_TEST( r300->state.render_inputs_bitset, _TNL_ATTRIB_COLOR0 ))
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_COLOR;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
- if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i))
+ if(RENDERINPUTS_TEST( r300->state.render_inputs_bitset, _TNL_ATTRIB_TEX(i) ))
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
#endif
@@ -573,15 +590,15 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
if(OutputsWritten & (1<<(VERT_RESULT_TEX0+i)))
r300->hw.vof.cmd[R300_VOF_CNTL_1] |= (4<<(3*i));
} else {
- if(inputs & _TNL_BIT_POS)
+ if(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_POS ))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
- if(inputs & _TNL_BIT_COLOR0)
+ if(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_COLOR0 ))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
- if(inputs & _TNL_BIT_COLOR1)
+ if(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_COLOR1 ))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
- if(inputs & (_TNL_BIT_TEX0<<i))
+ if(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_TEX(i) ))
r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
}
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index c78462af2ed..4afe4f239c2 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -517,6 +517,10 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_PM_BACK_LINE (1 << 7)
# define R300_PM_BACK_FILL (1 << 8)
+/* Fog parameters */
+#define R300_RE_FOG_SCALE 0x4294
+#define R300_RE_FOG_START 0x4298
+
/* Not sure why there are duplicate of factor and constant values.
My best guess so far is that there are seperate zbiases for test and write.
Ordering might be wrong.
@@ -1113,7 +1117,17 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_FPI2_UNKNOWN_31 (1 << 31)
/* END */
-/* gap */
+/* Fog state and color */
+#define R300_RE_FOG_STATE 0x4BC0
+# define R300_FOG_ENABLE (1 << 0)
+# define R300_FOG_MODE_LINEAR (0 << 1)
+# define R300_FOG_MODE_EXP (1 << 1)
+# define R300_FOG_MODE_EXP2 (2 << 1)
+# define R300_FOG_MODE_MASK (3 << 1)
+#define R300_FOG_COLOR_R 0x4BC8
+#define R300_FOG_COLOR_G 0x4BCC
+#define R300_FOG_COLOR_B 0x4BD0
+
#define R300_PP_ALPHA_TEST 0x4BD4
# define R300_REF_ALPHA_MASK 0x000000ff
# define R300_ALPHA_TEST_FAIL (0 << 8)
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index a0375f90227..f86a439bc29 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -382,7 +382,6 @@ GLboolean r300_run_vb_render(GLcontext *ctx,
r300UpdateShaders(rmesa);
if (rmesa->state.VB.LockCount == 0 || 1) {
- r300ReleaseArrays(ctx);
r300EmitArrays(ctx, GL_FALSE);
r300UpdateShaderStates(rmesa);
@@ -446,6 +445,7 @@ GLboolean r300_run_vb_render(GLcontext *ctx,
#ifdef USER_BUFFERS
r300UseArrays(ctx);
#endif
+ r300ReleaseArrays(ctx);
return GL_FALSE;
}
@@ -462,19 +462,19 @@ int r300Fallback(GLcontext *ctx)
{
int i;
- //FALLBACK_IF(ctx->RenderMode != GL_RENDER); // We do not do SELECT or FEEDBACK (yet ?)
+ FALLBACK_IF(ctx->RenderMode != GL_RENDER); // We do not do SELECT or FEEDBACK (yet ?)
#if 0 /* These should work now.. */
FALLBACK_IF(ctx->Color.DitherFlag);
FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
+ FALLBACK_IF(ctx->Fog.Enabled);
#endif
FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
//FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
- //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
//FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH disabling to get blender going
FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index d4dafe62a73..70d42c2ea3b 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -417,6 +417,24 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
case GL_TEXTURE_3D:
break;
+ case GL_FOG:
+ R300_STATECHANGE(r300, fogs);
+ if (state) {
+ r300->hw.fogs.cmd[R300_FOGS_STATE] |=
+ R300_FOG_ENABLE;
+
+ ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL );
+ ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+ ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
+ ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
+ ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
+ } else {
+ r300->hw.fogs.cmd[R300_FOGS_STATE] &=
+ ~R300_FOG_ENABLE;
+ }
+
+ break;
+
case GL_ALPHA_TEST:
R300_STATECHANGE(r300, at);
if (state) {
@@ -640,6 +658,101 @@ static void r300ColorMask(GLcontext* ctx,
}
/* =============================================================
+ * Fog
+ */
+static void r300Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ union { int i; float f; } fogScale, fogStart;
+
+ (void) param;
+
+ fogScale.i = r300->hw.fogp.cmd[R300_FOGP_SCALE];
+ fogStart.i = r300->hw.fogp.cmd[R300_FOGP_START];
+
+ switch (pname) {
+ case GL_FOG_MODE:
+ if (!ctx->Fog.Enabled)
+ return;
+ switch (ctx->Fog.Mode) {
+ case GL_LINEAR:
+ R300_STATECHANGE(r300, fogs);
+ r300->hw.fogs.cmd[R300_FOGS_STATE] =
+ (r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_LINEAR;
+
+ if (ctx->Fog.Start == ctx->Fog.End) {
+ fogScale.f = -1.0;
+ fogStart.f = 1.0;
+ }
+ else {
+ fogScale.f = 1.0 / (ctx->Fog.End-ctx->Fog.Start);
+ fogStart.f = -ctx->Fog.Start / (ctx->Fog.End-ctx->Fog.Start);
+ }
+ break;
+ case GL_EXP:
+ R300_STATECHANGE(r300, fogs);
+ r300->hw.fogs.cmd[R300_FOGS_STATE] =
+ (r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_EXP;
+ fogScale.f = 0.0933*ctx->Fog.Density;
+ fogStart.f = 0.0;
+ break;
+ case GL_EXP2:
+ R300_STATECHANGE(r300, fogs);
+ r300->hw.fogs.cmd[R300_FOGS_STATE] =
+ (r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_EXP2;
+ fogScale.f = 0.3*ctx->Fog.Density;
+ fogStart.f = 0.0;
+ default:
+ return;
+ }
+ break;
+ case GL_FOG_DENSITY:
+ switch (ctx->Fog.Mode) {
+ case GL_EXP:
+ fogScale.f = 0.0933*ctx->Fog.Density;
+ fogStart.f = 0.0;
+ break;
+ case GL_EXP2:
+ fogScale.f = 0.3*ctx->Fog.Density;
+ fogStart.f = 0.0;
+ default:
+ break;
+ }
+ break;
+ case GL_FOG_START:
+ case GL_FOG_END:
+ if (ctx->Fog.Mode == GL_LINEAR) {
+ if (ctx->Fog.Start == ctx->Fog.End) {
+ fogScale.f = -1.0;
+ fogStart.f = 1.0;
+ }
+ else {
+ fogScale.f = 1.0 / (ctx->Fog.End-ctx->Fog.Start);
+ fogStart.f = -ctx->Fog.Start / (ctx->Fog.End-ctx->Fog.Start);
+ }
+ }
+ break;
+ case GL_FOG_COLOR:
+ R300_STATECHANGE(r300, fogc);
+ r300->hw.fogc.cmd[R300_FOGC_R] = (GLuint) (ctx->Fog.Color[0]*1023.0F) & 0x3FF;
+ r300->hw.fogc.cmd[R300_FOGC_G] = (GLuint) (ctx->Fog.Color[1]*1023.0F) & 0x3FF;
+ r300->hw.fogc.cmd[R300_FOGC_B] = (GLuint) (ctx->Fog.Color[2]*1023.0F) & 0x3FF;
+ break;
+ case GL_FOG_COORD_SRC:
+ break;
+ default:
+ return;
+ }
+
+ if (fogScale.i != r300->hw.fogp.cmd[R300_FOGP_SCALE] ||
+ fogStart.i != r300->hw.fogp.cmd[R300_FOGP_START]) {
+ R300_STATECHANGE(r300, fogp);
+ r300->hw.fogp.cmd[R300_FOGP_SCALE] = fogScale.i;
+ r300->hw.fogp.cmd[R300_FOGP_START] = fogStart.i;
+ }
+}
+
+/* =============================================================
* Point state
*/
static void r300PointSize(GLcontext * ctx, GLfloat size)
@@ -750,8 +863,8 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
GLenum func, GLint ref, GLuint mask)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- GLuint refmask = ((ctx->Stencil.Ref[0] << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
- (ctx->Stencil.ValueMask[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
+ GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
+ ((ctx->Stencil.ValueMask[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
GLuint flag;
@@ -777,7 +890,7 @@ static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
R300_STATECHANGE(rmesa, zs);
rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~(R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT);
- rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT;
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= (ctx->Stencil.WriteMask[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT;
}
@@ -807,9 +920,9 @@ static void r300ClearStencil(GLcontext * ctx, GLint s)
r300ContextPtr rmesa = R300_CONTEXT(ctx);
rmesa->state.stencil.clear =
- ((GLuint) ctx->Stencil.Clear |
+ ((GLuint) (ctx->Stencil.Clear & 0xff) |
(R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT) |
- (ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT));
+ ((ctx->Stencil.WriteMask[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT));
}
/* =============================================================
@@ -1157,6 +1270,15 @@ void r300_setup_textures(GLcontext *ctx)
fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], last_hw_tmu);
}
+union r300_outputs_written {
+ GLuint vp_outputs; /* hw_tcl_on */
+ DECLARE_RENDERINPUTS(index_bitset); /* !hw_tcl_on */
+};
+
+#define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
+ ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
+ RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
+
void r300_setup_rs_unit(GLcontext *ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
@@ -1171,16 +1293,16 @@ void r300_setup_rs_unit(GLcontext *ctx)
0x00,
0x00
};
- GLuint OutputsWritten;
+ union r300_outputs_written OutputsWritten;
GLuint InputsRead;
int fp_reg, high_rr;
int in_texcoords, col_interp_nr;
int i;
if(hw_tcl_on)
- OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten;
+ OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten;
else
- OutputsWritten = r300->state.render_inputs;
+ RENDERINPUTS_COPY( OutputsWritten.index_bitset, r300->state.render_inputs_bitset );
if (ctx->FragmentProgram._Current)
InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
@@ -1211,7 +1333,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
| (fp_reg << R300_RS_ROUTE_DEST_SHIFT);
high_rr = fp_reg;
- if (!(OutputsWritten & (hw_tcl_on ? (1 << (VERT_RESULT_TEX0+i)) : (_TNL_BIT_TEX0<<i)))) {
+ 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);
@@ -1221,12 +1343,12 @@ void r300_setup_rs_unit(GLcontext *ctx)
fp_reg++;
}
/* Need to count all coords enabled at vof */
- if (OutputsWritten & (hw_tcl_on ? (1 << (VERT_RESULT_TEX0+i)) : (_TNL_BIT_TEX0<<i)))
+ if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten, VERT_RESULT_TEX0+i, _TNL_ATTRIB_TEX(i) ))
in_texcoords++;
}
if (InputsRead & FRAG_BIT_COL0) {
- if (!(OutputsWritten & (hw_tcl_on ? (1<<VERT_RESULT_COL0) : _TNL_BIT_COLOR0))) {
+ 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);
@@ -1242,7 +1364,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
out:
if (InputsRead & FRAG_BIT_COL1) {
- if (!(OutputsWritten & (hw_tcl_on ? (1<<VERT_RESULT_COL1) : _TNL_BIT_COLOR1))) {
+ if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1 )) {
WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
//exit(-1);
}
@@ -1281,6 +1403,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
#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; \
+ assert(_nc < 256); \
if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
}while(0)
@@ -1402,7 +1525,7 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
)
o_reg += 2;
- if (r300->state.render_inputs & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( r300->state.render_inputs_bitset, _TNL_ATTRIB_COLOR1 )) {
WRITE_OP(
EASY_VSF_OP(MUL, o_reg++, ALL, RESULT),
VSF_REG(r300->state.vap_reg.i_color[1]),
@@ -1413,7 +1536,7 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
/* Pass through texture coordinates, if any */
for(i=0;i < r300->radeon.glCtx->Const.MaxTextureUnits;i++)
- if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i)){
+ if (RENDERINPUTS_TEST( r300->state.render_inputs_bitset, _TNL_ATTRIB_TEX(i) )){
// fprintf(stderr, "i_tex[%d]=%d\n", i, r300->state.vap_reg.i_tex[i]);
WRITE_OP(
EASY_VSF_OP(MUL, o_reg++ /* 2+i */, ALL, RESULT),
@@ -1870,7 +1993,8 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_RV300
| R300_GB_TILE_SIZE_16;
- r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
+ /* set to 0 when fog is disabled? */
+ r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = R300_GB_FOG_SELECT_1_1_W;
r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
//r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
@@ -1907,9 +2031,6 @@ void r300ResetHwState(r300ContextPtr r300)
r300PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode);
r300->hw.unk4288.cmd[2] = 0x00000001;
r300->hw.unk4288.cmd[3] = 0x00000000;
- r300->hw.unk4288.cmd[4] = 0x00000000;
- r300->hw.unk4288.cmd[5] = 0x00000000;
-
r300->hw.unk42A0.cmd[1] = 0x00000000;
r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor, ctx->Polygon.OffsetUnits);
@@ -1949,13 +2070,13 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
}
#endif
-
- r300->hw.unk4BC0.cmd[1] = 0;
-
- r300->hw.unk4BC8.cmd[1] = 0;
- r300->hw.unk4BC8.cmd[2] = 0;
- r300->hw.unk4BC8.cmd[3] = 0;
-
+ r300Enable(ctx, GL_FOG, ctx->Fog.Enabled);
+ ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL );
+ ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+ ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
+ ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
+ ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
+ ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL );
r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
r300->hw.unk4BD8.cmd[1] = 0;
@@ -2128,6 +2249,7 @@ void r300InitStateFuncs(struct dd_function_table* functions)
functions->DepthFunc = r300DepthFunc;
functions->DepthMask = r300DepthMask;
functions->CullFace = r300CullFace;
+ functions->Fogfv = r300Fogfv;
functions->FrontFace = r300FrontFace;
functions->ShadeModel = r300ShadeModel;
diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c
index a9f64b47c4c..c1d01020cdb 100644
--- a/src/mesa/drivers/dri/r300/r300_texmem.c
+++ b/src/mesa/drivers/dri/r300/r300_texmem.c
@@ -130,6 +130,12 @@ static void r300UploadGARTClientSubImage(r300ContextPtr rmesa,
srcPitch = t->image[0][0].width * texFormat->TexelBytes;
dstPitch = t->image[0][0].width * texFormat->TexelBytes;
break;
+ case 8:
+ case 16:
+ blit_format = R200_CP_COLOR_FORMAT_CI8;
+ srcPitch = t->image[0][0].width * texFormat->TexelBytes;
+ dstPitch = t->image[0][0].width * texFormat->TexelBytes;
+ break;
default:
return;
}
@@ -144,6 +150,10 @@ static void r300UploadGARTClientSubImage(r300ContextPtr rmesa,
width = texImage->Width;
height = texImage->Height;
+ if (texFormat->TexelBytes > 4) {
+ width *= texFormat->TexelBytes;
+ }
+
r300EmitWait(rmesa, R300_WAIT_3D);
r300EmitBlit(rmesa, blit_format,
@@ -177,6 +187,10 @@ static void r300UploadRectSubImage(r300ContextPtr rmesa,
case 4:
blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
break;
+ case 8:
+ case 16:
+ blit_format = R200_CP_COLOR_FORMAT_CI8;
+ break;
default:
return;
}
@@ -189,6 +203,10 @@ static void r300UploadRectSubImage(r300ContextPtr rmesa,
height = texImage->Height;
dstPitch = t->pitch;
+ if (texFormat->TexelBytes > 4) {
+ width *= texFormat->TexelBytes;
+ }
+
if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) {
/* In this case, could also use GART texturing. This is
* currently disabled, but has been tested & works.
diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c
index f794c9aa67a..9e32cfcfef9 100644
--- a/src/mesa/drivers/dri/r300/r300_vertexprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c
@@ -916,6 +916,16 @@ void r300_translate_vertex_shader(struct r300_vertex_program *vp)
fprintf(stderr, "Dont know how to handle op %d yet\n", vpi->Opcode);
exit(-1);
break;
+ case OPCODE_SWZ:
+ hw_op=(src[0].File == PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : R300_VPI_OUT_OP_MAD;
+
+ o_inst->op=MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask), t_dst_class(vpi->DstReg.File));
+ o_inst->src1=t_src(vp, &src[0]);
+ o_inst->src2=ONE_SRC_0;
+ o_inst->src3=ZERO_SRC_0;
+
+ goto next;
case OPCODE_END:
break;
default:
diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c
index 4e351dd66b0..0147c6492e5 100644
--- a/src/mesa/drivers/dri/r300/radeon_context.c
+++ b/src/mesa/drivers/dri/r300/radeon_context.c
@@ -76,7 +76,7 @@ static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
case GL_RENDERER:
{
unsigned offset;
- GLuint agp_mode = radeon->radeonScreen->IsPCI ? 0 :
+ GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
radeon->radeonScreen->AGPMode;
const char* chipname;
diff --git a/src/mesa/drivers/dri/r300/radeon_span.c b/src/mesa/drivers/dri/r300/radeon_span.c
index 1f000b97666..1b74f6779b4 100644
--- a/src/mesa/drivers/dri/r300/radeon_span.c
+++ b/src/mesa/drivers/dri/r300/radeon_span.c
@@ -40,7 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Keith Whitwell <keith@tungstengraphics.com>
*
*/
-
+#include <unistd.h>
#include "glheader.h"
#include "imports.h"
#include "swrast/swrast.h"
@@ -252,6 +252,29 @@ do { \
static void radeonSpanRenderStart( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+ {
+ static int first = 1;
+ r300ContextPtr r300 = (r300ContextPtr)rmesa;
+
+ if (first) {
+ r300->span_dlocking = getenv("R300_SPAN_DISABLE_LOCKING") ? 1 : 0;
+ if (r300->span_dlocking == 0) {
+ fprintf(stderr, "Try R300_SPAN_DISABLE_LOCKING env var if this hangs.\n");
+ fflush(stderr);
+ sleep(1);
+ }
+ first = 0;
+ }
+
+ if (r300->span_dlocking) {
+ r300Flush(ctx);
+ LOCK_HARDWARE( rmesa );
+ radeonWaitForIdleLocked( rmesa );
+ UNLOCK_HARDWARE( rmesa );
+
+ return;
+ }
+ }
// R300_FIREVERTICES( rmesa );
// old code has flush
r300Flush(ctx);
@@ -262,8 +285,10 @@ static void radeonSpanRenderStart( GLcontext *ctx )
static void radeonSpanRenderFinish( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+ r300ContextPtr r300 = (r300ContextPtr)rmesa;
_swrast_flush( ctx );
- UNLOCK_HARDWARE( rmesa );
+ if (r300->span_dlocking == 0)
+ UNLOCK_HARDWARE( rmesa );
}
void radeonInitSpanFuncs( GLcontext *ctx )
diff --git a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c
index 5ea9bb4eb45..1044973b001 100644
--- a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c
+++ b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c
@@ -71,7 +71,7 @@ void radeon_vb_to_rvb(r300ContextPtr rmesa, struct radeon_vertex_buffer *rvb, st
CONV_VB(VERT_ATTRIB_COLOR1, SecondaryColorPtr[0]);
CONV_VB(VERT_ATTRIB_FOG, FogCoordPtr);
- for (i=0; i < MAX_TEXTURE_COORD_UNITS; i++)
+ for (i=0; i < ctx->Const.MaxTextureCoordUnits; i++)
CONV_VB(VERT_ATTRIB_TEX0 + i, TexCoordPtr[i]);
rvb->Primitive = vb->Primitive;
@@ -182,7 +182,7 @@ static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const G
unsigned int min = ~0, max = 0;
struct tnl_prim prim;
static void *ptr = NULL;
- static struct r300_dma_region rvb;
+ struct r300_dma_region rvb;
const GLvoid *indices = c_indices;
if (count > 65535) {
@@ -205,8 +205,8 @@ static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const G
return;
FLUSH_CURRENT( ctx, 0 );
- r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
+ memset(&rvb, 0, sizeof(rvb));
switch (type) {
case GL_UNSIGNED_BYTE:
for (i=0; i < count; i++) {
@@ -216,14 +216,22 @@ static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const G
max = ((unsigned char *)indices)[i];
}
+#ifdef FORCE_32BITS_ELTS
+ elt_size = 4;
+#else
elt_size = 2;
-
+#endif
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
+#ifdef FORCE_32BITS_ELTS
+ for (i=0; i < count; i++)
+ ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
+#else
for (i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
+#endif
break;
case GL_UNSIGNED_SHORT:
@@ -234,14 +242,23 @@ static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const G
max = ((unsigned short int *)indices)[i];
}
+#ifdef FORCE_32BITS_ELTS
+ elt_size = 4;
+#else
elt_size = 2;
+#endif
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
+#ifdef FORCE_32BITS_ELTS
+ for (i=0; i < count; i++)
+ ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
+#else
for (i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
+#endif
break;
case GL_UNSIGNED_INT:
@@ -252,17 +269,20 @@ static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const G
max = ((unsigned int *)indices)[i];
}
+#ifdef FORCE_32BITS_ELTS
+ elt_size = 4;
+#else
if (max - min <= 65535)
elt_size = 2;
else
elt_size = 4;
-
+#endif
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
- if (max - min <= 65535)
+ if (elt_size == 2)
for (i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
else
@@ -278,12 +298,12 @@ static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const G
if (ctx->NewState)
_mesa_update_state( ctx );
- for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+ for (i=_TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &rmesa->dummy_attrib[i];
}
r300UpdateShaders(rmesa);
- for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+ for (i=_TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
}
@@ -311,8 +331,10 @@ static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const G
return;
}
} else {
- if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL)
+ if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) {
+ r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
goto fallback;
+ }
rmesa->state.VB.Count = max - min + 1;
}
@@ -337,6 +359,7 @@ static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const G
if(rvb.buf)
radeon_mm_use(rmesa, rvb.buf->id);
+ r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
return;
fallback:
@@ -355,7 +378,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
int elt_size;
int i;
void *ptr = NULL;
- static struct r300_dma_region rvb;
+ struct r300_dma_region rvb;
const GLvoid *indices = c_indices;
if (count > 65535) {
@@ -381,23 +404,34 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
#ifdef OPTIMIZE_ELTS
min = 0;
#endif
- r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
- switch(type){
+ memset(&rvb, 0, sizeof(rvb));
+ switch (type){
case GL_UNSIGNED_BYTE:
+#ifdef FORCE_32BITS_ELTS
+ elt_size = 4;
+#else
elt_size = 2;
-
+#endif
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
+#ifdef FORCE_32BITS_ELTS
+ for(i=0; i < count; i++)
+ ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
+#else
for(i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
+#endif
break;
case GL_UNSIGNED_SHORT:
+#ifdef FORCE_32BITS_ELTS
+ elt_size = 4;
+#else
elt_size = 2;
-
+#endif
#ifdef OPTIMIZE_ELTS
if (min == 0 && ctx->Array.ElementArrayBufferObj->Name){
ptr = indices;
@@ -408,21 +442,29 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
+#ifdef FORCE_32BITS_ELTS
+ for(i=0; i < count; i++)
+ ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
+#else
for(i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
+#endif
break;
case GL_UNSIGNED_INT:
+#ifdef FORCE_32BITS_ELTS
+ elt_size = 4;
+#else
if (max - min <= 65535)
elt_size = 2;
else
elt_size = 4;
-
+#endif
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
- if (max - min <= 65535)
+ if (elt_size == 2)
for (i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
else
@@ -440,12 +482,12 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
if (ctx->NewState)
_mesa_update_state( ctx );
- for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+ for (i=_TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &rmesa->dummy_attrib[i];
}
r300UpdateShaders(rmesa);
- for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+ for (i=_TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
}
@@ -473,8 +515,10 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
return;
}*/
} else {
- if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL)
+ if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) {
+ r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
goto fallback;
+ }
rmesa->state.VB.Count = max - min + 1;
}
@@ -501,6 +545,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
if(rvb.buf)
radeon_mm_use(rmesa, rvb.buf->id);
+ r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
return ;
fallback:
@@ -533,12 +578,12 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count )
/* XXX: setup_arrays before state update? */
- for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+ for (i=_TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &rmesa->dummy_attrib[i];
}
r300UpdateShaders(rmesa);
- for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+ for (i=_TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
}
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile
index 34dc58e2dc2..6e46620b397 100644
--- a/src/mesa/drivers/dri/radeon/Makefile
+++ b/src/mesa/drivers/dri/radeon/Makefile
@@ -32,7 +32,7 @@ C_SOURCES = \
$(COMMON_SOURCES) \
$(DRIVER_SOURCES)
-DEFINES += -DRADEON_COMMON=0
+DRIVER_DEFINES = -DRADEON_COMMON=0
X86_SOURCES = \
radeon_vtxtmp_x86.S
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 791d1a37bc0..21161d2f69d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -102,7 +102,7 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
static char buffer[128];
unsigned offset;
- GLuint agp_mode = rmesa->radeonScreen->IsPCI ? 0 :
+ GLuint agp_mode = (rmesa->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
rmesa->radeonScreen->AGPMode;
switch ( name ) {
@@ -521,10 +521,6 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
radeonVtxfmtDestroy( rmesa->glCtx );
}
- /* free the Mesa context */
- rmesa->glCtx->DriverCtx = NULL;
- _mesa_destroy_context( rmesa->glCtx );
-
_mesa_vector4f_free( &rmesa->tcl.ObjClean );
if (rmesa->state.scissor.pClipRects) {
@@ -546,6 +542,10 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
assert( is_empty_list( & rmesa->swapped ) );
}
+ /* free the Mesa context */
+ rmesa->glCtx->DriverCtx = NULL;
+ _mesa_destroy_context( rmesa->glCtx );
+
/* free the option cache */
driDestroyOptionCache (&rmesa->optionCache);
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h
index 9abd8667308..9902e60c595 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_context.h
@@ -735,7 +735,7 @@ struct radeon_context {
GLuint TclFallback;
GLuint Fallback;
GLuint NewGLState;
- GLuint tnl_index; /* index of bits for last tnl_install_attrs */
+ DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */
/* Vertex buffers
*/
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 5257e541e5f..3a0a8d208b2 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -159,7 +159,7 @@ DRI_CONF_BEGIN
DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
- DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(16, 2, 16)
+ DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(8, 2, 8)
DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8)
DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
DRI_CONF_SECTION_END
@@ -209,6 +209,19 @@ extern const struct dri_extension card_extensions[];
static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
+static int
+radeonGetParam(int fd, int param, void *value)
+{
+ int ret;
+ drm_radeon_getparam_t gp;
+
+ gp.param = param;
+ gp.value = value;
+
+ ret = drmCommandWriteRead( fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
+ return ret;
+}
+
static __GLcontextModes *
radeonFillInModes( unsigned pixel_bits, unsigned depth_bits,
unsigned stencil_bits, GLboolean have_back_buffer )
@@ -326,52 +339,39 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
/* This is first since which regions we map depends on whether or
* not we are using a PCI card.
*/
- screen->IsPCI = dri_priv->IsPCI;
-
+ screen->card_type = (dri_priv->IsPCI ? RADEON_CARD_PCI : RADEON_CARD_AGP);
{
int ret;
- drm_radeon_getparam_t gp;
-
- gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
- gp.value = &screen->gart_buffer_offset;
-
- ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
- &gp, sizeof(gp));
+ ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BUFFER_OFFSET,
+ &screen->gart_buffer_offset);
+
if (ret) {
FREE( screen );
fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
return NULL;
}
- if (sPriv->drmMinor >= 6) {
- gp.param = RADEON_PARAM_GART_BASE;
- gp.value = &screen->gart_base;
-
- ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
- &gp, sizeof(gp));
- if (ret) {
- FREE( screen );
- fprintf(stderr, "drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n", ret);
- return NULL;
- }
-
- gp.param = RADEON_PARAM_IRQ_NR;
- gp.value = &screen->irq;
-
- ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
- &gp, sizeof(gp));
- if (ret) {
- FREE( screen );
- fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
- return NULL;
- }
- screen->drmSupportsCubeMapsR200 = (sPriv->drmMinor >= 7);
- screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
- screen->drmSupportsTriPerf = (sPriv->drmMinor >= 16);
- screen->drmSupportsFragShader = (sPriv->drmMinor >= 18);
- screen->drmSupportsPointSprites = (sPriv->drmMinor >= 13);
- screen->drmSupportsCubeMapsR100 = (sPriv->drmMinor >= 15);
+ ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BASE,
+ &screen->gart_base);
+ if (ret) {
+ FREE( screen );
+ fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BASE): %d\n", ret);
+ return NULL;
+ }
+
+ ret = radeonGetParam( sPriv->fd, RADEON_PARAM_IRQ_NR,
+ &screen->irq);
+ if (ret) {
+ FREE( screen );
+ fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
+ return NULL;
}
+ screen->drmSupportsCubeMapsR200 = (sPriv->drmMinor >= 7);
+ screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
+ screen->drmSupportsTriPerf = (sPriv->drmMinor >= 16);
+ screen->drmSupportsFragShader = (sPriv->drmMinor >= 18);
+ screen->drmSupportsPointSprites = (sPriv->drmMinor >= 13);
+ screen->drmSupportsCubeMapsR100 = (sPriv->drmMinor >= 15);
}
screen->mmio.handle = dri_priv->registerHandle;
@@ -425,9 +425,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
return NULL;
}
- screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
- ? INREG( RADEON_AIC_LO_ADDR )
- : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
+ screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base;
}
screen->chip_flags = 0;
@@ -976,12 +974,12 @@ __driCreateNewScreen_20050727( __DRInativeDisplay *dpy,
static const char *driver_name = "Radeon";
static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
- static const __DRIversion drm_expected = { 1, 3, 0 };
+ static const __DRIversion drm_expected = { 1, 6, 0 };
#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
static const char *driver_name = "R200";
static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
- static const __DRIversion drm_expected = { 1, 5, 0 };
+ static const __DRIversion drm_expected = { 1, 6, 0 };
#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
static const char *driver_name = "R300";
static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h
index 08433c445b8..3e0f9454e7f 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.h
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.h
@@ -59,7 +59,7 @@ typedef struct {
int chip_family;
int chip_flags;
int cpp;
- int IsPCI; /* Current card is a PCI card */
+ int card_type;
int AGPMode;
unsigned int irq; /* IRQ number (0 means none) */
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 447619b56d0..307c1f341b4 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -1282,8 +1282,8 @@ radeonStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
GLint ref, GLuint mask )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLuint refmask = ((ctx->Stencil.Ref[0] << RADEON_STENCIL_REF_SHIFT) |
- (ctx->Stencil.ValueMask[0] << RADEON_STENCIL_MASK_SHIFT));
+ GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) |
+ ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
RADEON_STATECHANGE( rmesa, ctx );
RADEON_STATECHANGE( rmesa, msk );
@@ -1330,7 +1330,7 @@ radeonStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
RADEON_STATECHANGE( rmesa, msk );
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
- (ctx->Stencil.WriteMask[0] << RADEON_STENCIL_WRITEMASK_SHIFT);
+ ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
}
static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail,
@@ -1458,9 +1458,9 @@ static void radeonClearStencil( GLcontext *ctx, GLint s )
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
rmesa->state.stencil.clear =
- ((GLuint) ctx->Stencil.Clear |
+ ((GLuint) (ctx->Stencil.Clear & 0xff) |
(0xff << RADEON_STENCIL_MASK_SHIFT) |
- (ctx->Stencil.WriteMask[0] << RADEON_STENCIL_WRITEMASK_SHIFT));
+ ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT));
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
index 9924931e1a2..4d5bbbd1f18 100644
--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
@@ -92,10 +92,11 @@ static void radeonSetVertexFormat( GLcontext *ctx )
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
int fmt_0 = 0;
int offset = 0;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
/* Important:
*/
@@ -113,7 +114,7 @@ static void radeonSetVertexFormat( GLcontext *ctx )
* build up a hardware vertex.
*/
if ( !rmesa->swtcl.needproj ||
- (index & _TNL_BITS_TEX_ANY)) { /* for projtex */
+ RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { /* for projtex */
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F,
RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_Z | RADEON_CP_VC_FRMT_W0 );
offset = 4;
@@ -135,10 +136,11 @@ static void radeonSetVertexFormat( GLcontext *ctx )
offset += 1;
rmesa->swtcl.specoffset = 0;
- if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
#if MESA_LITTLE_ENDIAN
- if (index & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
rmesa->swtcl.specoffset = offset;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB,
RADEON_CP_VC_FRMT_PKSPEC );
@@ -147,7 +149,7 @@ static void radeonSetVertexFormat( GLcontext *ctx )
EMIT_PAD( 3 );
}
- if (index & _TNL_BIT_FOG) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F,
RADEON_CP_VC_FRMT_PKSPEC );
}
@@ -155,7 +157,7 @@ static void radeonSetVertexFormat( GLcontext *ctx )
EMIT_PAD( 1 );
}
#else
- if (index & _TNL_BIT_FOG) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F,
RADEON_CP_VC_FRMT_PKSPEC );
}
@@ -163,7 +165,7 @@ static void radeonSetVertexFormat( GLcontext *ctx )
EMIT_PAD( 1 );
}
- if (index & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
rmesa->swtcl.specoffset = offset;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR,
RADEON_CP_VC_FRMT_PKSPEC );
@@ -174,11 +176,11 @@ static void radeonSetVertexFormat( GLcontext *ctx )
#endif
}
- if (index & _TNL_BITS_TEX_ANY) {
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
int i;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- if (index & _TNL_BIT_TEX(i)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
GLuint sz = VB->TexCoordPtr[i]->size;
switch (sz) {
@@ -204,7 +206,7 @@ static void radeonSetVertexFormat( GLcontext *ctx )
}
}
- if ( rmesa->tnl_index != index ||
+ if (!RENDERINPUTS_EQUAL( rmesa->tnl_index_bitset, index_bitset ) ||
fmt_0 != rmesa->swtcl.vertex_format) {
RADEON_NEWPRIM(rmesa);
rmesa->swtcl.vertex_format = fmt_0;
@@ -214,7 +216,7 @@ static void radeonSetVertexFormat( GLcontext *ctx )
rmesa->swtcl.vertex_attr_count,
NULL, 0 );
rmesa->swtcl.vertex_size /= 4;
- rmesa->tnl_index = index;
+ RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset );
if (RADEON_DEBUG & DEBUG_VERTS)
fprintf( stderr, "%s: vertex_size= %d floats\n",
__FUNCTION__, rmesa->swtcl.vertex_size);
@@ -257,8 +259,9 @@ void radeonChooseVertexState( GLcontext *ctx )
* bigger one.
*/
- if ( ((tnl->render_inputs & (_TNL_BITS_TEX_ANY|_TNL_BIT_COLOR1) ) == 0)
- || (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+ if ((!RENDERINPUTS_TEST_RANGE( tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) &&
+ !RENDERINPUTS_TEST( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR1 ))
+ || (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
rmesa->swtcl.needproj = GL_TRUE;
se_coord_fmt = (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
RADEON_VTX_Z_PRE_MULT_1_OVER_W0 |
@@ -938,7 +941,7 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
*/
_tnl_invalidate_vertex_state( ctx, ~0 );
_tnl_invalidate_vertices( ctx, ~0 );
- rmesa->tnl_index = 0;
+ RENDERINPUTS_ZERO( rmesa->tnl_index_bitset );
radeonChooseVertexState( ctx );
radeonChooseRenderState( ctx );
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
index 3b3f459dffb..e9a76dc92eb 100644
--- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
+++ b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
@@ -929,7 +929,8 @@ void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
GLvertexformat *vfmt = &(rmesa->vb.vtxfmt);
- MEMSET( vfmt, 0, sizeof(GLvertexformat) );
+ /* start by initializing to no-op functions */
+ _mesa_noop_vtxfmt_init(vfmt);
/* Hook in chooser functions for codegen, etc:
*/
@@ -939,7 +940,6 @@ void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
*/
vfmt->Materialfv = radeon_Materialfv;
vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
- vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
vfmt->Begin = radeon_Begin;
vfmt->End = radeon_End;
@@ -953,15 +953,6 @@ void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
vfmt->DrawElements = radeon_fallback_DrawElements;
vfmt->DrawRangeElements = radeon_fallback_DrawRangeElements;
-
- /* Not active in supported states; just keep ctx->Current uptodate:
- */
- vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
- vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
- vfmt->Indexf = _mesa_noop_Indexf;
- vfmt->Indexfv = _mesa_noop_Indexfv;
-
-
/* Active but unsupported -- fallback if we receive these:
*/
vfmt->CallList = radeon_fallback_CallList;
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S b/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S
index d2bb1d15192..1b433491aa8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S
+++ b/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S
@@ -492,3 +492,7 @@ GLOBL( _sse_MultiTexCoord2f_2 )
ret
GLOBL( _sse_MultiTexCoord2f_2_end )
#endif
+
+#if defined (__ELF__) && defined (__linux__)
+ .section .note.GNU-stack,"",%progbits
+#endif
diff --git a/src/mesa/drivers/dri/radeon/server/radeon_dri.c b/src/mesa/drivers/dri/radeon/server/radeon_dri.c
index 7f83d868cb8..7ead588dac8 100644
--- a/src/mesa/drivers/dri/radeon/server/radeon_dri.c
+++ b/src/mesa/drivers/dri/radeon/server/radeon_dri.c
@@ -1260,6 +1260,7 @@ static int radeonInitFBDev( DRIDriverContext *ctx )
}
ctx->shared.virtualWidth = dummy;
+ ctx->shared.Width = dummy;
}
fprintf(stderr,"shared virtual width is %d\n", ctx->shared.virtualWidth);
diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c
index 44cf2f20d37..3a267e025c9 100644
--- a/src/mesa/drivers/dri/savage/savagestate.c
+++ b/src/mesa/drivers/dri/savage/savagestate.c
@@ -986,8 +986,8 @@ savageDDStencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
const u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
const u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;
- imesa->regs.s4.zBufCtrl.ni.stencilRefVal = ctx->Stencil.Ref[0];
- imesa->regs.s4.stencilCtrl.ni.readMask = ctx->Stencil.ValueMask[0];
+ imesa->regs.s4.zBufCtrl.ni.stencilRefVal = ctx->Stencil.Ref[0] & 0xff;
+ imesa->regs.s4.stencilCtrl.ni.readMask = ctx->Stencil.ValueMask[0] & 0xff;
switch (ctx->Stencil.Function[0])
{
@@ -1015,8 +1015,8 @@ savageDDStencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
{
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
- if (imesa->regs.s4.stencilCtrl.ni.writeMask != ctx->Stencil.WriteMask[0]) {
- imesa->regs.s4.stencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0];
+ if (imesa->regs.s4.stencilCtrl.ni.writeMask != (ctx->Stencil.WriteMask[0] & 0xff)) {
+ imesa->regs.s4.stencilCtrl.ni.writeMask = (ctx->Stencil.WriteMask[0] & 0xff);
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}
}
diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c
index b2802904bda..f0fe0c52594 100644
--- a/src/mesa/drivers/dri/savage/savagetex.c
+++ b/src/mesa/drivers/dri/savage/savagetex.c
@@ -525,80 +525,11 @@ savageAllocTexObj( struct gl_texture_object *texObj )
* because we can't tell the hardware to ignore the color components
* and only use the alpha component. So we define our own texture
* formats that promote to ARGB8888 or ARGB4444 and set the color
- * components to white. This way we get the correct result. */
-static GLboolean
-_savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
- GLenum baseInternalFormat,
- const struct gl_texture_format *dstFormat,
- GLvoid *dstAddr,
- GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
- GLint dstRowStride, GLint dstImageStride,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking);
-static GLboolean
-_savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
- GLenum baseInternalFormat,
- const struct gl_texture_format *dstFormat,
- GLvoid *dstAddr,
- GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
- GLint dstRowStride, GLint dstImageStride,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking);
-
-static struct gl_texture_format _savage_texformat_a1114444 = {
- MESA_FORMAT_ARGB4444, /* MesaFormat */
- GL_RGBA, /* BaseFormat */
- GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
- 4, /* RedBits */
- 4, /* GreenBits */
- 4, /* BlueBits */
- 4, /* AlphaBits */
- 0, /* LuminanceBits */
- 0, /* IntensityBits */
- 0, /* IndexBits */
- 0, /* DepthBits */
- 0, /* StencilBits */
- 2, /* TexelBytes */
- _savage_texstore_a1114444, /* StoreTexImageFunc */
- NULL, NULL, NULL, NULL, NULL, NULL /* FetchTexel* filled in by
- * savageDDInitTextureFuncs */
-};
-static struct gl_texture_format _savage_texformat_a1118888 = {
- MESA_FORMAT_ARGB8888, /* MesaFormat */
- GL_RGBA, /* BaseFormat */
- GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
- 8, /* RedBits */
- 8, /* GreenBits */
- 8, /* BlueBits */
- 8, /* AlphaBits */
- 0, /* LuminanceBits */
- 0, /* IntensityBits */
- 0, /* IndexBits */
- 0, /* DepthBits */
- 0, /* StencilBits */
- 4, /* TexelBytes */
- _savage_texstore_a1118888, /* StoreTexImageFunc */
- NULL, NULL, NULL, NULL, NULL, NULL /* FetchTexel* filled in by
- * savageDDInitTextureFuncs */
-};
-
+ * components to white. This way we get the correct result.
+ */
static GLboolean
-_savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
- GLenum baseInternalFormat,
- const struct gl_texture_format *dstFormat,
- GLvoid *dstAddr,
- GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
- GLint dstRowStride, GLint dstImageStride,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
+_savage_texstore_a1114444(TEXSTORE_PARAMS)
{
- /* general path */
const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
baseInternalFormat,
@@ -606,10 +537,6 @@ _savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
srcFormat, srcType, srcAddr,
srcPacking);
const GLchan *src = tempImage;
- GLubyte *dstImage = (GLubyte *) dstAddr
- + dstZoffset * dstImageStride
- + dstYoffset * dstRowStride
- + dstXoffset * dstFormat->TexelBytes;
GLint img, row, col;
ASSERT(dstFormat == &_savage_texformat_a1114444);
@@ -619,7 +546,10 @@ _savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
return GL_FALSE;
_mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstImage;
+ GLubyte *dstRow = (GLubyte *) dstAddr
+ + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
for (row = 0; row < srcHeight; row++) {
GLushort *dstUI = (GLushort *) dstRow;
for (col = 0; col < srcWidth; col++) {
@@ -629,25 +559,16 @@ _savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
}
dstRow += dstRowStride;
}
- dstImage += dstImageStride;
}
_mesa_free((void *) tempImage);
return GL_TRUE;
}
+
+
static GLboolean
-_savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
- GLenum baseInternalFormat,
- const struct gl_texture_format *dstFormat,
- GLvoid *dstAddr,
- GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
- GLint dstRowStride, GLint dstImageStride,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
+_savage_texstore_a1118888(TEXSTORE_PARAMS)
{
- /* general path */
const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
baseInternalFormat,
@@ -655,10 +576,6 @@ _savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
srcFormat, srcType, srcAddr,
srcPacking);
const GLchan *src = tempImage;
- GLubyte *dstImage = (GLubyte *) dstAddr
- + dstZoffset * dstImageStride
- + dstYoffset * dstRowStride
- + dstXoffset * dstFormat->TexelBytes;
GLint img, row, col;
ASSERT(dstFormat == &_savage_texformat_a1118888);
@@ -668,7 +585,10 @@ _savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
return GL_FALSE;
_mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstImage;
+ GLubyte *dstRow = (GLubyte *) dstAddr
+ + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
for (row = 0; row < srcHeight; row++) {
GLuint *dstUI = (GLuint *) dstRow;
for (col = 0; col < srcWidth; col++) {
@@ -678,13 +598,51 @@ _savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
}
dstRow += dstRowStride;
}
- dstImage += dstImageStride;
}
_mesa_free((void *) tempImage);
return GL_TRUE;
}
+
+static struct gl_texture_format _savage_texformat_a1114444 = {
+ MESA_FORMAT_ARGB4444, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4, /* RedBits */
+ 4, /* GreenBits */
+ 4, /* BlueBits */
+ 4, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _savage_texstore_a1114444, /* StoreTexImageFunc */
+ NULL, NULL, NULL, NULL, NULL, NULL /* FetchTexel* filled in by
+ * savageDDInitTextureFuncs */
+};
+static struct gl_texture_format _savage_texformat_a1118888 = {
+ MESA_FORMAT_ARGB8888, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4, /* TexelBytes */
+ _savage_texstore_a1118888, /* StoreTexImageFunc */
+ NULL, NULL, NULL, NULL, NULL, NULL /* FetchTexel* filled in by
+ * savageDDInitTextureFuncs */
+};
+
+
/* Called by the _mesa_store_teximage[123]d() functions. */
static const struct gl_texture_format *
savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c
index 18470401372..3dd821a4d39 100644
--- a/src/mesa/drivers/dri/savage/savagetris.c
+++ b/src/mesa/drivers/dri/savage/savagetris.c
@@ -867,15 +867,17 @@ static GLboolean savageCheckPTexHack( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
- if (index & _TNL_BIT_TEX(0) && VB->TexCoordPtr[0]->size == 4) {
- if ((index & _TNL_BITS_TEX_ANY) == _TNL_BIT_TEX(0))
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->TexCoordPtr[0]->size == 4) {
+ if (!RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_ATTRIB_TEX1, _TNL_LAST_TEX ))
return GL_TRUE; /* apply ptex hack */
else
FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_TRUE);
}
- if ((index & _TNL_BIT_TEX(1)) && VB->TexCoordPtr[1]->size == 4)
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->TexCoordPtr[1]->size == 4)
FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_TRUE);
return GL_FALSE; /* don't apply ptex hack */
@@ -929,10 +931,11 @@ static __inline__ GLuint savageChooseVertexFormat_s3d( GLcontext *ctx )
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
GLuint setupIndex = SAVAGE_EMIT_XYZ;
GLubyte skip;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
imesa->vertex_attr_count = 0;
skip = SAVAGE_SKIP_ALL_S3D;
@@ -941,7 +944,7 @@ static __inline__ GLuint savageChooseVertexFormat_s3d( GLcontext *ctx )
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
* build up a hardware vertex.
*/
- if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE))
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) || !(ctx->_TriangleCaps & DD_FLATSHADE))
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W );
else {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
@@ -952,17 +955,17 @@ static __inline__ GLuint savageChooseVertexFormat_s3d( GLcontext *ctx )
/* t_context.c always includes a diffuse color */
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 );
- if ((index & _TNL_BIT_COLOR1))
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ))
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 );
else
EMIT_PAD( 3 );
- if ((index & _TNL_BIT_FOG))
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 );
else
EMIT_PAD( 1 );
skip &= ~SAVAGE_SKIP_C1;
- if (index & _TNL_BIT_TEX(0)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
if (imesa->ptexHack)
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0);
else if (VB->TexCoordPtr[0]->size == 4)
@@ -991,28 +994,27 @@ static __inline__ GLuint savageChooseVertexFormat_s4( GLcontext *ctx )
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
GLuint setupIndex = SAVAGE_EMIT_XYZ;
GLubyte skip;
GLuint size, mask;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
skip = SAVAGE_SKIP_ALL_S4;
skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */
- if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE))
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) || !(ctx->_TriangleCaps & DD_FLATSHADE))
NEED_ATTR( SAVAGE_EMIT_W, SAVAGE_SKIP_W );
/* t_context.c always includes a diffuse color */
NEED_ATTR( SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 );
-
- if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
- if ((index & _TNL_BIT_COLOR1))
- NEED_ATTR( SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 );
- if ((index & _TNL_BIT_FOG))
- NEED_ATTR( SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 );
- }
- if (index & _TNL_BIT_TEX(0)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ))
+ NEED_ATTR( SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 );
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
+ NEED_ATTR( SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 );
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
if (imesa->ptexHack)
NEED_ATTR( SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0);
else if (VB->TexCoordPtr[0]->size == 4)
@@ -1024,7 +1026,7 @@ static __inline__ GLuint savageChooseVertexFormat_s4( GLcontext *ctx )
else
NEED_ATTR( SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 );
}
- if (index & _TNL_BIT_TEX(1)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
if (VB->TexCoordPtr[1]->size == 4)
/* projective textures are not supported by the hardware */
assert (0); /* should be caught by savageCheckPTexHack */
diff --git a/src/mesa/drivers/dri/sis/sis_clear.c b/src/mesa/drivers/dri/sis/sis_clear.c
index d7807b157e9..637d502381e 100644
--- a/src/mesa/drivers/dri/sis/sis_clear.c
+++ b/src/mesa/drivers/dri/sis/sis_clear.c
@@ -133,7 +133,8 @@ sisDDClear( GLcontext * ctx, GLbitfield mask, GLboolean all,
if ((smesa->current.hwCapEnable2 & (MASK_AlphaMaskWriteEnable |
MASK_ColorMaskWriteEnable) &&
(mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT)) != 0) ||
- (ctx->Stencil.WriteMask[0] < 0xff && (mask & BUFFER_BIT_STENCIL) != 0) )
+ ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff &&
+ (mask & BUFFER_BIT_STENCIL) != 0) )
{
mask = sis_3D_Clear( ctx, mask, x1, y1, width1, height1 );
}
@@ -213,13 +214,13 @@ sis_3D_Clear( GLcontext * ctx, GLbitfield mask,
if (bClrStencil) {
dwSten1 = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS |
- (ctx->Stencil.Clear << 8) | 0xff;
+ ((ctx->Stencil.Clear & 0xff) << 8) | 0xff;
dwSten2 = SiS_SFAIL_REPLACE | SiS_SPASS_ZFAIL_REPLACE |
SiS_SPASS_ZPASS_REPLACE;
dwEnable1 = MASK_ZWriteEnable | MASK_StencilWriteEnable |
MASK_StencilTestEnable;
dwEnable2 |= MASK_ZMaskWriteEnable;
- dwDepthMask |= ctx->Stencil.WriteMask[0] << 24;
+ dwDepthMask |= (ctx->Stencil.WriteMask[0] & 0xff) << 24;
} else if (bClrDepth) {
dwEnable1 = MASK_ZWriteEnable;
dwEnable2 |= MASK_ZMaskWriteEnable;
diff --git a/src/mesa/drivers/dri/sis/sis_context.h b/src/mesa/drivers/dri/sis/sis_context.h
index ead4a26678e..c349bf96ed2 100644
--- a/src/mesa/drivers/dri/sis/sis_context.h
+++ b/src/mesa/drivers/dri/sis/sis_context.h
@@ -332,7 +332,7 @@ struct sis_context
GLint drawableID;
GLint GlobalFlag;
- GLuint last_tcl_state;
+ DECLARE_RENDERINPUTS(last_tcl_state_bitset);
/* Stereo */
GLboolean useStereo;
diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c
index 1a4c3241153..a30001c7462 100644
--- a/src/mesa/drivers/dri/sis/sis_state.c
+++ b/src/mesa/drivers/dri/sis/sis_state.c
@@ -251,7 +251,7 @@ sisDDDepthMask( GLcontext * ctx, GLboolean flag )
if (ctx->Visual.stencilBits) {
if (flag || (ctx->Stencil.WriteMask[0] != 0)) {
current->hwCapEnable |= MASK_ZWriteEnable;
- if (flag && (ctx->Stencil.WriteMask[0] == 0xff)) {
+ if (flag && ((ctx->Stencil.WriteMask[0] & 0xff) == 0xff)) {
current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable;
} else {
current->hwCapEnable2 |= MASK_ZMaskWriteEnable;
diff --git a/src/mesa/drivers/dri/sis/sis_stencil.c b/src/mesa/drivers/dri/sis/sis_stencil.c
index 1febe86b94c..a1ce2966e89 100644
--- a/src/mesa/drivers/dri/sis/sis_stencil.c
+++ b/src/mesa/drivers/dri/sis/sis_stencil.c
@@ -45,8 +45,9 @@ sisDDStencilFuncSeparate( GLcontext * ctx, GLenum face,
__GLSiSHardware *current = &smesa->current;
/* set reference */
- current->hwStSetting = STENCIL_FORMAT_8 | (ctx->Stencil.Ref[0] << 8) |
- ctx->Stencil.ValueMask[0];
+ current->hwStSetting = (STENCIL_FORMAT_8 |
+ ((ctx->Stencil.Ref[0] & 0xff) << 8) |
+ (ctx->Stencil.ValueMask[0] & 0xff));
switch (func)
{
diff --git a/src/mesa/drivers/dri/sis/sis_tris.c b/src/mesa/drivers/dri/sis/sis_tris.c
index 24f6cb9aa87..a0e39dcd3c9 100644
--- a/src/mesa/drivers/dri/sis/sis_tris.c
+++ b/src/mesa/drivers/dri/sis/sis_tris.c
@@ -842,10 +842,12 @@ static void sisRenderStart( GLcontext *ctx )
TNLcontext *tnl = TNL_CONTEXT(ctx);
sisContextPtr smesa = SIS_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
GLuint AGPParseSet = smesa->AGPParseSet;
GLboolean tex_fallback = GL_FALSE;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
if (ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT &&
smesa->driDrawable->numClipRects != 0)
{
@@ -869,7 +871,7 @@ static void sisRenderStart( GLcontext *ctx )
AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat);
AGPParseSet |= SiS_PS_HAS_XYZ | SiS_PS_HAS_DIFFUSE;
- if (index & _TNL_BITS_TEX_ANY) {
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT);
AGPParseSet |= SiS_PS_HAS_W;
smesa->coloroffset = 4;
@@ -881,17 +883,18 @@ static void sisRenderStart( GLcontext *ctx )
EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA);
smesa->specoffset = 0;
- if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
AGPParseSet |= SiS_PS_HAS_SPECULAR;
- if (index & _TNL_BIT_COLOR1) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR);
smesa->specoffset = smesa->coloroffset + 1;
} else {
EMIT_PAD(3);
}
- if (index & _TNL_BIT_FOG) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F);
} else {
EMIT_PAD(1);
@@ -899,14 +902,14 @@ static void sisRenderStart( GLcontext *ctx )
}
/* projective textures are not supported by the hardware */
- if (index & _TNL_BIT_TEX(0)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
if (VB->TexCoordPtr[0]->size > 2)
tex_fallback = GL_TRUE;
EMIT_ATTR(_TNL_ATTRIB_TEX0, EMIT_2F);
AGPParseSet |= SiS_PS_HAS_UV0;
}
/* Will only hit tex1 on SiS300 */
- if (index & _TNL_BIT_TEX(1)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
if (VB->TexCoordPtr[1]->size > 2)
tex_fallback = GL_TRUE;
EMIT_ATTR(_TNL_ATTRIB_TEX1, EMIT_2F);
@@ -914,7 +917,7 @@ static void sisRenderStart( GLcontext *ctx )
}
FALLBACK(smesa, SIS_FALLBACK_TEXTURE, tex_fallback);
- if (smesa->last_tcl_state != index) {
+ if (!RENDERINPUTS_EQUAL( smesa->last_tcl_state_bitset, index_bitset )) {
smesa->AGPParseSet = AGPParseSet;
smesa->vertex_size = _tnl_install_attrs( ctx, smesa->vertex_attrs,
diff --git a/src/mesa/drivers/dri/tdfx/BUGS b/src/mesa/drivers/dri/tdfx/BUGS
new file mode 100644
index 00000000000..b15f6a91ed8
--- /dev/null
+++ b/src/mesa/drivers/dri/tdfx/BUGS
@@ -0,0 +1,64 @@
+REMOVE THIS FILE BEFORE MERGING WITH TRUNK
+------------------------------------------
+
+OUTSTANDING BUGS
+
+demos/reflect - reading back Z on Voodoo3, image offset to right
+ Fixed in latest Glide.
+
+Q3 - some polygons drawn as vertical strips, similar to bug that was
+ seen in demos/fire. Voodoo3 only. May be related to glDepthMask
+ or glColorMask.
+
+book/fog - not fogging
+ Fog in orthograph mode still not implemented. Checking with
+ 3dfx engineers for ideas.
+
+Q3 demo crashes after changing display settings
+ but the full Q3 game version seems OK.
+
+
+
+MORE OUTSTANDING BUGS
+
+private context was NULL! causing immediate failure of any glx prog. cant
+reproduce after restarting the X server. putting it down as halluc.
+
+texture object image was NULL, causing segmentation failure. happens with
+prboom. ive put a check in tdfx_texstate.c but this isn't a fix.
+
+prboom, wall textures near first chainsaw aren't bound properly. sideways
+movements causes the wall textures to move with you. prboom busted?
+
+16bpp mode, quake3, windowed, q3dm1, floor under rocketlauncher bands. it
+looks like multitexturing gone wrong. i'll disable a tmu and test.
+
+sof, polygons appear at wrong x,y,z positions, intermittent, have not yet
+found reliable way of reproducing. culling? sometimes polys disappear.
+
+descent3 is all black in 16bpp mode - FIXED (palette problems)
+
+smeared pixels in quake3 - FIXED (texture memory overlapped FB)
+
+
+
+PERFORMANCE COMPARISON (Brian / Alan)
+
+ V3/16 is Voodoo3 in 16bpp on a P3/500
+ V5/16 is Voodoo5 in 16bpp on a P3/600
+ V5/32 is Voodoo5 in 32bpp on a P3/600
+ V5A/16 is Voodoo5 in 16bpp on an Alpha AXP/600
+ V5A/32 is Voodoo5 in 32bpp on an Alpha AXP/600
+
+ tdfx-2-1-branch tdfx-3-0-0-branch
+demo V3/16 V5/16 V5/32 V3/16 V5/16 V5/32 V5A/16 V5A/32
+------------------------------------------------------------------------
+gloss 257 183 174 320 308 177 313 167
+fire 42 39 52 41
+fire (no help) 98 80 50 106 113 73 124 80
+tunnel 61 50 70 58
+tunnel (no help) 167 142 57 138 152 113 171 122
+gears 663 554 540 881 1232 776 1484 830
+teapot 20 21 37 36
+teapot (no help) 22 14 14 24 30 30 43 42
+
diff --git a/src/mesa/drivers/dri/tdfx/X86/fx_3dnow_fastpath.S b/src/mesa/drivers/dri/tdfx/X86/fx_3dnow_fastpath.S
new file mode 100644
index 00000000000..0f4cc45089b
--- /dev/null
+++ b/src/mesa/drivers/dri/tdfx/X86/fx_3dnow_fastpath.S
@@ -0,0 +1,84 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S,v 1.2 2000/09/26 15:56:51 tsi Exp $ */
+
+#include "../../X86/assyntax.h"
+
+#define SETUP_RGBA 0x1
+#define SETUP_TMU0 0x2
+#define SETUP_TMU1 0x4
+
+
+/* Pack either rgba or texture into the remaining half of a 32 byte vertex.
+ */
+#define CLIP_R 24
+#define CLIP_G 16
+#define CLIP_B 20
+#define CLIP_A 28 /* defined inf fxdrv.h */
+
+#define CLIP_S0 16
+#define CLIP_T0 20
+#define CLIP_S1 24
+#define CLIP_T1 28
+
+#define SIZE 4
+#define TYPE (0)
+#define TAG(x) x
+#include "fx_3dnow_fasttmp.h"
+
+#define SIZE 8
+#define TYPE (SETUP_RGBA)
+#define TAG(x) x##_RGBA
+#include "fx_3dnow_fasttmp.h"
+
+#define SIZE 6
+#define TYPE (SETUP_TMU0)
+#define TAG(x) x##_TMU0
+#include "fx_3dnow_fasttmp.h"
+
+#define SIZE 8
+#define TYPE (SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) x##_TMU0_TMU1
+#include "fx_3dnow_fasttmp.h"
+
+#undef CLIP_S1
+#undef CLIP_T1
+#define CLIP_S1 16
+#define CLIP_T1 20
+
+#define SIZE 6
+#define TYPE (SETUP_TMU1)
+#define TAG(x) x##_TMU1
+#include "fx_3dnow_fasttmp.h"
+
+/* These three need to use a full 64 byte clip-space vertex.
+ */
+#undef CLIP_S0
+#undef CLIP_T0
+#undef CLIP_S1
+#undef CLIP_T1
+
+#define CLIP_S0 32
+#define CLIP_T0 36
+#define CLIP_S1 40
+#define CLIP_T1 44
+
+#define SIZE 10
+#define TYPE (SETUP_RGBA|SETUP_TMU0)
+#define TAG(x) x##_RGBA_TMU0
+#include "fx_3dnow_fasttmp.h"
+
+#define SIZE 12
+#define TYPE (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) x##_RGBA_TMU0_TMU1
+#include "fx_3dnow_fasttmp.h"
+
+#undef CLIP_S1
+#undef CLIP_T1
+#define CLIP_S1 32
+#define CLIP_T1 36
+
+#define SIZE 10
+#define TYPE (SETUP_RGBA|SETUP_TMU1)
+#define TAG(x) x##_RGBA_TMU1
+#include "fx_3dnow_fasttmp.h"
+
+
diff --git a/src/mesa/drivers/dri/tdfx/X86/fx_3dnow_fasttmp.h b/src/mesa/drivers/dri/tdfx/X86/fx_3dnow_fasttmp.h
new file mode 100644
index 00000000000..9ec4935d781
--- /dev/null
+++ b/src/mesa/drivers/dri/tdfx/X86/fx_3dnow_fasttmp.h
@@ -0,0 +1,314 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fasttmp.h,v 1.2 2000/09/26 15:56:51 tsi Exp $ */
+
+#if !defined(NASM_ASSEMBLER) && !defined(MASM_ASSEMBLER)
+#define TAGLLBL(a) TAG(.L##a)
+#else
+#define TAGLLBL(a) TAG(a)
+#endif
+
+#if !GLIDE3
+
+#define GR_VERTEX_X_OFFSET 0
+#define GR_VERTEX_Y_OFFSET 4
+#define GR_VERTEX_Z_OFFSET 8
+#define GR_VERTEX_R_OFFSET 12
+#define GR_VERTEX_G_OFFSET 16
+#define GR_VERTEX_B_OFFSET 20
+#define GR_VERTEX_OOZ_OFFSET 24
+#define GR_VERTEX_A_OFFSET 28
+#define GR_VERTEX_OOW_OFFSET 32
+
+#else /* GLIDE3 */
+
+#define GR_VERTEX_X_OFFSET 0
+#define GR_VERTEX_Y_OFFSET 4
+#define GR_VERTEX_OOZ_OFFSET 8
+#define GR_VERTEX_OOW_OFFSET 12
+#define GR_VERTEX_R_OFFSET 16
+#define GR_VERTEX_G_OFFSET 20
+#define GR_VERTEX_B_OFFSET 24
+#define GR_VERTEX_A_OFFSET 28
+#define GR_VERTEX_Z_OFFSET 32
+
+#endif /* GLIDE3 */
+
+#define GR_VERTEX_SOW_TMU0_OFFSET 36
+#define GR_VERTEX_TOW_TMU0_OFFSET 40
+#define GR_VERTEX_OOW_TMU0_OFFSET 44
+#define GR_VERTEX_SOW_TMU1_OFFSET 48
+#define GR_VERTEX_TOW_TMU1_OFFSET 52
+#define GR_VERTEX_OOW_TMU1_OFFSET 56
+
+
+
+
+/*#define MAT_SX 0 /* accessed by REGIND !! */
+#define MAT_SY 20
+#define MAT_SZ 40
+#define MAT_TX 48
+#define MAT_TY 52
+#define MAT_TZ 56
+
+
+
+
+/* Do viewport map, device scale and perspective projection.
+ *
+ * void project_verts( GLfloat *first,
+ * GLfloat *last,
+ * const GLfloat *m,
+ * GLuint stride )
+ *
+ *
+ * Rearrange fxVertices to look like grVertices.
+ */
+
+GLOBL GLNAME( TAG(fx_3dnow_project_vertices) )
+GLNAME( TAG(fx_3dnow_project_vertices) ):
+
+ PUSH_L ( EBP )
+
+ MOV_L ( REGOFF(8, ESP), ECX ) /* first_vert */
+ MOV_L ( REGOFF(12, ESP), EDX ) /* last_vert */
+
+ CMP_L ( ECX, EDX )
+ JE ( TAGLLBL(FXPV_end) )
+
+ FEMMS
+
+ PREFETCH ( REGIND(ECX) ) /* fetch the first vertex */
+
+ MOV_L ( REGOFF(16, ESP), EBP ) /* matrix */
+ MOV_L ( REGOFF(20, ESP), EAX ) /* stride */
+
+ MOVD ( REGOFF(MAT_TX, EBP), MM6 ) /* | tx */
+ PUNPCKLDQ ( REGOFF(MAT_TY, EBP), MM6 ) /* ty | tx */
+
+#if !defined(FX_V2)
+ MOV_L ( CONST(0x49400000), REGOFF(-8, ESP) ) /* snapper */
+ MOV_L ( CONST(0x49400000), REGOFF(-4, ESP) ) /* snapper */
+#endif
+
+ MOVQ ( REGOFF(-8, ESP), MM4 ) /* snapper | snapper */
+ PFADD ( MM4, MM6 ) /* ty+snapper | tx+snapper */
+
+ MOVD ( REGIND(EBP), MM5 )
+ PUNPCKLDQ ( REGOFF(MAT_SY, EBP), MM5 ) /* vsy | vsx */
+
+ MOVD ( REGOFF(MAT_SZ, EBP), MM1 ) /* | vsz */
+
+
+ALIGNTEXT32
+TAGLLBL(FXPV_loop_start):
+
+ PREFETCH ( REGOFF(64, ECX) ) /* fetch the next-ish vertex */
+
+
+ MOVD ( REGOFF(12, ECX), MM0 ) /* | f[3] */
+ PFRCP ( MM0, MM0 ) /* oow = 1/f[3] */
+
+ MOVD ( REGOFF(12, ECX), MM7 ) /* | f[3] */
+ PFRCPIT1 ( MM0, MM7 )
+ PFRCPIT2 ( MM0, MM7 ) /* oow | oow */
+
+ PUNPCKLDQ ( MM7, MM7 )
+
+
+#if (TYPE & SETUP_RGBA)
+ MOVD ( REGOFF(CLIP_R, ECX ), MM0 ) /* f[RCOORD] = f[CLIP_R]; */
+ MOVD ( MM0, REGOFF(GR_VERTEX_R_OFFSET, ECX) )
+#endif
+
+#if (TYPE & SETUP_TMU1)
+ MOVQ ( REGOFF(CLIP_S1, ECX), MM0 ) /* f[S1COORD] = f[CLIP_S1] * oow */
+ PFMUL ( MM7, MM0 ) /* f[T1COORD] = f[CLIP_T1] * oow */
+ MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU1_OFFSET, ECX) )
+#endif
+
+
+#if (TYPE & SETUP_TMU0)
+ MOVQ ( REGOFF(CLIP_S0, ECX), MM0 ) /* f[S0COORD] = f[CLIP_S0] * oow */
+ PFMUL ( MM7, MM0 ) /* f[T0COORD] = f[CLIP_T0] * oow */
+ MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU0_OFFSET, ECX) )
+#endif
+
+
+
+
+
+/* DO_SETUP_XYZ */
+
+ MOVQ ( REGIND(ECX), MM2 ) /* f[1] | f[0] */
+ PFMUL ( MM7, MM2 ) /* f[1] * oow | f[0] * oow */
+
+ MOVD ( REGOFF(8, ECX), MM3 ) /* | f[2] */
+ PFMUL ( MM7, MM3 ) /* | f[2] * oow */
+
+ MOVD ( REGOFF(MAT_TZ, EBP), MM0 ) /* | vtz */
+ PFMUL ( MM1, MM3 ) /* | f[2] *= vsz */
+
+ PFADD ( MM0, MM3 ) /* | f[2] += vtz */
+ PFMUL ( MM5, MM2 ) /* f[1] *= vsy | f[0] *= vsx */
+
+ PFADD ( MM6, MM2 ) /* f[1] += vty | f[0] += vtx */
+
+#if !defined(FX_V2)
+ PFSUB ( MM4, MM2 ) /* f[0,1] -= snapper */
+#endif
+
+ MOVQ ( MM2, REGOFF(GR_VERTEX_X_OFFSET, ECX) )
+ MOVD ( MM3, REGOFF(GR_VERTEX_OOZ_OFFSET, ECX) )
+
+
+/* end of DO_SETUP_XYZ */
+
+ MOVD ( MM7, REGOFF(GR_VERTEX_OOW_OFFSET, ECX) ) /* f[OOWCOORD] = oow */
+ ADD_L ( EAX, ECX ) /* f += stride */
+
+ CMP_L ( ECX, EDX ) /* stall??? */
+ JA ( TAGLLBL(FXPV_loop_start) )
+
+TAGLLBL(FXPV_end):
+ FEMMS
+ POP_L ( EBP )
+ RET
+
+
+
+
+
+
+
+/* void project_verts( GLfloat *first,
+ * GLfloat *last,
+ * const GLfloat *m,
+ * GLuint stride,
+ * const GLubyte *mask )
+ *
+ */
+
+GLOBL GLNAME( TAG(fx_3dnow_project_clipped_vertices) )
+GLNAME( TAG(fx_3dnow_project_clipped_vertices) ):
+
+ PUSH_L ( EBP )
+
+ MOV_L ( REGOFF(8, ESP), ECX ) /* first FXDRIVER(VB)->verts*/
+ MOV_L ( REGOFF(12, ESP), EDX ) /* last FXDRIVER(VB)->last_vert */
+
+ FEMMS
+
+ PUSH_L ( EDI )
+ PUSH_L ( ESI )
+
+ PREFETCH ( REGIND(ECX) ) /* fetch the first vertex */
+
+ MOV_L ( REGOFF(24, ESP), EBP ) /* mat ctx->Viewport.WindowMap.M */
+ MOV_L ( REGOFF(28, ESP), EAX ) /* stride */
+ MOV_L ( REGOFF(32, ESP), ESI ) /* VB->ClipMask */
+
+ MOVD ( REGOFF(MAT_TX, EBP), MM6 ) /* | tx */
+ PUNPCKLDQ ( REGOFF(MAT_TY, EBP), MM6 ) /* ty | tx */
+
+#if !defined(FX_V2)
+ MOV_L ( CONST(0x49400000), REGOFF(-8, ESP) ) /* snapper */
+ MOV_L ( CONST(0x49400000), REGOFF(-4, ESP) ) /* snapper */
+#endif
+
+ MOVQ ( REGOFF(-8, ESP), MM4 ) /* snapper | snapper */
+ PFADD ( MM4, MM6 ) /* ty+snapper | tx+snapper */
+
+ MOVD ( REGIND(EBP), MM5 )
+ PUNPCKLDQ ( REGOFF(MAT_SY, EBP), MM5 ) /* vsy | vsx */
+
+ MOVD ( REGOFF(MAT_SZ, EBP), MM1 ) /* | vsz */
+
+
+
+ALIGNTEXT32
+TAGLLBL(FXPCV_loop_start):
+
+ PREFETCH ( REGOFF(64, ECX) ) /* fetch the next-ish vertex */
+
+ CMP_B ( CONST(0), REGIND(ESI) )
+ JNE ( TAGLLBL(FXPCV_skip) )
+
+ MOVD ( REGOFF(12, ECX), MM0) /* | f[3] */
+ PFRCP ( MM0, MM0 ) /* oow = 1/f[3] */
+
+ MOVD ( REGOFF(12, ECX), MM7) /* | f[3] */
+ PFRCPIT1 ( MM0, MM7 )
+ PFRCPIT2 ( MM0, MM7 ) /* oow | oow */
+
+ PUNPCKLDQ ( MM7, MM7 )
+
+
+#if (TYPE & SETUP_RGBA)
+ MOVD ( REGOFF(CLIP_R, ECX ), MM0 ) /* f[RCOORD] = f[CLIP_R]; */
+ MOVD ( MM0, REGOFF(GR_VERTEX_R_OFFSET, ECX) )
+#endif
+
+#if (TYPE & SETUP_TMU1)
+ MOVQ ( REGOFF(CLIP_S1, ECX), MM0 ) /* f[S1COORD] = f[CLIP_S1] * oow */
+ PFMUL ( MM7, MM0 ) /* f[T1COORD] = f[CLIP_T1] * oow */
+ MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU1_OFFSET, ECX) )
+#endif
+
+
+#if (TYPE & SETUP_TMU0)
+ MOVQ ( REGOFF(CLIP_S0, ECX), MM0 ) /* f[S0COORD] = f[CLIP_S0] * oow */
+ PFMUL ( MM7, MM0 ) /* f[T0COORD] = f[CLIP_T0] * oow */
+ MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU0_OFFSET, ECX) )
+#endif
+
+
+
+
+/* DO_SETUP_XYZ */
+
+ MOVQ ( REGIND(ECX), MM2 ) /* f[1] | f[0] */
+ PFMUL ( MM7, MM2 ) /* f[1] * oow | f[0] * oow */
+
+ MOVD ( REGOFF(8, ECX), MM3 ) /* | f[2] */
+ PFMUL ( MM7, MM3 ) /* | f[2] * oow */
+
+ MOVD ( REGOFF(MAT_TZ, EBP), MM0 ) /* | vtz */
+ PFMUL ( MM1, MM3 ) /* | f[2] *= vsz */
+
+ PFADD ( MM0, MM3 ) /* | f[2] += vtz */
+ PFMUL ( MM5, MM2 ) /* f[1] *= vsy | f[0] *= vsx */
+
+ PFADD ( MM6, MM2 ) /* f[1] += vty | f[0] += vtx */
+
+#if !defined(FX_V2)
+ PFSUB ( MM4, MM2 ) /* f[0,1] -= snapper */
+#endif
+
+ MOVQ ( MM2, REGOFF(GR_VERTEX_X_OFFSET, ECX) )
+ MOVD ( MM3, REGOFF(GR_VERTEX_OOZ_OFFSET, ECX) )
+
+
+/* end of DO_SETUP_XYZ */
+
+ MOVD ( MM7, REGOFF(GR_VERTEX_OOW_OFFSET, ECX) ) /* f[OOWCOORD] = oow */
+
+TAGLLBL(FXPCV_skip):
+ ADD_L ( EAX, ECX ) /* f += stride */
+
+ INC_L ( ESI ) /* next ClipMask */
+ CMP_L ( ECX, EDX )
+ JA ( TAGLLBL(FXPCV_loop_start) )
+
+ POP_L ( ESI )
+ POP_L ( EDI )
+
+TAGLLBL(FXPCV_end):
+ FEMMS
+ POP_L ( EBP )
+ RET
+
+
+
+#undef TYPE
+#undef TAG
+#undef SIZE
+
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_render.c b/src/mesa/drivers/dri/tdfx/tdfx_render.c
index 56f5f147eeb..a30ec78a558 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_render.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_render.c
@@ -70,7 +70,7 @@ static void tdfxClear( GLcontext *ctx,
mask &= ~(BUFFER_BIT_ACCUM);
if (mask & BUFFER_BIT_STENCIL) {
- if (!fxMesa->haveHwStencil || ctx->Stencil.WriteMask[0] != 0xff) {
+ if (!fxMesa->haveHwStencil || (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
/* Napalm seems to have trouble with stencil write masks != 0xff */
/* do stencil clear in software */
mask &= ~(BUFFER_BIT_STENCIL);
@@ -98,7 +98,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
/* set stencil ref value = desired clear value */
fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS,
- fxMesa->Stencil.Clear, 0xff);
+ (fxMesa->Stencil.Clear & 0xff), 0xff);
fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE,
GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE);
fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
@@ -129,7 +129,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
}
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
@@ -152,11 +152,11 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
- fxMesa->Depth.Clear);
+ fxMesa->Depth.Clear & 0xff);
/* clear front */
FX_grColorMaskv_NoLock(ctx, true4);
fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
@@ -164,7 +164,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
@@ -181,7 +181,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
@@ -198,7 +198,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
@@ -215,7 +215,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
@@ -225,7 +225,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
@@ -242,7 +242,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
@@ -254,7 +254,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
@@ -272,7 +272,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
else
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
@@ -293,7 +293,7 @@ static void tdfxClear( GLcontext *ctx,
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
fxMesa->Color.ClearAlpha,
fxMesa->Depth.Clear,
- (FxU32) ctx->Stencil.Clear);
+ (FxU32) (ctx->Stencil.Clear & 0xff));
if (ctx->Depth.Mask && ctx->Depth.Test) {
fxMesa->Glide.grDepthMask(FXTRUE);
}
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c
index 1869de47374..a389273b2f0 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_state.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c
@@ -462,9 +462,9 @@ static void tdfxUpdateStencil( GLcontext *ctx )
if (fxMesa->haveHwStencil) {
if (ctx->Stencil.Enabled) {
fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER + GR_CMP_NEVER;
- fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0];
- fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0];
- fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0];
+ fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0] & 0xff;
+ fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0] & 0xff;
+ fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0] & 0xff;
fxMesa->Stencil.FailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[0]);
fxMesa->Stencil.ZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[0]);
fxMesa->Stencil.ZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[0]);
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
index d8a80534bb9..04ddfaad24b 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
@@ -52,7 +52,7 @@
/* no borders! can't halve 1x1! (stride > width * comp) not allowed */
-void
+static void
_mesa_halve2x2_teximage2d ( GLcontext *ctx,
struct gl_texture_image *texImage,
GLuint bytesPerPixel,
@@ -65,6 +65,7 @@ _mesa_halve2x2_teximage2d ( GLcontext *ctx,
GLint srcRowStride = srcWidth * bytesPerPixel;
GLubyte *src = (GLubyte *)srcImage;
GLubyte *dst = dstImage;
+ GLuint dstImageOffsets = 0;
GLuint bpt = 0;
GLubyte *_s = NULL;
@@ -96,7 +97,7 @@ _mesa_halve2x2_teximage2d ( GLcontext *ctx,
&_mesa_texformat_rgba8888_rev, src,
0, 0, 0, /* dstX/Y/Zoffset */
srcRowStride, /* dstRowStride */
- 0, /* dstImageStride */
+ &dstImageOffsets,
srcWidth, srcHeight, 1,
texImage->_BaseFormat, _t, srcImage, &ctx->DefaultPacking);
}
@@ -143,7 +144,7 @@ _mesa_halve2x2_teximage2d ( GLcontext *ctx,
texImage->TexFormat, dstImage,
0, 0, 0, /* dstX/Y/Zoffset */
dstWidth * bpt,
- 0, /* dstImageStride */
+ &dstImageOffsets,
dstWidth, dstHeight, 1,
GL_BGRA, CHAN_TYPE, dst, &ctx->DefaultPacking);
FREE(dst);
@@ -1177,6 +1178,7 @@ adjust2DRatio (GLcontext *ctx,
const GLint newWidth = width * mml->wScale;
const GLint newHeight = height * mml->hScale;
GLvoid *tempImage;
+ GLuint dstImageOffsets = 0;
if (!texImage->IsCompressed) {
GLubyte *destAddr;
@@ -1189,7 +1191,7 @@ adjust2DRatio (GLcontext *ctx,
texImage->TexFormat, tempImage,
0, 0, 0, /* dstX/Y/Zoffset */
width * texelBytes, /* dstRowStride */
- 0, /* dstImageStride */
+ &dstImageOffsets,
width, height, 1,
format, type, pixels, packing);
@@ -1213,6 +1215,7 @@ adjust2DRatio (GLcontext *ctx,
}
tempImage = MALLOC(newWidth * newHeight * rawBytes);
if (!tempImage) {
+ FREE(rawImage);
return GL_FALSE;
}
/* unpack image, apply transfer ops and store in rawImage */
@@ -1220,7 +1223,7 @@ adjust2DRatio (GLcontext *ctx,
&_mesa_texformat_rgba8888_rev, rawImage,
0, 0, 0, /* dstX/Y/Zoffset */
width * rawBytes, /* dstRowStride */
- 0, /* dstImageStride */
+ &dstImageOffsets,
width, height, 1,
format, type, pixels, packing);
_mesa_rescale_teximage2d(rawBytes,
@@ -1233,7 +1236,7 @@ adjust2DRatio (GLcontext *ctx,
texImage->TexFormat, texImage->Data,
xoffset * mml->wScale, yoffset * mml->hScale, 0, /* dstX/Y/Zoffset */
dstRowStride,
- 0, /* dstImageStride */
+ &dstImageOffsets,
newWidth, newHeight, 1,
GL_RGBA, CHAN_TYPE, tempImage, &ctx->DefaultPacking);
FREE(rawImage);
@@ -1257,6 +1260,7 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level,
tdfxTexInfo *ti;
tdfxMipMapLevel *mml;
GLint texelBytes, dstRowStride;
+ GLuint mesaFormat;
/*
printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
@@ -1344,9 +1348,10 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level,
texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
internalFormat, format, type);
assert(texImage->TexFormat);
- mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat);
+ mesaFormat = texImage->TexFormat->MesaFormat;
+ mml->glideFormat = fxGlideFormat(mesaFormat);
ti->info.format = mml->glideFormat;
- texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat);
+ texImage->FetchTexelc = fxFetchFunction(mesaFormat);
texelBytes = texImage->TexFormat->TexelBytes;
if (texImage->IsCompressed) {
@@ -1354,12 +1359,13 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level,
mml->width,
mml->height,
1,
- internalFormat);
- dstRowStride = _mesa_compressed_row_stride(internalFormat, mml->width);
- texImage->Data = _mesa_malloc(texImage->CompressedSize);
+ mesaFormat);
+ dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width);
+ texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize);
} else {
dstRowStride = mml->width * texelBytes;
- texImage->Data = _mesa_malloc(mml->width * mml->height * texelBytes);
+ texImage->Data = _mesa_alloc_texmemory(mml->width * mml->height *
+ texelBytes);
}
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
@@ -1387,12 +1393,12 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level,
/* no rescaling needed */
/* unpack image, apply transfer ops and store in texImage->Data */
texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
- texImage->TexFormat, texImage->Data,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- 0, /* dstImageStride */
- width, height, 1,
- format, type, pixels, packing);
+ texImage->TexFormat, texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, pixels, packing);
}
/* GL_SGIS_generate_mipmap */
@@ -1473,7 +1479,7 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
texelBytes = texImage->TexFormat->TexelBytes;
if (texImage->IsCompressed) {
- dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, mml->width);
+ dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width);
} else {
dstRowStride = mml->width * texelBytes;
}
@@ -1497,12 +1503,12 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
else {
/* no rescaling needed */
texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
- texImage->TexFormat, texImage->Data,
- xoffset, yoffset, 0,
- dstRowStride,
- 0, /* dstImageStride */
- width, height, 1,
- format, type, pixels, packing);
+ texImage->TexFormat, texImage->Data,
+ xoffset, yoffset, 0,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, pixels, packing);
}
/* GL_SGIS_generate_mipmap */
@@ -1600,6 +1606,7 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target,
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
tdfxTexInfo *ti;
tdfxMipMapLevel *mml;
+ GLuint mesaFormat;
if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
fprintf(stderr, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
@@ -1651,9 +1658,10 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target,
/* Determine the appropriate Glide texel format,
* given the user's internal texture format hint.
*/
- mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat);
+ mesaFormat = texImage->TexFormat->MesaFormat;
+ mml->glideFormat = fxGlideFormat(mesaFormat);
ti->info.format = mml->glideFormat;
- texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat);
+ texImage->FetchTexelc = fxFetchFunction(mesaFormat);
/* allocate new storage for texture image, if needed */
if (!texImage->Data) {
@@ -1661,8 +1669,8 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target,
mml->width,
mml->height,
1,
- internalFormat);
- texImage->Data = _mesa_malloc(texImage->CompressedSize);
+ mesaFormat);
+ texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
return;
@@ -1685,9 +1693,10 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target,
* we replicate the data over the padded area.
* For now, we take 2) + 3) but texelfetchers will be wrong!
*/
- GLuint srcRowStride = _mesa_compressed_row_stride(internalFormat, width);
+ const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
+ GLuint srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
- GLuint destRowStride = _mesa_compressed_row_stride(internalFormat,
+ GLuint destRowStride = _mesa_compressed_row_stride(mesaFormat,
mml->width);
_mesa_upscale_teximage2d(srcRowStride, (height+3) / 4,
@@ -1726,6 +1735,7 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
GLint destRowStride, srcRowStride;
GLint i, rows;
GLubyte *dest;
+ const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
fprintf(stderr, "tdfxCompressedTexSubImage2D: id=%d\n", texObj->Name);
@@ -1736,12 +1746,11 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
mml = TDFX_TEXIMAGE_DATA(texImage);
assert(mml);
- srcRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, width);
+ srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
- destRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,
- mml->width);
+ destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width);
dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
- texImage->InternalFormat,
+ mesaFormat,
mml->width,
(GLubyte*) texImage->Data);
@@ -1757,10 +1766,9 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
* see fxDDCompressedTexImage2D for caveats
*/
if (mml->wScale != 1 || mml->hScale != 1) {
- srcRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, texImage->Width);
+ srcRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
- destRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,
- mml->width);
+ destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width);
_mesa_upscale_teximage2d(srcRowStride, texImage->Height / 4,
destRowStride, mml->height / 4,
1, texImage->Data, destRowStride,
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c
index 1daf49f151f..c8c6dc01933 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.c
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c
@@ -233,7 +233,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
if (mask & BUFFER_BIT_STENCIL) {
if (vmesa->have_hw_stencil) {
- if (ctx->Stencil.WriteMask[0] == 0xff) {
+ if ((ctx->Stencil.WriteMask[0] & 0xff) == 0xff) {
flag |= VIA_DEPTH;
clear_depth &= ~0xff;
clear_depth |= (ctx->Stencil.Clear & 0xff);
diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c
index 19b270955eb..b344c009318 100644
--- a/src/mesa/drivers/dri/unichrome/via_tex.c
+++ b/src/mesa/drivers/dri/unichrome/via_tex.c
@@ -691,6 +691,14 @@ static void viaTexImage(GLcontext *ctx,
}
texelBytes = texImage->TexFormat->TexelBytes;
+ if (texelBytes == 0) {
+ /* compressed format */
+ texImage->IsCompressed = GL_TRUE;
+ texImage->CompressedSize =
+ ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
+ texImage->Height, texImage->Depth,
+ texImage->TexFormat->MesaFormat);
+ }
/* Minimum pitch of 32 bytes */
if (postConvWidth * texelBytes < 32) {
@@ -779,10 +787,10 @@ static void viaTexImage(GLcontext *ctx,
return;
}
else {
- GLint dstRowStride, dstImageStride = 0;
+ GLint dstRowStride;
GLboolean success;
if (texImage->IsCompressed) {
- dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,width);
+ dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
}
else {
dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
@@ -793,7 +801,8 @@ static void viaTexImage(GLcontext *ctx,
texImage->TexFormat,
texImage->Data,
0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride, dstImageStride,
+ dstRowStride,
+ texImage->ImageOffsets,
width, height, 1,
format, type, pixels, packing);
if (!success) {
diff --git a/src/mesa/drivers/dri/unichrome/via_tris.c b/src/mesa/drivers/dri/unichrome/via_tris.c
index 9cb88ae2399..4cc7942b1b6 100644
--- a/src/mesa/drivers/dri/unichrome/via_tris.c
+++ b/src/mesa/drivers/dri/unichrome/via_tris.c
@@ -744,16 +744,18 @@ static void viaChooseVertexState( GLcontext *ctx )
{
struct via_context *vmesa = VIA_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
GLuint regCmdB = HC_HVPMSK_X | HC_HVPMSK_Y | HC_HVPMSK_Z;
GLuint setupIndex = 0;
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
vmesa->vertex_attr_count = 0;
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
* build up a hardware vertex.
*/
- if (index & (_TNL_BITS_TEX_ANY|_TNL_BIT_FOG)) {
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VIA_EMIT_W, HC_HVPMSK_W );
vmesa->coloroffset = 4;
}
@@ -767,8 +769,9 @@ static void viaChooseVertexState( GLcontext *ctx )
HC_HVPMSK_Cd );
vmesa->specoffset = 0;
- if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
- if ((index & _TNL_BIT_COLOR1)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
vmesa->specoffset = vmesa->coloroffset + 1;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VIA_EMIT_SPEC,
HC_HVPMSK_Cs );
@@ -776,13 +779,13 @@ static void viaChooseVertexState( GLcontext *ctx )
else
EMIT_PAD( 3 );
- if ((index & _TNL_BIT_FOG))
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VIA_EMIT_FOG, HC_HVPMSK_Cs );
else
EMIT_PAD( 1 );
}
- if (index & _TNL_BIT_TEX(0)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
if (vmesa->ptexHack)
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, VIA_EMIT_PTEX0,
(HC_HVPMSK_S | HC_HVPMSK_T) );
@@ -791,7 +794,7 @@ static void viaChooseVertexState( GLcontext *ctx )
(HC_HVPMSK_S | HC_HVPMSK_T) );
}
- if (index & _TNL_BIT_TEX(1)) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, VIA_EMIT_TEX1,
(HC_HVPMSK_S | HC_HVPMSK_T) );
}
@@ -824,17 +827,19 @@ static GLboolean viaCheckPTexHack( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint index = tnl->render_inputs;
+ DECLARE_RENDERINPUTS(index_bitset);
GLboolean fallback = GL_FALSE;
GLboolean ptexHack = GL_FALSE;
- if (index & _TNL_BIT_TEX(0) && VB->TexCoordPtr[0]->size == 4) {
- if ((index & _TNL_BITS_TEX_ANY) == _TNL_BIT_TEX(0))
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->TexCoordPtr[0]->size == 4) {
+ if (!RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_ATTRIB_TEX1, _TNL_LAST_TEX ))
ptexHack = GL_TRUE;
else
fallback = GL_TRUE;
}
- if ((index & _TNL_BIT_TEX(1)) && VB->TexCoordPtr[1]->size == 4)
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->TexCoordPtr[1]->size == 4)
fallback = GL_TRUE;
FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_PROJ_TEXTURE, fallback);