diff options
-rw-r--r-- | src/gallium/winsys/drm/nouveau/Makefile | 2 | ||||
-rw-r--r-- | src/gallium/winsys/drm/nouveau/dri2/Makefile | 2 | ||||
-rw-r--r-- | src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h (renamed from src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h) | 0 | ||||
-rw-r--r-- | src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c | 86 | ||||
-rw-r--r-- | src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h | 2 | ||||
-rw-r--r-- | src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h | 2 |
6 files changed, 92 insertions, 2 deletions
diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile index f8c8135854..be4cad6f9e 100644 --- a/src/gallium/winsys/drm/nouveau/Makefile +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -SUBDIRS = drm dri dri2 +SUBDIRS = drm dri2 default install clean: @for dir in $(SUBDIRS) ; do \ diff --git a/src/gallium/winsys/drm/nouveau/dri2/Makefile b/src/gallium/winsys/drm/nouveau/dri2/Makefile index 377a80d518..024ab150cb 100644 --- a/src/gallium/winsys/drm/nouveau/dri2/Makefile +++ b/src/gallium/winsys/drm/nouveau/dri2/Makefile @@ -1,7 +1,7 @@ TOP = ../../../../../.. include $(TOP)/configs/current -LIBNAME = nouveau_dri2.so +LIBNAME = nouveau_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \ diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h index 1207c2d609..1207c2d609 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c index a558fda140..b355a1391d 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -7,9 +7,68 @@ #include "nouveau_channel.h" #include "nouveau_bo.h" +static struct pipe_surface * +dri_surface_from_handle(struct pipe_screen *screen, + unsigned handle, + enum pipe_format format, + unsigned width, + unsigned height, + unsigned pitch) +{ + struct pipe_surface *surface = NULL; + struct pipe_texture *texture = NULL; + struct pipe_texture templat; + struct pipe_buffer *buf = NULL; + + buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle); + if (!buf) + return NULL; + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY | + NOUVEAU_TEXTURE_USAGE_LINEAR; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = format; + templat.width[0] = width; + templat.height[0] = height; + pf_get_block(templat.format, &templat.block); + + texture = screen->texture_blanket(screen, + &templat, + &pitch, + buf); + + /* we don't need the buffer from this point on */ + pipe_buffer_reference(&buf, NULL); + + if (!texture) + return NULL; + + surface = screen->get_tex_surface(screen, texture, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + /* we don't need the texture from this point on */ + pipe_texture_reference(&texture, NULL); + return surface; +} + +static struct pipe_surface * +nouveau_dri1_front_surface(struct pipe_context *pipe) +{ + return nouveau_screen(pipe->screen)->front; +} + +static struct dri1_api nouveau_dri1_api = { + nouveau_dri1_front_surface, +}; + static struct pipe_screen * nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg) { + struct dri1_create_screen_arg *dri1 = (void *)arg; struct pipe_winsys *ws; struct nouveau_winsys *nvws; struct nouveau_device *dev = NULL; @@ -67,6 +126,33 @@ nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg) return NULL; } + if (arg->mode == DRM_CREATE_DRI1) { + struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws); + struct nouveau_dri *nvdri = dri1->ddx_info; + enum pipe_format format; + + if (nvdri->bpp == 16) + format = PIPE_FORMAT_R5G6B5_UNORM; + else + format = PIPE_FORMAT_A8R8G8B8_UNORM; + + nvpws->front = dri_surface_from_handle(nvpws->pscreen, + nvdri->front_offset, + format, + nvdri->width, + nvdri->height, + nvdri->front_pitch * + (nvdri->bpp / 8)); + if (!nvpws->front) { + debug_printf("%s: error referencing front buffer\n", + __func__); + ws->destroy(ws); + return NULL; + } + + dri1->api = &nouveau_dri1_api; + } + return nouveau_pipe_winsys(ws)->pscreen; } diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h index 2782c83c0e..cc237bfc13 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h @@ -1,5 +1,7 @@ #ifndef __NOUVEAU_DRM_API_H__ #define __NOUVEAU_DRM_API_H__ #include "state_tracker/drm_api.h" +#include "state_tracker/dri1_api.h" +#include "nouveau_dri.h" #endif diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h index 10e1e269e8..ec10f1e00c 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h @@ -29,6 +29,8 @@ struct nouveau_pipe_winsys { unsigned nr_pctx; struct pipe_context **pctx; + + struct pipe_surface *front; }; static INLINE struct nouveau_pipe_winsys * |