Beispiel #1
0
static GLboolean
CreateContext(void)
{
   struct dd_function_table ddFuncs;
   GLvisual *vis;
   GLframebuffer *buf;
   GLcontext *ctx;
   CompilerContext *cc;

   vis = _mesa_create_visual(GL_FALSE, GL_FALSE, /* RGB */
                             8, 8, 8, 8,  /* color */
                             0, 0,  /* z, stencil */
                             0, 0, 0, 0, 1);  /* accum */
   buf = _mesa_create_framebuffer(vis);

   cc = calloc(1, sizeof(*cc));
   if (!vis || !buf || !cc) {
      if (vis)
         _mesa_destroy_visual(vis);
      if (buf)
         _mesa_destroy_framebuffer(buf);
      return GL_FALSE;
   }

   _mesa_init_driver_functions(&ddFuncs);
   ddFuncs.GetString = NULL;/*get_string;*/
   ddFuncs.UpdateState = UpdateState;
   ddFuncs.GetBufferSize = NULL;

   ctx = &cc->MesaContext;
   _mesa_initialize_context(ctx, vis, NULL, &ddFuncs, cc);
   _mesa_enable_sw_extensions(ctx);

   if (!_swrast_CreateContext( ctx ) ||
       !_vbo_CreateContext( ctx ) ||
       !_tnl_CreateContext( ctx ) ||
       !_swsetup_CreateContext( ctx )) {
      _mesa_destroy_visual(vis);
      _mesa_free_context_data(ctx);
      free(cc);
      return GL_FALSE;
   }
   TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
   _swsetup_Wakeup( ctx );

   /* Override the context's default pragma settings */
   ctx->Shader.DefaultPragmas = Options.Pragmas;

   _mesa_make_current(ctx, buf, buf);

   return GL_TRUE;
}
Beispiel #2
0
MesaDriver::~MesaDriver()
{
   _mesa_destroy_visual(m_glvisual);
   _mesa_destroy_framebuffer(m_glframebuffer);
   _mesa_destroy_context(m_glcontext);
   
   delete m_bitmap;
}
Beispiel #3
0
MesaSoftwareRenderer::~MesaSoftwareRenderer()
{
	CALLED();
	_swsetup_DestroyContext(fContext);
	_swrast_DestroyContext(fContext);
	_tnl_DestroyContext(fContext);
	_vbo_DestroyContext(fContext);
	_mesa_destroy_visual(fVisual);
	_mesa_destroy_framebuffer(&fFrameBuffer->Base);
	_mesa_destroy_context(fContext);

	free(fInfo);

	delete fBitmap;
}
Beispiel #4
0
/*
 * Destroy an Off-Screen Mesa rendering context.
 *
 * Input:  ctx - the context to destroy
 */
GLAPI void GLAPIENTRY
OSMesaDestroyContext( OSMesaContext ctx )
{
   if (ctx) {
      _swsetup_DestroyContext( &ctx->mesa );
      _tnl_DestroyContext( &ctx->mesa );
      _ac_DestroyContext( &ctx->mesa );
      _swrast_DestroyContext( &ctx->mesa );

      _mesa_destroy_visual( ctx->gl_visual );
      _mesa_destroy_framebuffer( ctx->gl_buffer );
      _mesa_free_context_data( &ctx->mesa );
      FREE( ctx );
   }
}
Beispiel #5
0
/**
 * Destroy an Off-Screen Mesa rendering context.
 *
 * \param osmesa  the context to destroy
 */
GLAPI void GLAPIENTRY
OSMesaDestroyContext( OSMesaContext osmesa )
{
   if (osmesa) {
      if (osmesa->rb)
         _mesa_reference_renderbuffer(&osmesa->rb, NULL);

      _swsetup_DestroyContext( &osmesa->mesa );
      _tnl_DestroyContext( &osmesa->mesa );
      _vbo_DestroyContext( &osmesa->mesa );
      _swrast_DestroyContext( &osmesa->mesa );

      _mesa_destroy_visual( osmesa->gl_visual );
      _mesa_unreference_framebuffer( &osmesa->gl_buffer );

      _mesa_free_context_data( &osmesa->mesa );
      _mesa_free( osmesa );
   }
}
Beispiel #6
0
/*
 * New in Mesa 3.5
 *
 * Create context and specify size of ancillary buffers.
 */
GLAPI OSMesaContext GLAPIENTRY
OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
                        GLint accumBits, OSMesaContext sharelist )
{
   OSMesaContext osmesa;
   struct dd_function_table functions;
   GLint rind, gind, bind, aind;
   GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
   GLboolean rgbmode;

   rind = gind = bind = aind = 0;
   if (format==OSMESA_COLOR_INDEX) {
      indexBits = 8;
      rgbmode = GL_FALSE;
   }
   else if (format==OSMESA_RGBA) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      rind = 0;
      gind = 1;
      bind = 2;
      aind = 3;
      rgbmode = GL_TRUE;
   }
   else if (format==OSMESA_BGRA) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      bind = 0;
      gind = 1;
      rind = 2;
      aind = 3;
      rgbmode = GL_TRUE;
   }
   else if (format==OSMESA_ARGB) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      aind = 0;
      rind = 1;
      gind = 2;
      bind = 3;
      rgbmode = GL_TRUE;
   }
   else if (format==OSMESA_RGB) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = 0;
      rind = 0;
      gind = 1;
      bind = 2;
      rgbmode = GL_TRUE;
   }
   else if (format==OSMESA_BGR) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = 0;
      rind = 2;
      gind = 1;
      bind = 0;
      rgbmode = GL_TRUE;
   }
#if CHAN_TYPE == GL_UNSIGNED_BYTE
   else if (format==OSMESA_RGB_565) {
      indexBits = 0;
      redBits = 5;
      greenBits = 6;
      blueBits = 5;
      alphaBits = 0;
      rind = 0; /* not used */
      gind = 0;
      bind = 0;
      rgbmode = GL_TRUE;
   }
#endif
   else {
      return NULL;
   }

   osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
   if (osmesa) {
      osmesa->gl_visual = _mesa_create_visual( rgbmode,
                                               GL_FALSE,    /* double buffer */
                                               GL_FALSE,    /* stereo */
                                               redBits,
                                               greenBits,
                                               blueBits,
                                               alphaBits,
                                               indexBits,
                                               depthBits,
                                               stencilBits,
                                               accumBits,
                                               accumBits,
                                               accumBits,
                                               alphaBits ? accumBits : 0,
                                               1            /* num samples */
                                               );
      if (!osmesa->gl_visual) {
         FREE(osmesa);
         return NULL;
      }

      /* Initialize device driver function table */
      _mesa_init_driver_functions(&functions);
      /* override with our functions */
      functions.GetString = get_string;
      functions.UpdateState = osmesa_update_state;
      functions.GetBufferSize = get_buffer_size;

      if (!_mesa_initialize_context(&osmesa->mesa,
                                    osmesa->gl_visual,
                                    sharelist ? &sharelist->mesa
                                              : (GLcontext *) NULL,
                                    &functions, (void *) osmesa)) {
         _mesa_destroy_visual( osmesa->gl_visual );
         FREE(osmesa);
         return NULL;
      }

      _mesa_enable_sw_extensions(&(osmesa->mesa));
      _mesa_enable_1_3_extensions(&(osmesa->mesa));
      _mesa_enable_1_4_extensions(&(osmesa->mesa));
      _mesa_enable_1_5_extensions(&(osmesa->mesa));

      osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
      if (!osmesa->gl_buffer) {
         _mesa_destroy_visual( osmesa->gl_visual );
         _mesa_free_context_data( &osmesa->mesa );
         FREE(osmesa);
         return NULL;
      }

      /* create front color buffer in user-provided memory (no back buffer) */
      _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
                             new_osmesa_renderbuffer(format));
      _mesa_add_soft_renderbuffers(osmesa->gl_buffer,
                                   GL_FALSE, /* color */
                                   osmesa->gl_visual->haveDepthBuffer,
                                   osmesa->gl_visual->haveStencilBuffer,
                                   osmesa->gl_visual->haveAccumBuffer,
                                   GL_FALSE, /* alpha */
                                   GL_FALSE /* aux */ );

      osmesa->format = format;
      osmesa->buffer = NULL;
      osmesa->width = 0;
      osmesa->height = 0;
      osmesa->userRowLength = 0;
      osmesa->rowlength = 0;
      osmesa->yup = GL_TRUE;
      osmesa->rInd = rind;
      osmesa->gInd = gind;
      osmesa->bInd = bind;
      osmesa->aInd = aind;

      /* Initialize the software rasterizer and helper modules. */
      {
	 GLcontext *ctx = &osmesa->mesa;
         SWcontext *swrast;
         TNLcontext *tnl;

	 if (!_swrast_CreateContext( ctx ) ||
             !_ac_CreateContext( ctx ) ||
             !_tnl_CreateContext( ctx ) ||
             !_swsetup_CreateContext( ctx )) {
            _mesa_destroy_visual(osmesa->gl_visual);
            _mesa_free_context_data(ctx);
            _mesa_free(osmesa);
            return NULL;
         }
	
	 _swsetup_Wakeup( ctx );

         /* use default TCL pipeline */
         tnl = TNL_CONTEXT(ctx);
         tnl->Driver.RunPipeline = _tnl_run_pipeline;

         /* Extend the software rasterizer with our optimized line and triangle
          * drawing functions.
          */
         swrast = SWRAST_CONTEXT( ctx );
         swrast->choose_line = osmesa_choose_line;
         swrast->choose_triangle = osmesa_choose_triangle;
      }
   }
   return osmesa;
}
Beispiel #7
0
uint64
hsp_create_layer_context(Bitmap *bitmap, int layerPlane)
{
	TRACE("%s(bitmap: %p layerPlane: %d)\n", __FUNCTION__,
		bitmap, layerPlane);
	time_t total_beg, total_end;
	time_t beg, end;
	total_beg = time(NULL);
	struct hsp_context *ctx = NULL;
	struct pipe_screen *screen = NULL;
	GLvisual *visual = NULL;
	struct pipe_context *pipe = NULL;
	uint ctxId = 0;

	if (!hsp_dev) {
		TRACE("%s> there is no hsp_dev!\n", __FUNCTION__);
		return 0;
	}

	if (layerPlane != 0) {
		TRACE("%s> layerPlane != 0\n", __FUNCTION__);
		return 0;
	}

	ctx = CALLOC_STRUCT(hsp_context);
	if (!ctx) {
		TRACE("%s> can't alloc hsp_context!\n", __FUNCTION__);
		goto no_ctx;
	}

	ctx->bitmap = bitmap;
	ctx->colorSpace = get_bitmap_color_space(bitmap);
	ctx->draw = NULL;
	ctx->read = NULL;

	screen = hsp_dev->screen;

#ifdef DEBUG
    /* Unwrap screen */
    if (hsp_dev->trace_running)
        screen = trace_screen(screen)->screen;
#endif

	ulong options = hsp_dev->options;

	const GLboolean rgbFlag		= ((options & BGL_INDEX) == 0);
	const GLboolean alphaFlag	= ((options & BGL_ALPHA) == BGL_ALPHA);
	const GLboolean dblFlag		= ((options & BGL_DOUBLE) == BGL_DOUBLE);
	const GLboolean stereoFlag	= false;
	const GLint depth		= (options & BGL_DEPTH) ? 24 : 0;
	const GLint stencil		= (options & BGL_STENCIL) ? 8 : 0;
	const GLint accum		= 0;					// (options & BGL_ACCUM) ? 16 : 0;
	const GLint index		= 0;					// (options & BGL_INDEX) ? 32 : 0;
	const GLint red			= rgbFlag ? 8 : 0;
	const GLint green		= rgbFlag ? 8 : 0;
	const GLint blue		= rgbFlag ? 8 : 0;
	const GLint alpha		= alphaFlag ? 8 : 0;

	TRACE("rgb         :\t%d\n", (bool)rgbFlag);
	TRACE("alpha       :\t%d\n", (bool)alphaFlag);
	TRACE("dbl         :\t%d\n", (bool)dblFlag);
	TRACE("stereo      :\t%d\n", (bool)stereoFlag);
	TRACE("depth       :\t%d\n", depth);
	TRACE("stencil     :\t%d\n", stencil);
	TRACE("accum       :\t%d\n", accum);
	TRACE("index       :\t%d\n", index);
	TRACE("red         :\t%d\n", red);
	TRACE("green       :\t%d\n", green);
	TRACE("blue        :\t%d\n", blue);
	TRACE("alpha       :\t%d\n", alpha);

	visual = _mesa_create_visual(
		rgbFlag, dblFlag, stereoFlag, red, green, blue, alpha, index, depth,
		stencil, accum, accum, accum, alpha ? accum : 0, 1);

	TRACE("depthBits   :\t%d\n", visual->depthBits);
	TRACE("stencilBits :\t%d\n", visual->stencilBits);

	if (!visual) {
		TRACE("%s> can't create mesa visual!\n", __FUNCTION__);
		goto no_ctx_id;
	}

	pipe = hsp_dev->hsp_winsys->create_context(screen);

	if (!pipe) {
		TRACE("%s> can't create pipe!\n", __FUNCTION__);
		goto no_pipe;
	}

#ifdef DEBUG
    if (hsp_dev->trace_running)
        pipe = trace_context_create(hsp_dev->screen, pipe);
#endif

	assert(!pipe->priv);
	pipe->priv = bitmap;

	ctx->st = st_create_context(pipe, visual, NULL);
	if (!ctx->st) {
		TRACE("%s> can't create mesa statetracker context!\n",
			__FUNCTION__);
		goto no_st_ctx;
	}

	ctx->st->ctx->DriverCtx = ctx;

	pipe_mutex_lock(hsp_dev->mutex);
	uint64 i;
	for (i = 0; i < HSP_CONTEXT_MAX; i++) {
		if (hsp_dev->ctx_array[i].ctx == NULL) {
			hsp_dev->ctx_array[i].ctx = ctx;
			ctxId = i + 1;
			break;
		}
	}
	pipe_mutex_unlock(hsp_dev->mutex);

	if (ctxId != 0)
		return ctxId;

no_ctx_id:
	TRACE("%s> no_ctx_id!\n", __FUNCTION__);
    _mesa_destroy_visual(visual);
    st_destroy_context(ctx->st);
    goto no_pipe; /* st_context_destroy already destroy pipe */
no_st_ctx:
	TRACE("%s> no_st_ctx!\n", __FUNCTION__);
    pipe->destroy(pipe);
no_pipe:
	TRACE("%s> no_pipe!\n", __FUNCTION__);
    FREE(ctx);
no_ctx:
	TRACE("%s> no_ctx!\n", __FUNCTION__);
    return 0;
}
Beispiel #8
0
void GLAPIENTRY AMesaDestroyVisual(AMesaVisual visual)
{
	_mesa_destroy_visual(visual->GLVisual);
	free(visual);
}
context_id
GalliumContext::CreateContext(Bitmap *bitmap)
{
	CALLED();

	struct hgl_context* context = CALLOC_STRUCT(hgl_context);

	if (!context) {
		ERROR("%s: Couldn't create pipe context!\n", __FUNCTION__);
		return 0;
	}

	// Set up the initial things our context needs
	context->bitmap = bitmap;
	context->colorSpace = get_bitmap_color_space(bitmap);
	context->draw = NULL;
	context->read = NULL;
	context->st = NULL;

	context->api = st_gl_api_create();
	if (!context->api) {
		ERROR("%s: Couldn't obtain Mesa state tracker API!\n", __func__);
		return -1;
	}

	context->manager = CALLOC_STRUCT(st_manager);
	if (!context->manager) {
		ERROR("%s: Couldn't allocate Mesa state tracker manager!\n", __func__);
		return -1;
	}
	context->manager->get_param = hook_stm_get_param;

	// Calculate visual configuration
	const GLboolean rgbFlag		= ((fOptions & BGL_INDEX) == 0);
	const GLboolean alphaFlag	= ((fOptions & BGL_ALPHA) == BGL_ALPHA);
	const GLboolean dblFlag		= ((fOptions & BGL_DOUBLE) == BGL_DOUBLE);
	const GLboolean stereoFlag	= false;
	const GLint depth			= (fOptions & BGL_DEPTH) ? 24 : 0;
	const GLint stencil			= (fOptions & BGL_STENCIL) ? 8 : 0;
	const GLint accum			= (fOptions & BGL_ACCUM) ? 16 : 0;
	const GLint red				= rgbFlag ? 8 : 5;
	const GLint green			= rgbFlag ? 8 : 5;
	const GLint blue			= rgbFlag ? 8 : 5;
	const GLint alpha			= alphaFlag ? 8 : 0;

	TRACE("rgb      :\t%d\n", (bool)rgbFlag);
	TRACE("alpha    :\t%d\n", (bool)alphaFlag);
	TRACE("dbl      :\t%d\n", (bool)dblFlag);
	TRACE("stereo   :\t%d\n", (bool)stereoFlag);
	TRACE("depth    :\t%d\n", depth);
	TRACE("stencil  :\t%d\n", stencil);
	TRACE("accum    :\t%d\n", accum);
	TRACE("red      :\t%d\n", red);
	TRACE("green    :\t%d\n", green);
	TRACE("blue     :\t%d\n", blue);
	TRACE("alpha    :\t%d\n", alpha);

	gl_config* glVisual = _mesa_create_visual(dblFlag, stereoFlag, red, green,
		blue, alpha, depth, stencil, accum, accum, accum, alpha ? accum : 0, 1);

	if (!glVisual) {
		ERROR("%s: Couldn't create Mesa visual!\n", __func__);
		return -1;
	}

	TRACE("depthBits   :\t%d\n", glVisual->depthBits);
	TRACE("stencilBits :\t%d\n", glVisual->stencilBits);

	// Convert Mesa calculated visual into state tracker visual
	context->stVisual = hgl_fill_st_visual(glVisual);

	context->draw = new GalliumFramebuffer(context->stVisual, (void*)this);
	context->read = new GalliumFramebuffer(context->stVisual, (void*)this);

	if (!context->draw || !context->read) {
		ERROR("%s: Problem allocating framebuffer!\n", __func__);
		_mesa_destroy_visual(glVisual);
		return -1;
	}

	// We need to assign the screen *before* calling st_api create_context
	context->manager->screen = fScreen;

	// Build state tracker attributes
	struct st_context_attribs attribs;
	memset(&attribs, 0, sizeof(attribs));
	attribs.options.force_glsl_extensions_warn = false;
	attribs.profile = ST_PROFILE_DEFAULT;
	attribs.visual = *context->stVisual;
	attribs.major = 1;
	attribs.minor = 0;
	//attribs.flags |= ST_CONTEXT_FLAG_DEBUG;

	struct st_api* api = context->api;

	// Create context using state tracker api call
	enum st_context_error result;
	context->st = api->create_context(api, context->manager, &attribs,
		&result, context->st);

	if (!context->st) {
		ERROR("%s: Couldn't create mesa state tracker context!\n",
			__func__);
		switch (result) {
			case ST_CONTEXT_SUCCESS:
				ERROR("%s: State tracker error: SUCCESS?\n", __func__);
				break;
			case ST_CONTEXT_ERROR_NO_MEMORY:
				ERROR("%s: State tracker error: NO_MEMORY\n", __func__);
				break;
			case ST_CONTEXT_ERROR_BAD_API:
				ERROR("%s: State tracker error: BAD_API\n", __func__);
				break;
			case ST_CONTEXT_ERROR_BAD_VERSION:
				ERROR("%s: State tracker error: BAD_VERSION\n", __func__);
				break;
			case ST_CONTEXT_ERROR_BAD_FLAG:
				ERROR("%s: State tracker error: BAD_FLAG\n", __func__);
				break;
			case ST_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE:
				ERROR("%s: State tracker error: BAD_ATTRIBUTE\n", __func__);
				break;
			case ST_CONTEXT_ERROR_UNKNOWN_FLAG:
				ERROR("%s: State tracker error: UNKNOWN_FLAG\n", __func__);
				break;
		}

		FREE(context);
		return -1;
	}

	assert(!context->st->st_manager_private);
	context->st->st_manager_private = (void*)context;

	struct st_context *stContext = (struct st_context*)context->st;
	
	stContext->ctx->Driver.Viewport = hgl_viewport;

	// Init Gallium3D Post Processing
	// TODO: no pp filters are enabled yet through postProcessEnable
	context->postProcess = pp_init(stContext->pipe, context->postProcessEnable,
		stContext->cso_context);

	context_id contextNext = -1;
	Lock();
	for (context_id i = 0; i < CONTEXT_MAX; i++) {
		if (fContext[i] == NULL) {
			fContext[i] = context;
			contextNext = i;
			break;
		}
	}
	Unlock();

	if (contextNext < 0) {
		ERROR("%s: The next context is invalid... something went wrong!\n",
			__func__);
		//st_destroy_context(context->st);
		FREE(context);
		_mesa_destroy_visual(glVisual);
		return -1;
	}

	TRACE("%s: context #%" B_PRIu64 " is the next available context\n",
		__func__, contextNext);

	return contextNext;
}
/*
 * Destroy the given FX/Mesa context.
 */
void GLAPIENTRY
fxMesaDestroyContext(fxMesaContext fxMesa)
{
   if (TDFX_DEBUG & VERBOSE_DRIVER) {
      fprintf(stderr, "fxMesaDestroyContext(...)\n");
   }

   if (!fxMesa)
      return;

   if (fxMesa->verbose) {
      fprintf(stderr, "Misc Stats:\n");
      fprintf(stderr, "  # swap buffer: %u\n", fxMesa->stats.swapBuffer);

      if (!fxMesa->stats.swapBuffer)
	 fxMesa->stats.swapBuffer = 1;

      fprintf(stderr, "Textures Stats:\n");
      fprintf(stderr, "  Free texture memory on TMU0: %d\n",
	      fxMesa->freeTexMem[FX_TMU0]);
      if (fxMesa->haveTwoTMUs)
	 fprintf(stderr, "  Free texture memory on TMU1: %d\n",
		 fxMesa->freeTexMem[FX_TMU1]);
      fprintf(stderr, "  # request to TMM to upload a texture objects: %u\n",
	      fxMesa->stats.reqTexUpload);
      fprintf(stderr,
	      "  # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
	      fxMesa->stats.reqTexUpload / (float) fxMesa->stats.swapBuffer);
      fprintf(stderr, "  # texture objects uploaded: %u\n",
	      fxMesa->stats.texUpload);
      fprintf(stderr, "  # texture objects uploaded per swapbuffer: %.2f\n",
	      fxMesa->stats.texUpload / (float) fxMesa->stats.swapBuffer);
      fprintf(stderr, "  # MBs uploaded to texture memory: %.2f\n",
	      fxMesa->stats.memTexUpload / (float) (1 << 20));
      fprintf(stderr,
	      "  # MBs uploaded to texture memory per swapbuffer: %.2f\n",
	      (fxMesa->stats.memTexUpload /
	       (float) fxMesa->stats.swapBuffer) / (float) (1 << 20));
   }

   glbTotNumCtx--;

   if (!glbTotNumCtx && getenv("MESA_FX_INFO")) {
      GrSstPerfStats_t st;

      FX_grSstPerfStats(&st);

      fprintf(stderr, "Pixels Stats:\n");
      fprintf(stderr, "  # pixels processed (minus buffer clears): %u\n",
              (unsigned) st.pixelsIn);
      fprintf(stderr, "  # pixels not drawn due to chroma key test failure: %u\n",
              (unsigned) st.chromaFail);
      fprintf(stderr, "  # pixels not drawn due to depth test failure: %u\n",
              (unsigned) st.zFuncFail);
      fprintf(stderr,
              "  # pixels not drawn due to alpha test failure: %u\n",
              (unsigned) st.aFuncFail);
      fprintf(stderr, "  # pixels drawn (including buffer clears and LFB writes): %u\n",
              (unsigned) st.pixelsOut);
   }

   /* close the hardware first,
    * so we can debug atexit problems (memory leaks, etc).
    */
   grSstWinClose(fxMesa->glideContext);
   fxCloseHardware();

   fxDDDestroyFxMesaContext(fxMesa); /* must be before _mesa_destroy_context */
   _mesa_destroy_visual(fxMesa->glVis);
   _mesa_destroy_context(fxMesa->glCtx);
   _mesa_unreference_framebuffer(&fxMesa->glBuffer);
   fxTMClose(fxMesa); /* must be after _mesa_destroy_context */

   FREE(fxMesa);

   if (fxMesa == fxMesaCurrentCtx)
      fxMesaCurrentCtx = NULL;
}
Beispiel #11
0
//
// Input:  rect - initial rectangle
//         name - window name
//         resizingMode - example: B_FOLLOW_NONE
//         mode - usually 0 ?
//         options - Bitwise-OR of BGL_* tokens
//
BGLView::BGLView(BRect rect, char *name,
                 ulong resizingMode, ulong mode,
                 ulong options)
   : BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS) //  | B_FULL_UPDATE_ON_RESIZE)
{
	// We don't support single buffering (yet): double buffering forced.
	options |= BGL_DOUBLE;

   const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
   const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
   const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
   const GLboolean stereoFlag = false;
   const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
   const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
   const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
   const GLint index = (options & BGL_INDEX) ? 32 : 0;
   const GLint red = rgbFlag ? 8 : 0;
   const GLint green = rgbFlag ? 8 : 0;
   const GLint blue = rgbFlag ? 8 : 0;
   const GLint alpha = alphaFlag ? 8 : 0;

	m_options = options | BGL_INDIRECT;

   struct dd_function_table functions;
 
   if (!rgbFlag) {
      fprintf(stderr, "Mesa Warning: color index mode not supported\n");
   }

   // Allocate auxiliary data object
   MesaDriver * md = new MesaDriver();

   // examine option flags and create gl_context struct
   GLvisual * visual = _mesa_create_visual( rgbFlag,
                                            dblFlag,
                                            stereoFlag,
                                            red, green, blue, alpha,
                                            index,
                                            depth,
                                            stencil,
                                            accum, accum, accum, accum,
                                            1
                                            );

	// Initialize device driver function table
	_mesa_init_driver_functions(&functions);

	functions.GetString 	= md->GetString;
	functions.UpdateState 	= md->UpdateState;
	functions.GetBufferSize = md->GetBufferSize;
	functions.Clear 		= md->Clear;
	functions.ClearIndex 	= md->ClearIndex;
	functions.ClearColor 	= md->ClearColor;
	functions.Error			= md->Error;
        functions.Viewport      = md->Viewport;

	// create core context
	GLcontext *ctx = _mesa_create_context(visual, NULL, &functions, md);
	if (! ctx) {
         _mesa_destroy_visual(visual);
         delete md;
         return;
      }
   _mesa_enable_sw_extensions(ctx);
   _mesa_enable_1_3_extensions(ctx);
   _mesa_enable_1_4_extensions(ctx);
   _mesa_enable_1_5_extensions(ctx);


   // create core framebuffer
   GLframebuffer * buffer = _mesa_create_framebuffer(visual,
                                              depth > 0 ? GL_TRUE : GL_FALSE,
                                              stencil > 0 ? GL_TRUE: GL_FALSE,
                                              accum > 0 ? GL_TRUE : GL_FALSE,
                                              alphaFlag
                                              );

   /* Initialize the software rasterizer and helper modules.
    */
   _swrast_CreateContext(ctx);
   _vbo_CreateContext(ctx);
   _tnl_CreateContext(ctx);
   _swsetup_CreateContext(ctx);
   _swsetup_Wakeup(ctx);

   md->Init(this, ctx, visual, buffer );

   // Hook aux data into BGLView object
   m_gc = md;

   // some stupid applications (Quake2) don't even think about calling LockGL()
   // before using glGetString and friends... so make sure there is at least a
   // valid context.
   if (!_mesa_get_current_context()) {
      LockGL();
      // not needed, we don't have a looper yet: UnlockLooper();
   }

}
Beispiel #12
0
BOOL sw_SetPixelFormat(HDC hdc, struct wgl_dc_data* dc_data, INT format)
{
    struct sw_framebuffer* fb;
    BOOL doubleBuffered;
    
    assert(dc_data->sw_data == NULL);

    /* So, someone is crazy enough to ask for sw implementation. Announce it. */
    TRACE("OpenGL software implementation START!\n");
    
    /* allocate our structure */
    fb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(struct sw_framebuffer, bmi.bmiColors[3]));
    if(!fb)
    {
        ERR("HeapAlloc FAILED!\n");
        return FALSE;
    }
    /* Get the format index */
    fb->format_index = index_from_format(dc_data, format, &doubleBuffered);
    TRACE("Using format %u - double buffered: %x.\n", fb->format_index, doubleBuffered);
    fb->flags = doubleBuffered ? SW_FB_DOUBLEBUFFERED : 0;
    /* Set the bitmap info describing the framebuffer */
    fb->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    fb->bmi.bmiHeader.biPlanes = 1;
    fb->bmi.bmiHeader.biBitCount = pixel_formats[fb->format_index].color_bits;
    fb->bmi.bmiHeader.biCompression = pixel_formats[fb->format_index].bmp_compression;
    fb->bmi.bmiHeader.biSizeImage = 0;
    fb->bmi.bmiHeader.biXPelsPerMeter = 0;
    fb->bmi.bmiHeader.biYPelsPerMeter = 0;
    fb->bmi.bmiHeader.biClrUsed = 0;
    fb->bmi.bmiHeader.biClrImportant = 0;
    *((DWORD*)&fb->bmi.bmiColors[0]) = pixel_formats[fb->format_index].red_mask;
    *((DWORD*)&fb->bmi.bmiColors[1]) = pixel_formats[fb->format_index].green_mask;
    *((DWORD*)&fb->bmi.bmiColors[2]) = pixel_formats[fb->format_index].blue_mask;
    /* Save the HDC */
    fb->hdc = hdc;
    
    /* Allocate the visual structure describing the format */
    fb->gl_visual = _mesa_create_visual(
        !!(fb->flags & SW_FB_DOUBLEBUFFERED),
        GL_FALSE, /* No stereoscopic support */
        pixel_formats[fb->format_index].red_bits,
        pixel_formats[fb->format_index].green_bits,
        pixel_formats[fb->format_index].blue_bits,
        pixel_formats[fb->format_index].alpha_bits,
        pixel_formats[fb->format_index].depth_bits,
        pixel_formats[fb->format_index].stencil_bits,
        pixel_formats[fb->format_index].accum_bits,
        pixel_formats[fb->format_index].accum_bits,
        pixel_formats[fb->format_index].accum_bits,
        pixel_formats[fb->format_index].alpha_bits ? 
            pixel_formats[fb->format_index].accum_bits : 0);
    
    if(!fb->gl_visual)
    {
        ERR("Failed to allocate a GL visual.\n");
        HeapFree(GetProcessHeap(), 0, fb);
        return FALSE;
    }
    
    /* Allocate the framebuffer structure */
    fb->gl_buffer = _mesa_create_framebuffer(fb->gl_visual);
    if (!fb->gl_buffer) {
        ERR("Failed to allocate the mesa framebuffer structure.\n");
        _mesa_destroy_visual( fb->gl_visual );
        HeapFree(GetProcessHeap(), 0, fb);
        return FALSE;
    }
    
    /* Add the depth/stencil/accum buffers */
    _swrast_add_soft_renderbuffers(fb->gl_buffer,
                             GL_FALSE, /* color */
                             fb->gl_visual->haveDepthBuffer,
                             fb->gl_visual->haveStencilBuffer,
                             fb->gl_visual->haveAccumBuffer,
                             GL_FALSE, /* alpha */
                             GL_FALSE /* aux */ );
    
    /* Initialize our render buffers */
    sw_init_renderbuffers(fb);

    /* Everything went fine */
    dc_data->sw_data = fb;
    return TRUE;
}
MesaSoftwareRenderer::MesaSoftwareRenderer(BGLView* view, ulong options,
	BGLDispatcher* dispatcher)
	: BGLRenderer(view, options, dispatcher),
	fBitmap(NULL),
	fDirectModeEnabled(false),
	fInfo(NULL),
	fInfoLocker("info locker"),
	fContext(NULL),
	fVisual(NULL),
	fFrameBuffer(NULL),
	fFrontRenderBuffer(NULL),
	fBackRenderBuffer(NULL),
	fColorSpace(B_NO_COLOR_SPACE)
{
	CALLED();

	fClearColor[BE_RCOMP] = 0;
	fClearColor[BE_GCOMP] = 0;
	fClearColor[BE_BCOMP] = 0;
	fClearColor[BE_ACOMP] = 0;

	fClearIndex = 0;

	fColorSpace = BScreen(GLView()->Window()).ColorSpace();

	// We force single buffering for the time being
	options &= ~BGL_DOUBLE;

	const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
	const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
	const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
	const GLboolean stereoFlag = false;
	const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
	const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
	const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
	const GLint red = rgbFlag ? 8 : 0;
	const GLint green = rgbFlag ? 8 : 0;
	const GLint blue = rgbFlag ? 8 : 0;
	const GLint alpha = alphaFlag ? 8 : 0;

	fOptions = options; // | BGL_INDIRECT;
	struct dd_function_table functions;

	fVisual = _mesa_create_visual(dblFlag, stereoFlag, red, green,
		blue, alpha, depth, stencil, accum, accum, accum,
		alpha ? accum : 0, 1);

	// Initialize device driver function table
	_mesa_init_driver_functions(&functions);

	functions.GetString 	= _GetString;
	functions.UpdateState 	= _UpdateState;
	functions.GetBufferSize = NULL;
	functions.Error			= _Error;
	functions.Viewport		= _Viewport;
	functions.Flush			= _Flush;

	// create core context
#if HAIKU_MESA_VER <= 708
	fContext = _mesa_create_context(fVisual, NULL, &functions, this);
#else
	fContext = _mesa_create_context(API_OPENGL, fVisual, NULL,
		&functions, this);
#endif

	if (!fContext) {
		ERROR("%s: Failed to create Mesa context!\n", __func__);
		_mesa_destroy_visual(fVisual);
		return;
	}

	/* Initialize the software rasterizer and helper modules. */
	_swrast_CreateContext(fContext);
	_vbo_CreateContext(fContext);
	_tnl_CreateContext(fContext);
	_swsetup_CreateContext(fContext);
	_swsetup_Wakeup(fContext);

	// Use default TCL pipeline
	TNL_CONTEXT(fContext)->Driver.RunPipeline = _tnl_run_pipeline;

	_mesa_meta_init(fContext);
	_mesa_enable_sw_extensions(fContext);
	_mesa_enable_1_3_extensions(fContext);
	_mesa_enable_1_4_extensions(fContext);
	_mesa_enable_1_5_extensions(fContext);
	_mesa_enable_2_0_extensions(fContext);
	_mesa_enable_2_1_extensions(fContext);

	// create core framebuffer
	fFrameBuffer = (struct msr_framebuffer*)calloc(1,
		sizeof(*fFrameBuffer));
	if (fFrameBuffer == NULL) {
		ERROR("%s: Unable to calloc GL FrameBuffer!\n", __func__);
		_mesa_destroy_visual(fVisual);
		return;
	}
	_mesa_initialize_window_framebuffer(&fFrameBuffer->base, fVisual);

	// Setup front render buffer
	fFrontRenderBuffer = _NewRenderBuffer(true);
	if (fFrontRenderBuffer == NULL) {
		ERROR("%s: FrontRenderBuffer is requested but unallocated!\n",
			__func__);
		_mesa_destroy_visual(fVisual);
		free(fFrameBuffer);
		return;
	}
	_mesa_add_renderbuffer(&fFrameBuffer->base, BUFFER_FRONT_LEFT,
		&fFrontRenderBuffer->base);

	// Setup back render buffer (if requested)
	if (fVisual->doubleBufferMode) {
		fBackRenderBuffer = _NewRenderBuffer(false);
		if (fBackRenderBuffer == NULL) {
			ERROR("%s: BackRenderBuffer is requested but unallocated!\n",
				__func__);
			_mesa_destroy_visual(fVisual);
			free(fFrameBuffer);
			return;
		}
		_mesa_add_renderbuffer(&fFrameBuffer->base, BUFFER_BACK_LEFT,
			&fBackRenderBuffer->base);
	}

#if HAIKU_MESA_VER >= 709
	// New Mesa
	_swrast_add_soft_renderbuffers(&fFrameBuffer->base, GL_FALSE,
		fVisual->haveDepthBuffer, fVisual->haveStencilBuffer,
		fVisual->haveAccumBuffer, alphaFlag, GL_FALSE);
#else
	// Old Mesa
	_mesa_add_soft_renderbuffers(&fFrameBuffer->base, GL_FALSE,
		fVisual->haveDepthBuffer, fVisual->haveStencilBuffer,
		fVisual->haveAccumBuffer, alphaFlag, GL_FALSE);
#endif

	BRect bounds = view->Bounds();
	fWidth = fNewWidth = (GLint)bounds.Width();
	fHeight = fNewHeight = (GLint)bounds.Height();

	// some stupid applications (Quake2) don't even think about calling LockGL()
	// before using glGetString and its glGet*() friends...
	// so make sure there is at least a valid context.

	if (!_mesa_get_current_context()) {
		LockGL();
		// not needed, we don't have a looper yet: UnlockLooper();
	}
}
Beispiel #14
0
MesaSoftwareRenderer::MesaSoftwareRenderer(BGLView* view, ulong options,
		BGLDispatcher* dispatcher)
	: BGLRenderer(view, options, dispatcher),
	fBitmap(NULL),
	fDirectModeEnabled(false),
	fInfo(NULL),
	fInfoLocker("info locker"),
	fContext(NULL),
	fVisual(NULL),
	fFrameBuffer(NULL),
	fFrontRenderBuffer(NULL),
	fBackRenderBuffer(NULL),
	fColorSpace(B_NO_COLOR_SPACE)
{
	CALLED();

	fClearColor[BE_RCOMP] = 0;
	fClearColor[BE_GCOMP] = 0;
	fClearColor[BE_BCOMP] = 0;
	fClearColor[BE_ACOMP] = 0;

	fClearIndex = 0;

	fColorSpace = BScreen(GLView()->Window()).ColorSpace();

	// We force single buffering for the time being
	//options &= !BGL_DOUBLE;

	const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
	const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
	const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
	const GLboolean stereoFlag = false;
	const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
	const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
	const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
	const GLint index = (options & BGL_INDEX) ? 32 : 0;
	const GLint red = rgbFlag ? 8 : 0;
	const GLint green = rgbFlag ? 8 : 0;
	const GLint blue = rgbFlag ? 8 : 0;
	const GLint alpha = alphaFlag ? 8 : 0;

	fOptions = options; // | BGL_INDIRECT;
	struct dd_function_table functions;

	fVisual = _mesa_create_visual(rgbFlag, dblFlag, stereoFlag, red, green,
		blue, alpha, index, depth, stencil, accum, accum, accum,
		alpha ? accum : 0, 1);

	// Initialize device driver function table
	_mesa_init_driver_functions(&functions);

	functions.GetString 	= _GetString;
	functions.UpdateState 	= _UpdateState;
	functions.GetBufferSize = NULL;
	functions.Error			= _Error;
	functions.Viewport		= _Viewport;
	functions.Flush			= _Flush;

	// create core context
	fContext = _mesa_create_context(fVisual, NULL, &functions, this);
	if (!fContext) {
		_mesa_destroy_visual(fVisual);
		return;
	}

	/* Initialize the software rasterizer and helper modules. */
	_swrast_CreateContext(fContext);
	_vbo_CreateContext(fContext);
	_tnl_CreateContext(fContext);
	_swsetup_CreateContext(fContext);
	_swsetup_Wakeup(fContext);

	// Use default TCL pipeline
	TNL_CONTEXT(fContext)->Driver.RunPipeline = _tnl_run_pipeline;

	_mesa_enable_sw_extensions(fContext);
	_mesa_enable_1_3_extensions(fContext);
	_mesa_enable_1_4_extensions(fContext);
	_mesa_enable_1_5_extensions(fContext);
	_mesa_enable_2_0_extensions(fContext);
	_mesa_enable_2_1_extensions(fContext);

	// create core framebuffer
	fFrameBuffer = (struct msr_framebuffer*)_mesa_calloc(
		sizeof(*fFrameBuffer));
	_mesa_initialize_framebuffer(&fFrameBuffer->Base, fVisual);

	fFrontRenderBuffer = (struct msr_renderbuffer*)_mesa_calloc(
		sizeof(*fFrontRenderBuffer));
	_mesa_init_renderbuffer(&fFrontRenderBuffer->Base, 0);

	fFrontRenderBuffer->Base.AllocStorage = _FrontRenderbufferStorage;
	fFrontRenderBuffer->Base.Data = NULL;
	fFrontRenderBuffer->Base.InternalFormat = GL_RGBA;
	fFrontRenderBuffer->Base._BaseFormat = GL_RGBA;
	fFrontRenderBuffer->Base.DataType = GL_UNSIGNED_BYTE;
	fFrontRenderBuffer->Base.RedBits   = 8 * sizeof(GLubyte);
	fFrontRenderBuffer->Base.GreenBits = 8 * sizeof(GLubyte);
	fFrontRenderBuffer->Base.BlueBits  = 8 * sizeof(GLubyte);
	fFrontRenderBuffer->Base.AlphaBits = 8 * sizeof(GLubyte);
	_SetSpanFuncs(fFrontRenderBuffer, fColorSpace);
	_mesa_add_renderbuffer(&fFrameBuffer->Base, BUFFER_FRONT_LEFT,
		&fFrontRenderBuffer->Base);

	if (dblFlag) {
		fBackRenderBuffer = (struct msr_renderbuffer*)_mesa_calloc(
			sizeof(*fBackRenderBuffer));
		_mesa_init_renderbuffer(&fBackRenderBuffer->Base, 0);

		fBackRenderBuffer->Base.AllocStorage = _BackRenderbufferStorage;
		fBackRenderBuffer->Base.Data = NULL;
		fBackRenderBuffer->Base.Delete = _DeleteBackBuffer;
		fBackRenderBuffer->Base.InternalFormat = GL_RGBA;
		fBackRenderBuffer->Base._BaseFormat = GL_RGBA;
		fBackRenderBuffer->Base.DataType = GL_UNSIGNED_BYTE;
		fBackRenderBuffer->Base.RedBits   = 8 * sizeof(GLubyte);
		fBackRenderBuffer->Base.GreenBits = 8 * sizeof(GLubyte);
		fBackRenderBuffer->Base.BlueBits  = 8 * sizeof(GLubyte);
		fBackRenderBuffer->Base.AlphaBits = 8 * sizeof(GLubyte);
		_SetSpanFuncs(fBackRenderBuffer, fColorSpace);
		_mesa_add_renderbuffer(&fFrameBuffer->Base, BUFFER_BACK_LEFT,
			&fBackRenderBuffer->Base);
	}

	_mesa_add_soft_renderbuffers(&fFrameBuffer->Base, GL_FALSE,
		fVisual->haveDepthBuffer, fVisual->haveStencilBuffer,
		fVisual->haveAccumBuffer, alphaFlag, GL_FALSE);

	BRect bounds = view->Bounds();
	fWidth = fNewWidth = (GLint)bounds.Width();
	fHeight = fNewHeight = (GLint)bounds.Height();

	// some stupid applications (Quake2) don't even think about calling LockGL()
	// before using glGetString and its glGet*() friends...
	// so make sure there is at least a valid context.

	if (!_mesa_get_current_context()) {
		LockGL();
		// not needed, we don't have a looper yet: UnlockLooper();
	}
}
/**
 * New in Mesa 11.2
 *
 * Create context with attribute list.
 */
GLAPI OSMesaContext GLAPIENTRY
OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist)
{
   OSMesaContext osmesa;
   struct dd_function_table functions;
   GLint rind, gind, bind, aind;
   GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
   GLenum format = OSMESA_RGBA;
   GLint depthBits = 0, stencilBits = 0, accumBits = 0;
   int profile = OSMESA_COMPAT_PROFILE, version_major = 1, version_minor = 0;
   gl_api api_profile = API_OPENGL_COMPAT;
   int i;

   for (i = 0; attribList[i]; i += 2) {
      switch (attribList[i]) {
      case OSMESA_FORMAT:
         format = attribList[i+1];
         switch (format) {
         case OSMESA_COLOR_INDEX:
         case OSMESA_RGBA:
         case OSMESA_BGRA:
         case OSMESA_ARGB:
         case OSMESA_RGB:
         case OSMESA_BGR:
         case OSMESA_RGB_565:
            /* legal */
            break;
         default:
            return NULL;
         }
         break;
      case OSMESA_DEPTH_BITS:
         depthBits = attribList[i+1];
         if (depthBits < 0)
            return NULL;
         break;
      case OSMESA_STENCIL_BITS:
         stencilBits = attribList[i+1];
         if (stencilBits < 0)
            return NULL;
         break;
      case OSMESA_ACCUM_BITS:
         accumBits = attribList[i+1];
         if (accumBits < 0)
            return NULL;
         break;
      case OSMESA_PROFILE:
         profile = attribList[i+1];
         if (profile == OSMESA_COMPAT_PROFILE)
            api_profile = API_OPENGL_COMPAT;
         else if (profile == OSMESA_CORE_PROFILE)
            api_profile = API_OPENGL_CORE;
         else
            return NULL;
         break;
      case OSMESA_CONTEXT_MAJOR_VERSION:
         version_major = attribList[i+1];
         if (version_major < 1)
            return NULL;
         break;
      case OSMESA_CONTEXT_MINOR_VERSION:
         version_minor = attribList[i+1];
         if (version_minor < 0)
            return NULL;
         break;
      case 0:
         /* end of list */
         break;
      default:
         fprintf(stderr, "Bad attribute in OSMesaCreateContextAttribs()\n");
         return NULL;
      }
   }

   rind = gind = bind = aind = 0;
   if (format==OSMESA_RGBA) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      rind = 0;
      gind = 1;
      bind = 2;
      aind = 3;
   }
   else if (format==OSMESA_BGRA) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      bind = 0;
      gind = 1;
      rind = 2;
      aind = 3;
   }
   else if (format==OSMESA_ARGB) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      aind = 0;
      rind = 1;
      gind = 2;
      bind = 3;
   }
   else if (format==OSMESA_RGB) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = 0;
      rind = 0;
      gind = 1;
      bind = 2;
   }
   else if (format==OSMESA_BGR) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = 0;
      rind = 2;
      gind = 1;
      bind = 0;
   }
#if CHAN_TYPE == GL_UNSIGNED_BYTE
   else if (format==OSMESA_RGB_565) {
      redBits = 5;
      greenBits = 6;
      blueBits = 5;
      alphaBits = 0;
      rind = 0; /* not used */
      gind = 0;
      bind = 0;
   }
#endif
   else {
      return NULL;
   }

   osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
   if (osmesa) {
      osmesa->gl_visual = _mesa_create_visual( GL_FALSE,    /* double buffer */
                                               GL_FALSE,    /* stereo */
                                               redBits,
                                               greenBits,
                                               blueBits,
                                               alphaBits,
                                               depthBits,
                                               stencilBits,
                                               accumBits,
                                               accumBits,
                                               accumBits,
                                               alphaBits ? accumBits : 0,
                                               1            /* num samples */
                                               );
      if (!osmesa->gl_visual) {
         free(osmesa);
         return NULL;
      }

      /* Initialize device driver function table */
      _mesa_init_driver_functions(&functions);
      /* override with our functions */
      functions.GetString = get_string;
      functions.UpdateState = osmesa_update_state_wrapper;

      if (!_mesa_initialize_context(&osmesa->mesa,
                                    api_profile,
                                    osmesa->gl_visual,
                                    sharelist ? &sharelist->mesa
                                              : (struct gl_context *) NULL,
                                    &functions)) {
         _mesa_destroy_visual( osmesa->gl_visual );
         free(osmesa);
         return NULL;
      }

      _mesa_enable_sw_extensions(&(osmesa->mesa));

      osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
      if (!osmesa->gl_buffer) {
         _mesa_destroy_visual( osmesa->gl_visual );
         _mesa_free_context_data( &osmesa->mesa );
         free(osmesa);
         return NULL;
      }

      /* Create depth/stencil/accum buffers.  We'll create the color
       * buffer later in OSMesaMakeCurrent().
       */
      _swrast_add_soft_renderbuffers(osmesa->gl_buffer,
                                     GL_FALSE, /* color */
                                     osmesa->gl_visual->haveDepthBuffer,
                                     osmesa->gl_visual->haveStencilBuffer,
                                     osmesa->gl_visual->haveAccumBuffer,
                                     GL_FALSE, /* alpha */
                                     GL_FALSE /* aux */ );

      osmesa->format = format;
      osmesa->userRowLength = 0;
      osmesa->yup = GL_TRUE;
      osmesa->rInd = rind;
      osmesa->gInd = gind;
      osmesa->bInd = bind;
      osmesa->aInd = aind;

      _mesa_meta_init(&osmesa->mesa);

      /* Initialize the software rasterizer and helper modules. */
      {
	 struct gl_context *ctx = &osmesa->mesa;
         SWcontext *swrast;
         TNLcontext *tnl;

	 if (!_swrast_CreateContext( ctx ) ||
             !_vbo_CreateContext( ctx ) ||
             !_tnl_CreateContext( ctx ) ||
             !_swsetup_CreateContext( ctx )) {
            _mesa_destroy_visual(osmesa->gl_visual);
            _mesa_free_context_data(ctx);
            free(osmesa);
            return NULL;
         }
	
	 _swsetup_Wakeup( ctx );

         /* use default TCL pipeline */
         tnl = TNL_CONTEXT(ctx);
         tnl->Driver.RunPipeline = _tnl_run_pipeline;

         ctx->Driver.MapRenderbuffer = osmesa_MapRenderbuffer;
         ctx->Driver.UnmapRenderbuffer = osmesa_UnmapRenderbuffer;

         ctx->Driver.GenerateMipmap = _mesa_generate_mipmap;

         /* Extend the software rasterizer with our optimized line and triangle
          * drawing functions.
          */
         swrast = SWRAST_CONTEXT( ctx );
         swrast->choose_line = osmesa_choose_line;
         swrast->choose_triangle = osmesa_choose_triangle;

         _mesa_compute_version(ctx);

         if (ctx->Version < version_major * 10 + version_minor) {
            _mesa_destroy_visual(osmesa->gl_visual);
            _mesa_free_context_data(ctx);
            free(osmesa);
            return NULL;
         }

         /* Exec table initialization requires the version to be computed */
         _mesa_initialize_dispatch_tables(ctx);
         _mesa_initialize_vbo_vtxfmt(ctx);
      }
   }
   return osmesa;
}
Beispiel #16
0
/**
 * New in Mesa 3.5
 *
 * Create context and specify size of ancillary buffers.
 */
GLAPI OSMesaContext GLAPIENTRY
OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
                        GLint accumBits, OSMesaContext sharelist )
{
   OSMesaContext osmesa;
   struct dd_function_table functions;
   GLint rind, gind, bind, aind;
   GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;

   rind = gind = bind = aind = 0;
   if (format==OSMESA_RGBA) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      rind = 0;
      gind = 1;
      bind = 2;
      aind = 3;
   }
   else if (format==OSMESA_BGRA) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      bind = 0;
      gind = 1;
      rind = 2;
      aind = 3;
   }
   else if (format==OSMESA_ARGB) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      aind = 0;
      rind = 1;
      gind = 2;
      bind = 3;
   }
   else if (format==OSMESA_RGB) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = 0;
      rind = 0;
      gind = 1;
      bind = 2;
   }
   else if (format==OSMESA_BGR) {
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = 0;
      rind = 2;
      gind = 1;
      bind = 0;
   }
#if CHAN_TYPE == GL_UNSIGNED_BYTE
   else if (format==OSMESA_RGB_565) {
      redBits = 5;
      greenBits = 6;
      blueBits = 5;
      alphaBits = 0;
      rind = 0; /* not used */
      gind = 0;
      bind = 0;
   }
#endif
   else {
      return NULL;
   }

   osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
   if (osmesa) {
      osmesa->gl_visual = _mesa_create_visual( GL_FALSE,    /* double buffer */
                                               GL_FALSE,    /* stereo */
                                               redBits,
                                               greenBits,
                                               blueBits,
                                               alphaBits,
                                               depthBits,
                                               stencilBits,
                                               accumBits,
                                               accumBits,
                                               accumBits,
                                               alphaBits ? accumBits : 0,
                                               1            /* num samples */
                                               );
      if (!osmesa->gl_visual) {
         free(osmesa);
         return NULL;
      }

      /* Initialize device driver function table */
      _mesa_init_driver_functions(&functions);
      /* override with our functions */
      functions.GetString = get_string;
      functions.UpdateState = osmesa_update_state;
      functions.GetBufferSize = NULL;

      if (!_mesa_initialize_context(&osmesa->mesa,
                                    API_OPENGL_COMPAT,
                                    osmesa->gl_visual,
                                    sharelist ? &sharelist->mesa
                                              : (struct gl_context *) NULL,
                                    &functions)) {
         _mesa_destroy_visual( osmesa->gl_visual );
         free(osmesa);
         return NULL;
      }

      _mesa_enable_sw_extensions(&(osmesa->mesa));
      _mesa_enable_1_3_extensions(&(osmesa->mesa));
      _mesa_enable_1_4_extensions(&(osmesa->mesa));
      _mesa_enable_1_5_extensions(&(osmesa->mesa));
      _mesa_enable_2_0_extensions(&(osmesa->mesa));
      _mesa_enable_2_1_extensions(&(osmesa->mesa));

      osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
      if (!osmesa->gl_buffer) {
         _mesa_destroy_visual( osmesa->gl_visual );
         _mesa_free_context_data( &osmesa->mesa );
         free(osmesa);
         return NULL;
      }

      /* Create depth/stencil/accum buffers.  We'll create the color
       * buffer later in OSMesaMakeCurrent().
       */
      _swrast_add_soft_renderbuffers(osmesa->gl_buffer,
                                     GL_FALSE, /* color */
                                     osmesa->gl_visual->haveDepthBuffer,
                                     osmesa->gl_visual->haveStencilBuffer,
                                     osmesa->gl_visual->haveAccumBuffer,
                                     GL_FALSE, /* alpha */
                                     GL_FALSE /* aux */ );

      osmesa->format = format;
      osmesa->userRowLength = 0;
      osmesa->yup = GL_TRUE;
      osmesa->rInd = rind;
      osmesa->gInd = gind;
      osmesa->bInd = bind;
      osmesa->aInd = aind;

      _mesa_meta_init(&osmesa->mesa);

      /* Initialize the software rasterizer and helper modules. */
      {
	 struct gl_context *ctx = &osmesa->mesa;
         SWcontext *swrast;
         TNLcontext *tnl;

	 if (!_swrast_CreateContext( ctx ) ||
             !_vbo_CreateContext( ctx ) ||
             !_tnl_CreateContext( ctx ) ||
             !_swsetup_CreateContext( ctx )) {
            _mesa_destroy_visual(osmesa->gl_visual);
            _mesa_free_context_data(ctx);
            free(osmesa);
            return NULL;
         }
	
	 _swsetup_Wakeup( ctx );

         /* use default TCL pipeline */
         tnl = TNL_CONTEXT(ctx);
         tnl->Driver.RunPipeline = _tnl_run_pipeline;

         ctx->Driver.MapRenderbuffer = osmesa_MapRenderbuffer;
         ctx->Driver.UnmapRenderbuffer = osmesa_UnmapRenderbuffer;

         /* Extend the software rasterizer with our optimized line and triangle
          * drawing functions.
          */
         swrast = SWRAST_CONTEXT( ctx );
         swrast->choose_line = osmesa_choose_line;
         swrast->choose_triangle = osmesa_choose_triangle;
      }
   }
   return osmesa;
}
/*
 * Create a new FX/Mesa context and return a handle to it.
 */
fxMesaContext GLAPIENTRY
fxMesaCreateContext(GLuint win,
		    GrScreenResolution_t res,
		    GrScreenRefresh_t ref, const GLint attribList[])
{
 fxMesaContext fxMesa = NULL;
 GLcontext *ctx = NULL, *shareCtx = NULL;
 struct dd_function_table functions;

 int i;
 const char *str;
 int sliaa, numSLI, samplesPerChip;
 struct SstCard_St *voodoo;
 struct tdfx_glide *Glide;

 GLboolean aux;
 GLboolean doubleBuffer;
 GLuint colDepth;
 GLuint depthSize, alphaSize, stencilSize, accumSize;
 GLuint redBits, greenBits, blueBits, alphaBits;
 GrPixelFormat_t pixFmt;
   
 if (TDFX_DEBUG & VERBOSE_DRIVER) {
    fprintf(stderr, "fxMesaCreateContext(...)\n");
 }

 /* Okay, first process the user flags */
 aux = GL_FALSE;
 doubleBuffer = GL_FALSE;
 colDepth = 16;
 depthSize = alphaSize = stencilSize = accumSize = 0;

 i = 0;
 while (attribList[i] != FXMESA_NONE) {
       switch (attribList[i]) {
              case FXMESA_COLORDEPTH:
	           colDepth = attribList[++i];
	           break;
              case FXMESA_DOUBLEBUFFER:
	           doubleBuffer = GL_TRUE;
	           break;
              case FXMESA_ALPHA_SIZE:
	           if ((alphaSize = attribList[++i])) {
	              aux = GL_TRUE;
                   }
	           break;
              case FXMESA_DEPTH_SIZE:
	           if ((depthSize = attribList[++i])) {
	              aux = GL_TRUE;
                   }
	           break;
              case FXMESA_STENCIL_SIZE:
	           stencilSize = attribList[++i];
	           break;
              case FXMESA_ACCUM_SIZE:
	           accumSize = attribList[++i];
	           break;
              /* XXX ugly hack here for sharing display lists */
              case FXMESA_SHARE_CONTEXT:
                   shareCtx = (GLcontext *)attribList[++i];
	           break;
              default:
                   fprintf(stderr, "fxMesaCreateContext: ERROR: wrong parameter (%d) passed\n", attribList[i]);
	           return NULL;
       }
       i++;
 }

 if (!fxQueryHardware()) {
    str = "no Voodoo hardware!";
    goto errorhandler;
 }

 grSstSelect(glbCurrentBoard);
 /*grEnable(GR_OPENGL_MODE_EXT);*/ /* [koolsmoky] */
 voodoo = &glbHWConfig.SSTs[glbCurrentBoard];

 fxMesa = (fxMesaContext)CALLOC_STRUCT(tfxMesaContext);
 if (!fxMesa) {
    str = "private context";
    goto errorhandler;
 }

 if (getenv("MESA_FX_INFO")) {
    fxMesa->verbose = GL_TRUE;
 }

 fxMesa->type = voodoo->type;
 fxMesa->HavePalExt = voodoo->HavePalExt && !getenv("MESA_FX_IGNORE_PALEXT");
 fxMesa->HavePixExt = voodoo->HavePixExt && !getenv("MESA_FX_IGNORE_PIXEXT");
 fxMesa->HaveTexFmt = voodoo->HaveTexFmt && !getenv("MESA_FX_IGNORE_TEXFMT");
 fxMesa->HaveCmbExt = voodoo->HaveCmbExt && !getenv("MESA_FX_IGNORE_CMBEXT");
 fxMesa->HaveMirExt = voodoo->HaveMirExt && !getenv("MESA_FX_IGNORE_MIREXT");
 fxMesa->HaveTexUma = voodoo->HaveTexUma && !getenv("MESA_FX_IGNORE_TEXUMA");
 fxMesa->Glide = glbHWConfig.Glide;
 Glide = &fxMesa->Glide;
 fxMesa->HaveTexus2 = Glide->txImgQuantize &&
                      Glide->txMipQuantize &&
                      Glide->txPalToNcc && !getenv("MESA_FX_IGNORE_TEXUS2");

 /* Determine if we need vertex swapping, RGB order and SLI/AA */
 sliaa = 0;
 switch (fxMesa->type) {
        case GR_SSTTYPE_VOODOO:
        case GR_SSTTYPE_SST96:
        case GR_SSTTYPE_Banshee:
             fxMesa->bgrOrder = GL_TRUE;
             fxMesa->snapVertices = (getenv("MESA_FX_NOSNAP") == NULL);
             break;
        case GR_SSTTYPE_Voodoo2:
             fxMesa->bgrOrder = GL_TRUE;
             fxMesa->snapVertices = GL_FALSE;
             break;
        case GR_SSTTYPE_Voodoo4:
        case GR_SSTTYPE_Voodoo5:
             /* number of SLI units and AA Samples per chip */
             if ((str = Glide->grGetRegistryOrEnvironmentStringExt("SSTH3_SLI_AA_CONFIGURATION")) != NULL) {
                sliaa = atoi(str);
             }
        case GR_SSTTYPE_Voodoo3:
        default:
             fxMesa->bgrOrder = GL_FALSE;
             fxMesa->snapVertices = GL_FALSE;
             break;
 }
 /* XXX todo - Add the old SLI/AA settings for Napalm. */
 switch(voodoo->numChips) {
 case 4: /* 4 chips */
   switch(sliaa) {
   case 8: /* 8 Sample AA */
     numSLI         = 1;
     samplesPerChip = 2;
     break;
   case 7: /* 4 Sample AA */
     numSLI         = 1;
     samplesPerChip = 1;
     break;
   case 6: /* 2 Sample AA */
     numSLI         = 2;
     samplesPerChip = 1;
     break;
   default:
     numSLI         = 4;
     samplesPerChip = 1;
   }
   break;
 case 2: /* 2 chips */
   switch(sliaa) {
   case 4: /* 4 Sample AA */
     numSLI         = 1;
     samplesPerChip = 2;
     break;
   case 3: /* 2 Sample AA */
     numSLI         = 1;
     samplesPerChip = 1;
     break;
   default:
     numSLI         = 2;
     samplesPerChip = 1;
   }
   break;
 default: /* 1 chip */
   switch(sliaa) {
   case 1: /* 2 Sample AA */
     numSLI         = 1;
     samplesPerChip = 2;
     break;
   default:
     numSLI         = 1;
     samplesPerChip = 1;
   }
 }

 fxMesa->fsaa = samplesPerChip * voodoo->numChips / numSLI; /* 1:noFSAA, 2:2xFSAA, 4:4xFSAA, 8:8xFSAA */

 switch (fxMesa->colDepth = colDepth) {
   case 15:
     redBits   = 5;
     greenBits = 5;
     blueBits  = 5;
     alphaBits = depthSize ? 1 : 8;
     switch(fxMesa->fsaa) {
       case 8:
         pixFmt = GR_PIXFMT_AA_8_ARGB_1555;
         break;
       case 4:
         pixFmt = GR_PIXFMT_AA_4_ARGB_1555;
         break;
       case 2:
         pixFmt = GR_PIXFMT_AA_2_ARGB_1555;
         break;
       default:
         pixFmt = GR_PIXFMT_ARGB_1555;
     }
     break;
   case 16:
     redBits   = 5;
     greenBits = 6;
     blueBits  = 5;
     alphaBits = depthSize ? 0 : 8;
     switch(fxMesa->fsaa) {
       case 8:
         pixFmt = GR_PIXFMT_AA_8_RGB_565;
         break;
       case 4:
         pixFmt = GR_PIXFMT_AA_4_RGB_565;
         break;
       case 2:
         pixFmt = GR_PIXFMT_AA_2_RGB_565;
         break;
       default:
         pixFmt = GR_PIXFMT_RGB_565;
     }
     break;
   case 24:
     fxMesa->colDepth = 32;
   case 32:
     redBits   = 8;
     greenBits = 8;
     blueBits  = 8;
     alphaBits = 8;
     switch(fxMesa->fsaa) {
       case 8:
         pixFmt = GR_PIXFMT_AA_8_ARGB_8888;
         break;
       case 4:
         pixFmt = GR_PIXFMT_AA_4_ARGB_8888;
         break;
       case 2:
         pixFmt = GR_PIXFMT_AA_2_ARGB_8888;
         break;
       default:
         pixFmt = GR_PIXFMT_ARGB_8888;
     }
     break;
   default:
     str = "pixelFormat";
     goto errorhandler;
 }

 /* Tips:
  * 1. we don't bother setting/checking AUX for stencil, because we'll decide
  *    later whether we have HW stencil, based on depth buffer (thus AUX is
  *    properly set)
  * 2. when both DEPTH and ALPHA are enabled, depth should win. However, it is
  *    not clear whether 15bpp and 32bpp require AUX alpha buffer. Furthermore,
  *    alpha buffering is required only if destination alpha is used in alpha
  *    blending; alpha blending modes that do not use destination alpha can be
  *    used w/o alpha buffer.
  * 3. `alphaBits' is what we can provide
  *    `alphaSize' is what app requests
  *    if we cannot provide enough bits for alpha buffer, we should fallback to
  *    SW alpha. However, setting `alphaBits' to `alphaSize' might confuse some
  *    of the span functions...
  */

 fxMesa->haveHwAlpha = GL_FALSE;
 if (alphaSize && (alphaSize <= alphaBits)) {
    alphaSize = alphaBits;
    fxMesa->haveHwAlpha = GL_TRUE;
 }

 fxMesa->haveHwStencil = (fxMesa->HavePixExt && stencilSize && depthSize == 24);

 fxMesa->haveZBuffer = depthSize > 0;
 fxMesa->haveDoubleBuffer = doubleBuffer;
 fxMesa->haveGlobalPaletteTexture = GL_FALSE;
 fxMesa->board = glbCurrentBoard;

 fxMesa->haveTwoTMUs = (voodoo->nTexelfx > 1);

 if ((str = Glide->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_NUM_TMU"))) {
    if (atoi(str) <= 1) {
       fxMesa->haveTwoTMUs = GL_FALSE;
    }
 }

 if ((str = Glide->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPPENDINGCOUNT"))) {
    fxMesa->maxPendingSwapBuffers = atoi(str);
    if (fxMesa->maxPendingSwapBuffers > 6) {
       fxMesa->maxPendingSwapBuffers = 6;
    } else if (fxMesa->maxPendingSwapBuffers < 0) {
       fxMesa->maxPendingSwapBuffers = 0;
    }
 } else {
    fxMesa->maxPendingSwapBuffers = 2;
 }

 if ((str = Glide->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPINTERVAL"))) {
    fxMesa->swapInterval = atoi(str);
 } else {
    fxMesa->swapInterval = 0;
 }

 BEGIN_BOARD_LOCK();
 if (fxMesa->HavePixExt) {
    fxMesa->glideContext = Glide->grSstWinOpenExt((FxU32)win, res, ref,
                                                  GR_COLORFORMAT_ABGR, GR_ORIGIN_LOWER_LEFT,
                                                  pixFmt,
                                                  2, aux);
 } else if (pixFmt == GR_PIXFMT_RGB_565) {
    fxMesa->glideContext = grSstWinOpen((FxU32)win, res, ref,
                                        GR_COLORFORMAT_ABGR, GR_ORIGIN_LOWER_LEFT,
                                        2, aux);
 } else {
    fxMesa->glideContext = 0;
 }
 END_BOARD_LOCK();
 if (!fxMesa->glideContext) {
    str = "grSstWinOpen";
    goto errorhandler;
 }

   /* screen */
   fxMesa->screen_width = FX_grSstScreenWidth();
   fxMesa->screen_height = FX_grSstScreenHeight();

   /* window inside screen */
   fxMesa->width = fxMesa->screen_width;
   fxMesa->height = fxMesa->screen_height;

   /* scissor inside window */
   fxMesa->clipMinX = 0;
   fxMesa->clipMaxX = fxMesa->width;
   fxMesa->clipMinY = 0;
   fxMesa->clipMaxY = fxMesa->height;

   if (fxMesa->verbose) {
      FxI32 tmuRam, fbRam;

      /* Not that it matters, but tmuRam and fbRam change after grSstWinOpen. */
      tmuRam = voodoo->tmuConfig[GR_TMU0].tmuRam;
      fbRam  = voodoo->fbRam;
      BEGIN_BOARD_LOCK();
      grGet(GR_MEMORY_TMU, 4, &tmuRam);
      grGet(GR_MEMORY_FB, 4, &fbRam);
      END_BOARD_LOCK();

      fprintf(stderr, "Voodoo Using Glide %s\n", grGetString(GR_VERSION));
      fprintf(stderr, "Voodoo Board: %d/%d, %s, %d GPU\n",
                      fxMesa->board + 1,
                      glbHWConfig.num_sst,
                      grGetString(GR_HARDWARE),
                      voodoo->numChips);
      fprintf(stderr, "Voodoo Memory: FB = %ld, TM = %d x %ld\n",
                      fbRam,
                      voodoo->nTexelfx,
                      tmuRam);
      fprintf(stderr, "Voodoo Screen: %dx%d:%d %s, %svertex snapping\n",
	              fxMesa->screen_width,
                      fxMesa->screen_height,
                      colDepth,
                      fxMesa->bgrOrder ? "BGR" : "RGB",
                      fxMesa->snapVertices ? "" : "no ");
   }

  sprintf(fxMesa->rendererString, "Mesa %s v0.63 %s%s",
          grGetString(GR_RENDERER),
          grGetString(GR_HARDWARE),
          ((fxMesa->type < GR_SSTTYPE_Voodoo4) && (voodoo->numChips > 1)) ? " SLI" : "");

   fxMesa->glVis = _mesa_create_visual(GL_TRUE,		/* RGB mode */
				       doubleBuffer,
				       GL_FALSE,	/* stereo */
				       redBits,		/* RGBA.R bits */
				       greenBits,	/* RGBA.G bits */
				       blueBits,	/* RGBA.B bits */
				       alphaSize,	/* RGBA.A bits */
				       0,		/* index bits */
				       depthSize,	/* depth_size */
				       stencilSize,	/* stencil_size */
				       accumSize,
				       accumSize,
				       accumSize,
				       alphaSize ? accumSize : 0,
                                       1);
   if (!fxMesa->glVis) {
      str = "_mesa_create_visual";
      goto errorhandler;
   }

   _mesa_init_driver_functions(&functions);
   ctx = fxMesa->glCtx = _mesa_create_context(fxMesa->glVis, shareCtx,
					      &functions, (void *) fxMesa);
   if (!ctx) {
      str = "_mesa_create_context";
      goto errorhandler;
   }


   if (!fxDDInitFxMesaContext(fxMesa)) {
      str = "fxDDInitFxMesaContext";
      goto errorhandler;
   }


   fxMesa->glBuffer = _mesa_create_framebuffer(fxMesa->glVis);
#if 0
/* XXX this is a complete mess :(
 *	_mesa_add_soft_renderbuffers
 *	driNewRenderbuffer
 */
					       GL_FALSE,	/* no software depth */
					       stencilSize && !fxMesa->haveHwStencil,
					       fxMesa->glVis->accumRedBits > 0,
					       alphaSize && !fxMesa->haveHwAlpha);
#endif
   if (!fxMesa->glBuffer) {
      str = "_mesa_create_framebuffer";
      goto errorhandler;
   }

   glbTotNumCtx++;

   /* install signal handlers */
#if defined(__linux__)
   /* Only install if environment var. is not set. */
   if (!getenv("MESA_FX_NO_SIGNALS")) {
      signal(SIGINT, cleangraphics_handler);
      signal(SIGHUP, cleangraphics_handler);
      signal(SIGPIPE, cleangraphics_handler);
      signal(SIGFPE, cleangraphics_handler);
      signal(SIGBUS, cleangraphics_handler);
      signal(SIGILL, cleangraphics_handler);
      signal(SIGSEGV, cleangraphics_handler);
      signal(SIGTERM, cleangraphics_handler);
   }
#endif

   return fxMesa;

errorhandler:
 if (fxMesa) {
    if (fxMesa->glideContext) {
       grSstWinClose(fxMesa->glideContext);
       fxMesa->glideContext = 0;
    }

    if (fxMesa->state) {
       FREE(fxMesa->state);
    }
    if (fxMesa->fogTable) {
       FREE(fxMesa->fogTable);
    }
    if (fxMesa->glBuffer) {
       _mesa_unreference_framebuffer(&fxMesa->glBuffer);
    }
    if (fxMesa->glVis) {
       _mesa_destroy_visual(fxMesa->glVis);
    }
    if (fxMesa->glCtx) {
       _mesa_destroy_context(fxMesa->glCtx);
    }
    FREE(fxMesa);
 }

 fprintf(stderr, "fxMesaCreateContext: ERROR: %s\n", str);
 return NULL;
}