summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/trident/trident_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/trident/trident_context.c')
-rw-r--r--src/mesa/drivers/dri/trident/trident_context.c465
1 files changed, 465 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c
new file mode 100644
index 0000000000..b693a95ece
--- /dev/null
+++ b/src/mesa/drivers/dri/trident/trident_context.c
@@ -0,0 +1,465 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "trident_dri.h"
+#include "trident_context.h"
+#include "trident_lock.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "vbo/vbo.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+
+#include "main/context.h"
+#include "main/simple_list.h"
+#include "main/matrix.h"
+#include "main/extensions.h"
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
+#include "main/viewport.h"
+#if defined(USE_X86_ASM)
+#include "x86/common_x86_asm.h"
+#endif
+#include "main/simple_list.h"
+#include "main/mm.h"
+#include "drirenderbuffer.h"
+
+#include "drivers/common/driverfuncs.h"
+#include "dri_util.h"
+#include "utils.h"
+
+static const struct tnl_pipeline_stage *trident_pipeline[] = {
+ &_tnl_vertex_transform_stage,
+ &_tnl_normal_transform_stage,
+ &_tnl_lighting_stage,
+ &_tnl_texgen_stage,
+ &_tnl_texture_transform_stage,
+ &_tnl_render_stage,
+ 0,
+};
+
+
+static GLboolean
+tridentCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate)
+{
+ GLcontext *ctx, *shareCtx;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ tridentContextPtr tmesa;
+ tridentScreenPtr tridentscrn;
+ struct dd_function_table functions;
+#if 0
+ drm_trident_sarea_t *saPriv=(drm_trident_sarea_t *)(((char*)sPriv->pSAREA)+
+ sizeof(XF86DRISAREARec));
+#endif
+
+ tmesa = (tridentContextPtr) CALLOC( sizeof(*tmesa) );
+ if ( !tmesa ) return GL_FALSE;
+
+ /* Allocate the Mesa context */
+ if (sharedContextPrivate)
+ shareCtx = ((tridentContextPtr) sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+
+ _mesa_init_driver_functions(&functions);
+
+ tmesa->glCtx =
+ _mesa_create_context(glVisual, shareCtx, &functions, (void *)tmesa);
+
+ if (!tmesa->glCtx) {
+ FREE(tmesa);
+ return GL_FALSE;
+ }
+
+ tmesa->driContext = driContextPriv;
+ tmesa->driScreen = sPriv;
+ tmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
+
+ tmesa->hHWContext = driContextPriv->hHWContext;
+ tmesa->driHwLock = (drmLock *)&sPriv->pSAREA->lock;
+ tmesa->driFd = sPriv->fd;
+#if 0
+ tmesa->sarea = saPriv;
+#endif
+
+ tridentscrn = tmesa->tridentScreen = (tridentScreenPtr)(sPriv->private);
+
+ ctx = tmesa->glCtx;
+
+ ctx->Const.MaxTextureLevels = 13; /* 4K by 4K? Is that right? */
+ ctx->Const.MaxTextureUnits = 1; /* Permedia 3 */
+
+ ctx->Const.MinLineWidth = 0.0;
+ ctx->Const.MaxLineWidth = 255.0;
+
+ ctx->Const.MinLineWidthAA = 0.0;
+ ctx->Const.MaxLineWidthAA = 65536.0;
+
+ ctx->Const.MinPointSize = 0.0;
+ ctx->Const.MaxPointSize = 255.0;
+
+ ctx->Const.MinPointSizeAA = 0.5; /* 4x4 quality mode */
+ ctx->Const.MaxPointSizeAA = 16.0;
+ ctx->Const.PointSizeGranularity = 0.25;
+
+ ctx->Const.MaxDrawBuffers = 1;
+
+#if 0
+ tmesa->texHeap = mmInit( 0, tmesa->tridentScreen->textureSize );
+
+ make_empty_list(&tmesa->TexObjList);
+ make_empty_list(&tmesa->SwappedOut);
+
+ tmesa->CurrentTexObj[0] = 0;
+ tmesa->CurrentTexObj[1] = 0; /* Permedia 3, second texture */
+
+ tmesa->RenderIndex = ~0;
+#endif
+
+ /* Initialize the software rasterizer and helper modules.
+ */
+ _swrast_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+
+ /* Install the customized pipeline:
+ */
+ _tnl_destroy_pipeline( ctx );
+ _tnl_install_pipeline( ctx, trident_pipeline );
+
+ /* Configure swrast to match hardware characteristics:
+ */
+ _swrast_allow_pixel_fog( ctx, GL_FALSE );
+ _swrast_allow_vertex_fog( ctx, GL_TRUE );
+
+ tridentInitVB( ctx );
+ tridentDDInitExtensions( ctx );
+ tridentDDInitDriverFuncs( ctx );
+ tridentDDInitStateFuncs( ctx );
+#if 0
+ tridentDDInitSpanFuncs( ctx );
+ tridentDDInitTextureFuncs( ctx );
+#endif
+ tridentDDInitTriFuncs( ctx );
+ tridentDDInitState( tmesa );
+
+ driContextPriv->driverPrivate = (void *)tmesa;
+
+ UNLOCK_HARDWARE(tmesa);
+
+ return GL_TRUE;
+}
+
+static void
+tridentDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+ tridentContextPtr tmesa = (tridentContextPtr)driContextPriv->driverPrivate;
+
+ if (tmesa) {
+ _swsetup_DestroyContext( tmesa->glCtx );
+ _tnl_DestroyContext( tmesa->glCtx );
+ _vbo_DestroyContext( tmesa->glCtx );
+ _swrast_DestroyContext( tmesa->glCtx );
+
+ /* free the Mesa context */
+ tmesa->glCtx->DriverCtx = NULL;
+ _mesa_destroy_context(tmesa->glCtx);
+
+ _mesa_free(tmesa);
+ driContextPriv->driverPrivate = NULL;
+ }
+}
+
+
+static GLboolean
+tridentCreateBuffer( __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ const __GLcontextModes *mesaVis,
+ GLboolean isPixmap )
+{
+ tridentScreenPtr screen = (tridentScreenPtr) driScrnPriv->private;
+
+ if (isPixmap) {
+ return GL_FALSE; /* not implemented */
+ }
+ else {
+ struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
+
+ {
+ driRenderbuffer *frontRb
+ = driNewRenderbuffer(MESA_FORMAT_ARGB8888, NULL, screen->cpp,
+ screen->frontOffset, screen->frontPitch,
+ driDrawPriv);
+ /*
+ tridentSetSpanFunctions(frontRb, mesaVis);
+ */
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
+ }
+
+ if (mesaVis->doubleBufferMode) {
+ driRenderbuffer *backRb
+ = driNewRenderbuffer(MESA_FORMAT_ARGB8888, NULL, screen->cpp,
+ screen->backOffset, screen->backPitch,
+ driDrawPriv);
+ /*
+ tridentSetSpanFunctions(backRb, mesaVis);
+ */
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
+ }
+
+ if (mesaVis->depthBits == 16) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(MESA_FORMAT_Z16, NULL, screen->cpp,
+ screen->depthOffset, screen->depthPitch,
+ driDrawPriv);
+ /*
+ tridentSetSpanFunctions(depthRb, mesaVis);
+ */
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+ else if (mesaVis->depthBits == 24) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(MESA_FORMAT_Z24_S8, NULL, screen->cpp,
+ screen->depthOffset, screen->depthPitch,
+ driDrawPriv);
+ /*
+ tridentSetSpanFunctions(depthRb, mesaVis);
+ */
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+
+ /* no h/w stencil?
+ if (mesaVis->stencilBits > 0 && !swStencil) {
+ driRenderbuffer *stencilRb
+ = driNewRenderbuffer(MESA_FORMAT_S8);
+ tridentSetSpanFunctions(stencilRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
+ }
+ */
+
+ _mesa_add_soft_renderbuffers(fb,
+ GL_FALSE, /* color */
+ GL_FALSE, /* depth */
+ mesaVis->stencilBits > 0,
+ mesaVis->accumRedBits > 0,
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux */);
+ driDrawPriv->driverPrivate = (void *) fb;
+
+ return (driDrawPriv->driverPrivate != NULL);
+ }
+}
+
+
+static void
+tridentDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+ _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
+}
+
+static void
+tridentSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
+{
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+
+ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+ tridentContextPtr tmesa;
+ GLcontext *ctx;
+ tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate;
+ ctx = tmesa->glCtx;
+ if (ctx->Visual.doubleBufferMode) {
+ _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
+ tridentCopyBuffer( dPriv );
+ }
+ }
+ else {
+ /* XXX this shouldn't be an error but we can't handle it for now */
+ _mesa_problem(NULL, "tridentSwapBuffers: drawable has no context!\n");
+ }
+}
+
+static GLboolean
+tridentMakeCurrent(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv)
+{
+ if (driContextPriv) {
+ GET_CURRENT_CONTEXT(ctx);
+ tridentContextPtr oldCtx = ctx ? TRIDENT_CONTEXT(ctx) : NULL;
+ tridentContextPtr newCtx = (tridentContextPtr) driContextPriv->driverPrivate;
+
+ if ( newCtx != oldCtx ) {
+ newCtx->dirty = ~0;
+ }
+
+ if (newCtx->driDrawable != driDrawPriv) {
+ newCtx->driDrawable = driDrawPriv;
+#if 0
+ tridentUpdateWindow ( newCtx->glCtx );
+ tridentUpdateViewportOffset( newCtx->glCtx );
+#endif
+ }
+
+ newCtx->drawOffset = newCtx->tridentScreen->backOffset;
+ newCtx->drawPitch = newCtx->tridentScreen->backPitch;
+
+ _mesa_make_current( newCtx->glCtx,
+ (GLframebuffer *) driDrawPriv->driverPrivate,
+ (GLframebuffer *) driReadPriv->driverPrivate );
+
+ if (!newCtx->glCtx->Viewport.Width) {
+ _mesa_set_viewport(newCtx->glCtx, 0, 0,
+ driDrawPriv->w, driDrawPriv->h);
+ }
+ } else {
+ _mesa_make_current( NULL, NULL, NULL );
+ }
+ return GL_TRUE;
+}
+
+
+static GLboolean
+tridentUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+
+static tridentScreenPtr
+tridentCreateScreen( __DRIscreenPrivate *sPriv )
+{
+ TRIDENTDRIPtr tDRIPriv = (TRIDENTDRIPtr)sPriv->pDevPriv;
+ tridentScreenPtr tridentScreen;
+
+ if (sPriv->devPrivSize != sizeof(TRIDENTDRIRec)) {
+ fprintf(stderr,"\nERROR! sizeof(TRIDENTDRIRec) does not match passed size from device driver\n");
+ return GL_FALSE;
+ }
+
+ /* Allocate the private area */
+ tridentScreen = (tridentScreenPtr) CALLOC( sizeof(*tridentScreen) );
+ if ( !tridentScreen ) return NULL;
+
+ tridentScreen->driScreen = sPriv;
+
+ tridentScreen->frontOffset = tDRIPriv->frontOffset;
+ tridentScreen->backOffset = tDRIPriv->backOffset;
+ tridentScreen->depthOffset = tDRIPriv->depthOffset;
+ tridentScreen->frontPitch = tDRIPriv->frontPitch;
+ tridentScreen->backPitch = tDRIPriv->backPitch;
+ tridentScreen->depthPitch = tDRIPriv->depthPitch;
+ tridentScreen->width = tDRIPriv->width;
+ tridentScreen->height = tDRIPriv->height;
+
+printf("%d %d\n",tridentScreen->width,tridentScreen->height);
+printf("%d %d\n",tridentScreen->frontPitch,tridentScreen->backPitch);
+printf("offset 0x%x 0x%x\n",tridentScreen->backOffset,tridentScreen->depthOffset);
+
+ tridentScreen->mmio.handle = tDRIPriv->regs;
+ tridentScreen->mmio.size = 0x20000;
+
+ if (drmMap(sPriv->fd,
+ tridentScreen->mmio.handle, tridentScreen->mmio.size,
+ (drmAddressPtr)&tridentScreen->mmio.map)) {
+ FREE(tridentScreen);
+ return GL_FALSE;
+ }
+printf("MAPPED at %p\n", tridentScreen->mmio.map);
+
+ return tridentScreen;
+}
+
+/* Destroy the device specific screen private data struct.
+ */
+static void
+tridentDestroyScreen( __DRIscreenPrivate *sPriv )
+{
+ tridentScreenPtr tridentScreen = (tridentScreenPtr)sPriv->private;
+
+ FREE(tridentScreen);
+}
+
+static GLboolean
+tridentInitDriver(__DRIscreenPrivate *sPriv)
+{
+ sPriv->private = (void *) tridentCreateScreen( sPriv );
+
+ if (!sPriv->private) {
+ tridentDestroyScreen( sPriv );
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
+ */
+const __DRIconfig **tridentInitScreen(__DRIscreenPrivate *psp)
+{
+ static const __DRIversion ddx_expected = { 4, 0, 0 };
+ static const __DRIversion dri_expected = { 3, 1, 0 };
+ static const __DRIversion drm_expected = { 1, 0, 0 };
+
+ if ( ! driCheckDriDdxDrmVersions2( "Trident",
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
+ return NULL;
+
+ if (!tridentInitDriver(psp))
+ return NULL;
+
+ /* Wait... what? This driver doesn't report any modes... */
+#if 0
+ TRIDENTDRIPtr dri_priv = (TRIDENTDRIPtr) psp->pDevPriv;
+ *driver_modes = tridentFillInModes( dri_priv->bytesPerPixel * 8,
+ GL_TRUE );
+#endif
+
+ return NULL;
+}
+
+const struct __DriverAPIRec driDriverAPI = {
+ tridentInitScreen,
+ tridentDestroyScreen,
+ tridentCreateContext,
+ tridentDestroyContext,
+ tridentCreateBuffer,
+ tridentDestroyBuffer,
+ tridentSwapBuffers,
+ tridentMakeCurrent,
+ tridentUnbindContext,
+};