st/dri: add drisw

This commit is contained in:
George Sapountzis
2010-03-25 17:01:53 +02:00
parent 1bed0eb98e
commit 5b75e12f91
6 changed files with 400 additions and 0 deletions
@@ -13,6 +13,7 @@ struct pipe_texture;
enum drm_create_screen_mode {
DRM_CREATE_NORMAL = 0,
DRM_CREATE_DRI1,
DRM_CREATE_DRISW,
DRM_CREATE_DRIVER = 1024,
DRM_CREATE_MAX
};
@@ -30,7 +30,9 @@
*/
#include "utils.h"
#ifndef __NOT_HAVE_DRM_H
#include "vblank.h"
#endif
#include "xmlpool.h"
#include "dri_screen.h"
@@ -40,6 +42,7 @@
#include "dri1_helper.h"
#include "dri1.h"
#include "dri2.h"
#include "drisw.h"
#include "util/u_inlines.h"
#include "pipe/p_screen.h"
@@ -262,6 +265,8 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
/* let the state tracker allocate the accum buffer */
}
#ifndef __NOT_HAVE_DRM_H
/**
* Get information about previous buffer swaps.
*/
@@ -274,6 +279,8 @@ dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
return 0;
}
#endif
static void
dri_destroy_option_cache(struct dri_screen * screen)
{
@@ -308,6 +315,8 @@ dri_destroy_screen(__DRIscreen * sPriv)
sPriv->extensions = NULL;
}
#ifndef __NOT_HAVE_DRM_H
const struct __DriverAPIRec driDriverAPI = {
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
@@ -334,4 +343,28 @@ PUBLIC const __DRIextension *__driDriverExtensions[] = {
NULL
};
#else
const struct __DriverAPIRec driDriverAPI = {
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
.InitScreen = drisw_init_screen,
.SwapBuffers = drisw_swap_buffers,
};
/* This is the table of extensions that the loader will dlsym() for. */
PUBLIC const __DRIextension *__driDriverExtensions[] = {
&driCoreExtension.base,
&driSWRastExtension.base,
NULL
};
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
@@ -75,6 +75,8 @@ dri_screen(__DRIscreen * sPriv)
return (struct dri_screen *)sPriv->private;
}
#ifndef __NOT_HAVE_DRM_H
static INLINE boolean
dri_with_format(__DRIscreen * sPriv)
{
@@ -85,6 +87,16 @@ dri_with_format(__DRIscreen * sPriv)
&& (loader->getBuffersWithFormat != NULL);
}
#else
static INLINE boolean
dri_with_format(__DRIscreen * sPriv)
{
return TRUE;
}
#endif
extern const uint __driNConfigOptions;
const __DRIconfig **
@@ -38,6 +38,7 @@
#include "dri1_helper.h"
#include "dri1.h"
#include "dri2.h"
#include "drisw.h"
static boolean
dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
@@ -67,12 +68,19 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
if (new_stamp || new_mask) {
#ifndef __NOT_HAVE_DRM_H
if (__dri1_api_hooks) {
dri1_allocate_textures(drawable, statt_mask);
}
else {
dri_allocate_textures(drawable, statts, count);
}
#else
if (new_stamp)
drisw_update_drawable_info(drawable->dPriv);
drisw_allocate_textures(drawable, statt_mask);
#endif
/* add existing textures */
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
@@ -102,12 +110,16 @@ dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
struct dri_drawable *drawable =
(struct dri_drawable *) stfbi->st_manager_private;
#ifndef __NOT_HAVE_DRM_H
if (__dri1_api_hooks) {
dri1_flush_frontbuffer(drawable, statt);
}
else {
dri_flush_frontbuffer(drawable, statt);
}
#else
drisw_flush_frontbuffer(drawable, statt);
#endif
return TRUE;
}
+288
View File
@@ -0,0 +1,288 @@
/**************************************************************************
*
* Copyright 2009, VMware, Inc.
* All Rights Reserved.
* Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
*
* 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.
*
**************************************************************************/
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "pipe/p_context.h"
#include "state_tracker/drm_api.h"
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
#include "dri_st_api.h"
#include "dri1_helper.h"
#include "drisw.h"
static INLINE void
get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
{
__DRIscreen *sPriv = dPriv->driScreenPriv;
const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
int x, y;
loader->getDrawableInfo(dPriv,
&x, &y, w, h,
dPriv->loaderPrivate);
}
static INLINE void
put_image(__DRIdrawable *dPriv, void *data)
{
__DRIscreen *sPriv = dPriv->driScreenPriv;
const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
0, 0, dPriv->w, dPriv->h,
data, dPriv->loaderPrivate);
}
void
drisw_update_drawable_info(__DRIdrawable *dPriv)
{
get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
}
static INLINE void
drisw_present_texture(__DRIdrawable *dPriv,
struct pipe_texture *ptex)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct dri_screen *screen = dri_screen(drawable->sPriv);
struct pipe_context *pipe;
struct pipe_surface *psurf;
struct pipe_transfer *ptrans;
void *pmap;
pipe = dri1_get_pipe_context(screen);
psurf = dri1_get_pipe_surface(drawable, ptex);
if (!pipe || !psurf)
return;
ptrans = pipe->get_tex_transfer(pipe, ptex, 0, 0, 0,
PIPE_TRANSFER_READ,
0, 0, dPriv->w, dPriv->h);
pmap = pipe->transfer_map(pipe, ptrans);
assert(pmap);
put_image(dPriv, pmap);
pipe->transfer_unmap(pipe, ptrans);
pipe->tex_transfer_destroy(pipe, ptrans);
}
static INLINE void
drisw_invalidate_drawable(__DRIdrawable *dPriv)
{
struct dri_context *ctx = dri_get_current();
struct dri_drawable *drawable = dri_drawable(dPriv);
drawable->texture_stamp = dPriv->lastStamp - 1;
/* check if swapping currently bound buffer */
if (ctx && ctx->dPriv == dPriv)
ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
}
static INLINE void
drisw_copy_to_front(__DRIdrawable * dPriv,
struct pipe_texture *ptex)
{
drisw_present_texture(dPriv, ptex);
drisw_invalidate_drawable(dPriv);
}
/*
* Backend functions for st_framebuffer interface and swap_buffers.
*/
void
drisw_flush_frontbuffer(struct dri_drawable *drawable,
enum st_attachment_type statt)
{
struct dri_context *ctx = dri_get_current();
struct pipe_texture *ptex;
if (!ctx)
return;
ptex = drawable->textures[statt];
if (ptex) {
drisw_copy_to_front(ctx->dPriv, ptex);
}
}
void
drisw_swap_buffers(__DRIdrawable *dPriv)
{
struct dri_context *ctx = dri_get_current();
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_texture *ptex;
if (!ctx)
return;
ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
if (ptex) {
ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
drisw_copy_to_front(dPriv, ptex);
}
}
/**
* Allocate framebuffer attachments.
*
* During fixed-size operation, the function keeps allocating new attachments
* as they are requested. Unused attachments are not removed, not until the
* framebuffer is resized or destroyed.
*
* It should be possible for DRI1 and DRISW to share this function, but it
* seems a better seperation and safer for each DRI version to provide its own
* function.
*/
void
drisw_allocate_textures(struct dri_drawable *drawable,
unsigned mask)
{
struct dri_screen *screen = dri_screen(drawable->sPriv);
struct pipe_texture templ;
unsigned width, height;
boolean resized;
int i;
width = drawable->dPriv->w;
height = drawable->dPriv->h;
resized = (drawable->old_w != width ||
drawable->old_h != height);
/* remove outdated textures */
if (resized) {
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_texture_reference(&drawable->textures[i], NULL);
}
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
templ.last_level = 0;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
enum pipe_format format;
unsigned tex_usage;
/* the texture already exists or not requested */
if (drawable->textures[i] || !(mask & (1 << i))) {
continue;
}
switch (i) {
case ST_ATTACHMENT_FRONT_LEFT:
case ST_ATTACHMENT_BACK_LEFT:
case ST_ATTACHMENT_FRONT_RIGHT:
case ST_ATTACHMENT_BACK_RIGHT:
format = drawable->stvis.color_format;
tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_RENDER_TARGET;
break;
case ST_ATTACHMENT_DEPTH_STENCIL:
format = drawable->stvis.depth_stencil_format;
tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
break;
default:
format = PIPE_FORMAT_NONE;
break;
}
if (format != PIPE_FORMAT_NONE) {
templ.format = format;
templ.tex_usage = tex_usage;
drawable->textures[i] =
screen->pipe_screen->texture_create(screen->pipe_screen, &templ);
}
}
drawable->old_w = width;
drawable->old_h = height;
}
/*
* Backend function for init_screen.
*/
static const __DRIextension *drisw_screen_extensions[] = {
NULL
};
const __DRIconfig **
drisw_init_screen(__DRIscreen * sPriv)
{
struct dri_screen *screen;
struct drm_create_screen_arg arg;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
return NULL;
screen->api = drm_api_create();
screen->sPriv = sPriv;
screen->fd = -1;
sPriv->private = (void *)screen;
sPriv->extensions = drisw_screen_extensions;
arg.mode = DRM_CREATE_DRISW;
screen->pipe_screen = screen->api->create_screen(screen->api, -1, &arg);
if (!screen->pipe_screen) {
debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
goto fail;
}
screen->smapi = dri_create_st_manager(screen);
if (!screen->smapi)
goto fail;
driParseOptionInfo(&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
return dri_fill_in_modes(screen, 32);
fail:
dri_destroy_screen(sPriv);
return NULL;
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+54
View File
@@ -0,0 +1,54 @@
/**************************************************************************
*
* Copyright 2009, VMware, Inc.
* All Rights Reserved.
* Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
*
* 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.
*
**************************************************************************/
#ifndef DRISW_H
#define DRISW_H
#include "dri_context.h"
#include "dri_drawable.h"
#include "state_tracker/st_api.h"
#include "dri_wrapper.h"
const __DRIconfig **
drisw_init_screen(__DRIscreen * sPriv);
void
drisw_update_drawable_info(__DRIdrawable *dPriv);
void
drisw_flush_frontbuffer(struct dri_drawable *drawable,
enum st_attachment_type statt);
void
drisw_allocate_textures(struct dri_drawable *drawable,
unsigned mask);
void drisw_swap_buffers(__DRIdrawable * dPriv);
#endif /* DRISW_H */