Merge commit 'origin/gallium-winsys-handle-rebased'

This commit is contained in:
Keith Whitwell 2010-03-08 12:03:46 +00:00
commit 3ca933623c
43 changed files with 860 additions and 962 deletions

View file

@ -219,12 +219,12 @@ i915_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);
/* used for scanouts that need special layouts */
if (pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
if (pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
if (i915_scanout_layout(tex))
return;
/* for shared buffers we use something very like scanout */
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
/* shared buffers needs to be compatible with X servers */
if (pt->tex_usage & PIPE_TEXTURE_USAGE_SHARED)
if (i915_display_target_layout(tex))
return;
@ -369,12 +369,12 @@ i945_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0);
/* used for scanouts that need special layouts */
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
if (i915_scanout_layout(tex))
return;
/* for shared buffers we use some very like scanout */
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
/* shared buffers needs to be compatible with X servers */
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SHARED)
if (i915_display_target_layout(tex))
return;
@ -642,7 +642,7 @@ i915_texture_create(struct pipe_screen *screen,
/* for scanouts and cursors, cursors arn't scanouts */
if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width0 != 64)
if (templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT && templat->width0 != 64)
buf_usage = INTEL_NEW_SCANOUT;
else
buf_usage = INTEL_NEW_TEXTURE;
@ -672,6 +672,58 @@ fail:
return NULL;
}
static struct pipe_texture *
i915_texture_from_handle(struct pipe_screen * screen,
const struct pipe_texture *templat,
struct winsys_handle *whandle)
{
struct i915_screen *is = i915_screen(screen);
struct i915_texture *tex;
struct intel_winsys *iws = is->iws;
struct intel_buffer *buffer;
unsigned stride;
assert(screen);
buffer = iws->buffer_from_handle(iws, whandle, &stride);
/* Only supports one type */
if (templat->target != PIPE_TEXTURE_2D ||
templat->last_level != 0 ||
templat->depth0 != 1) {
return NULL;
}
tex = CALLOC_STRUCT(i915_texture);
if (!tex)
return NULL;
tex->base = *templat;
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
tex->stride = stride;
i915_miptree_set_level_info(tex, 0, 1, templat->width0, templat->height0, 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
tex->buffer = buffer;
return &tex->base;
}
static boolean
i915_texture_get_handle(struct pipe_screen * screen,
struct pipe_texture *texture,
struct winsys_handle *whandle)
{
struct i915_screen *is = i915_screen(screen);
struct i915_texture *tex = (struct i915_texture *)texture;
struct intel_winsys *iws = is->iws;
return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride);
}
static struct pipe_texture *
i915_texture_blanket(struct pipe_screen * screen,
const struct pipe_texture *base,
@ -869,6 +921,8 @@ void
i915_init_screen_texture_functions(struct i915_screen *is)
{
is->base.texture_create = i915_texture_create;
is->base.texture_from_handle = i915_texture_from_handle;
is->base.texture_get_handle = i915_texture_get_handle;
is->base.texture_blanket = i915_texture_blanket;
is->base.texture_destroy = i915_texture_destroy;
is->base.get_tex_surface = i915_get_tex_surface;
@ -878,53 +932,3 @@ i915_init_screen_texture_functions(struct i915_screen *is)
is->base.transfer_unmap = i915_transfer_unmap;
is->base.tex_transfer_destroy = i915_tex_transfer_destroy;
}
struct pipe_texture *
i915_texture_blanket_intel(struct pipe_screen *screen,
struct pipe_texture *base,
unsigned stride,
struct intel_buffer *buffer)
{
struct i915_texture *tex;
assert(screen);
/* Only supports one type */
if (base->target != PIPE_TEXTURE_2D ||
base->last_level != 0 ||
base->depth0 != 1) {
return NULL;
}
tex = CALLOC_STRUCT(i915_texture);
if (!tex)
return NULL;
tex->base = *base;
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
tex->stride = stride;
i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
tex->buffer = buffer;
return &tex->base;
}
boolean
i915_get_texture_buffer_intel(struct pipe_texture *texture,
struct intel_buffer **buffer,
unsigned *stride)
{
struct i915_texture *tex = (struct i915_texture *)texture;
if (!texture)
return FALSE;
*stride = tex->stride;
*buffer = tex->buffer;
return TRUE;
}

View file

@ -33,6 +33,7 @@ struct intel_buffer;
struct intel_batchbuffer;
struct pipe_texture;
struct pipe_fence_handle;
struct winsys_handle;
enum intel_buffer_usage
{
@ -128,6 +129,25 @@ struct intel_winsys {
unsigned size, unsigned alignment,
enum intel_buffer_type type);
/**
* Creates a buffer from a handle.
* Used to implement pipe_screen::texture_from_handle.
* Also provides the stride information needed for the
* texture via the stride argument.
*/
struct intel_buffer *(*buffer_from_handle)(struct intel_winsys *iws,
struct winsys_handle *whandle,
unsigned *stride);
/**
* Used to implement pipe_screen::texture_get_handle.
* The winsys might need the stride information.
*/
boolean (*buffer_get_handle)(struct intel_winsys *iws,
struct intel_buffer *buffer,
struct winsys_handle *whandle,
unsigned stride);
/**
* Fence a buffer with a fence reg.
* Not to be confused with pipe_fence_handle.
@ -204,23 +224,4 @@ struct intel_winsys {
struct pipe_screen *i915_create_screen(struct intel_winsys *iws, unsigned pci_id);
/**
* Get the intel_winsys buffer backing the texture.
*
* TODO UGLY
*/
boolean i915_get_texture_buffer_intel(struct pipe_texture *texture,
struct intel_buffer **buffer,
unsigned *stride);
/**
* Wrap a intel_winsys buffer with a texture blanket.
*
* TODO UGLY
*/
struct pipe_texture * i915_texture_blanket_intel(struct pipe_screen *screen,
struct pipe_texture *tmplt,
unsigned pitch,
struct intel_buffer *buffer);
#endif

View file

@ -231,8 +231,8 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen,
goto fail;
if (templ->tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY)) {
if (templ->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED)) {
buffer_type = BRW_BUFFER_TYPE_SCANOUT;
}
else {
@ -303,6 +303,119 @@ fail:
return NULL;
}
static struct pipe_texture *
brw_texture_from_handle(struct pipe_screen *screen,
const struct pipe_texture *templ,
struct winsys_handle *whandle)
{
struct brw_screen *bscreen = brw_screen(screen);
struct brw_texture *tex;
struct brw_winsys_buffer *buffer;
unsigned tiling;
unsigned pitch;
if (templ->target != PIPE_TEXTURE_2D ||
templ->last_level != 0 ||
templ->depth0 != 1)
return NULL;
if (util_format_is_compressed(templ->format))
return NULL;
tex = CALLOC_STRUCT(brw_texture);
if (!tex)
return NULL;
if (bscreen->sws->bo_from_handle(bscreen->sws, whandle, &pitch, &tiling, &buffer) != PIPE_OK)
goto fail;
memcpy(&tex->base, templ, sizeof *templ);
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
/* XXX: cpp vs. blocksize
*/
tex->cpp = util_format_get_blocksize(tex->base.format);
tex->tiling = tiling;
make_empty_list(&tex->views[0]);
make_empty_list(&tex->views[1]);
if (!brw_texture_layout(bscreen, tex))
goto fail;
/* XXX Maybe some more checks? */
if ((pitch / tex->cpp) < tex->pitch)
goto fail;
tex->pitch = pitch / tex->cpp;
tex->bo = buffer;
/* fix this warning */
#if 0
if (tex->size > buffer->size)
goto fail;
#endif
tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
tex->ss.ss0.surface_format = translate_tex_format(tex->base.format);
assert(tex->ss.ss0.surface_format != BRW_SURFACEFORMAT_INVALID);
/* This is ok for all textures with channel width 8bit or less:
*/
/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
/* XXX: what happens when tex->bo->offset changes???
*/
tex->ss.ss1.base_addr = 0; /* reloc */
tex->ss.ss2.mip_count = tex->base.last_level;
tex->ss.ss2.width = tex->base.width0 - 1;
tex->ss.ss2.height = tex->base.height0 - 1;
switch (tex->tiling) {
case BRW_TILING_NONE:
tex->ss.ss3.tiled_surface = 0;
tex->ss.ss3.tile_walk = 0;
break;
case BRW_TILING_X:
tex->ss.ss3.tiled_surface = 1;
tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
break;
case BRW_TILING_Y:
tex->ss.ss3.tiled_surface = 1;
tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
break;
}
tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
tex->ss.ss3.depth = tex->base.depth0 - 1;
tex->ss.ss4.min_lod = 0;
return &tex->base;
fail:
FREE(tex);
return NULL;
}
static boolean
brw_texture_get_handle(struct pipe_screen *screen,
struct pipe_texture *texture,
struct winsys_handle *whandle)
{
struct brw_screen *bscreen = brw_screen(screen);
struct brw_texture *tex = brw_texture(texture);
unsigned stride;
stride = tex->pitch * tex->cpp;
return bscreen->sws->bo_get_handle(tex->bo, whandle, stride);
}
static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen,
const struct pipe_texture *templ,
const unsigned *stride,
@ -451,125 +564,12 @@ brw_tex_transfer_destroy(struct pipe_transfer *trans)
}
/*
* Functions exported to the winsys
*/
boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
struct brw_winsys_buffer **buffer,
unsigned *stride)
{
struct brw_texture *tex = brw_texture(texture);
*buffer = tex->bo;
if (stride)
*stride = tex->pitch * tex->cpp;
return TRUE;
}
struct pipe_texture *
brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
const struct pipe_texture *templ,
unsigned pitch,
unsigned tiling,
struct brw_winsys_buffer *buffer)
{
struct brw_screen *bscreen = brw_screen(screen);
struct brw_texture *tex;
GLuint format;
if (templ->target != PIPE_TEXTURE_2D ||
templ->last_level != 0 ||
templ->depth0 != 1)
return NULL;
if (util_format_is_compressed(templ->format))
return NULL;
tex = CALLOC_STRUCT(brw_texture);
if (!tex)
return NULL;
memcpy(&tex->base, templ, sizeof *templ);
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
/* XXX: cpp vs. blocksize
*/
tex->cpp = util_format_get_blocksize(tex->base.format);
tex->tiling = tiling;
make_empty_list(&tex->views[0]);
make_empty_list(&tex->views[1]);
if (!brw_texture_layout(bscreen, tex))
goto fail;
/* XXX Maybe some more checks? */
if ((pitch / tex->cpp) < tex->pitch)
goto fail;
tex->pitch = pitch / tex->cpp;
tex->bo = buffer;
/* fix this warning */
#if 0
if (tex->size > buffer->size)
goto fail;
#endif
tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
format = translate_tex_format(tex->base.format);
assert(format != BRW_SURFACEFORMAT_INVALID);
tex->ss.ss0.surface_format = format;
/* This is ok for all textures with channel width 8bit or less:
*/
/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
/* XXX: what happens when tex->bo->offset changes???
*/
tex->ss.ss1.base_addr = 0; /* reloc */
tex->ss.ss2.mip_count = tex->base.last_level;
tex->ss.ss2.width = tex->base.width0 - 1;
tex->ss.ss2.height = tex->base.height0 - 1;
switch (tex->tiling) {
case BRW_TILING_NONE:
tex->ss.ss3.tiled_surface = 0;
tex->ss.ss3.tile_walk = 0;
break;
case BRW_TILING_X:
tex->ss.ss3.tiled_surface = 1;
tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
break;
case BRW_TILING_Y:
tex->ss.ss3.tiled_surface = 1;
tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
break;
}
tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
tex->ss.ss3.depth = tex->base.depth0 - 1;
tex->ss.ss4.min_lod = 0;
return &tex->base;
fail:
FREE(tex);
return NULL;
}
void brw_screen_tex_init( struct brw_screen *brw_screen )
{
brw_screen->base.is_format_supported = brw_is_format_supported;
brw_screen->base.texture_create = brw_texture_create;
brw_screen->base.texture_from_handle = brw_texture_from_handle;
brw_screen->base.texture_get_handle = brw_texture_get_handle;
brw_screen->base.texture_destroy = brw_texture_destroy;
brw_screen->base.texture_blanket = brw_texture_blanket;
brw_screen->base.get_tex_transfer = brw_get_tex_transfer;

View file

@ -162,6 +162,16 @@ struct brw_winsys_screen {
unsigned alignment,
struct brw_winsys_buffer **bo_out);
enum pipe_error (*bo_from_handle)(struct brw_winsys_screen *sws,
struct winsys_handle *whandle,
unsigned *stride,
unsigned *tiling,
struct brw_winsys_buffer **bo_out);
enum pipe_error (*bo_get_handle)(struct brw_winsys_buffer *buffer,
struct winsys_handle *whandle,
unsigned stride);
/* Destroy a buffer when our refcount goes to zero:
*/
void (*bo_destroy)(struct brw_winsys_buffer *buffer);

View file

@ -63,62 +63,6 @@ identity_drm_create_screen(struct drm_api *_api, int fd,
return identity_screen_create(screen);
}
static struct pipe_texture *
identity_drm_texture_from_shared_handle(struct drm_api *_api,
struct pipe_screen *_screen,
struct pipe_texture *templ,
const char *name,
unsigned stride,
unsigned handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct identity_drm_api *id_api = identity_drm_api(_api);
struct pipe_screen *screen = id_screen->screen;
struct drm_api *api = id_api->api;
struct pipe_texture *result;
result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
result = identity_texture_create(identity_screen(_screen), result);
return result;
}
static boolean
identity_drm_shared_handle_from_texture(struct drm_api *_api,
struct pipe_screen *_screen,
struct pipe_texture *_texture,
unsigned *stride,
unsigned *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct identity_texture *id_texture = identity_texture(_texture);
struct identity_drm_api *id_api = identity_drm_api(_api);
struct pipe_screen *screen = id_screen->screen;
struct pipe_texture *texture = id_texture->texture;
struct drm_api *api = id_api->api;
return api->shared_handle_from_texture(api, screen, texture, stride, handle);
}
static boolean
identity_drm_local_handle_from_texture(struct drm_api *_api,
struct pipe_screen *_screen,
struct pipe_texture *_texture,
unsigned *stride,
unsigned *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct identity_texture *id_texture = identity_texture(_texture);
struct identity_drm_api *id_api = identity_drm_api(_api);
struct pipe_screen *screen = id_screen->screen;
struct pipe_texture *texture = id_texture->texture;
struct drm_api *api = id_api->api;
return api->local_handle_from_texture(api, screen, texture, stride, handle);
}
static void
identity_drm_destroy(struct drm_api *_api)
{
@ -145,9 +89,6 @@ identity_drm_create(struct drm_api *api)
id_api->base.name = api->name;
id_api->base.driver_name = api->driver_name;
id_api->base.create_screen = identity_drm_create_screen;
id_api->base.texture_from_shared_handle = identity_drm_texture_from_shared_handle;
id_api->base.shared_handle_from_texture = identity_drm_shared_handle_from_texture;
id_api->base.local_handle_from_texture = identity_drm_local_handle_from_texture;
id_api->base.destroy = identity_drm_destroy;
id_api->api = api;

View file

@ -134,6 +134,39 @@ identity_screen_texture_create(struct pipe_screen *_screen,
return NULL;
}
static struct pipe_texture *
identity_screen_texture_from_handle(struct pipe_screen *_screen,
const struct pipe_texture *templ,
struct winsys_handle *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct pipe_screen *screen = id_screen->screen;
struct pipe_texture *result;
/* TODO trace call */
result = screen->texture_from_handle(screen, templ, handle);
result = identity_texture_create(identity_screen(_screen), result);
return result;
}
static boolean
identity_screen_texture_get_handle(struct pipe_screen *_screen,
struct pipe_texture *_texture,
struct winsys_handle *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct identity_texture *id_texture = identity_texture(_texture);
struct pipe_screen *screen = id_screen->screen;
struct pipe_texture *texture = id_texture->texture;
/* TODO trace call */
return screen->texture_get_handle(screen, texture, handle);
}
static struct pipe_texture *
identity_screen_texture_blanket(struct pipe_screen *_screen,
const struct pipe_texture *templat,
@ -495,6 +528,8 @@ identity_screen_create(struct pipe_screen *screen)
id_screen->base.is_format_supported = identity_screen_is_format_supported;
id_screen->base.context_create = identity_screen_context_create;
id_screen->base.texture_create = identity_screen_texture_create;
id_screen->base.texture_from_handle = identity_screen_texture_from_handle;
id_screen->base.texture_get_handle = identity_screen_texture_get_handle;
id_screen->base.texture_blanket = identity_screen_texture_blanket;
id_screen->base.texture_destroy = identity_screen_texture_destroy;
id_screen->base.get_tex_surface = identity_screen_get_tex_surface;

View file

@ -125,7 +125,8 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
lpt->base.screen = &screen->base;
if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY)) {
PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED)) {
if (!llvmpipe_displaytarget_layout(screen, lpt))
goto fail;
}

View file

@ -4,6 +4,7 @@
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
#include <stdio.h>
#include <errno.h>
@ -12,6 +13,9 @@
#include "nouveau_winsys.h"
#include "nouveau_screen.h"
/* XXX this should go away */
#include "state_tracker/drm_api.h"
static const char *
nouveau_screen_get_name(struct pipe_screen *pscreen)
{
@ -231,6 +235,71 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
return 0;
}
/*
* Both texture_{from|get}_handle use drm api defines directly which they
* shouldn't do. The problem is that from|get are pipe functions and as
* such they should be defined in the pipe level. If nouveau had a propper
* winsys interface we would have added from|get to that interface using
* the winsys_handle struct as done with other drivers. However this code
* calls directly into the libdrm_nouveau.so functions (nouveau_bo_*). So
* we need to translate the handle into something they understand.
*/
static struct pipe_texture *
nouveau_screen_texture_from_handle(struct pipe_screen *pscreen,
const struct pipe_texture *templ,
struct winsys_handle *whandle)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct pipe_texture *pt;
struct pipe_buffer *pb;
int ret;
pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
if (!pb)
return NULL;
ret = nouveau_bo_handle_ref(dev, whandle->handle, (struct nouveau_bo**)(pb+1));
if (ret) {
debug_printf("%s: ref name 0x%08x failed with %d\n",
__func__, whandle->handle, ret);
FREE(pb);
return NULL;
}
pipe_reference_init(&pb->reference, 1);
pb->screen = pscreen;
pb->alignment = 0;
pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
PIPE_BUFFER_USAGE_CPU_READ_WRITE;
pb->size = nouveau_bo(pb)->size;
pt = pscreen->texture_blanket(pscreen, templ, &whandle->stride, pb);
pipe_buffer_reference(&pb, NULL);
return pt;
}
static boolean
nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
struct pipe_texture *pt,
struct winsys_handle *whandle)
{
struct nouveau_miptree *mt = nouveau_miptree(pt);
if (!mt || !mt->bo)
return false;
whandle->stride = util_format_get_stride(mt->base.format, mt->base.width0);
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
return nouveau_bo_handle_get(mt->bo, &whandle->handle) == 0;
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
whandle->handle = mt->bo->handle;
return TRUE;
} else {
return FALSE;
}
}
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
@ -258,6 +327,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
pscreen->fence_signalled = nouveau_screen_fence_signalled;
pscreen->fence_finish = nouveau_screen_fence_finish;
pscreen->texture_from_handle = nouveau_screen_texture_from_handle;
pscreen->texture_get_handle = nouveau_screen_texture_get_handle;
return 0;
}

View file

@ -18,7 +18,7 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY);
PIPE_TEXTURE_USAGE_SCANOUT);
if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
@ -78,7 +78,7 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
pt->height0 & (pt->height0 - 1))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;

View file

@ -20,7 +20,7 @@ nv40_miptree_layout(struct nv40_miptree *mt)
PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY);
PIPE_TEXTURE_USAGE_SCANOUT);
if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
@ -80,7 +80,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
pt->height0 & (pt->height0 - 1))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;

View file

@ -104,7 +104,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
tile_flags = 0x7400;
break;
default:
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) &&
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) &&
util_format_get_blocksizebits(pt->format) == 32)
tile_flags = 0x7a00;
else

View file

@ -72,11 +72,8 @@ r300_is_texture_referenced(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level)
{
struct pipe_buffer* buf = 0;
r300_get_texture_buffer(pipe->screen, texture, &buf, NULL);
return pipe->is_buffer_referenced(pipe, buf);
return pipe->is_buffer_referenced(pipe,
((struct r300_texture *)texture)->buffer);
}
static unsigned int
@ -86,7 +83,14 @@ r300_is_buffer_referenced(struct pipe_context *pipe,
/* This only checks to see whether actual hardware buffers are
* referenced. Since we use managed BOs and transfers, it's actually not
* possible for pipe_buffers to ever reference the actual hardware, so
* buffers are never referenced. */
* buffers are never referenced.
*/
/* XXX: that doesn't make sense given that
* r300_is_texture_referenced is implemented on top of this
* function and hardware can certainly refer to textures
* directly...
*/
return 0;
}

View file

@ -231,14 +231,16 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
/* Check colorbuffer format support. */
if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY)) &&
PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED)) &&
/* 2101010 cannot be rendered to on non-r5xx. */
(is_r500 || !is_color2101010) &&
r300_is_colorbuffer_format_supported(format)) {
retval |= usage &
(PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY);
PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED);
}
/* Check depth-stencil format support. */

View file

@ -887,6 +887,70 @@ static struct pipe_texture*
return (struct pipe_texture*)tex;
}
static struct pipe_texture*
r300_texture_from_handle(struct pipe_screen* screen,
const struct pipe_texture* base,
struct winsys_handle *whandle)
{
struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
struct r300_screen* rscreen = r300_screen(screen);
struct pipe_buffer *buffer;
struct r300_texture* tex;
unsigned stride;
/* Support only 2D textures without mipmaps */
if (base->target != PIPE_TEXTURE_2D ||
base->depth0 != 1 ||
base->last_level != 0) {
return NULL;
}
buffer = winsys->buffer_from_handle(winsys, screen, whandle, &stride);
if (!buffer) {
return NULL;
}
tex = CALLOC_STRUCT(r300_texture);
if (!tex) {
return NULL;
}
tex->tex = *base;
pipe_reference_init(&tex->tex.reference, 1);
tex->tex.screen = screen;
tex->stride_override = stride;
tex->pitch[0] = stride / util_format_get_blocksize(base->format);
r300_setup_flags(tex);
r300_setup_texture_state(rscreen, tex);
/* one ref already taken */
tex->buffer = buffer;
return (struct pipe_texture*)tex;
}
static boolean
r300_texture_get_handle(struct pipe_screen* screen,
struct pipe_texture *texture,
struct winsys_handle *whandle)
{
struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
struct r300_texture* tex = (struct r300_texture*)texture;
unsigned stride;
if (!tex) {
return FALSE;
}
stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
winsys->buffer_get_handle(winsys, tex->buffer, stride, whandle);
return TRUE;
}
static struct pipe_video_surface *
r300_video_surface_create(struct pipe_screen *screen,
enum pipe_video_chroma_format chroma_format,
@ -938,6 +1002,8 @@ static void r300_video_surface_destroy(struct pipe_video_surface *vsfc)
void r300_init_screen_texture_functions(struct pipe_screen* screen)
{
screen->texture_create = r300_texture_create;
screen->texture_from_handle = r300_texture_from_handle;
screen->texture_get_handle = r300_texture_get_handle;
screen->texture_destroy = r300_texture_destroy;
screen->get_tex_surface = r300_get_tex_surface;
screen->tex_surface_destroy = r300_tex_surface_destroy;
@ -947,21 +1013,3 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen)
screen->video_surface_destroy= r300_video_surface_destroy;
}
boolean r300_get_texture_buffer(struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride)
{
struct r300_texture* tex = (struct r300_texture*)texture;
if (!tex) {
return FALSE;
}
pipe_buffer_reference(buffer, tex->buffer);
if (stride) {
*stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
}
return TRUE;
}

View file

@ -60,13 +60,11 @@ r300_video_surface(struct pipe_video_surface *pvs)
return (struct r300_video_surface *)pvs;
}
#ifndef R300_WINSYS_H
/* Used internally for texture_is_referenced()
*/
boolean r300_get_texture_buffer(struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
#endif /* R300_WINSYS_H */
#endif /* R300_TEXTURE_H */

View file

@ -40,11 +40,6 @@ struct radeon_winsys;
struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
boolean r300_get_texture_buffer(struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
#ifdef __cplusplus
}
#endif

View file

@ -123,7 +123,8 @@ softpipe_texture_create(struct pipe_screen *screen,
util_is_power_of_two(template->depth0));
if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY)) {
PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED)) {
if (!softpipe_displaytarget_layout(screen, spt))
goto fail;
}
@ -474,24 +475,4 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
}
/**
* Return pipe_buffer handle and stride for given texture object.
* XXX used for???
*/
boolean
softpipe_get_texture_buffer( struct pipe_texture *texture,
struct pipe_buffer **buf,
unsigned *stride )
{
struct softpipe_texture *tex = (struct softpipe_texture *) texture;
if (!tex)
return FALSE;
pipe_buffer_reference(buf, tex->buffer);
if (stride)
*stride = tex->stride[0];
return TRUE;
}

View file

@ -60,12 +60,6 @@ struct pipe_screen *softpipe_create_screen( struct pipe_winsys * );
*/
struct pipe_screen *softpipe_create_screen_malloc(void);
boolean
softpipe_get_texture_buffer( struct pipe_texture *texture,
struct pipe_buffer **buf,
unsigned *stride );
#ifdef __cplusplus
}
#endif

View file

@ -315,7 +315,11 @@ svga_texture_create(struct pipe_screen *screen,
tex->key.cachable = 0;
}
if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
if(templat->tex_usage & PIPE_TEXTURE_USAGE_SHARED) {
tex->key.cachable = 0;
}
if(templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) {
tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
tex->key.cachable = 0;
}
@ -422,13 +426,15 @@ svga_texture_blanket(struct pipe_screen * screen,
}
struct pipe_texture *
svga_screen_texture_wrap_surface(struct pipe_screen *screen,
struct pipe_texture *base,
enum SVGA3dSurfaceFormat format,
struct svga_winsys_surface *srf)
static struct pipe_texture *
svga_screen_texture_from_handle(struct pipe_screen *screen,
const struct pipe_texture *base,
struct winsys_handle *whandle)
{
struct svga_winsys_screen *sws = svga_winsys_screen(screen);
struct svga_winsys_surface *srf;
struct svga_texture *tex;
enum SVGA3dSurfaceFormat format = 0;
assert(screen);
/* Only supports one type */
@ -438,6 +444,8 @@ svga_screen_texture_wrap_surface(struct pipe_screen *screen,
return NULL;
}
srf = sws->surface_from_handle(sws, whandle, &format);
if (!srf)
return NULL;
@ -478,6 +486,22 @@ svga_screen_texture_wrap_surface(struct pipe_screen *screen,
}
static boolean
svga_screen_texture_get_handle(struct pipe_screen *screen,
struct pipe_texture *texture,
struct winsys_handle *whandle)
{
struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
unsigned stride;
assert(svga_texture(texture)->key.cachable == 0);
svga_texture(texture)->key.cachable = 0;
stride = util_format_get_nblocksx(texture->format, texture->width0) *
util_format_get_blocksize(texture->format);
return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle);
}
static void
svga_texture_destroy(struct pipe_texture *pt)
{
@ -955,6 +979,8 @@ void
svga_screen_init_texture_functions(struct pipe_screen *screen)
{
screen->texture_create = svga_texture_create;
screen->texture_from_handle = svga_screen_texture_from_handle;
screen->texture_get_handle = svga_screen_texture_get_handle;
screen->texture_destroy = svga_texture_destroy;
screen->get_tex_surface = svga_get_tex_surface;
screen->tex_surface_destroy = svga_tex_surface_destroy;
@ -1120,33 +1146,3 @@ svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
pipe_texture_reference(&v->texture, NULL);
FREE(v);
}
boolean
svga_screen_buffer_from_texture(struct pipe_texture *texture,
struct pipe_buffer **buffer,
unsigned *stride)
{
struct svga_texture *stex = svga_texture(texture);
*buffer = svga_screen_buffer_wrap_surface
(texture->screen,
svga_translate_format(texture->format),
stex->handle);
*stride = util_format_get_stride(texture->format, texture->width0);
return *buffer != NULL;
}
struct svga_winsys_surface *
svga_screen_texture_get_winsys_surface(struct pipe_texture *texture)
{
struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
struct svga_winsys_surface *vsurf = NULL;
assert(svga_texture(texture)->key.cachable == 0);
svga_texture(texture)->key.cachable = 0;
sws->surface_reference(sws, &vsurf, svga_texture(texture)->handle);
return vsurf;
}

View file

@ -51,6 +51,7 @@ struct pipe_context;
struct pipe_fence_handle;
struct pipe_texture;
struct svga_region;
struct winsys_handle;
#define SVGA_BUFFER_USAGE_PINNED (PIPE_BUFFER_USAGE_CUSTOM << 0)
@ -186,6 +187,25 @@ struct svga_winsys_screen
uint32 numFaces,
uint32 numMipLevels);
/**
* Creates a surface from a winsys handle.
* Used to implement pipe_screen::texture_from_handle.
*/
struct svga_winsys_surface *
(*surface_from_handle)(struct svga_winsys_screen *sws,
struct winsys_handle *whandle,
SVGA3dSurfaceFormat *format);
/**
* Get a winsys_handle from a surface.
* Used to implement pipe_screen::texture_get_handle.
*/
boolean
(*surface_get_handle)(struct svga_winsys_screen *sws,
struct svga_winsys_surface *surface,
unsigned stride,
struct winsys_handle *whandle);
/**
* Whether this surface is sitting in a validate list
*/
@ -283,20 +303,7 @@ svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
enum SVGA3dSurfaceFormat format,
struct svga_winsys_surface *srf);
struct svga_winsys_surface *
svga_screen_texture_get_winsys_surface(struct pipe_texture *texture);
struct svga_winsys_surface *
svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer);
boolean
svga_screen_buffer_from_texture(struct pipe_texture *texture,
struct pipe_buffer **buffer,
unsigned *stride);
struct pipe_texture *
svga_screen_texture_wrap_surface(struct pipe_screen *screen,
struct pipe_texture *base,
enum SVGA3dSurfaceFormat format,
struct svga_winsys_surface *srf);
#endif /* SVGA_WINSYS_H_ */

View file

@ -62,71 +62,10 @@ trace_drm_create_screen(struct drm_api *_api, int fd,
screen = api->create_screen(api, fd, arg);
return trace_screen_create(screen);
}
static struct pipe_texture *
trace_drm_texture_from_shared_handle(struct drm_api *_api,
struct pipe_screen *_screen,
struct pipe_texture *templ,
const char *name,
unsigned stride,
unsigned handle)
{
struct trace_screen *tr_screen = trace_screen(_screen);
struct trace_drm_api *tr_api = trace_drm_api(_api);
struct pipe_screen *screen = tr_screen->screen;
struct drm_api *api = tr_api->api;
struct pipe_texture *result;
/* TODO trace call */
result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
result = trace_texture_create(trace_screen(_screen), result);
return result;
}
static boolean
trace_drm_shared_handle_from_texture(struct drm_api *_api,
struct pipe_screen *_screen,
struct pipe_texture *_texture,
unsigned *stride,
unsigned *handle)
{
struct trace_screen *tr_screen = trace_screen(_screen);
struct trace_texture *tr_texture = trace_texture(_texture);
struct trace_drm_api *tr_api = trace_drm_api(_api);
struct pipe_screen *screen = tr_screen->screen;
struct pipe_texture *texture = tr_texture->texture;
struct drm_api *api = tr_api->api;
/* TODO trace call */
return api->shared_handle_from_texture(api, screen, texture, stride, handle);
}
static boolean
trace_drm_local_handle_from_texture(struct drm_api *_api,
struct pipe_screen *_screen,
struct pipe_texture *_texture,
unsigned *stride,
unsigned *handle)
{
struct trace_screen *tr_screen = trace_screen(_screen);
struct trace_texture *tr_texture = trace_texture(_texture);
struct trace_drm_api *tr_api = trace_drm_api(_api);
struct pipe_screen *screen = tr_screen->screen;
struct pipe_texture *texture = tr_texture->texture;
struct drm_api *api = tr_api->api;
/* TODO trace call */
return api->local_handle_from_texture(api, screen, texture, stride, handle);
}
static void
trace_drm_destroy(struct drm_api *_api)
{
@ -158,9 +97,6 @@ trace_drm_create(struct drm_api *api)
tr_api->base.name = api->name;
tr_api->base.driver_name = api->driver_name;
tr_api->base.create_screen = trace_drm_create_screen;
tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle;
tr_api->base.shared_handle_from_texture = trace_drm_shared_handle_from_texture;
tr_api->base.local_handle_from_texture = trace_drm_local_handle_from_texture;
tr_api->base.destroy = trace_drm_destroy;
tr_api->api = api;

View file

@ -236,6 +236,38 @@ trace_screen_texture_create(struct pipe_screen *_screen,
return result;
}
static struct pipe_texture *
trace_screen_texture_from_handle(struct pipe_screen *_screen,
const struct pipe_texture *templ,
struct winsys_handle *handle)
{
struct trace_screen *tr_screen = trace_screen(_screen);
struct pipe_screen *screen = tr_screen->screen;
struct pipe_texture *result;
/* TODO trace call */
result = screen->texture_from_handle(screen, templ, handle);
result = trace_texture_create(trace_screen(_screen), result);
return result;
}
static boolean
trace_screen_texture_get_handle(struct pipe_screen *_screen,
struct pipe_texture *_texture,
struct winsys_handle *handle)
{
struct trace_screen *tr_screen = trace_screen(_screen);
struct trace_texture *tr_texture = trace_texture(_texture);
struct pipe_screen *screen = tr_screen->screen;
struct pipe_texture *texture = tr_texture->texture;
/* TODO trace call */
return screen->texture_get_handle(screen, texture, handle);
}
static struct pipe_texture *
trace_screen_texture_blanket(struct pipe_screen *_screen,
@ -931,6 +963,8 @@ trace_screen_create(struct pipe_screen *screen)
assert(screen->context_create);
tr_scr->base.context_create = trace_screen_context_create;
tr_scr->base.texture_create = trace_screen_texture_create;
tr_scr->base.texture_from_handle = trace_screen_texture_from_handle;
tr_scr->base.texture_get_handle = trace_screen_texture_get_handle;
tr_scr->base.texture_blanket = trace_screen_texture_blanket;
tr_scr->base.texture_destroy = trace_screen_texture_destroy;
tr_scr->base.get_tex_surface = trace_screen_get_tex_surface;

View file

@ -176,11 +176,12 @@ enum pipe_texture_target {
#define PIPE_TEX_COMPARE_R_TO_TEXTURE 1
#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1
#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */
#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */
#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* windows presentable buffer, ie a backbuffer */
#define PIPE_TEXTURE_USAGE_SCANOUT 0x4 /* ie a frontbuffer */
#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8
#define PIPE_TEXTURE_USAGE_SAMPLER 0x10
#define PIPE_TEXTURE_USAGE_DYNAMIC 0x20
#define PIPE_TEXTURE_USAGE_SHARED 0x40
/** Pipe driver custom usage flags should be greater or equal to this value */
#define PIPE_TEXTURE_USAGE_CUSTOM (1 << 16)

View file

@ -49,6 +49,8 @@ extern "C" {
#endif
/** Opaque type */
struct winsys_handle;
/** Opaque type */
struct pipe_fence_handle;
struct pipe_winsys;
@ -107,6 +109,24 @@ struct pipe_screen {
struct pipe_texture * (*texture_create)(struct pipe_screen *,
const struct pipe_texture *templat);
/**
* Create a texture from a winsys_handle. The handle is often created in
* another process by first creating a pipe texture and then calling
* texture_get_handle.
*/
struct pipe_texture * (*texture_from_handle)(struct pipe_screen *,
const struct pipe_texture *templat,
struct winsys_handle *handle);
/**
* Get a winsys_handle from a texture. Some platforms/winsys requires
* that the texture is created with a special usage flag like
* DISPLAYTARGET or PRIMARY.
*/
boolean (*texture_get_handle)(struct pipe_screen *,
struct pipe_texture *tex,
struct winsys_handle *handle);
/**
* Create a new texture object, using the given template info, but on top of
* existing memory.

View file

@ -17,6 +17,31 @@ enum drm_create_screen_mode {
DRM_CREATE_MAX
};
#define DRM_API_HANDLE_TYPE_SHARED 0
#define DRM_API_HANDLE_TYPE_KMS 1
/**
* For use with pipe_screen::{texture_from_handle|texture_get_handle}.
*/
struct winsys_handle
{
/**
* Unused for texture_from_handle, always DRM_API_HANDLE_TYPE_SHARED.
* Input to texture_get_handle, use TEXTURE_USAGE to select handle for kms or ipc.
*/
unsigned type;
/**
* Input to texture_from_handle.
* Output for texture_get_handle.
*/
unsigned handle;
/**
* Input to texture_from_handle.
* Output for texture_get_handle.
*/
unsigned stride;
};
/**
* Modes other than DRM_CREATE_NORMAL derive from this struct.
*/
@ -28,6 +53,8 @@ struct drm_create_screen_arg {
struct drm_api
{
void (*destroy)(struct drm_api *api);
const char *name;
/**
@ -36,37 +63,10 @@ struct drm_api
const char *driver_name;
/**
* Special buffer functions
* Create a pipe srcreen.
*/
/*@{*/
struct pipe_screen* (*create_screen)(struct drm_api *api, int drm_fd,
struct drm_create_screen_arg *arg);
/*@}*/
/**
* Special buffer functions
*/
/*@{*/
struct pipe_texture*
(*texture_from_shared_handle)(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *templ,
const char *name,
unsigned stride,
unsigned handle);
boolean (*shared_handle_from_texture)(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *stride,
unsigned *handle);
boolean (*local_handle_from_texture)(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *stride,
unsigned *handle);
/*@}*/
void (*destroy)(struct drm_api *api);
};
extern struct drm_api * drm_api_create(void);

View file

@ -58,6 +58,7 @@ dri_surface_from_handle(struct drm_api *api,
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;
@ -68,8 +69,11 @@ dri_surface_from_handle(struct drm_api *api,
templat.width0 = width;
templat.height0 = height;
texture = api->texture_from_shared_handle(api, screen, &templat,
"dri2 buffer", pitch, handle);
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__);

View file

@ -55,7 +55,7 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
templ.format = ksurf->color_format;
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT)
templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
templ.tex_usage |= PIPE_TEXTURE_SCANOUT;
}
/* create textures */

View file

@ -114,6 +114,7 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
struct pipe_texture templ;
struct winsys_handle whandle;
uint valid_mask;
int i;
@ -171,9 +172,11 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
continue;
}
dri2surf->textures[natt] =
dri2dpy->api->texture_from_shared_handle(dri2dpy->api,
dri2dpy->base.screen, &templ, desc, xbuf->pitch, xbuf->name);
memset(&whandle, 0, sizeof(whandle));
whandle.stride = xbuf->pitch;
whandle.handle = xbuf->name;
dri2surf->textures[natt] = dri2dpy->base.screen->texture_from_handle(
dri2dpy->base.screen, &templ, &whandle);
if (dri2surf->textures[natt])
valid_mask |= 1 << natt;
}

View file

@ -197,11 +197,11 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
if (!crtcp->cursor_tex) {
struct pipe_texture templat;
unsigned pitch;
struct winsys_handle whandle;
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
templat.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth0 = 1;
@ -209,13 +209,14 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
templat.width0 = 64;
templat.height0 = 64;
memset(&whandle, 0, sizeof(whandle));
whandle.type = DRM_API_HANDLE_TYPE_KMS;
crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
&templat);
ms->api->local_handle_from_texture(ms->api,
ms->screen,
crtcp->cursor_tex,
&pitch,
&crtcp->cursor_handle);
ms->screen->texture_get_handle(ms->screen, crtcp->cursor_tex, &whandle);
crtcp->cursor_handle = whandle.handle;
}
transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex,

View file

@ -67,7 +67,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
struct exa_pixmap_priv *exa_priv;
BufferPrivatePtr private = buffer->driverPrivate;
PixmapPtr pPixmap;
unsigned stride, handle;
struct winsys_handle whandle;
if (pDraw->type == DRAWABLE_PIXMAP)
pPixmap = (PixmapPtr) pDraw;
@ -75,6 +75,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
exa_priv = exaGetPixmapDriverPrivate(pPixmap);
switch (buffer->attachment) {
default:
if (buffer->attachment != DRI2BufferFakeFrontLeft ||
@ -128,7 +129,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
PIPE_TEXTURE_USAGE_SHARED;
tex = ms->screen->texture_create(ms->screen, &template);
pipe_texture_reference(&exa_priv->depth_stencil_tex, tex);
}
@ -153,10 +154,13 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
if (!tex)
FatalError("NO TEXTURE IN DRI2\n");
ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
memset(&whandle, 0, sizeof(whandle));
whandle.type = DRM_API_HANDLE_TYPE_SHARED;
buffer->name = handle;
buffer->pitch = stride;
ms->screen->texture_get_handle(ms->screen, tex, &whandle);
buffer->name = whandle.handle;
buffer->pitch = whandle.stride;
buffer->cpp = 4;
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */

View file

@ -989,8 +989,9 @@ static Bool
drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
unsigned handle, stride, fb_id;
struct pipe_texture *tex;
struct winsys_handle whandle;
unsigned fb_id;
int ret;
ms->noEvict = TRUE;
@ -1001,10 +1002,10 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
if (!tex)
return FALSE;
if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
tex,
&stride,
&handle))
memset(&whandle, 0, sizeof(whandle));
whandle.type = DRM_API_HANDLE_TYPE_KMS;
if (!ms->screen->texture_get_handle(ms->screen, tex, &whandle))
goto err_destroy;
ret = drmModeAddFB(ms->fd,
@ -1012,8 +1013,8 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
stride,
handle,
whandle.stride,
whandle.handle,
&fb_id);
if (ret) {
debug_printf("%s: failed to create framebuffer (%i, %s)\n",

View file

@ -789,7 +789,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
return 0;
}
priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
priv->flags |= PIPE_TEXTURE_USAGE_SCANOUT;
return 0;
}
@ -805,7 +805,7 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap)
return 0;
}
priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
priv->flags |= PIPE_TEXTURE_USAGE_SHARED;
return 0;
}
@ -943,7 +943,7 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex)
{
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
int mask = PIPE_TEXTURE_USAGE_SHARED | PIPE_TEXTURE_USAGE_SCANOUT;
if (!priv)
return FALSE;
@ -976,8 +976,8 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
template.depth0 = 1;
template.last_level = 0;
template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
template.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
template.tex_usage |= PIPE_TEXTURE_USAGE_SHARED;
return exa->scrn->texture_create(exa->scrn, &template);
}

View file

@ -106,7 +106,7 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u
template.width0 = width;
template.height0 = height;
template.depth0 = 1;
template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
template.tex_usage = PIPE_TEXTURE_USAGE_SHARED;
tex = vpipe->screen->texture_create(vpipe->screen, &template);
if (!tex)

View file

@ -37,129 +37,6 @@ i965_libdrm_get_device_id(unsigned int *device_id)
fclose(file);
}
static struct i965_libdrm_buffer *
i965_libdrm_buffer_from_handle(struct i965_libdrm_winsys *idws,
const char* name, unsigned handle)
{
struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
uint32_t swizzle = 0;
if (BRW_DUMP)
debug_printf("%s\n", __FUNCTION__);
if (!buf)
return NULL;
pipe_reference_init(&buf->base.reference, 1);
buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, name, handle);
buf->base.size = buf->bo->size;
buf->base.sws = &idws->base;
buf->flinked = TRUE;
buf->flink = handle;
if (!buf->bo)
goto err;
drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
if (buf->tiling != 0)
buf->map_gtt = TRUE;
return buf;
err:
FREE(buf);
return NULL;
}
/*
* Exported functions
*/
static struct pipe_texture *
i965_libdrm_texture_from_shared_handle(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *template,
const char* name,
unsigned pitch,
unsigned handle)
{
/* XXX: this is silly -- there should be a way to get directly from
* the "drm_api" struct to ourselves, without peering into
* unrelated code:
*/
struct i965_libdrm_winsys *idws = i965_libdrm_winsys(brw_screen(screen)->sws);
struct i965_libdrm_buffer *buffer;
if (BRW_DUMP)
debug_printf("%s %s pitch %d handle 0x%x\n", __FUNCTION__,
name, pitch, handle);
buffer = i965_libdrm_buffer_from_handle(idws, name, handle);
if (!buffer)
return NULL;
return brw_texture_blanket_winsys_buffer(screen, template, pitch,
buffer->tiling,
&buffer->base);
}
static boolean
i965_libdrm_shared_handle_from_texture(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *pitch,
unsigned *handle)
{
struct i965_libdrm_buffer *buf = NULL;
struct brw_winsys_buffer *buffer = NULL;
if (BRW_DUMP)
debug_printf("%s\n", __FUNCTION__);
if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
return FALSE;
buf = i965_libdrm_buffer(buffer);
if (!buf->flinked) {
if (drm_intel_bo_flink(buf->bo, &buf->flink))
return FALSE;
buf->flinked = TRUE;
}
*handle = buf->flink;
if (BRW_DUMP)
debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
return TRUE;
}
static boolean
i965_libdrm_local_handle_from_texture(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *pitch,
unsigned *handle)
{
struct brw_winsys_buffer *buffer = NULL;
if (BRW_DUMP)
debug_printf("%s\n", __FUNCTION__);
if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
return FALSE;
*handle = i965_libdrm_buffer(buffer)->bo->handle;
if (BRW_DUMP)
debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
return TRUE;
}
static void
i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
{
@ -225,9 +102,6 @@ struct drm_api i965_libdrm_api =
{
.name = "i965",
.create_screen = i965_libdrm_create_screen,
.texture_from_shared_handle = i965_libdrm_texture_from_shared_handle,
.shared_handle_from_texture = i965_libdrm_shared_handle_from_texture,
.local_handle_from_texture = i965_libdrm_local_handle_from_texture,
.destroy = destroy,
};

View file

@ -1,4 +1,5 @@
#include "state_tracker/drm_api.h"
#include "i965_drm_winsys.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
@ -122,6 +123,78 @@ err:
return PIPE_ERROR_OUT_OF_MEMORY;
}
static enum pipe_error
i965_libdrm_bo_from_handle(struct brw_winsys_screen *sws,
struct winsys_handle *whandle,
unsigned *stride,
unsigned *tile,
struct brw_winsys_buffer **bo_out)
{
struct i965_libdrm_winsys *idws = i965_libdrm_winsys(sws);
struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
uint32_t swizzle = 0;
if (BRW_DUMP)
debug_printf("%s\n", __FUNCTION__);
if (!buf)
return PIPE_ERROR_OUT_OF_MEMORY;
pipe_reference_init(&buf->base.reference, 1);
buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, "FROM_HANDLE", whandle->handle);
buf->base.size = buf->bo->size;
buf->base.sws = &idws->base;
buf->flinked = TRUE;
buf->flink = whandle->handle;
if (!buf->bo)
goto err;
drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
if (buf->tiling != 0)
buf->map_gtt = TRUE;
*tile = buf->tiling;
*stride = whandle->stride;
*bo_out = &buf->base;
return PIPE_OK;
err:
FREE(buf);
return PIPE_ERROR_OUT_OF_MEMORY;
}
static enum pipe_error
i965_libdrm_bo_get_handle(struct brw_winsys_buffer *buffer,
struct winsys_handle *whandle,
unsigned stride)
{
struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
if (BRW_DUMP)
debug_printf("%s\n", __FUNCTION__);
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
if (!buf->flinked) {
if (drm_intel_bo_flink(buf->bo, &buf->flink))
return PIPE_ERROR_BAD_INPUT;
buf->flinked = TRUE;
}
whandle->handle = buf->flink;
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
whandle->handle = buf->bo->handle;
} else {
assert(!"unknown usage");
return PIPE_ERROR_BAD_INPUT;
}
whandle->stride = stride;
return PIPE_OK;
}
static void
i965_libdrm_bo_destroy(struct brw_winsys_buffer *buffer)
{
@ -415,6 +488,8 @@ void
i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws)
{
idws->base.bo_alloc = i965_libdrm_bo_alloc;
idws->base.bo_from_handle = i965_libdrm_bo_from_handle;
idws->base.bo_get_handle = i965_libdrm_bo_get_handle;
idws->base.bo_destroy = i965_libdrm_bo_destroy;
idws->base.bo_emit_reloc = i965_libdrm_bo_emit_reloc;
idws->base.bo_exec = i965_libdrm_bo_exec;

View file

@ -38,99 +38,6 @@ intel_drm_get_device_id(unsigned int *device_id)
fclose(file);
}
static struct intel_buffer *
intel_drm_buffer_from_handle(struct intel_drm_winsys *idws,
const char* name, unsigned handle)
{
struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
uint32_t tile = 0, swizzle = 0;
if (!buf)
return NULL;
buf->magic = 0xDEAD1337;
buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, name, handle);
buf->flinked = TRUE;
buf->flink = handle;
if (!buf->bo)
goto err;
drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
if (tile != INTEL_TILE_NONE)
buf->map_gtt = TRUE;
return (struct intel_buffer *)buf;
err:
FREE(buf);
return NULL;
}
/*
* Exported functions
*/
static struct pipe_texture *
intel_drm_texture_from_shared_handle(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *templ,
const char* name,
unsigned pitch,
unsigned handle)
{
struct intel_drm_winsys *idws = intel_drm_winsys(i915_screen(screen)->iws);
struct intel_buffer *buffer;
buffer = intel_drm_buffer_from_handle(idws, name, handle);
if (!buffer)
return NULL;
return i915_texture_blanket_intel(screen, templ, pitch, buffer);
}
static boolean
intel_drm_shared_handle_from_texture(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *pitch,
unsigned *handle)
{
struct intel_drm_buffer *buf = NULL;
struct intel_buffer *buffer = NULL;
if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
return FALSE;
buf = intel_drm_buffer(buffer);
if (!buf->flinked) {
if (drm_intel_bo_flink(buf->bo, &buf->flink))
return FALSE;
buf->flinked = TRUE;
}
*handle = buf->flink;
return TRUE;
}
static boolean
intel_drm_local_handle_from_texture(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *pitch,
unsigned *handle)
{
struct intel_buffer *buffer = NULL;
if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
return FALSE;
*handle = intel_drm_buffer(buffer)->bo->handle;
return TRUE;
}
static void
intel_drm_winsys_destroy(struct intel_winsys *iws)
{
@ -192,9 +99,6 @@ struct drm_api intel_drm_api =
.name = "i915",
.driver_name = "i915",
.create_screen = intel_drm_create_screen,
.texture_from_shared_handle = intel_drm_texture_from_shared_handle,
.shared_handle_from_texture = intel_drm_shared_handle_from_texture,
.local_handle_from_texture = intel_drm_local_handle_from_texture,
.destroy = destroy,
};

View file

@ -1,4 +1,5 @@
#include "state_tracker/drm_api.h"
#include "intel_drm_winsys.h"
#include "util/u_memory.h"
@ -52,6 +53,66 @@ err:
return NULL;
}
static struct intel_buffer *
intel_drm_buffer_from_handle(struct intel_winsys *iws,
struct winsys_handle *whandle,
unsigned *stride)
{
struct intel_drm_winsys *idws = intel_drm_winsys(iws);
struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
uint32_t tile = 0, swizzle = 0;
if (!buf)
return NULL;
buf->magic = 0xDEAD1337;
buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, "gallium3d_from_handle", whandle->handle);
buf->flinked = TRUE;
buf->flink = whandle->handle;
if (!buf->bo)
goto err;
drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
if (tile != INTEL_TILE_NONE)
buf->map_gtt = TRUE;
*stride = whandle->stride;
return (struct intel_buffer *)buf;
err:
FREE(buf);
return NULL;
}
static boolean
intel_drm_buffer_get_handle(struct intel_winsys *iws,
struct intel_buffer *buffer,
struct winsys_handle *whandle,
unsigned stride)
{
struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
if (!buf->flinked) {
if (drm_intel_bo_flink(buf->bo, &buf->flink))
return FALSE;
buf->flinked = TRUE;
}
whandle->handle = buf->flink;
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
whandle->handle = buf->bo->handle;
} else {
assert(!"unknown usage");
return FALSE;
}
whandle->stride = stride;
return TRUE;
}
static int
intel_drm_buffer_set_fence_reg(struct intel_winsys *iws,
struct intel_buffer *buffer,
@ -146,6 +207,8 @@ void
intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws)
{
idws->base.buffer_create = intel_drm_buffer_create;
idws->base.buffer_from_handle = intel_drm_buffer_from_handle;
idws->base.buffer_get_handle = intel_drm_buffer_get_handle;
idws->base.buffer_set_fence_reg = intel_drm_buffer_set_fence_reg;
idws->base.buffer_map = intel_drm_buffer_map;
idws->base.buffer_unmap = intel_drm_buffer_unmap;

View file

@ -21,9 +21,10 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
struct pipe_surface *ps = NULL;
struct pipe_texture *pt = NULL;
struct pipe_texture tmpl;
struct winsys_handle whandle;
memset(&tmpl, 0, sizeof(tmpl));
tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY;
tmpl.tex_usage = PIPE_TEXTURE_USAGE_SCANOUT;
tmpl.target = PIPE_TEXTURE_2D;
tmpl.last_level = 0;
tmpl.depth0 = 1;
@ -31,8 +32,11 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
tmpl.width0 = width;
tmpl.height0 = height;
pt = api->texture_from_shared_handle(api, pscreen, &tmpl,
"front buffer", pitch, handle);
memset(&whandle, 0, sizeof(whandle));
whandle.stride = pitch;
whandle.handle = handle;
pt = pscreen->texture_from_handle(pscreen, &tmpl, &whandle);
if (!pt)
return NULL;
@ -142,74 +146,10 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
return nvws->pscreen;
}
static struct pipe_texture *
nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen,
struct pipe_texture *templ, const char *name,
unsigned stride, unsigned handle)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct pipe_texture *pt;
struct pipe_buffer *pb;
int ret;
pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
if (!pb)
return NULL;
ret = nouveau_bo_handle_ref(dev, handle, (struct nouveau_bo**)(pb+1));
if (ret) {
debug_printf("%s: ref name 0x%08x failed with %d\n",
__func__, handle, ret);
FREE(pb);
return NULL;
}
pipe_reference_init(&pb->reference, 1);
pb->screen = pscreen;
pb->alignment = 0;
pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
PIPE_BUFFER_USAGE_CPU_READ_WRITE;
pb->size = nouveau_bo(pb)->size;
pt = pscreen->texture_blanket(pscreen, templ, &stride, pb);
pipe_buffer_reference(&pb, NULL);
return pt;
}
static boolean
nouveau_drm_name_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
struct pipe_texture *pt, unsigned *stride,
unsigned *handle)
{
struct nouveau_miptree *mt = nouveau_miptree(pt);
if (!mt || !mt->bo)
return false;
return nouveau_bo_handle_get(mt->bo, handle) == 0;
}
static boolean
nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
struct pipe_texture *pt, unsigned *stride,
unsigned *handle)
{
struct nouveau_miptree *mt = nouveau_miptree(pt);
if (!mt || !mt->bo)
return false;
*handle = mt->bo->handle;
*stride = util_format_get_stride(mt->base.format, mt->base.width0);
return true;
}
struct drm_api drm_api_hooks = {
.name = "nouveau",
.driver_name = "nouveau",
.create_screen = nouveau_drm_create_screen,
.texture_from_shared_handle = nouveau_drm_pt_from_name,
.shared_handle_from_texture = nouveau_drm_name_from_pt,
.local_handle_from_texture = nouveau_drm_handle_from_pt,
};
struct drm_api *

View file

@ -264,6 +264,75 @@ static int radeon_fence_finish(struct pipe_winsys *ws,
return 0;
}
/* Create a buffer from a handle. */
static struct pipe_buffer* radeon_buffer_from_handle(struct radeon_winsys *radeon_ws,
struct pipe_screen *screen,
struct winsys_handle *whandle,
unsigned *stride)
{
struct radeon_bo_manager* bom = radeon_ws->priv->bom;
struct radeon_pipe_buffer* radeon_buffer;
struct radeon_bo* bo = NULL;
bo = radeon_bo_open(bom, whandle->handle, 0, 0, 0, 0);
if (bo == NULL) {
return NULL;
}
radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer);
if (radeon_buffer == NULL) {
radeon_bo_unref(bo);
return NULL;
}
pipe_reference_init(&radeon_buffer->base.reference, 1);
radeon_buffer->base.screen = screen;
radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
radeon_buffer->bo = bo;
*stride = whandle->stride;
return &radeon_buffer->base;
}
static boolean radeon_buffer_get_handle(struct radeon_winsys *radeon_ws,
struct pipe_buffer *buffer,
unsigned stride,
struct winsys_handle *whandle)
{
int retval, fd;
struct drm_gem_flink flink;
struct radeon_pipe_buffer* radeon_buffer;
radeon_buffer = (struct radeon_pipe_buffer*)buffer;
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
if (!radeon_buffer->flinked) {
fd = radeon_ws->priv->fd;
flink.handle = radeon_buffer->bo->handle;
retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
if (retval) {
debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n",
retval);
return FALSE;
}
radeon_buffer->flink = flink.name;
radeon_buffer->flinked = TRUE;
}
whandle->handle = radeon_buffer->flink;
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
whandle->handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
}
whandle->stride = stride;
return TRUE;
}
struct radeon_winsys* radeon_pipe_winsys(int fd)
{
struct radeon_winsys* radeon_ws;
@ -298,6 +367,8 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
radeon_ws->base.get_name = radeon_get_name;
radeon_ws->buffer_set_tiling = radeon_buffer_set_tiling;
radeon_ws->buffer_from_handle = radeon_buffer_from_handle;
radeon_ws->buffer_get_handle = radeon_buffer_get_handle;
return radeon_ws;
}

View file

@ -148,124 +148,6 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
}
}
boolean radeon_buffer_from_texture(struct drm_api* api,
struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride)
{
/* XXX fix this */
return r300_get_texture_buffer(screen, texture, buffer, stride);
}
/* Create a buffer from a handle. */
/* XXX what's up with name? */
struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
struct pipe_screen* screen,
const char* name,
unsigned handle)
{
struct radeon_bo_manager* bom =
((struct radeon_winsys*)screen->winsys)->priv->bom;
struct radeon_pipe_buffer* radeon_buffer;
struct radeon_bo* bo = NULL;
bo = radeon_bo_open(bom, handle, 0, 0, 0, 0);
if (bo == NULL) {
return NULL;
}
radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer);
if (radeon_buffer == NULL) {
radeon_bo_unref(bo);
return NULL;
}
pipe_reference_init(&radeon_buffer->base.reference, 1);
radeon_buffer->base.screen = screen;
radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
radeon_buffer->bo = bo;
return &radeon_buffer->base;
}
static struct pipe_texture*
radeon_texture_from_shared_handle(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *templ,
const char *name,
unsigned stride,
unsigned handle)
{
struct pipe_buffer *buffer;
struct pipe_texture *blanket;
buffer = radeon_buffer_from_handle(api, screen, name, handle);
if (!buffer) {
return NULL;
}
blanket = screen->texture_blanket(screen, templ, &stride, buffer);
pipe_buffer_reference(&buffer, NULL);
return blanket;
}
static boolean radeon_shared_handle_from_texture(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *stride,
unsigned *handle)
{
int retval, fd;
struct drm_gem_flink flink;
struct radeon_pipe_buffer* radeon_buffer;
struct pipe_buffer *buffer = NULL;
if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
return FALSE;
}
radeon_buffer = (struct radeon_pipe_buffer*)buffer;
if (!radeon_buffer->flinked) {
fd = ((struct radeon_winsys*)screen->winsys)->priv->fd;
flink.handle = radeon_buffer->bo->handle;
retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
if (retval) {
debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n",
retval);
return FALSE;
}
radeon_buffer->flink = flink.name;
radeon_buffer->flinked = TRUE;
}
*handle = radeon_buffer->flink;
return TRUE;
}
static boolean radeon_local_handle_from_texture(struct drm_api *api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *stride,
unsigned *handle)
{
struct pipe_buffer *buffer = NULL;
if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
return FALSE;
}
*handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
pipe_buffer_reference(&buffer, NULL);
return TRUE;
}
static void radeon_drm_api_destroy(struct drm_api *api)
{
return;
@ -275,9 +157,6 @@ struct drm_api drm_api_hooks = {
.name = "radeon",
.driver_name = "radeon",
.create_screen = radeon_create_screen,
.texture_from_shared_handle = radeon_texture_from_shared_handle,
.shared_handle_from_texture = radeon_shared_handle_from_texture,
.local_handle_from_texture = radeon_local_handle_from_texture,
.destroy = radeon_drm_api_destroy,
};

View file

@ -37,28 +37,6 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
struct drm_create_screen_arg *arg);
boolean radeon_buffer_from_texture(struct drm_api* api,
struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
struct pipe_screen* screen,
const char* name,
unsigned handle);
boolean radeon_handle_from_buffer(struct drm_api* api,
struct pipe_screen* screen,
struct pipe_buffer* buffer,
unsigned* handle);
boolean radeon_global_handle_from_buffer(struct drm_api* api,
struct pipe_screen* screen,
struct pipe_buffer* buffer,
unsigned* handle);
void radeon_destroy_drm_api(struct drm_api* api);
/* Guess at whether this chipset should use r300g.

View file

@ -56,6 +56,18 @@ struct radeon_winsys {
/* VRAM size. */
uint32_t vram_size;
/* Create a buffer from a winsys handle. */
struct pipe_buffer *(*buffer_from_handle)(struct radeon_winsys *winsys,
struct pipe_screen *screen,
struct winsys_handle *whandle,
unsigned *stride);
/* Get the handle from a buffer. */
boolean (*buffer_get_handle)(struct radeon_winsys *winsys,
struct pipe_buffer *buffer,
unsigned stride,
struct winsys_handle *whandle);
/* Add a pipe_buffer to the list of buffer objects to validate. */
boolean (*add_buffer)(struct radeon_winsys* winsys,
struct pipe_buffer* pbuffer,

View file

@ -44,6 +44,16 @@
#include <stdio.h>
static struct svga_winsys_surface *
vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
struct winsys_handle *whandle,
SVGA3dSurfaceFormat *format);
static boolean
vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
struct svga_winsys_surface *surface,
unsigned stride,
struct winsys_handle *whandle);
static struct dri1_api dri1_api_hooks;
static struct dri1_api_version ddx_required = { 0, 1, 0 };
static struct dri1_api_version ddx_compat = { 0, 0, 0 };
@ -129,7 +139,12 @@ vmw_drm_create_screen(struct drm_api *drm_api,
&drm_compat, "use old scanout field (not a error)"))
use_old_scanout_flag = TRUE;
dri1->api = &dri1_api_hooks;
#if 0
break;
#else
assert(!"No dri 1 support for now\n");
return NULL;
#endif
default:
return NULL;
}
@ -139,6 +154,10 @@ vmw_drm_create_screen(struct drm_api *drm_api,
if (!vws)
goto out_no_vws;
/* XXX do this properly */
vws->base.surface_from_handle = vmw_drm_surface_from_handle;
vws->base.surface_get_handle = vmw_drm_surface_get_handle;
screen = svga_screen_create( &vws->base );
if (!screen)
goto out_no_screen;
@ -200,6 +219,7 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
const struct drm_clip_rect *bbox,
struct pipe_fence_handle **p_fence)
{
#if 0
struct svga_winsys_surface *srf =
svga_screen_texture_get_winsys_surface(surf->texture);
struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
@ -246,21 +266,19 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
*p_fence = (visible) ? vmw_pipe_fence(fence_seq) : NULL;
vmw_svga_winsys_surface_reference(&vsrf, NULL);
#else
assert(!"No dri 1 support for now\n");
#endif
}
static struct pipe_texture *
vmw_drm_texture_from_handle(struct drm_api *drm_api,
struct pipe_screen *screen,
struct pipe_texture *templat,
const char *name,
unsigned stride,
unsigned handle)
static struct svga_winsys_surface *
vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
struct winsys_handle *whandle,
SVGA3dSurfaceFormat *format)
{
struct vmw_svga_winsys_surface *vsrf;
struct svga_winsys_surface *ssrf;
struct vmw_winsys_screen *vws =
vmw_winsys_screen(svga_winsys_screen(screen));
struct pipe_texture *tex;
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
union drm_vmw_surface_reference_arg arg;
struct drm_vmw_surface_arg *req = &arg.req;
struct drm_vmw_surface_create_req *rep = &arg.rep;
@ -273,7 +291,7 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
*/
memset(&arg, 0, sizeof(arg));
req->sid = handle;
req->sid = whandle->handle;
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
&arg, sizeof(arg));
@ -281,14 +299,14 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
if (ret) {
fprintf(stderr, "Failed referencing shared surface. SID %d.\n"
"Error %d (%s).\n",
handle, ret, strerror(-ret));
whandle->handle, ret, strerror(-ret));
return NULL;
}
if (rep->mip_levels[0] != 1) {
fprintf(stderr, "Incorrect number of mipmap levels on shared surface."
" SID %d, levels %d\n",
handle, rep->mip_levels[0]);
whandle->handle, rep->mip_levels[0]);
goto out_mip;
}
@ -296,7 +314,7 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
if (rep->mip_levels[i] != 0) {
fprintf(stderr, "Incorrect number of faces levels on shared surface."
" SID %d, face %d present.\n",
handle, i);
whandle->handle, i);
goto out_mip;
}
}
@ -308,38 +326,32 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
pipe_reference_init(&vsrf->refcnt, 1);
p_atomic_set(&vsrf->validated, 0);
vsrf->screen = vws;
vsrf->sid = handle;
vsrf->sid = whandle->handle;
ssrf = svga_winsys_surface(vsrf);
tex = svga_screen_texture_wrap_surface(screen, templat, rep->format, ssrf);
if (!tex)
vmw_svga_winsys_surface_reference(&vsrf, NULL);
*format = rep->format;
return ssrf;
return tex;
out_mip:
vmw_ioctl_surface_destroy(vws, handle);
vmw_ioctl_surface_destroy(vws, whandle->handle);
return NULL;
}
static boolean
vmw_drm_handle_from_texture(struct drm_api *drm_api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *stride,
unsigned *handle)
vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
struct svga_winsys_surface *surface,
unsigned stride,
struct winsys_handle *whandle)
{
struct svga_winsys_surface *surface =
svga_screen_texture_get_winsys_surface(texture);
struct vmw_svga_winsys_surface *vsrf;
if (!surface)
return FALSE;
vsrf = vmw_svga_winsys_surface(surface);
*handle = vsrf->sid;
*stride = util_format_get_nblocksx(texture->format, texture->width0) *
util_format_get_blocksize(texture->format);
whandle->handle = vsrf->sid;
whandle->stride = stride;
vmw_svga_winsys_surface_reference(&vsrf, NULL);
return TRUE;
}
@ -353,9 +365,6 @@ static struct drm_api vmw_drm_api_hooks = {
.name = "vmwgfx",
.driver_name = "vmwgfx",
.create_screen = vmw_drm_create_screen,
.texture_from_shared_handle = vmw_drm_texture_from_handle,
.shared_handle_from_texture = vmw_drm_handle_from_texture,
.local_handle_from_texture = vmw_drm_handle_from_texture,
};
struct drm_api* drm_api_create()