Commit 12deb9e6 authored by Chia-I Wu's avatar Chia-I Wu

Merge remote branch 'origin/gallium-st-api-dri'

parents 162bc831 fe5f070e
......@@ -15,7 +15,9 @@ C_SOURCES = \
dri_context.c \
dri_screen.c \
dri_drawable.c \
dri_extensions.c
dri_extensions.c \
dri_st_api.c \
dri1.c
# $(TOP)/src/mesa/drivers/dri/common/utils.c \
$(TOP)/src/mesa/drivers/dri/common/vblank.c \
......
......@@ -18,6 +18,8 @@ if env['dri']:
'dri_drawable.c',
'dri_extensions.c',
'dri_screen.c',
'dri_st_api.c',
'dri1.c',
]
)
Export('st_dri')
This diff is collapsed.
/**************************************************************************
*
* 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>
*/
#ifndef DRI1_H
#define DRI1_H
#include "dri_context.h"
#include "dri_drawable.h"
#include "state_tracker/st_api.h"
#include "dri_util.h"
extern struct dri1_api *__dri1_api_hooks;
const __DRIconfig **
dri1_init_screen(__DRIscreen * sPriv);
void
dri1_flush_frontbuffer(struct dri_drawable *drawable,
struct pipe_texture *ptex);
void
dri1_allocate_textures(struct dri_drawable *drawable,
unsigned width, unsigned height,
unsigned mask);
void dri1_swap_buffers(__DRIdrawable * dPriv);
void
dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
void
dri1_swap_fences_clear(struct dri_drawable *drawable);
#endif /* DRI1_H */
......@@ -30,25 +30,24 @@
*/
#include "dri_screen.h"
#include "dri_drawable.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/dri1_api.h"
#include "state_tracker/st_public.h"
#include "pipe/p_context.h"
#include "dri_context.h"
#include "dri_st_api.h"
#include "dri1.h"
#include "pipe/p_context.h"
#include "util/u_memory.h"
GLboolean
dri_create_context(const __GLcontextModes * visual,
__DRIcontext * cPriv, void *sharedContextPrivate)
{
struct st_api *stapi = dri_get_st_api();
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct dri_context *ctx = NULL;
struct st_context *st_share = NULL;
struct st_context_iface *st_share = NULL;
struct st_visual stvis;
if (sharedContextPrivate) {
st_share = ((struct dri_context *)sharedContextPrivate)->st;
......@@ -62,21 +61,15 @@ dri_create_context(const __GLcontextModes * visual,
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
ctx->lock = screen->drmLock;
ctx->d_stamp = -1;
ctx->r_stamp = -1;
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache, sPriv->myNum, "dri");
ctx->pipe = screen->pipe_screen->context_create( screen->pipe_screen,
ctx );
if (ctx->pipe == NULL)
goto fail;
ctx->st = st_create_context(ctx->pipe, visual, st_share);
dri_fill_st_visual(&stvis, screen, visual);
ctx->st = stapi->create_context(stapi, screen->smapi, &stvis, st_share);
if (ctx->st == NULL)
goto fail;
ctx->st->st_manager_private = (void *) ctx;
dri_init_extensions(ctx);
......@@ -84,10 +77,7 @@ dri_create_context(const __GLcontextModes * visual,
fail:
if (ctx && ctx->st)
st_destroy_context(ctx->st);
if (ctx && ctx->pipe)
ctx->pipe->destroy(ctx->pipe);
ctx->st->destroy(ctx->st);
FREE(ctx);
return FALSE;
......@@ -109,11 +99,8 @@ dri_destroy_context(__DRIcontext * cPriv)
* to avoid having to add code elsewhere to cope with flushing a
* partially destroyed context.
*/
st_flush(ctx->st, 0, NULL);
/* Also frees ctx->pipe?
*/
st_destroy_context(ctx->st);
ctx->st->flush(ctx->st, 0, NULL);
ctx->st->destroy(ctx->st);
FREE(ctx);
}
......@@ -121,14 +108,16 @@ dri_destroy_context(__DRIcontext * cPriv)
GLboolean
dri_unbind_context(__DRIcontext * cPriv)
{
struct st_api *stapi = dri_get_st_api();
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
if (--ctx->bind_count == 0) {
if (ctx->st && ctx->st == st_get_current()) {
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
st_make_current(NULL, NULL, NULL, NULL);
}
if (ctx->st == stapi->get_current(stapi)) {
ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
stapi->make_current(stapi, NULL, NULL, NULL);
}
}
}
......@@ -140,83 +129,47 @@ dri_make_current(__DRIcontext * cPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv)
{
struct st_api *stapi = dri_get_st_api();
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
struct dri_drawable *draw = dri_drawable(driDrawPriv);
struct dri_drawable *read = dri_drawable(driReadPriv);
struct st_context *old_st = st_get_current();
struct st_context_iface *old_st;
old_st = stapi->get_current(stapi);
if (old_st && old_st != ctx->st)
st_flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
ctx->st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
++ctx->bind_count;
if (ctx->dPriv != driDrawPriv) {
ctx->dPriv = driDrawPriv;
ctx->d_stamp = driDrawPriv->lastStamp - 1;
draw->texture_stamp = driDrawPriv->lastStamp - 1;
}
if (ctx->rPriv != driReadPriv) {
ctx->rPriv = driReadPriv;
ctx->r_stamp = driReadPriv->lastStamp - 1;
read->texture_stamp = driReadPriv->lastStamp - 1;
}
/* DRI co-state tracker currently overrides flush_frontbuffer.
* When this is fixed, will need to pass the drawable in the
* fourth parameter here so that when Mesa calls
* flush_frontbuffer directly (in front-buffer rendering), it
* will have access to the drawable argument:
*/
st_make_current(ctx->st, draw->stfb, read->stfb, ctx);
if (__dri1_api_hooks) {
dri1_update_drawables(ctx, draw, read);
} else {
dri_update_buffer(ctx->pipe->screen,
ctx->pipe->priv);
}
} else {
st_make_current(NULL, NULL, NULL, NULL);
stapi->make_current(stapi, ctx->st, draw->stfb, read->stfb);
}
else {
stapi->make_current(stapi, NULL, NULL, NULL);
}
return GL_TRUE;
}
static void
st_dri_lock(struct pipe_context *pipe)
{
dri_lock((struct dri_context *)pipe->priv);
}
static void
st_dri_unlock(struct pipe_context *pipe)
{
dri_unlock((struct dri_context *)pipe->priv);
}
static boolean
st_dri_is_locked(struct pipe_context *pipe)
struct dri_context *
dri_get_current(void)
{
return ((struct dri_context *)pipe->priv)->isLocked;
}
struct st_api *stapi = dri_get_st_api();
struct st_context_iface *st;
static boolean
st_dri_lost_lock(struct pipe_context *pipe)
{
return ((struct dri_context *)pipe->priv)->wsLostLock;
}
st = stapi->get_current(stapi);
static void
st_dri_clear_lost_lock(struct pipe_context *pipe)
{
((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
return (struct dri_context *) (st) ? st->st_manager_private : NULL;
}
struct dri1_api_lock_funcs dri1_lf = {
.lock = st_dri_lock,
.unlock = st_dri_unlock,
.is_locked = st_dri_is_locked,
.is_lock_lost = st_dri_lost_lock,
.clear_lost_lock = st_dri_clear_lost_lock
};
/* vim: set sw=3 ts=8 sts=3 expandtab: */
......@@ -51,9 +51,6 @@ struct dri_context
driOptionCache optionCache;
unsigned int d_stamp;
unsigned int r_stamp;
drmLock *lock;
boolean isLocked;
boolean stLostLock;
......@@ -62,8 +59,7 @@ struct dri_context
unsigned int bind_count;
/* gallium */
struct st_context *st;
struct pipe_context *pipe;
struct st_context_iface *st;
};
static INLINE struct dri_context *
......@@ -72,33 +68,9 @@ dri_context(__DRIcontext * driContextPriv)
return (struct dri_context *)driContextPriv->driverPrivate;
}
static INLINE void
dri_lock(struct dri_context *ctx)
{
drm_context_t hw_context = ctx->cPriv->hHWContext;
char ret = 0;
DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
if (ret) {
drmGetLock(ctx->sPriv->fd, hw_context, 0);
ctx->stLostLock = TRUE;
ctx->wsLostLock = TRUE;
}
ctx->isLocked = TRUE;
}
static INLINE void
dri_unlock(struct dri_context *ctx)
{
ctx->isLocked = FALSE;
DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
}
/***********************************************************************
* dri_context.c
*/
extern struct dri1_api_lock_funcs dri1_lf;
void dri_destroy_context(__DRIcontext * driContextPriv);
boolean dri_unbind_context(__DRIcontext * driContextPriv);
......@@ -108,6 +80,9 @@ dri_make_current(__DRIcontext * driContextPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv);
struct dri_context *
dri_get_current(void);
boolean
dri_create_context(const __GLcontextModes * visual,
__DRIcontext * driContextPriv,
......
......@@ -29,6 +29,8 @@
#define DRI_DRAWABLE_H
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "state_tracker/st_api.h"
struct pipe_surface;
struct pipe_fence_handle;
......@@ -44,26 +46,26 @@ struct dri_drawable
__DRIdrawable *dPriv;
__DRIscreen *sPriv;
unsigned attachments[8];
unsigned num_attachments;
boolean is_pixmap;
/* gallium */
struct st_framebuffer_iface *stfb;
struct st_visual stvis;
__DRIbuffer old[8];
unsigned old_num;
unsigned old_w;
unsigned old_h;
/* gallium */
struct st_framebuffer *stfb;
struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
unsigned int texture_mask, texture_stamp;
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
unsigned int head;
unsigned int tail;
unsigned int desired_fences;
unsigned int cur_fences;
enum pipe_format color_format;
enum pipe_format depth_stencil_format;
/* used only by DRI1 */
struct pipe_surface *dri1_surface;
};
static INLINE struct dri_drawable *
......@@ -80,20 +82,6 @@ dri_create_buffer(__DRIscreen * sPriv,
__DRIdrawable * dPriv,
const __GLcontextModes * visual, boolean isPixmap);
void
dri_update_buffer(struct pipe_screen *screen, void *context_private);
void
dri_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surf, void *context_private);
void dri_swap_buffers(__DRIdrawable * dPriv);
void
dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
void dri_get_buffers(__DRIdrawable * dPriv);
void dri_destroy_buffer(__DRIdrawable * dPriv);
void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
......@@ -102,13 +90,6 @@ void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
__DRIdrawable *dPriv);
void
dri1_update_drawables(struct dri_context *ctx,
struct dri_drawable *draw, struct dri_drawable *read);
void
dri1_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surf, void *context_private);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
......@@ -38,9 +38,11 @@
void
dri_init_extensions(struct dri_context *ctx)
{
struct st_context *st = (struct st_context *) ctx->st;
/* New extensions should be added in mesa/state_tracker/st_extensions.c
* and not in this file. */
driInitExtensions(ctx->st->ctx, NULL, GL_FALSE);
driInitExtensions(st->ctx, NULL, GL_FALSE);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
......@@ -36,11 +36,13 @@
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
#include "dri_st_api.h"
#include "dri1.h"
#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_format.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/dri1_api.h"
#include "util/u_debug.h"
......@@ -53,7 +55,7 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END DRI_CONF_END;
const uint __driNConfigOptions = 3;
const uint __driNConfigOptions = 3;
static const __DRItexBufferExtension dri2TexBufferExtension = {
{ __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
......@@ -66,10 +68,23 @@ dri2_flush_drawable(__DRIdrawable *draw)
{
}
static void
dri2_invalidate_drawable(__DRIdrawable *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct dri_context *ctx = dri_context(dPriv->driContextPriv);
dri2InvalidateDrawable(dPriv);
drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;
if (ctx)
ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
}
static const __DRI2flushExtension dri2FlushExtension = {
{ __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
dri2_flush_drawable,
dri2InvalidateDrawable,
dri2_invalidate_drawable,
};
static const __DRIextension *dri_screen_extensions[] = {
......@@ -83,9 +98,7 @@ static const __DRI2flushExtension dri2FlushExtension = {
NULL
};
struct dri1_api *__dri1_api_hooks = NULL;
static const __DRIconfig **
const __DRIconfig **
dri_fill_in_modes(struct dri_screen *screen,
unsigned pixel_bits)
{
......@@ -228,6 +241,68 @@ dri_fill_in_modes(struct dri_screen *screen,
return (const __DRIconfig **)configs;
}
/**
* Roughly the converse of dri_fill_in_modes.
*/
void
dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
const __GLcontextModes *mode)
{
memset(stvis, 0, sizeof(*stvis));
stvis->samples = mode->samples;
stvis->render_buffer = ST_ATTACHMENT_INVALID;
if (mode->redBits == 8) {
if (mode->alphaBits == 8)
stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
else
stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
} else {
stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM;
}
switch (mode->depthBits) {
default:
case 0:
stvis->depth_stencil_format = PIPE_FORMAT_NONE;
break;
case 16:
stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
break;
case 24:
if (mode->stencilBits == 0) {
stvis->depth_stencil_format = (screen->d_depth_bits_last) ?
PIPE_FORMAT_Z24X8_UNORM:
PIPE_FORMAT_X8Z24_UNORM;
} else {
stvis->depth_stencil_format = (screen->sd_depth_bits_last) ?
PIPE_FORMAT_Z24S8_UNORM:
PIPE_FORMAT_S8Z24_UNORM;
}
break;
case 32:
stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
break;
}
stvis->accum_format = (mode->haveAccumBuffer) ?
PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
if (mode->doubleBufferMode)
stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
if (mode->stereoMode) {
stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
if (mode->doubleBufferMode)
stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
}
if (mode->haveDepthBuffer || mode->haveStencilBuffer)
stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
/* let the state tracker allocate the accum buffer */
}
/**
* Get information about previous buffer swaps.
*/
......@@ -240,73 +315,31 @@ dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
return 0;
}
static INLINE void
dri_copy_version(struct dri1_api_version *dst,
const struct __DRIversionRec *src)
{
dst->major = src->major;
dst->minor = src->minor;
dst->patch_level = src->patch;
}
static const __DRIconfig **
dri_init_screen(__DRIscreen * sPriv)
static void
dri_destroy_screen(__DRIscreen * sPriv)
{
struct dri_screen *screen;
const __DRIconfig **configs;
struct dri1_create_screen_arg arg;
struct dri_screen *screen = dri_screen(sPriv);
int i;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
return NULL;
if (screen->dri1_pipe)
screen->dri1_pipe->destroy(screen->dri1_pipe);
screen->api = drm_api_create();
screen->sPriv = sPriv;
screen->fd = sPriv->fd;
screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
if (screen->smapi)
dri_destroy_st_manager(screen->smapi);
if (screen->pipe_screen)
screen->pipe_screen->destroy(screen->pipe_screen);
sPriv->private = (void *)screen;
sPriv->extensions = dri_screen_extensions;
arg.base.mode = DRM_CREATE_DRI1;
arg.lf = &dri1_lf;
arg.ddx_info = sPriv->pDevPriv;
arg.ddx_info_size = sPriv->devPrivSize;
arg.sarea = sPriv->pSAREA;
dri_copy_version(&arg.ddx_version, &sPriv->ddx_version);
dri_copy_version(&arg.dri_version, &sPriv->dri_version);
dri_copy_version(&arg.drm_version, &sPriv->drm_version);
arg.api = NULL;
screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg.base);
if (!screen->pipe_screen || !arg.api) {
debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
goto out_no_screen;
for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
FREE(screen->optionCache.info[i].name);
FREE(screen->optionCache.info[i].ranges);
}
__dri1_api_hooks = arg.api;
screen->pipe_screen->flush_frontbuffer = dri1_flush_frontbuffer;
driParseOptionInfo(&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
/**
* FIXME: If the driver supports format conversion swapbuffer blits, we might
* want to support other color bit depths than the server is currently
* using.
*/
configs = dri_fill_in_modes(screen, sPriv->fbBPP);
if (!configs)
goto out_no_configs;
FREE(screen->optionCache.info);
FREE(screen->optionCache.values);
return configs;
out_no_configs:
screen->pipe_screen->destroy(screen->pipe_screen);
out_no_screen:
FREE(screen);
return NULL;
sPriv->private = NULL;
sPriv->extensions = NULL;
}
/**
......@@ -324,7 +357,7 @@ dri_init_screen2(__DRIscreen * sPriv)
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
goto fail;
return NULL;
screen->api = drm_api_create();
screen->sPriv = sPriv;
......@@ -339,9 +372,9 @@ dri_init_screen2(__DRIscreen * sPriv)
goto fail;
}
/* We need to hook in here */
screen->pipe_screen->update_buffer = dri_update_buffer;
screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer;
screen->smapi = dri_create_st_manager(screen);
if (!screen->smapi)
goto fail;
driParseOptionInfo(&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
......@@ -350,46 +383,27 @@ dri_init_screen2(__DRIscreen * sPriv)
dri2_ext->getBuffersWithFormat != NULL;
return dri_fill_in_modes(screen, 32);
fail:
fail:
dri_destroy_screen(sPriv);
return NULL;
}
static void
dri_destroy_screen(__DRIscreen * sPriv)
{
struct dri_screen *screen = dri_screen(sPriv);
int i;
screen->pipe_screen->destroy(screen->pipe_screen);
for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
FREE(screen->optionCache.info[i].name);
FREE(screen->optionCache.info[i].ranges);
}
FREE(screen->optionCache.info);
FREE(screen->optionCache.values);
FREE(screen);
sPriv->private = NULL;
}
PUBLIC const struct __DriverAPIRec driDriverAPI = {
.InitScreen = dri_init_screen,
const struct __DriverAPIRec driDriverAPI = {
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri_create_buffer,