mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 18:10:11 +01:00
Merge remote branch 'origin/gallium-st-api-dri'
This commit is contained in:
commit
12deb9e6ca
14 changed files with 1348 additions and 907 deletions
|
|
@ -15,7 +15,9 @@ C_SOURCES = \
|
||||||
dri_context.c \
|
dri_context.c \
|
||||||
dri_screen.c \
|
dri_screen.c \
|
||||||
dri_drawable.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/utils.c \
|
||||||
$(TOP)/src/mesa/drivers/dri/common/vblank.c \
|
$(TOP)/src/mesa/drivers/dri/common/vblank.c \
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ if env['dri']:
|
||||||
'dri_drawable.c',
|
'dri_drawable.c',
|
||||||
'dri_extensions.c',
|
'dri_extensions.c',
|
||||||
'dri_screen.c',
|
'dri_screen.c',
|
||||||
|
'dri_st_api.c',
|
||||||
|
'dri1.c',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
Export('st_dri')
|
Export('st_dri')
|
||||||
|
|
|
||||||
583
src/gallium/state_trackers/dri/dri1.c
Normal file
583
src/gallium/state_trackers/dri/dri1.c
Normal file
|
|
@ -0,0 +1,583 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX DRI1 is untested after the switch to st_api.h */
|
||||||
|
|
||||||
|
#include "util/u_memory.h"
|
||||||
|
#include "util/u_rect.h"
|
||||||
|
#include "util/u_inlines.h"
|
||||||
|
#include "pipe/p_context.h"
|
||||||
|
#include "state_tracker/dri1_api.h"
|
||||||
|
|
||||||
|
#include "dri_screen.h"
|
||||||
|
#include "dri_context.h"
|
||||||
|
#include "dri_drawable.h"
|
||||||
|
#include "dri_st_api.h"
|
||||||
|
#include "dri1.h"
|
||||||
|
|
||||||
|
static INLINE void
|
||||||
|
dri1_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
|
||||||
|
dri1_unlock(struct dri_context *ctx)
|
||||||
|
{
|
||||||
|
ctx->isLocked = FALSE;
|
||||||
|
DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pipe_fence_handle *
|
||||||
|
dri_swap_fences_pop_front(struct dri_drawable *draw)
|
||||||
|
{
|
||||||
|
struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
|
||||||
|
struct pipe_fence_handle *fence = NULL;
|
||||||
|
|
||||||
|
if (draw->cur_fences >= draw->desired_fences) {
|
||||||
|
screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
|
||||||
|
screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
|
||||||
|
--draw->cur_fences;
|
||||||
|
draw->tail &= DRI_SWAP_FENCES_MASK;
|
||||||
|
}
|
||||||
|
return fence;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri_swap_fences_push_back(struct dri_drawable *draw,
|
||||||
|
struct pipe_fence_handle *fence)
|
||||||
|
{
|
||||||
|
struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
|
||||||
|
|
||||||
|
if (!fence)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
|
||||||
|
draw->cur_fences++;
|
||||||
|
screen->fence_reference(screen, &draw->swap_fences[draw->head++],
|
||||||
|
fence);
|
||||||
|
draw->head &= DRI_SWAP_FENCES_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dri1_swap_fences_clear(struct dri_drawable *drawable)
|
||||||
|
{
|
||||||
|
struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
|
||||||
|
struct pipe_fence_handle *fence;
|
||||||
|
|
||||||
|
while (drawable->cur_fences) {
|
||||||
|
fence = dri_swap_fences_pop_front(drawable);
|
||||||
|
screen->fence_reference(screen, &fence, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri1_update_drawables_locked(struct dri_context *ctx,
|
||||||
|
__DRIdrawable * driDrawPriv,
|
||||||
|
__DRIdrawable * driReadPriv)
|
||||||
|
{
|
||||||
|
if (ctx->stLostLock) {
|
||||||
|
ctx->stLostLock = FALSE;
|
||||||
|
if (driDrawPriv == driReadPriv)
|
||||||
|
DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
|
||||||
|
else
|
||||||
|
DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
|
||||||
|
driReadPriv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This ensures all contexts which bind to a drawable pick up the
|
||||||
|
* drawable change and signal new buffer state.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dri1_propagate_drawable_change(struct dri_context *ctx)
|
||||||
|
{
|
||||||
|
__DRIdrawable *dPriv = ctx->dPriv;
|
||||||
|
__DRIdrawable *rPriv = ctx->rPriv;
|
||||||
|
struct dri_drawable *draw = dri_drawable(dPriv);
|
||||||
|
struct dri_drawable *read = dri_drawable(rPriv);
|
||||||
|
boolean flushed = FALSE;
|
||||||
|
|
||||||
|
if (dPriv && draw->texture_stamp != dPriv->lastStamp) {
|
||||||
|
ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
||||||
|
flushed = TRUE;
|
||||||
|
ctx->st->notify_invalid_framebuffer(ctx->st, draw->stfb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rPriv && dPriv != rPriv && read->texture_stamp != rPriv->lastStamp) {
|
||||||
|
if (!flushed)
|
||||||
|
ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
||||||
|
ctx->st->notify_invalid_framebuffer(ctx->st, read->stfb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE boolean
|
||||||
|
dri1_intersect_src_bbox(struct drm_clip_rect *dst,
|
||||||
|
int dst_x,
|
||||||
|
int dst_y,
|
||||||
|
const struct drm_clip_rect *src,
|
||||||
|
const struct drm_clip_rect *bbox)
|
||||||
|
{
|
||||||
|
int xy1;
|
||||||
|
int xy2;
|
||||||
|
|
||||||
|
xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
|
||||||
|
(int)bbox->x1 + dst_x;
|
||||||
|
xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
|
||||||
|
(int)bbox->x2 + dst_x;
|
||||||
|
if (xy1 >= xy2 || xy1 < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
dst->x1 = xy1;
|
||||||
|
dst->x2 = xy2;
|
||||||
|
|
||||||
|
xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
|
||||||
|
(int)bbox->y1 + dst_y;
|
||||||
|
xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
|
||||||
|
(int)bbox->y2 + dst_y;
|
||||||
|
if (xy1 >= xy2 || xy1 < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
dst->y1 = xy1;
|
||||||
|
dst->y2 = xy2;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri1_swap_copy(struct pipe_context *pipe,
|
||||||
|
struct pipe_surface *dst,
|
||||||
|
struct pipe_surface *src,
|
||||||
|
__DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
|
||||||
|
{
|
||||||
|
struct drm_clip_rect clip;
|
||||||
|
struct drm_clip_rect *cur;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cur = dPriv->pClipRects;
|
||||||
|
|
||||||
|
for (i = 0; i < dPriv->numClipRects; ++i) {
|
||||||
|
if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
|
||||||
|
if (pipe->surface_copy) {
|
||||||
|
pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
|
||||||
|
src,
|
||||||
|
(int)clip.x1 - dPriv->x,
|
||||||
|
(int)clip.y1 - dPriv->y,
|
||||||
|
clip.x2 - clip.x1, clip.y2 - clip.y1);
|
||||||
|
} else {
|
||||||
|
util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
|
||||||
|
src,
|
||||||
|
(int)clip.x1 - dPriv->x,
|
||||||
|
(int)clip.y1 - dPriv->y,
|
||||||
|
clip.x2 - clip.x1, clip.y2 - clip.y1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pipe_surface *
|
||||||
|
dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_texture *ptex)
|
||||||
|
{
|
||||||
|
struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->pipe_screen;
|
||||||
|
struct pipe_surface *psurf = drawable->dri1_surface;
|
||||||
|
|
||||||
|
if (!psurf || psurf->texture != ptex) {
|
||||||
|
pipe_surface_reference(&drawable->dri1_surface, NULL);
|
||||||
|
|
||||||
|
drawable->dri1_surface = pipe_screen->get_tex_surface(pipe_screen,
|
||||||
|
ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
|
||||||
|
|
||||||
|
psurf = drawable->dri1_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
return psurf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pipe_context *
|
||||||
|
dri1_get_pipe_context(struct dri_drawable *drawable)
|
||||||
|
{
|
||||||
|
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||||
|
struct pipe_context *pipe = screen->dri1_pipe;
|
||||||
|
|
||||||
|
if (!pipe) {
|
||||||
|
screen->dri1_pipe =
|
||||||
|
screen->pipe_screen->context_create(screen->pipe_screen, NULL);
|
||||||
|
pipe = screen->dri1_pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri1_present_texture_locked(__DRIdrawable * dPriv,
|
||||||
|
struct pipe_texture *ptex,
|
||||||
|
const struct drm_clip_rect *sub_box,
|
||||||
|
struct pipe_fence_handle **fence)
|
||||||
|
{
|
||||||
|
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||||
|
struct pipe_context *pipe;
|
||||||
|
struct pipe_surface *psurf;
|
||||||
|
struct drm_clip_rect bbox;
|
||||||
|
boolean visible = TRUE;
|
||||||
|
|
||||||
|
*fence = NULL;
|
||||||
|
|
||||||
|
bbox.x1 = 0;
|
||||||
|
bbox.x2 = ptex->width0;
|
||||||
|
bbox.y1 = 0;
|
||||||
|
bbox.y2 = ptex->height0;
|
||||||
|
|
||||||
|
if (sub_box)
|
||||||
|
visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
|
||||||
|
if (!visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pipe = dri1_get_pipe_context(drawable);
|
||||||
|
psurf = dri1_get_pipe_surface(drawable, ptex);
|
||||||
|
if (!pipe || !psurf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (__dri1_api_hooks->present_locked) {
|
||||||
|
__dri1_api_hooks->present_locked(pipe, psurf,
|
||||||
|
dPriv->pClipRects, dPriv->numClipRects,
|
||||||
|
dPriv->x, dPriv->y, &bbox, fence);
|
||||||
|
} else if (__dri1_api_hooks->front_srf_locked) {
|
||||||
|
struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
|
||||||
|
|
||||||
|
if (front)
|
||||||
|
dri1_swap_copy(pipe, front, psurf, dPriv, &bbox);
|
||||||
|
|
||||||
|
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, fence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri1_copy_to_front(struct dri_context *ctx,
|
||||||
|
struct pipe_texture *ptex,
|
||||||
|
__DRIdrawable * dPriv,
|
||||||
|
const struct drm_clip_rect *sub_box,
|
||||||
|
struct pipe_fence_handle **fence)
|
||||||
|
{
|
||||||
|
boolean save_lost_lock;
|
||||||
|
|
||||||
|
dri1_lock(ctx);
|
||||||
|
save_lost_lock = ctx->stLostLock;
|
||||||
|
dri1_update_drawables_locked(ctx, dPriv, dPriv);
|
||||||
|
|
||||||
|
dri1_present_texture_locked(dPriv, ptex, sub_box, fence);
|
||||||
|
|
||||||
|
ctx->stLostLock = save_lost_lock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: Revisit this: Update drawables on copy_sub_buffer ?
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!sub_box)
|
||||||
|
dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
|
||||||
|
|
||||||
|
dri1_unlock(ctx);
|
||||||
|
dri1_propagate_drawable_change(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dri1_flush_frontbuffer(struct dri_drawable *drawable,
|
||||||
|
struct pipe_texture *ptex)
|
||||||
|
{
|
||||||
|
struct st_api *stapi = dri_get_st_api();
|
||||||
|
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||||
|
struct pipe_screen *pipe_screen = screen->pipe_screen;
|
||||||
|
struct dri_context *ctx;
|
||||||
|
struct pipe_fence_handle *dummy_fence;
|
||||||
|
struct st_context_iface *st = stapi->get_current(stapi);
|
||||||
|
|
||||||
|
if (!st)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ctx = (struct dri_context *) st->st_manager_private;
|
||||||
|
|
||||||
|
dri1_copy_to_front(ctx, ptex, ctx->dPriv, NULL, &dummy_fence);
|
||||||
|
pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: Do we need swap throttling here?
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dri1_swap_buffers(__DRIdrawable * dPriv)
|
||||||
|
{
|
||||||
|
struct dri_context *ctx = dri_get_current();
|
||||||
|
struct dri_drawable *draw = dri_drawable(dPriv);
|
||||||
|
struct dri_screen *screen = dri_screen(draw->sPriv);
|
||||||
|
struct pipe_screen *pipe_screen = screen->pipe_screen;
|
||||||
|
struct pipe_fence_handle *fence;
|
||||||
|
struct pipe_texture *ptex;
|
||||||
|
|
||||||
|
assert(__dri1_api_hooks != NULL);
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
return; /* For now */
|
||||||
|
|
||||||
|
ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT];
|
||||||
|
if (ptex) {
|
||||||
|
ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
||||||
|
fence = dri_swap_fences_pop_front(draw);
|
||||||
|
if (fence) {
|
||||||
|
(void)pipe_screen->fence_finish(pipe_screen, fence, 0);
|
||||||
|
pipe_screen->fence_reference(pipe_screen, &fence, NULL);
|
||||||
|
}
|
||||||
|
dri1_copy_to_front(ctx, ptex, dPriv, NULL, &fence);
|
||||||
|
dri_swap_fences_push_back(draw, fence);
|
||||||
|
pipe_screen->fence_reference(pipe_screen, &fence, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
struct dri_context *ctx = dri_get_current();
|
||||||
|
struct dri_screen *screen = dri_screen(dPriv->driScreenPriv);
|
||||||
|
struct pipe_screen *pipe_screen = screen->pipe_screen;
|
||||||
|
struct drm_clip_rect sub_bbox;
|
||||||
|
struct dri_drawable *draw = dri_drawable(dPriv);
|
||||||
|
struct pipe_fence_handle *dummy_fence;
|
||||||
|
struct pipe_texture *ptex;
|
||||||
|
|
||||||
|
assert(__dri1_api_hooks != NULL);
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sub_bbox.x1 = x;
|
||||||
|
sub_bbox.x2 = x + w;
|
||||||
|
sub_bbox.y1 = y;
|
||||||
|
sub_bbox.y2 = y + h;
|
||||||
|
|
||||||
|
ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT];
|
||||||
|
if (ptex) {
|
||||||
|
ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
||||||
|
dri1_copy_to_front(ctx, ptex, dPriv, &sub_bbox, &dummy_fence);
|
||||||
|
pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dri1_allocate_textures(struct dri_drawable *drawable,
|
||||||
|
unsigned width, unsigned height,
|
||||||
|
unsigned mask)
|
||||||
|
{
|
||||||
|
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||||
|
struct pipe_texture templ;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* remove outdated textures */
|
||||||
|
if (drawable->old_w != width || drawable->old_h != height) {
|
||||||
|
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))) {
|
||||||
|
/* remember the texture */
|
||||||
|
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;
|
||||||
|
drawable->texture_mask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
st_dri_lock(struct pipe_context *pipe)
|
||||||
|
{
|
||||||
|
dri1_lock((struct dri_context *)pipe->priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
st_dri_unlock(struct pipe_context *pipe)
|
||||||
|
{
|
||||||
|
dri1_unlock((struct dri_context *)pipe->priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
st_dri_is_locked(struct pipe_context *pipe)
|
||||||
|
{
|
||||||
|
return ((struct dri_context *)pipe->priv)->isLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
st_dri_lost_lock(struct pipe_context *pipe)
|
||||||
|
{
|
||||||
|
return ((struct dri_context *)pipe->priv)->wsLostLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
st_dri_clear_lost_lock(struct pipe_context *pipe)
|
||||||
|
{
|
||||||
|
((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static 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
|
||||||
|
};
|
||||||
|
|
||||||
|
static const __DRIextension *dri1_screen_extensions[] = {
|
||||||
|
&driReadDrawableExtension,
|
||||||
|
&driCopySubBufferExtension.base,
|
||||||
|
&driSwapControlExtension.base,
|
||||||
|
&driFrameTrackingExtension.base,
|
||||||
|
&driMediaStreamCounterExtension.base,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dri1_api *__dri1_api_hooks = NULL;
|
||||||
|
|
||||||
|
static INLINE void
|
||||||
|
dri1_copy_version(struct dri1_api_version *dst,
|
||||||
|
const struct __DRIversionRec *src)
|
||||||
|
{
|
||||||
|
dst->major = src->major;
|
||||||
|
dst->minor = src->minor;
|
||||||
|
dst->patch_level = src->patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const __DRIconfig **
|
||||||
|
dri1_init_screen(__DRIscreen * sPriv)
|
||||||
|
{
|
||||||
|
struct dri_screen *screen;
|
||||||
|
const __DRIconfig **configs;
|
||||||
|
struct dri1_create_screen_arg arg;
|
||||||
|
|
||||||
|
screen = CALLOC_STRUCT(dri_screen);
|
||||||
|
if (!screen)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
screen->api = drm_api_create();
|
||||||
|
screen->sPriv = sPriv;
|
||||||
|
screen->fd = sPriv->fd;
|
||||||
|
screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
|
||||||
|
|
||||||
|
sPriv->private = (void *)screen;
|
||||||
|
sPriv->extensions = dri1_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;
|
||||||
|
dri1_copy_version(&arg.ddx_version, &sPriv->ddx_version);
|
||||||
|
dri1_copy_version(&arg.dri_version, &sPriv->dri_version);
|
||||||
|
dri1_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
__dri1_api_hooks = arg.api;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
return configs;
|
||||||
|
out_no_configs:
|
||||||
|
screen->pipe_screen->destroy(screen->pipe_screen);
|
||||||
|
out_no_screen:
|
||||||
|
FREE(screen);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
63
src/gallium/state_trackers/dri/dri1.h
Normal file
63
src/gallium/state_trackers/dri/dri1.h
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* 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_screen.h"
|
||||||
|
|
||||||
#include "dri_drawable.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_context.h"
|
||||||
|
#include "dri_st_api.h"
|
||||||
|
#include "dri1.h"
|
||||||
|
|
||||||
|
#include "pipe/p_context.h"
|
||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
|
|
||||||
GLboolean
|
GLboolean
|
||||||
dri_create_context(const __GLcontextModes * visual,
|
dri_create_context(const __GLcontextModes * visual,
|
||||||
__DRIcontext * cPriv, void *sharedContextPrivate)
|
__DRIcontext * cPriv, void *sharedContextPrivate)
|
||||||
{
|
{
|
||||||
|
struct st_api *stapi = dri_get_st_api();
|
||||||
__DRIscreen *sPriv = cPriv->driScreenPriv;
|
__DRIscreen *sPriv = cPriv->driScreenPriv;
|
||||||
struct dri_screen *screen = dri_screen(sPriv);
|
struct dri_screen *screen = dri_screen(sPriv);
|
||||||
struct dri_context *ctx = NULL;
|
struct dri_context *ctx = NULL;
|
||||||
struct st_context *st_share = NULL;
|
struct st_context_iface *st_share = NULL;
|
||||||
|
struct st_visual stvis;
|
||||||
|
|
||||||
if (sharedContextPrivate) {
|
if (sharedContextPrivate) {
|
||||||
st_share = ((struct dri_context *)sharedContextPrivate)->st;
|
st_share = ((struct dri_context *)sharedContextPrivate)->st;
|
||||||
|
|
@ -62,21 +61,15 @@ dri_create_context(const __GLcontextModes * visual,
|
||||||
ctx->cPriv = cPriv;
|
ctx->cPriv = cPriv;
|
||||||
ctx->sPriv = sPriv;
|
ctx->sPriv = sPriv;
|
||||||
ctx->lock = screen->drmLock;
|
ctx->lock = screen->drmLock;
|
||||||
ctx->d_stamp = -1;
|
|
||||||
ctx->r_stamp = -1;
|
|
||||||
|
|
||||||
driParseConfigFiles(&ctx->optionCache,
|
driParseConfigFiles(&ctx->optionCache,
|
||||||
&screen->optionCache, sPriv->myNum, "dri");
|
&screen->optionCache, sPriv->myNum, "dri");
|
||||||
|
|
||||||
ctx->pipe = screen->pipe_screen->context_create( screen->pipe_screen,
|
dri_fill_st_visual(&stvis, screen, visual);
|
||||||
ctx );
|
ctx->st = stapi->create_context(stapi, screen->smapi, &stvis, st_share);
|
||||||
|
|
||||||
if (ctx->pipe == NULL)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
ctx->st = st_create_context(ctx->pipe, visual, st_share);
|
|
||||||
if (ctx->st == NULL)
|
if (ctx->st == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
ctx->st->st_manager_private = (void *) ctx;
|
||||||
|
|
||||||
dri_init_extensions(ctx);
|
dri_init_extensions(ctx);
|
||||||
|
|
||||||
|
|
@ -84,10 +77,7 @@ dri_create_context(const __GLcontextModes * visual,
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (ctx && ctx->st)
|
if (ctx && ctx->st)
|
||||||
st_destroy_context(ctx->st);
|
ctx->st->destroy(ctx->st);
|
||||||
|
|
||||||
if (ctx && ctx->pipe)
|
|
||||||
ctx->pipe->destroy(ctx->pipe);
|
|
||||||
|
|
||||||
FREE(ctx);
|
FREE(ctx);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
@ -109,11 +99,8 @@ dri_destroy_context(__DRIcontext * cPriv)
|
||||||
* to avoid having to add code elsewhere to cope with flushing a
|
* to avoid having to add code elsewhere to cope with flushing a
|
||||||
* partially destroyed context.
|
* partially destroyed context.
|
||||||
*/
|
*/
|
||||||
st_flush(ctx->st, 0, NULL);
|
ctx->st->flush(ctx->st, 0, NULL);
|
||||||
|
ctx->st->destroy(ctx->st);
|
||||||
/* Also frees ctx->pipe?
|
|
||||||
*/
|
|
||||||
st_destroy_context(ctx->st);
|
|
||||||
|
|
||||||
FREE(ctx);
|
FREE(ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -121,14 +108,16 @@ dri_destroy_context(__DRIcontext * cPriv)
|
||||||
GLboolean
|
GLboolean
|
||||||
dri_unbind_context(__DRIcontext * cPriv)
|
dri_unbind_context(__DRIcontext * cPriv)
|
||||||
{
|
{
|
||||||
|
struct st_api *stapi = dri_get_st_api();
|
||||||
|
|
||||||
if (cPriv) {
|
if (cPriv) {
|
||||||
struct dri_context *ctx = dri_context(cPriv);
|
struct dri_context *ctx = dri_context(cPriv);
|
||||||
|
|
||||||
if (--ctx->bind_count == 0) {
|
if (--ctx->bind_count == 0) {
|
||||||
if (ctx->st && ctx->st == st_get_current()) {
|
if (ctx->st == stapi->get_current(stapi)) {
|
||||||
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
||||||
st_make_current(NULL, NULL, NULL, NULL);
|
stapi->make_current(stapi, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,83 +129,47 @@ dri_make_current(__DRIcontext * cPriv,
|
||||||
__DRIdrawable * driDrawPriv,
|
__DRIdrawable * driDrawPriv,
|
||||||
__DRIdrawable * driReadPriv)
|
__DRIdrawable * driReadPriv)
|
||||||
{
|
{
|
||||||
|
struct st_api *stapi = dri_get_st_api();
|
||||||
|
|
||||||
if (cPriv) {
|
if (cPriv) {
|
||||||
struct dri_context *ctx = dri_context(cPriv);
|
struct dri_context *ctx = dri_context(cPriv);
|
||||||
struct dri_drawable *draw = dri_drawable(driDrawPriv);
|
struct dri_drawable *draw = dri_drawable(driDrawPriv);
|
||||||
struct dri_drawable *read = dri_drawable(driReadPriv);
|
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)
|
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;
|
++ctx->bind_count;
|
||||||
|
|
||||||
if (ctx->dPriv != driDrawPriv) {
|
if (ctx->dPriv != driDrawPriv) {
|
||||||
ctx->dPriv = driDrawPriv;
|
ctx->dPriv = driDrawPriv;
|
||||||
ctx->d_stamp = driDrawPriv->lastStamp - 1;
|
draw->texture_stamp = driDrawPriv->lastStamp - 1;
|
||||||
}
|
}
|
||||||
if (ctx->rPriv != driReadPriv) {
|
if (ctx->rPriv != driReadPriv) {
|
||||||
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.
|
stapi->make_current(stapi, ctx->st, draw->stfb, read->stfb);
|
||||||
* When this is fixed, will need to pass the drawable in the
|
}
|
||||||
* fourth parameter here so that when Mesa calls
|
else {
|
||||||
* flush_frontbuffer directly (in front-buffer rendering), it
|
stapi->make_current(stapi, NULL, NULL, NULL);
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
struct dri_context *
|
||||||
st_dri_lock(struct pipe_context *pipe)
|
dri_get_current(void)
|
||||||
{
|
{
|
||||||
dri_lock((struct dri_context *)pipe->priv);
|
struct st_api *stapi = dri_get_st_api();
|
||||||
}
|
struct st_context_iface *st;
|
||||||
|
|
||||||
static void
|
st = stapi->get_current(stapi);
|
||||||
st_dri_unlock(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
dri_unlock((struct dri_context *)pipe->priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
return (struct dri_context *) (st) ? st->st_manager_private : NULL;
|
||||||
st_dri_is_locked(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
return ((struct dri_context *)pipe->priv)->isLocked;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean
|
|
||||||
st_dri_lost_lock(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
return ((struct dri_context *)pipe->priv)->wsLostLock;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
st_dri_clear_lost_lock(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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: */
|
/* vim: set sw=3 ts=8 sts=3 expandtab: */
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,6 @@ struct dri_context
|
||||||
|
|
||||||
driOptionCache optionCache;
|
driOptionCache optionCache;
|
||||||
|
|
||||||
unsigned int d_stamp;
|
|
||||||
unsigned int r_stamp;
|
|
||||||
|
|
||||||
drmLock *lock;
|
drmLock *lock;
|
||||||
boolean isLocked;
|
boolean isLocked;
|
||||||
boolean stLostLock;
|
boolean stLostLock;
|
||||||
|
|
@ -62,8 +59,7 @@ struct dri_context
|
||||||
unsigned int bind_count;
|
unsigned int bind_count;
|
||||||
|
|
||||||
/* gallium */
|
/* gallium */
|
||||||
struct st_context *st;
|
struct st_context_iface *st;
|
||||||
struct pipe_context *pipe;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static INLINE struct dri_context *
|
static INLINE struct dri_context *
|
||||||
|
|
@ -72,33 +68,9 @@ dri_context(__DRIcontext * driContextPriv)
|
||||||
return (struct dri_context *)driContextPriv->driverPrivate;
|
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
|
* dri_context.c
|
||||||
*/
|
*/
|
||||||
extern struct dri1_api_lock_funcs dri1_lf;
|
|
||||||
|
|
||||||
void dri_destroy_context(__DRIcontext * driContextPriv);
|
void dri_destroy_context(__DRIcontext * driContextPriv);
|
||||||
|
|
||||||
boolean dri_unbind_context(__DRIcontext * driContextPriv);
|
boolean dri_unbind_context(__DRIcontext * driContextPriv);
|
||||||
|
|
@ -108,6 +80,9 @@ dri_make_current(__DRIcontext * driContextPriv,
|
||||||
__DRIdrawable * driDrawPriv,
|
__DRIdrawable * driDrawPriv,
|
||||||
__DRIdrawable * driReadPriv);
|
__DRIdrawable * driReadPriv);
|
||||||
|
|
||||||
|
struct dri_context *
|
||||||
|
dri_get_current(void);
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
dri_create_context(const __GLcontextModes * visual,
|
dri_create_context(const __GLcontextModes * visual,
|
||||||
__DRIcontext * driContextPriv,
|
__DRIcontext * driContextPriv,
|
||||||
|
|
|
||||||
|
|
@ -32,251 +32,30 @@
|
||||||
#include "dri_screen.h"
|
#include "dri_screen.h"
|
||||||
#include "dri_context.h"
|
#include "dri_context.h"
|
||||||
#include "dri_drawable.h"
|
#include "dri_drawable.h"
|
||||||
|
#include "dri_st_api.h"
|
||||||
|
#include "dri1.h"
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_screen.h"
|
#include "pipe/p_screen.h"
|
||||||
#include "main/mtypes.h"
|
|
||||||
#include "main/renderbuffer.h"
|
|
||||||
#include "state_tracker/drm_api.h"
|
|
||||||
#include "state_tracker/dri1_api.h"
|
|
||||||
#include "state_tracker/st_context.h"
|
|
||||||
#include "state_tracker/st_public.h"
|
|
||||||
#include "state_tracker/st_cb_fbo.h"
|
|
||||||
|
|
||||||
#include "util/u_format.h"
|
#include "util/u_format.h"
|
||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
#include "util/u_rect.h"
|
|
||||||
#include "util/u_inlines.h"
|
#include "util/u_inlines.h"
|
||||||
|
|
||||||
static struct pipe_surface *
|
|
||||||
dri_surface_from_handle(struct drm_api *api,
|
|
||||||
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 winsys_handle whandle;
|
|
||||||
|
|
||||||
memset(&templat, 0, sizeof(templat));
|
|
||||||
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
|
|
||||||
templat.target = PIPE_TEXTURE_2D;
|
|
||||||
templat.last_level = 0;
|
|
||||||
templat.depth0 = 1;
|
|
||||||
templat.format = format;
|
|
||||||
templat.width0 = width;
|
|
||||||
templat.height0 = height;
|
|
||||||
|
|
||||||
memset(&whandle, 0, sizeof(whandle));
|
|
||||||
whandle.handle = handle;
|
|
||||||
whandle.stride = pitch;
|
|
||||||
|
|
||||||
texture = screen->texture_from_handle(screen, &templat, &whandle);
|
|
||||||
|
|
||||||
if (!texture) {
|
|
||||||
debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pixmaps have will have the same name of fake front and front.
|
|
||||||
*/
|
|
||||||
static boolean
|
|
||||||
dri2_check_if_pixmap(__DRIbuffer *buffers, int count)
|
|
||||||
{
|
|
||||||
boolean found = FALSE;
|
|
||||||
boolean is_pixmap = FALSE;
|
|
||||||
unsigned name;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
switch (buffers[i].attachment) {
|
|
||||||
case __DRI_BUFFER_FRONT_LEFT:
|
|
||||||
case __DRI_BUFFER_FAKE_FRONT_LEFT:
|
|
||||||
if (found) {
|
|
||||||
is_pixmap = buffers[i].name == name;
|
|
||||||
} else {
|
|
||||||
name = buffers[i].name;
|
|
||||||
found = TRUE;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return is_pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This will be called a drawable is known to have been resized.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
dri_get_buffers(__DRIdrawable * dPriv)
|
|
||||||
{
|
|
||||||
|
|
||||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
|
||||||
struct pipe_surface *surface = NULL;
|
|
||||||
struct dri_screen *st_screen = dri_screen(drawable->sPriv);
|
|
||||||
struct pipe_screen *screen = st_screen->pipe_screen;
|
|
||||||
__DRIbuffer *buffers = NULL;
|
|
||||||
__DRIscreen *dri_screen = drawable->sPriv;
|
|
||||||
__DRIdrawable *dri_drawable = drawable->dPriv;
|
|
||||||
struct drm_api *api = st_screen->api;
|
|
||||||
boolean have_depth = FALSE;
|
|
||||||
int i, count;
|
|
||||||
|
|
||||||
if ((dri_screen->dri2.loader
|
|
||||||
&& (dri_screen->dri2.loader->base.version > 2)
|
|
||||||
&& (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) {
|
|
||||||
buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
|
|
||||||
(dri_drawable, &dri_drawable->w, &dri_drawable->h,
|
|
||||||
drawable->attachments, drawable->num_attachments,
|
|
||||||
&count, dri_drawable->loaderPrivate);
|
|
||||||
} else {
|
|
||||||
assert(dri_screen->dri2.loader);
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (drawable->old_num == count &&
|
|
||||||
drawable->old_w == dri_drawable->w &&
|
|
||||||
drawable->old_h == dri_drawable->h &&
|
|
||||||
memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
drawable->old_num = count;
|
|
||||||
drawable->old_w = dri_drawable->w;
|
|
||||||
drawable->old_h = dri_drawable->h;
|
|
||||||
memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawable->is_pixmap = dri2_check_if_pixmap(buffers, count);
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
enum pipe_format format = 0;
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
switch (buffers[i].attachment) {
|
|
||||||
case __DRI_BUFFER_FRONT_LEFT:
|
|
||||||
if (!st_screen->auto_fake_front)
|
|
||||||
continue;
|
|
||||||
/* fallthrough */
|
|
||||||
case __DRI_BUFFER_FAKE_FRONT_LEFT:
|
|
||||||
index = ST_SURFACE_FRONT_LEFT;
|
|
||||||
format = drawable->color_format;
|
|
||||||
break;
|
|
||||||
case __DRI_BUFFER_BACK_LEFT:
|
|
||||||
index = ST_SURFACE_BACK_LEFT;
|
|
||||||
format = drawable->color_format;
|
|
||||||
break;
|
|
||||||
case __DRI_BUFFER_DEPTH:
|
|
||||||
case __DRI_BUFFER_DEPTH_STENCIL:
|
|
||||||
case __DRI_BUFFER_STENCIL:
|
|
||||||
index = ST_SURFACE_DEPTH;
|
|
||||||
format = drawable->depth_stencil_format;
|
|
||||||
break;
|
|
||||||
case __DRI_BUFFER_ACCUM:
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == ST_SURFACE_DEPTH) {
|
|
||||||
if (have_depth)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
have_depth = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface = dri_surface_from_handle(api,
|
|
||||||
screen,
|
|
||||||
buffers[i].name,
|
|
||||||
format,
|
|
||||||
dri_drawable->w,
|
|
||||||
dri_drawable->h, buffers[i].pitch);
|
|
||||||
|
|
||||||
switch (buffers[i].attachment) {
|
|
||||||
case __DRI_BUFFER_FRONT_LEFT:
|
|
||||||
case __DRI_BUFFER_FAKE_FRONT_LEFT:
|
|
||||||
case __DRI_BUFFER_BACK_LEFT:
|
|
||||||
drawable->color_format = surface->format;
|
|
||||||
break;
|
|
||||||
case __DRI_BUFFER_DEPTH:
|
|
||||||
case __DRI_BUFFER_DEPTH_STENCIL:
|
|
||||||
case __DRI_BUFFER_STENCIL:
|
|
||||||
drawable->depth_stencil_format = surface->format;
|
|
||||||
break;
|
|
||||||
case __DRI_BUFFER_ACCUM:
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are used for GLX_EXT_texture_from_pixmap
|
* These are used for GLX_EXT_texture_from_pixmap
|
||||||
*/
|
*/
|
||||||
void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
|
void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
|
||||||
GLint format, __DRIdrawable *dPriv)
|
GLint format, __DRIdrawable *dPriv)
|
||||||
{
|
{
|
||||||
|
struct dri_context *ctx = dri_context(pDRICtx);
|
||||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||||
struct pipe_surface *ps;
|
struct pipe_texture *pt =
|
||||||
|
dri_get_st_framebuffer_texture(drawable->stfb, ST_ATTACHMENT_FRONT_LEFT);
|
||||||
|
|
||||||
if (!drawable->stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer) {
|
if (pt) {
|
||||||
struct gl_renderbuffer *rb =
|
ctx->st->teximage(ctx->st,
|
||||||
st_new_renderbuffer_fb(drawable->color_format, 0 /*XXX*/, FALSE);
|
(target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
|
||||||
_mesa_add_renderbuffer(&drawable->stfb->Base, BUFFER_FRONT_LEFT, rb);
|
0, drawable->stvis.color_format, pt, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
dri_get_buffers(drawable->dPriv);
|
|
||||||
st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
|
|
||||||
|
|
||||||
if (!ps)
|
|
||||||
return;
|
|
||||||
|
|
||||||
st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
|
|
||||||
ST_TEXTURE_RECT, 0, drawable->color_format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
|
void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
|
||||||
|
|
@ -285,53 +64,6 @@ void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
|
||||||
dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
|
dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
dri_update_buffer(struct pipe_screen *screen, void *context_private)
|
|
||||||
{
|
|
||||||
struct dri_context *ctx = (struct dri_context *)context_private;
|
|
||||||
|
|
||||||
if (ctx->d_stamp == *ctx->dPriv->pStamp &&
|
|
||||||
ctx->r_stamp == *ctx->rPriv->pStamp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ctx->d_stamp = *ctx->dPriv->pStamp;
|
|
||||||
ctx->r_stamp = *ctx->rPriv->pStamp;
|
|
||||||
|
|
||||||
/* Ask the X server for new renderbuffers. */
|
|
||||||
dri_get_buffers(ctx->dPriv);
|
|
||||||
if (ctx->dPriv != ctx->rPriv)
|
|
||||||
dri_get_buffers(ctx->rPriv);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dri_flush_frontbuffer(struct pipe_screen *screen,
|
|
||||||
struct pipe_surface *surf, void *context_private)
|
|
||||||
{
|
|
||||||
struct dri_context *ctx = (struct dri_context *)context_private;
|
|
||||||
struct dri_drawable *drawable = dri_drawable(ctx->dPriv);
|
|
||||||
__DRIdrawable *dri_drawable = ctx->dPriv;
|
|
||||||
__DRIscreen *dri_screen = ctx->sPriv;
|
|
||||||
|
|
||||||
/* XXX Does this function get called with DRI1? */
|
|
||||||
|
|
||||||
if (ctx->dPriv == NULL) {
|
|
||||||
debug_printf("%s: no drawable bound to context\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* TODO if rendering to pixmaps is slow enable this code. */
|
|
||||||
if (drawable->is_pixmap)
|
|
||||||
return;
|
|
||||||
#else
|
|
||||||
(void)drawable;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
(*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable,
|
|
||||||
dri_drawable->loaderPrivate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is called when we need to set up GL rendering to a new X window.
|
* This is called when we need to set up GL rendering to a new X window.
|
||||||
*/
|
*/
|
||||||
|
|
@ -342,7 +74,6 @@ dri_create_buffer(__DRIscreen * sPriv,
|
||||||
{
|
{
|
||||||
struct dri_screen *screen = sPriv->private;
|
struct dri_screen *screen = sPriv->private;
|
||||||
struct dri_drawable *drawable = NULL;
|
struct dri_drawable *drawable = NULL;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (isPixmap)
|
if (isPixmap)
|
||||||
goto fail; /* not implemented */
|
goto fail; /* not implemented */
|
||||||
|
|
@ -351,45 +82,8 @@ dri_create_buffer(__DRIscreen * sPriv,
|
||||||
if (drawable == NULL)
|
if (drawable == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (visual->redBits == 8) {
|
dri_fill_st_visual(&drawable->stvis, screen, visual);
|
||||||
if (visual->alphaBits == 8)
|
drawable->stfb = dri_create_st_framebuffer(drawable);
|
||||||
drawable->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
else
|
|
||||||
drawable->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
|
|
||||||
} else {
|
|
||||||
drawable->color_format = PIPE_FORMAT_B5G6R5_UNORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(visual->depthBits) {
|
|
||||||
default:
|
|
||||||
case 0:
|
|
||||||
drawable->depth_stencil_format = PIPE_FORMAT_NONE;
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
if (visual->stencilBits == 0) {
|
|
||||||
drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
|
|
||||||
PIPE_FORMAT_Z24X8_UNORM:
|
|
||||||
PIPE_FORMAT_X8Z24_UNORM;
|
|
||||||
} else {
|
|
||||||
drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
|
|
||||||
PIPE_FORMAT_Z24S8_UNORM:
|
|
||||||
PIPE_FORMAT_S8Z24_UNORM;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
drawable->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawable->stfb = st_create_framebuffer(visual,
|
|
||||||
drawable->color_format,
|
|
||||||
drawable->depth_stencil_format,
|
|
||||||
drawable->depth_stencil_format,
|
|
||||||
dPriv->w,
|
|
||||||
dPriv->h, (void *)drawable);
|
|
||||||
if (drawable->stfb == NULL)
|
if (drawable->stfb == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
@ -397,48 +91,6 @@ dri_create_buffer(__DRIscreen * sPriv,
|
||||||
drawable->dPriv = dPriv;
|
drawable->dPriv = dPriv;
|
||||||
dPriv->driverPrivate = (void *)drawable;
|
dPriv->driverPrivate = (void *)drawable;
|
||||||
|
|
||||||
/* setup dri2 buffers information */
|
|
||||||
/* TODO incase of double buffer visual, delay fake creation */
|
|
||||||
i = 0;
|
|
||||||
if (sPriv->dri2.loader
|
|
||||||
&& (sPriv->dri2.loader->base.version > 2)
|
|
||||||
&& (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
|
|
||||||
drawable->attachments[i++] = visual->rgbBits;
|
|
||||||
if (!screen->auto_fake_front) {
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
|
|
||||||
drawable->attachments[i++] = visual->rgbBits;
|
|
||||||
}
|
|
||||||
if (visual->doubleBufferMode) {
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
|
|
||||||
drawable->attachments[i++] = visual->rgbBits;
|
|
||||||
}
|
|
||||||
if (visual->depthBits && visual->stencilBits) {
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
|
|
||||||
drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
|
|
||||||
} else if (visual->depthBits) {
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
|
|
||||||
drawable->attachments[i++] = visual->depthBits;
|
|
||||||
} else if (visual->stencilBits) {
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
|
|
||||||
drawable->attachments[i++] = visual->stencilBits;
|
|
||||||
}
|
|
||||||
drawable->num_attachments = i / 2;
|
|
||||||
} else {
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
|
|
||||||
if (!screen->auto_fake_front)
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
|
|
||||||
if (visual->doubleBufferMode)
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
|
|
||||||
if (visual->depthBits && visual->stencilBits)
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
|
|
||||||
else if (visual->depthBits)
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
|
|
||||||
else if (visual->stencilBits)
|
|
||||||
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
|
|
||||||
drawable->num_attachments = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawable->desired_fences = 2;
|
drawable->desired_fences = 2;
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
|
|
@ -447,319 +99,23 @@ fail:
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pipe_fence_handle *
|
|
||||||
dri_swap_fences_pop_front(struct dri_drawable *draw)
|
|
||||||
{
|
|
||||||
struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
|
|
||||||
struct pipe_fence_handle *fence = NULL;
|
|
||||||
|
|
||||||
if (draw->cur_fences >= draw->desired_fences) {
|
|
||||||
screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
|
|
||||||
screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
|
|
||||||
--draw->cur_fences;
|
|
||||||
draw->tail &= DRI_SWAP_FENCES_MASK;
|
|
||||||
}
|
|
||||||
return fence;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dri_swap_fences_push_back(struct dri_drawable *draw,
|
|
||||||
struct pipe_fence_handle *fence)
|
|
||||||
{
|
|
||||||
struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
|
|
||||||
|
|
||||||
if (!fence)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
|
|
||||||
draw->cur_fences++;
|
|
||||||
screen->fence_reference(screen, &draw->swap_fences[draw->head++],
|
|
||||||
fence);
|
|
||||||
draw->head &= DRI_SWAP_FENCES_MASK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dri_destroy_buffer(__DRIdrawable * dPriv)
|
dri_destroy_buffer(__DRIdrawable * dPriv)
|
||||||
{
|
{
|
||||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||||
struct pipe_fence_handle *fence;
|
int i;
|
||||||
struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
|
|
||||||
|
dri1_swap_fences_clear(drawable);
|
||||||
|
|
||||||
|
pipe_surface_reference(&drawable->dri1_surface, NULL);
|
||||||
|
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
|
||||||
|
pipe_texture_reference(&drawable->textures[i], NULL);
|
||||||
|
|
||||||
|
dri_destroy_st_framebuffer(drawable->stfb);
|
||||||
|
|
||||||
st_unreference_framebuffer(drawable->stfb);
|
|
||||||
drawable->desired_fences = 0;
|
drawable->desired_fences = 0;
|
||||||
while (drawable->cur_fences) {
|
|
||||||
fence = dri_swap_fences_pop_front(drawable);
|
|
||||||
screen->fence_reference(screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
FREE(drawable);
|
FREE(drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
dri1_update_drawables_locked(struct dri_context *ctx,
|
|
||||||
__DRIdrawable * driDrawPriv,
|
|
||||||
__DRIdrawable * driReadPriv)
|
|
||||||
{
|
|
||||||
if (ctx->stLostLock) {
|
|
||||||
ctx->stLostLock = FALSE;
|
|
||||||
if (driDrawPriv == driReadPriv)
|
|
||||||
DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
|
|
||||||
else
|
|
||||||
DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
|
|
||||||
driReadPriv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This ensures all contexts which bind to a drawable pick up the
|
|
||||||
* drawable change and signal new buffer state.
|
|
||||||
* Calling st_resize_framebuffer for each context may seem like overkill,
|
|
||||||
* but no new buffers will actually be allocated if the dimensions don't
|
|
||||||
* change.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
dri1_propagate_drawable_change(struct dri_context *ctx)
|
|
||||||
{
|
|
||||||
__DRIdrawable *dPriv = ctx->dPriv;
|
|
||||||
__DRIdrawable *rPriv = ctx->rPriv;
|
|
||||||
boolean flushed = FALSE;
|
|
||||||
|
|
||||||
if (dPriv && ctx->d_stamp != dPriv->lastStamp) {
|
|
||||||
|
|
||||||
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
|
||||||
flushed = TRUE;
|
|
||||||
ctx->d_stamp = dPriv->lastStamp;
|
|
||||||
st_resize_framebuffer(dri_drawable(dPriv)->stfb, dPriv->w, dPriv->h);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rPriv && dPriv != rPriv && ctx->r_stamp != rPriv->lastStamp) {
|
|
||||||
|
|
||||||
if (!flushed)
|
|
||||||
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
|
||||||
ctx->r_stamp = rPriv->lastStamp;
|
|
||||||
st_resize_framebuffer(dri_drawable(rPriv)->stfb, rPriv->w, rPriv->h);
|
|
||||||
|
|
||||||
} else if (rPriv && dPriv == rPriv) {
|
|
||||||
|
|
||||||
ctx->r_stamp = ctx->d_stamp;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dri1_update_drawables(struct dri_context *ctx,
|
|
||||||
struct dri_drawable *draw, struct dri_drawable *read)
|
|
||||||
{
|
|
||||||
dri_lock(ctx);
|
|
||||||
dri1_update_drawables_locked(ctx, draw->dPriv, read->dPriv);
|
|
||||||
dri_unlock(ctx);
|
|
||||||
|
|
||||||
dri1_propagate_drawable_change(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE boolean
|
|
||||||
dri1_intersect_src_bbox(struct drm_clip_rect *dst,
|
|
||||||
int dst_x,
|
|
||||||
int dst_y,
|
|
||||||
const struct drm_clip_rect *src,
|
|
||||||
const struct drm_clip_rect *bbox)
|
|
||||||
{
|
|
||||||
int xy1;
|
|
||||||
int xy2;
|
|
||||||
|
|
||||||
xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
|
|
||||||
(int)bbox->x1 + dst_x;
|
|
||||||
xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
|
|
||||||
(int)bbox->x2 + dst_x;
|
|
||||||
if (xy1 >= xy2 || xy1 < 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
dst->x1 = xy1;
|
|
||||||
dst->x2 = xy2;
|
|
||||||
|
|
||||||
xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
|
|
||||||
(int)bbox->y1 + dst_y;
|
|
||||||
xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
|
|
||||||
(int)bbox->y2 + dst_y;
|
|
||||||
if (xy1 >= xy2 || xy1 < 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
dst->y1 = xy1;
|
|
||||||
dst->y2 = xy2;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dri1_swap_copy(struct dri_context *ctx,
|
|
||||||
struct pipe_surface *dst,
|
|
||||||
struct pipe_surface *src,
|
|
||||||
__DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct drm_clip_rect clip;
|
|
||||||
struct drm_clip_rect *cur;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
cur = dPriv->pClipRects;
|
|
||||||
|
|
||||||
for (i = 0; i < dPriv->numClipRects; ++i) {
|
|
||||||
if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
|
|
||||||
if (pipe->surface_copy) {
|
|
||||||
pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
|
|
||||||
src,
|
|
||||||
(int)clip.x1 - dPriv->x,
|
|
||||||
(int)clip.y1 - dPriv->y,
|
|
||||||
clip.x2 - clip.x1, clip.y2 - clip.y1);
|
|
||||||
} else {
|
|
||||||
util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
|
|
||||||
src,
|
|
||||||
(int)clip.x1 - dPriv->x,
|
|
||||||
(int)clip.y1 - dPriv->y,
|
|
||||||
clip.x2 - clip.x1, clip.y2 - clip.y1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dri1_copy_to_front(struct dri_context *ctx,
|
|
||||||
struct pipe_surface *surf,
|
|
||||||
__DRIdrawable * dPriv,
|
|
||||||
const struct drm_clip_rect *sub_box,
|
|
||||||
struct pipe_fence_handle **fence)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
boolean save_lost_lock;
|
|
||||||
uint cur_w;
|
|
||||||
uint cur_h;
|
|
||||||
struct drm_clip_rect bbox;
|
|
||||||
boolean visible = TRUE;
|
|
||||||
|
|
||||||
*fence = NULL;
|
|
||||||
|
|
||||||
dri_lock(ctx);
|
|
||||||
save_lost_lock = ctx->stLostLock;
|
|
||||||
dri1_update_drawables_locked(ctx, dPriv, dPriv);
|
|
||||||
st_get_framebuffer_dimensions(dri_drawable(dPriv)->stfb, &cur_w, &cur_h);
|
|
||||||
|
|
||||||
bbox.x1 = 0;
|
|
||||||
bbox.x2 = cur_w;
|
|
||||||
bbox.y1 = 0;
|
|
||||||
bbox.y2 = cur_h;
|
|
||||||
|
|
||||||
if (sub_box)
|
|
||||||
visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
|
|
||||||
|
|
||||||
if (visible && __dri1_api_hooks->present_locked) {
|
|
||||||
|
|
||||||
__dri1_api_hooks->present_locked(pipe,
|
|
||||||
surf,
|
|
||||||
dPriv->pClipRects,
|
|
||||||
dPriv->numClipRects,
|
|
||||||
dPriv->x, dPriv->y, &bbox, fence);
|
|
||||||
|
|
||||||
} else if (visible && __dri1_api_hooks->front_srf_locked) {
|
|
||||||
|
|
||||||
struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
|
|
||||||
|
|
||||||
if (front)
|
|
||||||
dri1_swap_copy(ctx, front, surf, dPriv, &bbox);
|
|
||||||
|
|
||||||
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->stLostLock = save_lost_lock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: Revisit this: Update drawables on copy_sub_buffer ?
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!sub_box)
|
|
||||||
dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
|
|
||||||
|
|
||||||
dri_unlock(ctx);
|
|
||||||
dri1_propagate_drawable_change(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dri1_flush_frontbuffer(struct pipe_screen *screen,
|
|
||||||
struct pipe_surface *surf, void *context_private)
|
|
||||||
{
|
|
||||||
struct dri_context *ctx = (struct dri_context *)context_private;
|
|
||||||
struct pipe_fence_handle *dummy_fence;
|
|
||||||
|
|
||||||
dri1_copy_to_front(ctx, surf, ctx->dPriv, NULL, &dummy_fence);
|
|
||||||
screen->fence_reference(screen, &dummy_fence, NULL);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: Do we need swap throttling here?
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dri_swap_buffers(__DRIdrawable * dPriv)
|
|
||||||
{
|
|
||||||
struct dri_context *ctx;
|
|
||||||
struct pipe_surface *back_surf;
|
|
||||||
struct dri_drawable *draw = dri_drawable(dPriv);
|
|
||||||
struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
|
|
||||||
struct pipe_fence_handle *fence;
|
|
||||||
struct st_context *st = st_get_current();
|
|
||||||
|
|
||||||
assert(__dri1_api_hooks != NULL);
|
|
||||||
|
|
||||||
if (!st)
|
|
||||||
return; /* For now */
|
|
||||||
|
|
||||||
ctx = (struct dri_context *)st->pipe->priv;
|
|
||||||
|
|
||||||
st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
|
|
||||||
if (back_surf) {
|
|
||||||
st_notify_swapbuffers(draw->stfb);
|
|
||||||
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
|
||||||
fence = dri_swap_fences_pop_front(draw);
|
|
||||||
if (fence) {
|
|
||||||
(void)screen->fence_finish(screen, fence, 0);
|
|
||||||
screen->fence_reference(screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
dri1_copy_to_front(ctx, back_surf, dPriv, NULL, &fence);
|
|
||||||
dri_swap_fences_push_back(draw, fence);
|
|
||||||
screen->fence_reference(screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen;
|
|
||||||
struct drm_clip_rect sub_bbox;
|
|
||||||
struct dri_context *ctx;
|
|
||||||
struct pipe_surface *back_surf;
|
|
||||||
struct dri_drawable *draw = dri_drawable(dPriv);
|
|
||||||
struct pipe_fence_handle *dummy_fence;
|
|
||||||
struct st_context *st = st_get_current();
|
|
||||||
|
|
||||||
assert(__dri1_api_hooks != NULL);
|
|
||||||
|
|
||||||
if (!st)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ctx = (struct dri_context *)st->pipe->priv;
|
|
||||||
|
|
||||||
sub_bbox.x1 = x;
|
|
||||||
sub_bbox.x2 = x + w;
|
|
||||||
sub_bbox.y1 = y;
|
|
||||||
sub_bbox.y2 = y + h;
|
|
||||||
|
|
||||||
st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
|
|
||||||
if (back_surf) {
|
|
||||||
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
|
||||||
dri1_copy_to_front(ctx, back_surf, dPriv, &sub_bbox, &dummy_fence);
|
|
||||||
screen->fence_reference(screen, &dummy_fence, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vim: set sw=3 ts=8 sts=3 expandtab: */
|
/* vim: set sw=3 ts=8 sts=3 expandtab: */
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
#define DRI_DRAWABLE_H
|
#define DRI_DRAWABLE_H
|
||||||
|
|
||||||
#include "pipe/p_compiler.h"
|
#include "pipe/p_compiler.h"
|
||||||
|
#include "pipe/p_format.h"
|
||||||
|
#include "state_tracker/st_api.h"
|
||||||
|
|
||||||
struct pipe_surface;
|
struct pipe_surface;
|
||||||
struct pipe_fence_handle;
|
struct pipe_fence_handle;
|
||||||
|
|
@ -44,26 +46,26 @@ struct dri_drawable
|
||||||
__DRIdrawable *dPriv;
|
__DRIdrawable *dPriv;
|
||||||
__DRIscreen *sPriv;
|
__DRIscreen *sPriv;
|
||||||
|
|
||||||
unsigned attachments[8];
|
/* gallium */
|
||||||
unsigned num_attachments;
|
struct st_framebuffer_iface *stfb;
|
||||||
|
struct st_visual stvis;
|
||||||
boolean is_pixmap;
|
|
||||||
|
|
||||||
__DRIbuffer old[8];
|
__DRIbuffer old[8];
|
||||||
unsigned old_num;
|
unsigned old_num;
|
||||||
unsigned old_w;
|
unsigned old_w;
|
||||||
unsigned old_h;
|
unsigned old_h;
|
||||||
|
|
||||||
/* gallium */
|
struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
|
||||||
struct st_framebuffer *stfb;
|
unsigned int texture_mask, texture_stamp;
|
||||||
|
|
||||||
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
|
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
|
||||||
unsigned int head;
|
unsigned int head;
|
||||||
unsigned int tail;
|
unsigned int tail;
|
||||||
unsigned int desired_fences;
|
unsigned int desired_fences;
|
||||||
unsigned int cur_fences;
|
unsigned int cur_fences;
|
||||||
|
|
||||||
enum pipe_format color_format;
|
/* used only by DRI1 */
|
||||||
enum pipe_format depth_stencil_format;
|
struct pipe_surface *dri1_surface;
|
||||||
};
|
};
|
||||||
|
|
||||||
static INLINE struct dri_drawable *
|
static INLINE struct dri_drawable *
|
||||||
|
|
@ -80,20 +82,6 @@ dri_create_buffer(__DRIscreen * sPriv,
|
||||||
__DRIdrawable * dPriv,
|
__DRIdrawable * dPriv,
|
||||||
const __GLcontextModes * visual, boolean isPixmap);
|
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 dri_destroy_buffer(__DRIdrawable * dPriv);
|
||||||
|
|
||||||
void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
|
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,
|
void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
|
||||||
__DRIdrawable *dPriv);
|
__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
|
#endif
|
||||||
|
|
||||||
/* vim: set sw=3 ts=8 sts=3 expandtab: */
|
/* vim: set sw=3 ts=8 sts=3 expandtab: */
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,11 @@
|
||||||
void
|
void
|
||||||
dri_init_extensions(struct dri_context *ctx)
|
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
|
/* New extensions should be added in mesa/state_tracker/st_extensions.c
|
||||||
* and not in this file. */
|
* 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: */
|
/* vim: set sw=3 ts=8 sts=3 expandtab: */
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,13 @@
|
||||||
#include "dri_screen.h"
|
#include "dri_screen.h"
|
||||||
#include "dri_context.h"
|
#include "dri_context.h"
|
||||||
#include "dri_drawable.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_screen.h"
|
||||||
#include "pipe/p_format.h"
|
#include "pipe/p_format.h"
|
||||||
#include "state_tracker/drm_api.h"
|
#include "state_tracker/drm_api.h"
|
||||||
#include "state_tracker/dri1_api.h"
|
|
||||||
|
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
|
|
||||||
|
|
@ -53,7 +55,7 @@ PUBLIC const char __driConfigOptions[] =
|
||||||
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
|
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
|
||||||
DRI_CONF_SECTION_END DRI_CONF_END;
|
DRI_CONF_SECTION_END DRI_CONF_END;
|
||||||
|
|
||||||
const uint __driNConfigOptions = 3;
|
const uint __driNConfigOptions = 3;
|
||||||
|
|
||||||
static const __DRItexBufferExtension dri2TexBufferExtension = {
|
static const __DRItexBufferExtension dri2TexBufferExtension = {
|
||||||
{ __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
|
{ __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 = {
|
static const __DRI2flushExtension dri2FlushExtension = {
|
||||||
{ __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
|
{ __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
|
||||||
dri2_flush_drawable,
|
dri2_flush_drawable,
|
||||||
dri2InvalidateDrawable,
|
dri2_invalidate_drawable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const __DRIextension *dri_screen_extensions[] = {
|
static const __DRIextension *dri_screen_extensions[] = {
|
||||||
|
|
@ -83,9 +98,7 @@ static const __DRI2flushExtension dri2FlushExtension = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dri1_api *__dri1_api_hooks = NULL;
|
const __DRIconfig **
|
||||||
|
|
||||||
static const __DRIconfig **
|
|
||||||
dri_fill_in_modes(struct dri_screen *screen,
|
dri_fill_in_modes(struct dri_screen *screen,
|
||||||
unsigned pixel_bits)
|
unsigned pixel_bits)
|
||||||
{
|
{
|
||||||
|
|
@ -228,6 +241,68 @@ dri_fill_in_modes(struct dri_screen *screen,
|
||||||
return (const __DRIconfig **)configs;
|
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.
|
* Get information about previous buffer swaps.
|
||||||
*/
|
*/
|
||||||
|
|
@ -240,73 +315,31 @@ dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void
|
static void
|
||||||
dri_copy_version(struct dri1_api_version *dst,
|
dri_destroy_screen(__DRIscreen * sPriv)
|
||||||
const struct __DRIversionRec *src)
|
|
||||||
{
|
{
|
||||||
dst->major = src->major;
|
struct dri_screen *screen = dri_screen(sPriv);
|
||||||
dst->minor = src->minor;
|
int i;
|
||||||
dst->patch_level = src->patch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const __DRIconfig **
|
if (screen->dri1_pipe)
|
||||||
dri_init_screen(__DRIscreen * sPriv)
|
screen->dri1_pipe->destroy(screen->dri1_pipe);
|
||||||
{
|
|
||||||
struct dri_screen *screen;
|
|
||||||
const __DRIconfig **configs;
|
|
||||||
struct dri1_create_screen_arg arg;
|
|
||||||
|
|
||||||
screen = CALLOC_STRUCT(dri_screen);
|
if (screen->smapi)
|
||||||
if (!screen)
|
dri_destroy_st_manager(screen->smapi);
|
||||||
return NULL;
|
if (screen->pipe_screen)
|
||||||
|
screen->pipe_screen->destroy(screen->pipe_screen);
|
||||||
|
|
||||||
screen->api = drm_api_create();
|
for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
|
||||||
screen->sPriv = sPriv;
|
FREE(screen->optionCache.info[i].name);
|
||||||
screen->fd = sPriv->fd;
|
FREE(screen->optionCache.info[i].ranges);
|
||||||
screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__dri1_api_hooks = arg.api;
|
FREE(screen->optionCache.info);
|
||||||
|
FREE(screen->optionCache.values);
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
return configs;
|
|
||||||
out_no_configs:
|
|
||||||
screen->pipe_screen->destroy(screen->pipe_screen);
|
|
||||||
out_no_screen:
|
|
||||||
FREE(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);
|
screen = CALLOC_STRUCT(dri_screen);
|
||||||
if (!screen)
|
if (!screen)
|
||||||
goto fail;
|
return NULL;
|
||||||
|
|
||||||
screen->api = drm_api_create();
|
screen->api = drm_api_create();
|
||||||
screen->sPriv = sPriv;
|
screen->sPriv = sPriv;
|
||||||
|
|
@ -339,9 +372,9 @@ dri_init_screen2(__DRIscreen * sPriv)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to hook in here */
|
screen->smapi = dri_create_st_manager(screen);
|
||||||
screen->pipe_screen->update_buffer = dri_update_buffer;
|
if (!screen->smapi)
|
||||||
screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer;
|
goto fail;
|
||||||
|
|
||||||
driParseOptionInfo(&screen->optionCache,
|
driParseOptionInfo(&screen->optionCache,
|
||||||
__driConfigOptions, __driNConfigOptions);
|
__driConfigOptions, __driNConfigOptions);
|
||||||
|
|
@ -350,46 +383,27 @@ dri_init_screen2(__DRIscreen * sPriv)
|
||||||
dri2_ext->getBuffersWithFormat != NULL;
|
dri2_ext->getBuffersWithFormat != NULL;
|
||||||
|
|
||||||
return dri_fill_in_modes(screen, 32);
|
return dri_fill_in_modes(screen, 32);
|
||||||
fail:
|
fail:
|
||||||
|
dri_destroy_screen(sPriv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
const struct __DriverAPIRec driDriverAPI = {
|
||||||
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,
|
|
||||||
.DestroyScreen = dri_destroy_screen,
|
.DestroyScreen = dri_destroy_screen,
|
||||||
.CreateContext = dri_create_context,
|
.CreateContext = dri_create_context,
|
||||||
.DestroyContext = dri_destroy_context,
|
.DestroyContext = dri_destroy_context,
|
||||||
.CreateBuffer = dri_create_buffer,
|
.CreateBuffer = dri_create_buffer,
|
||||||
.DestroyBuffer = dri_destroy_buffer,
|
.DestroyBuffer = dri_destroy_buffer,
|
||||||
.SwapBuffers = dri_swap_buffers,
|
|
||||||
.MakeCurrent = dri_make_current,
|
.MakeCurrent = dri_make_current,
|
||||||
.UnbindContext = dri_unbind_context,
|
.UnbindContext = dri_unbind_context,
|
||||||
.GetSwapInfo = dri_get_swap_info,
|
.GetSwapInfo = dri_get_swap_info,
|
||||||
.GetDrawableMSC = driDrawableGetMSC32,
|
.GetDrawableMSC = driDrawableGetMSC32,
|
||||||
.WaitForMSC = driWaitForMSC32,
|
.WaitForMSC = driWaitForMSC32,
|
||||||
.CopySubBuffer = dri_copy_sub_buffer,
|
|
||||||
.InitScreen = dri_init_screen,
|
|
||||||
.InitScreen2 = dri_init_screen2,
|
.InitScreen2 = dri_init_screen2,
|
||||||
|
|
||||||
|
.InitScreen = dri1_init_screen,
|
||||||
|
.SwapBuffers = dri1_swap_buffers,
|
||||||
|
.CopySubBuffer = dri1_copy_sub_buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is the table of extensions that the loader will dlsym() for. */
|
/* This is the table of extensions that the loader will dlsym() for. */
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,9 @@
|
||||||
#include "xmlconfig.h"
|
#include "xmlconfig.h"
|
||||||
|
|
||||||
#include "pipe/p_compiler.h"
|
#include "pipe/p_compiler.h"
|
||||||
|
#include "pipe/p_context.h"
|
||||||
#include "state_tracker/dri1_api.h"
|
#include "pipe/p_state.h"
|
||||||
|
#include "state_tracker/st_api.h"
|
||||||
|
|
||||||
struct dri_screen
|
struct dri_screen
|
||||||
{
|
{
|
||||||
|
|
@ -60,6 +61,11 @@ struct dri_screen
|
||||||
boolean d_depth_bits_last;
|
boolean d_depth_bits_last;
|
||||||
boolean sd_depth_bits_last;
|
boolean sd_depth_bits_last;
|
||||||
boolean auto_fake_front;
|
boolean auto_fake_front;
|
||||||
|
|
||||||
|
struct st_manager *smapi;
|
||||||
|
|
||||||
|
/* used only by DRI1 */
|
||||||
|
struct pipe_context *dri1_pipe;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** cast wrapper */
|
/** cast wrapper */
|
||||||
|
|
@ -69,11 +75,14 @@ dri_screen(__DRIscreen * sPriv)
|
||||||
return (struct dri_screen *)sPriv->private;
|
return (struct dri_screen *)sPriv->private;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
extern const uint __driNConfigOptions;
|
||||||
* dri_screen.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern struct dri1_api *__dri1_api_hooks;
|
const __DRIconfig **
|
||||||
|
dri_fill_in_modes(struct dri_screen *screen, unsigned pixel_bits);
|
||||||
|
|
||||||
|
void
|
||||||
|
dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
|
||||||
|
const __GLcontextModes *mode);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
445
src/gallium/state_trackers/dri/dri_st_api.c
Normal file
445
src/gallium/state_trackers/dri/dri_st_api.c
Normal file
|
|
@ -0,0 +1,445 @@
|
||||||
|
/*
|
||||||
|
* Mesa 3-D graphics library
|
||||||
|
* Version: 7.9
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 LunarG Inc.
|
||||||
|
*
|
||||||
|
* 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, sublicense,
|
||||||
|
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* BRIAN PAUL 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.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Chia-I Wu <olv@lunarg.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "util/u_memory.h"
|
||||||
|
#include "util/u_inlines.h"
|
||||||
|
#include "util/u_format.h"
|
||||||
|
#include "util/u_debug.h"
|
||||||
|
#include "state_tracker/drm_api.h"
|
||||||
|
#include "state_tracker/st_manager.h" /* for st_manager_create_api */
|
||||||
|
|
||||||
|
#include "dri_screen.h"
|
||||||
|
#include "dri_context.h"
|
||||||
|
#include "dri_drawable.h"
|
||||||
|
#include "dri_st_api.h"
|
||||||
|
#include "dri1.h"
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int32_t refcnt;
|
||||||
|
struct st_api *stapi;
|
||||||
|
} dri_st_api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the format of an attachment.
|
||||||
|
*/
|
||||||
|
static INLINE enum pipe_format
|
||||||
|
dri_drawable_get_format(struct dri_drawable *drawable,
|
||||||
|
enum st_attachment_type statt)
|
||||||
|
{
|
||||||
|
enum pipe_format format;
|
||||||
|
|
||||||
|
switch (statt) {
|
||||||
|
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;
|
||||||
|
break;
|
||||||
|
case ST_ATTACHMENT_DEPTH_STENCIL:
|
||||||
|
format = drawable->stvis.depth_stencil_format;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
format = PIPE_FORMAT_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process __DRIbuffer and convert them into pipe_textures.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dri_drawable_process_buffers(struct dri_drawable *drawable,
|
||||||
|
__DRIbuffer *buffers, unsigned count)
|
||||||
|
{
|
||||||
|
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||||
|
__DRIdrawable *dri_drawable = drawable->dPriv;
|
||||||
|
struct pipe_texture templ;
|
||||||
|
struct winsys_handle whandle;
|
||||||
|
boolean have_depth = FALSE;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (drawable->old_num == count &&
|
||||||
|
drawable->old_w == dri_drawable->w &&
|
||||||
|
drawable->old_h == dri_drawable->h &&
|
||||||
|
memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
|
||||||
|
pipe_texture_reference(&drawable->textures[i], NULL);
|
||||||
|
|
||||||
|
memset(&templ, 0, sizeof(templ));
|
||||||
|
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
|
||||||
|
templ.target = PIPE_TEXTURE_2D;
|
||||||
|
templ.last_level = 0;
|
||||||
|
templ.width0 = dri_drawable->w;
|
||||||
|
templ.height0 = dri_drawable->h;
|
||||||
|
templ.depth0 = 1;
|
||||||
|
|
||||||
|
memset(&whandle, 0, sizeof(whandle));
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
__DRIbuffer *buf = &buffers[i];
|
||||||
|
enum st_attachment_type statt;
|
||||||
|
enum pipe_format format;
|
||||||
|
|
||||||
|
switch (buf->attachment) {
|
||||||
|
case __DRI_BUFFER_FRONT_LEFT:
|
||||||
|
if (!screen->auto_fake_front) {
|
||||||
|
statt = ST_ATTACHMENT_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fallthrough */
|
||||||
|
case __DRI_BUFFER_FAKE_FRONT_LEFT:
|
||||||
|
statt = ST_ATTACHMENT_FRONT_LEFT;
|
||||||
|
break;
|
||||||
|
case __DRI_BUFFER_BACK_LEFT:
|
||||||
|
statt = ST_ATTACHMENT_BACK_LEFT;
|
||||||
|
break;
|
||||||
|
case __DRI_BUFFER_DEPTH:
|
||||||
|
case __DRI_BUFFER_DEPTH_STENCIL:
|
||||||
|
case __DRI_BUFFER_STENCIL:
|
||||||
|
statt = ST_ATTACHMENT_DEPTH_STENCIL;
|
||||||
|
/* use only the first depth/stencil buffer */
|
||||||
|
if (have_depth)
|
||||||
|
statt = ST_ATTACHMENT_INVALID;
|
||||||
|
else
|
||||||
|
have_depth = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statt = ST_ATTACHMENT_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
format = dri_drawable_get_format(drawable, statt);
|
||||||
|
if (statt == ST_ATTACHMENT_INVALID || format == PIPE_FORMAT_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
templ.format = format;
|
||||||
|
whandle.handle = buf->name;
|
||||||
|
whandle.stride = buf->pitch;
|
||||||
|
|
||||||
|
drawable->textures[statt] =
|
||||||
|
screen->pipe_screen->texture_from_handle(screen->pipe_screen,
|
||||||
|
&templ, &whandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawable->old_num = count;
|
||||||
|
drawable->old_w = dri_drawable->w;
|
||||||
|
drawable->old_h = dri_drawable->h;
|
||||||
|
memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve __DRIbuffer from the DRI loader.
|
||||||
|
*/
|
||||||
|
static __DRIbuffer *
|
||||||
|
dri_drawable_get_buffers(struct dri_drawable *drawable,
|
||||||
|
const enum st_attachment_type *statts,
|
||||||
|
unsigned *count)
|
||||||
|
{
|
||||||
|
__DRIdrawable *dri_drawable = drawable->dPriv;
|
||||||
|
struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
|
||||||
|
boolean with_format;
|
||||||
|
__DRIbuffer *buffers;
|
||||||
|
int num_buffers;
|
||||||
|
unsigned attachments[8];
|
||||||
|
unsigned num_attachments, i;
|
||||||
|
|
||||||
|
assert(loader);
|
||||||
|
with_format = (loader->base.version > 2 && loader->getBuffersWithFormat);
|
||||||
|
|
||||||
|
num_attachments = 0;
|
||||||
|
for (i = 0; i < *count; i++) {
|
||||||
|
enum pipe_format format;
|
||||||
|
int att;
|
||||||
|
|
||||||
|
format = dri_drawable_get_format(drawable, statts[i]);
|
||||||
|
if (format == PIPE_FORMAT_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (statts[i]) {
|
||||||
|
case ST_ATTACHMENT_FRONT_LEFT:
|
||||||
|
att = __DRI_BUFFER_FRONT_LEFT;
|
||||||
|
break;
|
||||||
|
case ST_ATTACHMENT_BACK_LEFT:
|
||||||
|
att = __DRI_BUFFER_BACK_LEFT;
|
||||||
|
break;
|
||||||
|
case ST_ATTACHMENT_FRONT_RIGHT:
|
||||||
|
att = __DRI_BUFFER_FRONT_RIGHT;
|
||||||
|
break;
|
||||||
|
case ST_ATTACHMENT_BACK_RIGHT:
|
||||||
|
att = __DRI_BUFFER_BACK_RIGHT;
|
||||||
|
break;
|
||||||
|
case ST_ATTACHMENT_DEPTH_STENCIL:
|
||||||
|
att = __DRI_BUFFER_DEPTH_STENCIL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
att = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (att >= 0) {
|
||||||
|
attachments[num_attachments++] = att;
|
||||||
|
if (with_format) {
|
||||||
|
attachments[num_attachments++] =
|
||||||
|
util_format_get_blocksizebits(format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (with_format) {
|
||||||
|
num_attachments /= 2;
|
||||||
|
buffers = loader->getBuffersWithFormat(dri_drawable,
|
||||||
|
&dri_drawable->w, &dri_drawable->h,
|
||||||
|
attachments, num_attachments,
|
||||||
|
&num_buffers, dri_drawable->loaderPrivate);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buffers = loader->getBuffers(dri_drawable,
|
||||||
|
&dri_drawable->w, &dri_drawable->h,
|
||||||
|
attachments, num_attachments,
|
||||||
|
&num_buffers, dri_drawable->loaderPrivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffers) {
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
*count = num_buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
|
||||||
|
const enum st_attachment_type *statts,
|
||||||
|
unsigned count,
|
||||||
|
struct pipe_texture **out)
|
||||||
|
{
|
||||||
|
struct dri_drawable *drawable =
|
||||||
|
(struct dri_drawable *) stfbi->st_manager_private;
|
||||||
|
unsigned statt_mask, i;
|
||||||
|
|
||||||
|
statt_mask = 0x0;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
statt_mask |= (1 << statts[i]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dPriv->pStamp is the server stamp. It should be accessed with a lock, at
|
||||||
|
* least for DRI1. dPriv->lastStamp is the client stamp. It has the value
|
||||||
|
* of the server stamp when last checked.
|
||||||
|
*
|
||||||
|
* This function updates the textures and records the stamp of the textures.
|
||||||
|
*/
|
||||||
|
if (drawable->texture_stamp != drawable->dPriv->lastStamp ||
|
||||||
|
(statt_mask & ~drawable->texture_mask)) {
|
||||||
|
if (__dri1_api_hooks) {
|
||||||
|
dri1_allocate_textures(drawable,
|
||||||
|
drawable->dPriv->w, drawable->dPriv->h, statt_mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
__DRIbuffer *buffers;
|
||||||
|
unsigned num_buffers = count;
|
||||||
|
|
||||||
|
buffers = dri_drawable_get_buffers(drawable, statts, &num_buffers);
|
||||||
|
dri_drawable_process_buffers(drawable, buffers, num_buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawable->texture_stamp = drawable->dPriv->lastStamp;
|
||||||
|
drawable->texture_mask = statt_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!out)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
out[i] = NULL;
|
||||||
|
pipe_texture_reference(&out[i], drawable->textures[statts[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
|
||||||
|
enum st_attachment_type statt)
|
||||||
|
{
|
||||||
|
struct dri_drawable *drawable =
|
||||||
|
(struct dri_drawable *) stfbi->st_manager_private;
|
||||||
|
struct __DRIdri2LoaderExtensionRec *loader =
|
||||||
|
drawable->sPriv->dri2.loader;
|
||||||
|
|
||||||
|
if (__dri1_api_hooks) {
|
||||||
|
struct pipe_texture *ptex = drawable->textures[statt];
|
||||||
|
if (ptex)
|
||||||
|
dri1_flush_frontbuffer(drawable, ptex);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statt == ST_ATTACHMENT_FRONT_LEFT && loader->flushFrontBuffer) {
|
||||||
|
loader->flushFrontBuffer(drawable->dPriv,
|
||||||
|
drawable->dPriv->loaderPrivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a framebuffer from the given drawable.
|
||||||
|
*/
|
||||||
|
struct st_framebuffer_iface *
|
||||||
|
dri_create_st_framebuffer(struct dri_drawable *drawable)
|
||||||
|
{
|
||||||
|
struct st_framebuffer_iface *stfbi;
|
||||||
|
|
||||||
|
stfbi = CALLOC_STRUCT(st_framebuffer_iface);
|
||||||
|
if (stfbi) {
|
||||||
|
stfbi->visual = &drawable->stvis;
|
||||||
|
stfbi->flush_front = dri_st_framebuffer_flush_front;
|
||||||
|
stfbi->validate = dri_st_framebuffer_validate;
|
||||||
|
stfbi->st_manager_private = (void *) drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stfbi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a framebuffer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
|
||||||
|
{
|
||||||
|
FREE(stfbi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the texture at an attachment. Allocate the texture if it does not
|
||||||
|
* exist.
|
||||||
|
*/
|
||||||
|
struct pipe_texture *
|
||||||
|
dri_get_st_framebuffer_texture(struct st_framebuffer_iface *stfbi,
|
||||||
|
enum st_attachment_type statt)
|
||||||
|
{
|
||||||
|
struct dri_drawable *drawable =
|
||||||
|
(struct dri_drawable *) stfbi->st_manager_private;
|
||||||
|
|
||||||
|
if (!(drawable->texture_mask & (1 << statt))) {
|
||||||
|
enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
|
||||||
|
unsigned i, count = 0;
|
||||||
|
|
||||||
|
/* make sure DRI2 does not destroy existing buffers */
|
||||||
|
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
|
||||||
|
if (drawable->texture_mask & (1 << i)) {
|
||||||
|
statts[count++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statts[count++] = statt;
|
||||||
|
|
||||||
|
drawable->texture_stamp = drawable->dPriv->lastStamp - 1;
|
||||||
|
dri_st_framebuffer_validate(stfbi, statts, count, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return drawable->textures[statt];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a reference to the st_api of the state tracker.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_dri_get_st_api(void)
|
||||||
|
{
|
||||||
|
p_atomic_inc(&dri_st_api.refcnt);
|
||||||
|
if (p_atomic_read(&dri_st_api.refcnt) == 1)
|
||||||
|
dri_st_api.stapi = st_manager_create_api();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a reference to the st_api of the state tracker.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_dri_put_st_api(void)
|
||||||
|
{
|
||||||
|
struct st_api *stapi = dri_st_api.stapi;
|
||||||
|
|
||||||
|
if (p_atomic_dec_zero(&dri_st_api.refcnt)) {
|
||||||
|
stapi->destroy(dri_st_api.stapi);
|
||||||
|
dri_st_api.stapi = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a state tracker manager from the given screen.
|
||||||
|
*/
|
||||||
|
struct st_manager *
|
||||||
|
dri_create_st_manager(struct dri_screen *screen)
|
||||||
|
{
|
||||||
|
struct st_manager *smapi;
|
||||||
|
|
||||||
|
smapi = CALLOC_STRUCT(st_manager);
|
||||||
|
if (smapi) {
|
||||||
|
smapi->screen = screen->pipe_screen;
|
||||||
|
_dri_get_st_api();
|
||||||
|
}
|
||||||
|
|
||||||
|
return smapi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a state tracker manager.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dri_destroy_st_manager(struct st_manager *smapi)
|
||||||
|
{
|
||||||
|
_dri_put_st_api();
|
||||||
|
FREE(smapi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the st_api of OpenGL state tracker.
|
||||||
|
*/
|
||||||
|
struct st_api *
|
||||||
|
dri_get_st_api(void)
|
||||||
|
{
|
||||||
|
assert(dri_st_api.stapi);
|
||||||
|
return dri_st_api.stapi;
|
||||||
|
}
|
||||||
55
src/gallium/state_trackers/dri/dri_st_api.h
Normal file
55
src/gallium/state_trackers/dri/dri_st_api.h
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Mesa 3-D graphics library
|
||||||
|
* Version: 7.9
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 LunarG Inc.
|
||||||
|
*
|
||||||
|
* 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, sublicense,
|
||||||
|
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* BRIAN PAUL 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.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Chia-I Wu <olv@lunarg.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DRI_ST_API_H_
|
||||||
|
#define _DRI_ST_API_H_
|
||||||
|
|
||||||
|
#include "state_tracker/st_api.h"
|
||||||
|
|
||||||
|
struct dri_screen;
|
||||||
|
struct dri_drawable;
|
||||||
|
|
||||||
|
struct st_api *
|
||||||
|
dri_get_st_api(void);
|
||||||
|
|
||||||
|
struct st_manager *
|
||||||
|
dri_create_st_manager(struct dri_screen *screen);
|
||||||
|
|
||||||
|
void
|
||||||
|
dri_destroy_st_manager(struct st_manager *smapi);
|
||||||
|
|
||||||
|
struct st_framebuffer_iface *
|
||||||
|
dri_create_st_framebuffer(struct dri_drawable *drawable);
|
||||||
|
|
||||||
|
void
|
||||||
|
dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
|
||||||
|
|
||||||
|
struct pipe_texture *
|
||||||
|
dri_get_st_framebuffer_texture(struct st_framebuffer_iface *stfbi,
|
||||||
|
enum st_attachment_type statt);
|
||||||
|
|
||||||
|
#endif /* _DRI_ST_API_H_ */
|
||||||
|
|
@ -553,6 +553,7 @@ st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type target
|
||||||
_mesa_clear_texture_image(ctx, texImage);
|
_mesa_clear_texture_image(ctx, texImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stObj->pipe = st->pipe;
|
||||||
pipe_texture_reference(&stImage->pt, tex);
|
pipe_texture_reference(&stImage->pt, tex);
|
||||||
|
|
||||||
_mesa_dirty_texobj(ctx, texObj, GL_TRUE);
|
_mesa_dirty_texobj(ctx, texObj, GL_TRUE);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue