nouveau: use dri state tracker for dri1

This commit is contained in:
Ben Skeggs
2009-05-08 09:04:10 +10:00
parent fa95ecb467
commit b7f2b7e936
6 changed files with 92 additions and 2 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
TOP = ../../../../..
include $(TOP)/configs/current
SUBDIRS = drm dri dri2
SUBDIRS = drm dri2
default install clean:
@for dir in $(SUBDIRS) ; do \
+1 -1
View File
@@ -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 \
@@ -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;
}
@@ -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
@@ -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 *