Merge commit 'origin/master' into gallium-map-range

This commit is contained in:
José Fonseca 2009-03-03 13:18:15 +00:00
commit c7e46c1857
80 changed files with 3536 additions and 864 deletions

View file

@ -284,16 +284,26 @@ fenced_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
struct fenced_buffer_list *fenced_list = fenced_buf->list;
struct pb_fence_ops *ops = fenced_list->ops;
void *map;
assert(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE);
assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE));
flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE));
/* Check for GPU read/write access */
if(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) {
/* Wait for the GPU to finish writing */
_fenced_buffer_finish(fenced_buf);
/* Serialize writes */
if((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) ||
((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) && (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) {
if(flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
/* Don't wait for the GPU to finish writing */
if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0)
_fenced_buffer_remove(fenced_list, fenced_buf);
else
return NULL;
}
else {
/* Wait for the GPU to finish writing */
_fenced_buffer_finish(fenced_buf);
}
}
#if 0
@ -307,7 +317,7 @@ fenced_buffer_map(struct pb_buffer *buf,
map = pb_map(fenced_buf->buffer, flags);
if(map) {
++fenced_buf->mapcount;
fenced_buf->flags |= flags;
fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE;
}
return map;

View file

@ -87,7 +87,7 @@ nv04_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
{
tx->direct = true;
tx->surface = pscreen->get_tex_surface(pscreen, pt,
face, level, zslice,
0, 0, 0,
nv04_usage_tx_to_buf(usage));
return &tx->base;
}

View file

@ -87,7 +87,7 @@ nv10_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
{
tx->direct = true;
tx->surface = pscreen->get_tex_surface(pscreen, pt,
face, level, zslice,
0, 0, 0,
nv10_usage_tx_to_buf(usage));
return &tx->base;
}

View file

@ -87,7 +87,7 @@ nv20_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
{
tx->direct = true;
tx->surface = pscreen->get_tex_surface(pscreen, pt,
face, level, zslice,
0, 0, 0,
nv20_usage_tx_to_buf(usage));
return &tx->base;
}

View file

@ -104,7 +104,7 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
face, level, zslice,
0, 0, 0,
nv30_usage_tx_to_buf(usage));
pipe_texture_reference(&tx_tex, NULL);

View file

@ -104,7 +104,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
face, level, zslice,
0, 0, 0,
nv40_usage_tx_to_buf(usage));
pipe_texture_reference(&tx_tex, NULL);

View file

@ -215,6 +215,7 @@ enum pipe_transfer_usage {
#define PIPE_BUFFER_USAGE_INDEX (1 << 6)
#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7)
#define PIPE_BUFFER_USAGE_DISCARD (1 << 8)
#define PIPE_BUFFER_USAGE_DONTBLOCK (1 << 9)
/** Pipe driver custom usage flags should be greater or equal to this value */
#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16)

View file

@ -0,0 +1,28 @@
TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = dri2drm
LIBRARY_INCLUDES = \
-I$(TOP)/include \
-I$(TOP)/src/mesa \
-I$(TOP)/src/mesa/drivers/dri/common \
-I$(TOP)/src/mesa/main \
$(shell pkg-config --cflags-only-I libdrm)
C_SOURCES = \
dri_context.c \
dri_screen.c \
dri_drawable.c \
dri_extensions.c
# $(TOP)/src/mesa/drivers/dri/common/utils.c \
$(TOP)/src/mesa/drivers/dri/common/vblank.c \
$(TOP)/src/mesa/drivers/dri/common/dri_util.c \
$(TOP)/src/mesa/drivers/dri/common/xmlconfig.c \
$(TOP)/src/mesa/drivers/common/driverfuncs.c \
$(TOP)/src/mesa/drivers/dri/common/texmem.c \
$(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c
include ../../Makefile.template

View file

@ -18,22 +18,29 @@
* 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
* IN NO EVENT SHALL VMWARE 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: Keith Whitwell <keithw@vmware.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*/
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_winsys.h"
#include "dri_drawable.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_context.h"
#include "pipe/p_context.h"
#include "dri_context.h"
#include "util/u_memory.h"
@ -59,14 +66,13 @@ dri_create_context(const __GLcontextModes *visual,
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
driParseConfigFiles(&ctx->optionCache,
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache,
sPriv->myNum,
sPriv->myNum,
"dri");
ctx->pipe = screen->pipe_screen->create_context(screen->pipe_screen,
screen->pipe_winsys,
hw_winsys );
ctx->pipe = drm_api_hocks.create_context(screen->pipe_screen);
if (ctx->pipe == NULL)
goto fail;
@ -76,16 +82,16 @@ dri_create_context(const __GLcontextModes *visual,
if (ctx->st == NULL)
goto fail;
dri_init_extensions( ctx );
dri_init_extensions(ctx);
return GL_TRUE;
fail:
if (ctx && ctx->st)
st_destroy_context( ctx->st );
st_destroy_context(ctx->st);
if (ctx && ctx->pipe)
ctx->pipe->destroy( ctx->pipe );
ctx->pipe->destroy(ctx->pipe);
FREE(ctx);
return FALSE;
@ -97,14 +103,13 @@ dri_destroy_context(__DRIcontextPrivate *cPriv)
{
struct dri_context *ctx = dri_context(cPriv);
struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct pipe_winsys *winsys = screen->winsys;
/* No particular reason to wait for command completion before
* destroying a context, but it is probably worthwhile flushing it
* to avoid having to add code elsewhere to cope with flushing a
* partially destroyed context.
*/
st_flush(ctx->st);
st_flush(ctx->st, 0, NULL);
if (screen->dummyContext == ctx)
screen->dummyContext = NULL;
@ -143,26 +148,21 @@ dri_make_current(__DRIcontextPrivate *cPriv,
*/
screen->dummyContext = ctx;
st_make_current( ctx->st,
draw->stfb,
read->stfb );
st_make_current(ctx->st,
draw->stfb,
read->stfb);
ctx->dPriv = driDrawPriv;
/* Update window sizes if necessary:
*/
if (draw->stamp != driDrawPriv->lastStamp) {
dri_update_window_size( draw );
}
if (read->stamp != driReadPriv->lastStamp) {
dri_update_window_size( read );
}
}
else {
if (driDrawPriv)
dri_get_buffers(driDrawPriv);
if (driDrawPriv != driReadPriv && driReadPriv)
dri_get_buffers(driReadPriv);
} else {
st_make_current(NULL, NULL, NULL);
}
return GL_TRUE;
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
* Copyright (C) 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@ -17,12 +18,16 @@
* 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
* IN NO EVENT SHALL VMWARE 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: Keith Whitwell <keithw@vmware.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*/
#ifndef DRI_CONTEXT_H
#define DRI_CONTEXT_H
@ -35,22 +40,21 @@
struct pipe_context;
struct pipe_fence;
struct st_context;
struct dri_drawable;
struct dri_context
{
/* dri */
__DRIscreenPrivate *sPriv;
__DRIcontextPrivate *cPriv;
__DRIdrawablePrivate *dPriv;
driOptionCache optionCache;
/* gallium */
struct st_context *st;
struct pipe_context *pipe;
boolean locked;
/**
* Configuration cache
*/
driOptionCache optionCache;
};
@ -60,13 +64,14 @@ dri_context(__DRIcontextPrivate *driContextPriv)
return (struct dri_context *) driContextPriv->driverPrivate;
}
/***********************************************************************
* dri_context.c
*/
void
void
dri_destroy_context(__DRIcontextPrivate * driContextPriv);
boolean
boolean
dri_unbind_context(__DRIcontextPrivate * driContextPriv);
boolean
@ -80,16 +85,12 @@ dri_create_context(const __GLcontextModes * visual,
void *sharedContextPrivate);
/***********************************************************************
* dri_lock.c
* dri_extensions.c
*/
void dri_lock_hardware( struct dri_context *context,
struct dri_drawable *drawable );
void dri_unlock_hardware( struct dri_context *dri );
boolean dri_is_locked( struct dri_context *dri );
void
dri_init_extensions(struct dri_context *ctx);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -0,0 +1,315 @@
/**************************************************************************
*
* Copyright 2009, VMware, Inc.
* 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 VMWARE 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: Keith Whitwell <keithw@vmware.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*/
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_inlines.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_cb_fbo.h"
#include "util/u_memory.h"
static struct pipe_surface *
dri_surface_from_handle(struct pipe_screen *screen,
unsigned handle,
enum pipe_format format,
unsigned width,
unsigned height,
unsigned pitch)
{
struct pipe_surface *surface = NULL;
struct pipe_texture *texture = NULL;
struct pipe_texture templat;
struct pipe_buffer *buf = NULL;
buf = drm_api_hocks.buffer_from_handle(screen, "dri2 buffer", handle);
if (!buf)
return NULL;
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth[0] = 1;
templat.format = format;
templat.width[0] = width;
templat.height[0] = height;
pf_get_block(templat.format, &templat.block);
texture = screen->texture_blanket(screen,
&templat,
&pitch,
buf);
/* we don't need the buffer from this point on */
pipe_buffer_reference(screen, &buf, NULL);
if (!texture)
return NULL;
surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
/* we don't need the texture from this point on */
pipe_texture_reference(&texture, NULL);
return surface;
}
/**
* This will be called a drawable is known to have been resized.
*/
void
dri_get_buffers(__DRIdrawablePrivate *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_surface *surface = NULL;
struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
__DRIbuffer *buffers = NULL;
__DRIscreen *dri_screen = drawable->sPriv;
__DRIdrawable *dri_drawable = drawable->dPriv;
boolean have_depth = FALSE;
int i, count;
buffers = (*dri_screen->dri2.loader->getBuffers)(dri_drawable,
&dri_drawable->w,
&dri_drawable->h,
drawable->attachments,
drawable->num_attachments,
&count,
dri_drawable->loaderPrivate);
if (buffers == NULL) {
return;
}
/* set one cliprect to cover the whole dri_drawable */
dri_drawable->x = 0;
dri_drawable->y = 0;
dri_drawable->backX = 0;
dri_drawable->backY = 0;
dri_drawable->numClipRects = 1;
dri_drawable->pClipRects[0].x1 = 0;
dri_drawable->pClipRects[0].y1 = 0;
dri_drawable->pClipRects[0].x2 = dri_drawable->w;
dri_drawable->pClipRects[0].y2 = dri_drawable->h;
dri_drawable->numBackClipRects = 1;
dri_drawable->pBackClipRects[0].x1 = 0;
dri_drawable->pBackClipRects[0].y1 = 0;
dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
for (i = 0; i < count; i++) {
enum pipe_format format = 0;
int index = 0;
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
index = ST_SURFACE_FRONT_LEFT;
format = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
case __DRI_BUFFER_BACK_LEFT:
index = ST_SURFACE_BACK_LEFT;
format = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
case __DRI_BUFFER_DEPTH:
index = ST_SURFACE_DEPTH;
format = PIPE_FORMAT_Z24S8_UNORM;
break;
case __DRI_BUFFER_STENCIL:
index = ST_SURFACE_DEPTH;
format = PIPE_FORMAT_Z24S8_UNORM;
break;
case __DRI_BUFFER_ACCUM:
default:
assert(0);
}
assert(buffers[i].cpp == 4);
if (index == ST_SURFACE_DEPTH) {
if (have_depth)
continue;
else
have_depth = TRUE;
}
surface = dri_surface_from_handle(screen,
buffers[i].name,
format,
dri_drawable->w,
dri_drawable->h,
buffers[i].pitch);
st_set_framebuffer_surface(drawable->stfb, index, surface);
pipe_surface_reference(&surface, NULL);
}
/* this needed, or else the state tracker fails to pick the new buffers */
st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
}
void
dri_swap_buffers(__DRIdrawablePrivate * dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_surface *back_surf;
assert(drawable);
assert(drawable->stfb);
st_get_framebuffer_surface(drawable->stfb,
ST_SURFACE_BACK_LEFT,
&back_surf);
if (back_surf) {
st_notify_swapbuffers(drawable->stfb);
/* TODO do stuff here */
st_notify_swapbuffers_complete(drawable->stfb);
}
}
/**
* Called via glXCopySubBufferMESA() to copy a subrect of the back
* buffer to the front buffer/screen.
*/
void
dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_surface *back_surf;
assert(drawable);
assert(drawable->stfb);
st_get_framebuffer_surface(drawable->stfb,
ST_SURFACE_BACK_LEFT,
&back_surf);
if (back_surf) {
drm_clip_rect_t rect;
rect.x1 = x;
rect.y1 = y;
rect.x2 = w;
rect.y2 = h;
/* do stuff here */
}
}
/**
* This is called when we need to set up GL rendering to a new X window.
*/
boolean
dri_create_buffer(__DRIscreenPrivate *sPriv,
__DRIdrawablePrivate *dPriv,
const __GLcontextModes *visual,
boolean isPixmap)
{
enum pipe_format colorFormat, depthFormat, stencilFormat;
struct dri_drawable *drawable = NULL;
int i;
if (isPixmap)
goto fail; /* not implemented */
drawable = CALLOC_STRUCT(dri_drawable);
if (drawable == NULL)
goto fail;
/* XXX: todo: use the pipe_screen queries to figure out which
* render targets are supportable.
*/
assert(visual->redBits == 8);
assert(visual->depthBits == 24 || visual->depthBits == 0);
assert(visual->stencilBits == 8 || visual->stencilBits == 0);
colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
if (visual->depthBits)
depthFormat = PIPE_FORMAT_S8Z24_UNORM;
else
depthFormat = PIPE_FORMAT_NONE;
if (visual->stencilBits)
stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
else
stencilFormat = PIPE_FORMAT_NONE;
drawable->stfb = st_create_framebuffer(visual,
colorFormat,
depthFormat,
stencilFormat,
dPriv->w,
dPriv->h,
(void*) drawable);
if (drawable->stfb == NULL)
goto fail;
drawable->sPriv = sPriv;
drawable->dPriv = dPriv;
dPriv->driverPrivate = (void *) drawable;
/* setup dri2 buffers information */
i = 0;
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
if (visual->depthBits)
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
if (visual->stencilBits)
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
drawable->num_attachments = i;
return GL_TRUE;
fail:
FREE(drawable);
return GL_FALSE;
}
void
dri_destroy_buffer(__DRIdrawablePrivate *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
st_unreference_framebuffer(drawable->stfb);
FREE(drawable);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -18,7 +18,7 @@
* 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
* IN NO EVENT SHALL VMWARE 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.
@ -37,12 +37,14 @@ struct st_framebuffer;
struct dri_drawable
{
/* dri */
__DRIdrawablePrivate *dPriv;
unsigned stamp;
__DRIscreenPrivate *sPriv;
struct pipe_fence *last_swap_fence;
struct pipe_fence *first_swap_fence;
unsigned attachments[8];
unsigned num_attachments;
/* gallium */
struct st_framebuffer *stfb;
};
@ -57,17 +59,26 @@ dri_drawable(__DRIdrawablePrivate * driDrawPriv)
/***********************************************************************
* dri_drawable.c
*/
boolean
dri_create_buffer(__DRIscreenPrivate *sPriv,
__DRIdrawablePrivate *dPriv,
const __GLcontextModes *visual,
boolean isPixmap);
void
void
dri_swap_buffers(__DRIdrawablePrivate * dPriv);
void
void
dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv,
int x, int y,
int x, int y,
int w, int h);
void
dri_update_window_size(__DRIdrawablePrivate *dPriv);
void
dri_get_buffers(__DRIdrawablePrivate * dPriv);
void
dri_destroy_buffer(__DRIdrawablePrivate *dPriv);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -18,15 +18,20 @@
* 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
* IN NO EVENT SHALL VMWARE 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: Keith Whitwell <keithw@vmware.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*/
#include "dri_screen.h"
#include "dri_context.h"
#include "state_tracker/st_context.h"
#define need_GL_ARB_multisample
#define need_GL_ARB_point_parameters
@ -96,13 +101,17 @@ const struct dri_extension card_extensions[] = {
};
void
dri_init_extensions( void )
void
dri_init_extensions(struct dri_context *ctx)
{
/* The card_extensions list should be pruned according to the
* capabilities of the pipe_screen. This is actually something
* capabilities of the pipe_screen. This is actually something
* that can/should be done inside st_create_context().
*/
driInitExtensions( ctx->st->ctx, card_extensions, GL_TRUE );
if (ctx)
driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE);
else
driInitExtensions(NULL, card_extensions, GL_FALSE);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -18,23 +18,29 @@
* 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
* IN NO EVENT SHALL VMWARE 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: Keith Whitwell <keithw@vmware.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*/
#include "utils.h"
#include "vblank.h"
#include "xmlpool.h"
#include "dri_context.h"
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_inlines.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_cb_fbo.h"
@ -44,19 +50,15 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
// DRI_CONF_FORCE_S3TC_ENABLE(false)
/*DRI_CONF_FORCE_S3TC_ENABLE(false)*/
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END DRI_CONF_END;
const uint __driNConfigOptions = 3;
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
extern const struct dri_extension card_extensions[];
static const __DRIextension *driScreenExtensions[] = {
static const __DRIextension *dri_screen_extensions[] = {
&driReadDrawableExtension,
&driCopySubBufferExtension.base,
&driSwapControlExtension.base,
@ -66,46 +68,40 @@ static const __DRIextension *driScreenExtensions[] = {
};
static const char *
dri_get_name( struct pipe_winsys *winsys )
static void
dri_get_drm_minor(struct dri_screen *screen)
{
return "dri";
/* TODO get the real minor */
screen->minor = 0;
}
static void
dri_destroy_screen(__DRIscreenPrivate * sPriv)
dri_get_device_id(struct dri_screen *screen)
{
struct dri_screen *screen = dri_screen(sPriv);
char path[512];
FILE *file;
screen->pipe_screen->destroy( screen->pipe_screen );
screen->pipe_winsys->destroy( screen->pipe_winsys );
FREE(screen);
sPriv->private = NULL;
/*
* There must be a better way to get the deviceID.
* XXX this only works on Linux.
*/
snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", screen->minor);
file = fopen(path, "r");
if (!file) {
return;
}
fgets(path, sizeof(path), file);
sscanf(path, "%x", &screen->deviceID);
fclose(file);
}
/**
* Get information about previous buffer swaps.
*/
static int
dri_get_swap_info(__DRIdrawablePrivate * dPriv,
__DRIswapInfo * sInfo)
{
if (dPriv == NULL ||
dPriv->driverPrivate == NULL ||
sInfo == NULL)
return -1;
else
return 0;
}
static const __DRIconfig **
dri_fill_in_modes(__DRIscreenPrivate *psp,
unsigned pixel_bits )
unsigned pixel_bits, unsigned depth_bits,
unsigned stencil_bits, GLboolean have_back_buffer)
{
__DRIconfig **configs;
__GLcontextModes *m;
@ -115,17 +111,19 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,
uint8_t msaa_samples_array[1];
unsigned depth_buffer_factor;
unsigned back_buffer_factor;
unsigned msaa_samples_factor;
GLenum fb_format;
GLenum fb_type;
int i;
static const GLenum back_buffer_modes[] = {
GLX_NONE, GLX_SWAP_UNDEFINED_OML
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
};
/* TODO probe the hardware of what is supports */
depth_bits_array[0] = 0;
depth_bits_array[1] = depth_bits;
depth_bits_array[2] = depth_bits;
depth_bits_array[1] = 24;
depth_bits_array[2] = 24;
stencil_bits_array[0] = 0; /* no depth or stencil */
stencil_bits_array[1] = 0; /* z24x8 */
@ -134,9 +132,10 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,
msaa_samples_array[0] = 0;
depth_buffer_factor = 3;
back_buffer_factor = 1;
back_buffer_factor = 3;
msaa_samples_factor = 1;
num_modes = depth_buffer_factor * back_buffer_factor * 4;
num_modes = depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
if (pixel_bits == 16) {
fb_format = GL_RGB;
@ -148,85 +147,79 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,
}
configs = driCreateConfigs(fb_format, fb_type,
depth_bits_array,
stencil_bits_array, depth_buffer_factor,
depth_bits_array,
stencil_bits_array, depth_buffer_factor,
back_buffer_modes, back_buffer_factor,
msaa_samples_array, 1);
msaa_samples_array, msaa_samples_factor);
if (configs == NULL) {
debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__);
return NULL;
}
return configs;
for (i = 0; configs[i]; i++) {
m = &configs[i]->modes;
if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
m->visualRating = GLX_SLOW_CONFIG;
}
}
return (const const __DRIconfig **) configs;
}
/**
* Get information about previous buffer swaps.
*/
int
dri_get_swap_info(__DRIdrawablePrivate * dPriv,
__DRIswapInfo * sInfo)
{
if (dPriv == NULL ||
dPriv->driverPrivate == NULL ||
sInfo == NULL)
return -1;
else
return 0;
}
/* This is the driver specific part of the createNewScreen entry point.
*
/**
* This is the driver specific part of the createNewScreen entry point.
*
* Returns the __GLcontextModes supported by this driver.
*/
static const __DRIconfig **dri_init_screen(__DRIscreenPrivate *sPriv)
const __DRIconfig **
dri_init_screen2(__DRIscreenPrivate *sPriv)
{
static const __DRIversion ddx_expected = { 1, 6, 0 }; /* hw query */
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 5, 0 }; /* hw query */
struct dri_screen *screen;
if (!driCheckDriDdxDrmVersions2("dri",
&sPriv->dri_version, &dri_expected,
&sPriv->ddx_version, &ddx_expected,
&sPriv->drm_version, &drm_expected)) {
return NULL;
}
/* Set up dispatch table to cope with all known extensions:
*/
driInitExtensions( NULL, card_extensions, GL_FALSE );
/* Set up dispatch table to cope with all known extensions */
dri_init_extensions(NULL);
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
goto fail;
screen->sPriv = sPriv;
screen->fd = sPriv->fd;
dri_get_drm_minor(screen);
dri_get_device_id(screen);
sPriv->private = (void *) screen;
sPriv->extensions = dri_screen_extensions;
/* Search the registered winsys' for one that likes this sPriv.
* This is required in situations where multiple devices speak to
* the same DDX and are built into the same binary.
*
* Note that cases like Intel i915 vs i965 doesn't fall into this
* category because they are built into separate binaries.
*
* Nonetheless, it's healthy to keep that level of detail out of
* this state_tracker.
*/
for (i = 0;
i < dri1_winsys_count &&
screen->st_winsys == NULL;
i++)
{
screen->dri_winsys =
dri_winsys[i]->check_dri_privates( sPriv->pDevPriv,
sPriv->pSAREA
/* versions, etc?? */));
screen->pipe_screen = drm_api_hocks.create_screen(screen->fd, screen->deviceID);
if (!screen->pipe_screen) {
debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
goto fail;
}
driParseOptionInfo(&screen->optionCache,
__driConfigOptions,
__driConfigOptions,
__driNConfigOptions);
/* Plug our info back into the __DRIscreenPrivate:
*/
sPriv->private = (void *) screen;
sPriv->extensions = driScreenExtensions;
return dri_fill_in_modes(sPriv,
dri_priv->cpp * 8,
return dri_fill_in_modes(sPriv,
4 * 8,
24,
8,
1);
@ -235,21 +228,32 @@ fail:
}
void
dri_destroy_screen(__DRIscreenPrivate * sPriv)
{
struct dri_screen *screen = dri_screen(sPriv);
const struct __DriverAPIRec driDriverAPI = {
.InitScreen = dri_init_screen,
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
.SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
.GetSwapInfo = dri_get_swap_info,
.GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.CopySubBuffer = dri_copy_sub_buffer,
screen->pipe_screen->destroy(screen->pipe_screen);
FREE(screen);
sPriv->private = NULL;
}
//.InitScreen2 = dri_init_screen2,
PUBLIC const struct __DriverAPIRec driDriverAPI = {
.InitScreen = NULL,
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
.SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
.GetSwapInfo = dri_get_swap_info,
.GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.CopySubBuffer = dri_copy_sub_buffer,
.InitScreen2 = dri_init_screen2,
};
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -18,12 +18,16 @@
* 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
* IN NO EVENT SHALL VMWARE 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: Keith Whitwell <keithw@vmware.com>
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
*/
#ifndef DRI_SCREEN_H
#define DRI_SCREEN_H
@ -35,27 +39,8 @@
struct dri_screen
{
__DRIScreenPrivate *sPriv;
struct pipe_winsys *pipe_winsys;
struct pipe_screen *pipe_screen;
struct {
/* Need a pipe_surface pointer to do client-side swapbuffers:
*/
unsigned long buffer_handle;
struct pipe_surface *surface;
struct pipe_texture *texture;
int pitch; /* row stride, in bytes */
int width;
int height;
int size;
int cpp; /* for front and back buffers */
} front;
int deviceID;
int drmMinor;
/* dri */
__DRIscreenPrivate *sPriv;
/**
* Configuration cache with default values for all contexts
@ -67,8 +52,16 @@ struct dri_screen
* which we need a rendering context, but none is currently bound.
*/
struct dri_context *dummyContext;
};
/* drm */
int deviceID;
int fd;
int minor;
/* gallium */
struct pipe_winsys *pipe_winsys;
struct pipe_screen *pipe_screen;
};
/** cast wrapper */
@ -79,5 +72,19 @@ dri_screen(__DRIscreenPrivate *sPriv)
}
/***********************************************************************
* dri_screen.c
*/
const __DRIconfig **
dri_init_screen2(__DRIscreenPrivate *sPriv);
void
dri_destroy_screen(__DRIscreenPrivate * sPriv);
int
dri_get_swap_info(__DRIdrawablePrivate * dPriv,
__DRIswapInfo * sInfo);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -1,363 +0,0 @@
/**************************************************************************
*
* Copyright 2009, VMware, Inc.
* 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.
*
**************************************************************************/
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_swapbuffers.h"
#include "pipe/p_context.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_cb_fbo.h"
static void
blit_swapbuffers(__DRIdrawablePrivate *dPriv,
__DRIcontextPrivate *cPriv,
struct pipe_surface *src,
const drm_clip_rect_t *rect)
{
struct dri_screen *screen = dri_screen(dPriv->driScreenPriv);
struct dri_drawable *fb = dri_drawable(dPriv);
struct dri_context *context = dri_context(cPriv);
const int nbox = dPriv->numClipRects;
const drm_clip_rect_t *pbox = dPriv->pClipRects;
struct pipe_surface *dest = fb->front_surface;
const int backWidth = fb->stfb->Base.Width;
const int backHeight = fb->stfb->Base.Height;
int i;
for (i = 0; i < nbox; i++, pbox++) {
drm_clip_rect_t box;
drm_clip_rect_t sbox;
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
(pbox->x2 - pbox->x1) > dest->width ||
(pbox->y2 - pbox->y1) > dest->height)
continue;
box = *pbox;
if (rect) {
drm_clip_rect_t rrect;
rrect.x1 = dPriv->x + rect->x1;
rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y;
rrect.x2 = rect->x2 + rrect.x1;
rrect.y2 = rect->y2 + rrect.y1;
if (rrect.x1 > box.x1)
box.x1 = rrect.x1;
if (rrect.y1 > box.y1)
box.y1 = rrect.y1;
if (rrect.x2 < box.x2)
box.x2 = rrect.x2;
if (rrect.y2 < box.y2)
box.y2 = rrect.y2;
if (box.x1 > box.x2 || box.y1 > box.y2)
continue;
}
/* restrict blit to size of actually rendered area */
if (box.x2 - box.x1 > backWidth)
box.x2 = backWidth + box.x1;
if (box.y2 - box.y1 > backHeight)
box.y2 = backHeight + box.y1;
debug_printf("%s: box %d,%d-%d,%d\n", __FUNCTION__,
box.x1, box.y1, box.x2, box.y2);
sbox.x1 = box.x1 - dPriv->x;
sbox.y1 = box.y1 - dPriv->y;
ctx->st->pipe->surface_copy( ctx->st->pipe,
FALSE,
dest,
box.x1, box.y1,
src,
sbox.x1, sbox.y1,
box.x2 - box.x1,
box.y2 - box.y1 );
}
}
/**
* Display a colorbuffer surface in an X window.
* Used for SwapBuffers and flushing front buffer rendering.
*
* \param dPriv the window/drawable to display into
* \param surf the surface to display
* \param rect optional subrect of surface to display (may be NULL).
*/
static void
dri_display_surface(__DRIdrawablePrivate *dPriv,
struct pipe_surface *source,
const drm_clip_rect_t *rect)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct dri_screen *screen = dri_screen(dPriv->driScreenPriv);
struct dri_context *context = screen->dummy_context;
struct pipe_winsys *winsys = screen->winsys;
if (!context)
return;
if (drawable->last_swap_fence) {
winsys->fence_finish( winsys,
drawable->last_swap_fence,
0 );
winsys->fence_reference( winsys,
&drawable->last_swap_fence,
NULL );
}
drawable->last_swap_fence = drawable->first_swap_fence;
drawable->first_swap_fence = NULL;
/* Call lock_hardware to update dPriv cliprects.
*/
dri_lock_hardware(context, drawable);
{
if (dPriv->numClipRects) {
blit_swapbuffers( context, dPriv, source, rect );
}
}
dri_unlock_hardware(context);
if (drawble->stamp != drawable->dPriv->lastStamp) {
dri_update_window_size( dpriv );
}
}
/**
* This will be called a drawable is known to have moved/resized.
*/
void
dri_update_window_size(__DRIdrawablePrivate *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
st_resize_framebuffer(drawable->stfb, dPriv->w, dPriv->h);
drawable->stamp = dPriv->lastStamp;
}
void
dri_swap_buffers(__DRIdrawablePrivate * dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_surface *back_surf;
assert(drawable);
assert(drawable->stfb);
back_surf = st_get_framebuffer_surface(drawable->stfb,
ST_SURFACE_BACK_LEFT);
if (back_surf) {
st_notify_swapbuffers(drawable->stfb);
dri_display_surface(dPriv, back_surf, NULL);
st_notify_swapbuffers_complete(drawable->stfb);
}
}
/**
* Called via glXCopySubBufferMESA() to copy a subrect of the back
* buffer to the front buffer/screen.
*/
void
dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_surface *back_surf;
assert(drawable);
assert(drawable->stfb);
back_surf = st_get_framebuffer_surface(drawable->stfb,
ST_SURFACE_BACK_LEFT);
if (back_surf) {
drm_clip_rect_t rect;
rect.x1 = x;
rect.y1 = y;
rect.x2 = w;
rect.y2 = h;
st_notify_swapbuffers(drawable->stfb);
dri_display_surface(dPriv, back_surf, &rect);
}
}
/*
* The state tracker keeps track of whether the fake frontbuffer has
* been touched by any rendering since the last time we copied its
* contents to the real frontbuffer. Our task is easy:
*/
static void
dri_flush_frontbuffer( struct pipe_winsys *winsys,
struct pipe_surface *surf,
void *context_private)
{
struct dri_context *dri = (struct dri_context *) context_private;
__DRIdrawablePrivate *dPriv = dri->driDrawable;
dri_display_surface(dPriv, surf, NULL);
}
/* Need to create a surface which wraps the front surface to support
* client-side swapbuffers.
*/
static void
dri_create_front_surface(struct dri_screen *screen,
struct pipe_winsys *winsys,
unsigned handle)
{
struct pipe_screen *pipe_screen = screen->pipe_screen;
struct pipe_texture *texture;
struct pipe_texture templat;
struct pipe_surface *surface;
struct pipe_buffer *buffer;
unsigned pitch;
assert(screen->front.cpp == 4);
// buffer = dri_buffer_from_handle(screen->winsys,
// "front", handle);
if (!buffer)
return;
screen->front.buffer = dri_bo(buffer);
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth[0] = 1;
templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
templat.width[0] = screen->front.width;
templat.height[0] = screen->front.height;
pf_get_block(templat.format, &templat.block);
pitch = screen->front.pitch;
texture = pipe_screen->texture_blanket(pipe_screen,
&templat,
&pitch,
buffer);
/* Unref the buffer we don't need it anyways */
pipe_buffer_reference(screen, &buffer, NULL);
surface = pipe_screen->get_tex_surface(pipe_screen,
texture,
0,
0,
0,
PIPE_BUFFER_USAGE_GPU_WRITE);
screen->front.texture = texture;
screen->front.surface = surface;
}
/**
* This is called when we need to set up GL rendering to a new X window.
*/
static boolean
dri_create_buffer(__DRIscreenPrivate *sPriv,
__DRIdrawablePrivate *dPriv,
const __GLcontextModes *visual,
boolean isPixmap)
{
enum pipe_format colorFormat, depthFormat, stencilFormat;
struct dri_drawable *drawable;
if (isPixmap)
goto fail; /* not implemented */
drawable = CALLOC_STRUCT(dri_drawable);
if (drawable == NULL)
goto fail;
/* XXX: todo: use the pipe_screen queries to figure out which
* render targets are supportable.
*/
if (visual->redBits == 5)
colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
else
colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
if (visual->depthBits == 16)
depthFormat = PIPE_FORMAT_Z16_UNORM;
else if (visual->depthBits == 24) {
if (visual->stencilBits == 8)
depthFormat = PIPE_FORMAT_S8Z24_UNORM;
else
depthFormat = PIPE_FORMAT_X8Z24_UNORM;
}
drawable->stfb = st_create_framebuffer(visual,
colorFormat,
depthFormat,
dPriv->w,
dPriv->h,
(void*) drawable);
if (drawable->stfb == NULL)
goto fail;
dPriv->driverPrivate = (void *) drawable;
return GL_TRUE;
fail:
FREE(drawable);
return GL_FALSE;
}
static void
dri_destroy_buffer(__DRIdrawablePrivate *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
/* No particular need to wait on fences before dereferencing them:
*/
winsys->fence_reference( winsys, &ctx->last_swap_fence, NULL );
winsys->fence_reference( winsys, &ctx->first_swap_fence, NULL );
st_unreference_framebuffer(drawable->stfb);
FREE(drawable);
}

View file

@ -1,90 +0,0 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* 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.
*
**************************************************************************/
#include "pipe/p_thread.h"
#include "dri_context.h"
#include "xf86drm.h"
pipe_static_mutex( lockMutex );
static void
dri_contended_lock(struct dri_context *ctx)
{
__DRIdrawablePrivate *dPriv = ctx->dPriv;
__DRIcontextPrivate *cPriv = ctx->cPriv;
__DRIscreenPrivate *sPriv = cPriv->driScreenPriv;
drmGetLock(sPriv->fd, cPriv->hHWContext, 0);
/* Perform round trip communication with server (including dropping
* and retaking the above lock) to update window dimensions:
*/
if (dPriv)
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
}
/* Lock the hardware and validate our state.
*/
void dri_lock_hardware( struct dri_context *ctx )
{
__DRIcontextPrivate *cPriv = ctx->cPriv;
__DRIscreenPrivate *sPriv = cPriv->driScreenPriv;
char __ret = 0;
pipe_mutex_lock(lockMutex);
assert(!ctx->locked);
DRM_CAS((drmLock *) &sPriv->pSAREA->lock,
cPriv->hHWContext,
(DRM_LOCK_HELD | cPriv->hHWContext),
__ret);
if (__ret)
dri_contended_lock( ctx );
ctx->locked = TRUE;
}
/* Unlock the hardware using the global current context
*/
void dri_unlock_hardware( struct dri_context *ctx )
{
__DRIcontextPrivate *cPriv = ctx->cPriv;
__DRIscreenPrivate *sPriv = cPriv->driScreenPriv;
assert(ctx->locked);
ctx->locked = FALSE;
DRM_UNLOCK(sPriv->fd,
(drmLock *) &sPriv->pSAREA->lock,
cPriv->hHWContext);
pipe_mutex_unlock(lockMutex);
}

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)

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: */

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: */

View file

@ -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: */

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: */

View file

@ -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: */

View file

@ -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_ */

View file

@ -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

View file

@ -0,0 +1,22 @@
TOP = ../../../../../..
include $(TOP)/configs/current
LIBNAME = i915_dri.so
PIPE_DRIVERS = \
$(TOP)/src/gallium/state_trackers/dri2/libdri2drm.a \
$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a
DRIVER_SOURCES =
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
include ../../Makefile.template
DRI_LIB_DEPS += -ldrm_intel
symlinks:

View file

@ -21,7 +21,7 @@ intel_be_batchbuffer_alloc(struct intel_be_context *intel)
batch->base.size = 0;
batch->base.actual_size = intel->device->max_batch_size;
batch->base.relocs = 0;
batch->base.max_relocs = INTEL_DEFAULT_RELOCS;
batch->base.max_relocs = 500;/*INTEL_DEFAULT_RELOCS;*/
batch->base.map = malloc(batch->base.actual_size);
memset(batch->base.map, 0, batch->base.actual_size);
@ -47,7 +47,6 @@ intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
batch->base.size = batch->base.actual_size - BATCH_RESERVED;
batch->base.relocs = 0;
batch->base.max_relocs = INTEL_DEFAULT_RELOCS;
batch->bo = drm_intel_bo_alloc(dev->pools.gem,
"gallium3d_batch_buffer",

View file

@ -26,6 +26,12 @@ intel_be_buffer_map(struct pipe_winsys *winsys,
int write = 0;
int ret;
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
/* Remove this when drm_intel_bo_map supports DONTBLOCK
*/
return NULL;
}
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
write = 1;

View file

@ -0,0 +1,42 @@
TARGET = modesetting_drv.so
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../gem \
-I${GALLIUMDIR}/include \
-I${GALLIUMDIR}/drivers \
-I${GALLIUMDIR}/auxiliary \
-I${TOP}/src/mesa \
-I$(TOP)/include \
-I$(TOP)/src/egl/main
LIBS = \
$(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a \
$(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \
$(GALLIUM_AUXILIARIES)
#############################################
all default: $(TARGET)
$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a
$(TOP)/bin/mklib -noprefix -o $@ \
$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
clean:
rm -rf $(OBJECTS) $(TARGET)
install:
cp $(TARGET) /opt/kms/lib/xorg/modules/drivers
.PHONY = all clean install

View file

@ -0,0 +1,156 @@
/*
* 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 "../../../../state_trackers/xorg/xorg_winsys.h"
static void intel_xorg_identify(int flags);
static Bool intel_xorg_pci_probe(DriverPtr driver,
int entity_num,
struct pci_device *device,
intptr_t match_data);
static const struct pci_id_match intel_xorg_device_match[] = {
{0x8086, 0x2592, 0xffff, 0xffff, 0, 0, 0},
{0x8086, 0x27A2, 0xffff, 0xffff, 0, 0, 0},
{0, 0, 0},
};
static SymTabRec intel_xorg_chipsets[] = {
{0x2592, "Intel Graphics Device"},
{0x27A2, "Intel Graphics Device"},
{-1, NULL}
};
static PciChipsets intel_xorg_pci_devices[] = {
{0x2592, 0x2592, RES_SHARED_VGA},
{0x27A2, 0x27A2, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED}
};
static XF86ModuleVersionInfo intel_xorg_version = {
"modesetting",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
0, 1, 0, /* major, minor, patch */
ABI_CLASS_VIDEODRV,
ABI_VIDEODRV_VERSION,
MOD_CLASS_VIDEODRV,
{0, 0, 0, 0}
};
/*
* Xorg driver exported structures
*/
_X_EXPORT DriverRec modesetting = {
1,
"modesetting",
intel_xorg_identify,
NULL,
xorg_tracker_available_options,
NULL,
0,
NULL,
intel_xorg_device_match,
intel_xorg_pci_probe
};
static MODULESETUPPROTO(intel_xorg_setup);
_X_EXPORT XF86ModuleData modesettingModuleData = {
&intel_xorg_version,
intel_xorg_setup,
NULL
};
/*
* Xorg driver functions
*/
static pointer
intel_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
{
static Bool setupDone = 0;
/* This module should be loaded only once, but check to be sure.
*/
if (!setupDone) {
setupDone = 1;
xf86AddDriver(&modesetting, module, HaveDriverFuncs);
/*
* Tell the loader about symbols from other modules that this module
* might refer to.
*/
xorg_tracker_loader_ref_sym_lists();
/*
* The return value must be non-NULL on success even though there
* is no TearDownProc.
*/
return (pointer) 1;
} else {
if (errmaj)
*errmaj = LDR_ONCEONLY;
return NULL;
}
}
static void
intel_xorg_identify(int flags)
{
xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
intel_xorg_chipsets);
}
static Bool
intel_xorg_pci_probe(DriverPtr driver,
int entity_num, struct pci_device *device, intptr_t match_data)
{
ScrnInfoPtr scrn = NULL;
EntityInfoPtr entity;
scrn = xf86ConfigPciEntity(scrn, 0, entity_num, intel_xorg_pci_devices,
NULL, NULL, NULL, NULL, NULL);
if (scrn != NULL) {
scrn->driverVersion = 1;
scrn->driverName = "modesetting";
scrn->name = "modesetting";
scrn->Probe = NULL;
entity = xf86GetEntityInfo(entity_num);
/* Use all the functions from the xorg tracker */
xorg_tracker_set_functions(scrn);
}
return scrn != NULL;
}

View file

@ -119,6 +119,12 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
uint32_t map_flags = 0;
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
/* Remove this when this code is modified to support DONTBLOCK
*/
return NULL;
}
if (flags & PIPE_BUFFER_USAGE_CPU_READ)
map_flags |= NOUVEAU_BO_RD;
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)

View file

@ -112,6 +112,12 @@ static void *radeon_buffer_map(struct pipe_winsys *ws,
struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer;
int write = 0;
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
/* Remove this when radeon_bo_map supports DONTBLOCK
*/
return NULL;
}
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
write = 1;
}

View file

@ -6,6 +6,7 @@
#include <util/u_memory.h>
#include <util/u_math.h>
#include <softpipe/sp_winsys.h>
#include <softpipe/sp_texture.h>
/* pipe_winsys implementation */
@ -162,7 +163,7 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *
xsp_winsys->fbimage.width = surface->width;
xsp_winsys->fbimage.height = surface->height;
xsp_winsys->fbimage.bytes_per_line = surface->width * (xsp_winsys->fbimage.bits_per_pixel >> 3);
xsp_winsys->fbimage.data = pipe_surface_map(surface, 0);
xsp_winsys->fbimage.data = ((struct xsp_buffer *)softpipe_texture(surface->texture)->buffer)->data + surface->offset;
XPutImage
(
@ -178,7 +179,6 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *
surface->height
);
XFlush(xsp_context->display);
pipe_surface_unmap(surface);
}
static const char* xsp_get_name(struct pipe_winsys *pws)

View file

@ -308,7 +308,7 @@ _mesa_init_driver_state(GLcontext *ctx)
ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag);
ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag);
ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled);
ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled);
ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE);
ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE);
ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE);

View file

@ -275,7 +275,7 @@ ffbDDStencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
/* We will properly update sw/hw state when stenciling is
* enabled.
*/
if (! ctx->Stencil.Enabled)
if (! ctx->Stencil._Enabled)
return;
stencilctl = fmesa->stencilctl;
@ -333,7 +333,7 @@ ffbDDStencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
/* We will properly update sw/hw state when stenciling is
* enabled.
*/
if (! ctx->Stencil.Enabled)
if (! ctx->Stencil._Enabled)
return;
stencilctl = fmesa->stencilctl;

View file

@ -88,7 +88,7 @@ cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)
memset(key, 0, sizeof(*key));
key->stencil = ctx->Stencil.Enabled;
key->stencil = ctx->Stencil._Enabled;
key->stencil_two_side = ctx->Stencil._TestTwoSide;
if (key->stencil) {

View file

@ -75,7 +75,7 @@ static GLboolean do_check_fallback(struct brw_context *brw)
/* _NEW_STENCIL
*/
if (ctx->Stencil.Enabled &&
if (ctx->Stencil._Enabled &&
(ctx->DrawBuffer->Name == 0 && !brw->intel.hw_stencil)) {
DBG("FALLBACK: stencil\n");
return GL_TRUE;

View file

@ -210,7 +210,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
/* _NEW_STENCIL */
if (ctx->Stencil.Enabled) {
if (ctx->Stencil._Enabled) {
lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
if (ctx->Stencil.WriteMask[0] ||

View file

@ -263,7 +263,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
}
}
else {
/* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */
/* XXX FBO: instead of FALSE, pass ctx->Stencil._Enabled ??? */
FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
}
@ -274,7 +274,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
ctx->Driver.Enable(ctx, GL_DEPTH_TEST,
(ctx->Depth.Test && fb->Visual.depthBits > 0));
ctx->Driver.Enable(ctx, GL_STENCIL_TEST,
(ctx->Stencil.Enabled && fb->Visual.stencilBits > 0));
(ctx->Stencil._Enabled && fb->Visual.stencilBits > 0));
}
else {
ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL);

View file

@ -247,13 +247,10 @@ static const char *buffer_names[] = {
[BUFFER_BACK_LEFT] = "back",
[BUFFER_FRONT_RIGHT] = "front right",
[BUFFER_BACK_RIGHT] = "back right",
[BUFFER_AUX0] = "aux0",
[BUFFER_AUX1] = "aux1",
[BUFFER_AUX2] = "aux2",
[BUFFER_AUX3] = "aux3",
[BUFFER_DEPTH] = "depth",
[BUFFER_STENCIL] = "stencil",
[BUFFER_ACCUM] = "accum",
[BUFFER_AUX0] = "aux0",
[BUFFER_COLOR0] = "color0",
[BUFFER_COLOR1] = "color1",
[BUFFER_COLOR2] = "color2",

View file

@ -112,7 +112,7 @@ intel_check_blit_fragment_ops(GLcontext * ctx, GLboolean src_alpha_is_one)
return GL_FALSE;
}
if (ctx->Stencil.Enabled) {
if (ctx->Stencil._Enabled) {
DBG("fallback due to image stencil\n");
return GL_FALSE;
}

View file

@ -87,7 +87,7 @@ intel_check_copypixel_blit_fragment_ops(GLcontext * ctx)
ctx->Color.AlphaEnabled ||
ctx->Depth.Test ||
ctx->Fog.Enabled ||
ctx->Stencil.Enabled ||
ctx->Stencil._Enabled ||
!ctx->Color.ColorMask[0] ||
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||

View file

@ -233,7 +233,7 @@ intel_stencil_drawpixels(GLcontext * ctx,
}
/* We don't support stencil testing/ops here */
if (ctx->Stencil.Enabled)
if (ctx->Stencil._Enabled)
return GL_FALSE;
/* We use FBOs for our wrapping of the depthbuffer into a color

View file

@ -133,7 +133,7 @@ check_color_per_fragment_ops( const GLcontext *ctx )
ctx->Depth.Test ||
ctx->Fog.Enabled ||
ctx->Scissor.Enabled ||
ctx->Stencil.Enabled ||
ctx->Stencil._Enabled ||
!ctx->Color.ColorMask[0] ||
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||

View file

@ -87,7 +87,7 @@ check_color_per_fragment_ops( const GLcontext *ctx )
ctx->Depth.Test ||
ctx->Fog.Enabled ||
ctx->Scissor.Enabled ||
ctx->Stencil.Enabled ||
ctx->Stencil._Enabled ||
!ctx->Color.ColorMask[0] ||
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||

View file

@ -2205,7 +2205,7 @@ static void r300ResetHwState(r300ContextPtr r300)
r300DepthFunc(ctx, ctx->Depth.Func);
/* stencil */
r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled);
r300StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);
r300StencilFuncSeparate(ctx, 0, ctx->Stencil.Function[0],
ctx->Stencil.Ref[0], ctx->Stencil.ValueMask[0]);

View file

@ -514,7 +514,7 @@ static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)
imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
}
else if (imesa->glCtx->Stencil.Enabled && imesa->hw_stencil)
else if (imesa->glCtx->Stencil._Enabled && imesa->hw_stencil)
{
/* Need to keep Z on for Stencil. */
imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
@ -1092,7 +1092,7 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
else {
imesa->regs.s4.stencilCtrl.ni.stencilEn = state;
if (ctx->Stencil.Enabled &&
if (ctx->Stencil._Enabled &&
imesa->regs.s4.zBufCtrl.ni.zBufEn != GL_TRUE)
{
/* Stencil buffer requires Z enabled. */

View file

@ -610,7 +610,7 @@ tdfx_drawpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y,
ctx->Depth.Test ||
ctx->Fog.Enabled ||
ctx->Scissor.Enabled ||
ctx->Stencil.Enabled ||
ctx->Stencil._Enabled ||
!ctx->Color.ColorMask[0] ||
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||

View file

@ -740,7 +740,7 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa )
}
if ( fxMesa->dirty & TDFX_UPLOAD_STENCIL ) {
if (fxMesa->glCtx->Stencil.Enabled) {
if (fxMesa->glCtx->Stencil._Enabled) {
fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
fxMesa->Glide.grStencilOp(fxMesa->Stencil.FailFunc,
fxMesa->Stencil.ZFailFunc,

View file

@ -459,7 +459,7 @@ static void tdfxUpdateStencil( GLcontext *ctx )
}
if (fxMesa->haveHwStencil) {
if (ctx->Stencil.Enabled) {
if (ctx->Stencil._Enabled) {
fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER + GR_CMP_NEVER;
fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0] & 0xff;
fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0] & 0xff;

View file

@ -1342,7 +1342,7 @@ static void viaChooseStencilState(GLcontext *ctx)
{
struct via_context *vmesa = VIA_CONTEXT(ctx);
if (ctx->Stencil.Enabled) {
if (ctx->Stencil._Enabled) {
GLuint temp;
vmesa->regEnable |= HC_HenST_MASK;

View file

@ -472,7 +472,7 @@ static void GGItriangle_flat_depth(GLcontext *ctx, const SWvertex *v0, const SWv
static swrast_tri_func ggimesa_stubs_get_triangle_func(GLcontext *ctx)
{
if (ctx->Stencil.Enabled) return NULL;
if (ctx->Stencil._Enabled) return NULL;
if (ctx->Polygon.SmoothFlag) return NULL;
if (ctx->Polygon.StippleFlag) return NULL;
if (ctx->Texture._ReallyEnabled) return NULL;

View file

@ -1948,7 +1948,7 @@ fx_check_IsInHardware(GLcontext * ctx)
return FX_FALLBACK_RENDER_MODE;
}
if (ctx->Stencil.Enabled && !fxMesa->haveHwStencil) {
if (ctx->Stencil._Enabled && !fxMesa->haveHwStencil) {
return FX_FALLBACK_STENCIL;
}

View file

@ -2410,11 +2410,8 @@ xbuffer_to_renderbuffer(int buffer)
case GLX_AUX0_EXT:
return BUFFER_AUX0;
case GLX_AUX1_EXT:
return BUFFER_AUX1;
case GLX_AUX2_EXT:
return BUFFER_AUX2;
case GLX_AUX3_EXT:
return BUFFER_AUX3;
case GLX_AUX4_EXT:
case GLX_AUX5_EXT:
case GLX_AUX6_EXT:

View file

@ -471,8 +471,26 @@ static void put_row_8R8G8B_pixmap( PUT_ROW_ARGS )
if (mask) {
for (i=0;i<n;i++,x++) {
if (mask[i]) {
#if 1
/*
* XXX Something funny is going on here.
* If we're drawing into a window that uses a depth 32 TrueColor
* visual, we see the right pixels on screen, but when we read
* them back with XGetImage() we get random colors.
* The alternative code below which uses XPutImage() instead
* seems to mostly fix the problem, but not always.
* We don't normally create windows with this visual, but glean
* does and we're seeing some failures there.
*/
XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
#else
/* This code works more often, but not always */
XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
GLuint *ptr4 = (GLuint *) rowimg->data;
*ptr4 = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, 1, 1 );
#endif
}
}
}

View file

@ -87,11 +87,20 @@ check_valid_to_render(GLcontext *ctx, char *function)
return GL_FALSE;
}
/* Always need vertex positions, unless a vertex program is in use */
if (!ctx->VertexProgram._Current &&
!ctx->Array.ArrayObj->Vertex.Enabled &&
#if FEATURE_es2_glsl
/* For ES2, we can draw if any vertex array is enabled (and we should
* always have a vertex program/shader).
*/
if (ctx->Array.ArrayObj->_Enabled == 0x0 || !ctx->VertexProgram._Current)
return GL_FALSE;
#else
/* For regular OpenGL, only draw if we have vertex positions (regardless
* of whether or not we have a vertex program/shader).
*/
if (!ctx->Array.ArrayObj->Vertex.Enabled &&
!ctx->Array.ArrayObj->VertexAttrib[0].Enabled)
return GL_FALSE;
#endif
return GL_TRUE;
}

View file

@ -119,12 +119,6 @@ draw_buffer_enum_to_bitmask(GLenum buffer)
return BUFFER_BIT_FRONT_LEFT;
case GL_AUX0:
return BUFFER_BIT_AUX0;
case GL_AUX1:
return BUFFER_BIT_AUX1;
case GL_AUX2:
return BUFFER_BIT_AUX2;
case GL_AUX3:
return BUFFER_BIT_AUX3;
case GL_COLOR_ATTACHMENT0_EXT:
return BUFFER_BIT_COLOR0;
case GL_COLOR_ATTACHMENT1_EXT:
@ -176,12 +170,6 @@ read_buffer_enum_to_index(GLenum buffer)
return BUFFER_FRONT_LEFT;
case GL_AUX0:
return BUFFER_AUX0;
case GL_AUX1:
return BUFFER_AUX1;
case GL_AUX2:
return BUFFER_AUX2;
case GL_AUX3:
return BUFFER_AUX3;
case GL_COLOR_ATTACHMENT0_EXT:
return BUFFER_COLOR0;
case GL_COLOR_ATTACHMENT1_EXT:

View file

@ -68,7 +68,7 @@
#define MAX_PIXEL_MAP_TABLE 256
/** Maximum number of auxillary color buffers */
#define MAX_AUX_BUFFERS 4
#define MAX_AUX_BUFFERS 1
/** Maximum order (degree) of curves */
#ifdef AMIGA

View file

@ -36,6 +36,22 @@
struct gl_pixelstore_attrib;
struct gl_display_list;
#if FEATURE_ARB_vertex_buffer_object
/* Modifies GL_MAP_UNSYNCHRONIZED_BIT to allow driver to fail (return
* NULL) if buffer is unavailable for immediate mapping.
*
* Does GL_MAP_INVALIDATE_RANGE_BIT do this? It seems so, but it
* would require more book-keeping in the driver than seems necessary
* at this point.
*
* Does GL_MAP_INVALDIATE_BUFFER_BIT do this? Not really -- we don't
* want to provoke the driver to throw away the old storage, we will
* respect the contents of already referenced data.
*/
#define MESA_MAP_NOWAIT_BIT 0x0040
#endif
/**
* Device driver function table.
* Core Mesa uses these function pointers to call into device drivers.
@ -785,6 +801,16 @@ struct dd_function_table {
void * (*MapBuffer)( GLcontext *ctx, GLenum target, GLenum access,
struct gl_buffer_object *obj );
/* May return NULL if MESA_MAP_NOWAIT_BIT is set in access:
*/
void * (*MapBufferRange)( GLcontext *ctx, GLenum target,
GLintptr offset, GLsizeiptr length, GLbitfield access,
struct gl_buffer_object *obj);
void (*FlushMappedBufferRange) (GLcontext *ctx, GLenum target,
GLintptr offset, GLsizeiptr length,
struct gl_buffer_object *obj);
GLboolean (*UnmapBuffer)( GLcontext *ctx, GLenum target,
struct gl_buffer_object *obj );
/*@}*/
@ -954,6 +980,12 @@ struct dd_function_table {
GLuint NeedFlush;
GLuint SaveNeedFlush;
/* Called prior to any of the GLvertexformat functions being
* called. Paired with Driver.FlushVertices().
*/
void (*BeginVertices)( GLcontext *ctx );
/**
* If inside glBegin()/glEnd(), it should ASSERT(0). Otherwise, if
* FLUSH_STORED_VERTICES bit in \p flags is set flushes any buffered

View file

@ -23,6 +23,7 @@
*/
#include "mtypes.h"
#include "colormac.h"
#include "context.h"
#include "hash.h"
#include "imports.h"
@ -274,6 +275,27 @@ write_texture_image(struct gl_texture_object *texObj)
case MESA_FORMAT_ARGB8888:
write_ppm(s, img->Data, img->Width, img->Height, 4, 2, 1, 0);
break;
case MESA_FORMAT_RGB888:
write_ppm(s, img->Data, img->Width, img->Height, 3, 2, 1, 0);
break;
case MESA_FORMAT_RGB565:
{
GLubyte *buf2 = (GLubyte *) _mesa_malloc(img->Width * img->Height * 3);
GLint i;
for (i = 0; i < img->Width * img->Height; i++) {
GLint r, g, b;
GLushort s = ((GLushort *) img->Data)[i];
r = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) );
g = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) | ((s >> 9) & 0x3) );
b = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) );
buf2[i*3+1] = r;
buf2[i*3+2] = g;
buf2[i*3+3] = b;
}
write_ppm(s, buf2, img->Width, img->Height, 3, 2, 1, 0);
_mesa_free(buf2);
}
break;
default:
printf("XXXX unsupported mesa tex format %d in %s\n",
img->TexFormat->MesaFormat, __FUNCTION__);

View file

@ -602,11 +602,6 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
ctx->Texture.SharedPalette = state;
break;
case GL_STENCIL_TEST:
if (state && ctx->DrawBuffer->Visual.stencilBits == 0) {
_mesa_warning(ctx,
"glEnable(GL_STENCIL_TEST) but no stencil buffer");
return;
}
if (ctx->Stencil.Enabled == state)
return;
FLUSH_VERTICES(ctx, _NEW_STENCIL);

View file

@ -285,14 +285,11 @@ typedef enum
BUFFER_BACK_LEFT,
BUFFER_FRONT_RIGHT,
BUFFER_BACK_RIGHT,
/* optional aux buffers */
BUFFER_AUX0,
BUFFER_AUX1,
BUFFER_AUX2,
BUFFER_AUX3,
BUFFER_DEPTH,
BUFFER_STENCIL,
BUFFER_ACCUM,
/* optional aux buffer */
BUFFER_AUX0,
/* generic renderbuffers */
BUFFER_COLOR0,
BUFFER_COLOR1,
@ -336,9 +333,6 @@ typedef enum
BUFFER_BIT_FRONT_RIGHT | \
BUFFER_BIT_BACK_RIGHT | \
BUFFER_BIT_AUX0 | \
BUFFER_BIT_AUX1 | \
BUFFER_BIT_AUX2 | \
BUFFER_BIT_AUX3 | \
BUFFER_BIT_COLOR0 | \
BUFFER_BIT_COLOR1 | \
BUFFER_BIT_COLOR2 | \
@ -1018,6 +1012,7 @@ struct gl_stencil_attrib
GLboolean Enabled; /**< Enabled flag */
GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */
GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */
GLboolean _Enabled; /**< Enabled and stencil buffer present */
GLboolean _TestTwoSide;
GLubyte _BackFace; /**< Current back stencil state (1 or 2) */
GLenum Function[3]; /**< Stencil function */
@ -1446,14 +1441,20 @@ struct gl_texture_attrib
GLboolean SharedPalette;
struct gl_color_table Palette;
/** Per-unit flags */
/*@{*/
GLbitfield _EnabledUnits; /**< one bit set for each really-enabled unit */
GLbitfield _EnabledCoordUnits; /**< one bit per enabled coordinate unit */
GLbitfield _GenFlags; /**< for texgen */
GLbitfield _TexGenEnabled; /**< Mask of ENABLE_TEXGEN flags */
GLbitfield _TexMatEnabled; /**< Mask of ENABLE_TEXMAT flags */
/*@}*/
/** Texture units/samplers used by vertex or fragment texturing */
GLbitfield _EnabledUnits;
/** Texture coord units/sets used for fragment texturing */
GLbitfield _EnabledCoordUnits;
/** Texture coord units that have texgen enabled */
GLbitfield _TexGenEnabled;
/** Texture coord units that have non-identity matrices */
GLbitfield _TexMatEnabled;
/** Bitwise-OR of all Texture.Unit[i]._GenFlags */
GLbitfield _GenFlags;
};

View file

@ -490,7 +490,7 @@ _mesa_update_state_locked( GLcontext *ctx )
if (new_state & _NEW_LIGHT)
_mesa_update_lighting( ctx );
if (new_state & _NEW_STENCIL)
if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
_mesa_update_stencil( ctx );
#if FEATURE_pixel_transfer

View file

@ -536,7 +536,11 @@ _mesa_update_stencil(GLcontext *ctx)
{
const GLint face = ctx->Stencil._BackFace;
ctx->Stencil._TestTwoSide =
ctx->Stencil._Enabled = (ctx->Stencil.Enabled &&
ctx->DrawBuffer->Visual.stencilBits > 0);
ctx->Stencil._TestTwoSide =
ctx->Stencil._Enabled &&
(ctx->Stencil.Function[0] != ctx->Stencil.Function[face] ||
ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[face] ||
ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[face] ||

View file

@ -384,28 +384,6 @@ update_texture_compare_function(GLcontext *ctx,
}
/**
* Helper function for determining which texture object (1D, 2D, cube, etc)
* should actually be used.
*/
static void
texture_override(GLcontext *ctx,
struct gl_texture_unit *texUnit, GLbitfield enableBits,
struct gl_texture_object *texObj, GLuint textureBit)
{
if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) {
if (!texObj->_Complete) {
_mesa_test_texobj_completeness(ctx, texObj);
}
if (texObj->_Complete) {
texUnit->_ReallyEnabled = textureBit;
texUnit->_Current = texObj;
update_texture_compare_function(ctx, texObj);
}
}
}
/**
* Examine texture unit's combine/env state to update derived state.
*/
@ -514,6 +492,7 @@ update_texture_state( GLcontext *ctx )
GLuint unit;
struct gl_fragment_program *fprog = NULL;
struct gl_vertex_program *vprog = NULL;
GLbitfield enabledFragUnits = 0x0;
if (ctx->Shader.CurrentProgram &&
ctx->Shader.CurrentProgram->LinkStatus) {
@ -545,44 +524,60 @@ update_texture_state( GLcontext *ctx )
*/
for (unit = 0; unit < ctx->Const.MaxTextureImageUnits; unit++) {
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLbitfield enableBits;
GLbitfield enabledVertTargets = 0x0;
GLbitfield enabledFragTargets = 0x0;
GLbitfield enabledTargets = 0x0;
GLuint texIndex;
texUnit->_Current = NULL;
texUnit->_ReallyEnabled = 0x0;
/* Get the bitmask of texture target enables.
* enableBits will be a mask of the TEXTURE_*_BIT flags indicating
* which texture targets are enabled (fixed function) or referenced
* by a fragment shader/program. When multiple flags are set, we'll
* settle on the one with highest priority (see texture_override below).
* settle on the one with highest priority (see below).
*/
enableBits = 0x0;
if (vprog) {
enableBits |= vprog->Base.TexturesUsed[unit];
enabledVertTargets |= vprog->Base.TexturesUsed[unit];
}
if (fprog) {
enableBits |= fprog->Base.TexturesUsed[unit];
enabledFragTargets |= fprog->Base.TexturesUsed[unit];
}
else {
/* fixed-function fragment program */
enableBits |= texUnit->Enabled;
enabledFragTargets |= texUnit->Enabled;
}
if (enableBits == 0x0)
continue;
enabledTargets = enabledVertTargets | enabledFragTargets;
/* Look for the highest-priority texture target that's enabled and
* complete. That's the one we'll use for texturing. If we're using
* a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
texUnit->_ReallyEnabled = 0x0;
if (enabledTargets == 0x0) {
/* neither vertex nor fragment processing uses this unit */
continue;
}
/* Look for the highest priority texture target that's enabled (or used
* by the vert/frag shaders) and "complete". That's the one we'll use
* for texturing. If we're using vert/frag program we're guaranteed
* that bitcount(enabledBits) <= 1.
* Note that the TEXTURE_x_INDEX values are in high to low priority.
*/
for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
texture_override(ctx, texUnit, enableBits,
texUnit->CurrentTex[texIndex], 1 << texIndex);
if (enabledTargets & (1 << texIndex)) {
struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
if (!texObj->_Complete) {
_mesa_test_texobj_completeness(ctx, texObj);
}
if (texObj->_Complete) {
texUnit->_ReallyEnabled = 1 << texIndex;
_mesa_reference_texobj(&texUnit->_Current, texObj);
break;
}
}
}
if (!texUnit->_ReallyEnabled) {
_mesa_reference_texobj(&texUnit->_Current, NULL);
continue;
}
@ -590,7 +585,11 @@ update_texture_state( GLcontext *ctx )
ctx->Texture._EnabledUnits |= (1 << unit);
if (enabledFragTargets)
enabledFragUnits |= (1 << unit);
update_tex_combine(ctx, texUnit);
update_texture_compare_function(ctx, texUnit->_Current);
}
@ -601,7 +600,7 @@ update_texture_state( GLcontext *ctx )
= (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
}
else {
ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
ctx->Texture._EnabledCoordUnits = enabledFragUnits;
}
/* Setup texgen for those texture coordinate sets that are in use */

View file

@ -54,9 +54,12 @@
ASSERT( tnl->Current ); \
ASSERT( tnl->SwapCount < NUM_VERTEX_FORMAT_ENTRIES ); \
ASSERT( tmp_offset >= 0 ); \
\
/* Save the swapped function's dispatch entry so it can be */ \
/* restored later. */ \
\
if (tnl->SwapCount == 0) \
ctx->Driver.BeginVertices( ctx ); \
\
/* Save the swapped function's dispatch entry so it can be */ \
/* restored later. */ \
tnl->Swapped[tnl->SwapCount].location = & (((_glapi_proc *)ctx->Exec)[tmp_offset]); \
tnl->Swapped[tnl->SwapCount].function = (_glapi_proc)TAG(FUNC); \
tnl->SwapCount++; \

View file

@ -91,7 +91,6 @@ MATH_SOURCES = \
math/m_vector.c
MATH_XFORM_SOURCES = \
$(MATH_SOURCES) \
math/m_xform.c
SWRAST_SOURCES = \
@ -165,11 +164,6 @@ VBO_SOURCES = \
vbo/vbo_save_draw.c \
vbo/vbo_save_loopback.c
VF_SOURCES = \
vf/vf.c \
vf/vf_generic.c \
vf/vf_sse.c
STATETRACKER_SOURCES = \
state_tracker/st_atom.c \
state_tracker/st_atom_blend.c \
@ -311,6 +305,7 @@ COMMON_DRIVER_SOURCES = \
# Sources for building non-Gallium drivers
MESA_SOURCES = \
$(MAIN_SOURCES) \
$(MATH_SOURCES) \
$(MATH_XFORM_SOURCES) \
$(VBO_SOURCES) \
$(TNL_SOURCES) \

View file

@ -98,9 +98,11 @@ update_depth_stencil_alpha(struct st_context *st)
memset(dsa, 0, sizeof(*dsa));
dsa->depth.enabled = ctx->Depth.Test;
dsa->depth.writemask = ctx->Depth.Mask;
dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func);
if (ctx->Depth.Test && ctx->DrawBuffer->Visual.depthBits > 0) {
dsa->depth.enabled = 1;
dsa->depth.writemask = ctx->Depth.Mask;
dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func);
}
if (ctx->Query.CurrentOcclusionObject &&
ctx->Query.CurrentOcclusionObject->Active)

View file

@ -206,8 +206,40 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
}
/**
* Called via glMapBufferARB().
* Called via glMapBufferRange().
*/
static void *
st_bufferobj_map_range(GLcontext *ctx, GLenum target,
GLintptr offset, GLsizeiptr length, GLbitfield access,
struct gl_buffer_object *obj)
{
struct pipe_context *pipe = st_context(ctx)->pipe;
struct st_buffer_object *st_obj = st_buffer_object(obj);
GLuint flags = 0;
if (access & GL_MAP_WRITE_BIT)
flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
if (access & GL_MAP_READ_BIT)
flags |= PIPE_BUFFER_USAGE_CPU_READ;
/* ... other flags ...
*/
if (access & MESA_MAP_NOWAIT_BIT)
flags |= PIPE_BUFFER_USAGE_DONTBLOCK;
obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags);
return obj->Pointer;
}
/**
* Called via glUnmapBufferARB().
*/
static GLboolean
st_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
@ -230,5 +262,6 @@ st_init_bufferobject_functions(struct dd_function_table *functions)
functions->BufferSubData = st_bufferobj_subdata;
functions->GetBufferSubData = st_bufferobj_get_subdata;
functions->MapBuffer = st_bufferobj_map;
functions->MapBufferRange = st_bufferobj_map_range;
functions->UnmapBuffer = st_bufferobj_unmap;
}

View file

@ -317,10 +317,7 @@ _swrast_Clear(GLcontext *ctx, GLbitfield buffers)
BUFFER_BIT_DEPTH |
BUFFER_BIT_STENCIL |
BUFFER_BIT_ACCUM |
BUFFER_BIT_AUX0 |
BUFFER_BIT_AUX1 |
BUFFER_BIT_AUX2 |
BUFFER_BIT_AUX3;
BUFFER_BIT_AUX0;
assert((buffers & (~legalBits)) == 0);
}
#endif

View file

@ -61,7 +61,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
if (ctx->Depth.Test) rasterMask |= DEPTH_BIT;
if (swrast->_FogEnabled) rasterMask |= FOG_BIT;
if (ctx->Scissor.Enabled) rasterMask |= CLIP_BIT;
if (ctx->Stencil.Enabled) rasterMask |= STENCIL_BIT;
if (ctx->Stencil._Enabled) rasterMask |= STENCIL_BIT;
if (ctx->Visual.rgbMode) {
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
if (colorMask != 0xffffffff) rasterMask |= MASKING_BIT;

View file

@ -846,11 +846,11 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
}
/* Stencil and Z testing */
if (ctx->Depth.Test || ctx->Stencil.Enabled) {
if (ctx->Stencil._Enabled || ctx->Depth.Test) {
if (!(span->arrayMask & SPAN_Z))
_swrast_span_interpolate_z(ctx, span);
if (ctx->Stencil.Enabled) {
if (ctx->Stencil._Enabled) {
if (!_swrast_stencil_and_ztest_span(ctx, span)) {
span->arrayMask = origArrayMask;
return;
@ -1211,7 +1211,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
_swrast_exec_fragment_shader(ctx, span);
}
}
else if (ctx->Texture._EnabledUnits) {
else if (ctx->Texture._EnabledCoordUnits) {
/* conventional texturing */
#if CHAN_BITS == 32
@ -1250,7 +1250,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
void * const origRgba = span->array->rgba;
const GLboolean shader = (ctx->FragmentProgram._Current
|| ctx->ATIFragmentShader._Enabled);
const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits;
struct gl_framebuffer *fb = ctx->DrawBuffer;
/*
@ -1317,11 +1317,11 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
}
/* Stencil and Z testing */
if (ctx->Stencil.Enabled || ctx->Depth.Test) {
if (ctx->Stencil._Enabled || ctx->Depth.Test) {
if (!(span->arrayMask & SPAN_Z))
_swrast_span_interpolate_z(ctx, span);
if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) {
if (ctx->Stencil._Enabled) {
/* Combined Z/stencil tests */
if (!_swrast_stencil_and_ztest_span(ctx, span)) {
/* all fragments failed test */

View file

@ -266,7 +266,7 @@ affine_span(GLcontext *ctx, SWspan *span,
struct affine_info *info)
{
GLchan sample[4]; /* the filtered texture sample */
const GLuint texEnableSave = ctx->Texture._EnabledUnits;
const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits;
/* Instead of defining a function for each mode, a test is done
* between the outer and inner loops. This is to reduce code size
@ -397,7 +397,7 @@ affine_span(GLcontext *ctx, SWspan *span,
GLchan *dest = span->array->rgba[0];
/* Disable tex units so they're not re-applied in swrast_write_rgba_span */
ctx->Texture._EnabledUnits = 0x0;
ctx->Texture._EnabledCoordUnits = 0x0;
span->intTex[0] -= FIXED_HALF;
span->intTex[1] -= FIXED_HALF;
@ -504,7 +504,7 @@ affine_span(GLcontext *ctx, SWspan *span,
_swrast_write_rgba_span(ctx, span);
/* re-enable texture units */
ctx->Texture._EnabledUnits = texEnableSave;
ctx->Texture._EnabledCoordUnits = texEnableSave;
#undef SPAN_NEAREST
#undef SPAN_LINEAR
@ -664,8 +664,8 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
GLfloat tex_coord[3], tex_step[3];
GLchan *dest = span->array->rgba[0];
const GLuint savedTexEnable = ctx->Texture._EnabledUnits;
ctx->Texture._EnabledUnits = 0;
const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits;
ctx->Texture._EnabledCoordUnits = 0;
tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0] * (info->smask + 1);
tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1);
@ -778,7 +778,7 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
#undef SPAN_LINEAR
/* restore state */
ctx->Texture._EnabledUnits = savedTexEnable;
ctx->Texture._EnabledCoordUnits = texEnableSave;
}
@ -1022,7 +1022,7 @@ _swrast_choose_triangle( GLcontext *ctx )
ctx->Depth.Test &&
ctx->Depth.Mask == GL_FALSE &&
ctx->Depth.Func == GL_LESS &&
!ctx->Stencil.Enabled) {
!ctx->Stencil._Enabled) {
if ((rgbmode &&
ctx->Color.ColorMask[0] == 0 &&
ctx->Color.ColorMask[1] == 0 &&

View file

@ -57,6 +57,7 @@ void vbo_exec_init( GLcontext *ctx )
ctx->Driver.NeedFlush = 0;
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
ctx->Driver.BeginVertices = vbo_exec_BeginVertices;
ctx->Driver.FlushVertices = vbo_exec_FlushVertices;
vbo_exec_invalidate_state( ctx, ~0 );

View file

@ -43,7 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Wierd implementation stuff:
*/
#define VBO_VERT_BUFFER_SIZE (1024*16) /* dwords == 64k */
#define VBO_VERT_BUFFER_SIZE (1024*64) /* bytes */
#define VBO_MAX_ATTR_CODEGEN 16
#define ERROR_ATTRIB 16
@ -78,14 +78,15 @@ struct vbo_exec_context
struct {
struct gl_buffer_object *bufferobj;
GLubyte *buffer_map;
GLuint vertex_size;
GLuint vertex_size; /* in dwords */
struct _mesa_prim prim[VBO_MAX_PRIM];
GLuint prim_count;
GLfloat *vbptr; /* cursor, points into buffer */
GLfloat *buffer_map;
GLfloat *buffer_ptr; /* cursor, points into buffer */
GLuint buffer_used; /* in bytes */
GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */
GLuint vert_count;
@ -140,6 +141,9 @@ struct vbo_exec_context
void vbo_exec_init( GLcontext *ctx );
void vbo_exec_destroy( GLcontext *ctx );
void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state );
void vbo_exec_FlushVertices_internal( GLcontext *ctx, GLboolean unmap );
void vbo_exec_BeginVertices( GLcontext *ctx );
void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags );
@ -151,7 +155,8 @@ void vbo_exec_array_destroy( struct vbo_exec_context *exec );
void vbo_exec_vtx_init( struct vbo_exec_context *exec );
void vbo_exec_vtx_destroy( struct vbo_exec_context *exec );
void vbo_exec_vtx_flush( struct vbo_exec_context *exec );
void vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap );
void vbo_exec_vtx_map( struct vbo_exec_context *exec );
void vbo_exec_vtx_wrap( struct vbo_exec_context *exec );
void vbo_exec_eval_update( struct vbo_exec_context *exec );

View file

@ -62,7 +62,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
if (exec->vtx.prim_count == 0) {
exec->vtx.copied.nr = 0;
exec->vtx.vert_count = 0;
exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
}
else {
GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin;
@ -80,7 +80,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
/* Execute the buffer and save copied vertices.
*/
if (exec->vtx.vert_count)
vbo_exec_vtx_flush( exec );
vbo_exec_vtx_flush( exec, GL_FALSE );
else {
exec->vtx.prim_count = 0;
exec->vtx.copied.nr = 0;
@ -121,9 +121,9 @@ void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )
assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr);
for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
_mesa_memcpy( exec->vtx.vbptr, data,
_mesa_memcpy( exec->vtx.buffer_ptr, data,
exec->vtx.vertex_size * sizeof(GLfloat));
exec->vtx.vbptr += exec->vtx.vertex_size;
exec->vtx.buffer_ptr += exec->vtx.vertex_size;
data += exec->vtx.vertex_size;
exec->vtx.vert_count++;
}
@ -251,9 +251,10 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,
exec->vtx.attrsz[attr] = newsz;
exec->vtx.vertex_size += newsz - oldsz;
exec->vtx.max_vert = VBO_VERT_BUFFER_SIZE / exec->vtx.vertex_size;
exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /
(exec->vtx.vertex_size * sizeof(GLfloat)));
exec->vtx.vert_count = 0;
exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
/* Recalculate all the attrptr[] values
@ -279,10 +280,10 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,
if (exec->vtx.copied.nr)
{
GLfloat *data = exec->vtx.copied.buffer;
GLfloat *dest = exec->vtx.vbptr;
GLfloat *dest = exec->vtx.buffer_ptr;
GLuint j;
assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map);
assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);
for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
@ -308,7 +309,7 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,
}
}
exec->vtx.vbptr = dest;
exec->vtx.buffer_ptr = dest;
exec->vtx.vert_count += exec->vtx.copied.nr;
exec->vtx.copied.nr = 0;
}
@ -373,9 +374,9 @@ do { \
GLuint i; \
\
for (i = 0; i < exec->vtx.vertex_size; i++) \
exec->vtx.vbptr[i] = exec->vtx.vertex[i]; \
exec->vtx.buffer_ptr[i] = exec->vtx.vertex[i]; \
\
exec->vtx.vbptr += exec->vtx.vertex_size; \
exec->vtx.buffer_ptr += exec->vtx.vertex_size; \
exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \
\
if (++exec->vtx.vert_count >= exec->vtx.max_vert) \
@ -532,7 +533,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
* begin/end pairs.
*/
if (exec->vtx.vertex_size && !exec->vtx.attrsz[0])
vbo_exec_FlushVertices( ctx, ~0 );
vbo_exec_FlushVertices_internal( ctx, GL_FALSE );
i = exec->vtx.prim_count++;
exec->vtx.prim[i].mode = mode;
@ -566,7 +567,7 @@ static void GLAPIENTRY vbo_exec_End( void )
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
if (exec->vtx.prim_count == VBO_MAX_PRIM)
vbo_exec_vtx_flush( exec );
vbo_exec_vtx_flush( exec, GL_FALSE );
}
else
_mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
@ -672,23 +673,19 @@ void vbo_use_buffer_objects(GLcontext *ctx)
*/
GLuint bufName = 0xaabbccdd;
GLenum target = GL_ARRAY_BUFFER_ARB;
GLenum access = GL_READ_WRITE_ARB;
GLenum usage = GL_STREAM_DRAW_ARB;
GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat);
GLsizei size = VBO_VERT_BUFFER_SIZE;
/* Make sure this func is only used once */
assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj);
if (exec->vtx.buffer_map) {
_mesa_align_free(exec->vtx.buffer_map);
exec->vtx.buffer_map = NULL;
}
/* Allocate a real buffer object now */
exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
/* and map it */
exec->vtx.buffer_map
= ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
}
@ -708,7 +705,8 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
ctx->Array.NullBufferObj);
ASSERT(!exec->vtx.buffer_map);
exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64);
exec->vtx.buffer_map = (GLfloat *)ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE, 64);
vbo_exec_vtxfmt_init( exec );
/* Hook our functions into the dispatch table.
@ -747,22 +745,45 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
}
}
void vbo_exec_BeginVertices( GLcontext *ctx )
{
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
if (0) _mesa_printf("%s\n", __FUNCTION__);
vbo_exec_vtx_map( exec );
}
void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags )
void vbo_exec_FlushVertices_internal( GLcontext *ctx, GLboolean unmap )
{
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)
return;
if (exec->vtx.vert_count) {
vbo_exec_vtx_flush( exec );
if (exec->vtx.vert_count || unmap) {
vbo_exec_vtx_flush( exec, unmap );
}
if (exec->vtx.vertex_size) {
vbo_exec_copy_to_current( exec );
reset_attrfv( exec );
}
}
void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags )
{
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
if (0) _mesa_printf("%s\n", __FUNCTION__);
if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__);
return;
}
vbo_exec_FlushVertices_internal( ctx, GL_TRUE );
/* Need to do this to ensure BeginVertices gets called again:
*/
_mesa_restore_exec_vtxfmt( ctx );
exec->ctx->Driver.NeedFlush = 0;
}

View file

@ -31,6 +31,7 @@
#include "main/api_validate.h"
#include "main/api_noop.h"
#include "main/varray.h"
#include "main/bufferobj.h"
#include "glapi/dispatch.h"
#include "vbo_context.h"
@ -291,6 +292,47 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
prim[0].indexed = 0;
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count - 1 );
#if 0
{
int i;
_mesa_printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
mode, start, count);
for (i = 0; i < 32; i++) {
GLuint bufName = exec->array.inputs[i]->BufferObj->Name;
GLint stride = exec->array.inputs[i]->Stride;
_mesa_printf("attr %2d: size %d stride %d enabled %d "
"ptr %p Bufobj %u\n",
i,
exec->array.inputs[i]->Size,
stride,
/*exec->array.inputs[i]->Enabled,*/
exec->array.legacy_array[i]->Enabled,
exec->array.inputs[i]->Ptr,
bufName);
if (bufName) {
struct gl_buffer_object *buf = _mesa_lookup_bufferobj(ctx, bufName);
GLubyte *p = ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB,
GL_READ_ONLY_ARB, buf);
int offset = (int) exec->array.inputs[i]->Ptr;
float *f = (float *) (p + offset);
int *k = (int *) f;
int i;
int n = (count * stride) / 4;
if (n > 32)
n = 32;
_mesa_printf(" Data at offset %d:\n", offset);
for (i = 0; i < n; i++) {
_mesa_printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]);
}
ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, buf);
}
}
}
#endif
}

View file

@ -70,7 +70,7 @@ static GLuint vbo_copy_vertices( struct vbo_exec_context *exec )
GLuint ovf, i;
GLuint sz = exec->vtx.vertex_size;
GLfloat *dst = exec->vtx.copied.buffer;
GLfloat *src = ((GLfloat *)exec->vtx.buffer_map +
GLfloat *src = (exec->vtx.buffer_map +
exec->vtx.prim[exec->vtx.prim_count-1].start *
exec->vtx.vertex_size);
@ -147,7 +147,7 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )
struct vbo_exec_context *exec = &vbo->exec;
struct gl_client_array *arrays = exec->vtx.arrays;
GLuint count = exec->vtx.vert_count;
GLubyte *data = exec->vtx.buffer_map;
GLubyte *data = (GLubyte *)exec->vtx.buffer_map;
const GLuint *map;
GLuint attr;
GLbitfield varying_inputs = 0x0;
@ -234,10 +234,78 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )
}
static void vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
{
GLenum target = GL_ARRAY_BUFFER_ARB;
if (exec->vtx.bufferobj->Name) {
GLcontext *ctx = exec->ctx;
exec->vtx.buffer_used += (exec->vtx.buffer_ptr -
exec->vtx.buffer_map) * sizeof(float);
ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj);
exec->vtx.buffer_map = NULL;
exec->vtx.buffer_ptr = NULL;
exec->vtx.max_vert = 0;
}
}
void vbo_exec_vtx_map( struct vbo_exec_context *exec )
{
GLcontext *ctx = exec->ctx;
GLenum target = GL_ARRAY_BUFFER_ARB;
GLenum access = GL_READ_WRITE_ARB;
GLenum usage = GL_STREAM_DRAW_ARB;
if (exec->vtx.bufferobj->Name == 0)
return;
if (exec->vtx.buffer_map != NULL) {
assert(0);
exec->vtx.buffer_map = NULL;
}
if (VBO_VERT_BUFFER_SIZE > exec->vtx.buffer_used + 1024 &&
ctx->Driver.MapBufferRange)
{
exec->vtx.buffer_map =
(GLfloat *)ctx->Driver.MapBufferRange(ctx,
target,
exec->vtx.buffer_used,
(VBO_VERT_BUFFER_SIZE -
exec->vtx.buffer_used),
(GL_MAP_WRITE_BIT |
GL_MAP_INVALIDATE_RANGE_BIT |
GL_MAP_UNSYNCHRONIZED_BIT |
MESA_MAP_NOWAIT_BIT),
exec->vtx.bufferobj);
}
if (exec->vtx.buffer_map) {
exec->vtx.buffer_map += exec->vtx.buffer_used / sizeof(float);
}
else {
exec->vtx.buffer_used = 0;
ctx->Driver.BufferData(ctx, target,
VBO_VERT_BUFFER_SIZE,
NULL, usage, exec->vtx.bufferobj);
exec->vtx.buffer_map =
(GLfloat *)ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
}
if (0) _mesa_printf("map %d..\n", exec->vtx.buffer_used);
}
/**
* Execute the buffer and save copied verts.
*/
void vbo_exec_vtx_flush( struct vbo_exec_context *exec )
void vbo_exec_vtx_flush( struct vbo_exec_context *exec,
GLboolean unmap )
{
if (0)
vbo_exec_debug_verts( exec );
@ -250,25 +318,22 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec )
if (exec->vtx.copied.nr != exec->vtx.vert_count) {
GLcontext *ctx = exec->ctx;
GLenum target = GL_ARRAY_BUFFER_ARB;
GLenum access = GL_READ_WRITE_ARB;
GLenum usage = GL_STREAM_DRAW_ARB;
GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat);
/* Before the unmap (why?)
/* Before the update_state() as this may raise _NEW_ARRAY
* from _mesa_set_varying_vp_inputs().
*/
vbo_exec_bind_arrays( ctx );
if (ctx->NewState)
_mesa_update_state( ctx );
/* if using a real VBO, unmap it before drawing */
if (exec->vtx.bufferobj->Name) {
ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj);
exec->vtx.buffer_map = NULL;
vbo_exec_vtx_unmap( exec );
}
if (0) _mesa_printf("%s %d %d\n", __FUNCTION__, exec->vtx.prim_count,
exec->vtx.vert_count);
vbo_context(ctx)->draw_prims( ctx,
exec->vtx.inputs,
exec->vtx.prim,
@ -277,16 +342,31 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec )
0,
exec->vtx.vert_count - 1);
/* If using a real VBO, get new storage */
if (exec->vtx.bufferobj->Name) {
ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
exec->vtx.buffer_map =
ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
}
/* If using a real VBO, get new storage -- unless asked not to.
*/
if (exec->vtx.bufferobj->Name && !unmap) {
vbo_exec_vtx_map( exec );
}
}
}
/* May have to unmap explicitly if we didn't draw:
*/
if (unmap &&
exec->vtx.bufferobj->Name &&
exec->vtx.buffer_map) {
vbo_exec_vtx_unmap( exec );
}
if (unmap)
exec->vtx.max_vert = 0;
else
exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /
(exec->vtx.vertex_size * sizeof(GLfloat)));
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
exec->vtx.prim_count = 0;
exec->vtx.vert_count = 0;
exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
}

View file

@ -130,7 +130,7 @@ struct vbo_save_context {
struct vbo_save_vertex_store *vertex_store;
struct vbo_save_primitive_store *prim_store;
GLfloat *vbptr; /* cursor, points into buffer */
GLfloat *buffer_ptr; /* cursor, points into buffer */
GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current values */
GLfloat *attrptr[VBO_ATTRIB_MAX];
GLuint vert_count;

View file

@ -241,7 +241,7 @@ static void _save_reset_counters( GLcontext *ctx )
save->buffer = (save->vertex_store->buffer +
save->vertex_store->used);
assert(save->buffer == save->vbptr);
assert(save->buffer == save->buffer_ptr);
if (save->vertex_size)
save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
@ -343,7 +343,7 @@ static void _save_compile_vertex_list( GLcontext *ctx )
/* Allocate and map new store:
*/
save->vertex_store = alloc_vertex_store( ctx );
save->vbptr = map_vertex_store( ctx, save->vertex_store );
save->buffer_ptr = map_vertex_store( ctx, save->vertex_store );
}
if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
@ -414,9 +414,9 @@ static void _save_wrap_filled_vertex( GLcontext *ctx )
assert(save->max_vert - save->vert_count > save->copied.nr);
for (i = 0 ; i < save->copied.nr ; i++) {
_mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat));
_mesa_memcpy( save->buffer_ptr, data, save->vertex_size * sizeof(GLfloat));
data += save->vertex_size;
save->vbptr += save->vertex_size;
save->buffer_ptr += save->vertex_size;
save->vert_count++;
}
}
@ -550,7 +550,7 @@ static void _save_upgrade_vertex( GLcontext *ctx,
}
}
save->vbptr = dest;
save->buffer_ptr = dest;
save->vert_count += save->copied.nr;
}
}
@ -622,9 +622,9 @@ do { \
GLuint i; \
\
for (i = 0; i < save->vertex_size; i++) \
save->vbptr[i] = save->vertex[i]; \
save->buffer_ptr[i] = save->vertex[i]; \
\
save->vbptr += save->vertex_size; \
save->buffer_ptr += save->vertex_size; \
\
if (++save->vert_count >= save->max_vert) \
_save_wrap_filled_vertex( ctx ); \
@ -1035,7 +1035,7 @@ void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )
if (!save->vertex_store)
save->vertex_store = alloc_vertex_store( ctx );
save->vbptr = map_vertex_store( ctx, save->vertex_store );
save->buffer_ptr = map_vertex_store( ctx, save->vertex_store );
_save_reset_vertex( ctx );
_save_reset_counters( ctx );