Merge commit 'origin/master' into drm-gem
This commit is contained in:
@@ -192,6 +192,7 @@ MAIN_FILES = \
|
||||
$(DIRECTORY)/bin/install-sh \
|
||||
$(DIRECTORY)/bin/mklib \
|
||||
$(DIRECTORY)/bin/minstall \
|
||||
$(DIRECTORY)/bin/version.mk \
|
||||
$(DIRECTORY)/configs/[a-z]* \
|
||||
$(DIRECTORY)/docs/*.html \
|
||||
$(DIRECTORY)/docs/COPYING \
|
||||
|
||||
+108
-101
@@ -39,11 +39,6 @@ if test "x$GCC" = xyes; then
|
||||
fi
|
||||
AC_SUBST([MKDEP_OPTIONS])
|
||||
|
||||
dnl Check to see if dlopen is in default libraries (like Solaris, which
|
||||
dnl has it in libc), or if libdl is needed to get it.
|
||||
AC_CHECK_FUNC([dlopen], [],
|
||||
[AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])])
|
||||
|
||||
dnl Make sure the pkg-config macros are defined
|
||||
m4_ifdef([PKG_PROG_PKG_CONFIG],[],[
|
||||
m4_errprint([Error: Could not locate the pkg-config autoconf macros.
|
||||
@@ -230,6 +225,107 @@ AC_SUBST([GLUT_LIB_NAME])
|
||||
AC_SUBST([GLW_LIB_NAME])
|
||||
AC_SUBST([OSMESA_LIB_NAME])
|
||||
|
||||
dnl
|
||||
dnl Arch/platform-specific settings
|
||||
dnl
|
||||
AC_ARG_ENABLE([asm],
|
||||
[AS_HELP_STRING([--disable-asm],
|
||||
[disable assembly usage @<:@default=enabled on supported plaforms@:>@])],
|
||||
[enable_asm="$enableval"],
|
||||
[enable_asm=yes]
|
||||
)
|
||||
asm_arch=""
|
||||
ASM_FLAGS=""
|
||||
ASM_SOURCES=""
|
||||
ASM_API=""
|
||||
AC_MSG_CHECKING([whether to enable assembly])
|
||||
test "x$enable_asm" = xno && AC_MSG_RESULT([no])
|
||||
# disable if cross compiling on x86/x86_64 since we must run gen_matypes
|
||||
if test "x$enable_asm" = xyes && test "x$cross_compiling" = xyes; then
|
||||
case "$host_cpu" in
|
||||
i?86 | x86_64)
|
||||
enable_asm=no
|
||||
AC_MSG_RESULT([no, cross compiling])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# check for supported arches
|
||||
if test "x$enable_asm" = xyes; then
|
||||
case "$host_cpu" in
|
||||
i?86)
|
||||
case "$host_os" in
|
||||
linux* | freebsd* | dragonfly*)
|
||||
test "x$enable_64bit" = xyes && asm_arch=x86_64 || asm_arch=x86
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
x86_64)
|
||||
case "$host_os" in
|
||||
linux* | freebsd* | dragonfly*)
|
||||
test "x$enable_32bit" = xyes && asm_arch=x86 || asm_arch=x86_64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
powerpc)
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
asm_arch=ppc
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$asm_arch" in
|
||||
x86)
|
||||
ASM_FLAGS="-DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM"
|
||||
ASM_SOURCES='$(X86_SOURCES)'
|
||||
ASM_API='$(X86_API)'
|
||||
AC_MSG_RESULT([yes, x86])
|
||||
;;
|
||||
x86_64)
|
||||
ASM_FLAGS="-DUSE_X86_64_ASM"
|
||||
ASM_SOURCES='$(X86-64_SOURCES)'
|
||||
ASM_API='$(X86-64_API)'
|
||||
AC_MSG_RESULT([yes, x86_64])
|
||||
;;
|
||||
ppc)
|
||||
ASM_FLAGS="-DUSE_PPC_ASM -DUSE_VMX_ASM"
|
||||
ASM_SOURCES='$(PPC_SOURCES)'
|
||||
AC_MSG_RESULT([yes, ppc])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([no, platform not supported])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_SUBST([ASM_FLAGS])
|
||||
AC_SUBST([ASM_SOURCES])
|
||||
AC_SUBST([ASM_API])
|
||||
|
||||
dnl PIC code macro
|
||||
MESA_PIC_FLAGS
|
||||
|
||||
dnl Check to see if dlopen is in default libraries (like Solaris, which
|
||||
dnl has it in libc), or if libdl is needed to get it.
|
||||
AC_CHECK_FUNC([dlopen], [],
|
||||
[AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])])
|
||||
|
||||
dnl SELinux awareness.
|
||||
AC_ARG_ENABLE([selinux],
|
||||
[AS_HELP_STRING([--enable-selinux],
|
||||
[Build SELinux-aware Mesa @<:@default=disabled@:>@])],
|
||||
[MESA_SELINUX="$enableval"],
|
||||
[MESA_SELINUX=no])
|
||||
if test "x$enable_selinux" = "xyes"; then
|
||||
AC_CHECK_HEADER([selinux/selinux.h],[],
|
||||
[AC_MSG_ERROR([SELinux headers not found])])
|
||||
AC_CHECK_LIB([selinux],[is_selinux_enabled],[],
|
||||
[AC_MSG_ERROR([SELinux library not found])])
|
||||
SELINUX_LIBS="-lselinux"
|
||||
DEFINES="$DEFINES -DMESA_SELINUX"
|
||||
fi
|
||||
|
||||
|
||||
dnl
|
||||
dnl Driver configuration. Options are xlib, dri and osmesa right now.
|
||||
dnl More later: directfb, fbdev, ...
|
||||
@@ -368,21 +464,6 @@ else
|
||||
enable_xcb=no
|
||||
fi
|
||||
|
||||
# SELinux awareness.
|
||||
AC_ARG_ENABLE([selinux],
|
||||
[AS_HELP_STRING([--enable-selinux],
|
||||
[Build SELinux-aware Mesa (default: disabled)])],
|
||||
[MESA_SELINUX="$enableval"],
|
||||
[MESA_SELINUX=no])
|
||||
if test "x$enable_selinux" = "xyes"; then
|
||||
AC_CHECK_HEADER([selinux/selinux.h],[],
|
||||
[AC_MSG_ERROR([SELinux headers not found])])
|
||||
AC_CHECK_LIB([selinux],[is_selinux_enabled],[],
|
||||
[AC_MSG_ERROR([SELinux library not found])])
|
||||
SELINUX_LIBS="-lselinux"
|
||||
DEFINES="$DEFINES -DMESA_SELINUX"
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl libGL configuration per driver
|
||||
dnl
|
||||
@@ -481,7 +562,7 @@ AC_ARG_ENABLE([driglx-direct],
|
||||
dnl ttm support
|
||||
AC_ARG_ENABLE([ttm-api],
|
||||
[AS_HELP_STRING([--enable-ttm-api],
|
||||
[enable TTM API users])],
|
||||
[enable TTM API users @<:@default=disabled@:>@])],
|
||||
[ttmapi="$enableval"],
|
||||
[ttmapi="no"])
|
||||
|
||||
@@ -564,6 +645,12 @@ if test "$mesa_driver" = dri; then
|
||||
DRI_DIRS="mach64 r128 r200 r300 radeon tdfx swrast"
|
||||
fi
|
||||
;;
|
||||
sparc*)
|
||||
# Build only the drivers for cards that exist on sparc`
|
||||
if test "x$DRI_DIRS" = x; then
|
||||
DRI_DIRS="mach64 r128 r200 r300 radeon ffb swrast"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
freebsd* | dragonfly*)
|
||||
@@ -832,86 +919,6 @@ fi
|
||||
AC_SUBST([APP_LIB_DEPS])
|
||||
AC_SUBST([PROGRAM_DIRS])
|
||||
|
||||
dnl
|
||||
dnl Arch/platform-specific settings
|
||||
dnl
|
||||
AC_ARG_ENABLE([asm],
|
||||
[AS_HELP_STRING([--disable-asm],
|
||||
[disable assembly usage @<:@default=enabled on supported plaforms@:>@])],
|
||||
[enable_asm="$enableval"],
|
||||
[enable_asm=yes]
|
||||
)
|
||||
asm_arch=""
|
||||
ASM_FLAGS=""
|
||||
ASM_SOURCES=""
|
||||
ASM_API=""
|
||||
AC_MSG_CHECKING([whether to enable assembly])
|
||||
test "x$enable_asm" = xno && AC_MSG_RESULT([no])
|
||||
# disable if cross compiling on x86/x86_64 since we must run gen_matypes
|
||||
if test "x$enable_asm" = xyes && test "x$cross_compiling" = xyes; then
|
||||
case "$host_cpu" in
|
||||
i?86 | x86_64)
|
||||
enable_asm=no
|
||||
AC_MSG_RESULT([no, cross compiling])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# check for supported arches
|
||||
if test "x$enable_asm" = xyes; then
|
||||
case "$host_cpu" in
|
||||
i?86)
|
||||
case "$host_os" in
|
||||
linux* | freebsd* | dragonfly*)
|
||||
test "x$enable_64bit" = xyes && asm_arch=x86_64 || asm_arch=x86
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
x86_64)
|
||||
case "$host_os" in
|
||||
linux* | freebsd* | dragonfly*)
|
||||
test "x$enable_32bit" = xyes && asm_arch=x86 || asm_arch=x86_64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
powerpc)
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
asm_arch=ppc
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$asm_arch" in
|
||||
x86)
|
||||
ASM_FLAGS="-DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM"
|
||||
ASM_SOURCES='$(X86_SOURCES)'
|
||||
ASM_API='$(X86_API)'
|
||||
AC_MSG_RESULT([yes, x86])
|
||||
;;
|
||||
x86_64)
|
||||
ASM_FLAGS="-DUSE_X86_64_ASM"
|
||||
ASM_SOURCES='$(X86-64_SOURCES)'
|
||||
ASM_API='$(X86-64_API)'
|
||||
AC_MSG_RESULT([yes, x86_64])
|
||||
;;
|
||||
ppc)
|
||||
ASM_FLAGS="-DUSE_PPC_ASM -DUSE_VMX_ASM"
|
||||
ASM_SOURCES='$(PPC_SOURCES)'
|
||||
AC_MSG_RESULT([yes, ppc])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([no, platform not supported])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_SUBST([ASM_FLAGS])
|
||||
AC_SUBST([ASM_SOURCES])
|
||||
AC_SUBST([ASM_API])
|
||||
|
||||
dnl PIC code macro
|
||||
MESA_PIC_FLAGS
|
||||
|
||||
|
||||
dnl Restore LDFLAGS and CPPFLAGS
|
||||
LDFLAGS="$_SAVE_LDFLAGS"
|
||||
|
||||
@@ -26,7 +26,7 @@ TBD
|
||||
|
||||
<h2>New features</h2>
|
||||
<ul>
|
||||
<li>autoconf-based configuration
|
||||
<li>autoconf-based configuration (and clean-up of Makefiles)
|
||||
<li>Reduced dependencies between X server and Mesa
|
||||
<li>GL_EXT_texture_from_pixmap extension for Xlib driver
|
||||
<li>Support for the GL shading language with i965 driver (implemented by Intel)
|
||||
|
||||
+17
-17
@@ -1,17 +1,17 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Mesa Source Code Documentation</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="qindex">
|
||||
<a class="qindex" href="../main/index.html">core</a> |
|
||||
<a class="qindex" href="../glapi/index.html">glapi</a> |
|
||||
<a class="qindex" href="../vbo/index.html">vbo</a> |
|
||||
<a class="qindex" href="../math/index.html">math</a> |
|
||||
<a class="qindex" href="../shader/index.html">shader</a> |
|
||||
<a class="qindex" href="../swrast/index.html">swrast</a> |
|
||||
<a class="qindex" href="../swrast_setup/index.html">swrast_setup</a> |
|
||||
<a class="qindex" href="../tnl/index.html">tnl</a> |
|
||||
<a class="qindex" href="../tnl_dd/index.html">tnl_dd</a>
|
||||
</div>
|
||||
<html>
|
||||
<head>
|
||||
<title>Mesa Source Code Documentation</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="qindex">
|
||||
<a class="qindex" href="../main/index.html">core</a> |
|
||||
<a class="qindex" href="../glapi/index.html">glapi</a> |
|
||||
<a class="qindex" href="../vbo/index.html">vbo</a> |
|
||||
<a class="qindex" href="../math/index.html">math</a> |
|
||||
<a class="qindex" href="../shader/index.html">shader</a> |
|
||||
<a class="qindex" href="../swrast/index.html">swrast</a> |
|
||||
<a class="qindex" href="../swrast_setup/index.html">swrast_setup</a> |
|
||||
<a class="qindex" href="../tnl/index.html">tnl</a> |
|
||||
<a class="qindex" href="../tnl_dd/index.html">tnl_dd</a>
|
||||
</div>
|
||||
|
||||
+11
-11
@@ -1,11 +1,11 @@
|
||||
<html>
|
||||
<head><title>Mesa Source Code Documentation</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="qindex">
|
||||
<a class="qindex" href="../core_subset/index.html">Mesa Core</a> |
|
||||
<a class="qindex" href="../math_subset/index.html">math</a> |
|
||||
<a class="qindex" href="../miniglx/index.html">MiniGLX</a> |
|
||||
<a class="qindex" href="../radeon_subset/index.html">radeon_subset</a>
|
||||
</div>
|
||||
<html>
|
||||
<head><title>Mesa Source Code Documentation</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="qindex">
|
||||
<a class="qindex" href="../core_subset/index.html">Mesa Core</a> |
|
||||
<a class="qindex" href="../math_subset/index.html">math</a> |
|
||||
<a class="qindex" href="../miniglx/index.html">MiniGLX</a> |
|
||||
<a class="qindex" href="../radeon_subset/index.html">radeon_subset</a>
|
||||
</div>
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.0
|
||||
* Copyright (C) 1995-1998 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Example Foo/Mesa interface. See src/ddsample.c for more info.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef FOOMESA_H
|
||||
#define FOOMESA_H
|
||||
|
||||
|
||||
|
||||
typedef struct foo_mesa_visual *FooMesaVisual;
|
||||
|
||||
typedef struct foo_mesa_buffer *FooMesaBuffer;
|
||||
|
||||
typedef struct foo_mesa_context *FooMesaContext;
|
||||
|
||||
|
||||
|
||||
#ifdef BEOS
|
||||
#pragma export on
|
||||
#endif
|
||||
|
||||
|
||||
extern FooMesaVisual FooMesaChooseVisual( /* your params */ );
|
||||
|
||||
extern void FooMesaDestroyVisual( FooMesaVisual visual );
|
||||
|
||||
|
||||
extern FooMesaBuffer FooMesaCreateBuffer( FooMesaVisual visual,
|
||||
void *your_window_id );
|
||||
|
||||
extern void FooMesaDestroyBuffer( FooMesaBuffer buffer );
|
||||
|
||||
|
||||
extern FooMesaContext FooMesaCreateContext( FooMesaVisual visual,
|
||||
FooMesaContext sharelist );
|
||||
|
||||
extern void FooMesaDestroyContext( FooMesaContext context );
|
||||
|
||||
|
||||
extern void FooMesaMakeCurrent( FooMesaContext context, FooMesaBuffer buffer );
|
||||
|
||||
|
||||
extern void FooMesaSwapBuffers( FooMesaBuffer buffer );
|
||||
|
||||
|
||||
/* Probably some more functions... */
|
||||
|
||||
|
||||
#ifdef BEOS
|
||||
#pragma export off
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
static GLfloat Xrot = 0, Yrot = -30, Zrot = 0;
|
||||
static GLboolean Anim = GL_TRUE;
|
||||
static GLint Bias = 0, BiasStepSign = +1; /* ints avoid fp precision problem */
|
||||
static GLint Bias = 4, BiasStepSign = +1; /* ints avoid fp precision problem */
|
||||
static GLint BiasMin = -400, BiasMax = 400;
|
||||
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ int textureWidth = 64;
|
||||
int textureHeight = 64;
|
||||
|
||||
int winWidth = 580, winHeight = 720;
|
||||
int win;
|
||||
|
||||
struct formatInfo {
|
||||
GLenum baseFormat;
|
||||
@@ -288,6 +289,7 @@ static void keyboard( unsigned char c, int x, int y )
|
||||
displayLevelInfo = !displayLevelInfo;
|
||||
break;
|
||||
case 27: /* Escape key should force exit. */
|
||||
glutDestroyWindow(win);
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
@@ -785,7 +787,7 @@ int main( int argc, char *argv[] )
|
||||
|
||||
glutInitWindowSize( winWidth, winHeight );
|
||||
glutInitWindowPosition( 0, 0 );
|
||||
glutCreateWindow( "Texture Environment Test" );
|
||||
win = glutCreateWindow( "Texture Environment Test" );
|
||||
|
||||
initialize();
|
||||
instructions();
|
||||
|
||||
@@ -4,10 +4,13 @@ bump
|
||||
deriv
|
||||
extfuncs.h
|
||||
mandelbrot
|
||||
multitex
|
||||
noise
|
||||
points
|
||||
readtex.c
|
||||
readtex.h
|
||||
shaderutil.c
|
||||
shaderutil.h
|
||||
texdemo1
|
||||
toyball
|
||||
trirast
|
||||
|
||||
@@ -407,7 +407,10 @@ test(GLenum type, GLint bits, const char *filename)
|
||||
glGetIntegerv(GL_ALPHA_BITS, &cBits);
|
||||
assert(cBits == bits);
|
||||
|
||||
printf("Rendering %d bit/channel image: %s\n", bits, filename);
|
||||
if (WriteFiles)
|
||||
printf("Rendering %d bit/channel image: %s\n", bits, filename);
|
||||
else
|
||||
printf("Rendering %d bit/channel image\n", bits);
|
||||
|
||||
OSMesaColorClamp(GL_TRUE);
|
||||
|
||||
@@ -458,6 +461,8 @@ main( int argc, char *argv[] )
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Use -f to write image files\n");
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-f") == 0)
|
||||
WriteFiles = GL_TRUE;
|
||||
|
||||
+113
-74
@@ -88,12 +88,18 @@ current_time(void)
|
||||
#endif
|
||||
|
||||
|
||||
/** Event handler results: */
|
||||
#define NOP 0
|
||||
#define EXIT 1
|
||||
#define DRAW 2
|
||||
|
||||
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
|
||||
static GLint gear1, gear2, gear3;
|
||||
static GLfloat angle = 0.0;
|
||||
|
||||
static GLboolean fullscreen = GL_FALSE; /* Create a single fullscreen window */
|
||||
static GLboolean stereo = GL_FALSE; /* Enable stereo. */
|
||||
static GLboolean animate = GL_TRUE; /* Animation */
|
||||
static GLfloat eyesep = 5.0; /* Eye separation. */
|
||||
static GLfloat fix_point = 40.0; /* Fixation point distance. */
|
||||
static GLfloat left, right, asp; /* Stereo frustum params. */
|
||||
@@ -239,7 +245,7 @@ gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
|
||||
|
||||
|
||||
static void
|
||||
do_draw(void)
|
||||
draw(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
@@ -269,8 +275,9 @@ do_draw(void)
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
draw(void)
|
||||
draw_gears(void)
|
||||
{
|
||||
if (stereo) {
|
||||
/* First left eye. */
|
||||
@@ -284,7 +291,7 @@ draw(void)
|
||||
|
||||
glPushMatrix();
|
||||
glTranslated(+0.5 * eyesep, 0.0, 0.0);
|
||||
do_draw();
|
||||
draw();
|
||||
glPopMatrix();
|
||||
|
||||
/* Then right eye. */
|
||||
@@ -298,10 +305,50 @@ draw(void)
|
||||
|
||||
glPushMatrix();
|
||||
glTranslated(-0.5 * eyesep, 0.0, 0.0);
|
||||
do_draw();
|
||||
draw();
|
||||
glPopMatrix();
|
||||
} else
|
||||
do_draw();
|
||||
}
|
||||
else {
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Draw single frame, do SwapBuffers, compute FPS */
|
||||
static void
|
||||
draw_frame(Display *dpy, Window win)
|
||||
{
|
||||
static int frames = 0;
|
||||
static double tRot0 = -1.0, tRate0 = -1.0;
|
||||
double dt, t = current_time();
|
||||
|
||||
if (tRot0 < 0.0)
|
||||
tRot0 = t;
|
||||
dt = t - tRot0;
|
||||
tRot0 = t;
|
||||
|
||||
if (animate) {
|
||||
/* advance rotation for next frame */
|
||||
angle += 70.0 * dt; /* 70 degrees per second */
|
||||
if (angle > 3600.0)
|
||||
angle -= 3600.0;
|
||||
}
|
||||
|
||||
draw_gears();
|
||||
glXSwapBuffers(dpy, win);
|
||||
|
||||
frames++;
|
||||
|
||||
if (tRate0 < 0.0)
|
||||
tRate0 = t;
|
||||
if (t - tRate0 >= 5.0) {
|
||||
GLfloat seconds = t - tRate0;
|
||||
GLfloat fps = frames / seconds;
|
||||
printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
|
||||
fps);
|
||||
tRate0 = t;
|
||||
frames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -319,7 +366,8 @@ reshape(int width, int height)
|
||||
|
||||
left = -5.0 * ((w - 0.5 * eyesep) / fix_point);
|
||||
right = 5.0 * ((w + 0.5 * eyesep) / fix_point);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
GLfloat h = (GLfloat) height / (GLfloat) width;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
@@ -430,6 +478,7 @@ make_window( Display *dpy, const char *name,
|
||||
attr.border_pixel = 0;
|
||||
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
|
||||
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
|
||||
/* XXX this is a bad way to get a borderless window! */
|
||||
attr.override_redirect = fullscreen;
|
||||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;
|
||||
|
||||
@@ -463,79 +512,70 @@ make_window( Display *dpy, const char *name,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle one X event.
|
||||
* \return NOP, EXIT or DRAW
|
||||
*/
|
||||
static int
|
||||
handle_event(Display *dpy, Window win, XEvent *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case Expose:
|
||||
return DRAW;
|
||||
case ConfigureNotify:
|
||||
reshape(event->xconfigure.width, event->xconfigure.height);
|
||||
break;
|
||||
case KeyPress:
|
||||
{
|
||||
char buffer[10];
|
||||
int r, code;
|
||||
code = XLookupKeysym(&event->xkey, 0);
|
||||
if (code == XK_Left) {
|
||||
view_roty += 5.0;
|
||||
}
|
||||
else if (code == XK_Right) {
|
||||
view_roty -= 5.0;
|
||||
}
|
||||
else if (code == XK_Up) {
|
||||
view_rotx += 5.0;
|
||||
}
|
||||
else if (code == XK_Down) {
|
||||
view_rotx -= 5.0;
|
||||
}
|
||||
else {
|
||||
r = XLookupString(&event->xkey, buffer, sizeof(buffer),
|
||||
NULL, NULL);
|
||||
if (buffer[0] == 27) {
|
||||
/* escape */
|
||||
return EXIT;
|
||||
}
|
||||
else if (buffer[0] == 'a' || buffer[0] == 'A') {
|
||||
animate = !animate;
|
||||
}
|
||||
}
|
||||
return DRAW;
|
||||
}
|
||||
}
|
||||
return NOP;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
event_loop(Display *dpy, Window win)
|
||||
{
|
||||
while (1) {
|
||||
while (XPending(dpy) > 0) {
|
||||
int op;
|
||||
while (!animate || XPending(dpy) > 0) {
|
||||
XEvent event;
|
||||
XNextEvent(dpy, &event);
|
||||
switch (event.type) {
|
||||
case Expose:
|
||||
/* we'll redraw below */
|
||||
break;
|
||||
case ConfigureNotify:
|
||||
reshape(event.xconfigure.width, event.xconfigure.height);
|
||||
break;
|
||||
case KeyPress:
|
||||
{
|
||||
char buffer[10];
|
||||
int r, code;
|
||||
code = XLookupKeysym(&event.xkey, 0);
|
||||
if (code == XK_Left) {
|
||||
view_roty += 5.0;
|
||||
}
|
||||
else if (code == XK_Right) {
|
||||
view_roty -= 5.0;
|
||||
}
|
||||
else if (code == XK_Up) {
|
||||
view_rotx += 5.0;
|
||||
}
|
||||
else if (code == XK_Down) {
|
||||
view_rotx -= 5.0;
|
||||
}
|
||||
else {
|
||||
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
|
||||
NULL, NULL);
|
||||
if (buffer[0] == 27) {
|
||||
/* escape */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
op = handle_event(dpy, win, &event);
|
||||
if (op == EXIT)
|
||||
return;
|
||||
else if (op == DRAW)
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
static int frames = 0;
|
||||
static double tRot0 = -1.0, tRate0 = -1.0;
|
||||
double dt, t = current_time();
|
||||
if (tRot0 < 0.0)
|
||||
tRot0 = t;
|
||||
dt = t - tRot0;
|
||||
tRot0 = t;
|
||||
|
||||
/* advance rotation for next frame */
|
||||
angle += 70.0 * dt; /* 70 degrees per second */
|
||||
if (angle > 3600.0)
|
||||
angle -= 3600.0;
|
||||
|
||||
draw();
|
||||
glXSwapBuffers(dpy, win);
|
||||
|
||||
frames++;
|
||||
|
||||
if (tRate0 < 0.0)
|
||||
tRate0 = t;
|
||||
if (t - tRate0 >= 5.0) {
|
||||
GLfloat seconds = t - tRate0;
|
||||
GLfloat fps = frames / seconds;
|
||||
printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
|
||||
fps);
|
||||
tRate0 = t;
|
||||
frames = 0;
|
||||
}
|
||||
}
|
||||
draw_frame(dpy, win);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,8 +588,7 @@ usage(void)
|
||||
printf(" -stereo run in stereo mode\n");
|
||||
printf(" -fullscreen run in fullscreen mode\n");
|
||||
printf(" -info display OpenGL renderer info\n");
|
||||
printf(" -winwidth <width> window width (default: 300)\n");
|
||||
printf(" -winheight <height> window height (default: 300)\n");
|
||||
printf(" -geometry WxH+X+Y window geometry\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -713,8 +713,8 @@ gluSphere(GLUquadric *qobj, GLdouble radius, GLint slices, GLint stacks)
|
||||
GLfloat cosCache3b[CACHE_SIZE];
|
||||
GLfloat angle;
|
||||
GLfloat zLow, zHigh;
|
||||
GLfloat sintemp1, sintemp2, sintemp3 = 0.0, sintemp4 = 0.0;
|
||||
GLfloat costemp1, costemp2 = 0.0, costemp3 = 0.0, costemp4 = 0.0;
|
||||
GLfloat sintemp1 = 0.0, sintemp2 = 0.0, sintemp3 = 0.0, sintemp4 = 0.0;
|
||||
GLfloat costemp1 = 0.0, costemp2 = 0.0, costemp3 = 0.0, costemp4 = 0.0;
|
||||
GLboolean needCache2, needCache3;
|
||||
GLint start, finish;
|
||||
|
||||
|
||||
+419
-419
@@ -1,420 +1,420 @@
|
||||
/* WarpWin.c */
|
||||
/* glut for Warp */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "WarpWin.h"
|
||||
#include "WarpGL.h"
|
||||
|
||||
#define POKA 0
|
||||
|
||||
/* global variables that must be set for some functions to operate
|
||||
correctly. */
|
||||
HDC XHDC;
|
||||
HWND XHWND;
|
||||
|
||||
|
||||
void
|
||||
XStoreColor(Display* display, Colormap colormap, XColor* color)
|
||||
{
|
||||
/* KLUDGE: set XHDC to 0 if the palette should NOT be realized after
|
||||
setting the color. set XHDC to the correct HDC if it should. */
|
||||
|
||||
LONG pe;
|
||||
ULONG cclr;
|
||||
int r,g,b;
|
||||
/* X11 stores color from 0-65535, Win32 expects them to be 0-256, so
|
||||
twiddle the bits ( / 256). */
|
||||
r = color->red / 256;
|
||||
g = color->green / 256;
|
||||
b = color->blue / 256;
|
||||
pe = LONGFromRGB(r,g,b);
|
||||
/* make sure we use this flag, otherwise the colors might get mapped
|
||||
to another place in the colormap, and when we glIndex() that
|
||||
color, it may have moved (argh!!) */
|
||||
pe |= (PC_NOCOLLAPSE<<24);
|
||||
/* This function changes the entries in a palette. */
|
||||
#if POKA
|
||||
OS2:
|
||||
rc = GpiSetPaletteEntries(colormap,LCOLF_CONSECRGB, color->pixel, 1, &pe);
|
||||
GpiSelectPalette(hps,colormap);
|
||||
WinRealizePalette(hwnd,hps,&cclr);
|
||||
source Win:
|
||||
if (XHDC) {
|
||||
UnrealizeObject(colormap);
|
||||
SelectPalette(XHDC, colormap, FALSE);
|
||||
RealizePalette(XHDC);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
XSetWindowColormap(Display* display, Window window, Colormap colormap)
|
||||
{
|
||||
#if POKA
|
||||
HDC hdc = GetDC(window);
|
||||
|
||||
/* if the third parameter is FALSE, the logical colormap is copied
|
||||
into the device palette when the application is in the
|
||||
foreground, if it is TRUE, the colors are mapped into the current
|
||||
palette in the best possible way. */
|
||||
SelectPalette(hdc, colormap, FALSE);
|
||||
RealizePalette(hdc);
|
||||
|
||||
/* note that we don't have to release the DC, since our window class
|
||||
uses the WC_OWNDC flag! */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* display, root and visual - don't used at all */
|
||||
Colormap
|
||||
XCreateColormap(Display* display, Window root, Visual* visual, int alloc)
|
||||
{
|
||||
/* KLUDGE: this function needs XHDC to be set to the HDC currently
|
||||
being operated on before it is invoked! */
|
||||
|
||||
HPAL palette;
|
||||
int n;
|
||||
#if POKA
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
LOGPALETTE *logical;
|
||||
|
||||
/* grab the pixel format */
|
||||
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
DescribePixelFormat(XHDC, GetPixelFormat(XHDC),
|
||||
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||
|
||||
if (!(pfd.dwFlags & PFD_NEED_PALETTE ||
|
||||
pfd.iPixelType == PFD_TYPE_COLORINDEX))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = 1 << pfd.cColorBits;
|
||||
|
||||
/* allocate a bunch of memory for the logical palette (assume 256
|
||||
colors in a Win32 palette */
|
||||
logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
|
||||
sizeof(PALETTEENTRY) * n);
|
||||
memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
|
||||
|
||||
/* set the entries in the logical palette */
|
||||
logical->palVersion = 0x300;
|
||||
logical->palNumEntries = n;
|
||||
|
||||
/* start with a copy of the current system palette */
|
||||
GetSystemPaletteEntries(XHDC, 0, 256, &logical->palPalEntry[0]);
|
||||
|
||||
if (pfd.iPixelType == PFD_TYPE_RGBA) {
|
||||
int redMask = (1 << pfd.cRedBits) - 1;
|
||||
int greenMask = (1 << pfd.cGreenBits) - 1;
|
||||
int blueMask = (1 << pfd.cBlueBits) - 1;
|
||||
int i;
|
||||
|
||||
/* fill in an RGBA color palette */
|
||||
for (i = 0; i < n; ++i) {
|
||||
logical->palPalEntry[i].peRed =
|
||||
(((i >> pfd.cRedShift) & redMask) * 255) / redMask;
|
||||
logical->palPalEntry[i].peGreen =
|
||||
(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
|
||||
logical->palPalEntry[i].peBlue =
|
||||
(((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
|
||||
logical->palPalEntry[i].peFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
palette = CreatePalette(logical);
|
||||
free(logical);
|
||||
|
||||
SelectPalette(XHDC, palette, FALSE);
|
||||
RealizePalette(XHDC);
|
||||
#endif /* POKA */
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GetSystemMetrics( int mode)
|
||||
{ RECTL rect;
|
||||
|
||||
switch(mode)
|
||||
{ case SM_CXSCREEN:
|
||||
WinQueryWindowRect(HWND_DESKTOP,&rect);
|
||||
return (rect.xRight-rect.xLeft);
|
||||
break;
|
||||
case SM_CYSCREEN:
|
||||
WinQueryWindowRect(HWND_DESKTOP,&rect);
|
||||
return (rect.yTop-rect.yBottom);
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* XParseGeometry parses strings of the form
|
||||
* "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
|
||||
* width, height, xoffset, and yoffset are unsigned integers.
|
||||
* Example: "=80x24+300-49"
|
||||
* The equal sign is optional.
|
||||
* It returns a bitmask that indicates which of the four values
|
||||
* were actually found in the string. For each value found,
|
||||
* the corresponding argument is updated; for each value
|
||||
* not found, the corresponding argument is left unchanged.
|
||||
*/
|
||||
|
||||
static int
|
||||
ReadInteger(char *string, char **NextString)
|
||||
{
|
||||
register int Result = 0;
|
||||
int Sign = 1;
|
||||
|
||||
if (*string == '+')
|
||||
string++;
|
||||
else if (*string == '-')
|
||||
{
|
||||
string++;
|
||||
Sign = -1;
|
||||
}
|
||||
for (; (*string >= '0') && (*string <= '9'); string++)
|
||||
{
|
||||
Result = (Result * 10) + (*string - '0');
|
||||
}
|
||||
*NextString = string;
|
||||
if (Sign >= 0)
|
||||
return (Result);
|
||||
else
|
||||
return (-Result);
|
||||
}
|
||||
|
||||
int XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height)
|
||||
{
|
||||
int mask = NoValue;
|
||||
register char *strind;
|
||||
unsigned int tempWidth, tempHeight;
|
||||
int tempX, tempY;
|
||||
char *nextCharacter;
|
||||
|
||||
if ( (string == NULL) || (*string == '\0')) return(mask);
|
||||
if (*string == '=')
|
||||
string++; /* ignore possible '=' at beg of geometry spec */
|
||||
|
||||
strind = (char *)string;
|
||||
if (*strind != '+' && *strind != '-' && *strind != 'x') {
|
||||
tempWidth = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= WidthValue;
|
||||
}
|
||||
|
||||
if (*strind == 'x' || *strind == 'X') {
|
||||
strind++;
|
||||
tempHeight = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= HeightValue;
|
||||
}
|
||||
|
||||
if ((*strind == '+') || (*strind == '-')) {
|
||||
if (*strind == '-') {
|
||||
strind++;
|
||||
tempX = -ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= XNegative;
|
||||
|
||||
}
|
||||
else
|
||||
{ strind++;
|
||||
tempX = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
}
|
||||
mask |= XValue;
|
||||
if ((*strind == '+') || (*strind == '-')) {
|
||||
if (*strind == '-') {
|
||||
strind++;
|
||||
tempY = -ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
mask |= YNegative;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
strind++;
|
||||
tempY = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
}
|
||||
mask |= YValue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If strind isn't at the end of the string the it's an invalid
|
||||
geometry specification. */
|
||||
|
||||
if (*strind != '\0') return (0);
|
||||
|
||||
if (mask & XValue)
|
||||
*x = tempX;
|
||||
if (mask & YValue)
|
||||
*y = tempY;
|
||||
if (mask & WidthValue)
|
||||
*width = tempWidth;
|
||||
if (mask & HeightValue)
|
||||
*height = tempHeight;
|
||||
return (mask);
|
||||
}
|
||||
|
||||
int gettimeofday(struct timeval* tp, void* tzp)
|
||||
{
|
||||
DATETIME DateTime;
|
||||
APIRET ulrc; /* Return Code. */
|
||||
|
||||
ulrc = DosGetDateTime(&DateTime);
|
||||
tp->tv_sec = 60 * (60*DateTime.hours + DateTime.minutes) + DateTime.seconds;
|
||||
tp->tv_usec = DateTime.hundredths * 10000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
XPending(Display* display)
|
||||
{
|
||||
/* similar functionality...I don't think that it is exact, but this
|
||||
will have to do. */
|
||||
QMSG msg;
|
||||
extern HAB hab; /* PM anchor block handle */
|
||||
|
||||
//?? WinPeekMsg(hab
|
||||
return WinPeekMsg(hab, &msg, NULLHANDLE, 0, 0, PM_NOREMOVE);
|
||||
}
|
||||
|
||||
void
|
||||
__glutAdjustCoords(Window parent, int* x, int* y, int* width, int* height)
|
||||
{
|
||||
RECTL rect;
|
||||
|
||||
/* adjust the window rectangle because Win32 thinks that the x, y,
|
||||
width & height are the WHOLE window (including decorations),
|
||||
whereas GLUT treats the x, y, width & height as only the CLIENT
|
||||
area of the window. */
|
||||
rect.xLeft = *x; rect.yTop = *y;
|
||||
rect.xRight = *x + *width; rect.yBottom = *y + *height;
|
||||
|
||||
/* must adjust the coordinates according to the correct style
|
||||
because depending on the style, there may or may not be
|
||||
borders. */
|
||||
//?? AdjustWindowRect(&rect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
|
||||
//?? (parent ? WS_CHILD : WS_OVERLAPPEDWINDOW),
|
||||
//?? FALSE);
|
||||
/* FALSE in the third parameter = window has no menu bar */
|
||||
|
||||
/* readjust if the x and y are offscreen */
|
||||
if(rect.xLeft < 0) {
|
||||
*x = 0;
|
||||
} else {
|
||||
*x = rect.xLeft;
|
||||
}
|
||||
|
||||
if(rect.yTop < 0) {
|
||||
*y = 0;
|
||||
} else {
|
||||
*y = rect.yTop;
|
||||
}
|
||||
|
||||
*width = rect.xRight - rect.xLeft; /* adjusted width */
|
||||
*height = -(rect.yBottom - rect.yTop); /* adjusted height */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo)
|
||||
{
|
||||
/* the transparent pixel on Win32 is always index number 0. So if
|
||||
we put this routine in this file, we can avoid compiling the
|
||||
whole of layerutil.c which is where this routine normally comes
|
||||
from. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Translate point coordinates src_x and src_y from src to dst */
|
||||
|
||||
Bool
|
||||
XTranslateCoordinates(Display *display, Window src, Window dst,
|
||||
int src_x, int src_y,
|
||||
int* dest_x_return, int* dest_y_return,
|
||||
Window* child_return)
|
||||
{
|
||||
SWP swp_src,swp_dst;
|
||||
|
||||
WinQueryWindowPos(src,&swp_src);
|
||||
WinQueryWindowPos(dst,&swp_dst);
|
||||
|
||||
*dest_x_return = src_x + swp_src.x - swp_dst.x;
|
||||
*dest_y_return = src_y + swp_src.y - swp_dst.y;
|
||||
|
||||
/* just to make compilers happy...we don't use the return value. */
|
||||
return True;
|
||||
}
|
||||
|
||||
Status
|
||||
XGetGeometry(Display* display, Window window, Window* root_return,
|
||||
int* x_return, int* y_return,
|
||||
unsigned int* width_return, unsigned int* height_return,
|
||||
unsigned int *border_width_return, unsigned int* depth_return)
|
||||
{
|
||||
/* KLUDGE: doesn't return the border_width or depth or root, x & y
|
||||
are in screen coordinates. */
|
||||
SWP swp_src;
|
||||
WinQueryWindowPos(window,&swp_src);
|
||||
|
||||
*x_return = swp_src.x;
|
||||
*y_return = swp_src.y;
|
||||
*width_return = swp_src.cx;
|
||||
*height_return = swp_src.cy;
|
||||
|
||||
/* just to make compilers happy...we don't use the return value. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get Display Width in millimeters */
|
||||
int
|
||||
DisplayWidthMM(Display* display, int screen)
|
||||
{
|
||||
int width;
|
||||
LONG *pVC_Caps;
|
||||
pVC_Caps = GetVideoConfig(NULLHANDLE);
|
||||
width = (int)( 0.001 * pVC_Caps[CAPS_WIDTH] / pVC_Caps[CAPS_HORIZONTAL_RESOLUTION]);/* mm */
|
||||
return width;
|
||||
}
|
||||
|
||||
/* Get Display Height in millimeters */
|
||||
int
|
||||
DisplayHeightMM(Display* display, int screen)
|
||||
{
|
||||
int height;
|
||||
LONG *pVC_Caps;
|
||||
pVC_Caps = GetVideoConfig(NULLHANDLE);
|
||||
height = (int)( 0.001 * pVC_Caps[CAPS_HEIGHT] / pVC_Caps[CAPS_VERTICAL_RESOLUTION]); /* mm */
|
||||
return height;
|
||||
}
|
||||
|
||||
void ScreenToClient( HWND hwnd, POINTL *point)
|
||||
{
|
||||
SWP swp_src;
|
||||
WinQueryWindowPos(hwnd,&swp_src);
|
||||
point->x -= swp_src.x;
|
||||
point->y -= swp_src.y;
|
||||
}
|
||||
|
||||
/* WarpWin.c */
|
||||
/* glut for Warp */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "WarpWin.h"
|
||||
#include "WarpGL.h"
|
||||
|
||||
#define POKA 0
|
||||
|
||||
/* global variables that must be set for some functions to operate
|
||||
correctly. */
|
||||
HDC XHDC;
|
||||
HWND XHWND;
|
||||
|
||||
|
||||
void
|
||||
XStoreColor(Display* display, Colormap colormap, XColor* color)
|
||||
{
|
||||
/* KLUDGE: set XHDC to 0 if the palette should NOT be realized after
|
||||
setting the color. set XHDC to the correct HDC if it should. */
|
||||
|
||||
LONG pe;
|
||||
ULONG cclr;
|
||||
int r,g,b;
|
||||
/* X11 stores color from 0-65535, Win32 expects them to be 0-256, so
|
||||
twiddle the bits ( / 256). */
|
||||
r = color->red / 256;
|
||||
g = color->green / 256;
|
||||
b = color->blue / 256;
|
||||
pe = LONGFromRGB(r,g,b);
|
||||
/* make sure we use this flag, otherwise the colors might get mapped
|
||||
to another place in the colormap, and when we glIndex() that
|
||||
color, it may have moved (argh!!) */
|
||||
pe |= (PC_NOCOLLAPSE<<24);
|
||||
/* This function changes the entries in a palette. */
|
||||
#if POKA
|
||||
OS2:
|
||||
rc = GpiSetPaletteEntries(colormap,LCOLF_CONSECRGB, color->pixel, 1, &pe);
|
||||
GpiSelectPalette(hps,colormap);
|
||||
WinRealizePalette(hwnd,hps,&cclr);
|
||||
source Win:
|
||||
if (XHDC) {
|
||||
UnrealizeObject(colormap);
|
||||
SelectPalette(XHDC, colormap, FALSE);
|
||||
RealizePalette(XHDC);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
XSetWindowColormap(Display* display, Window window, Colormap colormap)
|
||||
{
|
||||
#if POKA
|
||||
HDC hdc = GetDC(window);
|
||||
|
||||
/* if the third parameter is FALSE, the logical colormap is copied
|
||||
into the device palette when the application is in the
|
||||
foreground, if it is TRUE, the colors are mapped into the current
|
||||
palette in the best possible way. */
|
||||
SelectPalette(hdc, colormap, FALSE);
|
||||
RealizePalette(hdc);
|
||||
|
||||
/* note that we don't have to release the DC, since our window class
|
||||
uses the WC_OWNDC flag! */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* display, root and visual - don't used at all */
|
||||
Colormap
|
||||
XCreateColormap(Display* display, Window root, Visual* visual, int alloc)
|
||||
{
|
||||
/* KLUDGE: this function needs XHDC to be set to the HDC currently
|
||||
being operated on before it is invoked! */
|
||||
|
||||
HPAL palette;
|
||||
int n;
|
||||
#if POKA
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
LOGPALETTE *logical;
|
||||
|
||||
/* grab the pixel format */
|
||||
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
DescribePixelFormat(XHDC, GetPixelFormat(XHDC),
|
||||
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||
|
||||
if (!(pfd.dwFlags & PFD_NEED_PALETTE ||
|
||||
pfd.iPixelType == PFD_TYPE_COLORINDEX))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = 1 << pfd.cColorBits;
|
||||
|
||||
/* allocate a bunch of memory for the logical palette (assume 256
|
||||
colors in a Win32 palette */
|
||||
logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
|
||||
sizeof(PALETTEENTRY) * n);
|
||||
memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
|
||||
|
||||
/* set the entries in the logical palette */
|
||||
logical->palVersion = 0x300;
|
||||
logical->palNumEntries = n;
|
||||
|
||||
/* start with a copy of the current system palette */
|
||||
GetSystemPaletteEntries(XHDC, 0, 256, &logical->palPalEntry[0]);
|
||||
|
||||
if (pfd.iPixelType == PFD_TYPE_RGBA) {
|
||||
int redMask = (1 << pfd.cRedBits) - 1;
|
||||
int greenMask = (1 << pfd.cGreenBits) - 1;
|
||||
int blueMask = (1 << pfd.cBlueBits) - 1;
|
||||
int i;
|
||||
|
||||
/* fill in an RGBA color palette */
|
||||
for (i = 0; i < n; ++i) {
|
||||
logical->palPalEntry[i].peRed =
|
||||
(((i >> pfd.cRedShift) & redMask) * 255) / redMask;
|
||||
logical->palPalEntry[i].peGreen =
|
||||
(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
|
||||
logical->palPalEntry[i].peBlue =
|
||||
(((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
|
||||
logical->palPalEntry[i].peFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
palette = CreatePalette(logical);
|
||||
free(logical);
|
||||
|
||||
SelectPalette(XHDC, palette, FALSE);
|
||||
RealizePalette(XHDC);
|
||||
#endif /* POKA */
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GetSystemMetrics( int mode)
|
||||
{ RECTL rect;
|
||||
|
||||
switch(mode)
|
||||
{ case SM_CXSCREEN:
|
||||
WinQueryWindowRect(HWND_DESKTOP,&rect);
|
||||
return (rect.xRight-rect.xLeft);
|
||||
break;
|
||||
case SM_CYSCREEN:
|
||||
WinQueryWindowRect(HWND_DESKTOP,&rect);
|
||||
return (rect.yTop-rect.yBottom);
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* XParseGeometry parses strings of the form
|
||||
* "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
|
||||
* width, height, xoffset, and yoffset are unsigned integers.
|
||||
* Example: "=80x24+300-49"
|
||||
* The equal sign is optional.
|
||||
* It returns a bitmask that indicates which of the four values
|
||||
* were actually found in the string. For each value found,
|
||||
* the corresponding argument is updated; for each value
|
||||
* not found, the corresponding argument is left unchanged.
|
||||
*/
|
||||
|
||||
static int
|
||||
ReadInteger(char *string, char **NextString)
|
||||
{
|
||||
register int Result = 0;
|
||||
int Sign = 1;
|
||||
|
||||
if (*string == '+')
|
||||
string++;
|
||||
else if (*string == '-')
|
||||
{
|
||||
string++;
|
||||
Sign = -1;
|
||||
}
|
||||
for (; (*string >= '0') && (*string <= '9'); string++)
|
||||
{
|
||||
Result = (Result * 10) + (*string - '0');
|
||||
}
|
||||
*NextString = string;
|
||||
if (Sign >= 0)
|
||||
return (Result);
|
||||
else
|
||||
return (-Result);
|
||||
}
|
||||
|
||||
int XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height)
|
||||
{
|
||||
int mask = NoValue;
|
||||
register char *strind;
|
||||
unsigned int tempWidth, tempHeight;
|
||||
int tempX, tempY;
|
||||
char *nextCharacter;
|
||||
|
||||
if ( (string == NULL) || (*string == '\0')) return(mask);
|
||||
if (*string == '=')
|
||||
string++; /* ignore possible '=' at beg of geometry spec */
|
||||
|
||||
strind = (char *)string;
|
||||
if (*strind != '+' && *strind != '-' && *strind != 'x') {
|
||||
tempWidth = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= WidthValue;
|
||||
}
|
||||
|
||||
if (*strind == 'x' || *strind == 'X') {
|
||||
strind++;
|
||||
tempHeight = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= HeightValue;
|
||||
}
|
||||
|
||||
if ((*strind == '+') || (*strind == '-')) {
|
||||
if (*strind == '-') {
|
||||
strind++;
|
||||
tempX = -ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= XNegative;
|
||||
|
||||
}
|
||||
else
|
||||
{ strind++;
|
||||
tempX = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
}
|
||||
mask |= XValue;
|
||||
if ((*strind == '+') || (*strind == '-')) {
|
||||
if (*strind == '-') {
|
||||
strind++;
|
||||
tempY = -ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
mask |= YNegative;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
strind++;
|
||||
tempY = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
}
|
||||
mask |= YValue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If strind isn't at the end of the string the it's an invalid
|
||||
geometry specification. */
|
||||
|
||||
if (*strind != '\0') return (0);
|
||||
|
||||
if (mask & XValue)
|
||||
*x = tempX;
|
||||
if (mask & YValue)
|
||||
*y = tempY;
|
||||
if (mask & WidthValue)
|
||||
*width = tempWidth;
|
||||
if (mask & HeightValue)
|
||||
*height = tempHeight;
|
||||
return (mask);
|
||||
}
|
||||
|
||||
int gettimeofday(struct timeval* tp, void* tzp)
|
||||
{
|
||||
DATETIME DateTime;
|
||||
APIRET ulrc; /* Return Code. */
|
||||
|
||||
ulrc = DosGetDateTime(&DateTime);
|
||||
tp->tv_sec = 60 * (60*DateTime.hours + DateTime.minutes) + DateTime.seconds;
|
||||
tp->tv_usec = DateTime.hundredths * 10000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
XPending(Display* display)
|
||||
{
|
||||
/* similar functionality...I don't think that it is exact, but this
|
||||
will have to do. */
|
||||
QMSG msg;
|
||||
extern HAB hab; /* PM anchor block handle */
|
||||
|
||||
//?? WinPeekMsg(hab
|
||||
return WinPeekMsg(hab, &msg, NULLHANDLE, 0, 0, PM_NOREMOVE);
|
||||
}
|
||||
|
||||
void
|
||||
__glutAdjustCoords(Window parent, int* x, int* y, int* width, int* height)
|
||||
{
|
||||
RECTL rect;
|
||||
|
||||
/* adjust the window rectangle because Win32 thinks that the x, y,
|
||||
width & height are the WHOLE window (including decorations),
|
||||
whereas GLUT treats the x, y, width & height as only the CLIENT
|
||||
area of the window. */
|
||||
rect.xLeft = *x; rect.yTop = *y;
|
||||
rect.xRight = *x + *width; rect.yBottom = *y + *height;
|
||||
|
||||
/* must adjust the coordinates according to the correct style
|
||||
because depending on the style, there may or may not be
|
||||
borders. */
|
||||
//?? AdjustWindowRect(&rect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
|
||||
//?? (parent ? WS_CHILD : WS_OVERLAPPEDWINDOW),
|
||||
//?? FALSE);
|
||||
/* FALSE in the third parameter = window has no menu bar */
|
||||
|
||||
/* readjust if the x and y are offscreen */
|
||||
if(rect.xLeft < 0) {
|
||||
*x = 0;
|
||||
} else {
|
||||
*x = rect.xLeft;
|
||||
}
|
||||
|
||||
if(rect.yTop < 0) {
|
||||
*y = 0;
|
||||
} else {
|
||||
*y = rect.yTop;
|
||||
}
|
||||
|
||||
*width = rect.xRight - rect.xLeft; /* adjusted width */
|
||||
*height = -(rect.yBottom - rect.yTop); /* adjusted height */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo)
|
||||
{
|
||||
/* the transparent pixel on Win32 is always index number 0. So if
|
||||
we put this routine in this file, we can avoid compiling the
|
||||
whole of layerutil.c which is where this routine normally comes
|
||||
from. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Translate point coordinates src_x and src_y from src to dst */
|
||||
|
||||
Bool
|
||||
XTranslateCoordinates(Display *display, Window src, Window dst,
|
||||
int src_x, int src_y,
|
||||
int* dest_x_return, int* dest_y_return,
|
||||
Window* child_return)
|
||||
{
|
||||
SWP swp_src,swp_dst;
|
||||
|
||||
WinQueryWindowPos(src,&swp_src);
|
||||
WinQueryWindowPos(dst,&swp_dst);
|
||||
|
||||
*dest_x_return = src_x + swp_src.x - swp_dst.x;
|
||||
*dest_y_return = src_y + swp_src.y - swp_dst.y;
|
||||
|
||||
/* just to make compilers happy...we don't use the return value. */
|
||||
return True;
|
||||
}
|
||||
|
||||
Status
|
||||
XGetGeometry(Display* display, Window window, Window* root_return,
|
||||
int* x_return, int* y_return,
|
||||
unsigned int* width_return, unsigned int* height_return,
|
||||
unsigned int *border_width_return, unsigned int* depth_return)
|
||||
{
|
||||
/* KLUDGE: doesn't return the border_width or depth or root, x & y
|
||||
are in screen coordinates. */
|
||||
SWP swp_src;
|
||||
WinQueryWindowPos(window,&swp_src);
|
||||
|
||||
*x_return = swp_src.x;
|
||||
*y_return = swp_src.y;
|
||||
*width_return = swp_src.cx;
|
||||
*height_return = swp_src.cy;
|
||||
|
||||
/* just to make compilers happy...we don't use the return value. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get Display Width in millimeters */
|
||||
int
|
||||
DisplayWidthMM(Display* display, int screen)
|
||||
{
|
||||
int width;
|
||||
LONG *pVC_Caps;
|
||||
pVC_Caps = GetVideoConfig(NULLHANDLE);
|
||||
width = (int)( 0.001 * pVC_Caps[CAPS_WIDTH] / pVC_Caps[CAPS_HORIZONTAL_RESOLUTION]);/* mm */
|
||||
return width;
|
||||
}
|
||||
|
||||
/* Get Display Height in millimeters */
|
||||
int
|
||||
DisplayHeightMM(Display* display, int screen)
|
||||
{
|
||||
int height;
|
||||
LONG *pVC_Caps;
|
||||
pVC_Caps = GetVideoConfig(NULLHANDLE);
|
||||
height = (int)( 0.001 * pVC_Caps[CAPS_HEIGHT] / pVC_Caps[CAPS_VERTICAL_RESOLUTION]); /* mm */
|
||||
return height;
|
||||
}
|
||||
|
||||
void ScreenToClient( HWND hwnd, POINTL *point)
|
||||
{
|
||||
SWP swp_src;
|
||||
WinQueryWindowPos(hwnd,&swp_src);
|
||||
point->x -= swp_src.x;
|
||||
point->y -= swp_src.y;
|
||||
}
|
||||
|
||||
|
||||
+258
-258
@@ -1,259 +1,259 @@
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "glutint.h"
|
||||
|
||||
#if defined(__OS2PM__)
|
||||
#define IsWindowVisible WinIsWindowVisible
|
||||
#endif
|
||||
|
||||
#define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i)))
|
||||
|
||||
/* CENTRY */
|
||||
void GLUTAPIENTRY
|
||||
glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)
|
||||
{
|
||||
GLUTcolormap *cmap, *newcmap;
|
||||
XVisualInfo *vis;
|
||||
XColor color;
|
||||
int i;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
cmap = __glutCurrentWindow->colormap;
|
||||
vis = __glutCurrentWindow->vis;
|
||||
} else {
|
||||
cmap = __glutCurrentWindow->overlay->colormap;
|
||||
vis = __glutCurrentWindow->overlay->vis;
|
||||
if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
|
||||
__glutWarning(
|
||||
"glutSetColor: cannot set color of overlay transparent index %d\n",
|
||||
ndx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmap) {
|
||||
__glutWarning("glutSetColor: current window is RGBA");
|
||||
return;
|
||||
}
|
||||
#if defined(_WIN32) || defined(__OS2PM__)
|
||||
if (ndx >= 256 || /* always assume 256 colors on Win32 */
|
||||
#else
|
||||
if (ndx >= vis->visual->map_entries ||
|
||||
#endif
|
||||
ndx < 0) {
|
||||
__glutWarning("glutSetColor: index %d out of range", ndx);
|
||||
return;
|
||||
}
|
||||
if (cmap->refcnt > 1) {
|
||||
newcmap = __glutAssociateNewColormap(vis);
|
||||
cmap->refcnt--;
|
||||
/* Wouldn't it be nice if XCopyColormapAndFree could be
|
||||
told not to free the old colormap's entries! */
|
||||
for (i = cmap->size - 1; i >= 0; i--) {
|
||||
if (i == ndx) {
|
||||
/* We are going to set this cell shortly! */
|
||||
continue;
|
||||
}
|
||||
if (cmap->cells[i].component[GLUT_RED] >= 0.0) {
|
||||
color.pixel = i;
|
||||
newcmap->cells[i].component[GLUT_RED] =
|
||||
cmap->cells[i].component[GLUT_RED];
|
||||
color.red = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_RED];
|
||||
newcmap->cells[i].component[GLUT_GREEN] =
|
||||
cmap->cells[i].component[GLUT_GREEN];
|
||||
color.green = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_GREEN];
|
||||
newcmap->cells[i].component[GLUT_BLUE] =
|
||||
cmap->cells[i].component[GLUT_BLUE];
|
||||
color.blue = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_BLUE];
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
#if defined(_WIN32) || defined(__OS2PM__)
|
||||
if (IsWindowVisible(__glutCurrentWindow->win)) {
|
||||
XHDC = __glutCurrentWindow->hdc;
|
||||
} else {
|
||||
XHDC = 0;
|
||||
}
|
||||
#endif
|
||||
XStoreColor(__glutDisplay, newcmap->cmap, &color);
|
||||
} else {
|
||||
/* Leave unallocated entries unallocated. */
|
||||
}
|
||||
}
|
||||
cmap = newcmap;
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
__glutCurrentWindow->colormap = cmap;
|
||||
__glutCurrentWindow->cmap = cmap->cmap;
|
||||
} else {
|
||||
__glutCurrentWindow->overlay->colormap = cmap;
|
||||
__glutCurrentWindow->overlay->cmap = cmap->cmap;
|
||||
}
|
||||
XSetWindowColormap(__glutDisplay,
|
||||
__glutCurrentWindow->renderWin, cmap->cmap);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__OS2PM__)
|
||||
{
|
||||
GLUTwindow *toplevel;
|
||||
|
||||
toplevel = __glutToplevelOf(__glutCurrentWindow);
|
||||
if (toplevel->cmap != cmap->cmap) {
|
||||
__glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
color.pixel = ndx;
|
||||
red = CLAMP(red);
|
||||
cmap->cells[ndx].component[GLUT_RED] = red;
|
||||
color.red = (GLfloat) 0xffff *red;
|
||||
green = CLAMP(green);
|
||||
cmap->cells[ndx].component[GLUT_GREEN] = green;
|
||||
color.green = (GLfloat) 0xffff *green;
|
||||
blue = CLAMP(blue);
|
||||
cmap->cells[ndx].component[GLUT_BLUE] = blue;
|
||||
color.blue = (GLfloat) 0xffff *blue;
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
#if defined(_WIN32) || defined(__OS2PM__)
|
||||
if (IsWindowVisible(__glutCurrentWindow->win)) {
|
||||
XHDC = __glutCurrentWindow->hdc;
|
||||
} else {
|
||||
XHDC = 0;
|
||||
}
|
||||
#endif
|
||||
XStoreColor(__glutDisplay, cmap->cmap, &color);
|
||||
}
|
||||
|
||||
GLfloat GLUTAPIENTRY
|
||||
glutGetColor(int ndx, int comp)
|
||||
{
|
||||
GLUTcolormap *colormap;
|
||||
XVisualInfo *vis;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
colormap = __glutCurrentWindow->colormap;
|
||||
vis = __glutCurrentWindow->vis;
|
||||
} else {
|
||||
colormap = __glutCurrentWindow->overlay->colormap;
|
||||
vis = __glutCurrentWindow->overlay->vis;
|
||||
if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
|
||||
__glutWarning("glutGetColor: requesting overlay transparent index %d\n",
|
||||
ndx);
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!colormap) {
|
||||
__glutWarning("glutGetColor: current window is RGBA");
|
||||
return -1.0;
|
||||
}
|
||||
#if defined(_WIN32) || defined(__OS2PM__)
|
||||
#define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0)
|
||||
#else
|
||||
#define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0)
|
||||
#endif
|
||||
if (OUT_OF_RANGE_NDX(ndx)) {
|
||||
__glutWarning("glutGetColor: index %d out of range", ndx);
|
||||
return -1.0;
|
||||
}
|
||||
return colormap->cells[ndx].component[comp];
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutCopyColormap(int winnum)
|
||||
{
|
||||
GLUTwindow *window = __glutWindowList[winnum - 1];
|
||||
GLUTcolormap *oldcmap, *newcmap;
|
||||
XVisualInfo *dstvis;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
oldcmap = __glutCurrentWindow->colormap;
|
||||
dstvis = __glutCurrentWindow->vis;
|
||||
newcmap = window->colormap;
|
||||
} else {
|
||||
oldcmap = __glutCurrentWindow->overlay->colormap;
|
||||
dstvis = __glutCurrentWindow->overlay->vis;
|
||||
if (!window->overlay) {
|
||||
__glutWarning("glutCopyColormap: window %d has no overlay", winnum);
|
||||
return;
|
||||
}
|
||||
newcmap = window->overlay->colormap;
|
||||
}
|
||||
|
||||
if (!oldcmap) {
|
||||
__glutWarning("glutCopyColormap: destination colormap must be color index");
|
||||
return;
|
||||
}
|
||||
if (!newcmap) {
|
||||
__glutWarning(
|
||||
"glutCopyColormap: source colormap of window %d must be color index",
|
||||
winnum);
|
||||
return;
|
||||
}
|
||||
if (newcmap == oldcmap) {
|
||||
/* Source and destination are the same; now copy needed. */
|
||||
return;
|
||||
}
|
||||
#if !defined(_WIN32) && !defined(__OS2PM__)
|
||||
/* Play safe: compare visual IDs, not Visual*'s. */
|
||||
if (newcmap->visual->visualid == oldcmap->visual->visualid) {
|
||||
#endif
|
||||
/* Visuals match! "Copy" by reference... */
|
||||
__glutFreeColormap(oldcmap);
|
||||
newcmap->refcnt++;
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
__glutCurrentWindow->colormap = newcmap;
|
||||
__glutCurrentWindow->cmap = newcmap->cmap;
|
||||
} else {
|
||||
__glutCurrentWindow->overlay->colormap = newcmap;
|
||||
__glutCurrentWindow->overlay->cmap = newcmap->cmap;
|
||||
}
|
||||
XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin,
|
||||
newcmap->cmap);
|
||||
#if !defined(_WIN32) && !defined(__OS2PM__)
|
||||
__glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
|
||||
bla bla bla
|
||||
|
||||
} else {
|
||||
GLUTcolormap *copycmap;
|
||||
XColor color;
|
||||
int i, last;
|
||||
|
||||
/* Visuals different - need a distinct X colormap! */
|
||||
copycmap = __glutAssociateNewColormap(dstvis);
|
||||
/* Wouldn't it be nice if XCopyColormapAndFree could be
|
||||
told not to free the old colormap's entries! */
|
||||
last = newcmap->size;
|
||||
if (last > copycmap->size) {
|
||||
last = copycmap->size;
|
||||
}
|
||||
for (i = last - 1; i >= 0; i--) {
|
||||
if (newcmap->cells[i].component[GLUT_RED] >= 0.0) {
|
||||
color.pixel = i;
|
||||
copycmap->cells[i].component[GLUT_RED] =
|
||||
newcmap->cells[i].component[GLUT_RED];
|
||||
color.red = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_RED];
|
||||
copycmap->cells[i].component[GLUT_GREEN] =
|
||||
newcmap->cells[i].component[GLUT_GREEN];
|
||||
color.green = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_GREEN];
|
||||
copycmap->cells[i].component[GLUT_BLUE] =
|
||||
newcmap->cells[i].component[GLUT_BLUE];
|
||||
color.blue = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_BLUE];
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
XStoreColor(__glutDisplay, copycmap->cmap, &color);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "glutint.h"
|
||||
|
||||
#if defined(__OS2PM__)
|
||||
#define IsWindowVisible WinIsWindowVisible
|
||||
#endif
|
||||
|
||||
#define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i)))
|
||||
|
||||
/* CENTRY */
|
||||
void GLUTAPIENTRY
|
||||
glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)
|
||||
{
|
||||
GLUTcolormap *cmap, *newcmap;
|
||||
XVisualInfo *vis;
|
||||
XColor color;
|
||||
int i;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
cmap = __glutCurrentWindow->colormap;
|
||||
vis = __glutCurrentWindow->vis;
|
||||
} else {
|
||||
cmap = __glutCurrentWindow->overlay->colormap;
|
||||
vis = __glutCurrentWindow->overlay->vis;
|
||||
if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
|
||||
__glutWarning(
|
||||
"glutSetColor: cannot set color of overlay transparent index %d\n",
|
||||
ndx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmap) {
|
||||
__glutWarning("glutSetColor: current window is RGBA");
|
||||
return;
|
||||
}
|
||||
#if defined(_WIN32) || defined(__OS2PM__)
|
||||
if (ndx >= 256 || /* always assume 256 colors on Win32 */
|
||||
#else
|
||||
if (ndx >= vis->visual->map_entries ||
|
||||
#endif
|
||||
ndx < 0) {
|
||||
__glutWarning("glutSetColor: index %d out of range", ndx);
|
||||
return;
|
||||
}
|
||||
if (cmap->refcnt > 1) {
|
||||
newcmap = __glutAssociateNewColormap(vis);
|
||||
cmap->refcnt--;
|
||||
/* Wouldn't it be nice if XCopyColormapAndFree could be
|
||||
told not to free the old colormap's entries! */
|
||||
for (i = cmap->size - 1; i >= 0; i--) {
|
||||
if (i == ndx) {
|
||||
/* We are going to set this cell shortly! */
|
||||
continue;
|
||||
}
|
||||
if (cmap->cells[i].component[GLUT_RED] >= 0.0) {
|
||||
color.pixel = i;
|
||||
newcmap->cells[i].component[GLUT_RED] =
|
||||
cmap->cells[i].component[GLUT_RED];
|
||||
color.red = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_RED];
|
||||
newcmap->cells[i].component[GLUT_GREEN] =
|
||||
cmap->cells[i].component[GLUT_GREEN];
|
||||
color.green = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_GREEN];
|
||||
newcmap->cells[i].component[GLUT_BLUE] =
|
||||
cmap->cells[i].component[GLUT_BLUE];
|
||||
color.blue = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_BLUE];
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
#if defined(_WIN32) || defined(__OS2PM__)
|
||||
if (IsWindowVisible(__glutCurrentWindow->win)) {
|
||||
XHDC = __glutCurrentWindow->hdc;
|
||||
} else {
|
||||
XHDC = 0;
|
||||
}
|
||||
#endif
|
||||
XStoreColor(__glutDisplay, newcmap->cmap, &color);
|
||||
} else {
|
||||
/* Leave unallocated entries unallocated. */
|
||||
}
|
||||
}
|
||||
cmap = newcmap;
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
__glutCurrentWindow->colormap = cmap;
|
||||
__glutCurrentWindow->cmap = cmap->cmap;
|
||||
} else {
|
||||
__glutCurrentWindow->overlay->colormap = cmap;
|
||||
__glutCurrentWindow->overlay->cmap = cmap->cmap;
|
||||
}
|
||||
XSetWindowColormap(__glutDisplay,
|
||||
__glutCurrentWindow->renderWin, cmap->cmap);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__OS2PM__)
|
||||
{
|
||||
GLUTwindow *toplevel;
|
||||
|
||||
toplevel = __glutToplevelOf(__glutCurrentWindow);
|
||||
if (toplevel->cmap != cmap->cmap) {
|
||||
__glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
color.pixel = ndx;
|
||||
red = CLAMP(red);
|
||||
cmap->cells[ndx].component[GLUT_RED] = red;
|
||||
color.red = (GLfloat) 0xffff *red;
|
||||
green = CLAMP(green);
|
||||
cmap->cells[ndx].component[GLUT_GREEN] = green;
|
||||
color.green = (GLfloat) 0xffff *green;
|
||||
blue = CLAMP(blue);
|
||||
cmap->cells[ndx].component[GLUT_BLUE] = blue;
|
||||
color.blue = (GLfloat) 0xffff *blue;
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
#if defined(_WIN32) || defined(__OS2PM__)
|
||||
if (IsWindowVisible(__glutCurrentWindow->win)) {
|
||||
XHDC = __glutCurrentWindow->hdc;
|
||||
} else {
|
||||
XHDC = 0;
|
||||
}
|
||||
#endif
|
||||
XStoreColor(__glutDisplay, cmap->cmap, &color);
|
||||
}
|
||||
|
||||
GLfloat GLUTAPIENTRY
|
||||
glutGetColor(int ndx, int comp)
|
||||
{
|
||||
GLUTcolormap *colormap;
|
||||
XVisualInfo *vis;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
colormap = __glutCurrentWindow->colormap;
|
||||
vis = __glutCurrentWindow->vis;
|
||||
} else {
|
||||
colormap = __glutCurrentWindow->overlay->colormap;
|
||||
vis = __glutCurrentWindow->overlay->vis;
|
||||
if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
|
||||
__glutWarning("glutGetColor: requesting overlay transparent index %d\n",
|
||||
ndx);
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!colormap) {
|
||||
__glutWarning("glutGetColor: current window is RGBA");
|
||||
return -1.0;
|
||||
}
|
||||
#if defined(_WIN32) || defined(__OS2PM__)
|
||||
#define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0)
|
||||
#else
|
||||
#define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0)
|
||||
#endif
|
||||
if (OUT_OF_RANGE_NDX(ndx)) {
|
||||
__glutWarning("glutGetColor: index %d out of range", ndx);
|
||||
return -1.0;
|
||||
}
|
||||
return colormap->cells[ndx].component[comp];
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutCopyColormap(int winnum)
|
||||
{
|
||||
GLUTwindow *window = __glutWindowList[winnum - 1];
|
||||
GLUTcolormap *oldcmap, *newcmap;
|
||||
XVisualInfo *dstvis;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
oldcmap = __glutCurrentWindow->colormap;
|
||||
dstvis = __glutCurrentWindow->vis;
|
||||
newcmap = window->colormap;
|
||||
} else {
|
||||
oldcmap = __glutCurrentWindow->overlay->colormap;
|
||||
dstvis = __glutCurrentWindow->overlay->vis;
|
||||
if (!window->overlay) {
|
||||
__glutWarning("glutCopyColormap: window %d has no overlay", winnum);
|
||||
return;
|
||||
}
|
||||
newcmap = window->overlay->colormap;
|
||||
}
|
||||
|
||||
if (!oldcmap) {
|
||||
__glutWarning("glutCopyColormap: destination colormap must be color index");
|
||||
return;
|
||||
}
|
||||
if (!newcmap) {
|
||||
__glutWarning(
|
||||
"glutCopyColormap: source colormap of window %d must be color index",
|
||||
winnum);
|
||||
return;
|
||||
}
|
||||
if (newcmap == oldcmap) {
|
||||
/* Source and destination are the same; now copy needed. */
|
||||
return;
|
||||
}
|
||||
#if !defined(_WIN32) && !defined(__OS2PM__)
|
||||
/* Play safe: compare visual IDs, not Visual*'s. */
|
||||
if (newcmap->visual->visualid == oldcmap->visual->visualid) {
|
||||
#endif
|
||||
/* Visuals match! "Copy" by reference... */
|
||||
__glutFreeColormap(oldcmap);
|
||||
newcmap->refcnt++;
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
__glutCurrentWindow->colormap = newcmap;
|
||||
__glutCurrentWindow->cmap = newcmap->cmap;
|
||||
} else {
|
||||
__glutCurrentWindow->overlay->colormap = newcmap;
|
||||
__glutCurrentWindow->overlay->cmap = newcmap->cmap;
|
||||
}
|
||||
XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin,
|
||||
newcmap->cmap);
|
||||
#if !defined(_WIN32) && !defined(__OS2PM__)
|
||||
__glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
|
||||
bla bla bla
|
||||
|
||||
} else {
|
||||
GLUTcolormap *copycmap;
|
||||
XColor color;
|
||||
int i, last;
|
||||
|
||||
/* Visuals different - need a distinct X colormap! */
|
||||
copycmap = __glutAssociateNewColormap(dstvis);
|
||||
/* Wouldn't it be nice if XCopyColormapAndFree could be
|
||||
told not to free the old colormap's entries! */
|
||||
last = newcmap->size;
|
||||
if (last > copycmap->size) {
|
||||
last = copycmap->size;
|
||||
}
|
||||
for (i = last - 1; i >= 0; i--) {
|
||||
if (newcmap->cells[i].component[GLUT_RED] >= 0.0) {
|
||||
color.pixel = i;
|
||||
copycmap->cells[i].component[GLUT_RED] =
|
||||
newcmap->cells[i].component[GLUT_RED];
|
||||
color.red = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_RED];
|
||||
copycmap->cells[i].component[GLUT_GREEN] =
|
||||
newcmap->cells[i].component[GLUT_GREEN];
|
||||
color.green = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_GREEN];
|
||||
copycmap->cells[i].component[GLUT_BLUE] =
|
||||
newcmap->cells[i].component[GLUT_BLUE];
|
||||
color.blue = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_BLUE];
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
XStoreColor(__glutDisplay, copycmap->cmap, &color);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
|
||||
+679
-679
File diff suppressed because it is too large
Load Diff
+1220
-1220
File diff suppressed because it is too large
Load Diff
+126
-126
@@ -1,127 +1,127 @@
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void GLUTAPIENTRY
|
||||
glutSetWindowTitle(const char *title)
|
||||
{
|
||||
#if defined(__OS2PM__)
|
||||
__glutSetWindowText(__glutCurrentWindow->win, (char *)title);
|
||||
|
||||
#else
|
||||
XTextProperty textprop;
|
||||
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
IGNORE_IN_GAME_MODE();
|
||||
textprop.value = (unsigned char *) title;
|
||||
textprop.encoding = XA_STRING;
|
||||
textprop.format = 8;
|
||||
textprop.nitems = strlen(title);
|
||||
XSetWMName(__glutDisplay,
|
||||
__glutCurrentWindow->win, &textprop);
|
||||
XFlush(__glutDisplay);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutSetIconTitle(const char *title)
|
||||
{
|
||||
#if defined(__OS2PM__)
|
||||
//todo ?
|
||||
#else
|
||||
|
||||
XTextProperty textprop;
|
||||
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
IGNORE_IN_GAME_MODE();
|
||||
textprop.value = (unsigned char *) title;
|
||||
textprop.encoding = XA_STRING;
|
||||
textprop.format = 8;
|
||||
textprop.nitems = strlen(title);
|
||||
XSetWMIconName(__glutDisplay,
|
||||
__glutCurrentWindow->win, &textprop);
|
||||
XFlush(__glutDisplay);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutPositionWindow(int x, int y)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredX = x;
|
||||
__glutCurrentWindow->desiredY = y;
|
||||
__glutCurrentWindow->desiredConfMask |= CWX | CWY;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutReshapeWindow(int w, int h)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
if (w <= 0 || h <= 0)
|
||||
__glutWarning("glutReshapeWindow: non-positive width or height not allowed");
|
||||
|
||||
__glutCurrentWindow->desiredWidth = w;
|
||||
__glutCurrentWindow->desiredHeight = h;
|
||||
__glutCurrentWindow->desiredConfMask |= CWWidth | CWHeight;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutPopWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredStack = Above;
|
||||
__glutCurrentWindow->desiredConfMask |= CWStackMode;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutPushWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredStack = Below;
|
||||
__glutCurrentWindow->desiredConfMask |= CWStackMode;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutIconifyWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
__glutCurrentWindow->desiredMapState = IconicState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutShowWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredMapState = NormalState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutHideWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredMapState = WithdrawnState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void GLUTAPIENTRY
|
||||
glutSetWindowTitle(const char *title)
|
||||
{
|
||||
#if defined(__OS2PM__)
|
||||
__glutSetWindowText(__glutCurrentWindow->win, (char *)title);
|
||||
|
||||
#else
|
||||
XTextProperty textprop;
|
||||
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
IGNORE_IN_GAME_MODE();
|
||||
textprop.value = (unsigned char *) title;
|
||||
textprop.encoding = XA_STRING;
|
||||
textprop.format = 8;
|
||||
textprop.nitems = strlen(title);
|
||||
XSetWMName(__glutDisplay,
|
||||
__glutCurrentWindow->win, &textprop);
|
||||
XFlush(__glutDisplay);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutSetIconTitle(const char *title)
|
||||
{
|
||||
#if defined(__OS2PM__)
|
||||
//todo ?
|
||||
#else
|
||||
|
||||
XTextProperty textprop;
|
||||
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
IGNORE_IN_GAME_MODE();
|
||||
textprop.value = (unsigned char *) title;
|
||||
textprop.encoding = XA_STRING;
|
||||
textprop.format = 8;
|
||||
textprop.nitems = strlen(title);
|
||||
XSetWMIconName(__glutDisplay,
|
||||
__glutCurrentWindow->win, &textprop);
|
||||
XFlush(__glutDisplay);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutPositionWindow(int x, int y)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredX = x;
|
||||
__glutCurrentWindow->desiredY = y;
|
||||
__glutCurrentWindow->desiredConfMask |= CWX | CWY;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutReshapeWindow(int w, int h)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
if (w <= 0 || h <= 0)
|
||||
__glutWarning("glutReshapeWindow: non-positive width or height not allowed");
|
||||
|
||||
__glutCurrentWindow->desiredWidth = w;
|
||||
__glutCurrentWindow->desiredHeight = h;
|
||||
__glutCurrentWindow->desiredConfMask |= CWWidth | CWHeight;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutPopWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredStack = Above;
|
||||
__glutCurrentWindow->desiredConfMask |= CWStackMode;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutPushWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredStack = Below;
|
||||
__glutCurrentWindow->desiredConfMask |= CWStackMode;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutIconifyWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
__glutCurrentWindow->desiredMapState = IconicState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutShowWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredMapState = NormalState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
void GLUTAPIENTRY
|
||||
glutHideWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredMapState = WithdrawnState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
|
||||
+145
-145
@@ -1,146 +1,146 @@
|
||||
/* os2_glx.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "gl/gl.h"
|
||||
#include "WarpGL.h"
|
||||
#include "GL/os2mesa.h"
|
||||
|
||||
#define POKA 0
|
||||
/* global current HDC */
|
||||
|
||||
XVisualInfo *wglDescribePixelFormat(int iPixelFormat);
|
||||
|
||||
extern HDC XHDC;
|
||||
extern HWND XHWND;
|
||||
//extern HPS hpsCurrent;
|
||||
extern HAB hab; /* PM anchor block handle */
|
||||
|
||||
GLXContext
|
||||
glXCreateContext(HPS hps, XVisualInfo * visinfo,
|
||||
GLXContext share, Bool direct)
|
||||
{
|
||||
/* KLUDGE: GLX really expects a display pointer to be passed
|
||||
in as the first parameter, but Win32 needs an HDC instead,
|
||||
so BE SURE that the global XHDC is set before calling this
|
||||
routine. */
|
||||
HGLRC context;
|
||||
|
||||
context = wglCreateContext(XHDC,hps,hab);
|
||||
|
||||
|
||||
/* Since direct rendering is implicit, the direct flag is
|
||||
ignored. */
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glXGetConfig(XVisualInfo * visual, int attrib, int *value)
|
||||
{
|
||||
if (!visual)
|
||||
return GLX_BAD_VISUAL;
|
||||
|
||||
switch (attrib) {
|
||||
case GLX_USE_GL:
|
||||
if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) {
|
||||
/* XXX Brad's Matrix Millenium II has problems creating
|
||||
color index windows in 24-bit mode (lead to GDI crash)
|
||||
and 32-bit mode (lead to black window). The cColorBits
|
||||
filed of the PIXELFORMATDESCRIPTOR returned claims to
|
||||
have 24 and 32 bits respectively of color indices. 2^24
|
||||
and 2^32 are ridiculously huge writable colormaps.
|
||||
Assume that if we get back a color index
|
||||
PIXELFORMATDESCRIPTOR with 24 or more bits, the
|
||||
PIXELFORMATDESCRIPTOR doesn't really work and skip it.
|
||||
-mjk */
|
||||
if (visual->iPixelType == PFD_TYPE_COLORINDEX
|
||||
&& visual->cColorBits >= 24) {
|
||||
*value = 0;
|
||||
} else {
|
||||
*value = 1;
|
||||
}
|
||||
} else {
|
||||
*value = 0;
|
||||
}
|
||||
break;
|
||||
case GLX_BUFFER_SIZE:
|
||||
/* KLUDGE: if we're RGBA, return the number of bits/pixel,
|
||||
otherwise, return 8 (we guessed at 256 colors in CI
|
||||
mode). */
|
||||
if (visual->iPixelType == PFD_TYPE_RGBA)
|
||||
*value = visual->cColorBits;
|
||||
else
|
||||
*value = 8;
|
||||
break;
|
||||
case GLX_LEVEL:
|
||||
/* The bReserved flag of the pfd contains the
|
||||
overlay/underlay info. */
|
||||
*value = visual->bReserved;
|
||||
break;
|
||||
case GLX_RGBA:
|
||||
*value = visual->iPixelType == PFD_TYPE_RGBA;
|
||||
break;
|
||||
case GLX_DOUBLEBUFFER:
|
||||
*value = visual->dwFlags & PFD_DOUBLEBUFFER;
|
||||
break;
|
||||
case GLX_STEREO:
|
||||
*value = visual->dwFlags & PFD_STEREO;
|
||||
break;
|
||||
case GLX_AUX_BUFFERS:
|
||||
*value = visual->cAuxBuffers;
|
||||
break;
|
||||
case GLX_RED_SIZE:
|
||||
*value = visual->cRedBits;
|
||||
break;
|
||||
case GLX_GREEN_SIZE:
|
||||
*value = visual->cGreenBits;
|
||||
break;
|
||||
case GLX_BLUE_SIZE:
|
||||
*value = visual->cBlueBits;
|
||||
break;
|
||||
case GLX_ALPHA_SIZE:
|
||||
*value = visual->cAlphaBits;
|
||||
break;
|
||||
case GLX_DEPTH_SIZE:
|
||||
*value = visual->cDepthBits;
|
||||
break;
|
||||
case GLX_STENCIL_SIZE:
|
||||
*value = visual->cStencilBits;
|
||||
break;
|
||||
case GLX_ACCUM_RED_SIZE:
|
||||
*value = visual->cAccumRedBits;
|
||||
break;
|
||||
case GLX_ACCUM_GREEN_SIZE:
|
||||
*value = visual->cAccumGreenBits;
|
||||
break;
|
||||
case GLX_ACCUM_BLUE_SIZE:
|
||||
*value = visual->cAccumBlueBits;
|
||||
break;
|
||||
case GLX_ACCUM_ALPHA_SIZE:
|
||||
*value = visual->cAccumAlphaBits;
|
||||
break;
|
||||
#if POKA == 100
|
||||
#endif /* POKA == 100 */
|
||||
default:
|
||||
return GLX_BAD_ATTRIB;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
XVisualInfo * glXChooseVisual(int mode)
|
||||
{ int imode = 2;
|
||||
if(mode & GLUT_DOUBLE)
|
||||
imode = 1;
|
||||
return
|
||||
wglDescribePixelFormat(imode);
|
||||
}
|
||||
|
||||
|
||||
#if POKA
|
||||
#endif /* POKA */
|
||||
|
||||
/* os2_glx.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "gl/gl.h"
|
||||
#include "WarpGL.h"
|
||||
#include "GL/os2mesa.h"
|
||||
|
||||
#define POKA 0
|
||||
/* global current HDC */
|
||||
|
||||
XVisualInfo *wglDescribePixelFormat(int iPixelFormat);
|
||||
|
||||
extern HDC XHDC;
|
||||
extern HWND XHWND;
|
||||
//extern HPS hpsCurrent;
|
||||
extern HAB hab; /* PM anchor block handle */
|
||||
|
||||
GLXContext
|
||||
glXCreateContext(HPS hps, XVisualInfo * visinfo,
|
||||
GLXContext share, Bool direct)
|
||||
{
|
||||
/* KLUDGE: GLX really expects a display pointer to be passed
|
||||
in as the first parameter, but Win32 needs an HDC instead,
|
||||
so BE SURE that the global XHDC is set before calling this
|
||||
routine. */
|
||||
HGLRC context;
|
||||
|
||||
context = wglCreateContext(XHDC,hps,hab);
|
||||
|
||||
|
||||
/* Since direct rendering is implicit, the direct flag is
|
||||
ignored. */
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glXGetConfig(XVisualInfo * visual, int attrib, int *value)
|
||||
{
|
||||
if (!visual)
|
||||
return GLX_BAD_VISUAL;
|
||||
|
||||
switch (attrib) {
|
||||
case GLX_USE_GL:
|
||||
if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) {
|
||||
/* XXX Brad's Matrix Millenium II has problems creating
|
||||
color index windows in 24-bit mode (lead to GDI crash)
|
||||
and 32-bit mode (lead to black window). The cColorBits
|
||||
filed of the PIXELFORMATDESCRIPTOR returned claims to
|
||||
have 24 and 32 bits respectively of color indices. 2^24
|
||||
and 2^32 are ridiculously huge writable colormaps.
|
||||
Assume that if we get back a color index
|
||||
PIXELFORMATDESCRIPTOR with 24 or more bits, the
|
||||
PIXELFORMATDESCRIPTOR doesn't really work and skip it.
|
||||
-mjk */
|
||||
if (visual->iPixelType == PFD_TYPE_COLORINDEX
|
||||
&& visual->cColorBits >= 24) {
|
||||
*value = 0;
|
||||
} else {
|
||||
*value = 1;
|
||||
}
|
||||
} else {
|
||||
*value = 0;
|
||||
}
|
||||
break;
|
||||
case GLX_BUFFER_SIZE:
|
||||
/* KLUDGE: if we're RGBA, return the number of bits/pixel,
|
||||
otherwise, return 8 (we guessed at 256 colors in CI
|
||||
mode). */
|
||||
if (visual->iPixelType == PFD_TYPE_RGBA)
|
||||
*value = visual->cColorBits;
|
||||
else
|
||||
*value = 8;
|
||||
break;
|
||||
case GLX_LEVEL:
|
||||
/* The bReserved flag of the pfd contains the
|
||||
overlay/underlay info. */
|
||||
*value = visual->bReserved;
|
||||
break;
|
||||
case GLX_RGBA:
|
||||
*value = visual->iPixelType == PFD_TYPE_RGBA;
|
||||
break;
|
||||
case GLX_DOUBLEBUFFER:
|
||||
*value = visual->dwFlags & PFD_DOUBLEBUFFER;
|
||||
break;
|
||||
case GLX_STEREO:
|
||||
*value = visual->dwFlags & PFD_STEREO;
|
||||
break;
|
||||
case GLX_AUX_BUFFERS:
|
||||
*value = visual->cAuxBuffers;
|
||||
break;
|
||||
case GLX_RED_SIZE:
|
||||
*value = visual->cRedBits;
|
||||
break;
|
||||
case GLX_GREEN_SIZE:
|
||||
*value = visual->cGreenBits;
|
||||
break;
|
||||
case GLX_BLUE_SIZE:
|
||||
*value = visual->cBlueBits;
|
||||
break;
|
||||
case GLX_ALPHA_SIZE:
|
||||
*value = visual->cAlphaBits;
|
||||
break;
|
||||
case GLX_DEPTH_SIZE:
|
||||
*value = visual->cDepthBits;
|
||||
break;
|
||||
case GLX_STENCIL_SIZE:
|
||||
*value = visual->cStencilBits;
|
||||
break;
|
||||
case GLX_ACCUM_RED_SIZE:
|
||||
*value = visual->cAccumRedBits;
|
||||
break;
|
||||
case GLX_ACCUM_GREEN_SIZE:
|
||||
*value = visual->cAccumGreenBits;
|
||||
break;
|
||||
case GLX_ACCUM_BLUE_SIZE:
|
||||
*value = visual->cAccumBlueBits;
|
||||
break;
|
||||
case GLX_ACCUM_ALPHA_SIZE:
|
||||
*value = visual->cAccumAlphaBits;
|
||||
break;
|
||||
#if POKA == 100
|
||||
#endif /* POKA == 100 */
|
||||
default:
|
||||
return GLX_BAD_ATTRIB;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
XVisualInfo * glXChooseVisual(int mode)
|
||||
{ int imode = 2;
|
||||
if(mode & GLUT_DOUBLE)
|
||||
imode = 1;
|
||||
return
|
||||
wglDescribePixelFormat(imode);
|
||||
}
|
||||
|
||||
|
||||
#if POKA
|
||||
#endif /* POKA */
|
||||
|
||||
|
||||
+532
-532
File diff suppressed because it is too large
Load Diff
+1296
-1296
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,8 @@ SOURCES = \
|
||||
xfont.c \
|
||||
glx_pbuffer.c \
|
||||
glx_query.c \
|
||||
drisw_glx.c \
|
||||
dri_common.c \
|
||||
dri_glx.c \
|
||||
XF86dri.c \
|
||||
glxhash.c \
|
||||
|
||||
+1
-97
@@ -32,7 +32,6 @@
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
@@ -46,18 +45,10 @@
|
||||
#include <sys/mman.h>
|
||||
#include "xf86drm.h"
|
||||
#include "dri2.h"
|
||||
|
||||
|
||||
#ifndef RTLD_NOW
|
||||
#define RTLD_NOW 0
|
||||
#endif
|
||||
#ifndef RTLD_GLOBAL
|
||||
#define RTLD_GLOBAL 0
|
||||
#endif
|
||||
#include "dri_common.h"
|
||||
|
||||
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
|
||||
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
|
||||
typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate;
|
||||
|
||||
struct __GLXDRIdisplayPrivateRec {
|
||||
__GLXDRIdisplay base;
|
||||
@@ -76,11 +67,6 @@ struct __GLXDRIcontextPrivateRec {
|
||||
__GLXscreenConfigs *psc;
|
||||
};
|
||||
|
||||
struct __GLXDRIconfigPrivateRec {
|
||||
__GLcontextModes modes;
|
||||
const __DRIconfig *driConfig;
|
||||
};
|
||||
|
||||
static void dri2DestroyContext(__GLXDRIcontext *context,
|
||||
__GLXscreenConfigs *psc, Display *dpy)
|
||||
{
|
||||
@@ -253,94 +239,12 @@ static const __DRIloaderExtension dri2LoaderExtension = {
|
||||
dri2PostDamage
|
||||
};
|
||||
|
||||
_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension;
|
||||
|
||||
static const __DRIextension *loader_extensions[] = {
|
||||
&dri2LoaderExtension.base,
|
||||
&systemTimeExtension.base,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* We need a dri_common.h type-of-thing. */
|
||||
|
||||
extern void ErrorMessageF(const char *f, ...);
|
||||
|
||||
extern void *driOpenDriver(const char *driverName);
|
||||
|
||||
extern __GLcontextModes *
|
||||
driConvertConfigs(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig **configs);
|
||||
|
||||
extern void driBindExtensions(__GLXscreenConfigs *psc);
|
||||
|
||||
void
|
||||
driBindExtensions(__GLXscreenConfigs *psc)
|
||||
{
|
||||
const __DRIextension **extensions;
|
||||
int i;
|
||||
|
||||
extensions = psc->core->getExtensions(psc->__driScreen);
|
||||
|
||||
for (i = 0; extensions[i]; i++) {
|
||||
#ifdef __DRI_COPY_SUB_BUFFER
|
||||
if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
|
||||
psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer_bit");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_SWAP_CONTROL
|
||||
if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
|
||||
psc->swapControl = (__DRIswapControlExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
|
||||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_ALLOCATE
|
||||
if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
|
||||
psc->allocate = (__DRIallocateExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_FRAME_TRACKING
|
||||
if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
|
||||
psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_MEDIA_STREAM_COUNTER
|
||||
if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
|
||||
psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_SWAP_BUFFER_COUNTER
|
||||
/* No driver supports this at this time and the extension is
|
||||
* not defined in dri_interface.h. Will enable
|
||||
* GLX_OML_sync_control if implemented. */
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_READ_DRAWABLE
|
||||
if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
|
||||
__glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_TEX_BUFFER
|
||||
if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
|
||||
psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Ignore unknown extensions */
|
||||
}
|
||||
}
|
||||
|
||||
static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
|
||||
__GLXdisplayPrivate *priv)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Soft-
|
||||
* ware"), to deal in the Software without restriction, including without
|
||||
* limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, provided that the above copyright
|
||||
* notice(s) and this permission notice appear in all copies of the Soft-
|
||||
* ware and that both the above copyright notice(s) and this permission
|
||||
* notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
|
||||
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
|
||||
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
|
||||
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
|
||||
* QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
|
||||
* MANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of a copyright holder shall
|
||||
* not be used in advertising or otherwise to promote the sale, use or
|
||||
* other dealings in this Software without prior written authorization of
|
||||
* the copyright holder.
|
||||
*
|
||||
* Authors:
|
||||
* Kevin E. Martin <kevin@precisioninsight.com>
|
||||
* Brian Paul <brian@precisioninsight.com>
|
||||
* Kristian Høgsberg (krh@redhat.com)
|
||||
*/
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include "glheader.h"
|
||||
#include "glxclient.h"
|
||||
#include "glcontextmodes.h"
|
||||
#include "dri_common.h"
|
||||
|
||||
#ifndef RTLD_NOW
|
||||
#define RTLD_NOW 0
|
||||
#endif
|
||||
#ifndef RTLD_GLOBAL
|
||||
#define RTLD_GLOBAL 0
|
||||
#endif
|
||||
|
||||
_X_HIDDEN void InfoMessageF(const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
const char *env;
|
||||
|
||||
if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
|
||||
fprintf(stderr, "libGL: ");
|
||||
va_start(args, f);
|
||||
vfprintf(stderr, f, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print error to stderr, unless LIBGL_DEBUG=="quiet".
|
||||
*/
|
||||
_X_HIDDEN void ErrorMessageF(const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
const char *env;
|
||||
|
||||
if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) {
|
||||
fprintf(stderr, "libGL error: ");
|
||||
va_start(args, f);
|
||||
vfprintf(stderr, f, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DEFAULT_DRIVER_DIR
|
||||
/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */
|
||||
#define DEFAULT_DRIVER_DIR "/usr/local/lib/dri"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Try to \c dlopen the named driver.
|
||||
*
|
||||
* This function adds the "_dri.so" suffix to the driver name and searches the
|
||||
* directories specified by the \c LIBGL_DRIVERS_PATH environment variable in
|
||||
* order to find the driver.
|
||||
*
|
||||
* \param driverName - a name like "tdfx", "i810", "mga", etc.
|
||||
*
|
||||
* \returns
|
||||
* A handle from \c dlopen, or \c NULL if driver file not found.
|
||||
*/
|
||||
_X_HIDDEN void *driOpenDriver(const char *driverName)
|
||||
{
|
||||
void *glhandle, *handle;
|
||||
const char *libPaths, *p, *next;
|
||||
char realDriverName[200];
|
||||
int len;
|
||||
|
||||
/* Attempt to make sure libGL symbols will be visible to the driver */
|
||||
glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
|
||||
|
||||
libPaths = NULL;
|
||||
if (geteuid() == getuid()) {
|
||||
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
|
||||
libPaths = getenv("LIBGL_DRIVERS_PATH");
|
||||
if (!libPaths)
|
||||
libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
|
||||
}
|
||||
if (libPaths == NULL)
|
||||
libPaths = DEFAULT_DRIVER_DIR;
|
||||
|
||||
handle = NULL;
|
||||
for (p = libPaths; *p; p = next) {
|
||||
next = strchr(p, ':');
|
||||
if (next == NULL) {
|
||||
len = strlen(p);
|
||||
next = p + len;
|
||||
} else {
|
||||
len = next - p;
|
||||
next++;
|
||||
}
|
||||
|
||||
#ifdef GLX_USE_TLS
|
||||
snprintf(realDriverName, sizeof realDriverName,
|
||||
"%.*s/tls/%s_dri.so", len, p, driverName);
|
||||
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
|
||||
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
|
||||
#endif
|
||||
|
||||
if ( handle == NULL ) {
|
||||
snprintf(realDriverName, sizeof realDriverName,
|
||||
"%.*s/%s_dri.so", len, p, driverName);
|
||||
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
|
||||
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
|
||||
}
|
||||
|
||||
if ( handle != NULL )
|
||||
break;
|
||||
else
|
||||
ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
|
||||
}
|
||||
|
||||
if (!handle)
|
||||
ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);
|
||||
|
||||
if (glhandle)
|
||||
dlclose(glhandle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = {
|
||||
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
|
||||
__glXGetUST,
|
||||
__driGetMscRateOML
|
||||
};
|
||||
|
||||
#define __ATTRIB(attrib, field) \
|
||||
{ attrib, offsetof(__GLcontextModes, field) }
|
||||
|
||||
static const struct { unsigned int attrib, offset; } attribMap[] = {
|
||||
__ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
|
||||
__ATTRIB(__DRI_ATTRIB_LEVEL, level),
|
||||
__ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
|
||||
__ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
|
||||
__ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
|
||||
__ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
|
||||
__ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
|
||||
__ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
|
||||
__ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
|
||||
__ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
|
||||
__ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
|
||||
__ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
|
||||
#if 0
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentIndex),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
|
||||
__ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
|
||||
__ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
|
||||
__ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
|
||||
__ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
|
||||
#endif
|
||||
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
|
||||
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
|
||||
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
|
||||
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
|
||||
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
|
||||
#if 0
|
||||
__ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
|
||||
#endif
|
||||
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
|
||||
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
|
||||
__ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
|
||||
__ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
|
||||
static int
|
||||
scalarEqual(__GLcontextModes *mode, unsigned int attrib, unsigned int value)
|
||||
{
|
||||
unsigned int glxValue;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(attribMap); i++)
|
||||
if (attribMap[i].attrib == attrib) {
|
||||
glxValue = *(unsigned int *) ((char *) mode + attribMap[i].offset);
|
||||
return glxValue == GLX_DONT_CARE || glxValue == value;
|
||||
}
|
||||
|
||||
return GL_TRUE; /* Is a non-existing attribute equal to value? */
|
||||
}
|
||||
|
||||
static int
|
||||
driConfigEqual(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig *driConfig)
|
||||
{
|
||||
unsigned int attrib, value, glxValue;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
|
||||
switch (attrib) {
|
||||
case __DRI_ATTRIB_RENDER_TYPE:
|
||||
glxValue = 0;
|
||||
if (value & __DRI_ATTRIB_RGBA_BIT) {
|
||||
glxValue |= GLX_RGBA_BIT;
|
||||
} else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
|
||||
glxValue |= GLX_COLOR_INDEX_BIT;
|
||||
}
|
||||
if (glxValue != modes->renderType)
|
||||
return GL_FALSE;
|
||||
break;
|
||||
|
||||
case __DRI_ATTRIB_CONFIG_CAVEAT:
|
||||
if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
|
||||
glxValue = GLX_NON_CONFORMANT_CONFIG;
|
||||
else if (value & __DRI_ATTRIB_SLOW_BIT)
|
||||
glxValue = GLX_SLOW_CONFIG;
|
||||
else
|
||||
glxValue = GLX_NONE;
|
||||
if (glxValue != modes->visualRating)
|
||||
return GL_FALSE;
|
||||
break;
|
||||
|
||||
case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
|
||||
glxValue = 0;
|
||||
if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
|
||||
glxValue |= GLX_TEXTURE_1D_BIT_EXT;
|
||||
if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
|
||||
glxValue |= GLX_TEXTURE_2D_BIT_EXT;
|
||||
if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
|
||||
glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
|
||||
if (modes->bindToTextureTargets != GLX_DONT_CARE &&
|
||||
glxValue != modes->bindToTextureTargets)
|
||||
return GL_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!scalarEqual(modes, attrib, value))
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static __GLcontextModes *
|
||||
createDriMode(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig **driConfigs)
|
||||
{
|
||||
__GLXDRIconfigPrivate *config;
|
||||
int i;
|
||||
|
||||
for (i = 0; driConfigs[i]; i++) {
|
||||
if (driConfigEqual(core, modes, driConfigs[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (driConfigs[i] == NULL)
|
||||
return NULL;
|
||||
|
||||
config = Xmalloc(sizeof *config);
|
||||
if (config == NULL)
|
||||
return NULL;
|
||||
|
||||
config->modes = *modes;
|
||||
config->driConfig = driConfigs[i];
|
||||
|
||||
return &config->modes;
|
||||
}
|
||||
|
||||
_X_HIDDEN __GLcontextModes *
|
||||
driConvertConfigs(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig **configs)
|
||||
{
|
||||
__GLcontextModes head, *tail, *m;
|
||||
|
||||
tail = &head;
|
||||
head.next = NULL;
|
||||
for (m = modes; m; m = m->next) {
|
||||
tail->next = createDriMode(core, m, configs);
|
||||
if (tail->next == NULL) {
|
||||
/* no matching dri config for m */
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
tail = tail->next;
|
||||
}
|
||||
|
||||
_gl_context_modes_destroy(modes);
|
||||
|
||||
return head.next;
|
||||
}
|
||||
|
||||
_X_HIDDEN void
|
||||
driBindExtensions(__GLXscreenConfigs *psc)
|
||||
{
|
||||
const __DRIextension **extensions;
|
||||
int i;
|
||||
|
||||
extensions = psc->core->getExtensions(psc->__driScreen);
|
||||
|
||||
for (i = 0; extensions[i]; i++) {
|
||||
#ifdef __DRI_COPY_SUB_BUFFER
|
||||
if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
|
||||
psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer_bit");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_SWAP_CONTROL
|
||||
if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
|
||||
psc->swapControl = (__DRIswapControlExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
|
||||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_ALLOCATE
|
||||
if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
|
||||
psc->allocate = (__DRIallocateExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_FRAME_TRACKING
|
||||
if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
|
||||
psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_MEDIA_STREAM_COUNTER
|
||||
if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
|
||||
psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_SWAP_BUFFER_COUNTER
|
||||
/* No driver supports this at this time and the extension is
|
||||
* not defined in dri_interface.h. Will enable
|
||||
* GLX_OML_sync_control if implemented. */
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_READ_DRAWABLE
|
||||
if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
|
||||
__glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __DRI_TEX_BUFFER
|
||||
if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
|
||||
psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
|
||||
__glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Ignore unknown extensions */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GLX_DIRECT_RENDERING */
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Soft-
|
||||
* ware"), to deal in the Software without restriction, including without
|
||||
* limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, provided that the above copyright
|
||||
* notice(s) and this permission notice appear in all copies of the Soft-
|
||||
* ware and that both the above copyright notice(s) and this permission
|
||||
* notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
|
||||
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
|
||||
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
|
||||
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
|
||||
* QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
|
||||
* MANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of a copyright holder shall
|
||||
* not be used in advertising or otherwise to promote the sale, use or
|
||||
* other dealings in this Software without prior written authorization of
|
||||
* the copyright holder.
|
||||
*
|
||||
* Authors:
|
||||
* Kevin E. Martin <kevin@precisioninsight.com>
|
||||
* Brian Paul <brian@precisioninsight.com>
|
||||
* Kristian Høgsberg (krh@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef _DRI_COMMON_H
|
||||
#define _DRI_COMMON_H
|
||||
|
||||
typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate;
|
||||
|
||||
struct __GLXDRIconfigPrivateRec {
|
||||
__GLcontextModes modes;
|
||||
const __DRIconfig *driConfig;
|
||||
};
|
||||
|
||||
extern __GLcontextModes *
|
||||
driConvertConfigs(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig **configs);
|
||||
|
||||
extern const __DRIsystemTimeExtension systemTimeExtension;
|
||||
|
||||
extern void InfoMessageF(const char *f, ...);
|
||||
|
||||
extern void ErrorMessageF(const char *f, ...);
|
||||
|
||||
extern void *driOpenDriver(const char *driverName);
|
||||
|
||||
extern void driBindExtensions(__GLXscreenConfigs *psc);
|
||||
|
||||
#endif /* _DRI_COMMON_H */
|
||||
+182
-578
@@ -34,7 +34,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
@@ -47,17 +46,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include "xf86drm.h"
|
||||
|
||||
#ifndef RTLD_NOW
|
||||
#define RTLD_NOW 0
|
||||
#endif
|
||||
#ifndef RTLD_GLOBAL
|
||||
#define RTLD_GLOBAL 0
|
||||
#endif
|
||||
#include "dri_common.h"
|
||||
|
||||
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
|
||||
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
|
||||
typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate;
|
||||
|
||||
struct __GLXDRIdisplayPrivateRec {
|
||||
__GLXDRIdisplay base;
|
||||
@@ -77,128 +69,12 @@ struct __GLXDRIcontextPrivateRec {
|
||||
__GLXscreenConfigs *psc;
|
||||
};
|
||||
|
||||
struct __GLXDRIconfigPrivateRec {
|
||||
__GLcontextModes modes;
|
||||
const __DRIconfig *driConfig;
|
||||
};
|
||||
|
||||
#ifndef DEFAULT_DRIVER_DIR
|
||||
/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */
|
||||
#define DEFAULT_DRIVER_DIR "/usr/local/lib/dri"
|
||||
#endif
|
||||
|
||||
static void InfoMessageF(const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
const char *env;
|
||||
|
||||
if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
|
||||
fprintf(stderr, "libGL: ");
|
||||
va_start(args, f);
|
||||
vfprintf(stderr, f, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
extern void ErrorMessageF(const char *f, ...);
|
||||
|
||||
/**
|
||||
* Print error to stderr, unless LIBGL_DEBUG=="quiet".
|
||||
*/
|
||||
_X_HIDDEN void ErrorMessageF(const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
const char *env;
|
||||
|
||||
if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) {
|
||||
fprintf(stderr, "libGL error: ");
|
||||
va_start(args, f);
|
||||
vfprintf(stderr, f, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
extern void *driOpenDriver(const char *driverName);
|
||||
|
||||
/**
|
||||
* Try to \c dlopen the named driver.
|
||||
*
|
||||
* This function adds the "_dri.so" suffix to the driver name and searches the
|
||||
* directories specified by the \c LIBGL_DRIVERS_PATH environment variable in
|
||||
* order to find the driver.
|
||||
*
|
||||
* \param driverName - a name like "tdfx", "i810", "mga", etc.
|
||||
*
|
||||
* \returns
|
||||
* A handle from \c dlopen, or \c NULL if driver file not found.
|
||||
*/
|
||||
_X_HIDDEN void *driOpenDriver(const char *driverName)
|
||||
{
|
||||
void *glhandle, *handle;
|
||||
const char *libPaths, *p, *next;
|
||||
char realDriverName[200];
|
||||
int len;
|
||||
|
||||
/* Attempt to make sure libGL symbols will be visible to the driver */
|
||||
glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
|
||||
|
||||
libPaths = NULL;
|
||||
if (geteuid() == getuid()) {
|
||||
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
|
||||
libPaths = getenv("LIBGL_DRIVERS_PATH");
|
||||
if (!libPaths)
|
||||
libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
|
||||
}
|
||||
if (libPaths == NULL)
|
||||
libPaths = DEFAULT_DRIVER_DIR;
|
||||
|
||||
handle = NULL;
|
||||
for (p = libPaths; *p; p = next) {
|
||||
next = strchr(p, ':');
|
||||
if (next == NULL) {
|
||||
len = strlen(p);
|
||||
next = p + len;
|
||||
} else {
|
||||
len = next - p;
|
||||
next++;
|
||||
}
|
||||
|
||||
#ifdef GLX_USE_TLS
|
||||
snprintf(realDriverName, sizeof realDriverName,
|
||||
"%.*s/tls/%s_dri.so", len, p, driverName);
|
||||
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
|
||||
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
|
||||
#endif
|
||||
|
||||
if ( handle == NULL ) {
|
||||
snprintf(realDriverName, sizeof realDriverName,
|
||||
"%.*s/%s_dri.so", len, p, driverName);
|
||||
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
|
||||
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
|
||||
}
|
||||
|
||||
if ( handle != NULL )
|
||||
break;
|
||||
else
|
||||
ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
|
||||
}
|
||||
|
||||
if (!handle)
|
||||
ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);
|
||||
|
||||
if (glhandle)
|
||||
dlclose(glhandle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given a display pointer and screen number, determine the name of
|
||||
* the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
|
||||
* Return True for success, False for failure.
|
||||
*/
|
||||
static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)
|
||||
static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName)
|
||||
{
|
||||
int directCapable;
|
||||
Bool b;
|
||||
@@ -228,25 +104,6 @@ static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given a display pointer and screen number, return a __DRIdriver handle.
|
||||
* Return NULL if anything goes wrong.
|
||||
*/
|
||||
static void *driGetDriver(Display *dpy, int scrNum)
|
||||
{
|
||||
char *driverName;
|
||||
void *ret;
|
||||
|
||||
if (GetDriverName(dpy, scrNum, &driverName)) {
|
||||
ret = driOpenDriver(driverName);
|
||||
if (driverName)
|
||||
Xfree(driverName);
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exported function for querying the DRI driver for a given screen.
|
||||
*
|
||||
@@ -256,7 +113,7 @@ static void *driGetDriver(Display *dpy, int scrNum)
|
||||
PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
|
||||
static char ret[32];
|
||||
char *driverName;
|
||||
if (GetDriverName(dpy, scrNum, &driverName)) {
|
||||
if (driGetDriverName(dpy, scrNum, &driverName)) {
|
||||
int len;
|
||||
if (!driverName)
|
||||
return NULL;
|
||||
@@ -270,7 +127,6 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Exported function for obtaining a driver's option list (UTF-8 encoded XML).
|
||||
*
|
||||
@@ -291,63 +147,6 @@ PUBLIC const char *glXGetDriverConfig (const char *driverName)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern void
|
||||
driFilterModes(__GLcontextModes ** server_modes,
|
||||
const __GLcontextModes * driver_modes);
|
||||
|
||||
_X_HIDDEN void
|
||||
driFilterModes(__GLcontextModes ** server_modes,
|
||||
const __GLcontextModes * driver_modes)
|
||||
{
|
||||
__GLcontextModes * m;
|
||||
__GLcontextModes ** prev_next;
|
||||
const __GLcontextModes * check;
|
||||
|
||||
if (driver_modes == NULL) {
|
||||
fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* For each mode in server_modes, check to see if a matching mode exists
|
||||
* in driver_modes. If not, then the mode is not available.
|
||||
*/
|
||||
|
||||
prev_next = server_modes;
|
||||
for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
|
||||
GLboolean do_delete = GL_TRUE;
|
||||
|
||||
for ( check = driver_modes ; check != NULL ; check = check->next ) {
|
||||
if ( _gl_context_modes_are_same( m, check ) ) {
|
||||
do_delete = GL_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The 3D has to support all the modes that match the GLX visuals
|
||||
* sent from the X server.
|
||||
*/
|
||||
if ( do_delete && (m->visualID != 0) ) {
|
||||
do_delete = GL_FALSE;
|
||||
|
||||
/* don't warn for this visual (Novell #247471 / X.Org #6689) */
|
||||
if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) {
|
||||
fprintf(stderr, "libGL warning: 3D driver claims to not "
|
||||
"support visual 0x%02x\n", m->visualID);
|
||||
}
|
||||
}
|
||||
|
||||
if ( do_delete ) {
|
||||
*prev_next = m->next;
|
||||
|
||||
m->next = NULL;
|
||||
_gl_context_modes_destroy( m );
|
||||
}
|
||||
else {
|
||||
prev_next = & m->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XDAMAGE_1_1_INTERFACE
|
||||
|
||||
static GLboolean has_damage_post(Display *dpy)
|
||||
@@ -442,12 +241,6 @@ __glXDRIGetDrawableInfo(__DRIdrawable *drawable,
|
||||
numBackClipRects, pBackClipRects);
|
||||
}
|
||||
|
||||
_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = {
|
||||
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
|
||||
__glXGetUST,
|
||||
__driGetMscRateOML,
|
||||
};
|
||||
|
||||
static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
|
||||
{ __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
|
||||
__glXDRIGetDrawableInfo
|
||||
@@ -456,184 +249,13 @@ static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
|
||||
static const __DRIextension *loader_extensions[] = {
|
||||
&systemTimeExtension.base,
|
||||
&getDrawableInfoExtension.base,
|
||||
|
||||
#ifdef XDAMAGE_1_1_INTERFACE
|
||||
&damageExtension.base,
|
||||
#endif
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
#define __ATTRIB(attrib, field) \
|
||||
{ attrib, offsetof(__GLcontextModes, field) }
|
||||
|
||||
static const struct { unsigned int attrib, offset; } attribMap[] = {
|
||||
__ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
|
||||
__ATTRIB(__DRI_ATTRIB_LEVEL, level),
|
||||
__ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
|
||||
__ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
|
||||
__ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
|
||||
__ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
|
||||
__ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
|
||||
__ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
|
||||
__ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
|
||||
__ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
|
||||
__ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
|
||||
__ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
|
||||
__ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
|
||||
#if 0
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentIndex),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
|
||||
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
|
||||
__ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
|
||||
__ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
|
||||
__ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
|
||||
__ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
|
||||
#endif
|
||||
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
|
||||
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
|
||||
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
|
||||
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
|
||||
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
|
||||
#if 0
|
||||
__ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
|
||||
#endif
|
||||
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
|
||||
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
|
||||
__ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
|
||||
__ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
|
||||
static int
|
||||
scalarEqual(__GLcontextModes *mode, unsigned int attrib, unsigned int value)
|
||||
{
|
||||
unsigned int glxValue;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(attribMap); i++)
|
||||
if (attribMap[i].attrib == attrib) {
|
||||
glxValue = *(unsigned int *) ((char *) mode + attribMap[i].offset);
|
||||
return glxValue == GLX_DONT_CARE || glxValue == value;
|
||||
}
|
||||
|
||||
return GL_TRUE; /* Is a non-existing attribute equal to value? */
|
||||
}
|
||||
|
||||
static int
|
||||
driConfigEqual(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig *driConfig)
|
||||
{
|
||||
unsigned int attrib, value, glxValue;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
|
||||
switch (attrib) {
|
||||
case __DRI_ATTRIB_RENDER_TYPE:
|
||||
glxValue = 0;
|
||||
if (value & __DRI_ATTRIB_RGBA_BIT) {
|
||||
glxValue |= GLX_RGBA_BIT;
|
||||
} else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
|
||||
glxValue |= GLX_COLOR_INDEX_BIT;
|
||||
}
|
||||
if (glxValue != modes->renderType)
|
||||
return GL_FALSE;
|
||||
break;
|
||||
|
||||
case __DRI_ATTRIB_CONFIG_CAVEAT:
|
||||
if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
|
||||
glxValue = GLX_NON_CONFORMANT_CONFIG;
|
||||
else if (value & __DRI_ATTRIB_SLOW_BIT)
|
||||
glxValue = GLX_SLOW_CONFIG;
|
||||
else
|
||||
glxValue = GLX_NONE;
|
||||
if (glxValue != modes->visualRating)
|
||||
return GL_FALSE;
|
||||
break;
|
||||
|
||||
case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
|
||||
glxValue = 0;
|
||||
if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
|
||||
glxValue |= GLX_TEXTURE_1D_BIT_EXT;
|
||||
if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
|
||||
glxValue |= GLX_TEXTURE_2D_BIT_EXT;
|
||||
if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
|
||||
glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
|
||||
if (modes->bindToTextureTargets != GLX_DONT_CARE &&
|
||||
glxValue != modes->bindToTextureTargets)
|
||||
return GL_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!scalarEqual(modes, attrib, value))
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static __GLcontextModes *
|
||||
createDriMode(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig **driConfigs)
|
||||
{
|
||||
__GLXDRIconfigPrivate *config;
|
||||
int i;
|
||||
|
||||
for (i = 0; driConfigs[i]; i++) {
|
||||
if (driConfigEqual(core, modes, driConfigs[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (driConfigs[i] == NULL)
|
||||
return NULL;
|
||||
|
||||
config = Xmalloc(sizeof *config);
|
||||
if (config == NULL)
|
||||
return NULL;
|
||||
|
||||
config->modes = *modes;
|
||||
config->driConfig = driConfigs[i];
|
||||
|
||||
return &config->modes;
|
||||
}
|
||||
|
||||
extern __GLcontextModes *
|
||||
driConvertConfigs(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig **configs);
|
||||
|
||||
_X_HIDDEN __GLcontextModes *
|
||||
driConvertConfigs(const __DRIcoreExtension *core,
|
||||
__GLcontextModes *modes, const __DRIconfig **configs)
|
||||
{
|
||||
__GLcontextModes head, *tail, *m;
|
||||
|
||||
tail = &head;
|
||||
head.next = NULL;
|
||||
for (m = modes; m; m = m->next) {
|
||||
tail->next = createDriMode(core, m, configs);
|
||||
if (tail->next == NULL) {
|
||||
/* no matching dri config for m */
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
tail = tail->next;
|
||||
}
|
||||
|
||||
_gl_context_modes_destroy(modes);
|
||||
|
||||
return head.next;
|
||||
}
|
||||
#ifndef GLX_USE_APPLEGL
|
||||
|
||||
/**
|
||||
* Perform the required libGL-side initialization and call the client-side
|
||||
@@ -647,17 +269,12 @@ driConvertConfigs(const __DRIcoreExtension *core,
|
||||
* \c __driCreateNewScreen function.
|
||||
* \returns A pointer to the \c __DRIscreenPrivate structure returned by
|
||||
* the client-side driver on success, or \c NULL on failure.
|
||||
*
|
||||
* \todo This function needs to be modified to remove context-modes from the
|
||||
* list stored in the \c __GLXscreenConfigsRec to match the list
|
||||
* returned by the client-side driver.
|
||||
*/
|
||||
static void *
|
||||
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
|
||||
__GLXDRIdisplayPrivate * driDpy)
|
||||
{
|
||||
void *psp = NULL;
|
||||
#ifndef GLX_USE_APPLEGL
|
||||
drm_handle_t hSAREA;
|
||||
drmAddress pSAREA = MAP_FAILED;
|
||||
char *BusID;
|
||||
@@ -667,175 +284,159 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
|
||||
__DRIframebuffer framebuffer;
|
||||
int fd = -1;
|
||||
int status;
|
||||
const char * err_msg;
|
||||
const char * err_extra;
|
||||
|
||||
drm_magic_t magic;
|
||||
drmVersionPtr version;
|
||||
int newlyopened;
|
||||
char *driverName;
|
||||
drm_handle_t hFB;
|
||||
int junk;
|
||||
const __DRIconfig **driver_configs;
|
||||
|
||||
/* DRI protocol version. */
|
||||
dri_version.major = driDpy->driMajor;
|
||||
dri_version.minor = driDpy->driMinor;
|
||||
dri_version.patch = driDpy->driPatch;
|
||||
|
||||
err_msg = "XF86DRIOpenConnection";
|
||||
err_extra = NULL;
|
||||
|
||||
framebuffer.base = MAP_FAILED;
|
||||
framebuffer.dev_priv = NULL;
|
||||
|
||||
if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
|
||||
int newlyopened;
|
||||
fd = drmOpenOnce(NULL,BusID, &newlyopened);
|
||||
Xfree(BusID); /* No longer needed */
|
||||
|
||||
err_msg = "open DRM";
|
||||
err_extra = strerror( -fd );
|
||||
|
||||
if (fd >= 0) {
|
||||
drm_magic_t magic;
|
||||
|
||||
err_msg = "drmGetMagic";
|
||||
err_extra = NULL;
|
||||
|
||||
if (!drmGetMagic(fd, &magic)) {
|
||||
drmVersionPtr version = drmGetVersion(fd);
|
||||
if (version) {
|
||||
drm_version.major = version->version_major;
|
||||
drm_version.minor = version->version_minor;
|
||||
drm_version.patch = version->version_patchlevel;
|
||||
drmFreeVersion(version);
|
||||
}
|
||||
else {
|
||||
drm_version.major = -1;
|
||||
drm_version.minor = -1;
|
||||
drm_version.patch = -1;
|
||||
}
|
||||
|
||||
err_msg = "XF86DRIAuthConnection";
|
||||
if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
|
||||
char *driverName;
|
||||
|
||||
/*
|
||||
* Get device name (like "tdfx") and the ddx version
|
||||
* numbers. We'll check the version in each DRI driver's
|
||||
* "createNewScreen" function.
|
||||
*/
|
||||
err_msg = "XF86DRIGetClientDriverName";
|
||||
if (XF86DRIGetClientDriverName(dpy, scrn,
|
||||
&ddx_version.major,
|
||||
&ddx_version.minor,
|
||||
&ddx_version.patch,
|
||||
&driverName)) {
|
||||
drm_handle_t hFB;
|
||||
int junk;
|
||||
|
||||
/* No longer needed. */
|
||||
Xfree( driverName );
|
||||
|
||||
|
||||
/*
|
||||
* Get device-specific info. pDevPriv will point to a struct
|
||||
* (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
|
||||
* that has information about the screen size, depth, pitch,
|
||||
* ancilliary buffers, DRM mmap handles, etc.
|
||||
*/
|
||||
err_msg = "XF86DRIGetDeviceInfo";
|
||||
if (XF86DRIGetDeviceInfo(dpy, scrn,
|
||||
&hFB,
|
||||
&junk,
|
||||
&framebuffer.size,
|
||||
&framebuffer.stride,
|
||||
&framebuffer.dev_priv_size,
|
||||
&framebuffer.dev_priv)) {
|
||||
framebuffer.width = DisplayWidth(dpy, scrn);
|
||||
framebuffer.height = DisplayHeight(dpy, scrn);
|
||||
|
||||
/*
|
||||
* Map the framebuffer region.
|
||||
*/
|
||||
status = drmMap(fd, hFB, framebuffer.size,
|
||||
(drmAddressPtr)&framebuffer.base);
|
||||
|
||||
err_msg = "drmMap of framebuffer";
|
||||
err_extra = strerror( -status );
|
||||
|
||||
if ( status == 0 ) {
|
||||
/*
|
||||
* Map the SAREA region. Further mmap regions
|
||||
* may be setup in each DRI driver's
|
||||
* "createNewScreen" function.
|
||||
*/
|
||||
status = drmMap(fd, hSAREA, SAREA_MAX,
|
||||
&pSAREA);
|
||||
|
||||
err_msg = "drmMap of sarea";
|
||||
err_extra = strerror( -status );
|
||||
|
||||
if ( status == 0 ) {
|
||||
err_msg = "InitDriver";
|
||||
err_extra = NULL;
|
||||
psp = (*psc->legacy->createNewScreen)(scrn,
|
||||
& ddx_version,
|
||||
& dri_version,
|
||||
& drm_version,
|
||||
& framebuffer,
|
||||
pSAREA,
|
||||
fd,
|
||||
loader_extensions,
|
||||
& driver_configs,
|
||||
psc);
|
||||
|
||||
if (psp) {
|
||||
psc->configs =
|
||||
driConvertConfigs(psc->core,
|
||||
psc->configs,
|
||||
driver_configs);
|
||||
psc->visuals =
|
||||
driConvertConfigs(psc->core,
|
||||
psc->visuals,
|
||||
driver_configs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
|
||||
ErrorMessageF("XF86DRIOpenConnection failed\n");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
if ( psp == NULL ) {
|
||||
if ( pSAREA != MAP_FAILED ) {
|
||||
(void)drmUnmap(pSAREA, SAREA_MAX);
|
||||
}
|
||||
fd = drmOpenOnce(NULL, BusID, &newlyopened);
|
||||
|
||||
if ( framebuffer.base != MAP_FAILED ) {
|
||||
(void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
|
||||
}
|
||||
Xfree(BusID); /* No longer needed */
|
||||
|
||||
if ( framebuffer.dev_priv != NULL ) {
|
||||
Xfree(framebuffer.dev_priv);
|
||||
}
|
||||
|
||||
if ( fd >= 0 ) {
|
||||
(void)drmCloseOnce(fd);
|
||||
}
|
||||
|
||||
(void)XF86DRICloseConnection(dpy, scrn);
|
||||
|
||||
if ( err_extra != NULL ) {
|
||||
fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
|
||||
err_extra);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "libGL error: %s failed\n", err_msg );
|
||||
}
|
||||
|
||||
fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
|
||||
if (fd < 0) {
|
||||
ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
|
||||
goto handle_error;
|
||||
}
|
||||
#endif /* !GLX_USE_APPLEGL */
|
||||
|
||||
if (drmGetMagic(fd, &magic)) {
|
||||
ErrorMessageF("drmGetMagic failed\n");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
version = drmGetVersion(fd);
|
||||
if (version) {
|
||||
drm_version.major = version->version_major;
|
||||
drm_version.minor = version->version_minor;
|
||||
drm_version.patch = version->version_patchlevel;
|
||||
drmFreeVersion(version);
|
||||
}
|
||||
else {
|
||||
drm_version.major = -1;
|
||||
drm_version.minor = -1;
|
||||
drm_version.patch = -1;
|
||||
}
|
||||
|
||||
if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
|
||||
ErrorMessageF("XF86DRIAuthConnection failed\n");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
/* Get device name (like "tdfx") and the ddx version numbers.
|
||||
* We'll check the version in each DRI driver's "createNewScreen"
|
||||
* function. */
|
||||
if (!XF86DRIGetClientDriverName(dpy, scrn,
|
||||
&ddx_version.major,
|
||||
&ddx_version.minor,
|
||||
&ddx_version.patch,
|
||||
&driverName)) {
|
||||
ErrorMessageF("XF86DRIGetClientDriverName failed\n");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
Xfree(driverName); /* No longer needed. */
|
||||
|
||||
/*
|
||||
* Get device-specific info. pDevPriv will point to a struct
|
||||
* (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
|
||||
* has information about the screen size, depth, pitch, ancilliary
|
||||
* buffers, DRM mmap handles, etc.
|
||||
*/
|
||||
if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
|
||||
&framebuffer.size, &framebuffer.stride,
|
||||
&framebuffer.dev_priv_size, &framebuffer.dev_priv)) {
|
||||
ErrorMessageF("XF86DRIGetDeviceInfo failed");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
framebuffer.width = DisplayWidth(dpy, scrn);
|
||||
framebuffer.height = DisplayHeight(dpy, scrn);
|
||||
|
||||
/* Map the framebuffer region. */
|
||||
status = drmMap(fd, hFB, framebuffer.size,
|
||||
(drmAddressPtr)&framebuffer.base);
|
||||
if (status != 0) {
|
||||
ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status));
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
/* Map the SAREA region. Further mmap regions may be setup in
|
||||
* each DRI driver's "createNewScreen" function.
|
||||
*/
|
||||
status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
|
||||
if (status != 0) {
|
||||
ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status));
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
psp = (*psc->legacy->createNewScreen)(scrn,
|
||||
&ddx_version,
|
||||
&dri_version,
|
||||
&drm_version,
|
||||
&framebuffer,
|
||||
pSAREA,
|
||||
fd,
|
||||
loader_extensions,
|
||||
&driver_configs,
|
||||
psc);
|
||||
|
||||
if (psp == NULL) {
|
||||
ErrorMessageF("Calling driver entry point failed");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
|
||||
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
|
||||
|
||||
return psp;
|
||||
|
||||
handle_error:
|
||||
if (pSAREA != MAP_FAILED)
|
||||
drmUnmap(pSAREA, SAREA_MAX);
|
||||
|
||||
if (framebuffer.base != MAP_FAILED)
|
||||
drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
|
||||
|
||||
if (framebuffer.dev_priv != NULL)
|
||||
Xfree(framebuffer.dev_priv);
|
||||
|
||||
if (fd >= 0)
|
||||
drmCloseOnce(fd);
|
||||
|
||||
XF86DRICloseConnection(dpy, scrn);
|
||||
|
||||
ErrorMessageF("reverting to software direct rendering\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* !GLX_USE_APPLEGL */
|
||||
|
||||
static void *
|
||||
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
|
||||
__GLXDRIdisplayPrivate * driDpy)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* !GLX_USE_APPLEGL */
|
||||
|
||||
static void driDestroyContext(__GLXDRIcontext *context,
|
||||
__GLXscreenConfigs *psc, Display *dpy)
|
||||
{
|
||||
@@ -875,45 +476,44 @@ static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
|
||||
__DRIcontext *shared = NULL;
|
||||
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
|
||||
|
||||
if (psc && psc->driScreen) {
|
||||
if (shareList) {
|
||||
pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
|
||||
shared = pcp_shared->driContext;
|
||||
}
|
||||
if (!psc || !psc->driScreen)
|
||||
return NULL;
|
||||
|
||||
pcp = Xmalloc(sizeof *pcp);
|
||||
if (pcp == NULL)
|
||||
return NULL;
|
||||
|
||||
pcp->psc = psc;
|
||||
if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
|
||||
mode->visualID,
|
||||
&pcp->hwContextID, &hwContext)) {
|
||||
Xfree(pcp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp->driContext =
|
||||
(*psc->legacy->createNewContext)(psc->__driScreen,
|
||||
config->driConfig,
|
||||
renderType,
|
||||
shared,
|
||||
hwContext,
|
||||
pcp);
|
||||
if (pcp->driContext == NULL) {
|
||||
XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
|
||||
Xfree(pcp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp->base.destroyContext = driDestroyContext;
|
||||
pcp->base.bindContext = driBindContext;
|
||||
pcp->base.unbindContext = driUnbindContext;
|
||||
|
||||
return &pcp->base;
|
||||
if (shareList) {
|
||||
pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
|
||||
shared = pcp_shared->driContext;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
pcp = Xmalloc(sizeof *pcp);
|
||||
if (pcp == NULL)
|
||||
return NULL;
|
||||
|
||||
pcp->psc = psc;
|
||||
if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
|
||||
mode->visualID,
|
||||
&pcp->hwContextID, &hwContext)) {
|
||||
Xfree(pcp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp->driContext =
|
||||
(*psc->legacy->createNewContext)(psc->__driScreen,
|
||||
config->driConfig,
|
||||
renderType,
|
||||
shared,
|
||||
hwContext,
|
||||
pcp);
|
||||
if (pcp->driContext == NULL) {
|
||||
XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
|
||||
Xfree(pcp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp->base.destroyContext = driDestroyContext;
|
||||
pcp->base.bindContext = driBindContext;
|
||||
pcp->base.unbindContext = driUnbindContext;
|
||||
|
||||
return &pcp->base;
|
||||
}
|
||||
|
||||
static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
|
||||
@@ -979,15 +579,13 @@ static void driDestroyScreen(__GLXscreenConfigs *psc)
|
||||
dlclose(psc->driver);
|
||||
}
|
||||
|
||||
void
|
||||
driBindExtensions(__GLXscreenConfigs *psc);
|
||||
|
||||
static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
|
||||
__GLXdisplayPrivate *priv)
|
||||
{
|
||||
__GLXDRIdisplayPrivate *pdp;
|
||||
__GLXDRIscreen *psp;
|
||||
const __DRIextension **extensions;
|
||||
char *driverName;
|
||||
int i;
|
||||
|
||||
psp = Xmalloc(sizeof *psp);
|
||||
@@ -997,7 +595,13 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
|
||||
/* Initialize per screen dynamic client GLX extensions */
|
||||
psc->ext_list_first_time = GL_TRUE;
|
||||
|
||||
psc->driver = driGetDriver(priv->dpy, screen);
|
||||
if (!driGetDriverName(priv->dpy, screen, &driverName)) {
|
||||
Xfree(psp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
psc->driver = driOpenDriver(driverName);
|
||||
Xfree(driverName);
|
||||
if (psc->driver == NULL) {
|
||||
Xfree(psp);
|
||||
return NULL;
|
||||
|
||||
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* Copyright 2008 George Sapountzis
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "glheader.h"
|
||||
#include "glxclient.h"
|
||||
#include "glcontextmodes.h"
|
||||
#include <dlfcn.h>
|
||||
#include "dri_common.h"
|
||||
|
||||
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
|
||||
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
|
||||
typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
|
||||
|
||||
struct __GLXDRIdisplayPrivateRec {
|
||||
__GLXDRIdisplay base;
|
||||
};
|
||||
|
||||
struct __GLXDRIcontextPrivateRec {
|
||||
__GLXDRIcontext base;
|
||||
__DRIcontext *driContext;
|
||||
__GLXscreenConfigs *psc;
|
||||
};
|
||||
|
||||
struct __GLXDRIdrawablePrivateRec {
|
||||
__GLXDRIdrawable base;
|
||||
|
||||
GC gc;
|
||||
GC swapgc;
|
||||
|
||||
XVisualInfo *visinfo;
|
||||
XImage *ximage;
|
||||
int bpp;
|
||||
};
|
||||
|
||||
/**
|
||||
* swrast loader functions
|
||||
*/
|
||||
|
||||
static Bool XCreateDrawable(__GLXDRIdrawablePrivate *pdp,
|
||||
Display *dpy, XID drawable, int visualid)
|
||||
{
|
||||
XGCValues gcvalues;
|
||||
long visMask;
|
||||
XVisualInfo visTemp;
|
||||
int num_visuals;
|
||||
|
||||
/* create GC's */
|
||||
pdp->gc = XCreateGC(dpy, drawable, 0, NULL);
|
||||
pdp->swapgc = XCreateGC(dpy, drawable, 0, NULL);
|
||||
|
||||
gcvalues.function = GXcopy;
|
||||
gcvalues.graphics_exposures = False;
|
||||
XChangeGC(dpy, pdp->gc, GCFunction, &gcvalues);
|
||||
XChangeGC(dpy, pdp->swapgc, GCFunction, &gcvalues);
|
||||
XChangeGC(dpy, pdp->swapgc, GCGraphicsExposures, &gcvalues);
|
||||
|
||||
/* create XImage */
|
||||
visTemp.screen = DefaultScreen(dpy);
|
||||
visTemp.visualid = visualid;
|
||||
visMask = (VisualScreenMask | VisualIDMask);
|
||||
pdp->visinfo = XGetVisualInfo(dpy, visMask, &visTemp, &num_visuals);
|
||||
|
||||
pdp->ximage = XCreateImage(dpy,
|
||||
pdp->visinfo->visual,
|
||||
pdp->visinfo->depth,
|
||||
ZPixmap, 0, /* format, offset */
|
||||
NULL, /* data */
|
||||
0, 0, /* size */
|
||||
32, /* bitmap_pad */
|
||||
0); /* bytes_per_line */
|
||||
|
||||
/* get the true number of bits per pixel */
|
||||
pdp->bpp = pdp->ximage->bits_per_pixel;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static void XDestroyDrawable(__GLXDRIdrawablePrivate *pdp,
|
||||
Display *dpy, XID drawable)
|
||||
{
|
||||
XDestroyImage(pdp->ximage);
|
||||
XFree(pdp->visinfo);
|
||||
|
||||
XFreeGC(dpy, pdp->gc);
|
||||
XFreeGC(dpy, pdp->swapgc);
|
||||
}
|
||||
|
||||
static void
|
||||
swrastGetDrawableInfo(__DRIdrawable *draw,
|
||||
int *x, int *y, int *w, int *h,
|
||||
void *loaderPrivate)
|
||||
{
|
||||
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
|
||||
__GLXDRIdrawable *pdraw = &(pdp->base);;
|
||||
Display *dpy = pdraw->psc->dpy;
|
||||
Drawable drawable;
|
||||
|
||||
Window root;
|
||||
Status stat;
|
||||
unsigned int bw, depth;
|
||||
|
||||
drawable = pdraw->xDrawable;
|
||||
|
||||
stat = XGetGeometry(dpy, drawable, &root,
|
||||
x, y, (unsigned int *)w, (unsigned int *)h,
|
||||
&bw, &depth);
|
||||
}
|
||||
|
||||
static inline int
|
||||
bytes_per_line(int w, int bpp, unsigned mul)
|
||||
{
|
||||
unsigned mask = mul - 1;
|
||||
|
||||
return ((w * bpp + mask) & ~mask) / 8;
|
||||
}
|
||||
|
||||
static void
|
||||
swrastPutImage(__DRIdrawable *draw, int op,
|
||||
int x, int y, int w, int h, char *data,
|
||||
void *loaderPrivate)
|
||||
{
|
||||
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
|
||||
__GLXDRIdrawable *pdraw = &(pdp->base);;
|
||||
Display *dpy = pdraw->psc->dpy;
|
||||
Drawable drawable;
|
||||
XImage *ximage;
|
||||
GC gc;
|
||||
|
||||
switch (op) {
|
||||
case __DRI_SWRAST_IMAGE_OP_DRAW:
|
||||
gc = pdp->gc;
|
||||
break;
|
||||
case __DRI_SWRAST_IMAGE_OP_SWAP:
|
||||
gc = pdp->swapgc;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
drawable = pdraw->xDrawable;
|
||||
|
||||
ximage = pdp->ximage;
|
||||
ximage->data = data;
|
||||
ximage->width = w;
|
||||
ximage->height = h;
|
||||
ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);
|
||||
|
||||
XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
|
||||
|
||||
ximage->data = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
swrastGetImage(__DRIdrawable *draw,
|
||||
int x, int y, int w, int h, char *data,
|
||||
void *loaderPrivate)
|
||||
{
|
||||
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
|
||||
__GLXDRIdrawable *pdraw = &(pdp->base);;
|
||||
Display *dpy = pdraw->psc->dpy;
|
||||
Drawable drawable;
|
||||
XImage *ximage;
|
||||
|
||||
drawable = pdraw->xDrawable;
|
||||
|
||||
ximage = pdp->ximage;
|
||||
ximage->data = data;
|
||||
ximage->width = w;
|
||||
ximage->height = h;
|
||||
ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);
|
||||
|
||||
XGetSubImage(dpy, drawable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
|
||||
|
||||
ximage->data = NULL;
|
||||
}
|
||||
|
||||
static const __DRIswrastLoaderExtension swrastLoaderExtension = {
|
||||
{ __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION },
|
||||
swrastGetDrawableInfo,
|
||||
swrastPutImage,
|
||||
swrastGetImage
|
||||
};
|
||||
|
||||
static const __DRIextension *loader_extensions[] = {
|
||||
&systemTimeExtension.base,
|
||||
&swrastLoaderExtension.base,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* GLXDRI functions
|
||||
*/
|
||||
|
||||
static void driDestroyContext(__GLXDRIcontext *context,
|
||||
__GLXscreenConfigs *psc, Display *dpy)
|
||||
{
|
||||
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
|
||||
const __DRIcoreExtension *core = pcp->psc->core;
|
||||
|
||||
(*core->destroyContext)(pcp->driContext);
|
||||
|
||||
Xfree(pcp);
|
||||
}
|
||||
|
||||
static Bool driBindContext(__GLXDRIcontext *context,
|
||||
__GLXDRIdrawable *draw, __GLXDRIdrawable *read)
|
||||
{
|
||||
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
|
||||
const __DRIcoreExtension *core = pcp->psc->core;
|
||||
|
||||
return (*core->bindContext)(pcp->driContext,
|
||||
draw->driDrawable,
|
||||
read->driDrawable);
|
||||
}
|
||||
|
||||
static void driUnbindContext(__GLXDRIcontext *context)
|
||||
{
|
||||
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
|
||||
const __DRIcoreExtension *core = pcp->psc->core;
|
||||
|
||||
(*core->unbindContext)(pcp->driContext);
|
||||
}
|
||||
|
||||
static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
|
||||
const __GLcontextModes *mode,
|
||||
GLXContext gc,
|
||||
GLXContext shareList, int renderType)
|
||||
{
|
||||
__GLXDRIcontextPrivate *pcp, *pcp_shared;
|
||||
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
|
||||
const __DRIcoreExtension *core = psc->core;
|
||||
__DRIcontext *shared = NULL;
|
||||
|
||||
if (!psc || !psc->driScreen)
|
||||
return NULL;
|
||||
|
||||
if (shareList) {
|
||||
pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
|
||||
shared = pcp_shared->driContext;
|
||||
}
|
||||
|
||||
pcp = Xmalloc(sizeof *pcp);
|
||||
if (pcp == NULL)
|
||||
return NULL;
|
||||
|
||||
pcp->psc = psc;
|
||||
pcp->driContext =
|
||||
(*core->createNewContext)(psc->__driScreen,
|
||||
config->driConfig, shared, pcp);
|
||||
if (pcp->driContext == NULL) {
|
||||
Xfree(pcp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp->base.destroyContext = driDestroyContext;
|
||||
pcp->base.bindContext = driBindContext;
|
||||
pcp->base.unbindContext = driUnbindContext;
|
||||
|
||||
return &pcp->base;
|
||||
}
|
||||
|
||||
static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
|
||||
{
|
||||
__GLXDRIdrawablePrivate *pdp = (__GLXDRIdrawablePrivate *) pdraw;
|
||||
const __DRIcoreExtension *core = pdraw->psc->core;
|
||||
|
||||
(*core->destroyDrawable)(pdraw->driDrawable);
|
||||
|
||||
XDestroyDrawable(pdp, pdraw->psc->dpy, pdraw->drawable);
|
||||
Xfree(pdp);
|
||||
}
|
||||
|
||||
static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
|
||||
XID xDrawable,
|
||||
GLXDrawable drawable,
|
||||
const __GLcontextModes *modes)
|
||||
{
|
||||
__GLXDRIdrawable *pdraw;
|
||||
__GLXDRIdrawablePrivate *pdp;
|
||||
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
|
||||
const __DRIswrastExtension *swrast = psc->swrast;
|
||||
|
||||
/* Old dri can't handle GLX 1.3+ drawable constructors. */
|
||||
if (xDrawable != drawable)
|
||||
return NULL;
|
||||
|
||||
pdp = Xmalloc(sizeof(*pdp));
|
||||
if (!pdp)
|
||||
return NULL;
|
||||
|
||||
pdraw = &(pdp->base);
|
||||
pdraw->xDrawable = xDrawable;
|
||||
pdraw->drawable = drawable;
|
||||
pdraw->psc = psc;
|
||||
|
||||
XCreateDrawable(pdp, psc->dpy, xDrawable, modes->visualID);
|
||||
|
||||
/* Create a new drawable */
|
||||
pdraw->driDrawable =
|
||||
(*swrast->createNewDrawable)(psc->__driScreen,
|
||||
config->driConfig,
|
||||
pdp);
|
||||
|
||||
if (!pdraw->driDrawable) {
|
||||
XDestroyDrawable(pdp, psc->dpy, xDrawable);
|
||||
Xfree(pdp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pdraw->destroyDrawable = driDestroyDrawable;
|
||||
|
||||
return pdraw;
|
||||
}
|
||||
|
||||
static void driDestroyScreen(__GLXscreenConfigs *psc)
|
||||
{
|
||||
/* Free the direct rendering per screen data */
|
||||
(*psc->core->destroyScreen)(psc->__driScreen);
|
||||
psc->__driScreen = NULL;
|
||||
if (psc->driver)
|
||||
dlclose(psc->driver);
|
||||
}
|
||||
|
||||
static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
|
||||
__GLXdisplayPrivate *priv)
|
||||
{
|
||||
__GLXDRIscreen *psp;
|
||||
const __DRIconfig **driver_configs;
|
||||
const __DRIextension **extensions;
|
||||
const char *driverName = "swrast";
|
||||
int i;
|
||||
|
||||
psp = Xmalloc(sizeof *psp);
|
||||
if (psp == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Initialize per screen dynamic client GLX extensions */
|
||||
psc->ext_list_first_time = GL_TRUE;
|
||||
|
||||
psc->driver = driOpenDriver(driverName);
|
||||
if (psc->driver == NULL)
|
||||
goto handle_error;
|
||||
|
||||
extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
|
||||
if (extensions == NULL) {
|
||||
ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
for (i = 0; extensions[i]; i++) {
|
||||
if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
|
||||
psc->core = (__DRIcoreExtension *) extensions[i];
|
||||
if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0)
|
||||
psc->swrast = (__DRIswrastExtension *) extensions[i];
|
||||
}
|
||||
|
||||
if (psc->core == NULL || psc->swrast == NULL) {
|
||||
ErrorMessageF("core dri extension not found\n");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
psc->__driScreen =
|
||||
psc->swrast->createNewScreen(screen,
|
||||
loader_extensions, &driver_configs, psc);
|
||||
if (psc->__driScreen == NULL) {
|
||||
ErrorMessageF("failed to create dri screen\n");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
driBindExtensions(psc);
|
||||
|
||||
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
|
||||
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
|
||||
|
||||
psp->destroyScreen = driDestroyScreen;
|
||||
psp->createContext = driCreateContext;
|
||||
psp->createDrawable = driCreateDrawable;
|
||||
|
||||
return psp;
|
||||
|
||||
handle_error:
|
||||
Xfree(psp);
|
||||
|
||||
if (psc->driver)
|
||||
dlclose(psc->driver);
|
||||
|
||||
ErrorMessageF("reverting to indirect rendering\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Called from __glXFreeDisplayPrivate.
|
||||
*/
|
||||
static void driDestroyDisplay(__GLXDRIdisplay *dpy)
|
||||
{
|
||||
Xfree(dpy);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate, initialize and return a __DRIdisplayPrivate object.
|
||||
* This is called from __glXInitialize() when we are given a new
|
||||
* display pointer.
|
||||
*/
|
||||
_X_HIDDEN __GLXDRIdisplay *driswCreateDisplay(Display *dpy)
|
||||
{
|
||||
__GLXDRIdisplayPrivate *pdpyp;
|
||||
|
||||
pdpyp = Xmalloc(sizeof *pdpyp);
|
||||
if (pdpyp == NULL)
|
||||
return NULL;
|
||||
|
||||
pdpyp->base.destroyDisplay = driDestroyDisplay;
|
||||
pdpyp->base.createScreen = driCreateScreen;
|
||||
|
||||
return &pdpyp->base;
|
||||
}
|
||||
|
||||
#endif /* GLX_DIRECT_RENDERING */
|
||||
@@ -118,7 +118,7 @@ _gl_convert_to_x_visual_type( int visualType )
|
||||
* of the fields in \c config are copied to \c mode. Additional fields in
|
||||
* \c mode that can be derrived from the fields of \c config (i.e.,
|
||||
* \c haveDepthBuffer) are also filled in. The remaining fields in \c mode
|
||||
* that cannot be derrived are set to default values.
|
||||
* that cannot be derived are set to default values.
|
||||
*
|
||||
* \param mode Destination GL context mode.
|
||||
* \param config Source GLX visual config.
|
||||
@@ -184,6 +184,9 @@ _gl_copy_visual_to_context_mode( __GLcontextModes * mode,
|
||||
mode->transparentBlue = config->transparentBlue;
|
||||
mode->transparentAlpha = config->transparentAlpha;
|
||||
mode->transparentIndex = config->transparentIndex;
|
||||
mode->samples = config->multiSampleSize;
|
||||
mode->sampleBuffers = config->nMultiSampleBuffers;
|
||||
/* mode->visualSelectGroup = config->visualSelectGroup; ? */
|
||||
|
||||
mode->swapMethod = GLX_SWAP_UNDEFINED_OML;
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
|
||||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
|
||||
|
||||
if (pdraw != NULL && !pdraw->textureTarget)
|
||||
pdraw->textureTarget = determineTextureTarget(data,
|
||||
pdraw->textureTarget = determineTextureTarget((const int *)data,
|
||||
num_attributes);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -147,6 +147,7 @@ struct __GLXDRIdrawableRec {
|
||||
** Function to create and DRI display data and initialize the display
|
||||
** dependent methods.
|
||||
*/
|
||||
extern __GLXDRIdisplay *driswCreateDisplay(Display *dpy);
|
||||
extern __GLXDRIdisplay *driCreateDisplay(Display *dpy);
|
||||
extern __GLXDRIdisplay *dri2CreateDisplay(Display *dpy);
|
||||
|
||||
@@ -465,6 +466,7 @@ struct __GLXscreenConfigsRec {
|
||||
__DRIscreen *__driScreen;
|
||||
const __DRIcoreExtension *core;
|
||||
const __DRIlegacyExtension *legacy;
|
||||
const __DRIswrastExtension *swrast;
|
||||
__glxHashTable *drawHash;
|
||||
Display *dpy;
|
||||
int scr, fd;
|
||||
@@ -564,6 +566,7 @@ struct __GLXdisplayPrivateRec {
|
||||
/**
|
||||
* Per display direct rendering interface functions and data.
|
||||
*/
|
||||
__GLXDRIdisplay *driswDisplay;
|
||||
__GLXDRIdisplay *driDisplay;
|
||||
__GLXDRIdisplay *dri2Display;
|
||||
#endif
|
||||
|
||||
+13
-1
@@ -194,9 +194,14 @@ static int __glXFreeDisplayPrivate(XExtData *extension)
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
/* Free the direct rendering per display data */
|
||||
if (priv->driswDisplay)
|
||||
(*priv->driswDisplay->destroyDisplay)(priv->driswDisplay);
|
||||
priv->driswDisplay = NULL;
|
||||
|
||||
if (priv->driDisplay)
|
||||
(*priv->driDisplay->destroyDisplay)(priv->driDisplay);
|
||||
priv->driDisplay = NULL;
|
||||
|
||||
if (priv->dri2Display)
|
||||
(*priv->dri2Display->destroyDisplay)(priv->dri2Display);
|
||||
priv->dri2Display = NULL;
|
||||
@@ -596,10 +601,16 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
|
||||
psc->drawHash = __glxHashCreate();
|
||||
if (psc->drawHash == NULL)
|
||||
continue;
|
||||
|
||||
if (priv->dri2Display)
|
||||
psc->driScreen = (*priv->dri2Display->createScreen)(psc, i, priv);
|
||||
|
||||
if (psc->driScreen == NULL && priv->driDisplay)
|
||||
psc->driScreen = (*priv->driDisplay->createScreen)(psc, i, priv);
|
||||
|
||||
if (psc->driScreen == NULL && priv->driswDisplay)
|
||||
psc->driScreen = (*priv->driswDisplay->createScreen)(psc, i, priv);
|
||||
|
||||
if (psc->driScreen == NULL) {
|
||||
__glxHashDestroy(psc->drawHash);
|
||||
psc->drawHash = NULL;
|
||||
@@ -693,8 +704,9 @@ _X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy)
|
||||
** (e.g., those called in AllocAndFetchScreenConfigs).
|
||||
*/
|
||||
if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) {
|
||||
dpyPriv->dri2Display = dri2CreateDisplay(dpy);
|
||||
dpyPriv->dri2Display = dri2CreateDisplay(dpy);
|
||||
dpyPriv->driDisplay = driCreateDisplay(dpy);
|
||||
dpyPriv->driswDisplay = driswCreateDisplay(dpy);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+59
-137
@@ -6,11 +6,6 @@ include $(TOP)/configs/current
|
||||
include sources
|
||||
|
||||
|
||||
GL_MAJOR = 1
|
||||
GL_MINOR = 5
|
||||
GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
|
||||
|
||||
|
||||
.SUFFIXES : .cpp
|
||||
|
||||
.c.o:
|
||||
@@ -23,20 +18,62 @@ GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
|
||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Figure out what to make here
|
||||
default: depend
|
||||
@for driver in $(DRIVER_DIRS) ; do \
|
||||
case "$$driver" in \
|
||||
x11) $(MAKE) stand-alone || exit 1 ;; \
|
||||
dri) $(MAKE) linux-solo || exit 1 ;; \
|
||||
osmesa) $(MAKE) osmesa-only || exit 1 ;; \
|
||||
beos) $(MAKE) beos || exit 1 ;; \
|
||||
directfb) $(MAKE) directfb || exit 1 ;; \
|
||||
fbdev) $(MAKE) fbdev || exit 1 ;; \
|
||||
*) echo "$$driver is invalid in DRIVER_DIRS" >&2; exit 1;; \
|
||||
esac ; \
|
||||
done
|
||||
|
||||
# Default: build dependencies, then asm_subdirs, then convenience
|
||||
# libs (.a) and finally the device drivers:
|
||||
default: depend asm_subdirs libmesa.a libglapi.a driver_subdirs
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# Helper libraries used by many drivers:
|
||||
|
||||
# Make archive of core mesa object files
|
||||
libmesa.a: $(MESA_OBJECTS) asm_subdirs
|
||||
@ $(TOP)/bin/mklib -o mesa -static $(MESA_OBJECTS)
|
||||
|
||||
# Make archive of gl* API dispatcher functions only
|
||||
libglapi.a: $(GLAPI_OBJECTS) asm_subdirs
|
||||
@ $(TOP)/bin/mklib -o glapi -static $(GLAPI_OBJECTS)
|
||||
|
||||
|
||||
######################################################################
|
||||
# Device drivers
|
||||
driver_subdirs: libmesa.a libglapi.a
|
||||
(cd drivers && $(MAKE))
|
||||
|
||||
|
||||
######################################################################
|
||||
# Assembly subdirs
|
||||
asm_subdirs:
|
||||
@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \
|
||||
(cd x86 && $(MAKE)) || exit 1 ; \
|
||||
fi
|
||||
@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \
|
||||
(cd x86 && $(MAKE)) || exit 1 ; \
|
||||
(cd x86-64 && $(MAKE)) || exit 1 ; \
|
||||
fi
|
||||
|
||||
|
||||
######################################################################
|
||||
# Dependency generation
|
||||
|
||||
depend: $(ALL_SOURCES)
|
||||
@ echo "running $(MKDEP)"
|
||||
@ touch depend
|
||||
@$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \
|
||||
> /dev/null 2>/dev/null
|
||||
|
||||
|
||||
######################################################################
|
||||
# Installation rules
|
||||
|
||||
# this isn't fleshed out yet but is probably the way to go in the future
|
||||
new_install:
|
||||
(cd drivers && $(MAKE) install)
|
||||
|
||||
|
||||
# XXX replace this with new_install above someday
|
||||
install: default
|
||||
@for driver in $(DRIVER_DIRS) ; do \
|
||||
case "$$driver" in \
|
||||
@@ -51,120 +88,6 @@ install: default
|
||||
done
|
||||
|
||||
|
||||
######################################################################
|
||||
# BeOS driver target
|
||||
|
||||
beos: depend subdirs libmesa.a
|
||||
cd drivers/beos && $(MAKE)
|
||||
|
||||
|
||||
######################################################################
|
||||
# Linux DRI drivers
|
||||
|
||||
# Make archive of core object files
|
||||
libmesa.a: $(SOLO_OBJECTS)
|
||||
@ $(TOP)/bin/mklib -o mesa -static $(SOLO_OBJECTS);
|
||||
@if [ "${CONFIG_NAME}" = "beos" ] ; then \
|
||||
mimeset -f "$@" ; \
|
||||
fi
|
||||
|
||||
linux-solo: depend subdirs libmesa.a
|
||||
cd drivers/dri && $(MAKE)
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Stand-alone Mesa libGL, no built-in drivers (DirectFB)
|
||||
|
||||
libgl-core: $(CORE_OBJECTS)
|
||||
@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) $(CORE_OBJECTS) \
|
||||
$(GL_LIB_DEPS)
|
||||
|
||||
directfb: depend subdirs libgl-core
|
||||
cd drivers/directfb && $(MAKE)
|
||||
|
||||
|
||||
#####################################################################
|
||||
# fbdev Mesa driver (libGL.so)
|
||||
|
||||
fbdev: $(CORE_OBJECTS) $(FBDEV_DRIVER_OBJECTS) $(COMMON_DRIVER_OBJECTS)
|
||||
@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
|
||||
$(CORE_OBJECTS) $(FBDEV_DRIVER_OBJECTS) \
|
||||
$(COMMON_DRIVER_OBJECTS) $(GL_LIB_DEPS)
|
||||
|
||||
|
||||
######################################################################
|
||||
# Stand-alone Mesa libGL and libOSMesa
|
||||
STAND_ALONE_DRIVER_SOURCES = \
|
||||
$(COMMON_DRIVER_SOURCES) \
|
||||
$(X11_DRIVER_SOURCES)
|
||||
|
||||
STAND_ALONE_DRIVER_OBJECTS = $(STAND_ALONE_DRIVER_SOURCES:.c=.o)
|
||||
|
||||
STAND_ALONE_OBJECTS = \
|
||||
$(CORE_OBJECTS) \
|
||||
$(STAND_ALONE_DRIVER_OBJECTS)
|
||||
|
||||
# For libOSMesa16 or libOSMesa32 we link _all_ the objects into the library,
|
||||
# not just the osmesa.o object (i.e. we don't have a libGL).
|
||||
OSMESA16_OBJECTS = \
|
||||
$(CORE_OBJECTS) \
|
||||
$(COMMON_DRIVER_OBJECTS) \
|
||||
$(OSMESA_DRIVER_OBJECTS)
|
||||
|
||||
|
||||
stand-alone: depend subdirs libmesa.a \
|
||||
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
|
||||
|
||||
osmesa-only: depend subdirs \
|
||||
$(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
|
||||
|
||||
# Make the GL library
|
||||
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS)
|
||||
@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) \
|
||||
$(MKLIB_OPTIONS) $(GL_LIB_DEPS) $(STAND_ALONE_OBJECTS)
|
||||
|
||||
# Make the OSMesa library
|
||||
$(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECTS)
|
||||
@ if [ "${DRIVER_DIRS}" = "osmesa" ] ; then \
|
||||
$(TOP)/bin/mklib -o $(OSMESA_LIB) -linker '$(CC)' \
|
||||
-ldflags '$(LDFLAGS)' -major $(MESA_MAJOR) \
|
||||
-minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
|
||||
$(OSMESA_LIB_DEPS) $(OSMESA16_OBJECTS) ; \
|
||||
else \
|
||||
$(TOP)/bin/mklib -o $(OSMESA_LIB) -linker '$(CC)' \
|
||||
-ldflags '$(LDFLAGS)' -major $(MESA_MAJOR) \
|
||||
-minor $(MESA_MINOR) -patch $(GL_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
|
||||
$(OSMESA_LIB_DEPS) $(OSMESA_DRIVER_OBJECTS) ; \
|
||||
fi
|
||||
|
||||
|
||||
######################################################################
|
||||
# Generic stuff
|
||||
|
||||
depend: $(ALL_SOURCES)
|
||||
@ echo "running $(MKDEP)"
|
||||
@ touch depend
|
||||
@$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \
|
||||
> /dev/null 2>/dev/null
|
||||
|
||||
|
||||
subdirs:
|
||||
@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \
|
||||
(cd x86 && $(MAKE)) || exit 1 ; \
|
||||
fi
|
||||
@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \
|
||||
(cd x86 && $(MAKE)) || exit 1 ; \
|
||||
(cd x86-64 && $(MAKE)) || exit 1 ; \
|
||||
fi
|
||||
|
||||
pcedit = sed \
|
||||
-e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
|
||||
-e 's,@LIB_DIR@,$(LIB_DIR),' \
|
||||
@@ -193,22 +116,21 @@ install-osmesa: default
|
||||
install-dri:
|
||||
cd drivers/dri && $(MAKE) install
|
||||
|
||||
## NOT INSTALLED YET:
|
||||
## $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES
|
||||
## $(INSTALL) -m 644 include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES
|
||||
|
||||
|
||||
# Emacs tags
|
||||
tags:
|
||||
etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f */*.o
|
||||
-rm -f */*/*.o
|
||||
-rm -f depend depend.bak libmesa.a
|
||||
-rm -f depend depend.bak libmesa.a libglapi.a
|
||||
-rm -f drivers/*/*.o
|
||||
-@cd drivers/dri && $(MAKE) clean
|
||||
-@cd drivers/xorg && $(MAKE) clean
|
||||
-@cd drivers/x11 && $(MAKE) clean
|
||||
-@cd drivers/osmesa && $(MAKE) clean
|
||||
-@cd x86 && $(MAKE) clean
|
||||
-@cd x86-64 && $(MAKE) clean
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# src/mesa/drivers/Makefile
|
||||
|
||||
TOP = ../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
default:
|
||||
@for dir in $(DRIVER_DIRS) ; do \
|
||||
if [ -d $$dir ] ; then \
|
||||
(cd $$dir && $(MAKE)) || exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
|
||||
clean:
|
||||
@for dir in $(DRIVER_DIRS) ; do \
|
||||
if [ -d $$dir ] ; then \
|
||||
(cd $$dir && $(MAKE) clean) || exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
|
||||
install:
|
||||
@for dir in $(DRIVER_DIRS) ; do \
|
||||
if [ -d $$dir ] ; then \
|
||||
(cd $$dir && $(MAKE) install) || exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
@@ -169,8 +169,10 @@ OBJECTS := $(DRIVER_OBJECTS:.cpp=.o)
|
||||
|
||||
default: depend $(TOP)/$(LIB_DIR) $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
|
||||
|
||||
# XXX FIXME: mesa.a might be libmesa.a now
|
||||
$(MESA_MODULES):
|
||||
cd $(TOP)/src/mesa && $(MAKE) mesa.a ;
|
||||
mimeset -f "$@"
|
||||
|
||||
$(GLU_MODULES):
|
||||
cd $(GLU_DIR) && $(MAKE) $(subst $(GLU_DIR)/,,$(GLU_MODULES)) ;
|
||||
|
||||
@@ -25,11 +25,24 @@ DIRECTFBGL_MESA_OBJECTS = $(DIRECTFBGL_MESA_SOURCES:.c=.o)
|
||||
|
||||
DIRECTFBGL_MESA = libidirectfbgl_mesa.so
|
||||
|
||||
LIBS = $(TOP)/src/mesa/libmesa.a $(TOP)/src/mesa/libglapi.a
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DFB_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
default: directfbgl_mesa
|
||||
default: directfb-libgl directfbgl_mesa
|
||||
|
||||
|
||||
# XXX this used to be in src/mesa/Makefile and is probably broken now
|
||||
directfb-libgl: $(LIBS)
|
||||
@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) $(LIBS) \
|
||||
$(GL_LIB_DEPS)
|
||||
|
||||
|
||||
|
||||
# Mesa DirectFBGL module
|
||||
directfbgl_mesa: $(DIRECTFBGL_MESA_OBJECTS)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
MESA_MODULES = $(TOP)/src/mesa/libmesa.a
|
||||
|
||||
COMMON_SOURCES = \
|
||||
../../common/driverfuncs.c \
|
||||
../common/utils.c \
|
||||
../common/texmem.c \
|
||||
../common/vblank.c \
|
||||
|
||||
@@ -277,9 +277,9 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
|
||||
pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
|
||||
|
||||
DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
|
||||
{
|
||||
@@ -471,6 +471,7 @@ static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
|
||||
return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
|
||||
}
|
||||
|
||||
|
||||
static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
|
||||
int64_t divisor, int64_t remainder,
|
||||
int64_t * msc, int64_t * sbc)
|
||||
@@ -478,7 +479,6 @@ static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
|
||||
__DRIswapInfo sInfo;
|
||||
int status;
|
||||
|
||||
|
||||
status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc,
|
||||
divisor, remainder,
|
||||
msc );
|
||||
@@ -496,12 +496,14 @@ static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
|
||||
{ __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
|
||||
driWaitForMSC,
|
||||
driDrawableGetMSC,
|
||||
};
|
||||
|
||||
|
||||
static void driCopySubBuffer(__DRIdrawable *dPriv,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
@@ -595,6 +597,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
|
||||
return pdp;
|
||||
}
|
||||
|
||||
|
||||
static __DRIdrawable *
|
||||
dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config,
|
||||
unsigned int drawable_id, unsigned int head, void *data)
|
||||
@@ -602,6 +605,8 @@ dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config,
|
||||
__DRIdrawable *pdraw;
|
||||
|
||||
pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data);
|
||||
if (!pdraw)
|
||||
return NULL;
|
||||
|
||||
pdraw->dri2.drawable_id = drawable_id;
|
||||
pdraw->dri2.tail = head;
|
||||
@@ -642,8 +647,6 @@ driDestroyDrawable(__DRIdrawable *pdp)
|
||||
/**
|
||||
* Destroy the per-context private information.
|
||||
*
|
||||
* \param contextPrivate opaque pointer to the per-drawable private info.
|
||||
*
|
||||
* \internal
|
||||
* This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
|
||||
* drmDestroyContext(), and finally frees \p contextPrivate.
|
||||
@@ -661,13 +664,9 @@ driDestroyContext(__DRIcontext *pcp)
|
||||
/**
|
||||
* Create the per-drawable private driver information.
|
||||
*
|
||||
* \param dpy The display handle.
|
||||
* \param modes Mode used to create the new context.
|
||||
* \param render_type Type of rendering target. \c GLX_RGBA is the only
|
||||
* type likely to ever be supported for direct-rendering.
|
||||
* \param shared The shared context dependent methods or \c NULL if
|
||||
* non-existent.
|
||||
* \param pctx DRI context to receive the context dependent methods.
|
||||
* \param shared Context with which to share textures, etc. or NULL
|
||||
*
|
||||
* \returns An opaque pointer to the per-context private information on
|
||||
* success, or \c NULL on failure.
|
||||
@@ -716,6 +715,7 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
|
||||
return pcp;
|
||||
}
|
||||
|
||||
|
||||
static __DRIcontext *
|
||||
dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
|
||||
__DRIcontext *shared, void *data)
|
||||
@@ -734,6 +734,7 @@ dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
|
||||
return driCreateNewContext(screen, config, 0, shared, hwContext, data);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
|
||||
{
|
||||
@@ -751,10 +752,6 @@ driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
|
||||
/**
|
||||
* Destroy the per-screen private information.
|
||||
*
|
||||
* \param dpy the display handle.
|
||||
* \param scrn the screen number.
|
||||
* \param screenPrivate opaque pointer to the per-screen private information.
|
||||
*
|
||||
* \internal
|
||||
* This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
|
||||
* drmClose(), and finally frees \p screenPrivate.
|
||||
@@ -809,15 +806,10 @@ setupLoaderExtensions(__DRIscreen *psp,
|
||||
* This routine also fills in the linked list pointed to by \c driver_modes
|
||||
* with the \c __GLcontextModes that the driver can support for windows or
|
||||
* pbuffers.
|
||||
*
|
||||
* For legacy DRI.
|
||||
*
|
||||
* \param scrn Index of the screen
|
||||
* \param psc DRI screen data (not driver private)
|
||||
* \param modes Linked list of known display modes. This list is, at a
|
||||
* minimum, a list of modes based on the current display mode.
|
||||
* These roughly match the set of available X11 visuals, but it
|
||||
* need not be limited to X11! The calling libGL should create
|
||||
* a list that will inform the driver of the current display
|
||||
* mode (i.e., color buffer depth, depth buffer depth, etc.).
|
||||
* \param ddx_version Version of the 2D DDX. This may not be meaningful for
|
||||
* all drivers.
|
||||
* \param dri_version Version of the "server-side" DRI.
|
||||
@@ -826,9 +818,9 @@ setupLoaderExtensions(__DRIscreen *psp,
|
||||
* framebuffer.
|
||||
* \param pSAREA Pointer the the SAREA.
|
||||
* \param fd Device handle for the DRM.
|
||||
* \param internal_api_version Version of the internal interface between the
|
||||
* driver and libGL.
|
||||
* \param driverAPI Driver API functions used by other routines in dri_util.c.
|
||||
* \param extensions ??
|
||||
* \param driver_modes Returns modes suppoted by the driver
|
||||
* \param loaderPrivate ??
|
||||
*
|
||||
* \note There is no need to check the minimum API version in this
|
||||
* function. Since the name of this function is versioned, it is
|
||||
@@ -901,6 +893,9 @@ driCreateNewScreen(int scrn,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DRI2
|
||||
*/
|
||||
static __DRIscreen *
|
||||
dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
|
||||
const __DRIextension **extensions,
|
||||
@@ -984,6 +979,7 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp)
|
||||
return psp->extensions;
|
||||
}
|
||||
|
||||
/** Legacy DRI interface */
|
||||
const __DRIlegacyExtension driLegacyExtension = {
|
||||
{ __DRI_LEGACY, __DRI_LEGACY_VERSION },
|
||||
driCreateNewScreen,
|
||||
@@ -991,6 +987,7 @@ const __DRIlegacyExtension driLegacyExtension = {
|
||||
driCreateNewContext
|
||||
};
|
||||
|
||||
/** DRI2 interface */
|
||||
const __DRIcoreExtension driCoreExtension = {
|
||||
{ __DRI_CORE, __DRI_CORE_VERSION },
|
||||
dri2CreateNewScreen,
|
||||
|
||||
@@ -65,7 +65,12 @@ translate_texture_format(GLuint mesa_format, GLenum DepthMode)
|
||||
case MESA_FORMAT_RGBA_FXT1:
|
||||
return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
|
||||
case MESA_FORMAT_Z16:
|
||||
return (MAPSURF_16BIT | (DepthMode==GL_ALPHA?MT_16BIT_A16:MT_16BIT_L16));
|
||||
if (DepthMode == GL_ALPHA)
|
||||
return (MAPSURF_16BIT | MT_16BIT_A16);
|
||||
else if (DepthMode == GL_INTENSITY)
|
||||
return (MAPSURF_16BIT | MT_16BIT_I16);
|
||||
else
|
||||
return (MAPSURF_16BIT | MT_16BIT_L16);
|
||||
case MESA_FORMAT_RGBA_DXT1:
|
||||
case MESA_FORMAT_RGB_DXT1:
|
||||
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
|
||||
|
||||
@@ -737,7 +737,8 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
release_temp(c, tmp);
|
||||
}
|
||||
|
||||
if (inst->TexSrcTarget == GL_TEXTURE_RECTANGLE_NV)
|
||||
if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
|
||||
(inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
|
||||
release_temp(c, tmpcoord);
|
||||
}
|
||||
|
||||
@@ -1019,7 +1020,11 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
|
||||
case OPCODE_LIT:
|
||||
precalc_lit(c, inst);
|
||||
break;
|
||||
|
||||
|
||||
case OPCODE_TEX:
|
||||
precalc_tex(c, inst);
|
||||
break;
|
||||
|
||||
case OPCODE_TXP:
|
||||
precalc_txp(c, inst);
|
||||
break;
|
||||
|
||||
@@ -978,7 +978,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c,
|
||||
brw_ADD(p,
|
||||
dst[0],
|
||||
retype(src0[0], BRW_REGISTER_TYPE_W),
|
||||
brw_imm_d(- c->key.origin_x));
|
||||
brw_imm_d(0 - c->key.origin_x));
|
||||
}
|
||||
|
||||
if (mask & WRITEMASK_Y) {
|
||||
|
||||
@@ -327,9 +327,6 @@ intelEmitCopyBlit(struct intel_context *intel,
|
||||
return;
|
||||
}
|
||||
|
||||
dst_pitch &= 0xffff;
|
||||
src_pitch &= 0xffff;
|
||||
|
||||
/* Initial y values don't seem to work with negative pitches. If
|
||||
* we adjust the offsets manually (below), it seems to work fine.
|
||||
*
|
||||
@@ -362,7 +359,7 @@ intelEmitCopyBlit(struct intel_context *intel,
|
||||
|
||||
BEGIN_BATCH(8, NO_LOOP_CLIPRECTS);
|
||||
OUT_BATCH(CMD);
|
||||
OUT_BATCH(BR13 | dst_pitch);
|
||||
OUT_BATCH(BR13 | ((uint16_t)dst_pitch));
|
||||
OUT_BATCH((0 << 16) | dst_x);
|
||||
OUT_BATCH((h << 16) | dst_x2);
|
||||
OUT_RELOC(dst_buffer,
|
||||
|
||||
@@ -53,7 +53,11 @@
|
||||
#define PCI_CHIP_I965_GM 0x2A02
|
||||
#define PCI_CHIP_I965_GME 0x2A12
|
||||
|
||||
#define PCI_CHIP_IGD_GM 0x2A42
|
||||
#define PCI_CHIP_IGD_GM 0x2A42
|
||||
|
||||
#define PCI_CHIP_IGD_E_G 0x2E02
|
||||
#define PCI_CHIP_Q45_G 0x2E12
|
||||
#define PCI_CHIP_G45_G 0x2E22
|
||||
|
||||
#define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \
|
||||
devid == PCI_CHIP_I915_GM || \
|
||||
@@ -63,7 +67,11 @@
|
||||
devid == PCI_CHIP_I965_GME || \
|
||||
devid == PCI_CHIP_IGD_GM)
|
||||
|
||||
#define IS_IGD(devid) (devid == PCI_CHIP_IGD_GM)
|
||||
#define IS_IGD_GM(devid) (devid == PCI_CHIP_IGD_GM)
|
||||
#define IS_G4X(devid) (devid == PCI_CHIP_IGD_E_G || \
|
||||
devid == PCI_CHIP_Q45_G || \
|
||||
devid == PCI_CHIP_G45_G)
|
||||
#define IS_IGD(devid) (IS_IGD_GM(devid) || IS_G4X(devid))
|
||||
|
||||
#define IS_915(devid) (devid == PCI_CHIP_I915_G || \
|
||||
devid == PCI_CHIP_E7221_G || \
|
||||
|
||||
@@ -167,8 +167,15 @@ intelGetString(GLcontext * ctx, GLenum name)
|
||||
chipset = "Intel(R) 965GME/GLE";
|
||||
break;
|
||||
case PCI_CHIP_IGD_GM:
|
||||
case PCI_CHIP_IGD_E_G:
|
||||
chipset = "Intel(R) Integrated Graphics Device";
|
||||
break;
|
||||
case PCI_CHIP_G45_G:
|
||||
chipset = "Intel(R) G45/G43";
|
||||
break;
|
||||
case PCI_CHIP_Q45_G:
|
||||
chipset = "Intel(R) Q45/Q43";
|
||||
break;
|
||||
default:
|
||||
chipset = "Unknown Intel Chipset";
|
||||
break;
|
||||
|
||||
@@ -291,6 +291,10 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
|
||||
intelPrintSAREA(sarea);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DRI2 entrypoint
|
||||
*/
|
||||
static void
|
||||
intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv,
|
||||
__DRIcontextPrivate *pcp,
|
||||
@@ -332,6 +336,9 @@ intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv,
|
||||
|
||||
#define BUFFER_FLAG_TILED 0x0100
|
||||
|
||||
/**
|
||||
* DRI2 entrypoint
|
||||
*/
|
||||
static void
|
||||
intelHandleBufferAttach(__DRIdrawablePrivate *dPriv,
|
||||
__DRIcontextPrivate *pcp,
|
||||
@@ -734,6 +741,7 @@ intelFillInModes(__DRIscreenPrivate *psp,
|
||||
|
||||
/**
|
||||
* This is the driver specific part of the createNewScreen entry point.
|
||||
* Called when using legacy DRI.
|
||||
*
|
||||
* \todo maybe fold this into intelInitDriver
|
||||
*
|
||||
@@ -797,7 +805,8 @@ struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
|
||||
|
||||
/**
|
||||
* This is the driver specific part of the createNewScreen entry point.
|
||||
*
|
||||
* Called when using DRI2.
|
||||
*
|
||||
* \return the __GLcontextModes supported by this driver
|
||||
*/
|
||||
static const
|
||||
|
||||
@@ -28,7 +28,6 @@ DRIVER_SOURCES = \
|
||||
radeon_span.c \
|
||||
radeon_state.c \
|
||||
r300_mem.c \
|
||||
\
|
||||
r300_context.c \
|
||||
r300_ioctl.c \
|
||||
r300_cmdbuf.c \
|
||||
@@ -37,9 +36,13 @@ DRIVER_SOURCES = \
|
||||
r300_texmem.c \
|
||||
r300_tex.c \
|
||||
r300_texstate.c \
|
||||
radeon_program.c \
|
||||
radeon_program_alu.c \
|
||||
r300_vertprog.c \
|
||||
r300_fragprog.c \
|
||||
r300_fragprog_emit.c \
|
||||
r500_fragprog.c \
|
||||
r500_fragprog_emit.c \
|
||||
r300_shader.c \
|
||||
r300_emit.c \
|
||||
r300_swtcl.c \
|
||||
|
||||
@@ -98,6 +98,7 @@ const struct dri_extension card_extensions[] = {
|
||||
{"GL_ARB_fragment_program", NULL},
|
||||
{"GL_ARB_multisample", GL_ARB_multisample_functions},
|
||||
{"GL_ARB_multitexture", NULL},
|
||||
{"GL_ARB_shadow", NULL},
|
||||
{"GL_ARB_texture_border_clamp", NULL},
|
||||
{"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
|
||||
{"GL_ARB_texture_cube_map", NULL},
|
||||
@@ -116,6 +117,7 @@ const struct dri_extension card_extensions[] = {
|
||||
{"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
|
||||
{"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions},
|
||||
{"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
|
||||
{"GL_EXT_shadow_funcs", NULL},
|
||||
{"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
|
||||
{"GL_EXT_stencil_wrap", NULL},
|
||||
{"GL_EXT_texture_edge_clamp", NULL},
|
||||
|
||||
@@ -73,7 +73,6 @@ typedef struct r300_context *r300ContextPtr;
|
||||
}
|
||||
|
||||
#include "r300_vertprog.h"
|
||||
#include "r300_fragprog.h"
|
||||
#include "r500_fragprog.h"
|
||||
|
||||
/**
|
||||
@@ -179,13 +178,6 @@ struct r300_tex_obj {
|
||||
GLuint bufAddr; /* Offset to start of locally
|
||||
shared texture block */
|
||||
|
||||
GLuint dirty_state; /* Flags (1 per texunit) for
|
||||
whether or not this texobj
|
||||
has dirty hardware state
|
||||
(pp_*) that needs to be
|
||||
brought into the
|
||||
texunit. */
|
||||
|
||||
drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
|
||||
/* Six, for the cube faces */
|
||||
|
||||
@@ -581,9 +573,7 @@ struct r300_depthbuffer_state {
|
||||
};
|
||||
|
||||
struct r300_stencilbuffer_state {
|
||||
GLuint clear;
|
||||
GLboolean hw_stencil;
|
||||
|
||||
};
|
||||
|
||||
/* Vertex shader state */
|
||||
@@ -663,96 +653,40 @@ struct r300_vertex_program_cont {
|
||||
#define PFS_NUM_TEMP_REGS 32
|
||||
#define PFS_NUM_CONST_REGS 16
|
||||
|
||||
/* Mapping Mesa registers to R300 temporaries */
|
||||
struct reg_acc {
|
||||
int reg; /* Assigned hw temp */
|
||||
unsigned int refcount; /* Number of uses by mesa program */
|
||||
};
|
||||
struct r300_pfs_compile_state;
|
||||
|
||||
|
||||
/**
|
||||
* Describe the current lifetime information for an R300 temporary
|
||||
* Stores state that influences the compilation of a fragment program.
|
||||
*/
|
||||
struct reg_lifetime {
|
||||
/* Index of the first slot where this register is free in the sense
|
||||
that it can be used as a new destination register.
|
||||
This is -1 if the register has been assigned to a Mesa register
|
||||
and the last access to the register has not yet been emitted */
|
||||
int free;
|
||||
struct r300_fragment_program_external_state {
|
||||
struct {
|
||||
/**
|
||||
* If the sampler is used as a shadow sampler,
|
||||
* this field is:
|
||||
* 0 - GL_LUMINANCE
|
||||
* 1 - GL_INTENSITY
|
||||
* 2 - GL_ALPHA
|
||||
* depending on the depth texture mode.
|
||||
*/
|
||||
GLuint depth_texture_mode : 2;
|
||||
|
||||
/* Index of the first slot where this register is currently reserved.
|
||||
This is used to stop e.g. a scalar operation from being moved
|
||||
before the allocation time of a register that was first allocated
|
||||
for a vector operation. */
|
||||
int reserved;
|
||||
|
||||
/* Index of the first slot in which the register can be used as a
|
||||
source without losing the value that is written by the last
|
||||
emitted instruction that writes to the register */
|
||||
int vector_valid;
|
||||
int scalar_valid;
|
||||
|
||||
/* Index to the slot where the register was last read.
|
||||
This is also the first slot in which the register may be written again */
|
||||
int vector_lastread;
|
||||
int scalar_lastread;
|
||||
/**
|
||||
* If the sampler is used as a shadow sampler,
|
||||
* this field is (texture_compare_func - GL_NEVER).
|
||||
* [e.g. if compare function is GL_LEQUAL, this field is 3]
|
||||
*
|
||||
* Otherwise, this field is 0.
|
||||
*/
|
||||
GLuint texture_compare_func : 3;
|
||||
} unit[16];
|
||||
};
|
||||
|
||||
/**
|
||||
* Store usage information about an ALU instruction slot during the
|
||||
* compilation of a fragment program.
|
||||
*/
|
||||
#define SLOT_SRC_VECTOR (1<<0)
|
||||
#define SLOT_SRC_SCALAR (1<<3)
|
||||
#define SLOT_SRC_BOTH (SLOT_SRC_VECTOR | SLOT_SRC_SCALAR)
|
||||
#define SLOT_OP_VECTOR (1<<16)
|
||||
#define SLOT_OP_SCALAR (1<<17)
|
||||
#define SLOT_OP_BOTH (SLOT_OP_VECTOR | SLOT_OP_SCALAR)
|
||||
|
||||
struct r300_pfs_compile_slot {
|
||||
/* Bitmask indicating which parts of the slot are used, using SLOT_ constants
|
||||
defined above */
|
||||
unsigned int used;
|
||||
|
||||
/* Selected sources */
|
||||
int vsrc[3];
|
||||
int ssrc[3];
|
||||
};
|
||||
|
||||
/**
|
||||
* Store information during compilation of fragment programs.
|
||||
* Stores an R300 fragment program in its compiled-to-hardware form.
|
||||
*/
|
||||
struct r300_pfs_compile_state {
|
||||
int nrslots; /* number of ALU slots used so far */
|
||||
|
||||
/* Track which (parts of) slots are already filled with instructions */
|
||||
struct r300_pfs_compile_slot slot[PFS_MAX_ALU_INST];
|
||||
|
||||
/* Track the validity of R300 temporaries */
|
||||
struct reg_lifetime hwtemps[PFS_NUM_TEMP_REGS];
|
||||
|
||||
/* Used to map Mesa's inputs/temps onto hardware temps */
|
||||
int temp_in_use;
|
||||
struct reg_acc temps[PFS_NUM_TEMP_REGS];
|
||||
struct reg_acc inputs[32]; /* don't actually need 32... */
|
||||
|
||||
/* Track usage of hardware temps, for register allocation,
|
||||
* indirection detection, etc. */
|
||||
GLuint used_in_node;
|
||||
GLuint dest_in_node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Store everything about a fragment program that is needed
|
||||
* to render with that program.
|
||||
*/
|
||||
struct r300_fragment_program {
|
||||
struct gl_fragment_program mesa_program;
|
||||
|
||||
GLcontext *ctx;
|
||||
GLboolean translated;
|
||||
GLboolean error;
|
||||
struct r300_pfs_compile_state *cs;
|
||||
|
||||
struct r300_fragment_program_code {
|
||||
struct {
|
||||
int length;
|
||||
GLuint inst[PFS_MAX_TEX_INST];
|
||||
@@ -793,19 +727,51 @@ struct r300_fragment_program {
|
||||
int const_nr;
|
||||
|
||||
int max_temp_idx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Store everything about a fragment program that is needed
|
||||
* to render with that program.
|
||||
*/
|
||||
struct r300_fragment_program {
|
||||
struct gl_fragment_program mesa_program;
|
||||
|
||||
GLboolean translated;
|
||||
GLboolean error;
|
||||
|
||||
struct r300_fragment_program_external_state state;
|
||||
struct r300_fragment_program_code code;
|
||||
|
||||
GLboolean WritesDepth;
|
||||
GLuint optimization;
|
||||
};
|
||||
|
||||
struct r500_fragment_program {
|
||||
struct gl_fragment_program mesa_program;
|
||||
struct r500_pfs_compile_state;
|
||||
|
||||
GLcontext *ctx;
|
||||
GLboolean translated;
|
||||
GLboolean error;
|
||||
struct r300_pfs_compile_state *cs;
|
||||
struct r500_fragment_program_external_state {
|
||||
struct {
|
||||
/**
|
||||
* If the sampler is used as a shadow sampler,
|
||||
* this field is:
|
||||
* 0 - GL_LUMINANCE
|
||||
* 1 - GL_INTENSITY
|
||||
* 2 - GL_ALPHA
|
||||
* depending on the depth texture mode.
|
||||
*/
|
||||
GLuint depth_texture_mode : 2;
|
||||
|
||||
/**
|
||||
* If the sampler is used as a shadow sampler,
|
||||
* this field is (texture_compare_func - GL_NEVER).
|
||||
* [e.g. if compare function is GL_LEQUAL, this field is 3]
|
||||
*
|
||||
* Otherwise, this field is 0.
|
||||
*/
|
||||
GLuint texture_compare_func : 3;
|
||||
} unit[16];
|
||||
};
|
||||
|
||||
struct r500_fragment_program_code {
|
||||
struct {
|
||||
GLuint inst0;
|
||||
GLuint inst1;
|
||||
@@ -822,17 +788,28 @@ struct r500_fragment_program {
|
||||
int inst_end;
|
||||
|
||||
/* Hardware constants.
|
||||
* Contains a pointer to the value. The destination of the pointer
|
||||
* is supposed to be updated when GL state changes.
|
||||
* Typically, this is either a pointer into
|
||||
* gl_program_parameter_list::ParameterValues, or a pointer to a
|
||||
* global constant (e.g. for sin/cos-approximation)
|
||||
*/
|
||||
* Contains a pointer to the value. The destination of the pointer
|
||||
* is supposed to be updated when GL state changes.
|
||||
* Typically, this is either a pointer into
|
||||
* gl_program_parameter_list::ParameterValues, or a pointer to a
|
||||
* global constant (e.g. for sin/cos-approximation)
|
||||
*/
|
||||
const GLfloat *constant[PFS_NUM_CONST_REGS];
|
||||
int const_nr;
|
||||
|
||||
int max_temp_idx;
|
||||
};
|
||||
|
||||
struct r500_fragment_program {
|
||||
struct gl_fragment_program mesa_program;
|
||||
|
||||
GLcontext *ctx;
|
||||
GLboolean translated;
|
||||
GLboolean error;
|
||||
|
||||
struct r500_fragment_program_external_state state;
|
||||
struct r500_fragment_program_code code;
|
||||
|
||||
GLboolean writes_depth;
|
||||
|
||||
GLuint optimization;
|
||||
@@ -849,7 +826,6 @@ struct r300_state {
|
||||
struct r300_texture_state texture;
|
||||
int sw_tcl_inputs[VERT_ATTRIB_MAX];
|
||||
struct r300_vertex_shader_state vertex_shader;
|
||||
struct r300_pfs_compile_state pfs_compile;
|
||||
struct r300_dma_region aos[R300_MAX_AOS_ARRAYS];
|
||||
int aos_count;
|
||||
|
||||
@@ -949,6 +925,7 @@ struct r300_context {
|
||||
driTextureObject swapped;
|
||||
int texture_depth;
|
||||
float initialMaxAnisotropy;
|
||||
float LODBias;
|
||||
|
||||
/* Clientdata textures;
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,12 +40,7 @@
|
||||
#include "shader/prog_instruction.h"
|
||||
|
||||
#include "r300_context.h"
|
||||
|
||||
typedef struct r300_fragment_program_swizzle {
|
||||
GLuint length;
|
||||
GLuint src[4];
|
||||
GLuint inst[8];
|
||||
} r300_fragment_program_swizzle_t;
|
||||
#include "radeon_program.h"
|
||||
|
||||
/* supported hw opcodes */
|
||||
#define PFS_OP_MAD 0
|
||||
@@ -74,25 +69,6 @@ typedef struct r300_fragment_program_swizzle {
|
||||
#define SRC_MASK (63 << 0)
|
||||
#define SRC_STRIDE 6
|
||||
|
||||
#define NOP_INST0 ( \
|
||||
(R300_ALU_OUTC_MAD) | \
|
||||
(R300_ALU_ARGC_ZERO << R300_ALU_ARG0C_SHIFT) | \
|
||||
(R300_ALU_ARGC_ZERO << R300_ALU_ARG1C_SHIFT) | \
|
||||
(R300_ALU_ARGC_ZERO << R300_ALU_ARG2C_SHIFT))
|
||||
#define NOP_INST1 ( \
|
||||
((0 | SRC_CONST) << R300_ALU_SRC0C_SHIFT) | \
|
||||
((0 | SRC_CONST) << R300_ALU_SRC1C_SHIFT) | \
|
||||
((0 | SRC_CONST) << R300_ALU_SRC2C_SHIFT))
|
||||
#define NOP_INST2 ( \
|
||||
(R300_ALU_OUTA_MAD) | \
|
||||
(R300_ALU_ARGA_ZERO << R300_ALU_ARG0A_SHIFT) | \
|
||||
(R300_ALU_ARGA_ZERO << R300_ALU_ARG1A_SHIFT) | \
|
||||
(R300_ALU_ARGA_ZERO << R300_ALU_ARG2A_SHIFT))
|
||||
#define NOP_INST3 ( \
|
||||
((0 | SRC_CONST) << R300_ALU_SRC0A_SHIFT) | \
|
||||
((0 | SRC_CONST) << R300_ALU_SRC1A_SHIFT) | \
|
||||
((0 | SRC_CONST) << R300_ALU_SRC2A_SHIFT))
|
||||
|
||||
#define DRI_CONF_FP_OPTIMIZATION_SPEED 0
|
||||
#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1
|
||||
|
||||
@@ -161,4 +137,24 @@ struct r300_fragment_program;
|
||||
extern void r300TranslateFragmentShader(r300ContextPtr r300,
|
||||
struct r300_fragment_program *fp);
|
||||
|
||||
|
||||
/**
|
||||
* Used internally by the r300 fragment program code to store compile-time
|
||||
* only data.
|
||||
*/
|
||||
struct r300_fragment_program_compiler {
|
||||
r300ContextPtr r300;
|
||||
struct r300_fragment_program *fp;
|
||||
struct r300_fragment_program_code *code;
|
||||
struct radeon_compiler compiler;
|
||||
};
|
||||
|
||||
extern void r300FPTransformTextures(struct r300_fragment_program_compiler *compiler);
|
||||
extern GLboolean r300FragmentProgramEmit(struct r300_fragment_program_compiler *compiler);
|
||||
|
||||
|
||||
extern void r300FragmentProgramDump(
|
||||
struct r300_fragment_program *fp,
|
||||
struct r300_fragment_program_code *code);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -54,6 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "r300_vertprog.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "r300_emit.h"
|
||||
#include "r300_fragprog.h"
|
||||
|
||||
#include "vblank.h"
|
||||
|
||||
@@ -130,8 +131,6 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
|
||||
t1 |= R300_Z_ENABLE | R300_Z_WRITE_ENABLE;
|
||||
t2 |=
|
||||
(R300_ZS_ALWAYS << R300_Z_FUNC_SHIFT);
|
||||
} else { //XXX
|
||||
t1 |= R300_STENCIL_FRONT_BACK; // disable
|
||||
}
|
||||
|
||||
if (flags & CLEARBUFFER_STENCIL) {
|
||||
@@ -144,20 +143,13 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
|
||||
(R300_ZS_REPLACE <<
|
||||
R300_S_FRONT_ZPASS_OP_SHIFT) |
|
||||
(R300_ZS_REPLACE <<
|
||||
R300_S_FRONT_ZFAIL_OP_SHIFT) |
|
||||
(R300_ZS_ALWAYS <<
|
||||
R300_S_BACK_FUNC_SHIFT) |
|
||||
(R300_ZS_REPLACE <<
|
||||
R300_S_BACK_SFAIL_OP_SHIFT) |
|
||||
(R300_ZS_REPLACE <<
|
||||
R300_S_BACK_ZPASS_OP_SHIFT) |
|
||||
(R300_ZS_REPLACE <<
|
||||
R300_S_BACK_ZFAIL_OP_SHIFT);
|
||||
R300_S_FRONT_ZFAIL_OP_SHIFT);
|
||||
}
|
||||
|
||||
e32(t1);
|
||||
e32(t2);
|
||||
e32(r300->state.stencil.clear);
|
||||
e32(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << R300_STENCILWRITEMASK_SHIFT) |
|
||||
(ctx->Stencil.Clear & R300_STENCILREF_MASK));
|
||||
}
|
||||
|
||||
cmd2 = (drm_r300_cmd_header_t *) r300AllocCmdBuf(r300, 9, __FUNCTION__);
|
||||
@@ -307,7 +299,6 @@ static void r300EmitClearState(GLcontext * ctx)
|
||||
reg_start(R300_RS_INST_0, 0);
|
||||
e32(R300_RS_INST_COL_CN_WRITE);
|
||||
} else {
|
||||
|
||||
R300_STATECHANGE(r300, ri);
|
||||
reg_start(R500_RS_IP_0, 7);
|
||||
for (i = 0; i < 8; ++i) {
|
||||
|
||||
@@ -1371,29 +1371,22 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
# define R300_TX_MAG_FILTER_4 (0 << 9)
|
||||
# define R300_TX_MAG_FILTER_NEAREST (1 << 9)
|
||||
# define R300_TX_MAG_FILTER_LINEAR (2 << 9)
|
||||
# define R300_TX_MAG_FILTER_ANISO (3 << 9)
|
||||
# define R300_TX_MAG_FILTER_MASK (3 << 9)
|
||||
# define R300_TX_MIN_FILTER_NEAREST (1 << 11)
|
||||
# define R300_TX_MIN_FILTER_LINEAR (2 << 11)
|
||||
# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11) /* TODO: use spec */
|
||||
# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11) /* TODO: use spec */
|
||||
# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11) /* TODO: use spec */
|
||||
# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11) /* TODO: use spec */
|
||||
|
||||
/* NOTE: NEAREST doesnt seem to exist.
|
||||
* Im not seting MAG_FILTER_MASK and (3 << 11) on for all
|
||||
* anisotropy modes because that would void selected mag filter
|
||||
*/
|
||||
# define R300_TX_MIN_FILTER_ANISO_NEAREST (0 << 13)
|
||||
# define R300_TX_MIN_FILTER_ANISO_LINEAR (0 << 13)
|
||||
# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (1 << 13)
|
||||
# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (2 << 13)
|
||||
# define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) )
|
||||
# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21)
|
||||
# define R300_TX_MAX_ANISO_2_TO_1 (2 << 21)
|
||||
# define R300_TX_MAX_ANISO_4_TO_1 (4 << 21)
|
||||
# define R300_TX_MAX_ANISO_8_TO_1 (6 << 21)
|
||||
# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21)
|
||||
# define R300_TX_MAX_ANISO_MASK (14 << 21)
|
||||
# define R300_TX_MIN_FILTER_ANISO (3 << 11)
|
||||
# define R300_TX_MIN_FILTER_MASK (3 << 11)
|
||||
# define R300_TX_MIN_FILTER_MIP_NONE (0 << 13)
|
||||
# define R300_TX_MIN_FILTER_MIP_NEAREST (1 << 13)
|
||||
# define R300_TX_MIN_FILTER_MIP_LINEAR (2 << 13)
|
||||
# define R300_TX_MIN_FILTER_MIP_MASK (3 << 13)
|
||||
# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21)
|
||||
# define R300_TX_MAX_ANISO_2_TO_1 (1 << 21)
|
||||
# define R300_TX_MAX_ANISO_4_TO_1 (2 << 21)
|
||||
# define R300_TX_MAX_ANISO_8_TO_1 (3 << 21)
|
||||
# define R300_TX_MAX_ANISO_16_TO_1 (4 << 21)
|
||||
# define R300_TX_MAX_ANISO_MASK (7 << 21)
|
||||
|
||||
#define R300_TX_FILTER1_0 0x4440
|
||||
# define R300_CHROMA_KEY_MODE_DISABLE 0
|
||||
@@ -1401,7 +1394,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
# define R300_CHROMA_KEY_BLEND 2
|
||||
# define R300_MC_ROUND_NORMAL (0<<2)
|
||||
# define R300_MC_ROUND_MPEG4 (1<<2)
|
||||
# define R300_LOD_BIAS_MASK 0x1fff
|
||||
# define R300_LOD_BIAS_SHIFT 3
|
||||
# define R300_LOD_BIAS_MASK 0x1ff8
|
||||
# define R300_EDGE_ANISO_EDGE_DIAG (0<<13)
|
||||
# define R300_EDGE_ANISO_EDGE_ONLY (1<<13)
|
||||
# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14)
|
||||
@@ -1432,9 +1426,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
They are given meanings as R, G, B and Alpha by the swizzle
|
||||
specification */
|
||||
# define R300_TX_FORMAT_X8 0x0
|
||||
# define R500_TX_FORMAT_X1 0x0 // bit set in format 2
|
||||
# define R500_TX_FORMAT_X1 0x0 // bit set in format 2
|
||||
# define R300_TX_FORMAT_X16 0x1
|
||||
# define R500_TX_FORMAT_X1_REV 0x0 // bit set in format 2
|
||||
# define R500_TX_FORMAT_X1_REV 0x0 // bit set in format 2
|
||||
# define R300_TX_FORMAT_Y4X4 0x2
|
||||
# define R300_TX_FORMAT_Y8X8 0x3
|
||||
# define R300_TX_FORMAT_Y16X16 0x4
|
||||
@@ -2238,7 +2232,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_22 (1 << 1)
|
||||
# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_SAMPLE0 (0 << 2)
|
||||
# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE (1 << 2)
|
||||
|
||||
|
||||
|
||||
/* Discard src pixels less than or equal to threshold. */
|
||||
#define R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4ea0
|
||||
@@ -3179,7 +3173,7 @@ enum {
|
||||
* 2 to end: Up to 16380 dwords of vertex data.
|
||||
*/
|
||||
#define R300_PACKET3_3D_DRAW_INDX 0x00002A00
|
||||
|
||||
|
||||
|
||||
/* Specify the full set of vertex arrays as (address, stride).
|
||||
* The first parameter is the number of vertex arrays specified.
|
||||
@@ -3209,7 +3203,7 @@ enum {
|
||||
/* Same as R300_PACKET3_3D_DRAW_INDX but without VAP_VTX_FMT */
|
||||
#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600
|
||||
|
||||
/* Clears a portion of hierachical Z RAM
|
||||
/* Clears a portion of hierachical Z RAM
|
||||
* 3 dword parameters
|
||||
* 0. START
|
||||
* 1. COUNT: 13:0 (max is 0x3FFF)
|
||||
|
||||
@@ -74,6 +74,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "r300_reg.h"
|
||||
#include "r300_tex.h"
|
||||
#include "r300_emit.h"
|
||||
#include "r300_fragprog.h"
|
||||
extern int future_hw_tcl_on;
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,6 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target,
|
||||
target, id);
|
||||
} else {
|
||||
r300_fp = CALLOC_STRUCT(r300_fragment_program);
|
||||
r300_fp->ctx = ctx;
|
||||
return _mesa_init_fragment_program(ctx, &r300_fp->mesa_program,
|
||||
target, id);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "r300_state.h"
|
||||
#include "r300_reg.h"
|
||||
#include "r300_emit.h"
|
||||
#include "r300_fragprog.h"
|
||||
#include "r300_tex.h"
|
||||
|
||||
#include "drirenderbuffer.h"
|
||||
@@ -525,24 +526,15 @@ static void r300SetDepthState(GLcontext * ctx)
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
|
||||
R300_STATECHANGE(r300, zs);
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_STENCIL_ENABLE; // XXX
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_1] &=
|
||||
~(R300_ZS_MASK << R300_Z_FUNC_SHIFT);
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_STENCIL_ENABLE|R300_STENCIL_FRONT_BACK;
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_Z_FUNC_SHIFT);
|
||||
|
||||
if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER) {
|
||||
if (ctx->Depth.Test) {
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_ENABLE;
|
||||
if (ctx->Depth.Mask)
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
|
||||
R300_Z_ENABLE | R300_Z_WRITE_ENABLE | R300_STENCIL_FRONT_BACK; // XXX
|
||||
else
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_ENABLE | R300_STENCIL_FRONT_BACK; // XXX
|
||||
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_WRITE_ENABLE;
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_1] |=
|
||||
translate_func(ctx->Depth.
|
||||
Func) << R300_Z_FUNC_SHIFT;
|
||||
} else {
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_STENCIL_FRONT_BACK; // XXX
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_1] |=
|
||||
translate_func(GL_NEVER) << R300_Z_FUNC_SHIFT;
|
||||
translate_func(ctx->Depth.Func) << R300_Z_FUNC_SHIFT;
|
||||
}
|
||||
|
||||
r300SetEarlyZState(ctx);
|
||||
@@ -925,7 +917,7 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
|
||||
GLuint flag;
|
||||
|
||||
R300_STATECHANGE(rmesa, zs);
|
||||
|
||||
rmesa->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_STENCIL_FRONT_BACK;
|
||||
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~((R300_ZS_MASK <<
|
||||
R300_S_FRONT_FUNC_SHIFT)
|
||||
| (R300_ZS_MASK <<
|
||||
@@ -1000,17 +992,6 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,
|
||||
}
|
||||
}
|
||||
|
||||
static void r300ClearStencil(GLcontext * ctx, GLint s)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
|
||||
rmesa->state.stencil.clear =
|
||||
((GLuint) (ctx->Stencil.Clear & R300_STENCILREF_MASK) |
|
||||
(R300_STENCILREF_MASK << R300_STENCILMASK_SHIFT) |
|
||||
((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) <<
|
||||
R300_STENCILMASK_SHIFT));
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
* Window position and viewport transformation
|
||||
*/
|
||||
@@ -1284,7 +1265,7 @@ static unsigned long gen_fixed_filter(unsigned long f)
|
||||
return f;
|
||||
|
||||
mag = f & R300_TX_MAG_FILTER_MASK;
|
||||
min = f & R300_TX_MIN_FILTER_MASK;
|
||||
min = f & (R300_TX_MIN_FILTER_MASK|R300_TX_MIN_FILTER_MIP_MASK);
|
||||
|
||||
/* TODO: Check for anisto filters too */
|
||||
if ((mag != R300_TX_MAG_FILTER_NEAREST)
|
||||
@@ -1328,18 +1309,19 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
|
||||
int i;
|
||||
struct r300_fragment_program *fp = (struct r300_fragment_program *)
|
||||
(char *)ctx->FragmentProgram._Current;
|
||||
struct r300_fragment_program_code *code = &fp->code;
|
||||
|
||||
R300_STATECHANGE(r300, fpt);
|
||||
|
||||
for (i = 0; i < fp->tex.length; i++) {
|
||||
for (i = 0; i < code->tex.length; i++) {
|
||||
int unit;
|
||||
int opcode;
|
||||
unsigned long val;
|
||||
|
||||
unit = fp->tex.inst[i] >> R300_TEX_ID_SHIFT;
|
||||
unit = code->tex.inst[i] >> R300_TEX_ID_SHIFT;
|
||||
unit &= 15;
|
||||
|
||||
val = fp->tex.inst[i];
|
||||
val = code->tex.inst[i];
|
||||
val &= ~R300_TEX_ID_MASK;
|
||||
|
||||
opcode =
|
||||
@@ -1361,7 +1343,7 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
|
||||
}
|
||||
|
||||
r300->hw.fpt.cmd[R300_FPT_CMD_0] =
|
||||
cmdpacket0(R300_US_TEX_INST_0, fp->tex.length);
|
||||
cmdpacket0(R300_US_TEX_INST_0, code->tex.length);
|
||||
}
|
||||
|
||||
static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
|
||||
@@ -1369,14 +1351,15 @@ static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
|
||||
int i;
|
||||
struct r500_fragment_program *fp = (struct r500_fragment_program *)
|
||||
(char *)ctx->FragmentProgram._Current;
|
||||
struct r500_fragment_program_code *code = &fp->code;
|
||||
|
||||
/* find all the texture instructions and relocate the texture units */
|
||||
for (i = 0; i < fp->inst_end + 1; i++) {
|
||||
if ((fp->inst[i].inst0 & 0x3) == R500_INST_TYPE_TEX) {
|
||||
for (i = 0; i < code->inst_end + 1; i++) {
|
||||
if ((code->inst[i].inst0 & 0x3) == R500_INST_TYPE_TEX) {
|
||||
uint32_t val;
|
||||
int unit, opcode, new_unit;
|
||||
|
||||
val = fp->inst[i].inst1;
|
||||
val = code->inst[i].inst1;
|
||||
|
||||
unit = (val >> 16) & 0xf;
|
||||
|
||||
@@ -1393,11 +1376,23 @@ static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
|
||||
}
|
||||
}
|
||||
val |= R500_TEX_ID(new_unit);
|
||||
fp->inst[i].inst1 = val;
|
||||
code->inst[i].inst1 = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint r300CalculateTexLodBias(GLfloat bias)
|
||||
{
|
||||
GLuint b;
|
||||
b = (unsigned int)fabsf(ceilf(bias*31));
|
||||
if (signbit(bias)) {
|
||||
b ^= 0x3ff; /* 10 bits */
|
||||
}
|
||||
b <<= 3;
|
||||
b &= R300_LOD_BIAS_MASK;
|
||||
return b;
|
||||
}
|
||||
|
||||
static void r300SetupTextures(GLcontext * ctx)
|
||||
{
|
||||
int i, mtu;
|
||||
@@ -1461,8 +1456,8 @@ static void r300SetupTextures(GLcontext * ctx)
|
||||
r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 +
|
||||
hw_tmu] =
|
||||
gen_fixed_filter(t->filter) | (hw_tmu << 28);
|
||||
/* Currently disabled! */
|
||||
r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; //0x20501f80;
|
||||
r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->filter_1
|
||||
| r300CalculateTexLodBias(r300->LODBias);
|
||||
r300->hw.tex.size.cmd[R300_TEX_VALUE_0 + hw_tmu] =
|
||||
t->size;
|
||||
r300->hw.tex.format.cmd[R300_TEX_VALUE_0 +
|
||||
@@ -2426,6 +2421,7 @@ static void r300SetupPixelShader(r300ContextPtr rmesa)
|
||||
GLcontext *ctx = rmesa->radeon.glCtx;
|
||||
struct r300_fragment_program *fp = (struct r300_fragment_program *)
|
||||
(char *)ctx->FragmentProgram._Current;
|
||||
struct r300_fragment_program_code *code;
|
||||
int i, k;
|
||||
|
||||
if (!fp) /* should only happenen once, just after context is created */
|
||||
@@ -2437,62 +2433,63 @@ static void r300SetupPixelShader(r300ContextPtr rmesa)
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
code = &fp->code;
|
||||
|
||||
r300SetupTextures(ctx);
|
||||
|
||||
R300_STATECHANGE(rmesa, fpi[0]);
|
||||
rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, fp->alu_end + 1);
|
||||
for (i = 0; i <= fp->alu_end; i++) {
|
||||
rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst0;
|
||||
rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, code->alu_end + 1);
|
||||
for (i = 0; i <= code->alu_end; i++) {
|
||||
rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst0;
|
||||
}
|
||||
|
||||
R300_STATECHANGE(rmesa, fpi[1]);
|
||||
rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, fp->alu_end + 1);
|
||||
for (i = 0; i <= fp->alu_end; i++) {
|
||||
rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst1;
|
||||
rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, code->alu_end + 1);
|
||||
for (i = 0; i <= code->alu_end; i++) {
|
||||
rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst1;
|
||||
}
|
||||
|
||||
R300_STATECHANGE(rmesa, fpi[2]);
|
||||
rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, fp->alu_end + 1);
|
||||
for (i = 0; i <= fp->alu_end; i++) {
|
||||
rmesa->hw.fpi[2].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst2;
|
||||
rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, code->alu_end + 1);
|
||||
for (i = 0; i <= code->alu_end; i++) {
|
||||
rmesa->hw.fpi[2].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst2;
|
||||
}
|
||||
|
||||
R300_STATECHANGE(rmesa, fpi[3]);
|
||||
rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, fp->alu_end + 1);
|
||||
for (i = 0; i <= fp->alu_end; i++) {
|
||||
rmesa->hw.fpi[3].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst3;
|
||||
rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, code->alu_end + 1);
|
||||
for (i = 0; i <= code->alu_end; i++) {
|
||||
rmesa->hw.fpi[3].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst3;
|
||||
}
|
||||
|
||||
R300_STATECHANGE(rmesa, fp);
|
||||
rmesa->hw.fp.cmd[R300_FP_CNTL0] = fp->cur_node | (fp->first_node_has_tex << 3);
|
||||
rmesa->hw.fp.cmd[R300_FP_CNTL1] = fp->max_temp_idx;
|
||||
rmesa->hw.fp.cmd[R300_FP_CNTL0] = code->cur_node | (code->first_node_has_tex << 3);
|
||||
rmesa->hw.fp.cmd[R300_FP_CNTL1] = code->max_temp_idx;
|
||||
rmesa->hw.fp.cmd[R300_FP_CNTL2] =
|
||||
(fp->alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT) |
|
||||
(fp->alu_end << R300_PFS_CNTL_ALU_END_SHIFT) |
|
||||
(fp->tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT) |
|
||||
(fp->tex_end << R300_PFS_CNTL_TEX_END_SHIFT);
|
||||
(code->alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT) |
|
||||
(code->alu_end << R300_PFS_CNTL_ALU_END_SHIFT) |
|
||||
(code->tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT) |
|
||||
(code->tex_end << R300_PFS_CNTL_TEX_END_SHIFT);
|
||||
/* I just want to say, the way these nodes are stored.. weird.. */
|
||||
for (i = 0, k = (4 - (fp->cur_node + 1)); i < 4; i++, k++) {
|
||||
if (i < (fp->cur_node + 1)) {
|
||||
for (i = 0, k = (4 - (code->cur_node + 1)); i < 4; i++, k++) {
|
||||
if (i < (code->cur_node + 1)) {
|
||||
rmesa->hw.fp.cmd[R300_FP_NODE0 + k] =
|
||||
(fp->node[i].alu_offset << R300_ALU_START_SHIFT) |
|
||||
(fp->node[i].alu_end << R300_ALU_SIZE_SHIFT) |
|
||||
(fp->node[i].tex_offset << R300_TEX_START_SHIFT) |
|
||||
(fp->node[i].tex_end << R300_TEX_SIZE_SHIFT) |
|
||||
fp->node[i].flags;
|
||||
(code->node[i].alu_offset << R300_ALU_START_SHIFT) |
|
||||
(code->node[i].alu_end << R300_ALU_SIZE_SHIFT) |
|
||||
(code->node[i].tex_offset << R300_TEX_START_SHIFT) |
|
||||
(code->node[i].tex_end << R300_TEX_SIZE_SHIFT) |
|
||||
code->node[i].flags;
|
||||
} else {
|
||||
rmesa->hw.fp.cmd[R300_FP_NODE0 + (3 - i)] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
R300_STATECHANGE(rmesa, fpp);
|
||||
rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, fp->const_nr * 4);
|
||||
for (i = 0; i < fp->const_nr; i++) {
|
||||
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(fp->constant[i][0]);
|
||||
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(fp->constant[i][1]);
|
||||
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(fp->constant[i][2]);
|
||||
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat24(fp->constant[i][3]);
|
||||
rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, code->const_nr * 4);
|
||||
for (i = 0; i < code->const_nr; i++) {
|
||||
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(code->constant[i][0]);
|
||||
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(code->constant[i][1]);
|
||||
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(code->constant[i][2]);
|
||||
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat24(code->constant[i][3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2516,6 +2513,7 @@ static void r500SetupPixelShader(r300ContextPtr rmesa)
|
||||
struct r500_fragment_program *fp = (struct r500_fragment_program *)
|
||||
(char *)ctx->FragmentProgram._Current;
|
||||
int i;
|
||||
struct r500_fragment_program_code *code;
|
||||
|
||||
if (!fp) /* should only happenen once, just after context is created */
|
||||
return;
|
||||
@@ -2529,42 +2527,43 @@ static void r500SetupPixelShader(r300ContextPtr rmesa)
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
code = &fp->code;
|
||||
|
||||
r300SetupTextures(ctx);
|
||||
|
||||
R300_STATECHANGE(rmesa, fp);
|
||||
rmesa->hw.fp.cmd[R500_FP_PIXSIZE] = fp->max_temp_idx;
|
||||
rmesa->hw.fp.cmd[R500_FP_PIXSIZE] = code->max_temp_idx;
|
||||
|
||||
rmesa->hw.fp.cmd[R500_FP_CODE_ADDR] =
|
||||
R500_US_CODE_START_ADDR(fp->inst_offset) |
|
||||
R500_US_CODE_END_ADDR(fp->inst_end);
|
||||
R500_US_CODE_START_ADDR(code->inst_offset) |
|
||||
R500_US_CODE_END_ADDR(code->inst_end);
|
||||
rmesa->hw.fp.cmd[R500_FP_CODE_RANGE] =
|
||||
R500_US_CODE_RANGE_ADDR(fp->inst_offset) |
|
||||
R500_US_CODE_RANGE_SIZE(fp->inst_end);
|
||||
R500_US_CODE_RANGE_ADDR(code->inst_offset) |
|
||||
R500_US_CODE_RANGE_SIZE(code->inst_end);
|
||||
rmesa->hw.fp.cmd[R500_FP_CODE_OFFSET] =
|
||||
R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
|
||||
|
||||
R300_STATECHANGE(rmesa, r500fp);
|
||||
/* Emit our shader... */
|
||||
for (i = 0; i < fp->inst_end+1; i++) {
|
||||
rmesa->hw.r500fp.cmd[i*6+1] = fp->inst[i].inst0;
|
||||
rmesa->hw.r500fp.cmd[i*6+2] = fp->inst[i].inst1;
|
||||
rmesa->hw.r500fp.cmd[i*6+3] = fp->inst[i].inst2;
|
||||
rmesa->hw.r500fp.cmd[i*6+4] = fp->inst[i].inst3;
|
||||
rmesa->hw.r500fp.cmd[i*6+5] = fp->inst[i].inst4;
|
||||
rmesa->hw.r500fp.cmd[i*6+6] = fp->inst[i].inst5;
|
||||
for (i = 0; i < code->inst_end+1; i++) {
|
||||
rmesa->hw.r500fp.cmd[i*6+1] = code->inst[i].inst0;
|
||||
rmesa->hw.r500fp.cmd[i*6+2] = code->inst[i].inst1;
|
||||
rmesa->hw.r500fp.cmd[i*6+3] = code->inst[i].inst2;
|
||||
rmesa->hw.r500fp.cmd[i*6+4] = code->inst[i].inst3;
|
||||
rmesa->hw.r500fp.cmd[i*6+5] = code->inst[i].inst4;
|
||||
rmesa->hw.r500fp.cmd[i*6+6] = code->inst[i].inst5;
|
||||
}
|
||||
|
||||
bump_r500fp_count(rmesa->hw.r500fp.cmd, (fp->inst_end + 1) * 6);
|
||||
bump_r500fp_count(rmesa->hw.r500fp.cmd, (code->inst_end + 1) * 6);
|
||||
|
||||
R300_STATECHANGE(rmesa, r500fp_const);
|
||||
for (i = 0; i < fp->const_nr; i++) {
|
||||
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(fp->constant[i][0]);
|
||||
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(fp->constant[i][1]);
|
||||
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(fp->constant[i][2]);
|
||||
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat32(fp->constant[i][3]);
|
||||
for (i = 0; i < code->const_nr; i++) {
|
||||
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(code->constant[i][0]);
|
||||
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(code->constant[i][1]);
|
||||
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(code->constant[i][2]);
|
||||
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat32(code->constant[i][3]);
|
||||
}
|
||||
bump_r500fp_const_count(rmesa->hw.r500fp_const.cmd, fp->const_nr * 4);
|
||||
bump_r500fp_const_count(rmesa->hw.r500fp_const.cmd, code->const_nr * 4);
|
||||
|
||||
}
|
||||
|
||||
@@ -2637,12 +2636,10 @@ void r300InitState(r300ContextPtr r300)
|
||||
case 16:
|
||||
r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
|
||||
depth_fmt = R300_DEPTHFORMAT_16BIT_INT_Z;
|
||||
r300->state.stencil.clear = 0x00000000;
|
||||
break;
|
||||
case 24:
|
||||
r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
|
||||
depth_fmt = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
|
||||
r300->state.stencil.clear = 0x00ff0000;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
|
||||
@@ -2706,7 +2703,6 @@ void r300InitStateFuncs(struct dd_function_table *functions)
|
||||
functions->ShadeModel = r300ShadeModel;
|
||||
|
||||
/* Stencil related */
|
||||
functions->ClearStencil = r300ClearStencil;
|
||||
functions->StencilFuncSeparate = r300StencilFuncSeparate;
|
||||
functions->StencilMaskSeparate = r300StencilMaskSeparate;
|
||||
functions->StencilOpSeparate = r300StencilOpSeparate;
|
||||
|
||||
@@ -160,21 +160,18 @@ static void r300SetTexWrap(r300TexObjPtr t, GLenum swrap, GLenum twrap,
|
||||
t->filter |= hw_qwrap << R300_TX_WRAP_Q_SHIFT;
|
||||
}
|
||||
|
||||
static void r300SetTexMaxAnisotropy(r300TexObjPtr t, GLfloat max)
|
||||
static GLuint aniso_filter(GLfloat anisotropy)
|
||||
{
|
||||
|
||||
t->filter &= ~R300_TX_MAX_ANISO_MASK;
|
||||
|
||||
if (max <= 1.0) {
|
||||
t->filter |= R300_TX_MAX_ANISO_1_TO_1;
|
||||
} else if (max <= 2.0) {
|
||||
t->filter |= R300_TX_MAX_ANISO_2_TO_1;
|
||||
} else if (max <= 4.0) {
|
||||
t->filter |= R300_TX_MAX_ANISO_4_TO_1;
|
||||
} else if (max <= 8.0) {
|
||||
t->filter |= R300_TX_MAX_ANISO_8_TO_1;
|
||||
if (anisotropy >= 16.0) {
|
||||
return R300_TX_MAX_ANISO_16_TO_1;
|
||||
} else if (anisotropy >= 8.0) {
|
||||
return R300_TX_MAX_ANISO_8_TO_1;
|
||||
} else if (anisotropy >= 4.0) {
|
||||
return R300_TX_MAX_ANISO_4_TO_1;
|
||||
} else if (anisotropy >= 2.0) {
|
||||
return R300_TX_MAX_ANISO_2_TO_1;
|
||||
} else {
|
||||
t->filter |= R300_TX_MAX_ANISO_16_TO_1;
|
||||
return R300_TX_MAX_ANISO_1_TO_1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,54 +181,47 @@ static void r300SetTexMaxAnisotropy(r300TexObjPtr t, GLfloat max)
|
||||
* \param t Texture whose filter modes are to be set
|
||||
* \param minf Texture minification mode
|
||||
* \param magf Texture magnification mode
|
||||
* \param anisotropy Maximum anisotropy level
|
||||
*/
|
||||
|
||||
static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf)
|
||||
static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy)
|
||||
{
|
||||
GLuint anisotropy = (t->filter & R300_TX_MAX_ANISO_MASK);
|
||||
t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK);
|
||||
t->filter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY;
|
||||
|
||||
t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MAG_FILTER_MASK);
|
||||
/* Note that EXT_texture_filter_anisotropic is extremely vague about
|
||||
* how anisotropic filtering interacts with the "normal" filter modes.
|
||||
* When anisotropic filtering is enabled, we override min and mag
|
||||
* filter settings completely. This includes driconf's settings.
|
||||
*/
|
||||
if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) {
|
||||
t->filter |= R300_TX_MAG_FILTER_ANISO
|
||||
| R300_TX_MIN_FILTER_ANISO
|
||||
| R300_TX_MIN_FILTER_MIP_LINEAR
|
||||
| aniso_filter(anisotropy);
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "Using maximum anisotropy of %f\n", anisotropy);
|
||||
return;
|
||||
}
|
||||
|
||||
if (anisotropy == R300_TX_MAX_ANISO_1_TO_1) {
|
||||
switch (minf) {
|
||||
case GL_NEAREST:
|
||||
t->filter |= R300_TX_MIN_FILTER_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->filter |= R300_TX_MIN_FILTER_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
t->filter |= R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
t->filter |= R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
t->filter |= R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
t->filter |= R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (minf) {
|
||||
case GL_NEAREST:
|
||||
t->filter |= R300_TX_MIN_FILTER_ANISO_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->filter |= R300_TX_MIN_FILTER_ANISO_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
t->filter |=
|
||||
R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
t->filter |=
|
||||
R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR;
|
||||
break;
|
||||
}
|
||||
switch (minf) {
|
||||
case GL_NEAREST:
|
||||
t->filter |= R300_TX_MIN_FILTER_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->filter |= R300_TX_MIN_FILTER_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_LINEAR;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_LINEAR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Note we don't have 3D mipmaps so only use the mag filter setting
|
||||
@@ -252,6 +242,20 @@ static void r300SetTexBorderColor(r300TexObjPtr t, GLubyte c[4])
|
||||
t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
|
||||
}
|
||||
|
||||
static void r300SetTexLodBias(r300TexObjPtr t, GLfloat bias)
|
||||
{
|
||||
GLuint b;
|
||||
b = (unsigned int)fabsf(ceilf(bias*31));
|
||||
if (signbit(bias)) {
|
||||
b ^= 0x3ff; /* 10 bits */
|
||||
}
|
||||
b <<= 3;
|
||||
b &= R300_LOD_BIAS_MASK;
|
||||
|
||||
t->filter_1 &= ~R300_LOD_BIAS_MASK;
|
||||
t->filter_1 |= b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate space for and load the mesa images into the texture memory block.
|
||||
* This will happen before drawing with a new texture, or drawing with a
|
||||
@@ -278,8 +282,7 @@ static r300TexObjPtr r300AllocTexObj(struct gl_texture_object *texObj)
|
||||
make_empty_list(&t->base);
|
||||
|
||||
r300SetTexWrap(t, texObj->WrapS, texObj->WrapT, texObj->WrapR);
|
||||
r300SetTexMaxAnisotropy(t, texObj->MaxAnisotropy);
|
||||
r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter);
|
||||
r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
|
||||
r300SetTexBorderColor(t, texObj->_BorderChan);
|
||||
}
|
||||
|
||||
@@ -976,9 +979,38 @@ r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
|
||||
t->dirty_images[0] |= (1 << level);
|
||||
}
|
||||
|
||||
/* This feels like a prime target for code reuse, so I'm putting it here
|
||||
* instead of inlining it in TexEnv. */
|
||||
static GLenum r300TexUnitTarget(struct gl_texture_unit *unit) {
|
||||
if (unit->_ReallyEnabled & (TEXTURE_RECT_BIT)) {
|
||||
return GL_TEXTURE_RECTANGLE_NV;
|
||||
} else if (unit->_ReallyEnabled & (TEXTURE_1D_BIT)) {
|
||||
return GL_TEXTURE_1D;
|
||||
} else if (unit->_ReallyEnabled & (TEXTURE_2D_BIT)) {
|
||||
return GL_TEXTURE_2D;
|
||||
} else if (unit->_ReallyEnabled & (TEXTURE_3D_BIT)) {
|
||||
return GL_TEXTURE_3D;
|
||||
} else if (unit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) {
|
||||
return GL_TEXTURE_CUBE_MAP;
|
||||
}
|
||||
if (unit->Enabled & (TEXTURE_RECT_BIT)) {
|
||||
return GL_TEXTURE_RECTANGLE_NV;
|
||||
} else if (unit->Enabled & (TEXTURE_1D_BIT)) {
|
||||
return GL_TEXTURE_1D;
|
||||
} else if (unit->Enabled & (TEXTURE_2D_BIT)) {
|
||||
return GL_TEXTURE_2D;
|
||||
} else if (unit->Enabled & (TEXTURE_3D_BIT)) {
|
||||
return GL_TEXTURE_3D;
|
||||
} else if (unit->Enabled & (TEXTURE_CUBE_BIT)) {
|
||||
return GL_TEXTURE_CUBE_MAP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void r300TexEnv(GLcontext * ctx, GLenum target,
|
||||
GLenum pname, const GLfloat * param)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
if (RADEON_DEBUG & DEBUG_STATE) {
|
||||
fprintf(stderr, "%s( %s )\n",
|
||||
__FUNCTION__, _mesa_lookup_enum_by_nr(pname));
|
||||
@@ -989,41 +1021,24 @@ static void r300TexEnv(GLcontext * ctx, GLenum target,
|
||||
* between them according to _ReallyEnabled.
|
||||
*/
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_LOD_BIAS_EXT:{
|
||||
#if 0 /* Needs to be relocated in order to make sure we got the right tmu */
|
||||
GLfloat bias, min;
|
||||
GLuint b;
|
||||
case GL_TEXTURE_LOD_BIAS_EXT: {
|
||||
/* Needs to be relocated in order to make sure we got the right tmu */
|
||||
GLfloat bias, min;
|
||||
|
||||
/* The R300's LOD bias is a signed 2's complement value with a
|
||||
* range of -16.0 <= bias < 16.0.
|
||||
*
|
||||
* NOTE: Add a small bias to the bias for conform mipsel.c test.
|
||||
*/
|
||||
bias = *param + .01;
|
||||
min =
|
||||
driQueryOptionb(&rmesa->radeon.optionCache,
|
||||
"no_neg_lod_bias") ? 0.0 : -16.0;
|
||||
bias = CLAMP(bias, min, 16.0);
|
||||
/* The R300's LOD bias is a signed 2's complement value with a
|
||||
* range of -16.0 <= bias < 16.0.
|
||||
*
|
||||
* NOTE: Add a small bias to the bias for conform mipsel.c test.
|
||||
*/
|
||||
bias = *param + .01;
|
||||
min = driQueryOptionb(&rmesa->radeon.optionCache,
|
||||
"no_neg_lod_bias") ? 0.0 : -16.0;
|
||||
bias = CLAMP(bias, min, 16.0);
|
||||
|
||||
/* 0.0 - 16.0 == 0x0 - 0x1000 */
|
||||
/* 0.0 - -16.0 == 0x1001 - 0x1fff */
|
||||
b = 0x1000 / 16.0 * bias;
|
||||
b &= R300_LOD_BIAS_MASK;
|
||||
rmesa->LODBias = bias;
|
||||
|
||||
if (b !=
|
||||
(rmesa->hw.tex.unknown1.
|
||||
cmd[R300_TEX_VALUE_0 +
|
||||
unit] & R300_LOD_BIAS_MASK)) {
|
||||
R300_STATECHANGE(rmesa, tex.unknown1);
|
||||
rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0 +
|
||||
unit] &=
|
||||
~R300_LOD_BIAS_MASK;
|
||||
rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0 +
|
||||
unit] |= b;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
@@ -1050,8 +1065,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
|
||||
case GL_TEXTURE_MIN_FILTER:
|
||||
case GL_TEXTURE_MAG_FILTER:
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
r300SetTexMaxAnisotropy(t, texObj->MaxAnisotropy);
|
||||
r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter);
|
||||
r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_WRAP_S:
|
||||
@@ -1077,7 +1091,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
|
||||
break;
|
||||
|
||||
case GL_DEPTH_TEXTURE_MODE:
|
||||
if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat
|
||||
if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat
|
||||
== GL_DEPTH_COMPONENT) {
|
||||
r300SetDepthTexMode(texObj);
|
||||
break;
|
||||
@@ -1092,10 +1106,6 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark this texobj as dirty (one bit per tex unit)
|
||||
*/
|
||||
t->dirty_state = TEX_ALL;
|
||||
}
|
||||
|
||||
static void r300BindTexture(GLcontext * ctx, GLenum target,
|
||||
@@ -1157,6 +1167,10 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
|
||||
return NULL;
|
||||
obj->MaxAnisotropy = rmesa->initialMaxAnisotropy;
|
||||
|
||||
/* Attempt to fill LOD bias, if previously set.
|
||||
* Should start at 0.0, which won't affect the HW. */
|
||||
obj->LodBias = rmesa->LODBias;
|
||||
|
||||
r300AllocTexObj(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ static void r300UploadSubImage(r300ContextPtr rmesa, r300TexObjPtr t,
|
||||
imageWidth = texImage->Width;
|
||||
imageHeight = texImage->Height;
|
||||
|
||||
offset = t->bufAddr + t->base.totalSize / 6 * face;
|
||||
offset = t->bufAddr;
|
||||
|
||||
if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) {
|
||||
GLint imageX = 0;
|
||||
@@ -534,10 +534,6 @@ int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face)
|
||||
/* hope it's safe to add that here... */
|
||||
t->offset |= t->tile_bits;
|
||||
}
|
||||
|
||||
/* Mark this texobj as dirty on all units:
|
||||
*/
|
||||
t->dirty_state = TEX_ALL;
|
||||
}
|
||||
|
||||
/* Let the world know we've used this memory recently.
|
||||
|
||||
@@ -127,18 +127,18 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
|
||||
{
|
||||
static const GLuint formats[3][3] = {
|
||||
{
|
||||
R300_EASY_TX_FORMAT(X, X, X, X, X16),
|
||||
R300_EASY_TX_FORMAT(X, X, X, ONE, X16),
|
||||
R300_EASY_TX_FORMAT(X, X, X, X, X16),
|
||||
R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
|
||||
},
|
||||
{
|
||||
R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
|
||||
R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
|
||||
R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
|
||||
R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
|
||||
},
|
||||
{
|
||||
R300_EASY_TX_FORMAT(X, X, X, X, X32),
|
||||
R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
|
||||
R300_EASY_TX_FORMAT(X, X, X, X, X32),
|
||||
R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32),
|
||||
},
|
||||
};
|
||||
@@ -189,6 +189,112 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute sizes and fill in offset and blit information for the given
|
||||
* image (determined by \p face and \p level).
|
||||
*
|
||||
* \param curOffset points to the offset at which the image is to be stored
|
||||
* and is updated by this function according to the size of the image.
|
||||
*/
|
||||
static void compute_tex_image_offset(
|
||||
struct gl_texture_object *tObj,
|
||||
GLuint face,
|
||||
GLint level,
|
||||
GLint* curOffset)
|
||||
{
|
||||
r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
||||
const struct gl_texture_image* texImage;
|
||||
GLuint blitWidth = R300_BLIT_WIDTH_BYTES;
|
||||
GLuint texelBytes;
|
||||
GLuint size;
|
||||
|
||||
texImage = tObj->Image[0][level + t->base.firstLevel];
|
||||
if (!texImage)
|
||||
return;
|
||||
|
||||
texelBytes = texImage->TexFormat->TexelBytes;
|
||||
|
||||
/* find image size in bytes */
|
||||
if (texImage->IsCompressed) {
|
||||
if ((t->format & R300_TX_FORMAT_DXT1) ==
|
||||
R300_TX_FORMAT_DXT1) {
|
||||
// fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
|
||||
if ((texImage->Width + 3) < 8) /* width one block */
|
||||
size = texImage->CompressedSize * 4;
|
||||
else if ((texImage->Width + 3) < 16)
|
||||
size = texImage->CompressedSize * 2;
|
||||
else
|
||||
size = texImage->CompressedSize;
|
||||
} else {
|
||||
/* DXT3/5, 16 bytes per block */
|
||||
WARN_ONCE
|
||||
("DXT 3/5 suffers from multitexturing problems!\n");
|
||||
// fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
|
||||
if ((texImage->Width + 3) < 8)
|
||||
size = texImage->CompressedSize * 2;
|
||||
else
|
||||
size = texImage->CompressedSize;
|
||||
}
|
||||
} else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
size =
|
||||
((texImage->Width * texelBytes +
|
||||
63) & ~63) * texImage->Height;
|
||||
blitWidth = 64 / texelBytes;
|
||||
} else if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
||||
/* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
|
||||
though the actual offset may be different (if texture is less than
|
||||
32 bytes width) to the untiled case */
|
||||
int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
|
||||
size =
|
||||
(w * ((texImage->Height + 1) / 2)) *
|
||||
texImage->Depth;
|
||||
blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
||||
} else {
|
||||
int w = (texImage->Width * texelBytes + 31) & ~31;
|
||||
size = w * texImage->Height * texImage->Depth;
|
||||
blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
||||
}
|
||||
assert(size > 0);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
|
||||
texImage->Width, texImage->Height,
|
||||
texImage->Depth,
|
||||
texImage->TexFormat->TexelBytes,
|
||||
texImage->InternalFormat);
|
||||
|
||||
/* All images are aligned to a 32-byte offset */
|
||||
*curOffset = (*curOffset + 0x1f) & ~0x1f;
|
||||
|
||||
if (texelBytes) {
|
||||
/* fix x and y coords up later together with offset */
|
||||
t->image[face][level].x = *curOffset;
|
||||
t->image[face][level].y = 0;
|
||||
t->image[face][level].width =
|
||||
MIN2(size / texelBytes, blitWidth);
|
||||
t->image[face][level].height =
|
||||
(size / texelBytes) / t->image[face][level].width;
|
||||
} else {
|
||||
t->image[face][level].x = *curOffset % R300_BLIT_WIDTH_BYTES;
|
||||
t->image[face][level].y = *curOffset / R300_BLIT_WIDTH_BYTES;
|
||||
t->image[face][level].width =
|
||||
MIN2(size, R300_BLIT_WIDTH_BYTES);
|
||||
t->image[face][level].height = size / t->image[face][level].width;
|
||||
}
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr,
|
||||
"level %d, face %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
|
||||
level, face, texImage->Width, texImage->Height,
|
||||
t->image[face][level].x, t->image[face][level].y,
|
||||
t->image[face][level].width, t->image[face][level].height,
|
||||
size, *curOffset);
|
||||
|
||||
*curOffset += size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function computes the number of bytes of storage needed for
|
||||
* the given texture object (all mipmap levels, all cube faces).
|
||||
@@ -206,7 +312,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
||||
r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
||||
const struct gl_texture_image *baseImage =
|
||||
tObj->Image[0][tObj->BaseLevel];
|
||||
GLint curOffset, blitWidth;
|
||||
GLint curOffset;
|
||||
GLint i, texelBytes;
|
||||
GLint numLevels;
|
||||
GLint log2Width, log2Height, log2Depth;
|
||||
@@ -245,8 +351,6 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
||||
* The idea is that we lay out the mipmap levels within a block of
|
||||
* memory organized as a rectangle of width BLIT_WIDTH_BYTES.
|
||||
*/
|
||||
curOffset = 0;
|
||||
blitWidth = R300_BLIT_WIDTH_BYTES;
|
||||
t->tile_bits = 0;
|
||||
|
||||
/* figure out if this texture is suitable for tiling. */
|
||||
@@ -276,94 +380,20 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < numLevels; i++) {
|
||||
const struct gl_texture_image *texImage;
|
||||
GLuint size;
|
||||
curOffset = 0;
|
||||
|
||||
texImage = tObj->Image[0][i + t->base.firstLevel];
|
||||
if (!texImage)
|
||||
break;
|
||||
if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
|
||||
ASSERT(log2Width == log2Height);
|
||||
t->format |= R300_TX_FORMAT_CUBIC_MAP;
|
||||
|
||||
/* find image size in bytes */
|
||||
if (texImage->IsCompressed) {
|
||||
if ((t->format & R300_TX_FORMAT_DXT1) ==
|
||||
R300_TX_FORMAT_DXT1) {
|
||||
// fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
|
||||
if ((texImage->Width + 3) < 8) /* width one block */
|
||||
size = texImage->CompressedSize * 4;
|
||||
else if ((texImage->Width + 3) < 16)
|
||||
size = texImage->CompressedSize * 2;
|
||||
else
|
||||
size = texImage->CompressedSize;
|
||||
} else {
|
||||
/* DXT3/5, 16 bytes per block */
|
||||
WARN_ONCE
|
||||
("DXT 3/5 suffers from multitexturing problems!\n");
|
||||
// fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
|
||||
if ((texImage->Width + 3) < 8)
|
||||
size = texImage->CompressedSize * 2;
|
||||
else
|
||||
size = texImage->CompressedSize;
|
||||
}
|
||||
} else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
size =
|
||||
((texImage->Width * texelBytes +
|
||||
63) & ~63) * texImage->Height;
|
||||
blitWidth = 64 / texelBytes;
|
||||
} else if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
||||
/* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
|
||||
though the actual offset may be different (if texture is less than
|
||||
32 bytes width) to the untiled case */
|
||||
int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
|
||||
size =
|
||||
(w * ((texImage->Height + 1) / 2)) *
|
||||
texImage->Depth;
|
||||
blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
||||
} else {
|
||||
int w = (texImage->Width * texelBytes + 31) & ~31;
|
||||
size = w * texImage->Height * texImage->Depth;
|
||||
blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
||||
for(i = 0; i < numLevels; i++) {
|
||||
GLuint face;
|
||||
for(face = 0; face < 6; face++)
|
||||
compute_tex_image_offset(tObj, face, i, &curOffset);
|
||||
}
|
||||
assert(size > 0);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
|
||||
texImage->Width, texImage->Height,
|
||||
texImage->Depth,
|
||||
texImage->TexFormat->TexelBytes,
|
||||
texImage->InternalFormat);
|
||||
|
||||
/* Align to 32-byte offset. It is faster to do this unconditionally
|
||||
* (no branch penalty).
|
||||
*/
|
||||
|
||||
curOffset = (curOffset + 0x1f) & ~0x1f;
|
||||
|
||||
if (texelBytes) {
|
||||
/* fix x and y coords up later together with offset */
|
||||
t->image[0][i].x = curOffset;
|
||||
t->image[0][i].y = 0;
|
||||
t->image[0][i].width =
|
||||
MIN2(size / texelBytes, blitWidth);
|
||||
t->image[0][i].height =
|
||||
(size / texelBytes) / t->image[0][i].width;
|
||||
} else {
|
||||
t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
|
||||
t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
|
||||
t->image[0][i].width =
|
||||
MIN2(size, R300_BLIT_WIDTH_BYTES);
|
||||
t->image[0][i].height = size / t->image[0][i].width;
|
||||
}
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr,
|
||||
"level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
|
||||
i, texImage->Width, texImage->Height,
|
||||
t->image[0][i].x, t->image[0][i].y,
|
||||
t->image[0][i].width, t->image[0][i].height,
|
||||
size, curOffset);
|
||||
|
||||
curOffset += size;
|
||||
} else {
|
||||
for (i = 0; i < numLevels; i++)
|
||||
compute_tex_image_offset(tObj, 0, i, &curOffset);
|
||||
}
|
||||
|
||||
/* Align the total size of texture memory block.
|
||||
@@ -371,26 +401,6 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
||||
t->base.totalSize =
|
||||
(curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
|
||||
|
||||
/* Setup remaining cube face blits, if needed */
|
||||
if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
|
||||
GLuint face;
|
||||
for (face = 1; face < 6; face++) {
|
||||
for (i = 0; i < numLevels; i++) {
|
||||
t->image[face][i].x = t->image[0][i].x;
|
||||
t->image[face][i].y = t->image[0][i].y;
|
||||
t->image[face][i].width = t->image[0][i].width;
|
||||
t->image[face][i].height =
|
||||
t->image[0][i].height;
|
||||
}
|
||||
}
|
||||
t->base.totalSize *= 6; /* total texmem needed */
|
||||
}
|
||||
|
||||
if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
|
||||
ASSERT(log2Width == log2Height);
|
||||
t->format |= R300_TX_FORMAT_CUBIC_MAP;
|
||||
}
|
||||
|
||||
t->size =
|
||||
(((tObj->Image[0][t->base.firstLevel]->Width -
|
||||
1) << R300_TX_WIDTHMASK_SHIFT)
|
||||
@@ -408,7 +418,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
||||
t->pitch |=
|
||||
(tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
|
||||
} else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
unsigned int align = blitWidth - 1;
|
||||
unsigned int align = (64 / texelBytes) - 1;
|
||||
t->pitch |= ((tObj->Image[0][t->base.firstLevel]->Width *
|
||||
texelBytes) + 63) & ~(63);
|
||||
t->size |= R300_TX_SIZE_TXPITCH_EN;
|
||||
@@ -428,10 +438,6 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
||||
if (tObj->Image[0][t->base.firstLevel]->Height > 2048)
|
||||
t->pitch_reg |= R500_TXHEIGHT_BIT11;
|
||||
}
|
||||
|
||||
t->dirty_state = TEX_ALL;
|
||||
|
||||
/* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
@@ -568,7 +574,6 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
|
||||
|
||||
rmesa->state.texture.unit[unit].texobj = t;
|
||||
t->base.bound |= (1 << unit);
|
||||
t->dirty_state |= 1 << unit;
|
||||
driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,10 +36,14 @@
|
||||
#include "glheader.h"
|
||||
#include "macros.h"
|
||||
#include "enums.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
|
||||
#include "r300_context.h"
|
||||
#include "r300_state.h"
|
||||
#include "radeon_program.h"
|
||||
|
||||
/* supported hw opcodes */
|
||||
#define PFS_OP_MAD 0
|
||||
@@ -76,4 +80,13 @@ struct r500_fragment_program;
|
||||
extern void r500TranslateFragmentShader(r300ContextPtr r300,
|
||||
struct r500_fragment_program *fp);
|
||||
|
||||
struct r500_fragment_program_compiler {
|
||||
r300ContextPtr r300;
|
||||
struct r500_fragment_program *fp;
|
||||
struct r500_fragment_program_code *code;
|
||||
struct radeon_compiler compiler;
|
||||
};
|
||||
|
||||
extern GLboolean r500FragmentProgramEmit(struct r500_fragment_program_compiler *compiler);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,16 +53,6 @@ struct radeon_context;
|
||||
typedef struct radeon_context radeonContextRec;
|
||||
typedef struct radeon_context *radeonContextPtr;
|
||||
|
||||
#define TEX_0 0x1
|
||||
#define TEX_1 0x2
|
||||
#define TEX_2 0x4
|
||||
#define TEX_3 0x8
|
||||
#define TEX_4 0x10
|
||||
#define TEX_5 0x20
|
||||
#define TEX_6 0x40
|
||||
#define TEX_7 0x80
|
||||
#define TEX_ALL 0xff
|
||||
|
||||
/* Rasterizing fallbacks */
|
||||
/* See correponding strings in r200_swtcl.c */
|
||||
#define RADEON_FALLBACK_TEXTURE 0x0001
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Nicolai Haehnle.
|
||||
*
|
||||
* 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 THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "radeon_program.h"
|
||||
|
||||
#include "shader/prog_print.h"
|
||||
|
||||
/**
|
||||
* Initialize a compiler structure with a single mixed clause
|
||||
* containing all instructions from the source program.
|
||||
*/
|
||||
void radeonCompilerInit(
|
||||
struct radeon_compiler *compiler,
|
||||
GLcontext *ctx,
|
||||
struct gl_program *source)
|
||||
{
|
||||
struct radeon_clause* clause;
|
||||
|
||||
_mesa_memset(compiler, 0, sizeof(*compiler));
|
||||
compiler->Source = source;
|
||||
compiler->Ctx = ctx;
|
||||
|
||||
compiler->NumTemporaries = source->NumTemporaries;
|
||||
|
||||
clause = radeonCompilerInsertClause(compiler, 0, CLAUSE_MIXED);
|
||||
clause->NumInstructions = 0;
|
||||
while(source->Instructions[clause->NumInstructions].Opcode != OPCODE_END)
|
||||
clause->NumInstructions++;
|
||||
clause->ReservedInstructions = clause->NumInstructions;
|
||||
clause->Instructions = _mesa_alloc_instructions(clause->NumInstructions);
|
||||
_mesa_copy_instructions(clause->Instructions, source->Instructions, clause->NumInstructions);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free all data that is referenced by the compiler structure.
|
||||
* However, the compiler structure itself is not freed.
|
||||
*/
|
||||
void radeonCompilerCleanup(struct radeon_compiler *compiler)
|
||||
{
|
||||
radeonCompilerEraseClauses(compiler, 0, compiler->NumClauses);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate and return a unique temporary register.
|
||||
*/
|
||||
int radeonCompilerAllocateTemporary(struct radeon_compiler *compiler)
|
||||
{
|
||||
if (compiler->NumTemporaries >= 256) {
|
||||
_mesa_problem(compiler->Ctx, "radeonCompiler: Too many temporaries");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return compiler->NumTemporaries++;
|
||||
}
|
||||
|
||||
|
||||
static const char* clausename(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case CLAUSE_MIXED: return "CLAUSE_MIXED";
|
||||
case CLAUSE_ALU: return "CLAUSE_ALU";
|
||||
case CLAUSE_TEX: return "CLAUSE_TEX";
|
||||
default: return "CLAUSE_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dump the current compiler state to the console for debugging.
|
||||
*/
|
||||
void radeonCompilerDump(struct radeon_compiler *compiler)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < compiler->NumClauses; ++i) {
|
||||
struct radeon_clause *clause = &compiler->Clauses[i];
|
||||
int j;
|
||||
|
||||
_mesa_printf("%2i: %s\n", i+1, clausename(clause->Type));
|
||||
|
||||
for(j = 0; j < clause->NumInstructions; ++j) {
|
||||
_mesa_printf("%4i: ", j+1);
|
||||
_mesa_print_instruction(&clause->Instructions[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \p position index of the new clause; later clauses are moved
|
||||
* \p type of the new clause; one of CLAUSE_XXX
|
||||
* \return a pointer to the new clause
|
||||
*/
|
||||
struct radeon_clause* radeonCompilerInsertClause(
|
||||
struct radeon_compiler *compiler,
|
||||
int position, int type)
|
||||
{
|
||||
struct radeon_clause* oldClauses = compiler->Clauses;
|
||||
struct radeon_clause* clause;
|
||||
|
||||
assert(position >= 0 && position <= compiler->NumClauses);
|
||||
|
||||
compiler->Clauses = (struct radeon_clause *)
|
||||
_mesa_malloc((compiler->NumClauses+1) * sizeof(struct radeon_clause));
|
||||
if (oldClauses) {
|
||||
_mesa_memcpy(compiler->Clauses, oldClauses,
|
||||
position*sizeof(struct radeon_clause));
|
||||
_mesa_memcpy(compiler->Clauses+position+1, oldClauses+position,
|
||||
(compiler->NumClauses - position) * sizeof(struct radeon_clause));
|
||||
_mesa_free(oldClauses);
|
||||
}
|
||||
compiler->NumClauses++;
|
||||
|
||||
clause = compiler->Clauses + position;
|
||||
_mesa_memset(clause, 0, sizeof(*clause));
|
||||
clause->Type = type;
|
||||
|
||||
return clause;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove clauses in the range [start, end)
|
||||
*/
|
||||
void radeonCompilerEraseClauses(
|
||||
struct radeon_compiler *compiler,
|
||||
int start, int end)
|
||||
{
|
||||
struct radeon_clause* oldClauses = compiler->Clauses;
|
||||
int i;
|
||||
|
||||
assert(0 <= start);
|
||||
assert(start <= end);
|
||||
assert(end <= compiler->NumClauses);
|
||||
|
||||
if (end == start)
|
||||
return;
|
||||
|
||||
for(i = start; i < end; ++i) {
|
||||
struct radeon_clause* clause = oldClauses + i;
|
||||
_mesa_free_instructions(clause->Instructions, clause->NumInstructions);
|
||||
}
|
||||
|
||||
if (start > 0 || end < compiler->NumClauses) {
|
||||
compiler->Clauses = (struct radeon_clause*)
|
||||
_mesa_malloc((compiler->NumClauses+start-end) * sizeof(struct radeon_clause));
|
||||
_mesa_memcpy(compiler->Clauses, oldClauses,
|
||||
start * sizeof(struct radeon_clause));
|
||||
_mesa_memcpy(compiler->Clauses + start, oldClauses + end,
|
||||
(compiler->NumClauses - end) * sizeof(struct radeon_clause));
|
||||
compiler->NumClauses -= end - start;
|
||||
} else {
|
||||
compiler->Clauses = 0;
|
||||
compiler->NumClauses = 0;
|
||||
}
|
||||
|
||||
_mesa_free(oldClauses);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert new instructions at the given position, initialize them as NOPs
|
||||
* and return a pointer to the first new instruction.
|
||||
*/
|
||||
struct prog_instruction* radeonClauseInsertInstructions(
|
||||
struct radeon_compiler *compiler,
|
||||
struct radeon_clause *clause,
|
||||
int position, int count)
|
||||
{
|
||||
int newNumInstructions = clause->NumInstructions + count;
|
||||
|
||||
assert(position >= 0 && position <= clause->NumInstructions);
|
||||
|
||||
if (newNumInstructions <= clause->ReservedInstructions) {
|
||||
memmove(clause->Instructions + position + count, clause->Instructions + position,
|
||||
(clause->NumInstructions - position) * sizeof(struct prog_instruction));
|
||||
} else {
|
||||
struct prog_instruction *oldInstructions = clause->Instructions;
|
||||
|
||||
clause->ReservedInstructions *= 2;
|
||||
if (newNumInstructions > clause->ReservedInstructions)
|
||||
clause->ReservedInstructions = newNumInstructions;
|
||||
|
||||
clause->Instructions = (struct prog_instruction*)
|
||||
_mesa_malloc(clause->ReservedInstructions * sizeof(struct prog_instruction));
|
||||
|
||||
if (oldInstructions) {
|
||||
_mesa_memcpy(clause->Instructions, oldInstructions,
|
||||
position * sizeof(struct prog_instruction));
|
||||
_mesa_memcpy(clause->Instructions + position + count, oldInstructions + position,
|
||||
(clause->NumInstructions - position) * sizeof(struct prog_instruction));
|
||||
|
||||
_mesa_free(oldInstructions);
|
||||
}
|
||||
}
|
||||
|
||||
clause->NumInstructions = newNumInstructions;
|
||||
_mesa_init_instructions(clause->Instructions + position, count);
|
||||
return clause->Instructions + position;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transform the given clause in the following way:
|
||||
* 1. Replace it with an empty clause
|
||||
* 2. For every instruction in the original clause, try the given
|
||||
* transformations in order.
|
||||
* 3. If one of the transformations returns GL_TRUE, assume that it
|
||||
* has emitted the appropriate instruction(s) into the new clause;
|
||||
* otherwise, copy the instruction verbatim.
|
||||
*
|
||||
* \note The transformation is currently not recursive; in other words,
|
||||
* instructions emitted by transformations are not transformed.
|
||||
*
|
||||
* \note The transform is called 'local' because it can only look at
|
||||
* one instruction at a time.
|
||||
*/
|
||||
void radeonClauseLocalTransform(
|
||||
struct radeon_compiler *compiler,
|
||||
struct radeon_clause *clause,
|
||||
int num_transformations,
|
||||
struct radeon_program_transformation* transformations)
|
||||
{
|
||||
struct radeon_program_transform_context context;
|
||||
struct radeon_clause source;
|
||||
int ip;
|
||||
|
||||
source = *clause;
|
||||
clause->Instructions = 0;
|
||||
clause->NumInstructions = 0;
|
||||
clause->ReservedInstructions = 0;
|
||||
|
||||
context.compiler = compiler;
|
||||
context.dest = clause;
|
||||
context.src = &source;
|
||||
|
||||
for(ip = 0; ip < source.NumInstructions; ++ip) {
|
||||
struct prog_instruction *instr = source.Instructions + ip;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < num_transformations; ++i) {
|
||||
struct radeon_program_transformation* t = transformations + i;
|
||||
|
||||
if (t->function(&context, instr, t->userData))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= num_transformations) {
|
||||
struct prog_instruction *tgt =
|
||||
radeonClauseInsertInstructions(compiler, clause, clause->NumInstructions, 1);
|
||||
_mesa_copy_instructions(tgt, instr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
_mesa_free_instructions(source.Instructions, source.NumInstructions);
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Nicolai Haehnle.
|
||||
*
|
||||
* 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 THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_PROGRAM_H_
|
||||
#define __RADEON_PROGRAM_H_
|
||||
|
||||
#include "glheader.h"
|
||||
#include "macros.h"
|
||||
#include "enums.h"
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
|
||||
|
||||
enum {
|
||||
CLAUSE_MIXED = 0,
|
||||
CLAUSE_ALU,
|
||||
CLAUSE_TEX
|
||||
};
|
||||
|
||||
enum {
|
||||
PROGRAM_BUILTIN = PROGRAM_FILE_MAX /**< not a real register, but a special swizzle constant */
|
||||
};
|
||||
|
||||
#define SWIZZLE_0000 MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO)
|
||||
#define SWIZZLE_1111 MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE)
|
||||
|
||||
/**
|
||||
* A clause is simply a sequence of instructions that are executed
|
||||
* in order.
|
||||
*/
|
||||
struct radeon_clause {
|
||||
/**
|
||||
* Type of this clause, one of CLAUSE_XXX.
|
||||
*/
|
||||
int Type : 2;
|
||||
|
||||
/**
|
||||
* Pointer to an array of instructions.
|
||||
* The array is terminated by an OPCODE_END instruction.
|
||||
*/
|
||||
struct prog_instruction *Instructions;
|
||||
|
||||
/**
|
||||
* Number of instructions in this clause.
|
||||
*/
|
||||
int NumInstructions;
|
||||
|
||||
/**
|
||||
* Space reserved for instructions in this clause.
|
||||
*/
|
||||
int ReservedInstructions;
|
||||
};
|
||||
|
||||
/**
|
||||
* A compile object, holding the current intermediate state during compilation.
|
||||
*/
|
||||
struct radeon_compiler {
|
||||
struct gl_program *Source;
|
||||
GLcontext* Ctx;
|
||||
|
||||
/**
|
||||
* Number of clauses in this program.
|
||||
*/
|
||||
int NumClauses;
|
||||
|
||||
/**
|
||||
* Pointer to an array of NumClauses clauses.
|
||||
*/
|
||||
struct radeon_clause *Clauses;
|
||||
|
||||
/**
|
||||
* Number of registers in the PROGRAM_TEMPORARIES file.
|
||||
*/
|
||||
int NumTemporaries;
|
||||
};
|
||||
|
||||
void radeonCompilerInit(
|
||||
struct radeon_compiler *compiler,
|
||||
GLcontext *ctx,
|
||||
struct gl_program *source);
|
||||
void radeonCompilerCleanup(struct radeon_compiler *compiler);
|
||||
int radeonCompilerAllocateTemporary(struct radeon_compiler *compiler);
|
||||
void radeonCompilerDump(struct radeon_compiler *compiler);
|
||||
|
||||
struct radeon_clause *radeonCompilerInsertClause(
|
||||
struct radeon_compiler *compiler,
|
||||
int position,
|
||||
int type);
|
||||
void radeonCompilerEraseClauses(
|
||||
struct radeon_compiler *compiler,
|
||||
int start,
|
||||
int end);
|
||||
|
||||
struct prog_instruction* radeonClauseInsertInstructions(
|
||||
struct radeon_compiler *compiler,
|
||||
struct radeon_clause *clause,
|
||||
int position, int count);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
struct radeon_program_transform_context {
|
||||
struct radeon_compiler *compiler;
|
||||
|
||||
/**
|
||||
* Destination clause where new instructions must be written.
|
||||
*/
|
||||
struct radeon_clause *dest;
|
||||
|
||||
/**
|
||||
* Original clause that is currently being transformed.
|
||||
*/
|
||||
struct radeon_clause *src;
|
||||
};
|
||||
|
||||
/**
|
||||
* A transformation that can be passed to \ref radeonClauseLinearTransform.
|
||||
*
|
||||
* The function will be called once for each instruction.
|
||||
* It has to either emit the appropriate transformed code for the instruction
|
||||
* and return GL_TRUE, or return GL_FALSE if it doesn't understand the
|
||||
* instruction.
|
||||
*
|
||||
* The function gets passed the userData as last parameter.
|
||||
*/
|
||||
struct radeon_program_transformation {
|
||||
GLboolean (*function)(
|
||||
struct radeon_program_transform_context*,
|
||||
struct prog_instruction*,
|
||||
void*);
|
||||
void *userData;
|
||||
};
|
||||
|
||||
void radeonClauseLocalTransform(
|
||||
struct radeon_compiler *compiler,
|
||||
struct radeon_clause *clause,
|
||||
int num_transformations,
|
||||
struct radeon_program_transformation* transformations);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Nicolai Haehnle.
|
||||
*
|
||||
* 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 THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Shareable transformations that transform "special" ALU instructions
|
||||
* into ALU instructions that are supported by hardware.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "radeon_program_alu.h"
|
||||
|
||||
|
||||
static struct prog_instruction *emit1(struct radeon_program_transform_context* ctx,
|
||||
gl_inst_opcode Opcode, struct prog_dst_register DstReg,
|
||||
struct prog_src_register SrcReg)
|
||||
{
|
||||
struct prog_instruction *fpi =
|
||||
radeonClauseInsertInstructions(ctx->compiler, ctx->dest,
|
||||
ctx->dest->NumInstructions, 1);
|
||||
|
||||
fpi->Opcode = Opcode;
|
||||
fpi->DstReg = DstReg;
|
||||
fpi->SrcReg[0] = SrcReg;
|
||||
return fpi;
|
||||
}
|
||||
|
||||
static struct prog_instruction *emit2(struct radeon_program_transform_context* ctx,
|
||||
gl_inst_opcode Opcode, struct prog_dst_register DstReg,
|
||||
struct prog_src_register SrcReg0, struct prog_src_register SrcReg1)
|
||||
{
|
||||
struct prog_instruction *fpi =
|
||||
radeonClauseInsertInstructions(ctx->compiler, ctx->dest,
|
||||
ctx->dest->NumInstructions, 1);
|
||||
|
||||
fpi->Opcode = Opcode;
|
||||
fpi->DstReg = DstReg;
|
||||
fpi->SrcReg[0] = SrcReg0;
|
||||
fpi->SrcReg[1] = SrcReg1;
|
||||
return fpi;
|
||||
}
|
||||
|
||||
static struct prog_instruction *emit3(struct radeon_program_transform_context* ctx,
|
||||
gl_inst_opcode Opcode, struct prog_dst_register DstReg,
|
||||
struct prog_src_register SrcReg0, struct prog_src_register SrcReg1,
|
||||
struct prog_src_register SrcReg2)
|
||||
{
|
||||
struct prog_instruction *fpi =
|
||||
radeonClauseInsertInstructions(ctx->compiler, ctx->dest,
|
||||
ctx->dest->NumInstructions, 1);
|
||||
|
||||
fpi->Opcode = Opcode;
|
||||
fpi->DstReg = DstReg;
|
||||
fpi->SrcReg[0] = SrcReg0;
|
||||
fpi->SrcReg[1] = SrcReg1;
|
||||
fpi->SrcReg[2] = SrcReg2;
|
||||
return fpi;
|
||||
}
|
||||
|
||||
static void set_swizzle(struct prog_src_register *SrcReg, int coordinate, int swz)
|
||||
{
|
||||
SrcReg->Swizzle &= ~(7 << (3*coordinate));
|
||||
SrcReg->Swizzle |= swz << (3*coordinate);
|
||||
}
|
||||
|
||||
static void set_negate_base(struct prog_src_register *SrcReg, int coordinate, int negate)
|
||||
{
|
||||
SrcReg->NegateBase &= ~(1 << coordinate);
|
||||
SrcReg->NegateBase |= (negate << coordinate);
|
||||
}
|
||||
|
||||
static struct prog_dst_register dstreg(int file, int index)
|
||||
{
|
||||
struct prog_dst_register dst;
|
||||
dst.File = file;
|
||||
dst.Index = index;
|
||||
dst.WriteMask = WRITEMASK_XYZW;
|
||||
dst.CondMask = COND_TR;
|
||||
dst.CondSwizzle = SWIZZLE_NOOP;
|
||||
dst.CondSrc = 0;
|
||||
dst.pad = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static const struct prog_src_register builtin_zero = {
|
||||
.File = PROGRAM_BUILTIN,
|
||||
.Index = 0,
|
||||
.Swizzle = SWIZZLE_0000
|
||||
};
|
||||
static const struct prog_src_register builtin_one = {
|
||||
.File = PROGRAM_BUILTIN,
|
||||
.Index = 0,
|
||||
.Swizzle = SWIZZLE_1111
|
||||
};
|
||||
static const struct prog_src_register srcreg_undefined = {
|
||||
.File = PROGRAM_UNDEFINED,
|
||||
.Index = 0,
|
||||
.Swizzle = SWIZZLE_NOOP
|
||||
};
|
||||
|
||||
static struct prog_src_register srcreg(int file, int index)
|
||||
{
|
||||
struct prog_src_register src = srcreg_undefined;
|
||||
src.File = file;
|
||||
src.Index = index;
|
||||
return src;
|
||||
}
|
||||
|
||||
static struct prog_src_register negate(struct prog_src_register reg)
|
||||
{
|
||||
struct prog_src_register newreg = reg;
|
||||
newreg.NegateAbs = !newreg.NegateAbs;
|
||||
return newreg;
|
||||
}
|
||||
|
||||
static struct prog_src_register swizzle(struct prog_src_register reg, GLuint x, GLuint y, GLuint z, GLuint w)
|
||||
{
|
||||
struct prog_src_register swizzled = reg;
|
||||
swizzled.Swizzle = MAKE_SWIZZLE4(
|
||||
GET_SWZ(reg.Swizzle, x),
|
||||
GET_SWZ(reg.Swizzle, y),
|
||||
GET_SWZ(reg.Swizzle, z),
|
||||
GET_SWZ(reg.Swizzle, w));
|
||||
return swizzled;
|
||||
}
|
||||
|
||||
static struct prog_src_register scalar(struct prog_src_register reg)
|
||||
{
|
||||
return swizzle(reg, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
|
||||
}
|
||||
|
||||
static void transform_ABS(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
struct prog_src_register src = inst->SrcReg[0];
|
||||
src.Abs = 1;
|
||||
src.NegateBase = 0;
|
||||
src.NegateAbs = 0;
|
||||
emit1(ctx, OPCODE_MOV, inst->DstReg, src);
|
||||
}
|
||||
|
||||
static void transform_DPH(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
struct prog_src_register src0 = inst->SrcReg[0];
|
||||
if (src0.NegateAbs) {
|
||||
if (src0.Abs) {
|
||||
int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
|
||||
emit1(ctx, OPCODE_MOV, dstreg(PROGRAM_TEMPORARY, tempreg), src0);
|
||||
src0 = srcreg(src0.File, src0.Index);
|
||||
} else {
|
||||
src0.NegateAbs = 0;
|
||||
src0.NegateBase ^= NEGATE_XYZW;
|
||||
}
|
||||
}
|
||||
set_swizzle(&src0, 3, SWIZZLE_ONE);
|
||||
set_negate_base(&src0, 3, 0);
|
||||
emit2(ctx, OPCODE_DP4, inst->DstReg, src0, inst->SrcReg[1]);
|
||||
}
|
||||
|
||||
static void transform_FLR(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
|
||||
emit1(ctx, OPCODE_FRC, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0]);
|
||||
emit2(ctx, OPCODE_ADD, inst->DstReg, inst->SrcReg[0], negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
|
||||
}
|
||||
|
||||
static void transform_POW(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
|
||||
struct prog_dst_register tempdst = dstreg(PROGRAM_TEMPORARY, tempreg);
|
||||
struct prog_src_register tempsrc = srcreg(PROGRAM_TEMPORARY, tempreg);
|
||||
tempdst.WriteMask = WRITEMASK_W;
|
||||
tempsrc.Swizzle = SWIZZLE_WWWW;
|
||||
|
||||
emit1(ctx, OPCODE_LG2, tempdst, scalar(inst->SrcReg[0]));
|
||||
emit2(ctx, OPCODE_MUL, tempdst, tempsrc, scalar(inst->SrcReg[1]));
|
||||
emit1(ctx, OPCODE_EX2, inst->DstReg, tempsrc);
|
||||
}
|
||||
|
||||
static void transform_SGE(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
|
||||
|
||||
emit2(ctx, OPCODE_ADD, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0], negate(inst->SrcReg[1]));
|
||||
emit3(ctx, OPCODE_CMP, inst->DstReg, srcreg(PROGRAM_TEMPORARY, tempreg), builtin_zero, builtin_one);
|
||||
}
|
||||
|
||||
static void transform_SLT(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
|
||||
|
||||
emit2(ctx, OPCODE_ADD, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0], negate(inst->SrcReg[1]));
|
||||
emit3(ctx, OPCODE_CMP, inst->DstReg, srcreg(PROGRAM_TEMPORARY, tempreg), builtin_one, builtin_zero);
|
||||
}
|
||||
|
||||
static void transform_SUB(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
emit2(ctx, OPCODE_ADD, inst->DstReg, inst->SrcReg[0], negate(inst->SrcReg[1]));
|
||||
}
|
||||
|
||||
static void transform_SWZ(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
emit1(ctx, OPCODE_MOV, inst->DstReg, inst->SrcReg[0]);
|
||||
}
|
||||
|
||||
static void transform_XPD(struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst)
|
||||
{
|
||||
int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
|
||||
|
||||
emit2(ctx, OPCODE_MUL, dstreg(PROGRAM_TEMPORARY, tempreg),
|
||||
swizzle(inst->SrcReg[0], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
|
||||
swizzle(inst->SrcReg[1], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W));
|
||||
emit3(ctx, OPCODE_MAD, inst->DstReg,
|
||||
swizzle(inst->SrcReg[0], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W),
|
||||
swizzle(inst->SrcReg[1], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
|
||||
negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Can be used as a transformation for @ref radeonClauseLocalTransform,
|
||||
* no userData necessary.
|
||||
*
|
||||
* Eliminates the following ALU instructions:
|
||||
* ABS, DPH, FLR, POW, SGE, SLT, SUB, SWZ, XPD
|
||||
* using:
|
||||
* MOV, ADD, MUL, MAD, FRC, DP3, LG2, EX2, CMP
|
||||
*
|
||||
* @note should be applicable to R300 and R500 fragment programs.
|
||||
*
|
||||
* @todo add LIT here as well?
|
||||
*/
|
||||
GLboolean radeonTransformALU(
|
||||
struct radeon_program_transform_context* ctx,
|
||||
struct prog_instruction* inst,
|
||||
void* unused)
|
||||
{
|
||||
switch(inst->Opcode) {
|
||||
case OPCODE_ABS: transform_ABS(ctx, inst); return GL_TRUE;
|
||||
case OPCODE_DPH: transform_DPH(ctx, inst); return GL_TRUE;
|
||||
case OPCODE_FLR: transform_FLR(ctx, inst); return GL_TRUE;
|
||||
case OPCODE_POW: transform_POW(ctx, inst); return GL_TRUE;
|
||||
case OPCODE_SGE: transform_SGE(ctx, inst); return GL_TRUE;
|
||||
case OPCODE_SLT: transform_SLT(ctx, inst); return GL_TRUE;
|
||||
case OPCODE_SUB: transform_SUB(ctx, inst); return GL_TRUE;
|
||||
case OPCODE_SWZ: transform_SWZ(ctx, inst); return GL_TRUE;
|
||||
case OPCODE_XPD: transform_XPD(ctx, inst); return GL_TRUE;
|
||||
default:
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Nicolai Haehnle.
|
||||
*
|
||||
* 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 THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_PROGRAM_ALU_H_
|
||||
#define __RADEON_PROGRAM_ALU_H_
|
||||
|
||||
#include "radeon_program.h"
|
||||
|
||||
GLboolean radeonTransformALU(
|
||||
struct radeon_program_transform_context*,
|
||||
struct prog_instruction*,
|
||||
void*);
|
||||
|
||||
#endif /* __RADEON_PROGRAM_ALU_H_ */
|
||||
@@ -282,6 +282,30 @@ static void radeonSpanRenderStart(GLcontext * ctx)
|
||||
#endif
|
||||
LOCK_HARDWARE(rmesa);
|
||||
radeonWaitForIdleLocked(rmesa);
|
||||
|
||||
/* Read the first pixel in the frame buffer. This should
|
||||
* be a noop, right? In fact without this conform fails as reading
|
||||
* from the framebuffer sometimes produces old results -- the
|
||||
* on-card read cache gets mixed up and doesn't notice that the
|
||||
* framebuffer has been updated.
|
||||
*
|
||||
* Note that we should probably be reading some otherwise unused
|
||||
* region of VRAM, otherwise we might get incorrect results when
|
||||
* reading pixels from the top left of the screen.
|
||||
*
|
||||
* I found this problem on an R420 with glean's texCube test.
|
||||
* Note that the R200 span code also *writes* the first pixel in the
|
||||
* framebuffer, but I've found this to be unnecessary.
|
||||
* -- Nicolai Hähnle, June 2008
|
||||
*/
|
||||
{
|
||||
int p;
|
||||
driRenderbuffer *drb =
|
||||
(driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0];
|
||||
volatile int *buf =
|
||||
(volatile int *)(rmesa->dri.screen->pFB + drb->offset);
|
||||
p = *buf;
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonSpanRenderFinish(GLcontext * ctx)
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "vbo/vbo.h"
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "swrast_priv.h"
|
||||
|
||||
@@ -51,6 +52,7 @@
|
||||
#define need_GL_VERSION_1_4
|
||||
#define need_GL_VERSION_1_5
|
||||
#define need_GL_VERSION_2_0
|
||||
#define need_GL_VERSION_2_1
|
||||
|
||||
/* sw extensions for imaging */
|
||||
#define need_GL_EXT_blend_color
|
||||
@@ -75,7 +77,6 @@
|
||||
#define need_GL_NV_fragment_program
|
||||
|
||||
#include "extension_helper.h"
|
||||
#include "utils.h"
|
||||
|
||||
const struct dri_extension card_extensions[] =
|
||||
{
|
||||
@@ -83,6 +84,7 @@ const struct dri_extension card_extensions[] =
|
||||
{ "GL_VERSION_1_4", GL_VERSION_1_4_functions },
|
||||
{ "GL_VERSION_1_5", GL_VERSION_1_5_functions },
|
||||
{ "GL_VERSION_2_0", GL_VERSION_2_0_functions },
|
||||
{ "GL_VERSION_2_1", GL_VERSION_2_1_functions },
|
||||
|
||||
{ "GL_EXT_blend_color", GL_EXT_blend_color_functions },
|
||||
{ "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
|
||||
@@ -326,7 +328,7 @@ swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
|
||||
_mesa_free(rb->Data);
|
||||
|
||||
(void) swrast_alloc_front_storage(ctx, rb, internalFormat, width, height);
|
||||
swrast_alloc_front_storage(ctx, rb, internalFormat, width, height);
|
||||
|
||||
rb->Data = _mesa_malloc(height * xrb->pitch);
|
||||
|
||||
@@ -341,59 +343,61 @@ swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
|
||||
|
||||
TRACE;
|
||||
|
||||
if (xrb) {
|
||||
_mesa_init_renderbuffer(&xrb->Base, 0);
|
||||
if (!xrb)
|
||||
return NULL;
|
||||
|
||||
pixel_format = choose_pixel_format(visual);
|
||||
_mesa_init_renderbuffer(&xrb->Base, 0);
|
||||
|
||||
xrb->Base.Delete = swrast_delete_renderbuffer;
|
||||
if (front) {
|
||||
xrb->Base.AllocStorage = swrast_alloc_front_storage;
|
||||
swrast_set_span_funcs_front(xrb, pixel_format);
|
||||
}
|
||||
else {
|
||||
xrb->Base.AllocStorage = swrast_alloc_back_storage;
|
||||
swrast_set_span_funcs_back(xrb, pixel_format);
|
||||
}
|
||||
pixel_format = choose_pixel_format(visual);
|
||||
|
||||
switch (pixel_format) {
|
||||
case PF_A8R8G8B8:
|
||||
xrb->Base.InternalFormat = GL_RGBA;
|
||||
xrb->Base._BaseFormat = GL_RGBA;
|
||||
xrb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
xrb->Base.RedBits = 8 * sizeof(GLubyte);
|
||||
xrb->Base.GreenBits = 8 * sizeof(GLubyte);
|
||||
xrb->Base.BlueBits = 8 * sizeof(GLubyte);
|
||||
xrb->Base.AlphaBits = 8 * sizeof(GLubyte);
|
||||
break;
|
||||
case PF_R5G6B5:
|
||||
xrb->Base.InternalFormat = GL_RGB;
|
||||
xrb->Base._BaseFormat = GL_RGB;
|
||||
xrb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
xrb->Base.RedBits = 5 * sizeof(GLubyte);
|
||||
xrb->Base.GreenBits = 6 * sizeof(GLubyte);
|
||||
xrb->Base.BlueBits = 5 * sizeof(GLubyte);
|
||||
xrb->Base.AlphaBits = 0;
|
||||
break;
|
||||
case PF_R3G3B2:
|
||||
xrb->Base.InternalFormat = GL_RGB;
|
||||
xrb->Base._BaseFormat = GL_RGB;
|
||||
xrb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
xrb->Base.RedBits = 3 * sizeof(GLubyte);
|
||||
xrb->Base.GreenBits = 3 * sizeof(GLubyte);
|
||||
xrb->Base.BlueBits = 2 * sizeof(GLubyte);
|
||||
xrb->Base.AlphaBits = 0;
|
||||
break;
|
||||
case PF_CI8:
|
||||
xrb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
|
||||
xrb->Base._BaseFormat = GL_COLOR_INDEX;
|
||||
xrb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
xrb->Base.IndexBits = 8 * sizeof(GLubyte);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
xrb->Base.Delete = swrast_delete_renderbuffer;
|
||||
if (front) {
|
||||
xrb->Base.AllocStorage = swrast_alloc_front_storage;
|
||||
swrast_set_span_funcs_front(xrb, pixel_format);
|
||||
}
|
||||
else {
|
||||
xrb->Base.AllocStorage = swrast_alloc_back_storage;
|
||||
swrast_set_span_funcs_back(xrb, pixel_format);
|
||||
}
|
||||
|
||||
switch (pixel_format) {
|
||||
case PF_A8R8G8B8:
|
||||
xrb->Base.InternalFormat = GL_RGBA;
|
||||
xrb->Base._BaseFormat = GL_RGBA;
|
||||
xrb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
xrb->Base.RedBits = 8 * sizeof(GLubyte);
|
||||
xrb->Base.GreenBits = 8 * sizeof(GLubyte);
|
||||
xrb->Base.BlueBits = 8 * sizeof(GLubyte);
|
||||
xrb->Base.AlphaBits = 8 * sizeof(GLubyte);
|
||||
break;
|
||||
case PF_R5G6B5:
|
||||
xrb->Base.InternalFormat = GL_RGB;
|
||||
xrb->Base._BaseFormat = GL_RGB;
|
||||
xrb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
xrb->Base.RedBits = 5 * sizeof(GLubyte);
|
||||
xrb->Base.GreenBits = 6 * sizeof(GLubyte);
|
||||
xrb->Base.BlueBits = 5 * sizeof(GLubyte);
|
||||
xrb->Base.AlphaBits = 0;
|
||||
break;
|
||||
case PF_R3G3B2:
|
||||
xrb->Base.InternalFormat = GL_RGB;
|
||||
xrb->Base._BaseFormat = GL_RGB;
|
||||
xrb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
xrb->Base.RedBits = 3 * sizeof(GLubyte);
|
||||
xrb->Base.GreenBits = 3 * sizeof(GLubyte);
|
||||
xrb->Base.BlueBits = 2 * sizeof(GLubyte);
|
||||
xrb->Base.AlphaBits = 0;
|
||||
break;
|
||||
case PF_CI8:
|
||||
xrb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
|
||||
xrb->Base._BaseFormat = GL_COLOR_INDEX;
|
||||
xrb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
xrb->Base.IndexBits = 8 * sizeof(GLubyte);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return xrb;
|
||||
}
|
||||
|
||||
@@ -691,7 +695,6 @@ static int driUnbindContext(__DRIcontext *ctx)
|
||||
{
|
||||
TRACE;
|
||||
(void) ctx;
|
||||
_mesa_make_current(NULL, NULL, NULL);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# src/mesa/drivers/fbdev/Makefile for libGL.so
|
||||
|
||||
TOP = ../../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
SOURCES = glfbdev.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
INCLUDE_DIRS = \
|
||||
-I$(TOP)/include \
|
||||
-I$(TOP)/src/mesa \
|
||||
-I$(TOP)/src/mesa/main
|
||||
|
||||
CORE_MESA = $(TOP)/src/mesa/libmesa.a $(TOP)/src/mesa/libglapi.a
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
|
||||
|
||||
|
||||
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(CORE_MESA) $(OBJECTS)
|
||||
@ $(TOP)/bin/mklib -o $(GL_LIB) \
|
||||
-linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
|
||||
$(CORE_MESA) $(OBJECTS) $(GL_LIB_DEPS)
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f $(OBJECTS)
|
||||
@@ -0,0 +1,74 @@
|
||||
# src/mesa/drivers/osmesa/Makefile for libOSMesa.so
|
||||
|
||||
# Note that we may generate libOSMesa.so or libOSMesa16.so or libOSMesa32.so
|
||||
# with this Makefile
|
||||
|
||||
|
||||
TOP = ../../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
|
||||
SOURCES = osmesa.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
INCLUDE_DIRS = \
|
||||
-I$(TOP)/include \
|
||||
-I$(TOP)/src/mesa \
|
||||
-I$(TOP)/src/mesa/main
|
||||
|
||||
CORE_MESA = $(TOP)/src/mesa/libmesa.a $(TOP)/src/mesa/libglapi.a
|
||||
|
||||
|
||||
.PHONY: osmesa8
|
||||
.PHONY: osmesa16
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
default:
|
||||
# $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
|
||||
@ if [ "${DRIVER_DIRS}" = "osmesa" ] ; then \
|
||||
$(MAKE) osmesa16 ; \
|
||||
else \
|
||||
$(MAKE) osmesa8 ; \
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
# The normal libOSMesa is used in conjuction with libGL
|
||||
osmesa8: $(TOP)/lib/$(OSMESA_LIB_NAME)
|
||||
|
||||
$(TOP)/lib/$(OSMESA_LIB_NAME): $(OBJECTS)
|
||||
$(TOP)/bin/mklib -o $(OSMESA_LIB) \
|
||||
-linker "$(CC)" \
|
||||
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) \
|
||||
$(MKLIB_OPTIONS) \
|
||||
$(OSMESA_LIB_DEPS) $(OBJECTS)
|
||||
|
||||
|
||||
|
||||
|
||||
# The libOSMesa16/libOSMesa32 libraries do not use libGL but rather are built
|
||||
# with all the other Mesa sources (compiled with -DCHAN_BITS=16/32
|
||||
osmesa16: $(OBJECTS) $(CORE_MESA)
|
||||
$(TOP)/bin/mklib -o $(OSMESA_LIB) \
|
||||
-linker "$(CC)" \
|
||||
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) \
|
||||
$(MKLIB_OPTIONS) \
|
||||
$(OSMESA_LIB_DEPS) $(OBJECTS) $(CORE_MESA)
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f *.o *~
|
||||
|
||||
|
||||
# XXX todo install rule?
|
||||
@@ -33,14 +33,14 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "glheader.h"
|
||||
#include "main/glheader.h"
|
||||
#include "GL/osmesa.h"
|
||||
#include "context.h"
|
||||
#include "extensions.h"
|
||||
#include "framebuffer.h"
|
||||
#include "imports.h"
|
||||
#include "mtypes.h"
|
||||
#include "renderbuffer.h"
|
||||
#include "main/context.h"
|
||||
#include "main/extensions.h"
|
||||
#include "main/framebuffer.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "main/renderbuffer.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "swrast/s_context.h"
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# src/mesa/drivers/x11/Makefile for libGL.so
|
||||
|
||||
# This builds "stand-alone" Mesa, a version of libGL that does not need the
|
||||
# GLX extension. All rendering is converted to Xlib calls. No hardware
|
||||
# acceleration.
|
||||
|
||||
|
||||
TOP = ../../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
GL_MAJOR = 1
|
||||
GL_MINOR = 5
|
||||
GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
|
||||
|
||||
|
||||
HEADERS = \
|
||||
glxapi.h \
|
||||
glxheader.h \
|
||||
xfonts.h \
|
||||
xmesaP.h \
|
||||
xm_glide.h \
|
||||
xm_image.h
|
||||
|
||||
SOURCES = \
|
||||
fakeglx.c \
|
||||
glxapi.c \
|
||||
xfonts.c \
|
||||
xm_api.c \
|
||||
xm_buffer.c \
|
||||
xm_dd.c \
|
||||
xm_glide.c \
|
||||
xm_image.c \
|
||||
xm_line.c \
|
||||
xm_span.c \
|
||||
xm_tri.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
INCLUDE_DIRS = \
|
||||
-I$(TOP)/include \
|
||||
-I$(TOP)/src/mesa \
|
||||
-I$(TOP)/src/mesa/main
|
||||
|
||||
CORE_MESA = $(TOP)/src/mesa/libmesa.a $(TOP)/src/mesa/libglapi.a
|
||||
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
|
||||
|
||||
|
||||
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) $(CORE_MESA)
|
||||
@ $(TOP)/bin/mklib -o $(GL_LIB) \
|
||||
-linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) \
|
||||
$(MKLIB_OPTIONS) $(GL_LIB_DEPS) $(OBJECTS) $(CORE_MESA)
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f *.o *~
|
||||
-rm -f depend depend.bak
|
||||
|
||||
|
||||
|
||||
depend: $(SOURCES) $(HEADERS)
|
||||
@ echo "running $(MKDEP)"
|
||||
@ touch depend
|
||||
@$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(SOURCES) $(HEADERS) \
|
||||
> /dev/null 2>/dev/null
|
||||
|
||||
|
||||
-include depend
|
||||
@@ -34,8 +34,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "glheader.h"
|
||||
#include "glapi.h"
|
||||
#include "main/glheader.h"
|
||||
#include "glapi/glapi.h"
|
||||
#include "glxapi.h"
|
||||
|
||||
|
||||
|
||||
@@ -65,14 +65,14 @@
|
||||
#include "glxheader.h"
|
||||
#include "GL/xmesa.h"
|
||||
#include "xmesaP.h"
|
||||
#include "context.h"
|
||||
#include "extensions.h"
|
||||
#include "framebuffer.h"
|
||||
#include "glthread.h"
|
||||
#include "imports.h"
|
||||
#include "macros.h"
|
||||
#include "renderbuffer.h"
|
||||
#include "teximage.h"
|
||||
#include "main/context.h"
|
||||
#include "main/extensions.h"
|
||||
#include "main/framebuffer.h"
|
||||
#include "glapi/glthread.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/renderbuffer.h"
|
||||
#include "main/teximage.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "vbo/vbo.h"
|
||||
|
||||
@@ -64,7 +64,8 @@ FXcreateContext(XMesaVisual v, XMesaWindow w, XMesaContext c, XMesaBuffer b)
|
||||
attribs[numAttribs++] = FXMESA_NONE;
|
||||
|
||||
/* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */
|
||||
hw = fxMesaSelectCurrentBoard(0);
|
||||
/* hw = fxMesaSelectCurrentBoard(0); */
|
||||
hw = GR_SSTTYPE_Voodoo2;
|
||||
|
||||
/* if these fail, there's a new bug somewhere */
|
||||
ASSERT(b->mesa_buffer.Width > 0);
|
||||
|
||||
@@ -3963,7 +3963,7 @@ _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
|
||||
DEPTH_VALUES(GLuint, UINT_TO_FLOAT);
|
||||
break;
|
||||
case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
|
||||
if (dstType == GL_UNSIGNED_INT &&
|
||||
if (dstType == GL_UNSIGNED_INT_24_8_EXT &&
|
||||
depthMax == 0xffffff &&
|
||||
ctx->Pixel.DepthScale == 1.0 &&
|
||||
ctx->Pixel.DepthBias == 0.0) {
|
||||
|
||||
+4
-4
@@ -53,7 +53,7 @@ mmDumpMemInfo(const struct mem_block *heap)
|
||||
}
|
||||
|
||||
struct mem_block *
|
||||
mmInit(int ofs, int size)
|
||||
mmInit(unsigned int ofs, int size)
|
||||
{
|
||||
struct mem_block *heap, *block;
|
||||
|
||||
@@ -91,7 +91,7 @@ mmInit(int ofs, int size)
|
||||
|
||||
static struct mem_block *
|
||||
SliceBlock(struct mem_block *p,
|
||||
int startofs, int size,
|
||||
unsigned int startofs, int size,
|
||||
int reserved, int alignment)
|
||||
{
|
||||
struct mem_block *newblock;
|
||||
@@ -164,8 +164,8 @@ mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch)
|
||||
{
|
||||
struct mem_block *p;
|
||||
const int mask = (1 << align2)-1;
|
||||
int startofs = 0;
|
||||
int endofs;
|
||||
unsigned int startofs = 0;
|
||||
unsigned int endofs;
|
||||
|
||||
if (!heap || align2 < 0 || size <= 0)
|
||||
return NULL;
|
||||
|
||||
+3
-2
@@ -39,7 +39,8 @@ struct mem_block {
|
||||
struct mem_block *next, *prev;
|
||||
struct mem_block *next_free, *prev_free;
|
||||
struct mem_block *heap;
|
||||
int ofs,size;
|
||||
unsigned int ofs;
|
||||
int size;
|
||||
unsigned int free:1;
|
||||
unsigned int reserved:1;
|
||||
};
|
||||
@@ -50,7 +51,7 @@ struct mem_block {
|
||||
* input: total size in bytes
|
||||
* return: a heap pointer if OK, NULL if error
|
||||
*/
|
||||
extern struct mem_block *mmInit(int ofs, int size);
|
||||
extern struct mem_block *mmInit(unsigned int ofs, int size);
|
||||
|
||||
/**
|
||||
* Allocate 'size' bytes with 2^align2 bytes alignment,
|
||||
|
||||
@@ -68,6 +68,7 @@ struct state_key {
|
||||
struct {
|
||||
GLuint enabled:1;
|
||||
GLuint source_index:3; /* one of TEXTURE_1D/2D/3D/CUBE/RECT_INDEX */
|
||||
GLuint shadow:1;
|
||||
GLuint ScaleShiftRGB:2;
|
||||
GLuint ScaleShiftA:2;
|
||||
|
||||
@@ -219,6 +220,7 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
|
||||
|
||||
key->unit[i].source_index =
|
||||
translate_tex_src_bit(texUnit->_ReallyEnabled);
|
||||
key->unit[i].shadow = texUnit->_Current->CompareMode == GL_COMPARE_R_TO_TEXTURE;
|
||||
|
||||
key->unit[i].NumArgsRGB = texUnit->_CurrentCombine->_NumArgsRGB;
|
||||
key->unit[i].NumArgsA = texUnit->_CurrentCombine->_NumArgsA;
|
||||
@@ -945,11 +947,13 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit )
|
||||
|
||||
/* TODO: Use D0_MASK_XY where possible.
|
||||
*/
|
||||
if (p->state->unit[unit].enabled)
|
||||
if (p->state->unit[unit].enabled) {
|
||||
p->src_texture[unit] = emit_texld( p, OPCODE_TXP,
|
||||
tmp, WRITEMASK_XYZW,
|
||||
unit, dim, texcoord );
|
||||
else
|
||||
if (p->state->unit[unit].shadow)
|
||||
p->program->Base.ShadowSamplers |= 1 << unit;
|
||||
} else
|
||||
p->src_texture[unit] = get_zero(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2322,7 +2322,7 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
|
||||
GLboolean
|
||||
_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
|
||||
{
|
||||
const GLuint depthScale = 0xffffff;
|
||||
const GLfloat depthScale = (GLfloat) 0xffffff;
|
||||
|
||||
ASSERT(dstFormat == &_mesa_texformat_z24_s8);
|
||||
ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
|
||||
@@ -2360,7 +2360,7 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
|
||||
GLint i;
|
||||
/* the 24 depth bits will be in the high position: */
|
||||
_mesa_unpack_depth_span(ctx, srcWidth,
|
||||
GL_UNSIGNED_INT, /* dst type */
|
||||
GL_UNSIGNED_INT_24_8_EXT, /* dst type */
|
||||
dstRow, /* dst addr */
|
||||
depthScale,
|
||||
srcType, src, srcPacking);
|
||||
|
||||
@@ -3869,7 +3869,7 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
|
||||
program->Base.Parameters = ap.Base.Parameters;
|
||||
|
||||
#if DEBUG_FP
|
||||
_mesa_printf("____________Fragment program %u ________\n", program->Base.ID);
|
||||
_mesa_printf("____________Fragment program %u ________\n", program->Base.Id);
|
||||
_mesa_print_program(&program->Base);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -90,7 +90,8 @@ get_register_pointer(const struct prog_src_register *source,
|
||||
const struct gl_program_parameter_list *params;
|
||||
ASSERT(source->File == PROGRAM_LOCAL_PARAM ||
|
||||
source->File == PROGRAM_CONSTANT ||
|
||||
source->File == PROGRAM_STATE_VAR);
|
||||
source->File == PROGRAM_STATE_VAR ||
|
||||
source->File == PROGRAM_UNIFORM);
|
||||
params = machine->CurProgram->Parameters;
|
||||
if (reg < 0 || reg >= params->NumParameters)
|
||||
return ZeroVec;
|
||||
|
||||
@@ -62,6 +62,28 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
|
||||
}
|
||||
|
||||
|
||||
static GLint
|
||||
_mesa_fit_type_in_vec4(GLenum type)
|
||||
{
|
||||
switch (type) {
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
return 4;
|
||||
break;
|
||||
case GL_FLOAT_VEC2:
|
||||
case GL_INT_VEC2:
|
||||
return 2;
|
||||
break;
|
||||
case GL_FLOAT_VEC3:
|
||||
case GL_INT_VEC3:
|
||||
return 1;
|
||||
break;
|
||||
case GL_FLOAT_VEC4:
|
||||
case GL_INT_VEC4:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new parameter to a parameter list.
|
||||
@@ -272,7 +294,7 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList,
|
||||
}
|
||||
else {
|
||||
i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name,
|
||||
size, datatype, NULL, NULL);
|
||||
size * _mesa_fit_type_in_vec4(datatype), datatype, NULL, NULL);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ arb_output_attrib_string(GLint index, GLenum progType)
|
||||
*/
|
||||
static const char *
|
||||
reg_string(enum register_file f, GLint index, gl_prog_print_mode mode,
|
||||
const struct gl_program *prog)
|
||||
GLboolean relAddr, const struct gl_program *prog)
|
||||
{
|
||||
static char str[100];
|
||||
|
||||
@@ -214,7 +214,10 @@ reg_string(enum register_file f, GLint index, gl_prog_print_mode mode,
|
||||
|
||||
switch (mode) {
|
||||
case PROG_PRINT_DEBUG:
|
||||
sprintf(str, "%s[%d]", file_string(f, mode), index);
|
||||
if (relAddr)
|
||||
sprintf(str, "%s[ADDR%s%d]", file_string(f, mode), (index > 0) ? "+" : "", index);
|
||||
else
|
||||
sprintf(str, "%s[%d]", file_string(f, mode), index);
|
||||
break;
|
||||
|
||||
case PROG_PRINT_ARB:
|
||||
@@ -401,7 +404,7 @@ print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode,
|
||||
{
|
||||
_mesa_printf("%s%s",
|
||||
reg_string((enum register_file) dstReg->File,
|
||||
dstReg->Index, mode, prog),
|
||||
dstReg->Index, mode, GL_FALSE, prog),
|
||||
writemask_string(dstReg->WriteMask));
|
||||
|
||||
if (dstReg->CondMask != COND_TR) {
|
||||
@@ -424,9 +427,9 @@ print_src_reg(const struct prog_src_register *srcReg, gl_prog_print_mode mode,
|
||||
{
|
||||
_mesa_printf("%s%s",
|
||||
reg_string((enum register_file) srcReg->File,
|
||||
srcReg->Index, mode, prog),
|
||||
srcReg->Index, mode, srcReg->RelAddr, prog),
|
||||
_mesa_swizzle_string(srcReg->Swizzle,
|
||||
srcReg->NegateBase, GL_FALSE));
|
||||
srcReg->NegateBase, GL_FALSE));
|
||||
#if 0
|
||||
_mesa_printf("%s[%d]%s",
|
||||
file_string((enum register_file) srcReg->File, mode),
|
||||
@@ -590,7 +593,9 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
|
||||
break;
|
||||
|
||||
case OPCODE_ARL:
|
||||
_mesa_printf("ARL addr.x, ");
|
||||
_mesa_printf("ARL ");
|
||||
print_dst_reg(&inst->DstReg, mode, prog);
|
||||
_mesa_printf(", ");
|
||||
print_src_reg(&inst->SrcReg[0], mode, prog);
|
||||
print_comment(inst);
|
||||
break;
|
||||
|
||||
@@ -367,20 +367,22 @@ _mesa_count_texture_instructions(struct gl_program *prog)
|
||||
|
||||
|
||||
/**
|
||||
* Scan/rewrite program to remove reads of varying (output) registers.
|
||||
* Scan/rewrite program to remove reads of custom (output) registers.
|
||||
* The passed type has to be either PROGRAM_VARYING or PROGRAM_OUTPUT.
|
||||
* In GLSL vertex shaders, varying vars can be read and written.
|
||||
* Normally, vertex varying vars are implemented as output registers.
|
||||
* On some hardware, trying to read an output register causes trouble.
|
||||
* So, rewrite the program to use a temporary register in this case.
|
||||
*/
|
||||
void
|
||||
_mesa_remove_varying_reads(struct gl_program *prog)
|
||||
_mesa_remove_output_reads(struct gl_program *prog, enum register_file type)
|
||||
{
|
||||
GLuint i;
|
||||
GLint outputMap[VERT_RESULT_MAX];
|
||||
GLuint numVaryingReads = 0;
|
||||
|
||||
assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
|
||||
assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT);
|
||||
|
||||
for (i = 0; i < VERT_RESULT_MAX; i++)
|
||||
outputMap[i] = -1;
|
||||
@@ -391,7 +393,7 @@ _mesa_remove_varying_reads(struct gl_program *prog)
|
||||
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
|
||||
GLuint j;
|
||||
for (j = 0; j < numSrc; j++) {
|
||||
if (inst->SrcReg[j].File == PROGRAM_VARYING) {
|
||||
if (inst->SrcReg[j].File == type) {
|
||||
/* replace the read with a temp reg */
|
||||
const GLuint var = inst->SrcReg[j].Index;
|
||||
if (outputMap[var] == -1) {
|
||||
@@ -414,7 +416,7 @@ _mesa_remove_varying_reads(struct gl_program *prog)
|
||||
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
|
||||
GLuint j;
|
||||
for (j = 0; j < numSrc; j++) {
|
||||
if (inst->DstReg.File == PROGRAM_VARYING &&
|
||||
if (inst->DstReg.File == type &&
|
||||
outputMap[inst->DstReg.Index] >= 0) {
|
||||
/* change inst to write to the temp reg, instead of the varying */
|
||||
inst->DstReg.File = PROGRAM_TEMPORARY;
|
||||
@@ -447,7 +449,7 @@ _mesa_remove_varying_reads(struct gl_program *prog)
|
||||
if (outputMap[var] >= 0) {
|
||||
/* MOV VAR[var], TEMP[tmp]; */
|
||||
inst->Opcode = OPCODE_MOV;
|
||||
inst->DstReg.File = PROGRAM_VARYING;
|
||||
inst->DstReg.File = type;
|
||||
inst->DstReg.Index = var;
|
||||
inst->SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst->SrcReg[0].Index = outputMap[var];
|
||||
|
||||
@@ -40,6 +40,6 @@ extern void
|
||||
_mesa_count_texture_instructions(struct gl_program *prog);
|
||||
|
||||
extern void
|
||||
_mesa_remove_varying_reads(struct gl_program *prog);
|
||||
_mesa_remove_output_reads(struct gl_program *prog, enum register_file type);
|
||||
|
||||
#endif /* PROGRAMOPT_H */
|
||||
|
||||
@@ -258,9 +258,33 @@ parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len)
|
||||
|
||||
/* evaluate compile-time expression which is array size */
|
||||
_slang_simplify(&array_size, &space, C->atoms);
|
||||
result = (array_size.type == SLANG_OPER_LITERAL_INT);
|
||||
|
||||
*len = (GLint) array_size.literal[0];
|
||||
if (array_size.type == SLANG_OPER_LITERAL_INT) {
|
||||
result = GL_TRUE;
|
||||
*len = (GLint) array_size.literal[0];
|
||||
} else if (array_size.type == SLANG_OPER_IDENTIFIER) {
|
||||
slang_variable *var = _slang_locate_variable(array_size.locals, array_size.a_id, GL_TRUE);
|
||||
if (!var) {
|
||||
slang_info_log_error(C->L, "undefined variable '%s'",
|
||||
(char *) array_size.a_id);
|
||||
result = GL_FALSE;
|
||||
} else if (var->type.qualifier == SLANG_QUAL_CONST &&
|
||||
var->type.specifier.type == SLANG_SPEC_INT) {
|
||||
if (var->initializer &&
|
||||
var->initializer->type == SLANG_OPER_LITERAL_INT) {
|
||||
*len = (GLint) var->initializer->literal[0];
|
||||
result = GL_TRUE;
|
||||
} else {
|
||||
slang_info_log_error(C->L, "unable to parse array size declaration");
|
||||
result = GL_FALSE;
|
||||
}
|
||||
} else {
|
||||
slang_info_log_error(C->L, "unable to parse array size declaration");
|
||||
result = GL_FALSE;
|
||||
}
|
||||
} else {
|
||||
result = GL_FALSE;
|
||||
}
|
||||
|
||||
slang_operation_destruct(&array_size);
|
||||
return result;
|
||||
@@ -2188,7 +2212,8 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
|
||||
printf("Pre-remove output reads:\n");
|
||||
_mesa_print_program(shader->Programs[0]);
|
||||
#endif
|
||||
_mesa_remove_varying_reads(shader->Programs[0]);
|
||||
_mesa_remove_output_reads(shader->Programs[0], PROGRAM_VARYING);
|
||||
_mesa_remove_output_reads(shader->Programs[0], PROGRAM_OUTPUT);
|
||||
#if 0
|
||||
printf("Post-remove output reads:\n");
|
||||
_mesa_print_program(shader->Programs[0]);
|
||||
|
||||
@@ -223,6 +223,7 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
|
||||
assert(st->Size <= 4);
|
||||
src->File = st->File;
|
||||
src->Index = st->Index;
|
||||
src->RelAddr = st->RelAddr;
|
||||
if (st->Swizzle != SWIZZLE_NOOP)
|
||||
src->Swizzle = st->Swizzle;
|
||||
else
|
||||
@@ -1488,11 +1489,16 @@ emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
n->Store->Index = arrayAddr + index;
|
||||
}
|
||||
else {
|
||||
/* Variable index - PROBLEM */
|
||||
const GLint arrayAddr = n->Children[0]->Store->Index;
|
||||
const GLint index = 0;
|
||||
_mesa_problem(NULL, "variable array indexes not supported yet!");
|
||||
n->Store->Index = arrayAddr + index;
|
||||
/* Variable index*/
|
||||
struct prog_instruction *inst;
|
||||
inst = new_instruction(emitInfo, OPCODE_ARL);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store);
|
||||
inst->DstReg.File = PROGRAM_ADDRESS;
|
||||
inst->Comment = _mesa_strdup("ARL ADDR");
|
||||
n->Store->RelAddr = GL_TRUE;
|
||||
n->Store->Index = inst->DstReg.Index;/*index of the array*/
|
||||
inst->DstReg.Index = 0; /*addr index is always 0*/
|
||||
}
|
||||
return NULL; /* no instruction */
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ struct _slang_ir_storage
|
||||
GLint Size; /**< number of floats */
|
||||
GLuint Swizzle;
|
||||
GLint RefCount; /**< Used during IR tree delete */
|
||||
GLboolean RelAddr;
|
||||
};
|
||||
|
||||
typedef struct _slang_ir_storage slang_ir_storage;
|
||||
|
||||
@@ -262,6 +262,9 @@ _slang_resolve_attributes(struct gl_shader_program *shProg,
|
||||
return GL_FALSE;
|
||||
}
|
||||
_mesa_add_attribute(shProg->Attributes, name, size, attr);
|
||||
|
||||
/* set the attribute as used */
|
||||
usedAttributes |= 1<<attr;
|
||||
}
|
||||
|
||||
inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr;
|
||||
|
||||
+9
-56
@@ -241,57 +241,11 @@ SPARC_API = \
|
||||
COMMON_DRIVER_SOURCES = \
|
||||
drivers/common/driverfuncs.c
|
||||
|
||||
X11_DRIVER_SOURCES = \
|
||||
drivers/x11/glxapi.c \
|
||||
drivers/x11/fakeglx.c \
|
||||
drivers/x11/xfonts.c \
|
||||
drivers/x11/xm_api.c \
|
||||
drivers/x11/xm_buffer.c \
|
||||
drivers/x11/xm_dd.c \
|
||||
drivers/x11/xm_glide.c \
|
||||
drivers/x11/xm_line.c \
|
||||
drivers/x11/xm_span.c \
|
||||
drivers/x11/xm_tri.c
|
||||
|
||||
OSMESA_DRIVER_SOURCES = \
|
||||
drivers/osmesa/osmesa.c
|
||||
|
||||
GLIDE_DRIVER_SOURCES = \
|
||||
drivers/glide/fxapi.c \
|
||||
drivers/glide/fxdd.c \
|
||||
drivers/glide/fxddspan.c \
|
||||
drivers/glide/fxddtex.c \
|
||||
drivers/glide/fxsetup.c \
|
||||
drivers/glide/fxtexman.c \
|
||||
drivers/glide/fxtris.c \
|
||||
drivers/glide/fxvb.c \
|
||||
drivers/glide/fxglidew.c \
|
||||
drivers/glide/fxg.c
|
||||
|
||||
SVGA_DRIVER_SOURCES = \
|
||||
drivers/svga/svgamesa.c \
|
||||
drivers/svga/svgamesa8.c \
|
||||
drivers/svga/svgamesa15.c \
|
||||
drivers/svga/svgamesa16.c \
|
||||
drivers/svga/svgamesa24.c \
|
||||
drivers/svga/svgamesa32.c
|
||||
|
||||
FBDEV_DRIVER_SOURCES = \
|
||||
drivers/fbdev/glfbdev.c
|
||||
|
||||
|
||||
### All the core C sources
|
||||
|
||||
ALL_SOURCES = \
|
||||
$(GLAPI_SOURCES) \
|
||||
$(SOLO_SOURCES) \
|
||||
$(ASM_SOURCES) \
|
||||
$(COMMON_DRIVER_SOURCES)\
|
||||
$(X11_DRIVER_SOURCES) \
|
||||
$(FBDEV_DRIVER_SOURCES) \
|
||||
$(OSMESA_DRIVER_SOURCES)
|
||||
|
||||
SOLO_SOURCES = \
|
||||
MESA_SOURCES = \
|
||||
$(MAIN_SOURCES) \
|
||||
$(MATH_SOURCES) \
|
||||
$(VBO_SOURCES) \
|
||||
@@ -299,32 +253,31 @@ SOLO_SOURCES = \
|
||||
$(SHADER_SOURCES) \
|
||||
$(SWRAST_SOURCES) \
|
||||
$(SWRAST_SETUP_SOURCES) \
|
||||
$(COMMON_DRIVER_SOURCES) \
|
||||
$(ASM_C_SOURCES) \
|
||||
$(SLANG_SOURCES)
|
||||
|
||||
CORE_SOURCES = \
|
||||
ALL_SOURCES = \
|
||||
$(MESA_SOURCES) \
|
||||
$(GLAPI_SOURCES) \
|
||||
$(SOLO_SOURCES)
|
||||
$(ASM_SOURCES) \
|
||||
$(COMMON_DRIVER_SOURCES)
|
||||
|
||||
|
||||
|
||||
### Object files
|
||||
|
||||
SOLO_OBJECTS = \
|
||||
$(SOLO_SOURCES:.c=.o) \
|
||||
MESA_OBJECTS = \
|
||||
$(MESA_SOURCES:.c=.o) \
|
||||
$(ASM_SOURCES:.S=.o)
|
||||
|
||||
GLAPI_OBJECTS = \
|
||||
$(GLAPI_SOURCES:.c=.o) \
|
||||
$(ASM_API:.S=.o)
|
||||
|
||||
CORE_OBJECTS = $(SOLO_OBJECTS) $(GLAPI_OBJECTS)
|
||||
|
||||
OSMESA_DRIVER_OBJECTS = $(OSMESA_DRIVER_SOURCES:.c=.o)
|
||||
|
||||
COMMON_DRIVER_OBJECTS = $(COMMON_DRIVER_SOURCES:.c=.o)
|
||||
|
||||
FBDEV_DRIVER_OBJECTS = $(FBDEV_DRIVER_SOURCES:.c=.o)
|
||||
|
||||
|
||||
|
||||
### Include directories
|
||||
|
||||
@@ -832,6 +832,8 @@ _swrast_DestroyContext( GLcontext *ctx )
|
||||
}
|
||||
|
||||
FREE( swrast->SpanArrays );
|
||||
if (swrast->ZoomedArrays)
|
||||
FREE( swrast->ZoomedArrays );
|
||||
FREE( swrast->TexelBuffer );
|
||||
FREE( swrast );
|
||||
|
||||
|
||||
@@ -206,6 +206,7 @@ typedef struct
|
||||
* on some systems.
|
||||
*/
|
||||
SWspanarrays *SpanArrays;
|
||||
SWspanarrays *ZoomedArrays; /**< For pixel zooming */
|
||||
|
||||
/**
|
||||
* Used to buffer N GL_POINTS, instead of rendering one by one.
|
||||
|
||||
+17
-10
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.2
|
||||
* Version: 7.1
|
||||
*
|
||||
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -130,8 +130,8 @@ static void
|
||||
zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
|
||||
const GLvoid *src, GLenum format )
|
||||
{
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
SWspan zoomed;
|
||||
SWspanarrays zoomed_arrays; /* this is big! */
|
||||
GLint x0, x1, y0, y1;
|
||||
GLint zoomedWidth;
|
||||
|
||||
@@ -140,6 +140,13 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
|
||||
return; /* totally clipped */
|
||||
}
|
||||
|
||||
if (!swrast->ZoomedArrays) {
|
||||
/* allocate on demand */
|
||||
swrast->ZoomedArrays = (SWspanarrays *) CALLOC(sizeof(SWspanarrays));
|
||||
if (!swrast->ZoomedArrays)
|
||||
return;
|
||||
}
|
||||
|
||||
zoomedWidth = x1 - x0;
|
||||
ASSERT(zoomedWidth > 0);
|
||||
ASSERT(zoomedWidth <= MAX_WIDTH);
|
||||
@@ -151,14 +158,14 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
|
||||
INIT_SPAN(zoomed, GL_BITMAP);
|
||||
zoomed.x = x0;
|
||||
zoomed.end = zoomedWidth;
|
||||
zoomed.array = &zoomed_arrays;
|
||||
zoomed_arrays.ChanType = span->array->ChanType;
|
||||
if (zoomed_arrays.ChanType == GL_UNSIGNED_BYTE)
|
||||
zoomed_arrays.rgba = (GLchan (*)[4]) zoomed_arrays.rgba8;
|
||||
else if (zoomed_arrays.ChanType == GL_UNSIGNED_SHORT)
|
||||
zoomed_arrays.rgba = (GLchan (*)[4]) zoomed_arrays.rgba16;
|
||||
zoomed.array = swrast->ZoomedArrays;
|
||||
zoomed.array->ChanType = span->array->ChanType;
|
||||
if (zoomed.array->ChanType == GL_UNSIGNED_BYTE)
|
||||
zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba8;
|
||||
else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT)
|
||||
zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba16;
|
||||
else
|
||||
zoomed_arrays.rgba = (GLchan (*)[4]) zoomed_arrays.attribs[FRAG_ATTRIB_COL0];
|
||||
zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->attribs[FRAG_ATTRIB_COL0];
|
||||
|
||||
COPY_4V(zoomed.attrStart[FRAG_ATTRIB_WPOS], span->attrStart[FRAG_ATTRIB_WPOS]);
|
||||
COPY_4V(zoomed.attrStepX[FRAG_ATTRIB_WPOS], span->attrStepX[FRAG_ATTRIB_WPOS]);
|
||||
|
||||
@@ -105,10 +105,10 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
|
||||
const struct gl_vertex_program *vp = ctx->VertexProgram._Current;
|
||||
const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
|
||||
|
||||
if (new_state & (_NEW_HINT)) {
|
||||
if (new_state & (_NEW_HINT | _NEW_PROGRAM)) {
|
||||
ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog);
|
||||
tnl->_DoVertexFog = (tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|
||||
|| !tnl->AllowPixelFog;
|
||||
tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|
||||
|| !tnl->AllowPixelFog) && !fp;
|
||||
}
|
||||
|
||||
tnl->pipeline.new_state |= new_state;
|
||||
@@ -202,8 +202,8 @@ _tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value )
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
tnl->AllowVertexFog = value;
|
||||
tnl->_DoVertexFog = (tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|
||||
|| !tnl->AllowPixelFog;
|
||||
tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|
||||
|| !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current;
|
||||
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ _tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value )
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
tnl->AllowPixelFog = value;
|
||||
tnl->_DoVertexFog = (tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|
||||
|| !tnl->AllowPixelFog;
|
||||
tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|
||||
|| !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current;
|
||||
}
|
||||
|
||||
|
||||
@@ -199,11 +199,11 @@ const struct tnl_pipeline_stage *_tnl_default_pipeline[] = {
|
||||
&_tnl_vertex_transform_stage,
|
||||
&_tnl_normal_transform_stage,
|
||||
&_tnl_lighting_stage,
|
||||
&_tnl_fog_coordinate_stage,
|
||||
&_tnl_texgen_stage,
|
||||
&_tnl_texture_transform_stage,
|
||||
&_tnl_point_attenuation_stage,
|
||||
&_tnl_vertex_program_stage,
|
||||
&_tnl_fog_coordinate_stage,
|
||||
&_tnl_render_stage,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -148,11 +148,11 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
||||
struct fog_stage_data *store = FOG_STAGE_DATA(stage);
|
||||
GLvector4f *input;
|
||||
|
||||
if (!ctx->Fog.Enabled || ctx->VertexProgram._Current)
|
||||
|
||||
if (!ctx->Fog.Enabled)
|
||||
return GL_TRUE;
|
||||
|
||||
|
||||
if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) {
|
||||
if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && !ctx->VertexProgram._Current) {
|
||||
GLuint i;
|
||||
GLfloat *coord;
|
||||
/* Fog is computed from vertex or fragment Z values */
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "main/context.h"
|
||||
#include "main/glheader.h"
|
||||
#include "main/enums.h"
|
||||
|
||||
Reference in New Issue
Block a user