X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fsavage%2Fsavage_xmesa.c;h=9678c526aa01721503b8f8fd9dd03fefa0f258e4;hb=aac367f48afc62176faf67aa6f329fbeae2004b4;hp=bcbc9d69ed4f89d0173a5067e7ebf35b9e0d30fc;hpb=3d0487980196d386e75235fe9be0513546083613;p=mesa.git diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index bcbc9d69ed4..9678c526aa0 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -23,23 +23,24 @@ */ -#ifdef GLX_DIRECT_RENDERING - #include #include #include "savagecontext.h" #include "context.h" #include "matrix.h" - +#include "framebuffer.h" +#include "renderbuffer.h" #include "simple_list.h" #include "utils.h" +#include "extensions.h" + #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -55,10 +56,35 @@ #include "savage_dri.h" -#include "savagedma.h" +#include "drirenderbuffer.h" +#include "texmem.h" + +#define need_GL_ARB_multisample +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_EXT_secondary_color +#include "extension_helper.h" #include "xmlpool.h" +/* Driver-specific options + */ +#define SAVAGE_ENABLE_VDMA(def) \ +DRI_CONF_OPT_BEGIN(enable_vdma,bool,def) \ + DRI_CONF_DESC(en,"Use DMA for vertex transfers") \ + DRI_CONF_DESC(de,"Benutze DMA für Vertextransfers") \ +DRI_CONF_OPT_END +#define SAVAGE_ENABLE_FASTPATH(def) \ +DRI_CONF_OPT_BEGIN(enable_fastpath,bool,def) \ + DRI_CONF_DESC(en,"Use fast path for unclipped primitives") \ + DRI_CONF_DESC(de,"Schneller Codepfad für ungeschnittene Polygone") \ +DRI_CONF_OPT_END +#define SAVAGE_SYNC_FRAMES(def) \ +DRI_CONF_OPT_BEGIN(sync_frames,bool,def) \ + DRI_CONF_DESC(en,"Synchronize with graphics hardware after each frame") \ + DRI_CONF_DESC(de,"Synchronisiere nach jedem Frame mit Grafikhardware") \ +DRI_CONF_OPT_END + /* Configuration */ PUBLIC const char __driConfigOptions[] = @@ -66,25 +92,31 @@ DRI_CONF_BEGIN DRI_CONF_SECTION_QUALITY DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) + DRI_CONF_FLOAT_DEPTH(false) DRI_CONF_SECTION_END DRI_CONF_SECTION_PERFORMANCE + SAVAGE_ENABLE_VDMA(true) + SAVAGE_ENABLE_FASTPATH(true) + SAVAGE_SYNC_FRAMES(false) DRI_CONF_MAX_TEXTURE_UNITS(2,1,2) + DRI_CONF_TEXTURE_HEAPS(DRI_CONF_TEXTURE_HEAPS_ALL) + DRI_CONF_FORCE_S3TC_ENABLE(false) DRI_CONF_SECTION_END DRI_CONF_SECTION_DEBUG DRI_CONF_NO_RAST(false) DRI_CONF_SECTION_END DRI_CONF_END; -static const GLuint __driNConfigOptions = 4; +static const GLuint __driNConfigOptions = 10; -#ifdef USE_NEW_INTERFACE -static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -#endif /* USE_NEW_INTERFACE */ static const struct dri_debug_control debug_control[] = { { "fall", DEBUG_FALLBACKS }, { "api", DEBUG_VERBOSE_API }, - { "lru", DEBUG_VERBOSE_LRU }, + { "tex", DEBUG_VERBOSE_TEX }, + { "verb", DEBUG_VERBOSE_MSG }, + { "dma", DEBUG_DMA }, + { "state", DEBUG_STATE }, { NULL, 0 } }; #ifndef SAVAGE_DEBUG @@ -99,15 +131,27 @@ unsigned long time_sum=0; struct timeval tv_s1,tv_f1; #endif -static const char *const card_extensions[] = +static const struct dri_extension card_extensions[] = { - "GL_ARB_multitexture", - "GL_EXT_texture_lod_bias", - "GL_EXT_texture_env_add", - NULL + { "GL_ARB_multisample", GL_ARB_multisample_functions }, + { "GL_ARB_multitexture", NULL }, + { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, + { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, + { "GL_EXT_stencil_wrap", NULL }, + { "GL_EXT_texture_lod_bias", NULL }, + { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, + { NULL, NULL } }; -extern const struct tnl_pipeline_stage _savage_texnorm_stage; +static const struct dri_extension s4_extensions[] = +{ + { "GL_ARB_texture_env_add", NULL }, + { "GL_ARB_texture_mirrored_repeat", NULL }, + { NULL, NULL } +}; + +extern struct tnl_pipeline_stage _savage_texnorm_stage; +extern struct tnl_pipeline_stage _savage_render_stage; static const struct tnl_pipeline_stage *savage_pipeline[] = { @@ -118,6 +162,7 @@ static const struct tnl_pipeline_stage *savage_pipeline[] = { &_tnl_texgen_stage, &_tnl_texture_transform_stage, &_savage_texnorm_stage, + &_savage_render_stage, &_tnl_render_stage, 0, }; @@ -130,8 +175,15 @@ savageInitDriver(__DRIscreenPrivate *sPriv) { savageScreenPrivate *savageScreen; SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv; + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); + if (sPriv->devPrivSize != sizeof(SAVAGEDRIRec)) { + fprintf(stderr,"\nERROR! sizeof(SAVAGEDRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + /* Allocate the private area */ savageScreen = (savageScreenPrivate *)Xmalloc(sizeof(savageScreenPrivate)); if (!savageScreen) @@ -146,23 +198,19 @@ savageInitDriver(__DRIscreenPrivate *sPriv) savageScreen->mem=gDRIPriv->mem; savageScreen->cpp=gDRIPriv->cpp; savageScreen->zpp=gDRIPriv->zpp; - savageScreen->frontPitch=gDRIPriv->frontPitch; - savageScreen->frontOffset=gDRIPriv->frontOffset; - savageScreen->frontBitmapDesc = gDRIPriv->frontBitmapDesc; - + + savageScreen->agpMode=gDRIPriv->agpMode; + + savageScreen->bufferSize=gDRIPriv->bufferSize; + if (gDRIPriv->cpp == 4) savageScreen->frontFormat = DV_PF_8888; else savageScreen->frontFormat = DV_PF_565; - + savageScreen->frontOffset=gDRIPriv->frontOffset; savageScreen->backOffset = gDRIPriv->backOffset; - savageScreen->backBitmapDesc = gDRIPriv->backBitmapDesc; savageScreen->depthOffset=gDRIPriv->depthOffset; - savageScreen->depthBitmapDesc = gDRIPriv->depthBitmapDesc; -#if 0 - savageScreen->backPitch = gDRIPriv->auxPitch; - savageScreen->backPitchBits = gDRIPriv->auxPitchBits; -#endif + savageScreen->textureOffset[SAVAGE_CARD_HEAP] = gDRIPriv->textureOffset; savageScreen->textureSize[SAVAGE_CARD_HEAP] = @@ -171,57 +219,34 @@ savageInitDriver(__DRIscreenPrivate *sPriv) gDRIPriv->logTextureGranularity; savageScreen->textureOffset[SAVAGE_AGP_HEAP] = - gDRIPriv->agpTextures.handle; + gDRIPriv->agpTextureHandle; savageScreen->textureSize[SAVAGE_AGP_HEAP] = - gDRIPriv->agpTextures.size; + gDRIPriv->agpTextureSize; savageScreen->logTextureGranularity[SAVAGE_AGP_HEAP] = gDRIPriv->logAgpTextureGranularity; - - savageScreen->back.handle = gDRIPriv->backbuffer; - savageScreen->back.size = gDRIPriv->backbufferSize; - savageScreen->back.map = - (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->backOffset); - - savageScreen->depth.handle = gDRIPriv->depthbuffer; - savageScreen->depth.size = gDRIPriv->depthbufferSize; - savageScreen->depth.map = - (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->depthOffset); - - savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + savageScreen->agpTextures.handle = gDRIPriv->agpTextureHandle; + savageScreen->agpTextures.size = gDRIPriv->agpTextureSize; + if (gDRIPriv->agpTextureSize) { + if (drmMap(sPriv->fd, + savageScreen->agpTextures.handle, + savageScreen->agpTextures.size, + (drmAddress *)&(savageScreen->agpTextures.map)) != 0) { + Xfree(savageScreen); + sPriv->private = NULL; + return GL_FALSE; + } + } else + savageScreen->agpTextures.map = NULL; savageScreen->texVirtual[SAVAGE_CARD_HEAP] = - (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset); - - if (drmMap(sPriv->fd, - gDRIPriv->registers.handle, - gDRIPriv->registers.size, - (drmAddress *)&(gDRIPriv->registers.map)) != 0) - { - Xfree(savageScreen); - sPriv->private = NULL; - return GL_FALSE; - } - - if (drmMap(sPriv->fd, - gDRIPriv->agpTextures.handle, - gDRIPriv->agpTextures.size, - (drmAddress *)&(gDRIPriv->agpTextures.map)) != 0) - { - Xfree(savageScreen); - sPriv->private = NULL; - return GL_FALSE; - } - -/* agp texture*/ + (drmAddress)(((GLubyte *)sPriv->pFB)+gDRIPriv->textureOffset); savageScreen->texVirtual[SAVAGE_AGP_HEAP] = - (drmAddress)(gDRIPriv->agpTextures.map); + (drmAddress)(savageScreen->agpTextures.map); - gDRIPriv->BCIcmdBuf.map = (drmAddress *) - ((unsigned int)gDRIPriv->registers.map+0x00010000); - - savageScreen->aperture.handle = gDRIPriv->aperture.handle; - savageScreen->aperture.size = gDRIPriv->aperture.size; + savageScreen->aperture.handle = gDRIPriv->apertureHandle; + savageScreen->aperture.size = gDRIPriv->apertureSize; + savageScreen->aperturePitch = gDRIPriv->aperturePitch; if (drmMap(sPriv->fd, savageScreen->aperture.handle, savageScreen->aperture.size, @@ -230,12 +255,20 @@ savageInitDriver(__DRIscreenPrivate *sPriv) Xfree(savageScreen); sPriv->private = NULL; return GL_FALSE; - } - + } + + savageScreen->bufs = drmMapBufs(sPriv->fd); + + savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + /* parse information in __driConfigOptions */ driParseOptionInfo (&savageScreen->optionCache, __driConfigOptions, __driNConfigOptions); + if (glx_enable_extension != NULL) { + (*glx_enable_extension)(sPriv->psc, "GLX_SGI_make_current_read"); + } + #if 0 savageDDFastPathInit(); savageDDTrifuncInit(); @@ -251,6 +284,9 @@ savageDestroyScreen(__DRIscreenPrivate *sPriv) { savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private; + if (savageScreen->bufs) + drmUnmapBufs(savageScreen->bufs); + /* free all option information */ driDestroyOptionInfo (&savageScreen->optionCache); @@ -295,11 +331,10 @@ savageCreateContext( const __GLcontextModes *mesaVis, savageContextPtr imesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; struct dd_function_table functions; - SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv; savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private; drm_savage_sarea_t *saPriv=(drm_savage_sarea_t *)(((char*)sPriv->pSAREA)+ savageScreen->sarea_priv_offset); - GLuint maxTextureSize, minTextureSize, maxTextureLevels; + int textureSize[SAVAGE_NR_TEX_HEAPS]; int i; imesa = (savageContextPtr)Xcalloc(sizeof(savageContext), 1); if (!imesa) { @@ -323,59 +358,19 @@ savageCreateContext( const __GLcontextModes *mesaVis, } driContextPriv->driverPrivate = imesa; + imesa->cmdBuf.size = SAVAGE_CMDBUF_SIZE; + imesa->cmdBuf.base = imesa->cmdBuf.write = + malloc(SAVAGE_CMDBUF_SIZE * sizeof(drm_savage_cmd_header_t)); + if (!imesa->cmdBuf.base) + return GL_FALSE; + /* Parse configuration files */ driParseConfigFiles (&imesa->optionCache, &savageScreen->optionCache, sPriv->myNum, "savage"); - imesa->texture_depth = driQueryOptioni (&imesa->optionCache, - "texture_depth"); - if (imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) - imesa->texture_depth = ( savageScreen->cpp == 4 ) ? - DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; - - if (savageScreen->chipset >= S3_SAVAGE4) - ctx->Const.MaxTextureUnits = 2; - else - ctx->Const.MaxTextureUnits = 1; - if (driQueryOptioni(&imesa->optionCache, "texture_units") < - ctx->Const.MaxTextureUnits) - ctx->Const.MaxTextureUnits = - driQueryOptioni(&imesa->optionCache, "texture_units"); - ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; - ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; - - /* Set the maximum texture size small enough that we can guarentee - * that all texture units can bind a maximal texture and have them - * in memory at once. - */ - if (savageScreen->textureSize[SAVAGE_CARD_HEAP] > - savageScreen->textureSize[SAVAGE_AGP_HEAP]) { - maxTextureSize = savageScreen->textureSize[SAVAGE_CARD_HEAP]; - minTextureSize = savageScreen->textureSize[SAVAGE_AGP_HEAP]; - } else { - maxTextureSize = savageScreen->textureSize[SAVAGE_AGP_HEAP]; - minTextureSize = savageScreen->textureSize[SAVAGE_CARD_HEAP]; - } - if (ctx->Const.MaxTextureUnits == 2) { - /* How to distribute two maximum sized textures to two texture heaps? - * If the smaller heap is less then half the size of the bigger one - * then the maximum size is half the size of the bigger heap. - * Otherwise it's the size of the smaller heap. */ - if (minTextureSize < maxTextureSize / 2) - maxTextureSize = maxTextureSize / 2; - else - maxTextureSize = minTextureSize; - } - for (maxTextureLevels = 1; maxTextureLevels <= 11; ++maxTextureLevels) { - GLuint size = 1 << maxTextureLevels; - size *= size * 4; /* 4 bytes per texel */ - size = size * 4/3; /* all mipmap levels together take roughly - 4/3 the size of the biggest level */ - if (size > maxTextureSize) - break; - } - ctx->Const.MaxTextureLevels = maxTextureLevels; - assert (ctx->Const.MaxTextureLevels > 6); /*spec requires at least 64x64*/ + imesa->float_depth = driQueryOptionb(&imesa->optionCache, "float_depth") && + savageScreen->chipset >= S3_SAVAGE4; + imesa->no_rast = driQueryOptionb(&imesa->optionCache, "no_rast"); #if 0 ctx->Const.MinLineWidth = 1.0; @@ -398,49 +393,104 @@ savageCreateContext( const __GLcontextModes *mesaVis, /* DMA buffer */ - /*The shadow pointer*/ - imesa->shadowPointer = - (volatile GLuint *)((((GLuint)(&saPriv->shadow_status)) + 31) & 0xffffffe0L) ; - /* here we use eventTag1 because eventTag0 is used by HWXvMC*/ - imesa->eventTag1 = (volatile GLuint *)(imesa->shadowPointer + 6); - /* imesa->eventTag1=(volatile GLuint *)(imesa->MMIO_BASE+0x48c04);*/ - imesa->shadowCounter = MAX_SHADOWCOUNTER; - imesa->shadowStatus = GL_TRUE;/*Will judge by 2d message */ - - imesa->MMIO_BASE = (GLuint)gDRIPriv->registers.map; - imesa->BCIBase= (GLuint)gDRIPriv->BCIcmdBuf.map; for(i=0;i<5;i++) { - imesa->apertureBase[i] = ((GLuint)savageScreen->aperture.map + - 0x01000000 * i ); + imesa->apertureBase[i] = (GLubyte *)savageScreen->aperture.map + + 0x01000000 * i; } - imesa->aperturePitch = gDRIPriv->aperturePitch; - - + imesa->aperturePitch = savageScreen->aperturePitch; + /* change texHeap initialize to support two kind of texture heap*/ /* here is some parts of initialization, others in InitDriver() */ + (void) memset( imesa->textureHeaps, 0, sizeof( imesa->textureHeaps ) ); + make_empty_list( & imesa->swapped ); + + textureSize[SAVAGE_CARD_HEAP] = savageScreen->textureSize[SAVAGE_CARD_HEAP]; + textureSize[SAVAGE_AGP_HEAP] = savageScreen->textureSize[SAVAGE_AGP_HEAP]; imesa->lastTexHeap = savageScreen->texVirtual[SAVAGE_AGP_HEAP] ? 2 : 1; + switch(driQueryOptioni (&imesa->optionCache, "texture_heaps")) { + case DRI_CONF_TEXTURE_HEAPS_CARD: /* only use card memory, if available */ + if (textureSize[SAVAGE_CARD_HEAP]) + imesa->lastTexHeap = 1; + break; + case DRI_CONF_TEXTURE_HEAPS_GART: /* only use gart memory, if available */ + if (imesa->lastTexHeap == 2 && textureSize[SAVAGE_AGP_HEAP]) + textureSize[SAVAGE_CARD_HEAP] = 0; + break; + /*default: Nothing to do, use all available memory. */ + } - /*allocate texHeap for multi-tex*/ - { - int i; - - for(i=0;itexHeap[i] = mmInit( 0, savageScreen->textureSize[i] ); - make_empty_list(&imesa->TexObjList[i]); - } - - make_empty_list(&imesa->SwappedOut); + for (i = 0; i < imesa->lastTexHeap; i++) { + imesa->textureHeaps[i] = driCreateTextureHeap( + i, imesa, + textureSize[i], + 11, /* 2^11 = 2k alignment */ + SAVAGE_NR_TEX_REGIONS, + (drmTextureRegionPtr)imesa->sarea->texList[i], + &imesa->sarea->texAge[i], + &imesa->swapped, + sizeof( savageTexObj ), + (destroy_texture_object_t *) savageDestroyTexObj ); + /* If textureSize[i] == 0 textureHeaps[i] is NULL. This can happen + * if there is not enough card memory for a card texture heap. */ + if (imesa->textureHeaps[i]) + driSetTextureSwapCounterLocation( imesa->textureHeaps[i], + & imesa->c_textureSwaps ); + } + imesa->texture_depth = driQueryOptioni (&imesa->optionCache, + "texture_depth"); + if (imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) + imesa->texture_depth = ( savageScreen->cpp == 4 ) ? + DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; + + if (savageScreen->chipset >= S3_SAVAGE4) + ctx->Const.MaxTextureUnits = 2; + else + ctx->Const.MaxTextureUnits = 1; + if (driQueryOptioni(&imesa->optionCache, "texture_units") < + ctx->Const.MaxTextureUnits) + ctx->Const.MaxTextureUnits = + driQueryOptioni(&imesa->optionCache, "texture_units"); + ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + + driCalculateMaxTextureLevels( imesa->textureHeaps, + imesa->lastTexHeap, + & ctx->Const, + 4, + 11, /* max 2D texture size is 2048x2048 */ + 0, /* 3D textures unsupported. */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + 12, + GL_FALSE, + 0 ); + if (ctx->Const.MaxTextureLevels <= 6) { /*spec requires at least 64x64*/ + __driUtilMessage("Not enough texture memory. " + "Falling back to indirect rendering."); + Xfree(imesa); + return GL_FALSE; } imesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; imesa->depth_scale = (imesa->savageScreen->zpp == 2) ? - (1.0F/0x10000):(1.0F/0x1000000); + (1.0F/0xffff):(1.0F/0xffffff); + + imesa->bufferSize = savageScreen->bufferSize; + imesa->dmaVtxBuf.total = 0; + imesa->dmaVtxBuf.used = 0; + imesa->dmaVtxBuf.flushed = 0; + + imesa->clientVtxBuf.total = imesa->bufferSize / 4; + imesa->clientVtxBuf.used = 0; + imesa->clientVtxBuf.flushed = 0; + imesa->clientVtxBuf.buf = (u_int32_t *)malloc(imesa->bufferSize); - imesa->vertex_dma_buffer = NULL; + imesa->vtxBuf = &imesa->clientVtxBuf; + + imesa->firstElt = -1; /* Uninitialized vertex format. Force setting the vertex state in * savageRenderStart. @@ -450,29 +500,44 @@ savageCreateContext( const __GLcontextModes *mesaVis, /* Utah stuff */ imesa->new_state = ~0; + imesa->new_gl_state = ~0; imesa->RenderIndex = ~0; imesa->dirty = ~0; imesa->lostContext = GL_TRUE; - imesa->TextureMode = ctx->Texture.Unit[0].EnvMode; imesa->CurrentTexObj[0] = 0; imesa->CurrentTexObj[1] = 0; - imesa->texAge[SAVAGE_CARD_HEAP]=0; - imesa->texAge[SAVAGE_AGP_HEAP]=0; /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); /* Install the customized pipeline: */ -#if 1 _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, savage_pipeline ); -#endif + + imesa->enable_fastpath = driQueryOptionb(&imesa->optionCache, + "enable_fastpath"); + /* DRM versions before 2.1.3 would only render triangle lists. ELTS + * support was added in 2.2.0. */ + if (imesa->enable_fastpath && sPriv->drmMinor < 2) { + fprintf (stderr, + "*** Disabling fast path because your DRM version is buggy " + "or doesn't\n*** support ELTS. You need at least Savage DRM " + "version 2.2.\n"); + imesa->enable_fastpath = GL_FALSE; + } + + if (!savageScreen->bufs || savageScreen->chipset == S3_SUPERSAVAGE) + imesa->enable_vdma = GL_FALSE; + else + imesa->enable_vdma = driQueryOptionb(&imesa->optionCache, "enable_vdma"); + + imesa->sync_frames = driQueryOptionb(&imesa->optionCache, "sync_frames"); /* Configure swrast to match hardware characteristics: */ @@ -483,8 +548,6 @@ savageCreateContext( const __GLcontextModes *mesaVis, ctx->DriverCtx = (void *) imesa; imesa->glCtx = ctx; - if (savageDMAInit(imesa) == GL_FALSE) - return GL_FALSE; #ifndef SAVAGE_DEBUG SAVAGE_DEBUG = driParseDebugString( getenv( "SAVAGE_DEBUG" ), @@ -492,6 +555,16 @@ savageCreateContext( const __GLcontextModes *mesaVis, #endif driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (savageScreen->chipset >= S3_SAVAGE4) + driInitExtensions( ctx, s4_extensions, GL_FALSE ); + if (ctx->Mesa_DXTn || + driQueryOptionb (&imesa->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); + if (savageScreen->chipset >= S3_SAVAGE4) + /* This extension needs DXT3 and DTX5 support in hardware. + * Not available on Savage3D/MX/IX. */ + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + } savageDDInitStateFuncs( ctx ); savageDDInitSpanFuncs( ctx ); @@ -501,9 +574,6 @@ savageCreateContext( const __GLcontextModes *mesaVis, savageDDInitState( imesa ); - if (driQueryOptionb(&imesa->optionCache, "no_rast")) - FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_TRUE); - driContextPriv->driverPrivate = (void *) imesa; return GL_TRUE; @@ -513,27 +583,24 @@ static void savageDestroyContext(__DRIcontextPrivate *driContextPriv) { savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate; + GLuint i; assert (imesa); /* should never be NULL */ if (imesa) { - savageTextureObjectPtr next_t, t; + savageFlushVertices(imesa); + savageReleaseIndexedVerts(imesa); + savageFlushCmdBuf(imesa, GL_TRUE); /* release DMA buffer */ + WAIT_IDLE_EMPTY(imesa); - FLUSH_BATCH(imesa); + for (i = 0; i < imesa->lastTexHeap; i++) + driDestroyTextureHeap(imesa->textureHeaps[i]); + + free(imesa->cmdBuf.base); + free(imesa->clientVtxBuf.buf); - /* update for multi-tex*/ - { - int i; - for(i=0;iTexObjList[i])) - savageDestroyTexObj(imesa, t); - } - foreach_s (t, next_t, &(imesa->SwappedOut)) - savageDestroyTexObj(imesa, t); - /*free the dma buffer*/ - savageDMAClose(imesa); _swsetup_DestroyContext(imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); - _ac_DestroyContext( imesa->glCtx ); + _vbo_DestroyContext( imesa->glCtx ); _swrast_DestroyContext( imesa->glCtx ); /* free the Mesa context */ @@ -545,23 +612,97 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv) } } + static GLboolean savageCreateBuffer( __DRIscreenPrivate *driScrnPriv, __DRIdrawablePrivate *driDrawPriv, const __GLcontextModes *mesaVis, GLboolean isPixmap) { + savageScreenPrivate *screen = (savageScreenPrivate *) driScrnPriv->private; + if (isPixmap) { return GL_FALSE; /* not implemented */ } else { - GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; - driDrawPriv->driverPrivate = (void *) - _mesa_create_framebuffer(mesaVis, - GL_FALSE, /* software depth buffer? */ - swStencil, - mesaVis->accumRedBits > 0, - mesaVis->alphaBits > 0 ); + GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; + struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + /* + * XXX: this value needs to be set according to the config file + * setting. But we don't get that until we create a rendering + * context!!!! + */ + GLboolean float_depth = GL_FALSE; + + { + driRenderbuffer *frontRb + = driNewRenderbuffer(GL_RGBA, + (GLubyte *) screen->aperture.map + + 0x01000000 * TARGET_FRONT, + screen->cpp, + screen->frontOffset, screen->aperturePitch, + driDrawPriv); + savageSetSpanFunctions(frontRb, mesaVis, float_depth); + assert(frontRb->Base.Data); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); + } + + if (mesaVis->doubleBufferMode) { + driRenderbuffer *backRb + = driNewRenderbuffer(GL_RGBA, + (GLubyte *) screen->aperture.map + + 0x01000000 * TARGET_BACK, + screen->cpp, + screen->backOffset, screen->aperturePitch, + driDrawPriv); + savageSetSpanFunctions(backRb, mesaVis, float_depth); + assert(backRb->Base.Data); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); + } + + if (mesaVis->depthBits == 16) { + driRenderbuffer *depthRb + = driNewRenderbuffer(GL_DEPTH_COMPONENT16, + (GLubyte *) screen->aperture.map + + 0x01000000 * TARGET_DEPTH, + screen->zpp, + screen->depthOffset, screen->aperturePitch, + driDrawPriv); + savageSetSpanFunctions(depthRb, mesaVis, float_depth); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + else if (mesaVis->depthBits == 24) { + driRenderbuffer *depthRb + = driNewRenderbuffer(GL_DEPTH_COMPONENT24, + (GLubyte *) screen->aperture.map + + 0x01000000 * TARGET_DEPTH, + screen->zpp, + screen->depthOffset, screen->aperturePitch, + driDrawPriv); + savageSetSpanFunctions(depthRb, mesaVis, float_depth); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + + if (mesaVis->stencilBits > 0 && !swStencil) { + driRenderbuffer *stencilRb + = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, + (GLubyte *) screen->aperture.map + + 0x01000000 * TARGET_DEPTH, + screen->zpp, + screen->depthOffset, screen->aperturePitch, + driDrawPriv); + savageSetSpanFunctions(stencilRb, mesaVis, float_depth); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); + } + + _mesa_add_soft_renderbuffers(fb, + GL_FALSE, /* color */ + GL_FALSE, /* depth */ + swStencil, + mesaVis->accumRedBits > 0, + GL_FALSE, /* alpha */ + GL_FALSE /* aux */); + driDrawPriv->driverPrivate = (void *) fb; return (driDrawPriv->driverPrivate != NULL); } @@ -570,7 +711,7 @@ savageCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void savageDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } #if 0 @@ -584,62 +725,41 @@ void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) } #endif -void savageXMesaSetFrontClipRects( savageContextPtr imesa ) -{ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - - imesa->numClipRects = dPriv->numClipRects; - imesa->pClipRects = dPriv->pClipRects; - imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; - imesa->drawX = dPriv->x; - imesa->drawY = dPriv->y; - - savageEmitDrawingRectangle( imesa ); -} - -void savageXMesaSetBackClipRects( savageContextPtr imesa ) +void savageXMesaSetClipRects(savageContextPtr imesa) { __DRIdrawablePrivate *dPriv = imesa->driDrawable; - if (dPriv->numBackClipRects == 0) - { - - + if ((dPriv->numBackClipRects == 0) + || (imesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT)) { imesa->numClipRects = dPriv->numClipRects; imesa->pClipRects = dPriv->pClipRects; imesa->drawX = dPriv->x; imesa->drawY = dPriv->y; } else { - - imesa->numClipRects = dPriv->numBackClipRects; imesa->pClipRects = dPriv->pBackClipRects; imesa->drawX = dPriv->backX; imesa->drawY = dPriv->backY; } - savageEmitDrawingRectangle( imesa ); - imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; - - + savageCalcViewport( imesa->glCtx ); } static void savageXMesaWindowMoved( savageContextPtr imesa ) { + __DRIdrawablePrivate *const drawable = imesa->driDrawable; + __DRIdrawablePrivate *const readable = imesa->driReadable; + if (0) fprintf(stderr, "savageXMesaWindowMoved\n\n"); - switch (imesa->glCtx->Color._DrawDestMask[0]) { - case DD_FRONT_LEFT_BIT: - savageXMesaSetFrontClipRects( imesa ); - break; - case DD_BACK_LEFT_BIT: - savageXMesaSetBackClipRects( imesa ); - break; - default: - break; + savageXMesaSetClipRects(imesa); + + driUpdateFramebufferSize(imesa->glCtx, drawable); + if (drawable != readable) { + driUpdateFramebufferSize(imesa->glCtx, readable); } } @@ -680,7 +800,7 @@ savageCloseFullScreen(__DRIcontextPrivate *driContextPriv) if (driContextPriv) { savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate; - WAIT_IDLE_EMPTY; + WAIT_IDLE_EMPTY(imesa); imesa->IsFullScreen = GL_FALSE; imesa->savageScreen->frontOffset = imesa->backup_frontOffset; imesa->savageScreen->backOffset = imesa->backup_backOffset; @@ -696,22 +816,33 @@ savageMakeCurrent(__DRIcontextPrivate *driContextPriv, __DRIdrawablePrivate *driReadPriv) { if (driContextPriv) { - savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate; - + savageContextPtr imesa + = (savageContextPtr) driContextPriv->driverPrivate; + struct gl_framebuffer *drawBuffer + = (GLframebuffer *) driDrawPriv->driverPrivate; + struct gl_framebuffer *readBuffer + = (GLframebuffer *) driReadPriv->driverPrivate; + driRenderbuffer *frontRb = (driRenderbuffer *) + drawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + driRenderbuffer *backRb = (driRenderbuffer *) + drawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + + assert(frontRb->Base.Data); + if (imesa->glCtx->Visual.doubleBufferMode) { + assert(backRb->Base.Data); + } + imesa->driReadable = driReadPriv; imesa->driDrawable = driDrawPriv; - imesa->mesa_drawable = driDrawPriv; imesa->dirty = ~0; - _mesa_make_current2(imesa->glCtx, - (GLframebuffer *) driDrawPriv->driverPrivate, - (GLframebuffer *) driReadPriv->driverPrivate); + _mesa_make_current(imesa->glCtx, drawBuffer, readBuffer); savageXMesaWindowMoved( imesa ); } else { - _mesa_make_current(NULL, NULL); + _mesa_make_current(NULL, NULL, NULL); } return GL_TRUE; } @@ -719,12 +850,14 @@ savageMakeCurrent(__DRIcontextPrivate *driContextPriv, void savageGetLock( savageContextPtr imesa, GLuint flags ) { - __DRIdrawablePrivate *dPriv = imesa->driDrawable; + __DRIdrawablePrivate *const drawable = imesa->driDrawable; + __DRIdrawablePrivate *const readable = imesa->driReadable; __DRIscreenPrivate *sPriv = imesa->driScreen; drm_savage_sarea_t *sarea = imesa->sarea; int me = imesa->hHWContext; - int stamp = dPriv->lastStamp; + int stamp = drawable->lastStamp; int heap; + unsigned int timestamp = 0; @@ -742,69 +875,45 @@ void savageGetLock( savageContextPtr imesa, GLuint flags ) * NOTE: This releases and regains the hw lock, so all state * checking must be done *after* this call: */ - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); + if (drawable != readable) { + DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); + } - - /* If we lost context, need to dump all registers to hardware. * Note that we don't care about 2d contexts, even if they perform * accelerated commands, so the DRI locking in the X server is even * more broken than usual. */ if (sarea->ctxOwner != me) { - imesa->dirty |= (SAVAGE_UPLOAD_CTX | - SAVAGE_UPLOAD_CLIPRECTS | + imesa->dirty |= (SAVAGE_UPLOAD_LOCAL | + SAVAGE_UPLOAD_GLOBAL | + SAVAGE_UPLOAD_FOGTBL | SAVAGE_UPLOAD_TEX0 | - SAVAGE_UPLOAD_TEX1); + SAVAGE_UPLOAD_TEX1 | + SAVAGE_UPLOAD_TEXGLOBAL); imesa->lostContext = GL_TRUE; sarea->ctxOwner = me; } - /* Shared texture managment - if another client has played with - * texture space, figure out which if any of our textures have been - * ejected, and update our global LRU. - */ - /*frank just for compiling,texAge,texList,AGP*/ - - for(heap= 0 ;heap < imesa->lastTexHeap ; heap++) - { - if (sarea->texAge[heap] != imesa->texAge[heap]) { - int sz = 1 << (imesa->savageScreen->logTextureGranularity[heap]); - int idx, nr = 0; + for (heap = 0; heap < imesa->lastTexHeap; ++heap) { + /* If a heap was changed, update its timestamp. Do this before + * DRI_AGE_TEXTURES updates the local_age. */ + if (imesa->textureHeaps[heap] && + imesa->textureHeaps[heap]->global_age[0] > + imesa->textureHeaps[heap]->local_age) { + if (timestamp == 0) + timestamp = savageEmitEventLocked(imesa, 0); + imesa->textureHeaps[heap]->timestamp = timestamp; + } + DRI_AGE_TEXTURES( imesa->textureHeaps[heap] ); + } - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... - */ - for (idx = sarea->texList[heap][SAVAGE_NR_TEX_REGIONS].prev ; - idx != SAVAGE_NR_TEX_REGIONS && nr < SAVAGE_NR_TEX_REGIONS ; - idx = sarea->texList[heap][idx].prev, nr++) - { - if (sarea->texList[heap][idx].age > imesa->texAge[heap]) - { - savageTexturesGone(imesa, heap ,idx * sz, sz, - sarea->texList[heap][idx].in_use); - } - } - - if (nr == SAVAGE_NR_TEX_REGIONS) - { - savageTexturesGone(imesa, heap, 0, - imesa->savageScreen->textureSize[heap], 0); - savageResetGlobalLRU( imesa , heap ); - } - - imesa->dirty |= SAVAGE_UPLOAD_TEX0IMAGE; - imesa->dirty |= SAVAGE_UPLOAD_TEX1IMAGE; - imesa->texAge[heap] = sarea->texAge[heap]; - } - } /* end of for loop */ - - if (dPriv->lastStamp != stamp) + if (drawable->lastStamp != stamp) { + driUpdateFramebufferSize(imesa->glCtx, drawable); savageXMesaWindowMoved( imesa ); - - - + } } @@ -822,25 +931,6 @@ static const struct __DriverAPIRec savageAPI = { }; - -#ifndef DRI_NEW_INTERFACE_ONLY -/* - * This is the (old) bootstrap function for the driver. - * The __driCreateScreen name is the symbol that libGL.so fetches. - * Return: pointer to a __DRIscreenPrivate. - */ -void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, - int numConfigs, __GLXvisualConfig *config) -{ - __DRIscreenPrivate *psp; - psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &savageAPI); - return (void *) psp; -} -#endif /* DRI_NEW_INTERFACE_ONLY */ - - - -#ifdef USE_NEW_INTERFACE static __GLcontextModes * savageFillInModes( unsigned pixel_bits, unsigned depth_bits, unsigned stencil_bits, GLboolean have_back_buffer ) @@ -893,7 +983,7 @@ savageFillInModes( unsigned pixel_bits, unsigned depth_bits, fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } - modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) ); + modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) ); m = modes; if ( ! driFillInModes( & m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, @@ -936,22 +1026,24 @@ savageFillInModes( unsigned pixel_bits, unsigned depth_bits, * failure. */ PUBLIC -void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - __GLcontextModes ** driver_modes ) +void * __DRI_CREATE_NEW_SCREEN(int scrn, __DRIscreen *psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes ) { __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 0, 0 }; + static const __DRIversion ddx_expected = { 2, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 0, 0 }; + static const __DRIversion drm_expected = { 2, 1, 0 }; + dri_interface = interface; if ( ! driCheckDriDdxDrmVersions2( "Savage", dri_version, & dri_expected, @@ -960,24 +1052,27 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + psp = __driUtilCreateNewScreen(scrn, psc, NULL, ddx_version, dri_version, drm_version, frame_buffer, pSAREA, fd, internal_api_version, &savageAPI); if ( psp != NULL ) { - create_context_modes = (PFNGLXCREATECONTEXTMODES) - glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" ); - if ( create_context_modes != NULL ) { - SAVAGEDRIPtr dri_priv = (SAVAGEDRIPtr)psp->pDevPriv; - *driver_modes = savageFillInModes( dri_priv->cpp*8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, - (dri_priv->backOffset != dri_priv->depthOffset) ); - } + SAVAGEDRIPtr dri_priv = (SAVAGEDRIPtr)psp->pDevPriv; + *driver_modes = savageFillInModes( dri_priv->cpp*8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, + (dri_priv->backOffset != dri_priv->depthOffset) ); + + /* Calling driInitExtensions here, with a NULL context pointer, does not actually + * enable the extensions. It just makes sure that all the dispatch offsets for all + * the extensions that *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is called, but we can't + * enable the extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); } return (void *) psp; } -#endif /* USE_NEW_INTERFACE */ - -#endif