summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2003-03-13 17:13:34 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2003-03-13 17:13:34 +0000
commit9d4857a8169913795b251b0747b565064c2e042b (patch)
tree009b2fd666b7bfada4c197a6ea5babce66c3c413
parent3f00e34097d088a1447d414835c6f51436c7a3a4 (diff)
Very fragile support for VT switching between multiple running apps.
Not safe to use as there is no exclusion from fbdev hw actions at vt switch time.
-rw-r--r--src/glut/mini/init.c103
-rw-r--r--src/glut/mini/window.c49
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c5
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.c50
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.h14
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c6
-rw-r--r--src/mesa/drivers/dri/radeon/server/radeon_common.h4
-rw-r--r--src/mesa/drivers/dri/radeon/server/radeon_dri.c475
-rw-r--r--src/mesa/glapi/glapitemp.h2
-rw-r--r--src/miniglx/Makefile22
-rw-r--r--src/miniglx/dri_util.c6
-rw-r--r--src/miniglx/dri_util.h12
-rw-r--r--src/miniglx/miniglx.c154
-rw-r--r--src/miniglx/miniglxP.h22
-rw-r--r--src/miniglx/xf86drm.c16
-rw-r--r--src/miniglx/xf86drm.h184
16 files changed, 623 insertions, 501 deletions
diff --git a/src/glut/mini/init.c b/src/glut/mini/init.c
index e0feff8a65..5588db9aba 100644
--- a/src/glut/mini/init.c
+++ b/src/glut/mini/init.c
@@ -40,9 +40,6 @@ void APIENTRY glutInit (int *argcp, char **argv)
void APIENTRY glutInitDisplayMode (unsigned int mode)
{
g_display_mode = mode;
-
-/* pc_install_keyb(); */
-/* g_mouse = pc_install_mouse(); */
}
@@ -60,103 +57,3 @@ void APIENTRY glutInitWindowSize (int width, int height)
}
-void APIENTRY glutMainLoop (void)
-{
- GLboolean idle;
- static int old_mouse_x = 0;
- static int old_mouse_y = 0;
- static int old_mouse_b = 0;
-
- glutPostRedisplay();
- if (reshape_func) reshape_func(g_width, g_height);
- if (visibility_func) visibility_func(GLUT_VISIBLE);
-/* if (g_mouse) pc_show_mouse(); */
-
- while (GL_TRUE) {
- idle = GL_TRUE;
-
- if (g_redisplay && display_func) {
- idle = GL_FALSE;
- g_redisplay = GL_FALSE;
-
-/* if (g_mouse && !(g_display_mode & GLUT_DOUBLE)) pc_scare_mouse(); */
- display_func();
-/* if (g_mouse && !(g_display_mode & GLUT_DOUBLE)) pc_unscare_mouse(); */
- }
-
-#if 0
- if (pc_keypressed()) {
- int key;
-
- idle = GL_FALSE;
- key = pc_readkey();
-
- switch (key>>16) {
- case KEY_F1: if (special_func) special_func(GLUT_KEY_F1, 0, 0); break;
- case KEY_F2: if (special_func) special_func(GLUT_KEY_F2, 0, 0); break;
- case KEY_F3: if (special_func) special_func(GLUT_KEY_F3, 0, 0); break;
- case KEY_F4: if (special_func) special_func(GLUT_KEY_F4, 0, 0); break;
- case KEY_F5: if (special_func) special_func(GLUT_KEY_F5, 0, 0); break;
- case KEY_F6: if (special_func) special_func(GLUT_KEY_F6, 0, 0); break;
- case KEY_F7: if (special_func) special_func(GLUT_KEY_F7, 0, 0); break;
- case KEY_F8: if (special_func) special_func(GLUT_KEY_F8, 0, 0); break;
- case KEY_F9: if (special_func) special_func(GLUT_KEY_F9, 0, 0); break;
- case KEY_F10: if (special_func) special_func(GLUT_KEY_F10, 0, 0); break;
- case KEY_F11: if (special_func) special_func(GLUT_KEY_F11, 0, 0); break;
- case KEY_F12: if (special_func) special_func(GLUT_KEY_F12, 0, 0); break;
- case KEY_LEFT: if (special_func) special_func(GLUT_KEY_LEFT, 0, 0); break;
- case KEY_UP: if (special_func) special_func(GLUT_KEY_UP, 0, 0); break;
- case KEY_RIGHT: if (special_func) special_func(GLUT_KEY_RIGHT, 0, 0); break;
- case KEY_DOWN: if (special_func) special_func(GLUT_KEY_DOWN, 0, 0); break;
- case KEY_PGUP: if (special_func) special_func(GLUT_KEY_PAGE_UP, 0, 0); break;
- case KEY_PGDN: if (special_func) special_func(GLUT_KEY_PAGE_DOWN, 0, 0); break;
- case KEY_HOME: if (special_func) special_func(GLUT_KEY_HOME, 0, 0); break;
- case KEY_END: if (special_func) special_func(GLUT_KEY_END, 0, 0); break;
- case KEY_INSERT: if (special_func) special_func(GLUT_KEY_INSERT, 0, 0); break;
- default: if (keyboard_func) keyboard_func(key & 0xFF, 0, 0);
- }
- }
-
- if (g_mouse) {
- int mouse_x;
- int mouse_y;
- int mouse_b;
-
- mouse_b = pc_query_mouse(&mouse_x, &mouse_y);
-
- if (motion_func && ((mouse_x != old_mouse_x) || (mouse_y != old_mouse_y))) {
- idle = GL_FALSE;
- old_mouse_x = mouse_x;
- old_mouse_y = mouse_y;
-
- motion_func(old_mouse_x, old_mouse_y);
- }
-
- if (mouse_func && (mouse_b != old_mouse_b)) {
- int new_mouse_b = mouse_b;
-
- if ((old_mouse_b & 1) && !(new_mouse_b & 1))
- mouse_func(GLUT_LEFT_BUTTON, GLUT_UP, mouse_x, mouse_y);
- else if (!(old_mouse_b & 1) && (new_mouse_b & 1))
- mouse_func(GLUT_LEFT_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
-
- if ((old_mouse_b & 2) && !(new_mouse_b & 2))
- mouse_func(GLUT_RIGHT_BUTTON, GLUT_UP, mouse_x, mouse_y);
- else if (!(old_mouse_b & 2) && (new_mouse_b & 2))
- mouse_func(GLUT_RIGHT_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
-
- if ((old_mouse_b & 4) && !(new_mouse_b & 4))
- mouse_func(GLUT_MIDDLE_BUTTON, GLUT_UP, mouse_x, mouse_y);
- else if (!(old_mouse_b & 3) && (new_mouse_b & 4))
- mouse_func(GLUT_MIDDLE_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
-
- idle = GL_FALSE;
- old_mouse_b = new_mouse_b;
- }
- }
-#endif
-
- if (idle && idle_func)
- idle_func();
- }
-}
diff --git a/src/glut/mini/window.c b/src/glut/mini/window.c
index d3bdc7a944..4c9f9f965f 100644
--- a/src/glut/mini/window.c
+++ b/src/glut/mini/window.c
@@ -218,3 +218,52 @@ void APIENTRY glutShowWindow (void)
void APIENTRY glutHideWindow (void)
{
}
+
+void APIENTRY glutMainLoop (void)
+{
+ GLboolean idle;
+ GLboolean have_event;
+ XEvent evt;
+
+ glutPostRedisplay();
+ if (reshape_func) reshape_func(g_width, g_height);
+
+ while (GL_TRUE) {
+ idle = GL_TRUE;
+
+
+ if (idle_func)
+ have_event = XCheckWindowEvent( dpy, win, ~0, &evt );
+ else
+ have_event = XNextEvent( dpy, &evt );
+
+ if (have_event) {
+ fprintf(stderr, "got event type %d\n", evt.type);
+ idle = GL_FALSE;
+ switch(evt.type) {
+ case MapNotify:
+ if (visibility_func) visibility_func(GLUT_VISIBLE);
+ break;
+ case UnmapNotify:
+ if (visibility_func) visibility_func(GLUT_NOT_VISIBLE);
+ break;
+ case Expose:
+ g_redisplay = 1;
+ break;
+ }
+ }
+
+ if (g_redisplay && display_func) {
+ idle = GL_FALSE;
+ g_redisplay = GL_FALSE;
+
+ fprintf(stderr, "calling display_func()\n");
+ display_func();
+ }
+
+ if (idle && idle_func) {
+ fprintf(stderr, "calling idle_func()\n");
+ idle_func();
+ }
+ }
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index 610d262a5f..08b1f4fc8a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -879,7 +879,10 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv )
b[0] = box[0];
rmesa->sarea->nbox = 1;
}
-
+ else {
+ UNLOCK_HARDWARE( rmesa );
+ return;
+ }
/* Throttle the frame rate -- only allow one pending swap buffers
* request at a time.
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c
index 3ef8b82312..655ae82e51 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.c
@@ -109,6 +109,7 @@ radeonUpdatePageFlipping( radeonContextPtr rmesa )
return;
rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip;
+ rmesa->doPageFlip = 0;
use_back = (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT);
use_back ^= (rmesa->sarea->pfCurrentPage == 1);
@@ -127,23 +128,11 @@ radeonUpdatePageFlipping( radeonContextPtr rmesa )
}
-
-/* Update the hardware state. This is called if another context has
- * grabbed the hardware lock, which includes the X server. This
- * function also updates the driver's window state after the X server
- * moves, resizes or restacks a window -- the change will be reflected
- * in the drawable position and clip rects. Since the X server grabs
- * the hardware lock when it changes the window state, this routine will
- * automatically be called after such a change.
- */
-void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
+static void validate_drawable( radeonContextPtr rmesa )
{
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
- __DRIscreenPrivate *sPriv = rmesa->dri.screen;
- RADEONSAREAPrivPtr sarea = rmesa->sarea;
- int i;
- drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags );
+ fprintf(stderr, "%s\n", __FUNCTION__);
/* The window might have moved, so we might need to get new clip
* rects.
@@ -165,14 +154,45 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
radeonUpdateViewportOffset( rmesa->glCtx );
rmesa->lastStamp = dPriv->lastStamp;
}
+}
+
+
+/* Update the hardware state. This is called if another context has
+ * grabbed the hardware lock, which includes the X server. This
+ * function also updates the driver's window state after the X server
+ * moves, resizes or restacks a window -- the change will be reflected
+ * in the drawable position and clip rects. Since the X server grabs
+ * the hardware lock when it changes the window state, this routine will
+ * automatically be called after such a change.
+ */
+void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
+{
+ RADEONSAREAPrivPtr sarea = rmesa->sarea;
+ int i;
+
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags );
+
+ validate_drawable( rmesa );
if ( sarea->ctxOwner != rmesa->dri.hwContext ) {
sarea->ctxOwner = rmesa->dri.hwContext;
for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) {
- if ( rmesa->texture.heap[i] && sarea->texAge[i] != rmesa->texture.age[i] ) {
+ if ( rmesa->texture.heap[i] &&
+ sarea->texAge[i] != rmesa->texture.age[i] ) {
radeonAgeTextures( rmesa, i );
}
}
}
}
+
+/* In the current miniglx, cliprects can change while the lock is
+ * held... Probably need to fix this.
+ */
+void radeonUnlock( radeonContextPtr rmesa )
+{
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ validate_drawable( rmesa );
+ drmUnlock( rmesa->dri.fd, rmesa->dri.hwContext );
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h
index 5fb071ab44..f8e35369ee 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.h
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.h
@@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define __RADEON_LOCK_H__
extern void radeonGetLock( radeonContextPtr rmesa, GLuint flags );
+extern void radeonUnlock( radeonContextPtr rmesa );
/* Turn DEBUG_LOCKING on to find locking conflicts.
*/
@@ -99,12 +100,13 @@ extern int prevLockLine;
/* Unlock the hardware.
*/
-#define UNLOCK_HARDWARE( rmesa ) \
- do { \
- DRM_UNLOCK( rmesa->dri.fd, \
- rmesa->dri.hwLock, \
- rmesa->dri.hwContext ); \
- DEBUG_RESET(); \
+#define UNLOCK_HARDWARE( rmesa ) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ DRM_CAS( rmesa->dri.hwLock,DRM_LOCK_HELD|rmesa->dri.hwContext, \
+ rmesa->dri.hwContext,__ret); \
+ if (__ret) radeonUnlock( rmesa ); \
+ DEBUG_RESET(); \
} while (0)
#endif /* __RADEON_LOCK_H__ */
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 511d10acfe..6ad1166dcc 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -1126,7 +1126,9 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode )
void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode )
{
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
-
+
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
switch ( mode ) {
case GL_FRONT_LEFT:
rmesa->numClipRects = dPriv->numClipRects;
@@ -1153,6 +1155,8 @@ void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode )
return;
}
+ fprintf(stderr, "%s: %d cliprects\n", __FUNCTION__, rmesa->numClipRects);
+
if (rmesa->state.scissor.enabled)
radeonRecalcScissorRects( rmesa );
}
diff --git a/src/mesa/drivers/dri/radeon/server/radeon_common.h b/src/mesa/drivers/dri/radeon/server/radeon_common.h
index 41c2a0e598..bd808d124b 100644
--- a/src/mesa/drivers/dri/radeon/server/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/server/radeon_common.h
@@ -472,6 +472,10 @@ typedef struct drm_radeon_getparam {
#define RADEON_PARAM_LAST_CLEAR 4
#define RADEON_PARAM_IRQ_NR 5
#define RADEON_PARAM_AGP_BASE 6
+#define RADEON_PARAM_REGISTER_HANDLE 7
+#define RADEON_PARAM_STATUS_HANDLE 8
+#define RADEON_PARAM_SAREA_HANDLE 9
+#define RADEON_PARAM_AGP_TEX_HANDLE 10
#define RADEON_MEM_REGION_AGP 1
diff --git a/src/mesa/drivers/dri/radeon/server/radeon_dri.c b/src/mesa/drivers/dri/radeon/server/radeon_dri.c
index d8702f41e6..fc4f978aed 100644
--- a/src/mesa/drivers/dri/radeon/server/radeon_dri.c
+++ b/src/mesa/drivers/dri/radeon/server/radeon_dri.c
@@ -12,6 +12,8 @@
#include <errno.h>
#include "miniglxP.h"
+#include "dri_util.h"
+#include "drm.h"
#include "radeon.h"
#include "radeon_dri.h"
@@ -517,6 +519,285 @@ static void RADEONDRIIrqInit(struct MiniGLXDisplayRec *dpy,
info->irq);
}
+static int RADEONCheckDRMVersion( struct MiniGLXDisplayRec *dpy,
+ RADEONInfoPtr info )
+{
+ drmVersionPtr version;
+
+ version = drmGetVersion(dpy->drmFD);
+ if (version) {
+ int req_minor, req_patch;
+
+ /* Need 1.8.x for proper cleanup-on-client-exit behaviour.
+ */
+ req_minor = 8;
+ req_patch = 0;
+
+ if (version->version_major != 1 ||
+ version->version_minor < req_minor ||
+ (version->version_minor == req_minor &&
+ version->version_patchlevel < req_patch)) {
+ /* Incompatible drm version */
+ fprintf(stderr,
+ "[dri] RADEONDRIScreenInit failed because of a version "
+ "mismatch.\n"
+ "[dri] radeon.o kernel module version is %d.%d.%d "
+ "but version 1.%d.%d or newer is needed.\n"
+ "[dri] Disabling DRI.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel,
+ req_minor,
+ req_patch);
+ drmFreeVersion(version);
+ return 0;
+ }
+
+ info->drmMinor = version->version_minor;
+ drmFreeVersion(version);
+ }
+
+ return 1;
+}
+
+static int RADEONMemoryInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
+{
+ int width_bytes = dpy->virtualWidth * dpy->cpp;
+ int cpp = dpy->cpp;
+ int bufferSize = ((dpy->virtualHeight * width_bytes
+ + RADEON_BUFFER_ALIGN)
+ & ~RADEON_BUFFER_ALIGN);
+ int depthSize = ((((dpy->virtualHeight+15) & ~15) * width_bytes
+ + RADEON_BUFFER_ALIGN)
+ & ~RADEON_BUFFER_ALIGN);
+ int l;
+
+ info->frontOffset = 0;
+ info->frontPitch = dpy->virtualWidth;
+
+ fprintf(stderr,
+ "Using %d MB AGP aperture\n", info->agpSize);
+ fprintf(stderr,
+ "Using %d MB for the ring buffer\n", info->ringSize);
+ fprintf(stderr,
+ "Using %d MB for vertex/indirect buffers\n", info->bufSize);
+ fprintf(stderr,
+ "Using %d MB for AGP textures\n", info->agpTexSize);
+
+ /* Front, back and depth buffers - everything else texture??
+ */
+ info->textureSize = dpy->FrameBufferSize - 2 * bufferSize - depthSize;
+
+ if (info->textureSize < 0)
+ return 0;
+
+ l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
+ if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
+
+ /* Round the texture size up to the nearest whole number of
+ * texture regions. Again, be greedy about this, don't
+ * round down.
+ */
+ info->log2TexGran = l;
+ info->textureSize = (info->textureSize >> l) << l;
+
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256x32bpp textures.
+ */
+ if (info->textureSize < 512 * 1024) {
+ info->textureOffset = 0;
+ info->textureSize = 0;
+ }
+
+ /* Reserve space for textures */
+ info->textureOffset = ((dpy->FrameBufferSize - info->textureSize +
+ RADEON_BUFFER_ALIGN) &
+ ~RADEON_BUFFER_ALIGN);
+
+ /* Reserve space for the shared depth
+ * buffer.
+ */
+ info->depthOffset = ((info->textureOffset - depthSize +
+ RADEON_BUFFER_ALIGN) &
+ ~RADEON_BUFFER_ALIGN);
+ info->depthPitch = dpy->virtualWidth;
+
+ info->backOffset = ((info->depthOffset - bufferSize +
+ RADEON_BUFFER_ALIGN) &
+ ~RADEON_BUFFER_ALIGN);
+ info->backPitch = dpy->virtualWidth;
+
+
+ fprintf(stderr,
+ "Will use back buffer at offset 0x%x\n",
+ info->backOffset);
+ fprintf(stderr,
+ "Will use depth buffer at offset 0x%x\n",
+ info->depthOffset);
+ fprintf(stderr,
+ "Will use %d kb for textures at offset 0x%x\n",
+ info->textureSize/1024, info->textureOffset);
+
+ info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
+ (info->frontOffset >> 10));
+
+ info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
+ (info->backOffset >> 10));
+
+ info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) |
+ (info->depthOffset >> 10));
+
+ return 1;
+}
+
+static int RADEONGetParam( int fd, int param, int *value )
+{
+ drmRadeonGetParam p;
+ int ret;
+
+ p.param = param;
+ p.value = value;
+
+ ret = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &p, sizeof(p));
+
+ return ret == 0;
+}
+
+static void print_client_msg( RADEONDRIPtr pRADEONDRI )
+{
+ fprintf(stderr, "deviceID 0x%x\n", pRADEONDRI->deviceID);
+ fprintf(stderr, "width 0x%x\n", pRADEONDRI->width);
+ fprintf(stderr, "height 0x%x\n", pRADEONDRI->height);
+ fprintf(stderr, "depth 0x%x\n", pRADEONDRI->depth);
+ fprintf(stderr, "bpp 0x%x\n", pRADEONDRI->bpp);
+ fprintf(stderr, "IsPCI 0x%x\n", pRADEONDRI->IsPCI);
+ fprintf(stderr, "AGPMode 0x%x\n", pRADEONDRI->AGPMode);
+ fprintf(stderr, "frontOffset 0x%x\n", pRADEONDRI->frontOffset);
+ fprintf(stderr, "frontPitch 0x%x\n", pRADEONDRI->frontPitch);
+ fprintf(stderr, "backOffset 0x%x\n", pRADEONDRI->backOffset);
+ fprintf(stderr, "backPitch 0x%x\n", pRADEONDRI->backPitch);
+ fprintf(stderr, "depthOffset 0x%x\n", pRADEONDRI->depthOffset);
+ fprintf(stderr, "depthPitch 0x%x\n", pRADEONDRI->depthPitch);
+ fprintf(stderr, "textureOffset 0x%x\n", pRADEONDRI->textureOffset);
+ fprintf(stderr, "textureSize 0x%x\n", pRADEONDRI->textureSize);
+ fprintf(stderr, "log2TexGran 0x%x\n", pRADEONDRI->log2TexGran);
+ fprintf(stderr, "registerHandle 0x%x\n", (unsigned)pRADEONDRI->registerHandle);
+ fprintf(stderr, "registerSize 0x%x\n", pRADEONDRI->registerSize);
+ fprintf(stderr, "statusHandle 0x%x\n", (unsigned)pRADEONDRI->statusHandle);
+ fprintf(stderr, "statusSize 0x%x\n", pRADEONDRI->statusSize);
+ fprintf(stderr, "agpTexHandle 0x%x\n", (unsigned)pRADEONDRI->agpTexHandle);
+ fprintf(stderr, "agpTexMapSize 0x%x\n", pRADEONDRI->agpTexMapSize);
+ fprintf(stderr, "log2AGPTexGran 0x%x\n", pRADEONDRI->log2AGPTexGran);
+ fprintf(stderr, "agpTexOffset 0x%x\n", pRADEONDRI->agpTexOffset);
+ fprintf(stderr, "sarea_priv_offset 0x%x\n", pRADEONDRI->sarea_priv_offset);
+}
+
+
+static int RADEONScreenJoin( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
+{
+ int s, l;
+ RADEONDRIPtr pRADEONDRI;
+
+ /* Check the radeon DRM version */
+ if (!RADEONCheckDRMVersion(dpy, info)) {
+ return 0;
+ }
+
+ /* Memory manager setup */
+ if (!RADEONMemoryInit(dpy, info)) {
+ return 0;
+ }
+
+ /* Query the kernel for the various map handles (a handle is an
+ * offset into the mmap of dpy->drmFD).
+ */
+ if (!RADEONGetParam(dpy->drmFD, RADEON_PARAM_REGISTER_HANDLE,
+ (int *)&info->registerHandle) ||
+ !RADEONGetParam(dpy->drmFD, RADEON_PARAM_STATUS_HANDLE,
+ (int *)&info->ringReadPtrHandle)||
+ !RADEONGetParam(dpy->drmFD, RADEON_PARAM_SAREA_HANDLE,
+ (int *)&dpy->hSAREA)||
+ !RADEONGetParam(dpy->drmFD, RADEON_PARAM_AGP_TEX_HANDLE,
+ (int *)&info->agpTexHandle)) {
+ fprintf(stderr, "[drm] kernel parameter query failed\n");
+ return 0;
+ }
+
+ dpy->SAREASize = DRM_PAGE_SIZE;
+
+ /* Need to map this one here:
+ */
+ if (drmMap( dpy->drmFD,
+ dpy->hSAREA,
+ dpy->SAREASize,
+ (drmAddressPtr)(&dpy->pSAREA)) < 0)
+ {
+ fprintf(stderr, "[drm] drmMap failed\n");
+ return 0;
+ }
+
+
+ /* These assume that the default values set in __driInitFBDev are
+ * actually the ones in use by the kernel. These include:
+ *
+ * info->agpSize = RADEON_DEFAULT_AGP_SIZE;
+ * info->agpTexSize = RADEON_DEFAULT_AGP_TEX_SIZE;
+ * info->bufSize = RADEON_DEFAULT_BUFFER_SIZE;
+ * info->ringSize = RADEON_DEFAULT_RING_SIZE;
+ *
+ * Probably this should all be queried/deduced here.
+ */
+ info->agpOffset = 0;
+ info->ringStart = info->agpOffset;
+ info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
+ info->ringReadOffset = info->ringStart + info->ringMapSize;
+ info->ringReadMapSize = DRM_PAGE_SIZE;
+ info->bufStart = info->ringReadOffset + info->ringReadMapSize;
+ info->bufMapSize = info->bufSize*1024*1024;
+ info->agpTexStart = info->bufStart + info->bufMapSize;
+ s = (info->agpSize*1024*1024 - info->agpTexStart);
+ l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
+ if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
+ info->agpTexMapSize = (s >> l) << l;
+ info->log2AGPTexGran = l;
+
+ info->registerSize = dpy->FixedInfo.mmio_len;
+
+ /* This is the struct passed to radeon_dri.so for its initialization */
+ dpy->driverClientMsg = malloc(sizeof(RADEONDRIRec));
+ dpy->driverClientMsgSize = sizeof(RADEONDRIRec);
+ pRADEONDRI = (RADEONDRIPtr)dpy->driverClientMsg;
+ pRADEONDRI->deviceID = info->Chipset;
+ pRADEONDRI->width = dpy->virtualWidth;
+ pRADEONDRI->height = dpy->virtualHeight;
+ pRADEONDRI->depth = dpy->bpp; /* XXX: depth */
+ pRADEONDRI->bpp = dpy->bpp;
+ pRADEONDRI->IsPCI = 0;
+ pRADEONDRI->AGPMode = info->agpMode; /* query */
+ pRADEONDRI->frontOffset = info->frontOffset;
+ pRADEONDRI->frontPitch = info->frontPitch;
+ pRADEONDRI->backOffset = info->backOffset;
+ pRADEONDRI->backPitch = info->backPitch;
+ pRADEONDRI->depthOffset = info->depthOffset;
+ pRADEONDRI->depthPitch = info->depthPitch;
+ pRADEONDRI->textureOffset = info->textureOffset;
+ pRADEONDRI->textureSize = info->textureSize;
+ pRADEONDRI->log2TexGran = info->log2TexGran;
+ pRADEONDRI->registerHandle = info->registerHandle; /* param? */
+ pRADEONDRI->registerSize = info->registerSize;
+ pRADEONDRI->statusHandle = info->ringReadPtrHandle; /* param? */
+ pRADEONDRI->statusSize = info->ringReadMapSize;
+ pRADEONDRI->agpTexHandle = info->agpTexHandle; /* param? */
+ pRADEONDRI->agpTexMapSize = info->agpTexMapSize;
+ pRADEONDRI->log2AGPTexGran = info->log2AGPTexGran;
+ pRADEONDRI->agpTexOffset = info->agpTexStart;
+ pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+
+
+ print_client_msg( pRADEONDRI );
+
+ return 1;
+}
/**
@@ -539,8 +820,8 @@ static void RADEONDRIIrqInit(struct MiniGLXDisplayRec *dpy,
static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
{
RADEONDRIPtr pRADEONDRI;
- drmVersionPtr version;
int err;
+ unsigned int serverContext;
usleep(100);
@@ -568,13 +849,21 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
return 0;
}
+ info->registerSize = dpy->FixedInfo.mmio_len;
+ dpy->SAREASize = DRM_PAGE_SIZE;
/* Note that drmOpen will try to load the kernel module, if needed. */
dpy->drmFD = drmOpen("radeon", NULL );
if (dpy->drmFD < 0) {
/* failed to open DRM */
- fprintf(stderr, "[drm] drmOpen failed\n");
- return 0;
+ fprintf(stderr, "[drm] drmOpen failed, trying open by BusID\n");
+
+ dpy->drmFD = drmOpen( NULL, dpy->pciBusID );
+ if (dpy->drmFD >= 0) {
+ fprintf(stderr, "[drm] drmOpen by BusID succeeds...\n");
+ fprintf(stderr, "[drm] ...joining existing session\n");
+ return RADEONScreenJoin( dpy, info );
+ }
}
if ((err = drmSetBusid(dpy->drmFD, dpy->pciBusID)) < 0) {
@@ -583,9 +872,7 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
return 0;
}
-
- dpy->SAREASize = DRM_PAGE_SIZE;
-
+
if (drmAddMap( dpy->drmFD,
0,
dpy->SAREASize,
@@ -628,7 +915,6 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
- info->registerSize = dpy->FixedInfo.mmio_len;
if (drmAddMap(dpy->drmFD,
dpy->FixedInfo.mmio_start,
dpy->FixedInfo.mmio_len,
@@ -642,37 +928,8 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
"[drm] register handle = 0x%08lx\n", info->registerHandle);
/* Check the radeon DRM version */
- version = drmGetVersion(dpy->drmFD);
- if (version) {
- int req_minor, req_patch;
-
- /* Need 1.8.x for proper cleanup-on-client-exit behaviour.
- */
- req_minor = 8;
- req_patch = 0;
-
- if (version->version_major != 1 ||
- version->version_minor < req_minor ||
- (version->version_minor == req_minor &&
- version->version_patchlevel < req_patch)) {
- /* Incompatible drm version */
- fprintf(stderr,
- "[dri] RADEONDRIScreenInit failed because of a version "
- "mismatch.\n"
- "[dri] radeon.o kernel module version is %d.%d.%d "
- "but version 1.%d.%d or newer is needed.\n"
- "[dri] Disabling DRI.\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel,
- req_minor,
- req_patch);
- drmFreeVersion(version);
- return 0;
- }
-
- info->drmMinor = version->version_minor;
- drmFreeVersion(version);
+ if (!RADEONCheckDRMVersion(dpy, info)) {
+ return 0;
}
/* Initialize AGP */
@@ -682,114 +939,31 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
/* Memory manager setup */
- {
- int width_bytes = dpy->virtualWidth * dpy->cpp;
- int cpp = dpy->cpp;
- int bufferSize = ((dpy->virtualHeight * width_bytes
- + RADEON_BUFFER_ALIGN)
- & ~RADEON_BUFFER_ALIGN);
- int depthSize = ((((dpy->virtualHeight+15) & ~15) * width_bytes
- + RADEON_BUFFER_ALIGN)
- & ~RADEON_BUFFER_ALIGN);
- int l;
-
- info->frontOffset = 0;
- info->frontPitch = dpy->virtualWidth;
-
- fprintf(stderr,
- "Using %d MB AGP aperture\n", info->agpSize);
- fprintf(stderr,
- "Using %d MB for the ring buffer\n", info->ringSize);
- fprintf(stderr,
- "Using %d MB for vertex/indirect buffers\n", info->bufSize);
- fprintf(stderr,
- "Using %d MB for AGP textures\n", info->agpTexSize);
-
- /* Front, back and depth buffers - everything else texture??
- */
- info->textureSize = dpy->FrameBufferSize - 2 * bufferSize - depthSize;
-
- if (info->textureSize < 0)
- return 0;
-
- l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
- if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
-
- /* Round the texture size up to the nearest whole number of
- * texture regions. Again, be greedy about this, don't
- * round down.
- */
- info->log2TexGran = l;
- info->textureSize = (info->textureSize >> l) << l;
-
- /* Set a minimum usable local texture heap size. This will fit
- * two 256x256x32bpp textures.
- */
- if (info->textureSize < 512 * 1024) {
- info->textureOffset = 0;
- info->textureSize = 0;
- }
-
- /* Reserve space for textures */
- info->textureOffset = ((dpy->FrameBufferSize - info->textureSize +
- RADEON_BUFFER_ALIGN) &
- ~RADEON_BUFFER_ALIGN);
-
- /* Reserve space for the shared depth
- * buffer.
- */
- info->depthOffset = ((info->textureOffset - depthSize +
- RADEON_BUFFER_ALIGN) &
- ~RADEON_BUFFER_ALIGN);
- info->depthPitch = dpy->virtualWidth;
-
- info->backOffset = ((info->depthOffset - bufferSize +
- RADEON_BUFFER_ALIGN) &
- ~RADEON_BUFFER_ALIGN);
- info->backPitch = dpy->virtualWidth;
-
-
- fprintf(stderr,
- "Will use back buffer at offset 0x%x\n",
- info->backOffset);
- fprintf(stderr,
- "Will use depth buffer at offset 0x%x\n",
- info->depthOffset);
- fprintf(stderr,
- "Will use %d kb for textures at offset 0x%x\n",
- info->textureSize/1024, info->textureOffset);
-
- info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
- (info->frontOffset >> 10));
-
- info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
- (info->backOffset >> 10));
-
- info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) |
- (info->depthOffset >> 10));
- }
+ if (!RADEONMemoryInit(dpy, info)) {
+ return 0;
+ }
/* Create a 'server' context so we can grab the lock for
* initialization ioctls.
*/
- if ((err = drmCreateContext(dpy->drmFD, &dpy->serverContext)) != 0) {
+ if ((err = drmCreateContext(dpy->drmFD, &serverContext)) != 0) {
fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
return 0;
}
- DRM_LOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext, 0);
+ DRM_LOCK(dpy->drmFD, dpy->pSAREA, serverContext, 0);
/* Initialize the kernel data structures */
if (!RADEONDRIKernelInit(dpy, info)) {
fprintf(stderr, "RADEONDRIKernelInit failed\n");
- DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext);
+ DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext);
return 0;
}
/* Initialize the vertex buffers list */
if (!RADEONDRIBufInit(dpy, info)) {
fprintf(stderr, "RADEONDRIBufInit failed\n");
- DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext);
+ DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext);
return 0;
}
@@ -804,7 +978,7 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
/* Initialize and start the CP if required */
if ((err = drmCommandNone(dpy->drmFD, DRM_RADEON_CP_START)) != 0) {
fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err);
- DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext);
+ DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext);
return 0;
}
@@ -818,7 +992,7 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
}
/* Can release the lock now */
- DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext);
+ DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext);
/* This is the struct passed to radeon_dri.so for its initialization */
dpy->driverClientMsg = malloc(sizeof(RADEONDRIRec));
@@ -850,6 +1024,8 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
pRADEONDRI->agpTexOffset = info->agpTexStart;
pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+ print_client_msg( pRADEONDRI );
+
return 1;
}
@@ -1149,6 +1325,42 @@ static void __driHaltFBDev( struct MiniGLXDisplayRec *dpy )
/**
+ * \brief A VT release or aquire signal has been received, and
+ * requires some action. We deal with loosing the VT by setting the
+ * cliprects to zero and emitting an event to the application.
+ */
+static void __driVTSwitchHandler( struct MiniGLXDisplayRec *dpy, int have_vt )
+{
+ int *lock = (int *)dpy->pSAREA;
+ int old, new;
+ DRM_CAS_RESULT(ret);
+ GLXDrawable draw;
+ __DRIdrawable *pdraw;
+ __DRIdrawablePrivate *pdp;
+
+ /* Indicate cliprects have changed
+ */
+ draw = dpy->TheWindow;
+ if (!draw) return;
+ pdraw = &draw->driDrawable;
+ if (!pdraw) return;
+ pdp = (__DRIdrawablePrivate *) pdraw->private;
+ if (!pdp) return;
+ pdp->lastStamp++;
+ pdp->numClipRects = have_vt ? 1 : 0;
+
+ /* Mark the lock contended.
+ */
+ if (!dpy->pSAREA) return;
+ do {
+ old = *(int *)dpy->pSAREA;
+ new = old | _DRM_LOCK_CONT;
+ DRM_CAS( lock, old, new, ret );
+ fprintf(stderr, "old %x new %x\n", old, new );
+ } while (ret);
+}
+
+/**
* \brief Exported driver interface for Mini GLX.
*
* \sa MiniGLXDriverRec.
@@ -1158,5 +1370,6 @@ struct MiniGLXDriverRec __driMiniGLXDriver = {
__driValidateMode,
__driPostValidateMode,
__driInitFBDev,
- __driHaltFBDev
+ __driHaltFBDev,
+ __driVTSwitchHandler
};
diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h
index ba6a093787..ea2b3a67d9 100644
--- a/src/mesa/glapi/glapitemp.h
+++ b/src/mesa/glapi/glapitemp.h
@@ -25,6 +25,8 @@
*
*/
+#include <GL/gl.h>
+#include <GL/glext.h>
#ifndef KEYWORD1
#define KEYWORD1
diff --git a/src/miniglx/Makefile b/src/miniglx/Makefile
index 1baafa5466..cb21e2b39b 100644
--- a/src/miniglx/Makefile
+++ b/src/miniglx/Makefile
@@ -2,6 +2,8 @@
# Indirect rendering not supported, etc.
MESA=../..
+default: libGL.so.1.2 install drmtest
+include $(MESA)/Makefile.include
SOURCES = dispatch.c \
dri_util.c \
@@ -13,15 +15,9 @@ OBJS = $(SOURCES:.c=.o)
INCLUDES = -I. -I.. -I$(MESA)/include
-CFLAGS = -c -g $(INCLUDES) -MD
-
LIBS = -ldl
-
-default: libGL.so.1.2 install drmtest
-
-
libGL.so.1.2: $(OBJS) Makefile
gcc -shared -Wl,-soname,libGL.so -Wl,-Bsymbolic $(OBJS) $(LIBS) -o $@
@@ -33,9 +29,6 @@ install:
ln -s libGL.so.1 $(MESA)/lib/libGL.so
install example.miniglx.conf $(MESA)/lib/miniglx.conf
-#miniglx.a: $(OBJECTS) Makefile
-# rm -f $@ && ar rcv $@ $(OBJECTS) && ranlib $@
-
drmtest: xf86drm.o drmtest.o
rm -f drmtest && $(CC) -o drmtest xf86drm.o drmtest.o
@@ -43,15 +36,4 @@ drmtest: xf86drm.o drmtest.o
glapi.c: ../glapi.c
ln -s ../glapi.c .
-clean:
- rm -f *~ .*~ *.o libGL.so* glapi.c *.d
-
-tags:
- etags *.[ch]
-
-include $(SOURCES:.c=.d)
-
-.SUFFIXES: .c .d
-
-.c.d:
- $(CC) -M $(INCLUDES) $< > $@
diff --git a/src/miniglx/dri_util.c b/src/miniglx/dri_util.c
index 46ba4f8052..02c85358a9 100644
--- a/src/miniglx/dri_util.c
+++ b/src/miniglx/dri_util.c
@@ -282,6 +282,7 @@ static Bool driBindContext(Display *dpy, int scrn,
*/
void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
{
+ fprintf(stderr, "%s\n", __FUNCTION__);
/* nothing to do */
}
@@ -319,7 +320,6 @@ static void driDestroyDrawable(Display *dpy, void *drawablePrivate)
{
__DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate;
__DRIscreenPrivate *psp = pdp->driScreenPriv;
- int scrn = psp->myNum;
if (pdp) {
(*psp->DriverAPI.DestroyBuffer)(pdp);
@@ -455,7 +455,6 @@ static void driDestroyContext(Display *dpy, int scrn, void *contextPrivate)
{
__DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate;
__DRIscreenPrivate *psp = NULL;
- __DRIdrawablePrivate *pdp;
if (pcp) {
(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
@@ -602,8 +601,6 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
const struct __DriverAPIRec *driverAPI)
{
__DRIscreenPrivate *psp;
- char *driverName;
- drmHandle hFB;
psp = (__DRIscreenPrivate *)malloc(sizeof(__DRIscreenPrivate));
if (!psp) {
@@ -700,7 +697,6 @@ __driUtilCreateScreenNoDRM(Display *dpy, int scrn, __DRIscreen *psc,
const struct __DriverAPIRec *driverAPI)
{
__DRIscreenPrivate *psp;
- char *driverName;
psp = (__DRIscreenPrivate *)calloc(1, sizeof(__DRIscreenPrivate));
if (!psp)
diff --git a/src/miniglx/dri_util.h b/src/miniglx/dri_util.h
index cd01b61c39..6ba758a295 100644
--- a/src/miniglx/dri_util.h
+++ b/src/miniglx/dri_util.h
@@ -80,17 +80,7 @@ typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate; /**< \brief Alias f
*/
#define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \
do { \
- while (*(pdp->pStamp) != pdp->lastStamp) { \
- DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, \
- pdp->driContextPriv->hHWContext); \
- \
- DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \
- DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \
- DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \
- \
- DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, \
- pdp->driContextPriv->hHWContext); \
- } \
+ DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \
} while (0)
diff --git a/src/miniglx/miniglx.c b/src/miniglx/miniglx.c
index 007af16c0c..a4de596a3b 100644
--- a/src/miniglx/miniglx.c
+++ b/src/miniglx/miniglx.c
@@ -22,7 +22,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/* $Id: miniglx.c,v 1.1.4.46 2003/02/21 21:14:31 keithw Exp $ */
+/* $Id: miniglx.c,v 1.1.4.47 2003/03/13 17:13:56 keithw Exp $ */
/**
@@ -123,7 +123,6 @@
extern void
__driUtilInitScreen( Display *dpy, int scrn, __DRIscreen *psc );
-
/**
* \brief Current GLX context.
*
@@ -132,8 +131,112 @@ __driUtilInitScreen( Display *dpy, int scrn, __DRIscreen *psc );
static GLXContext CurrentContext = NULL;
-static void SwitchDisplay(int i_signal)
+
+/* Called from signal handler context, runs atomically wrt
+ * XCheckWindowEvent.
+ */
+static void queue_event( Display *dpy, int aquire )
+{
+ dpy->haveVT = aquire;
+ dpy->aquireVTCount += aquire;
+ dpy->releaseVTCount += !aquire;
+}
+
+static Display *SignalDisplay = 0;
+
+static void SwitchVT(int sig)
+{
+ fprintf(stderr, "SwitchVT %d dpy %p\n", sig, SignalDisplay);
+
+ if (!SignalDisplay)
+ return;
+
+ switch( sig )
+ {
+ case SIGUSR1: /* vt has been released */
+ queue_event( SignalDisplay, 0 );
+ if (SignalDisplay->driver)
+ SignalDisplay->driver->handleVTSwitch( SignalDisplay, 0 );
+ ioctl( SignalDisplay->ConsoleFD, VT_RELDISP, 1 );
+ break;
+ case SIGUSR2: /* vt has been acquired */
+ queue_event( SignalDisplay, 1 );
+ if (SignalDisplay->driver)
+ SignalDisplay->driver->handleVTSwitch( SignalDisplay, 1 );
+ ioctl( SignalDisplay->ConsoleFD, VT_RELDISP, VT_ACTIVATE );
+ break;
+ }
+}
+
+
+int XNextEvent(Display *display, XEvent *event_return)
{
+ /* This works because our events are really signals, which will
+ * terminate the sleep early. If keypress, mousemove, etc. events
+ * are ever added to miniglx, this would have to change.
+ */
+ while (!XCheckWindowEvent( display, display->TheWindow, ~0, event_return ))
+ sleep(1);
+
+ return True;
+}
+
+
+Bool XCheckWindowEvent(Display *display, Window w, long event_mask,
+ XEvent *er)
+{
+ if (!w || w != display->TheWindow)
+ return False;
+
+ /* Note: there is no actual queue for these events, so multiple
+ * cycles of aquire & release vt that occur between calls to
+ * XCheckWindowEvent will be lost, with only the current state
+ * being reported. However this should be safe with respect to the
+ * asynchronous arrival of signals, and avoids the issue of what to
+ * do if an event queue were to fill up.
+ */
+ if (display->haveVT) {
+ if (display->mapNotifyCount != display->aquireVTCount) {
+ er->xmap.type = MapNotify;
+ er->xmap.serial = 0;
+ er->xmap.send_event = False;
+ er->xmap.display = display;
+ er->xmap.event = w;
+ er->xmap.window = w;
+ er->xmap.override_redirect = False;
+ display->mapNotifyCount = display->aquireVTCount;
+ return True;
+ }
+ if (display->exposeNotifyCount != display->aquireVTCount) {
+ er->xexpose.type = Expose;
+ er->xexpose.serial = 0;
+ er->xexpose.send_event = False;
+ er->xexpose.display = display;
+ er->xexpose.window = w;
+ er->xexpose.x = 0;
+ er->xexpose.y = 0;
+ er->xexpose.width = w->w;
+ er->xexpose.height = w->h;
+ er->xexpose.count = 0;
+ display->exposeNotifyCount = display->aquireVTCount;
+ return True;
+ }
+ }
+ else {
+ if (display->unmapNotifyCount != display->releaseVTCount) {
+ er->xunmap.type = UnmapNotify;
+ er->xunmap.serial = 0;
+ er->xunmap.send_event = False;
+ er->xunmap.display = display;
+ er->xunmap.event = w;
+ er->xunmap.window = w;
+ er->xunmap.from_configure = False;
+ display->unmapNotifyCount = display->releaseVTCount;
+ return True;
+ }
+ }
+
+ return False;
}
/**********************************************************************/
@@ -180,6 +283,8 @@ OpenFBDev( Display *dpy )
fprintf(stderr, "error: couldn't get a free vt\n");
return GL_FALSE;
}
+
+ fprintf(stderr, "*** got vt nr: %d\n", vtnumber);
close(fd);
/* open the console tty */
@@ -209,39 +314,44 @@ OpenFBDev( Display *dpy )
struct vt_mode vt;
struct sigaction sig_tty;
- if (ioctl(dpy->ConsoleFD, VT_ACTIVATE, vtnumber) != 0)
- printf("ioctl VT_ACTIVATE: %s\n", strerror(errno));
- if (ioctl(dpy->ConsoleFD, VT_WAITACTIVE, vtnumber) != 0)
- printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno));
-
- if (ioctl(dpy->ConsoleFD, VT_GETMODE, &vt) < 0) {
- fprintf(stderr, "error: ioctl VT_GETMODE: %s\n", strerror(errno));
- return GL_FALSE;
- }
-
-
-
/* Set-up tty signal handler to catch the signal we request below */
+ SignalDisplay = dpy;
memset( &sig_tty, 0, sizeof( sig_tty ) );
- sig_tty.sa_handler = SwitchDisplay;
+ sig_tty.sa_handler = SwitchVT;
sigemptyset( &sig_tty.sa_mask );
- if( sigaction( SIGUSR1, &sig_tty, &dpy->OrigSigUsr1 ) )
+ if( sigaction( SIGUSR1, &sig_tty, &dpy->OrigSigUsr1 ) ||
+ sigaction( SIGUSR2, &sig_tty, &dpy->OrigSigUsr2 ) )
{
fprintf(stderr, "error: can't set up signal handler (%s)",
strerror(errno) );
return GL_FALSE;
}
+
vt.mode = VT_PROCESS;
vt.waitv = 0;
vt.relsig = SIGUSR1;
- vt.acqsig = SIGUSR1;
+ vt.acqsig = SIGUSR2;
if (ioctl(dpy->ConsoleFD, VT_SETMODE, &vt) < 0) {
fprintf(stderr, "error: ioctl(VT_SETMODE) failed: %s\n",
strerror(errno));
return GL_FALSE;
}
+
+
+ if (ioctl(dpy->ConsoleFD, VT_ACTIVATE, vtnumber) != 0)
+ printf("ioctl VT_ACTIVATE: %s\n", strerror(errno));
+ if (ioctl(dpy->ConsoleFD, VT_WAITACTIVE, vtnumber) != 0)
+ printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno));
+
+ if (ioctl(dpy->ConsoleFD, VT_GETMODE, &vt) < 0) {
+ fprintf(stderr, "error: ioctl VT_GETMODE: %s\n", strerror(errno));
+ return GL_FALSE;
+ }
+
+
+
}
/* go into graphics mode */
@@ -355,6 +465,9 @@ SetupFBDev( Display *dpy, Window win )
assert(dpy);
+ width = dpy->virtualWidth;
+ height = dpy->virtualHeight;
+
/* Bump size up to next supported mode.
*/
if (width <= 800 && height <= 600) {
@@ -968,8 +1081,6 @@ XOpenDisplay( const char *display_name )
void
XCloseDisplay( Display *display )
{
- GLXContext *ctx;
-
glXMakeCurrent( display, NULL, NULL);
if (display->NumWindows)
@@ -1374,8 +1485,6 @@ glXChooseVisual( Display *dpy, int screen, int *attribList )
GLboolean rgbFlag = GL_FALSE, dbFlag = GL_FALSE, stereoFlag = GL_FALSE;
GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0;
GLint indexBits = 0, depthBits = 0, stencilBits = 0;
- GLint accumRedBits = 0, accumGreenBits = 0;
- GLint accumBlueBits = 0, accumAlphaBits = 0;
GLint numSamples = 0;
int i;
@@ -1843,6 +1952,7 @@ glXQueryVersion( Display *dpy, int *major, int *minor )
(void) dpy;
*major = 1;
*minor = 0;
+ return True;
}
/*@}*/
diff --git a/src/miniglx/miniglxP.h b/src/miniglx/miniglxP.h
index 572a211be9..748f32deef 100644
--- a/src/miniglx/miniglxP.h
+++ b/src/miniglx/miniglxP.h
@@ -205,6 +205,11 @@ struct MiniGLXDriverRec {
* \brief Halt the framebuffer device.
*/
void (*haltFBDev)( struct MiniGLXDisplayRec *dpy );
+
+ /**
+ * \brief Handle VT switch events.
+ */
+ void (*handleVTSwitch)( struct MiniGLXDisplayRec *dpy, int have_vt );
};
@@ -242,6 +247,8 @@ struct MiniGLXVisualRec {
};
+#define MINIGLX_EVENT_QUEUE_SIZE 5
+
/**
* \brief X Window type.
*
@@ -262,6 +269,9 @@ struct MiniGLXWindowRec {
GLubyte *backBottom; /**< \brief pointer to last row */
GLubyte *curBottom; /**< = frontBottom or backBottom */
__DRIdrawable driDrawable;
+ GLuint ismapped;
+ GLuint event_queue[MINIGLX_EVENT_QUEUE_SIZE];
+ GLuint event_queue_len;
};
@@ -289,6 +299,7 @@ struct MiniGLXDisplayRec {
/** \brief original and current variable frambuffer screen info */
struct fb_var_screeninfo OrigVarInfo, VarInfo;
struct sigaction OrigSigUsr1;
+ struct sigaction OrigSigUsr2;
int OriginalVT;
int ConsoleFD; /**< \brief console TTY device file descriptor */
int FrameBufferFD; /**< \brief framebuffer device file descriptor */
@@ -299,6 +310,16 @@ struct MiniGLXDisplayRec {
int NumWindows; /**< \brief number of open windows */
Window TheWindow; /**< \brief open window - only allow one window for now */
+
+ int haveVT;
+ int aquireVTCount;
+ int releaseVTCount;
+ int exposeNotifyCount;
+ int mapNotifyCount;
+ int unmapNotifyCount;
+
+
+
/**
* \name Visual configurations
*/
@@ -350,7 +371,6 @@ struct MiniGLXDisplayRec {
int drmFD; /**< \brief DRM device file descriptor */
unsigned long hSAREA;
unsigned long hFrameBuffer;
- unsigned int serverContext; /* temporary DRM context -- make an auto var? */
int SAREASize;
void *pSAREA;
/*@}*/
diff --git a/src/miniglx/xf86drm.c b/src/miniglx/xf86drm.c
index 85c33af63c..c2cefaa974 100644
--- a/src/miniglx/xf86drm.c
+++ b/src/miniglx/xf86drm.c
@@ -328,6 +328,9 @@ static int drmOpenByName(const char *name)
if ((version = drmGetVersion(fd))) {
if (!strcmp(version->name, name)) {
drmFreeVersion(version);
+
+/* return fd; */
+
id = drmGetBusid(fd);
drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
if (!id || !*id) {
@@ -935,6 +938,7 @@ int drmGetLock(int fd, drmContext context, drmLockFlags flags)
return 0;
}
+static void (*drm_unlock_callback)( void ) = 0;
/**
* \brief Release the hardware lock.
@@ -951,10 +955,20 @@ int drmGetLock(int fd, drmContext context, drmLockFlags flags)
int drmUnlock(int fd, drmContext context)
{
drm_lock_t lock;
+ int ret;
lock.context = context;
lock.flags = 0;
- return ioctl(fd, DRM_IOCTL_UNLOCK, &lock);
+ ret = ioctl(fd, DRM_IOCTL_UNLOCK, &lock);
+
+ /* Need this to synchronize vt releasing. Could also teach fbdev
+ * about the drm lock...
+ */
+ if (drm_unlock_callback) {
+ drm_unlock_callback();
+ }
+
+ return ret;
}
diff --git a/src/miniglx/xf86drm.h b/src/miniglx/xf86drm.h
index 903c7c1b00..0169d89c28 100644
--- a/src/miniglx/xf86drm.h
+++ b/src/miniglx/xf86drm.h
@@ -285,100 +285,6 @@ typedef struct _drmVBlank {
"r" (new)); \
} while (0)
-#elif defined(__alpha__)
-
-#define DRM_CAS(lock, old, new, ret) \
- do { \
- int old32; \
- int cur32; \
- __asm__ __volatile__( \
- " mb\n" \
- " zap %4, 0xF0, %0\n" \
- " ldl_l %1, %2\n" \
- " zap %1, 0xF0, %1\n" \
- " cmpeq %0, %1, %1\n" \
- " beq %1, 1f\n" \
- " bis %5, %5, %1\n" \
- " stl_c %1, %2\n" \
- "1: xor %1, 1, %1\n" \
- " stl %1, %3" \
- : "+r" (old32), \
- "+&r" (cur32), \
- "=m" (__drm_dummy_lock(lock)),\
- "=m" (ret) \
- : "r" (old), \
- "r" (new)); \
- } while(0)
-
-#elif defined(__sparc__)
-
-#define DRM_CAS(lock,old,new,__ret) \
-do { register unsigned int __old __asm("o0"); \
- register unsigned int __new __asm("o1"); \
- register volatile unsigned int *__lock __asm("o2"); \
- __old = old; \
- __new = new; \
- __lock = (volatile unsigned int *)lock; \
- __asm__ __volatile__( \
- /*"cas [%2], %3, %0"*/ \
- ".word 0xd3e29008\n\t" \
- /*"membar #StoreStore | #StoreLoad"*/ \
- ".word 0x8143e00a" \
- : "=&r" (__new) \
- : "0" (__new), \
- "r" (__lock), \
- "r" (__old) \
- : "memory"); \
- __ret = (__new != __old); \
-} while(0)
-
-#elif defined(__ia64__)
-
-#if 0
-/* this currently generates bad code (missing stop bits)... */
-#include <ia64intrin.h>
-
-#define DRM_CAS(lock,old,new,__ret) \
- do { \
- __ret = (__sync_val_compare_and_swap(&__drm_dummy_lock(lock), \
- (old), (new)) \
- != (old)); \
- } while (0)
-
-#else
-#define DRM_CAS(lock,old,new,__ret) \
- do { \
- unsigned int __result, __old = (old); \
- __asm__ __volatile__( \
- "mf\n" \
- "mov ar.ccv=%2\n" \
- ";;\n" \
- "cmpxchg4.acq %0=%1,%3,ar.ccv" \
- : "=r" (__result), "=m" (__drm_dummy_lock(lock)) \
- : "r" (__old), "r" (new) \
- : "memory"); \
- __ret = (__result) != (__old); \
- } while (0)
-
-#endif
-
-#elif defined(__powerpc__)
-
-#define DRM_CAS(lock,old,new,__ret) \
- do { \
- __asm__ __volatile__( \
- "sync;" \
- "0: lwarx %0,0,%1;" \
- " xor. %0,%3,%0;" \
- " bne 1f;" \
- " stwcx. %2,0,%1;" \
- " bne- 0b;" \
- "1: " \
- "sync;" \
- : "=&r"(__ret) \
- : "r"(lock), "r"(new), "r"(old) \
- : "cr0", "memory"); \
- } while (0)
#endif /* architecture */
#endif /* __GNUC__ >= 2 */
@@ -400,19 +306,6 @@ do { register unsigned int __old __asm("o0"); \
if (__ret) drmGetLock(fd,context,0); \
} while(0)
-/**
- * \brief Counts fast locks.
- *
- * \note For benchmarking only.
- */
-#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \
- do { \
- DRM_CAS_RESULT(__ret); \
- DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
- if (__ret) drmGetLock(fd,context,0); \
- else ++count; \
- } while(0)
-
#define DRM_LOCK(fd,lock,context,flags) \
do { \
if (flags) drmGetLock(fd,context,flags); \
@@ -426,47 +319,6 @@ do { register unsigned int __old __asm("o0"); \
if (__ret) drmUnlock(fd,context); \
} while(0)
-/**
- * \brief Simple spin locks.
- */
-#define DRM_SPINLOCK(spin,val) \
- do { \
- DRM_CAS_RESULT(__ret); \
- do { \
- DRM_CAS(spin,0,val,__ret); \
- if (__ret) while ((spin)->lock); \
- } while (__ret); \
- } while(0)
-
-#define DRM_SPINLOCK_TAKE(spin,val) \
- do { \
- DRM_CAS_RESULT(__ret); \
- int cur; \
- do { \
- cur = (*spin).lock; \
- DRM_CAS(spin,cur,val,__ret); \
- } while (__ret); \
- } while(0)
-
-#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \
- do { \
- int __i; \
- __ret = 1; \
- for (__i = 0; __ret && __i < count; __i++) { \
- DRM_CAS(spin,0,val,__ret); \
- if (__ret) for (;__i < count && (spin)->lock; __i++); \
- } \
- } while(0)
-
-#define DRM_SPINUNLOCK(spin,val) \
- do { \
- DRM_CAS_RESULT(__ret); \
- if ((*spin).lock == val) { /* else server stole lock */ \
- do { \
- DRM_CAS(spin,val,0,__ret); \
- } while (__ret); \
- } \
- } while(0)
/* General user-level programmer's API: unprivileged */
extern int drmAvailable(void);
@@ -577,45 +429,9 @@ extern unsigned long drmAgpMemoryAvail(int fd);
extern unsigned int drmAgpVendorId(int fd);
extern unsigned int drmAgpDeviceId(int fd);
-/* PCI scatter/gather support: X server (root) only */
-extern int drmScatterGatherAlloc(int fd, unsigned long size,
- unsigned long *handle);
-extern int drmScatterGatherFree(int fd, unsigned long handle);
-
-extern int drmWaitVBlank(int fd, drmVBlankPtr vbl);
-
/* Support routines */
extern int drmError(int err, const char *label);
extern void *drmMalloc(int size);
extern void drmFree(void *pt);
-/* Hash table routines */
-extern void *drmHashCreate(void);
-extern int drmHashDestroy(void *t);
-extern int drmHashLookup(void *t, unsigned long key, void **value);
-extern int drmHashInsert(void *t, unsigned long key, void *value);
-extern int drmHashDelete(void *t, unsigned long key);
-extern int drmHashFirst(void *t, unsigned long *key, void **value);
-extern int drmHashNext(void *t, unsigned long *key, void **value);
-
-/* PRNG routines */
-extern void *drmRandomCreate(unsigned long seed);
-extern int drmRandomDestroy(void *state);
-extern unsigned long drmRandom(void *state);
-extern double drmRandomDouble(void *state);
-
-/* Skip list routines */
-
-extern void *drmSLCreate(void);
-extern int drmSLDestroy(void *l);
-extern int drmSLLookup(void *l, unsigned long key, void **value);
-extern int drmSLInsert(void *l, unsigned long key, void *value);
-extern int drmSLDelete(void *l, unsigned long key);
-extern int drmSLNext(void *l, unsigned long *key, void **value);
-extern int drmSLFirst(void *l, unsigned long *key, void **value);
-extern void drmSLDump(void *l);
-extern int drmSLLookupNeighbors(void *l, unsigned long key,
- unsigned long *prev_key, void **prev_value,
- unsigned long *next_key, void **next_value);
-
#endif