st/dri: add drisw
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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: */
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user