mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 04:30:10 +01:00
st/dri2: Add DRI2 a state tracker
This was based of the unfinnished code that Keith Whitwell started on but never finnished. I moved the code from the glx directory because dri drivers can be used for more things then just glx.
This commit is contained in:
parent
cc9fbb16a6
commit
1d060e36f2
10 changed files with 572 additions and 650 deletions
28
src/gallium/state_trackers/dri2/Makefile
Normal file
28
src/gallium/state_trackers/dri2/Makefile
Normal 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
|
||||
|
|
@ -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: */
|
||||
|
|
@ -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: */
|
||||
315
src/gallium/state_trackers/dri2/dri_drawable.c
Normal file
315
src/gallium/state_trackers/dri2/dri_drawable.c
Normal 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: */
|
||||
|
|
@ -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: */
|
||||
|
|
@ -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: */
|
||||
|
|
@ -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: */
|
||||
|
|
@ -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: */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue