st/xorg: Add Xorg state tracker

This commit is contained in:
Jakob Bornecrantz
2009-03-03 03:22:46 +01:00
parent 1d060e36f2
commit 84711c6582
8 changed files with 2261 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
TARGET = libxorgtracker.a
CFILES = $(wildcard ./*.c)
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
GALLIUMDIR = ../..
TOP = ../../../..
include $(TOP)/configs/current
CFLAGS = -DHAVE_CONFIG_H \
-g -Wall -Wimplicit-function-declaration -fPIC \
$(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \
-I$(GALLIUMDIR)/include \
-I$(GALLIUMDIR)/auxiliary \
-I$(TOP)/src/mesa/drivers/dri/common \
-I$(TOP)/src/mesa \
-I$(TOP)/include \
-I$(TOP)/src/egl/main
#############################################
.PHONY = all clean
all: $(TARGET)
$(TARGET): $(OBJECTS)
ar rcs $(TARGET) $(OBJECTS)
clean:
rm -rf $(OBJECTS) $(TARGET)
+314
View File
@@ -0,0 +1,314 @@
/*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
* Author: Alan Hourihane <alanh@tungstengraphics.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*
*/
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include "xorg-server.h"
#include <xf86.h>
#include <xf86i2c.h>
#include <xf86Crtc.h>
#include "xorg_tracker.h"
#include "xf86Modes.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
#include "pipe/p_inlines.h"
struct crtc_private
{
drmModeCrtcPtr drm_crtc;
/* hwcursor */
struct pipe_buffer *cursor_buf;
unsigned cursor_handle;
};
static void
crtc_dpms(xf86CrtcPtr crtc, int mode)
{
//ScrnInfoPtr pScrn = crtc->scrn;
switch (mode) {
case DPMSModeOn:
case DPMSModeStandby:
case DPMSModeSuspend:
break;
case DPMSModeOff:
break;
}
}
static Bool
crtc_lock(xf86CrtcPtr crtc)
{
return FALSE;
}
static void
crtc_unlock(xf86CrtcPtr crtc)
{
}
static void
crtc_prepare(xf86CrtcPtr crtc)
{
}
static void
crtc_commit(xf86CrtcPtr crtc)
{
}
static Bool
crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
return TRUE;
}
static void
crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode, int x, int y)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
modesettingPtr ms = modesettingPTR(crtc->scrn);
xf86OutputPtr output = config->output[config->compat_output];
drmModeConnectorPtr drm_connector = output->driver_private;
struct crtc_private *crtcp = crtc->driver_private;
drmModeCrtcPtr drm_crtc = crtcp->drm_crtc;
drmModeModeInfo drm_mode;
drm_mode.clock = mode->Clock;
drm_mode.hdisplay = mode->HDisplay;
drm_mode.hsync_start = mode->HSyncStart;
drm_mode.hsync_end = mode->HSyncEnd;
drm_mode.htotal = mode->HTotal;
drm_mode.vdisplay = mode->VDisplay;
drm_mode.vsync_start = mode->VSyncStart;
drm_mode.vsync_end = mode->VSyncEnd;
drm_mode.vtotal = mode->VTotal;
drm_mode.flags = mode->Flags;
drm_mode.hskew = mode->HSkew;
drm_mode.vscan = mode->VScan;
drm_mode.vrefresh = mode->VRefresh;
if (!mode->name)
xf86SetModeDefaultName(mode);
strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN);
drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y,
&drm_connector->connector_id, 1, &drm_mode);
}
#if 0
static void
crtc_load_lut(xf86CrtcPtr crtc)
{
//ScrnInfoPtr pScrn = crtc->scrn;
}
#endif
static void
crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
int size)
{
}
static void *
crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
//ScrnInfoPtr pScrn = crtc->scrn;
return NULL;
}
static PixmapPtr
crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
{
//ScrnInfoPtr pScrn = crtc->scrn;
return NULL;
}
static void
crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
{
//ScrnInfoPtr pScrn = crtc->scrn;
}
static void
crtc_destroy(xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
if (crtcp->cursor_buf)
pipe_buffer_reference(ms->screen, &crtcp->cursor_buf, NULL);
drmModeFreeCrtc(crtcp->drm_crtc);
xfree(crtcp);
}
static void
crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
{
unsigned char *ptr;
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
if (!crtcp->cursor_buf) {
crtcp->cursor_buf = pipe_buffer_create(ms->screen,
0,
PIPE_BUFFER_USAGE_CPU_WRITE |
PIPE_BUFFER_USAGE_GPU_READ,
64*64*4);
drm_api_hocks.handle_from_buffer(ms->screen,
crtcp->cursor_buf,
&crtcp->cursor_handle);
}
ptr = pipe_buffer_map(ms->screen, crtcp->cursor_buf, PIPE_BUFFER_USAGE_CPU_WRITE);
if (ptr)
memcpy(ptr, image, 64 * 64 * 4);
pipe_buffer_unmap(ms->screen, crtcp->cursor_buf);
}
static void
crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y);
}
static void
crtc_show_cursor(xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
if (crtcp->cursor_buf)
drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
crtcp->cursor_handle, 64, 64);
}
static void
crtc_hide_cursor(xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0);
}
static const xf86CrtcFuncsRec crtc_funcs = {
.dpms = crtc_dpms,
.save = NULL,
.restore = NULL,
.lock = crtc_lock,
.unlock = crtc_unlock,
.mode_fixup = crtc_mode_fixup,
.prepare = crtc_prepare,
.mode_set = crtc_mode_set,
.commit = crtc_commit,
.gamma_set = crtc_gamma_set,
.shadow_create = crtc_shadow_create,
.shadow_allocate = crtc_shadow_allocate,
.shadow_destroy = crtc_shadow_destroy,
.set_cursor_position = crtc_set_cursor_position,
.show_cursor = crtc_show_cursor,
.hide_cursor = crtc_hide_cursor,
.load_cursor_image = NULL, /* lets convert to argb only */
.set_cursor_colors = NULL, /* using argb only */
.load_cursor_argb = crtc_load_cursor_argb,
.destroy = crtc_destroy,
};
void
cursor_destroy(xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
if (crtcp->cursor_buf) {
pipe_buffer_reference(ms->screen, &crtcp->cursor_buf, NULL);
}
}
void
crtc_init(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
xf86CrtcPtr crtc;
drmModeResPtr res;
drmModeCrtcPtr drm_crtc = NULL;
struct crtc_private *crtcp;
int c;
res = drmModeGetResources(ms->fd);
if (res == 0) {
ErrorF("Failed drmModeGetResources %d\n", errno);
return;
}
for (c = 0; c < res->count_crtcs; c++) {
drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]);
if (!drm_crtc)
continue;
crtc = xf86CrtcCreate(pScrn, &crtc_funcs);
if (crtc == NULL)
goto out;
crtcp = xcalloc(1, sizeof(struct crtc_private));
if (!crtcp) {
xf86CrtcDestroy(crtc);
goto out;
}
crtcp->drm_crtc = drm_crtc;
crtc->driver_private = crtcp;
}
out:
drmModeFreeResources(res);
}
/* vim: set sw=4 ts=8 sts=4: */
+212
View File
@@ -0,0 +1,212 @@
/*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
* Author: Alan Hourihane <alanh@tungstengraphics.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*
*/
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xorg_tracker.h"
#include "dri2.h"
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
typedef struct {
PixmapPtr pPixmap;
struct pipe_texture *tex;
struct pipe_buffer *buf;
} *BufferPrivatePtr;
static DRI2BufferPtr
driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
{
struct pipe_texture *depth, *tex;
struct pipe_buffer *buf;
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr privates;
DRI2BufferPtr buffers;
PixmapPtr pPixmap;
unsigned stride, handle;
int i;
buffers = xcalloc(count, sizeof *buffers);
if (!buffers)
goto fail_buffers;
privates = xcalloc(count, sizeof *privates);
if (!privates)
goto fail_privates;
depth = NULL;
for (i = 0; i < count; i++) {
pPixmap = NULL;
tex = NULL;
buf = NULL;
if (attachments[i] == DRI2BufferFrontLeft) {
if (pDraw->type == DRAWABLE_PIXMAP)
pPixmap = (PixmapPtr) pDraw;
else
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
pPixmap->refcnt++;
tex = xorg_exa_get_texture(pPixmap);
} else if (attachments[i] == DRI2BufferStencil) {
pipe_texture_reference(&tex, depth);
} else if (attachments[i] == DRI2BufferDepth) {
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
template.compressed = 0;
template.format = PIPE_FORMAT_S8Z24_UNORM;
pf_get_block(template.format, &template.block);
template.width[0] = pDraw->width;
template.height[0] = pDraw->height;
template.depth[0] = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
tex = ms->screen->texture_create(ms->screen, &template);
} else {
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
template.compressed = 0;
template.format = PIPE_FORMAT_A8R8G8B8_UNORM;
pf_get_block(template.format, &template.block);
template.width[0] = pDraw->width;
template.height[0] = pDraw->height;
template.depth[0] = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
tex = ms->screen->texture_create(ms->screen, &template);
}
drm_api_hocks.buffer_from_texture(tex, &buf, &stride);
drm_api_hocks.global_handle_from_buffer(ms->screen, buf, &handle);
buffers[i].name = handle;
buffers[i].attachment = attachments[i];
buffers[i].pitch = stride;
buffers[i].cpp = 4;
buffers[i].driverPrivate = &privates[i];
buffers[i].flags = 0; /* not tiled */
privates[i].pPixmap = pPixmap;
privates[i].buf = buf;
privates[i].tex = tex;
}
return buffers;
fail_privates:
xfree(buffers);
fail_buffers:
return NULL;
}
static void
driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr private;
int i;
for (i = 0; i < count; i++) {
private = buffers[i].driverPrivate;
if (private->pPixmap)
(*pScreen->DestroyPixmap)(private->pPixmap);
pipe_texture_reference(&private->tex, NULL);
pipe_buffer_reference(ms->screen, &private->buf, NULL);
}
if (buffers) {
xfree(buffers[0].driverPrivate);
xfree(buffers);
}
}
static void
driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate;
BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate;
struct pipe_surface *dst_surf =
ms->screen->get_tex_surface(ms->screen, dst_priv->tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
struct pipe_surface *src_surf =
ms->screen->get_tex_surface(ms->screen, src_priv->tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ);
ms->ctx->surface_copy(ms->ctx, 0, dst_surf, 0, 0, src_surf,
0, 0, pDraw->width, pDraw->height);
pipe_surface_reference(&dst_surf, NULL);
pipe_surface_reference(&src_surf, NULL);
}
Bool
driScreenInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
DRI2InfoRec dri2info;
dri2info.version = 1;
dri2info.fd = ms->fd;
#if 0
dri2info.driverName = pScrn->name;
#else
dri2info.driverName = "i915"; /* FIXME */
#endif
dri2info.deviceName = "/dev/dri/card0"; /* FIXME */
dri2info.CreateBuffers = driCreateBuffers;
dri2info.DestroyBuffers = driDestroyBuffers;
dri2info.CopyRegion = driCopyRegion;
return DRI2ScreenInit(pScreen, &dri2info);
}
void
driCloseScreen(ScreenPtr pScreen)
{
DRI2CloseScreen(pScreen);
}
/* vim: set sw=4 ts=8 sts=4: */
@@ -0,0 +1,695 @@
/*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
* Author: Alan Hourihane <alanh@tungstengraphics.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*
*/
#include "xorg-server.h"
#include "xf86.h"
#include "xf86_OSproc.h"
#include "compiler.h"
#include "xf86RAC.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "xf86Resources.h"
#include "mipointer.h"
#include "micmap.h"
#include <X11/extensions/randr.h>
#include "fb.h"
#include "edid.h"
#include "xf86i2c.h"
#include "xf86Crtc.h"
#include "miscstruct.h"
#include "dixstruct.h"
#include "xf86xv.h"
#include <X11/extensions/Xv.h>
#ifndef XSERVER_LIBPCIACCESS
#error "libpciaccess needed"
#endif
#include <pciaccess.h>
#include "xorg_tracker.h"
#include "xorg_winsys.h"
static void AdjustFrame(int scrnIndex, int x, int y, int flags);
static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool EnterVT(int scrnIndex, int flags);
static Bool SaveHWState(ScrnInfoPtr pScrn);
static Bool RestoreHWState(ScrnInfoPtr pScrn);
static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
int flags);
static void FreeScreen(int scrnIndex, int flags);
static void LeaveVT(int scrnIndex, int flags);
static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
char **argv);
static Bool PreInit(ScrnInfoPtr pScrn, int flags);
typedef enum
{
OPTION_SW_CURSOR,
} modesettingOpts;
static const OptionInfoRec Options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/*
* Functions that might be needed
*/
static const char *exaSymbols[] = {
"exaGetVersion",
"exaDriverInit",
"exaDriverFini",
"exaOffscreenAlloc",
"exaOffscreenFree",
"exaWaitSync",
NULL
};
static const char *fbSymbols[] = {
"fbPictureInit",
"fbScreenInit",
NULL
};
static const char *ddcSymbols[] = {
"xf86PrintEDID",
"xf86SetDDCproperties",
NULL
};
/*
* Exported Xorg driver functions to winsys
*/
void
xorg_tracker_loader_ref_sym_lists()
{
LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL);
}
const OptionInfoRec *
xorg_tracker_available_options(int chipid, int busid)
{
return Options;
}
void
xorg_tracker_set_functions(ScrnInfoPtr scrn)
{
scrn->PreInit = PreInit;
scrn->ScreenInit = ScreenInit;
scrn->SwitchMode = SwitchMode;
scrn->AdjustFrame = AdjustFrame;
scrn->EnterVT = EnterVT;
scrn->LeaveVT = LeaveVT;
scrn->FreeScreen = FreeScreen;
scrn->ValidMode = ValidMode;
}
/*
* Static Xorg funtctions
*/
static Bool
GetRec(ScrnInfoPtr pScrn)
{
if (pScrn->driverPrivate)
return TRUE;
pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
return TRUE;
}
static void
FreeRec(ScrnInfoPtr pScrn)
{
if (!pScrn)
return;
if (!pScrn->driverPrivate)
return;
xfree(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
}
static void
ProbeDDC(ScrnInfoPtr pScrn, int index)
{
ConfiguredMonitor = NULL;
}
static Bool
CreateFrontBuffer(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
ScreenPtr pScreen = pScrn->pScreen;
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
ms->noEvict = TRUE;
pScreen->ModifyPixmapHeader(rootPixmap,
pScrn->virtualX, pScrn->virtualY,
pScrn->depth, pScrn->bitsPerPixel,
pScrn->displayWidth * pScrn->bitsPerPixel / 8,
NULL);
ms->noEvict = FALSE;
drmModeAddFB(ms->fd,
pScrn->virtualX,
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
pScrn->displayWidth * pScrn->bitsPerPixel / 8,
xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id);
pScrn->frameX0 = 0;
pScrn->frameY0 = 0;
AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
return TRUE;
}
static Bool
crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
modesettingPtr ms = modesettingPTR(pScrn);
//ScreenPtr pScreen = pScrn->pScreen;
//PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
//Bool fbAccessDisabled;
//CARD8 *fbstart;
if (width == pScrn->virtualX && height == pScrn->virtualY)
return TRUE;
ErrorF("RESIZING TO %dx%d\n", width, height);
pScrn->virtualX = width;
pScrn->virtualY = height;
/* HW dependent - FIXME */
pScrn->displayWidth = pScrn->virtualX;
drmModeRmFB(ms->fd, ms->fb_id);
/* now create new frontbuffer */
return CreateFrontBuffer(pScrn);
}
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
crtc_resize
};
static Bool
PreInit(ScrnInfoPtr pScrn, int flags)
{
xf86CrtcConfigPtr xf86_config;
modesettingPtr ms;
rgb defaultWeight = { 0, 0, 0 };
EntityInfoPtr pEnt;
EntPtr msEnt = NULL;
char *BusID;
int max_width, max_height;
if (pScrn->numEntities != 1)
return FALSE;
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (flags & PROBE_DETECT) {
ProbeDDC(pScrn, pEnt->index);
return TRUE;
}
/* Allocate driverPrivate */
if (!GetRec(pScrn))
return FALSE;
ms = modesettingPTR(pScrn);
ms->SaveGeneration = -1;
ms->pEnt = pEnt;
pScrn->displayWidth = 640; /* default it */
if (ms->pEnt->location.type != BUS_PCI)
return FALSE;
ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index);
/* Allocate an entity private if necessary */
if (xf86IsEntityShared(pScrn->entityList[0])) {
FatalError("Entity");
#if 0
msEnt = xf86GetEntityPrivate(pScrn->entityList[0],
modesettingEntityIndex)->ptr;
ms->entityPrivate = msEnt;
#else
(void)msEnt;
#endif
} else
ms->entityPrivate = NULL;
if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) {
return FALSE;
}
if (xf86IsEntityShared(pScrn->entityList[0])) {
if (xf86IsPrimInitDone(pScrn->entityList[0])) {
/* do something */
} else {
xf86SetPrimInitDone(pScrn->entityList[0]);
}
}
BusID = xalloc(64);
sprintf(BusID, "PCI:%d:%d:%d",
((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
ms->PciInfo->dev, ms->PciInfo->func
);
ms->fd = drmOpen(NULL, BusID);
if (ms->fd < 0)
return FALSE;
pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
pScrn->monitor = pScrn->confScreen->monitor;
pScrn->progClock = TRUE;
pScrn->rgbBits = 8;
if (!xf86SetDepthBpp
(pScrn, 0, 0, 0,
PreferConvert24to32 | SupportConvert24to32 | Support32bppFb))
return FALSE;
switch (pScrn->depth) {
case 15:
case 16:
case 24:
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Given depth (%d) is not supported by the driver\n",
pScrn->depth);
return FALSE;
}
xf86PrintDepthBpp(pScrn);
if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
return FALSE;
if (!xf86SetDefaultVisual(pScrn, -1))
return FALSE;
/* Process the options */
xf86CollectOptions(pScrn, NULL);
if (!(ms->Options = xalloc(sizeof(Options))))
return FALSE;
memcpy(ms->Options, Options, sizeof(Options));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
/* Allocate an xf86CrtcConfig */
xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
max_width = 8192;
max_height = 8192;
xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
ms->SWCursor = TRUE;
}
SaveHWState(pScrn);
crtc_init(pScrn);
output_init(pScrn);
if (!xf86InitialConfiguration(pScrn, TRUE)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
RestoreHWState(pScrn);
return FALSE;
}
RestoreHWState(pScrn);
/*
* If the driver can do gamma correction, it should call xf86SetGamma() here.
*/
{
Gamma zeros = { 0.0, 0.0, 0.0 };
if (!xf86SetGamma(pScrn, zeros)) {
return FALSE;
}
}
if (pScrn->modes == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
return FALSE;
}
pScrn->currentMode = pScrn->modes;
/* Set display resolution */
xf86SetDpi(pScrn, 0, 0);
/* Load the required sub modules */
if (!xf86LoadSubModule(pScrn, "fb")) {
return FALSE;
}
xf86LoaderReqSymLists(fbSymbols, NULL);
xf86LoadSubModule(pScrn, "exa");
#ifdef DRI2
xf86LoadSubModule(pScrn, "dri2");
#endif
return TRUE;
}
static Bool
SaveHWState(ScrnInfoPtr pScrn)
{
/*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
return TRUE;
}
static Bool
RestoreHWState(ScrnInfoPtr pScrn)
{
/*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
return TRUE;
}
static Bool
CreateScreenResources(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap;
Bool ret;
ms->noEvict = TRUE;
pScreen->CreateScreenResources = ms->createScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
pScreen->CreateScreenResources = CreateScreenResources;
rootPixmap = pScreen->GetScreenPixmap(pScreen);
if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
FatalError("Couldn't adjust screen pixmap\n");
ms->noEvict = FALSE;
drmModeAddFB(ms->fd,
pScrn->virtualX,
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
pScrn->displayWidth * pScrn->bitsPerPixel / 8,
xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id);
AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
return ret;
}
static Bool
ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
VisualPtr visual;
/* deal with server regeneration */
if (ms->fd < 0) {
char *BusID;
BusID = xalloc(64);
sprintf(BusID, "PCI:%d:%d:%d",
((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
ms->PciInfo->dev, ms->PciInfo->func
);
ms->fd = drmOpen(NULL, BusID);
if (ms->fd < 0)
return FALSE;
}
if (!ms->screen) {
ms->screen = drm_api_hocks.create_screen(ms->fd, ms->PciInfo->device_id);
if (!ms->screen) {
FatalError("Could not init pipe_screen\n");
return FALSE;
}
}
pScrn->pScreen = pScreen;
/* HW dependent - FIXME */
pScrn->displayWidth = pScrn->virtualX;
miClearVisualTypes();
if (!miSetVisualTypes(pScrn->depth,
miGetDefaultVisualMask(pScrn->depth),
pScrn->rgbBits, pScrn->defaultVisual))
return FALSE;
if (!miSetPixmapDepths())
return FALSE;
pScrn->memPhysBase = 0;
pScrn->fbOffset = 0;
if (!fbScreenInit(pScreen, NULL,
pScrn->virtualX, pScrn->virtualY,
pScrn->xDpi, pScrn->yDpi,
pScrn->displayWidth, pScrn->bitsPerPixel))
return FALSE;
if (pScrn->bitsPerPixel > 8) {
/* Fixup RGB ordering */
visual = pScreen->visuals + pScreen->numVisuals;
while (--visual >= pScreen->visuals) {
if ((visual->class | DynamicClass) == DirectColor) {
visual->offsetRed = pScrn->offset.red;
visual->offsetGreen = pScrn->offset.green;
visual->offsetBlue = pScrn->offset.blue;
visual->redMask = pScrn->mask.red;
visual->greenMask = pScrn->mask.green;
visual->blueMask = pScrn->mask.blue;
}
}
}
fbPictureInit(pScreen, NULL, 0);
ms->createScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = CreateScreenResources;
xf86SetBlackWhitePixels(pScreen);
ms->exa = xorg_exa_init(pScrn);
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
xf86SetSilkenMouse(pScreen);
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
/* Need to extend HWcursor support to handle mask interleave */
if (!ms->SWCursor)
xf86_cursors_init(pScreen, 64, 64,
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
HARDWARE_CURSOR_ARGB);
/* Must force it before EnterVT, so we are in control of VT and
* later memory should be bound when allocating, e.g rotate_mem */
pScrn->vtSema = TRUE;
pScreen->SaveScreen = xf86SaveScreen;
ms->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = CloseScreen;
if (!xf86CrtcScreenInit(pScreen))
return FALSE;
if (!miCreateDefColormap(pScreen))
return FALSE;
xf86DPMSInit(pScreen, xf86DPMSSet, 0);
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
#if 1
#ifdef DRI2
driScreenInit(pScreen);
#endif
#endif
return EnterVT(scrnIndex, 1);
}
static void
AdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86OutputPtr output = config->output[config->compat_output];
xf86CrtcPtr crtc = output->crtc;
if (crtc && crtc->enabled) {
crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x,
y);
crtc->x = output->initial_x + x;
crtc->y = output->initial_y + y;
}
}
static void
FreeScreen(int scrnIndex, int flags)
{
FreeRec(xf86Screens[scrnIndex]);
}
/* HACK */
void
cursor_destroy(xf86CrtcPtr crtc);
static void
LeaveVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int o;
for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o];
cursor_destroy(crtc);
if (crtc->rotatedPixmap || crtc->rotatedData) {
crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
crtc->rotatedData);
crtc->rotatedPixmap = NULL;
crtc->rotatedData = NULL;
}
}
drmModeRmFB(ms->fd, ms->fb_id);
RestoreHWState(pScrn);
pScrn->vtSema = FALSE;
}
/*
* This gets called when gaining control of the VT, and from ScreenInit().
*/
static Bool
EnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
/*
* Only save state once per server generation since that's what most
* drivers do. Could change this to save state at each VT enter.
*/
if (ms->SaveGeneration != serverGeneration) {
ms->SaveGeneration = serverGeneration;
SaveHWState(pScrn);
}
if (!flags) /* signals startup as we'll do this in CreateScreenResources */
CreateFrontBuffer(pScrn);
if (!xf86SetDesiredModes(pScrn))
return FALSE;
return TRUE;
}
static Bool
SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
}
static Bool
CloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
if (pScrn->vtSema) {
LeaveVT(scrnIndex, 0);
}
#ifdef DRI2
driCloseScreen(pScreen);
#endif
pScreen->CreateScreenResources = ms->createScreenResources;
if (ms->exa)
xorg_exa_close(pScrn);
drmClose(ms->fd);
ms->fd = -1;
pScrn->vtSema = FALSE;
pScreen->CloseScreen = ms->CloseScreen;
return (*pScreen->CloseScreen) (scrnIndex, pScreen);
}
static ModeStatus
ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
return MODE_OK;
}
/* vim: set sw=4 ts=8 sts=4: */
+534
View File
@@ -0,0 +1,534 @@
/*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
* Author: Alan Hourihane <alanh@tungstengraphics.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*
*/
/* FIXME ! */
#define DRI_DRIVER_PATH "/ISO/X.Org/modular/i386/lib/dri"
#include "xf86.h"
//#include "xf86_OSproc.h"
#include "xorg_tracker.h"
//#include "pipe/p_winsys.h"
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
struct exa_entity
{
ExaDriverPtr pExa;
struct pipe_context *ctx;
struct pipe_screen *scrn;
};
struct PixmapPriv
{
int flags;
struct pipe_texture *tex;
unsigned int color;
struct pipe_surface *src_surf; /* for copies */
struct pipe_transfer *map_transfer;
};
/*
* Helper functions
*/
static enum pipe_format
exa_get_pipe_format(int depth)
{
switch (depth) {
case 32:
return PIPE_FORMAT_A8R8G8B8_UNORM;
case 24:
return PIPE_FORMAT_X8R8G8B8_UNORM;
case 16:
return PIPE_FORMAT_R5G6B5_UNORM;
case 15:
return PIPE_FORMAT_A1R5G5B5_UNORM;
case 8:
case 4:
case 1:
return PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */
default:
assert(0);
return 0;
}
}
/*
* Static exported EXA functions
*/
static void
ExaWaitMarker(ScreenPtr pScreen, int marker)
{
}
static int
ExaMarkSync(ScreenPtr pScreen)
{
return 1;
}
static Bool
ExaPrepareAccess(PixmapPtr pPix, int index)
{
ScreenPtr pScreen = pPix->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
//PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
struct exa_entity *exa = ms->exa;
struct PixmapPriv *priv;
//int ret;
priv = exaGetPixmapDriverPrivate(pPix);
if (!priv)
return FALSE;
if (!priv->tex)
return FALSE;
{
priv->map_transfer =
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
PIPE_TRANSFER_READ_WRITE,
0, 0, priv->tex->width[0], priv->tex->height[0]);
pPix->devPrivate.ptr =
exa->scrn->transfer_map(exa->scrn, priv->map_transfer);
pPix->devKind = priv->map_transfer->stride;
}
return TRUE;
}
static void
ExaFinishAccess(PixmapPtr pPix, int index)
{
ScreenPtr pScreen = pPix->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
struct PixmapPriv *priv;
priv = exaGetPixmapDriverPrivate(pPix);
if (!priv)
return;
if (!priv->map_transfer)
return;
exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
pipe_transfer_reference(&priv->map_transfer, NULL);
}
static void
ExaDone(PixmapPtr pPixmap)
{
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
struct exa_entity *exa = ms->exa;
if (!priv)
return;
if (priv->src_surf)
exa->scrn->tex_surface_release(exa->scrn, &priv->src_surf);
priv->src_surf = NULL;
}
static void
ExaDoneComposite(PixmapPtr pPixmap)
{
}
static Bool
ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
{
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
struct exa_entity *exa = ms->exa;
if (1)
return FALSE;
if (pPixmap->drawable.depth < 15)
return FALSE;
if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
return FALSE;
if (!priv || !priv->tex)
return FALSE;
if (alu != GXcopy)
return FALSE;
if (!exa->ctx || !exa->ctx->surface_fill)
return FALSE;
priv->color = fg;
return TRUE;
}
static void
ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
{
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
struct pipe_surface *surf =
exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0,
priv->color);
exa->scrn->tex_surface_release(exa->scrn, &surf);
}
static Bool
ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
int ydir, int alu, Pixel planeMask)
{
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
struct PixmapPriv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
if (1)
return FALSE;
if (alu != GXcopy)
return FALSE;
if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15)
return FALSE;
if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
return FALSE;
if (!priv || !src_priv)
return FALSE;
if (!priv->tex || !src_priv->tex)
return FALSE;
if (!exa->ctx || !exa->ctx->surface_copy)
return FALSE;
priv->src_surf =
exa->scrn->get_tex_surface(exa->scrn, src_priv->tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
return FALSE;
}
static void
ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
int width, int height)
{
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
struct pipe_surface *surf =
exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
exa->ctx->surface_copy(exa->ctx, 0, surf, dstX, dstY, priv->src_surf,
srcX, srcY, width, height);
exa->scrn->tex_surface_release(exa->scrn, &surf);
}
static Bool
ExaPrepareComposite(int op, PicturePtr pSrcPicture,
PicturePtr pMaskPicture, PicturePtr pDstPicture,
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
{
return FALSE;
}
#if 0
static Bool
ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
int src_pitch)
{
ErrorF("UPLOAD\n");
return FALSE;
}
#endif
static void
ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
}
static Bool
ExaCheckComposite(int op,
PicturePtr pSrcPicture, PicturePtr pMaskPicture,
PicturePtr pDstPicture)
{
return FALSE;
}
static void *
ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
{
struct PixmapPriv *priv;
priv = xcalloc(1, sizeof(struct PixmapPriv));
if (!priv)
return NULL;
return priv;
}
static void
ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
{
struct PixmapPriv *priv = (struct PixmapPriv *)dPriv;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
if (!priv)
return;
if (priv->tex)
ms->screen->texture_release(exa->scrn, &priv->tex);
xfree(priv);
}
static Bool
ExaPixmapIsOffscreen(PixmapPtr pPixmap)
{
struct PixmapPriv *priv;
priv = exaGetPixmapDriverPrivate(pPixmap);
if (!priv)
return FALSE;
if (priv->tex)
return TRUE;
return FALSE;
}
unsigned
xorg_exa_get_pixmap_handle(PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct PixmapPriv *priv;
struct pipe_buffer *buffer = NULL;
unsigned handle;
unsigned stride;
if (!ms->exa) {
FatalError("NO MS->EXA\n");
return 0;
}
priv = exaGetPixmapDriverPrivate(pPixmap);
if (!priv) {
FatalError("NO PIXMAP PRIVATE\n");
return 0;
}
drm_api_hocks.buffer_from_texture(priv->tex, &buffer, &stride);
drm_api_hocks.handle_from_buffer(ms->screen, buffer, &handle);
pipe_buffer_reference(ms->screen, &buffer, NULL);
return handle;
}
static Bool
ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
int depth, int bitsPerPixel, int devKind,
pointer pPixData)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
modesettingPtr ms = modesettingPTR(pScrn);
//PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
struct exa_entity *exa = ms->exa;
if (!priv)
return FALSE;
if (depth <= 0)
depth = pPixmap->drawable.depth;
if (bitsPerPixel <= 0)
bitsPerPixel = pPixmap->drawable.bitsPerPixel;
if (width <= 0)
width = pPixmap->drawable.width;
if (height <= 0)
height = pPixmap->drawable.height;
if (width <= 0 || height <= 0 || depth <= 0)
return FALSE;
miModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, NULL);
/* Deal with screen resize */
if (priv->tex && (priv->tex->width[0] != width || priv->tex->height[0] != height)) {
pipe_texture_reference(&priv->tex, NULL);
}
if (!priv->tex) {
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
template.compressed = 0;
template.format = exa_get_pipe_format(depth);
pf_get_block(template.format, &template.block);
template.width[0] = width;
template.height[0] = height;
template.depth[0] = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
priv->tex = exa->scrn->texture_create(exa->scrn, &template);
}
return TRUE;
}
struct pipe_texture *
xorg_exa_get_texture(PixmapPtr pPixmap)
{
struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
struct pipe_texture *tex = NULL;
pipe_texture_reference(&tex, priv->tex);
return tex;
}
void
xorg_exa_close(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
if (exa->ctx)
exa->ctx->destroy(exa->ctx);
exaDriverFini(pScrn->pScreen);
xfree(exa);
ms->exa = NULL;
}
void *
xorg_exa_init(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa;
ExaDriverPtr pExa;
exa = xcalloc(1, sizeof(struct exa_entity));
if (!exa)
return NULL;
pExa = exaDriverAlloc();
if (!pExa) {
goto out_err;
}
memset(pExa, 0, sizeof(*pExa));
pExa->exa_major = 2;
pExa->exa_minor = 2;
pExa->memoryBase = 0;
pExa->memorySize = 0;
pExa->offScreenBase = 0;
pExa->pixmapOffsetAlign = 0;
pExa->pixmapPitchAlign = 1;
pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
pExa->maxX = 8191; /* FIXME */
pExa->maxY = 8191; /* FIXME */
pExa->WaitMarker = ExaWaitMarker;
pExa->MarkSync = ExaMarkSync;
pExa->PrepareSolid = ExaPrepareSolid;
pExa->Solid = ExaSolid;
pExa->DoneSolid = ExaDone;
pExa->PrepareCopy = ExaPrepareCopy;
pExa->Copy = ExaCopy;
pExa->DoneCopy = ExaDone;
pExa->CheckComposite = ExaCheckComposite;
pExa->PrepareComposite = ExaPrepareComposite;
pExa->Composite = ExaComposite;
pExa->DoneComposite = ExaDoneComposite;
pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
pExa->PrepareAccess = ExaPrepareAccess;
pExa->FinishAccess = ExaFinishAccess;
//pExa->UploadToScreen = ExaUploadToScreen;
pExa->UploadToScreen = NULL;
pExa->CreatePixmap = ExaCreatePixmap;
pExa->DestroyPixmap = ExaDestroyPixmap;
pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
if (!exaDriverInit(pScrn->pScreen, pExa)) {
goto out_err;
}
exa->scrn = ms->screen;
exa->ctx = drm_api_hocks.create_context(exa->scrn);
/* Share context with DRI */
ms->ctx = exa->ctx;
return (void *)exa;
out_err:
xorg_exa_close(pScrn);
return NULL;
}
/* vim: set sw=4 ts=8 sts=4: */
@@ -0,0 +1,296 @@
/*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
* Author: Alan Hourihane <alanh@tungstengraphics.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*
*/
#include "xorg-server.h"
#include <xf86.h>
#include <xf86i2c.h>
#include <xf86Crtc.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
#include "X11/Xatom.h"
#include "xorg_tracker.h"
static char *connector_enum_list[] = {
"Unknown",
"VGA",
"DVI-I",
"DVI-D",
"DVI-A",
"Composite",
"SVIDEO",
"LVDS",
"Component",
"9-pin DIN",
"DisplayPort",
"HDMI Type A",
"HDMI Type B",
};
static void
dpms(xf86OutputPtr output, int mode)
{
}
static void
save(xf86OutputPtr output)
{
}
static void
restore(xf86OutputPtr output)
{
}
static int
mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
return MODE_OK;
}
static Bool
mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
return TRUE;
}
static void
prepare(xf86OutputPtr output)
{
dpms(output, DPMSModeOff);
}
static void
mode_set(xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
}
static void
commit(xf86OutputPtr output)
{
dpms(output, DPMSModeOn);
if (output->scrn->pScreen != NULL)
xf86_reload_cursors(output->scrn->pScreen);
}
static xf86OutputStatus
detect(xf86OutputPtr output)
{
drmModeConnectorPtr drm_connector = output->driver_private;
switch (drm_connector->connection) {
case DRM_MODE_CONNECTED:
return XF86OutputStatusConnected;
case DRM_MODE_DISCONNECTED:
return XF86OutputStatusDisconnected;
default:
return XF86OutputStatusUnknown;
}
}
static DisplayModePtr
get_modes(xf86OutputPtr output)
{
drmModeConnectorPtr drm_connector = output->driver_private;
drmModeModeInfoPtr drm_mode = NULL;
DisplayModePtr modes = NULL, mode = NULL;
int i;
for (i = 0; i < drm_connector->count_modes; i++) {
drm_mode = &drm_connector->modes[i];
if (drm_mode) {
mode = xcalloc(1, sizeof(DisplayModeRec));
if (!mode)
continue;
mode->type = 0;
mode->Clock = drm_mode->clock;
mode->HDisplay = drm_mode->hdisplay;
mode->HSyncStart = drm_mode->hsync_start;
mode->HSyncEnd = drm_mode->hsync_end;
mode->HTotal = drm_mode->htotal;
mode->VDisplay = drm_mode->vdisplay;
mode->VSyncStart = drm_mode->vsync_start;
mode->VSyncEnd = drm_mode->vsync_end;
mode->VTotal = drm_mode->vtotal;
mode->Flags = drm_mode->flags;
mode->HSkew = drm_mode->hskew;
mode->VScan = drm_mode->vscan;
mode->VRefresh = xf86ModeVRefresh(mode);
mode->Private = (void *)drm_mode;
xf86SetModeDefaultName(mode);
modes = xf86ModesAdd(modes, mode);
xf86PrintModeline(0, mode);
}
}
return modes;
}
static void
destroy(xf86OutputPtr output)
{
drmModeFreeConnector(output->driver_private);
}
static void
create_resources(xf86OutputPtr output)
{
#ifdef RANDR_12_INTERFACE
#endif /* RANDR_12_INTERFACE */
}
#ifdef RANDR_12_INTERFACE
static Bool
set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
{
return TRUE;
}
#endif /* RANDR_12_INTERFACE */
#ifdef RANDR_13_INTERFACE
static Bool
get_property(xf86OutputPtr output, Atom property)
{
return TRUE;
}
#endif /* RANDR_13_INTERFACE */
#ifdef RANDR_GET_CRTC_INTERFACE
static xf86CrtcPtr
get_crtc(xf86OutputPtr output)
{
return NULL;
}
#endif
static const xf86OutputFuncsRec output_funcs = {
.create_resources = create_resources,
.dpms = dpms,
.save = save,
.restore = restore,
.mode_valid = mode_valid,
.mode_fixup = mode_fixup,
.prepare = prepare,
.mode_set = mode_set,
.commit = commit,
.detect = detect,
.get_modes = get_modes,
#ifdef RANDR_12_INTERFACE
.set_property = set_property,
#endif
#ifdef RANDR_13_INTERFACE
.get_property = get_property,
#endif
.destroy = destroy,
#ifdef RANDR_GET_CRTC_INTERFACE
.get_crtc = get_crtc,
#endif
};
void
output_init(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
xf86OutputPtr output;
drmModeResPtr res;
drmModeConnectorPtr drm_connector = NULL;
drmModeEncoderPtr drm_encoder = NULL;
char *name;
int c, v, p;
res = drmModeGetResources(ms->fd);
if (res == 0) {
DRV_ERROR("Failed drmModeGetResources\n");
return;
}
for (c = 0; c < res->count_connectors; c++) {
drm_connector = drmModeGetConnector(ms->fd, res->connectors[c]);
if (!drm_connector)
goto out;
#if 0
for (p = 0; p < drm_connector->count_props; p++) {
drmModePropertyPtr prop;
prop = drmModeGetProperty(ms->fd, drm_connector->props[p]);
name = NULL;
if (prop) {
ErrorF("VALUES %d\n", prop->count_values);
for (v = 0; v < prop->count_values; v++)
ErrorF("%s %lld\n", prop->name, prop->values[v]);
}
}
#else
(void)p;
(void)v;
#endif
name = connector_enum_list[drm_connector->connector_type];
output = xf86OutputCreate(pScrn, &output_funcs, name);
if (!output)
continue;
drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]);
if (drm_encoder) {
output->possible_crtcs = drm_encoder->possible_crtcs;
output->possible_clones = drm_encoder->possible_clones;
} else {
output->possible_crtcs = 0;
output->possible_clones = 0;
}
output->driver_private = drm_connector;
output->subpixel_order = SubPixelHorizontalRGB;
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
}
out:
drmModeFreeResources(res);
}
/* vim: set sw=4 ts=8 sts=4: */
@@ -0,0 +1,130 @@
/*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
* Author: Alan Hourihane <alanh@tungstengraphics.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*
*/
#ifndef _XORG_TRACKER_H_
#define _XORG_TRACKER_H_
#include <errno.h>
#include <drm.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "exa.h"
#include "pipe/p_screen.h"
#include "state_tracker/drm_api.h"
#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
typedef struct
{
int lastInstance;
int refCount;
ScrnInfoPtr pScrn_1;
ScrnInfoPtr pScrn_2;
} EntRec, *EntPtr;
typedef struct _modesettingRec
{
/* drm */
int fd;
unsigned fb_id;
/* X */
EntPtr entityPrivate;
int Chipset;
EntityInfoPtr pEnt;
struct pci_device *PciInfo;
Bool noAccel;
Bool SWCursor;
CloseScreenProcPtr CloseScreen;
/* Broken-out options. */
OptionInfoPtr Options;
unsigned int SaveGeneration;
CreateScreenResourcesProcPtr createScreenResources;
/* gallium */
struct pipe_screen *screen;
struct pipe_context *ctx;
/* exa */
void *exa;
Bool noEvict;
} modesettingRec, *modesettingPtr;
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
/***********************************************************************
* xorg_exa.c
*/
struct pipe_texture *
xorg_exa_get_texture(PixmapPtr pPixmap);
unsigned
xorg_exa_get_pixmap_handle(PixmapPtr pPixmap);
void *
xorg_exa_init(ScrnInfoPtr pScrn);
void
xorg_exa_close(ScrnInfoPtr pScrn);
/***********************************************************************
* xorg_dri2.c
*/
Bool
driScreenInit(ScreenPtr pScreen);
void
driCloseScreen(ScreenPtr pScreen);
/***********************************************************************
* xorg_crtc.c
*/
void
crtc_init(ScrnInfoPtr pScrn);
/***********************************************************************
* xorg_output.c
*/
void
output_init(ScrnInfoPtr pScrn);
#endif /* _XORG_TRACKER_H_ */
@@ -0,0 +1,51 @@
/*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
* Author: Alan Hourihane <alanh@tungstengraphics.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*
*/
/*
* File with all the junk needed to personalize the a xorg driver.
*/
#ifndef _XORG_WINSYS_H_
#define _XORG_WINSYS_H_
#include "xorg-server.h"
#include "xf86.h"
#include "xf86Resources.h"
#include "pciaccess.h"
#ifndef XSERVER_LIBPCIACCESS
#error "libpciaccess needed"
#endif
void xorg_tracker_set_functions(ScrnInfoPtr scrn);
const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid);
void xorg_tracker_loader_ref_sym_lists(void);
#endif