Hi!

I have problem initializing standalone mesa (linux-solo) WITHOUT using
the MiniGLX API for my GPLed 3D desktop attempt.

I am able to create screen, drawable and context, then bind these three
elements, but when calling gl* functions screen is always black, i put
fprintf's in r200 driver and the right functions are called but no drawing
occur, i am calling  `(*dri->drawable->swapBuffers)(dri->drawable);` to
swap the buffers.

ldd report libGL.so in right location, and dlopen works nicely with
r200_dri.so

Demos in progs/miniglx works correctly so i am pretty sure i am the faulty
one :)

Here is the last part of my DRI initialization routine, everything
before this is fbdev setup and works perfectly, do i am missing
some obvious things?

Attached is my complete DRI initialization routines in case you need the
full picture.

Thanks in advance!

-solca

----------- CUT&PASTE -----------

        /* post validate DRI driver context */
        if(!dri->driver->postValidateMode(&dri->driverContext)) {
                ee_error_num(0, "[dri] unable to post validate driver context", 
fbdev->path);
                return -1;
        }

        /* restore hardware state */
        dri->driver->restoreHardware(&dri->driverContext);

        /* unlock DRM */
        DRM_UNLOCK(dri->driverContext.drmFD, dri->driverContext.pSAREA, 
dri->driverContext.serverContext);

        /* create DRI screen */
        dri->screen = (*dri->screenCreate)(dri->driver, &dri->driverContext);
        if(!dri->screen) {
                ee_error_num(0, "[dri] function '%s' in '%s' failed", 
"__driCreateScreen", dri->path);
                return -1;
        } else
                ee_error_num(0, "[dri] create DRI screen   (@ %p) successfully", 
dri->screen);

        /* create DRI drawable */
        dri->drawable = (*dri->screen->createDrawable)
                        (dri->screen,
                         dri->driverContext.shared.virtualWidth,
                         dri->driverContext.shared.virtualHeight,
                         0, dri->driverMode);
        if(!dri->drawable) {
                ee_error_num(0, "[dri] function '%s' in '%s' failed", 
"__driCreateDrawable", dri->path);
                return -1;
        } else
                ee_error_num(0, "[dri] create DRI drawable (@ %p) successfully", 
dri->drawable);

        /* create DRI context */
        dri->context =  (*dri->screen->createContext)
                        (dri->screen,
                         dri->driverMode,
                         NULL);
        if(!dri->context) {
                ee_error_num(0, "[dri] function '%s' in '%s' failed", 
"__driCreateContext", dri->path);
                return -1;
        } else
                ee_error_num(0, "[dri] create DRI context  (@ %p) successfully", 
dri->context);

        /* bind screen, drawable and context so we can began issuing GL commands */
        (*dri->context->bindContext)(dri->screen, dri->drawable, dri->context);
        ee_error_num(0, "[dri] screen, drawable and context bound");

        /* set the drawable flag */
        dri->driverContext.pSAREA->drawableTable[0].stamp++;
        dri->driverContext.pSAREA->drawableTable[0].flags = flag;

        /* setup finish here */
        ee_error_num(0, "[dri] setup finished");

        /* return successfully */
        return 0;

--------- END CUT&PASTE ---------

static int ee_server_graphic_dri_init(struct ee_server_graphic_dri *dri) {
	
	/* no dri, is worthless */
	if(!dri)
		return -1;

	/* if no path is provided use r200_dri.so as default */
	if(!dri->path)
		dri->path = "r200_dri.so";

	/* try to load the dri driver */
	dri->dl = dlopen(dri->path, RTLD_NOW | RTLD_GLOBAL);
	if(!dri->dl) {
		ee_error("[dri] could not load %s", dlerror());
		if(dri->dl)
			ee_error_num(0, "[dri] '%s' must match same version than libGL", dri->path);
		return -1;
	} else
		ee_error_num(0, "[dri] Standalone MESA DRI driver '%s' loaded", dri->path);

	/* pull DRI driver hooks */

	dri->driver = (struct DRIDriverRec *) dlsym(dri->dl, "__driDriver");
	if(!dri->driver) {
		ee_error("[dri] could not find '%s' in '%s'", "__driDriver", dri->path);
		return -1;
	}

	dri->screenCreate = (driCreateScreenFunc*) dlsym(dri->dl, "__driCreateScreen");
	if(!dri->screenCreate) {
		ee_error("[dri] could not find '%s' in '%s'", "__driCreateScreen", dri->path);
		return -1;
	}

	/* return successfully */
	return 0;

} /* ee_server_graphic_dri_init */

static void ee_server_graphic_dri_drawable(struct ee_server_graphic_dri *dri, int flag) {

	/* no dri, is worthless */
	if(!dri)
		return;

	/* lock DRM */
	if(*dri->active)
		DRM_LIGHT_LOCK(dri->driverContext.drmFD, dri->driverContext.pSAREA, dri->driverContext.serverContext);

	/* set the flag */
	dri->driverContext.pSAREA->drawableTable[0].stamp++;
	dri->driverContext.pSAREA->drawableTable[0].flags = flag;

	/* unlock DRM */
	if(*dri->active)
		DRM_UNLOCK(dri->driverContext.drmFD, dri->driverContext.pSAREA, dri->driverContext.serverContext);

} /* ee_server_graphic_dri_drawable */

static void ee_server_graphic_dri_fini(struct ee_server_graphic_dri *dri) {

	/* no dri, is worthless */
	if(!dri)
		return;

	/* unbind and destroy the DRI context */
	if(dri->context) {
		/* mark as no drawable */
		ee_server_graphic_dri_drawable(dri, 0);

		(*dri->context-> unbindContext)(dri->drawable, dri->context);
		(*dri->context->destroyContext)(dri->context);
		dri->context = NULL;
	}

	/* destroy the DRI drawable */
	if(dri->drawable) {
		(*dri->drawable->destroyDrawable)(dri->drawable);
		dri->drawable = NULL;
	}

	/* destroy the DRI screen */
	if(dri->screen) {
		(*dri->screen->destroyScreen)(dri->screen);
		(*dri->driver->haltFBDev)(&dri->driverContext);
		dri->screen = NULL;
	}

	/* close the DRI dl handle */
	if(dri->dl)
		dlclose(dri->dl);

	/* invalidate pointers */
	dri->driver = NULL;
	dri->screenCreate  = NULL;

	/* avoid surprises, make the dl handle invalid */
	dri->dl = 0;
	
	/* inform user that dri have been properly shutdown */
	ee_error_num(0, "[dri] finished");

} /* ee_server_graphic_dri_fini */

static int ee_server_graphic_dri_setup(struct ee_server_graphic_fbdev *fbdev, struct ee_server_graphic_dri *dri) {

	int numValidModes;

	/* no dri nor fbdev, is worthless */
	if(!dri  ||  !fbdev)
		return -1;

	/* destroy DRI key structures so we can create it again */

	/* destroy and unbind the DRI context */
	if(dri->context) {
		(*dri->context-> unbindContext)(dri->drawable, dri->context);
		(*dri->context->destroyContext)(dri->context);
		dri->context = NULL;
	}

	/* destroy the DRI drawable */
	if(dri->drawable) {
		(*dri->drawable->destroyDrawable)(dri->drawable);
		dri->drawable = NULL;
	}

	/* destroy the DRI screen */
	if(dri->screen) {
		(*dri->screen->destroyScreen)(dri->screen);
		(*dri->driver->haltFBDev)(&dri->driverContext);
		dri->screen = NULL;
	}

	/* hopefully someday we'll be independent of fbdev for DRI setup */
	/* setup DRI to a usable state */

	dri->driverContext.cpp			= dri->driverContext.bpp / 8;
	dri->driverContext.shared.fbSize	= fbdev->info_fixed.smem_len;
	dri->driverContext.shared.fbStride	= dri->driverContext.shared.virtualWidth * (dri->driverContext.bpp / 8);
	/* fbdev context info */
	dri->driverContext.FBStart	 = fbdev->info_fixed.smem_start;
	dri->driverContext.FBSize	 = fbdev->info_fixed.smem_len;
	dri->driverContext.shared.fbSize = fbdev->info_fixed.smem_len;
	dri->driverContext.FBAddress	 = fbdev->mmap_fb;
	/* fbdev MMIO region context info */
	dri->driverContext.MMIOStart	 = fbdev->info_fixed.mmio_start;
	dri->driverContext.MMIOSize	 = fbdev->info_fixed.mmio_len;
	dri->driverContext.MMIOAddress	 = fbdev->mmap_mmio;

	/* inform user about configuration */
	ee_error_num(0, "[dri] setup");
	ee_error_num(0, "[dri] Bus ID %s", dri->driverContext.pciBusID);
	ee_error_num(0, "[dri] Chipset %04X", dri->driverContext.chipset);
	ee_error_num(0, "[dri] Visual Geometry %dx%d-%dbpp",
			dri->driverContext.shared.virtualWidth,
			dri->driverContext.shared.virtualHeight,
			dri->driverContext.bpp);
	ee_error_num(0, "[dri] FB Address %p mapped at %p", dri->driverContext.FBStart, dri->driverContext.FBAddress);
	ee_error_num(0, "[dri] FB Size %d bytes", dri->driverContext.FBSize);
	ee_error_num(0, "[dri] FB MMIO Address %p mapped at %p", dri->driverContext.MMIOStart, dri->driverContext.MMIOAddress);
	ee_error_num(0, "[dri] FB MMIO Size %d bytes", dri->driverContext.MMIOSize);

	/* ask DRI driver for list of supported configs */
	dri->driver->initContextModes(&dri->driverContext, &dri->driverNumModes, &dri->driverModes);

	/* report supported dri hardware visual modes */
	numValidModes = 0;
	ee_error_num(0, "[dri] Number of reported visuals: %d", dri->driverNumModes);
	for(int i = 0; i < dri->driverNumModes; i++) {
		const __GLcontextModes *mode = dri->driverModes + i;

		/* no RGBA mode nor Index mode, is an invalid mode */
		if(mode->rgbMode != GL_TRUE  &&  mode->colorIndexMode != GL_TRUE)
			continue;

		ee_error_num(0, "[dri]\tVisual ID %02d", i);
		if(mode->rgbMode == GL_TRUE)
			ee_error_num(0, "[dri]\t\tColor RGBA %d/%d/%d/%d",
					mode->redBits, mode->greenBits, mode->blueBits, mode->alphaBits);
		if(mode->colorIndexMode == GL_TRUE)
			ee_error_num(0, "[dri]\t\tColor Index %d bits", mode->indexBits);
		if(mode->doubleBufferMode == GL_TRUE)
			ee_error_num(0, "[dri]\t\tDouble Buffer Mode");
		if(mode->stereoMode == GL_TRUE)
			ee_error_num(0, "[dri]\t\tStereo Buffer Mode");
		if(mode->haveAccumBuffer == GL_TRUE)
			ee_error_num(0, "[dri]\t\tAccumulation Buffer RGBA %d/%d/%d/%d",
					mode->accumRedBits, mode->accumGreenBits, mode->accumBlueBits, mode->accumAlphaBits);
		if(mode->haveDepthBuffer == GL_TRUE)
			ee_error_num(0, "[dri]\t\tDepth Buffer %d bits", mode->depthBits);
		if(mode->haveStencilBuffer == GL_TRUE)
			ee_error_num(0, "[dri]\t\tStencil Buffer %d bits", mode->stencilBits);
		ee_error_num(0, "[dri]\t\tAuxiliary Buffers %d", mode->numAuxBuffers);
		ee_error_num(0, "[dri]\t\tLevel %d - Pixel Map Mode %d", mode->level, mode->pixmapMode);

		/* increment valid count */
		numValidModes++;

		/* check if this visual is what we need */
		if(mode->          rgbMode == GL_TRUE  &&
		   mode->          redBits == 8  &&
		   mode->        greenBits == 8  &&
		   mode->         blueBits == 8  &&
		   mode->        alphaBits == 8  &&
		   mode-> doubleBufferMode == GL_TRUE  &&
		   mode->       stereoMode != GL_TRUE  &&
		   mode->  haveAccumBuffer != GL_TRUE  &&
		   mode->  haveDepthBuffer == GL_TRUE  &&
		   mode->        depthBits == 24  &&
		   mode->haveStencilBuffer == GL_TRUE  &&
		   mode->      stencilBits == 8  &&
		   mode->    numAuxBuffers == 0  &&
		   mode->            level == 0  &&
		   mode->       pixmapMode == 0) {
			dri->driverMode = mode;
			ee_error_num(0, "[dri]\tChoosen visual: %02d", i);
		}
	}
	ee_error_num(0, "[dri] Number of valid visuals: %d", numValidModes);

	/* check if we choose a visual */
	if(!dri->driverMode) {
		ee_error_num(0, "[dri] Could not find a useful visual");
		return -1;
	}

	/* perform fbdev DRI driver initialization */
	if(!dri->driver->initFBDev(&dri->driverContext)) {
		ee_error("[dri] function '%s' in '%s' have failed", "__driInitFBDev", dri->path);
		return -1;
	}

	/* set fbdev geometry */
	fbdev->info_var_current.bits_per_pixel	= dri->driverContext.bpp;
	fbdev->info_var_current.xres_virtual	= dri->driverContext.shared.virtualWidth;
	fbdev->info_var_current.yres_virtual	= dri->driverContext.shared.virtualHeight;
	fbdev->info_var_current.xres		= dri->driverContext.shared.virtualWidth;
	fbdev->info_var_current.yres		= dri->driverContext.shared.virtualHeight;
	fbdev->info_var_current.xoffset		= 0;
	fbdev->info_var_current.yoffset		= 0;
	fbdev->info_var_current.nonstd		= 0;
	fbdev->info_var_current.vmode		= ~FB_VMODE_YWRAP;

	if(fbdev->info_var_current.bits_per_pixel == 32) {
		fbdev->info_var_current.transp.offset	= 24;
		fbdev->info_var_current.transp.length	= 8;
		fbdev->info_var_current.red.offset	= 16;
		fbdev->info_var_current.red.length	= 8;
		fbdev->info_var_current.green.offset	= 8;
		fbdev->info_var_current.green.length	= 8;
		fbdev->info_var_current.blue.offset	= 0;
		fbdev->info_var_current.blue.length	= 8;
	/* } else if(fbdev->info_var_current.bits_per_pixel == 16) {
		fbdev->info_var_current.transp.offset	= 24;
		fbdev->info_var_current.transp.length	= 8;
		fbdev->info_var_current.red.offset	= 16;
		fbdev->info_var_current.red.length	= 8;
		fbdev->info_var_current.green.offset	= 8;
		fbdev->info_var_current.green.length	= 8;
		fbdev->info_var_current.blue.offset	= 0;
		fbdev->info_var_current.blue.length	= 8; */
	} else {
		ee_error_num(0, "[dri] Visual depth of 32bpp required, depth requested: %d bpp",
			     fbdev->info_var_current.bits_per_pixel);
		return -1;
	}

	/* inform about color space setup */

	ee_error_num(0, "[dri] fbdev '%s' RGBA configuration: %d/%d,%d/%d,%d/%d,%d/%d", fbdev->path,
			fbdev->info_var_current.   red.length, fbdev->info_var_current.   red.offset,
			fbdev->info_var_current. green.length, fbdev->info_var_current. green.offset,
			fbdev->info_var_current.  blue.length, fbdev->info_var_current.  blue.offset,
			fbdev->info_var_current.transp.length, fbdev->info_var_current.transp.offset);

	/* DRI driver context validation */
	if(!dri->driver->validateMode(&dri->driverContext)) {
		ee_error("[dri] context validation failed");
		return -1;
	}

	/* set the fbdev timings (from fb.modes) for our requested mode */
	if(fbdev->info_var_current.xres == 1280  &&  /* 1280x1024-75 */
	   fbdev->info_var_current.yres == 1024) {
		fbdev->info_var_current.pixclock	= 7408;
		fbdev->info_var_current. left_margin	= 248;
		fbdev->info_var_current.right_margin	= 16;
		fbdev->info_var_current.upper_margin	= 38;
		fbdev->info_var_current.lower_margin	= 1;
		fbdev->info_var_current.hsync_len	= 144;
		fbdev->info_var_current.hsync_len	= 3;
	} else if(fbdev->info_var_current.xres == 1024  &&  /* 1024x768-75 */
	   fbdev->info_var_current.yres == 768) {
		fbdev->info_var_current.pixclock	= 12699;
		fbdev->info_var_current. left_margin	= 176;
		fbdev->info_var_current.right_margin	= 16;
		fbdev->info_var_current.upper_margin	= 28;
		fbdev->info_var_current.lower_margin	= 1;
		fbdev->info_var_current.hsync_len	= 96;
		fbdev->info_var_current.hsync_len	= 3;
	} else if(fbdev->info_var_current.xres == 768  &&  /* 768x1024-75 */
	   fbdev->info_var_current.yres == 1024) {
		fbdev->info_var_current.pixclock	= 11993;
		fbdev->info_var_current. left_margin	= 136;
		fbdev->info_var_current.right_margin	= 32;
		fbdev->info_var_current.upper_margin	= 41;
		fbdev->info_var_current.lower_margin	= 1;
		fbdev->info_var_current.hsync_len	= 80;
		fbdev->info_var_current.hsync_len	= 3;
	} else if(fbdev->info_var_current.xres == 800  &&  /* 800x600-75 */
	   fbdev->info_var_current.yres == 600) {
		fbdev->info_var_current.pixclock	= 20203;
		fbdev->info_var_current. left_margin	= 160;
		fbdev->info_var_current.right_margin	= 16;
		fbdev->info_var_current.upper_margin	= 21;
		fbdev->info_var_current.lower_margin	= 1;
		fbdev->info_var_current.hsync_len	= 80;
		fbdev->info_var_current.hsync_len	= 3;
	} else if(fbdev->info_var_current.xres == 640  &&  /* 640x480-60 */
	   fbdev->info_var_current.yres == 480) {
		fbdev->info_var_current.pixclock	= 20203;
		fbdev->info_var_current. left_margin	= 160;
		fbdev->info_var_current.right_margin	= 16;
		fbdev->info_var_current.upper_margin	= 21;
		fbdev->info_var_current.lower_margin	= 1;
		fbdev->info_var_current.hsync_len	= 80;
		fbdev->info_var_current.hsync_len	= 3;
	} else {
		ee_error_num(0, "[dri] Visual mode not supported: %dx%d-%d",
				fbdev->info_var_current.xres,
				fbdev->info_var_current.yres,
				fbdev->info_var_current.bits_per_pixel);
		return -1;
	}

	/* set the fbdev variable screen information */
	if(ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->info_var_current) != 0) {
		ee_error("[dri] could not set screen info for fbdev '%s'", fbdev->path);
		return -1;
	}

	/* read back variable screen information in case kernel change it */
	if(ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->info_var_current) != 0) {
		ee_error("[dri] could not get screen info from fbdev '%s'", fbdev->path);
		return -1;
	}

	/* read fixed screen information */
	if(ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->info_fixed) != 0) {
		ee_error("[dri] could not get screen fixed info from fbdev '%s'", fbdev->path);
		return -1;
	}

	/* we just support true-color or direct-color (with a palette) visuals */
	if(fbdev->info_fixed.visual != FB_VISUAL_TRUECOLOR  &&
	   fbdev->info_fixed.visual != FB_VISUAL_DIRECTCOLOR) {
		ee_error_num(0, "[dri] fbdev '%s' does not support a true-color visual", fbdev->path);
		return -1;
	}

	/* if visual is direct-color we need to setup a color palette */
	if(fbdev->info_fixed.visual == FB_VISUAL_DIRECTCOLOR) {
		struct fb_cmap map;
		unsigned short red[256], green[256], blue[256];
		int rcols = 1 << fbdev->info_var_current.  red.length;
		int gcols = 1 << fbdev->info_var_current.green.length;
		int bcols = 1 << fbdev->info_var_current. blue.length;
		int i;

		map.start  = 0;
		map.len    = gcols;
		map.red    = red;
		map.green  = green;
		map.blue   = blue;
		map.transp = NULL;

		for(i = 0; i < rcols; i++)
			  red[i] = (65536 / (rcols - 1)) * i;

		for(i = 0; i < gcols; i++)
			green[i] = (65536 / (gcols - 1)) * i;

		for(i = 0; i < rcols; i++)
			 blue[i] = (65536 / (bcols - 1)) * i;

		if(ioctl(fbdev->fd, FBIOPUTCMAP, (void *) &map) != 0) {
			ee_error("[dri] could not set color palette for direct-color visual on fbdev '%s'", fbdev->path);
			return -1;
		} else
			ee_error("[dri] color palette installed for direct-color visual on fbdev '%s'", fbdev->path);
	}

	/* post validate DRI driver context */
	if(!dri->driver->postValidateMode(&dri->driverContext)) {
		ee_error_num(0, "[dri] unable to post validate driver context", fbdev->path);
		return -1;
	}

	/* restore hardware state */
	dri->driver->restoreHardware(&dri->driverContext);

	/* unlock DRM */
	DRM_UNLOCK(dri->driverContext.drmFD, dri->driverContext.pSAREA, dri->driverContext.serverContext);

	/* create DRI screen */
	dri->screen = (*dri->screenCreate)(dri->driver, &dri->driverContext);
	if(!dri->screen) {
		ee_error_num(0, "[dri] function '%s' in '%s' failed", "__driCreateScreen", dri->path);
		return -1;
	} else
		ee_error_num(0, "[dri] create DRI screen   (@ %p) successfully", dri->screen);

	/* create DRI drawable */
	dri->drawable = (*dri->screen->createDrawable)
			(dri->screen,
			 dri->driverContext.shared.virtualWidth,
			 dri->driverContext.shared.virtualHeight,
			 0, dri->driverMode);
	if(!dri->drawable) {
		ee_error_num(0, "[dri] function '%s' in '%s' failed", "__driCreateDrawable", dri->path);
		return -1;
	} else
		ee_error_num(0, "[dri] create DRI drawable (@ %p) successfully", dri->drawable);

	/* create DRI context */
	dri->context =  (*dri->screen->createContext)
			(dri->screen,
			 dri->driverMode,
			 NULL);
	if(!dri->context) {
		ee_error_num(0, "[dri] function '%s' in '%s' failed", "__driCreateContext", dri->path);
		return -1;
	} else
		ee_error_num(0, "[dri] create DRI context  (@ %p) successfully", dri->context);

	/* bind screen, drawable and context so we can began issuing GL commands */
	(*dri->context->bindContext)(dri->screen, dri->drawable, dri->context);
	ee_error_num(0, "[dri] screen, drawable and context bound");

	/* setup finish here */
	ee_error_num(0, "[dri] setup finished");

	/* return successfully */
	return 0;

} /* ee_server_graphic_dri_setup */

static void ee_server_graphic_dri_swapbuffers(struct ee_server_graphic_dri *dri) {

	/* if no dri nor drawable, is worthless */
	if(!dri  ||  !dri->drawable)
		return;

	/* swap the front & back buffers */
	(*dri->drawable->swapBuffers)(dri->drawable);

} /* ee_server_graphic_dri_swapbuffers */

static int ee_server_graphic_setup(struct ee_server_graphic *graphic) {

	struct ee_server_graphic_dri *dri = &graphic->dri;
	int ret;

	if(graphic->was_setup)
		ee_server_graphic_dri_drawable(&graphic->dri, 0);

	/* physical card topology context info */
	dri->driverContext.pciBusID	 = "PCI:1:5:0";
	dri->driverContext.pciBus	 = 1;
	dri->driverContext.pciDevice	 = 5;
	dri->driverContext.pciFunc	 = 0;
	dri->driverContext.chipset	 = 0x5961;

	/* geometry context info */
	dri->driverContext.shared.virtualWidth  = graphic->width;
	dri->driverContext.shared.virtualHeight = graphic->height;
	dri->driverContext.bpp			= graphic->bpp;

	ret = ee_server_graphic_dri_setup(&graphic->fbdev, &graphic->dri);

	if(ret == 0) {
		ee_server_graphic_dri_drawable(&graphic->dri, 1);
		graphic->was_setup = 1;
		ee_server_scene_setup(graphic->width, graphic->height);
	}

	return ret;

} /* ee_server_graphic_setup */

Reply via email to