mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 07:08:04 +02:00
nouveau: Conversion to winsys handle
Not the best conversion that could be done.
This commit is contained in:
parent
86e146df97
commit
3bd622d64e
2 changed files with 78 additions and 66 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ 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_SCANOUT;
|
||||
|
|
@ -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 *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue