mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 08:08:06 +02:00
nouveau: rewrite winsys in terms of drm_api, support dri2 state tracker
drm_api is a set of hooks used by the dri2 state tracker, this wraps our dri1 code around the same set of hooks. Currently the dri2 build will produce nouveau_dri2.so which you'll need to install as nouveau_dri.so if you wish to try it. The dri2 state tracker doesn't make it easy for a driver to support both paths in the same binary.
This commit is contained in:
parent
b46fcf25be
commit
e00ae524e2
26 changed files with 505 additions and 746 deletions
|
|
@ -24,7 +24,7 @@
|
|||
#define NOUVEAU_BUFFER_USAGE_TRANSFER (1 << 18)
|
||||
|
||||
struct nouveau_winsys {
|
||||
struct nouveau_context *nv;
|
||||
struct pipe_winsys *ws;
|
||||
|
||||
struct nouveau_channel *channel;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
SUBDIRS = common dri
|
||||
SUBDIRS = drm dri dri2
|
||||
|
||||
default install clean:
|
||||
@for dir in $(SUBDIRS) ; do \
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
TOP = ../../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = nouveaudrm
|
||||
|
||||
C_SOURCES = \
|
||||
nouveau_context.c \
|
||||
nouveau_lock.c \
|
||||
nouveau_screen.c \
|
||||
nouveau_winsys.c \
|
||||
nouveau_winsys_pipe.c \
|
||||
nouveau_winsys_softpipe.c
|
||||
|
||||
LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
|
||||
|
||||
LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other \
|
||||
&& pkg-config libdrm --atleast-version=2.3.1 \
|
||||
&& pkg-config libdrm_nouveau --exact-version=0.5 \
|
||||
&& pkg-config libdrm_nouveau --cflags-only-other \
|
||||
&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
|
||||
|
||||
include ../../../../Makefile.template
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_screen.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_dri.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
static void
|
||||
nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
|
||||
{
|
||||
nouveau_channel_free(&nvc->channel);
|
||||
|
||||
FREE(nvc);
|
||||
}
|
||||
|
||||
static struct nouveau_channel_context *
|
||||
nouveau_channel_context_create(struct nouveau_device *dev)
|
||||
{
|
||||
struct nouveau_channel_context *nvc;
|
||||
int ret;
|
||||
|
||||
nvc = CALLOC_STRUCT(nouveau_channel_context);
|
||||
if (!nvc)
|
||||
return NULL;
|
||||
|
||||
if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002,
|
||||
&nvc->channel))) {
|
||||
NOUVEAU_ERR("Error creating GPU channel: %d\n", ret);
|
||||
nouveau_channel_context_destroy(nvc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nvc->next_handle = 0x77000000;
|
||||
return nvc;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_context_init(struct nouveau_screen *nv_screen,
|
||||
drm_context_t hHWContext, drmLock *sarea_lock,
|
||||
struct nouveau_context *nv_share,
|
||||
struct nouveau_context *nv)
|
||||
{
|
||||
struct pipe_context *pipe = NULL;
|
||||
struct nouveau_channel_context *nvc = NULL;
|
||||
struct nouveau_device *dev = nv_screen->device;
|
||||
int i;
|
||||
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x00:
|
||||
/* NV04 */
|
||||
case 0x10:
|
||||
case 0x20:
|
||||
/* NV10 */
|
||||
case 0x30:
|
||||
/* NV30 */
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
/* NV40 */
|
||||
case 0x50:
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
/* G80 */
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nv->nv_screen = nv_screen;
|
||||
|
||||
{
|
||||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
|
||||
nvdev->ctx = hHWContext;
|
||||
nvdev->lock = sarea_lock;
|
||||
}
|
||||
|
||||
/* Attempt to share a single channel between multiple contexts from
|
||||
* a single process.
|
||||
*/
|
||||
nvc = nv_screen->nvc;
|
||||
if (!nvc && nv_share)
|
||||
nvc = nv_share->nvc;
|
||||
|
||||
/*XXX: temporary - disable multi-context/single-channel on pre-NV4x */
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
/* NV40 class */
|
||||
case 0x50:
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
/* G80 class */
|
||||
break;
|
||||
default:
|
||||
nvc = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nvc) {
|
||||
nvc = nouveau_channel_context_create(dev);
|
||||
if (!nvc) {
|
||||
NOUVEAU_ERR("Failed initialising GPU context\n");
|
||||
return 1;
|
||||
}
|
||||
nv_screen->nvc = nvc;
|
||||
pipe_reference_init(&nvc->reference, 1);
|
||||
}
|
||||
|
||||
pipe_reference((struct pipe_reference**)&nv->nvc, &nvc->reference);
|
||||
|
||||
/* Find a free slot for a pipe context, allocate a new one if needed */
|
||||
nv->pctx_id = -1;
|
||||
for (i = 0; i < nvc->nr_pctx; i++) {
|
||||
if (nvc->pctx[i] == NULL) {
|
||||
nv->pctx_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nv->pctx_id < 0) {
|
||||
nv->pctx_id = nvc->nr_pctx++;
|
||||
nvc->pctx =
|
||||
realloc(nvc->pctx,
|
||||
sizeof(struct pipe_context *) * nvc->nr_pctx);
|
||||
}
|
||||
|
||||
/* Create pipe */
|
||||
if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) {
|
||||
struct pipe_screen *pscreen;
|
||||
|
||||
pipe = nouveau_pipe_create(nv);
|
||||
if (!pipe) {
|
||||
NOUVEAU_ERR("Couldn't create hw pipe\n");
|
||||
return 1;
|
||||
}
|
||||
pscreen = nvc->pscreen;
|
||||
|
||||
nv->cap.hw_vertex_buffer =
|
||||
pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF);
|
||||
nv->cap.hw_index_buffer =
|
||||
pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF);
|
||||
}
|
||||
|
||||
if (!pipe) {
|
||||
NOUVEAU_MSG("Using softpipe\n");
|
||||
pipe = nouveau_create_softpipe(nv);
|
||||
if (!pipe) {
|
||||
NOUVEAU_ERR("Error creating pipe, bailing\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct pipe_texture *fb_tex;
|
||||
struct pipe_surface *fb_surf;
|
||||
struct nouveau_pipe_buffer *fb_buf;
|
||||
enum pipe_format format;
|
||||
|
||||
fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer));
|
||||
pipe_reference_init(&fb_buf->base.reference, 1);
|
||||
fb_buf->base.usage = PIPE_BUFFER_USAGE_PIXEL;
|
||||
|
||||
nouveau_bo_handle_ref(dev, nv_screen->front_offset, &fb_buf->bo);
|
||||
|
||||
if (nv_screen->front_cpp == 4)
|
||||
format = PIPE_FORMAT_A8R8G8B8_UNORM;
|
||||
else
|
||||
format = PIPE_FORMAT_R5G6B5_UNORM;
|
||||
|
||||
fb_surf = nouveau_surface_buffer_ref(nv, &fb_buf->base, format,
|
||||
nv_screen->front_pitch /
|
||||
nv_screen->front_cpp,
|
||||
nv_screen->front_height,
|
||||
nv_screen->front_pitch,
|
||||
&fb_tex);
|
||||
|
||||
nv->frontbuffer = fb_surf;
|
||||
nv->frontbuffer_texture = fb_tex;
|
||||
}
|
||||
|
||||
pipe->priv = nv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_context_cleanup(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_channel_context *nvc = nv->nvc;
|
||||
|
||||
assert(nv);
|
||||
|
||||
if (nv->pctx_id >= 0) {
|
||||
nvc->pctx[nv->pctx_id] = NULL;
|
||||
if (pipe_reference((struct pipe_reference**)&nv->nvc, NULL)) {
|
||||
nouveau_channel_context_destroy(nvc);
|
||||
nv->nv_screen->nvc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: Who cleans up the pipe? */
|
||||
}
|
||||
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
#ifndef __NOUVEAU_CONTEXT_H__
|
||||
#define __NOUVEAU_CONTEXT_H__
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_device.h"
|
||||
#include "nouveau_channel.h"
|
||||
#include "nouveau_pushbuf.h"
|
||||
#include "nouveau_bo.h"
|
||||
#include "nouveau_grobj.h"
|
||||
#include "nouveau_notifier.h"
|
||||
#include "nouveau_class.h"
|
||||
#include "nouveau_local.h"
|
||||
|
||||
struct nouveau_channel_context {
|
||||
struct pipe_reference reference;
|
||||
struct pipe_screen *pscreen;
|
||||
|
||||
unsigned cur_pctx;
|
||||
unsigned nr_pctx;
|
||||
struct pipe_context **pctx;
|
||||
|
||||
struct nouveau_channel *channel;
|
||||
unsigned next_handle;
|
||||
};
|
||||
|
||||
struct nouveau_context {
|
||||
int locked;
|
||||
struct nouveau_screen *nv_screen;
|
||||
struct pipe_surface *frontbuffer;
|
||||
struct pipe_texture *frontbuffer_texture;
|
||||
|
||||
struct {
|
||||
int hw_vertex_buffer;
|
||||
int hw_index_buffer;
|
||||
} cap;
|
||||
|
||||
/* Hardware context */
|
||||
struct nouveau_channel_context *nvc;
|
||||
int pctx_id;
|
||||
};
|
||||
|
||||
extern int nouveau_context_init(struct nouveau_screen *nv_screen,
|
||||
drm_context_t hHWContext, drmLock *sarea_lock,
|
||||
struct nouveau_context *nv_share,
|
||||
struct nouveau_context *nv);
|
||||
extern void nouveau_context_cleanup(struct nouveau_context *nv);
|
||||
|
||||
extern void LOCK_HARDWARE(struct nouveau_context *);
|
||||
extern void UNLOCK_HARDWARE(struct nouveau_context *);
|
||||
|
||||
extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int);
|
||||
extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *);
|
||||
|
||||
/* Must be provided by clients of common code */
|
||||
extern void
|
||||
nouveau_contended_lock(struct nouveau_context *nv);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef __NOUVEAU_LOCAL_H__
|
||||
#define __NOUVEAU_LOCAL_H__
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* Debug output */
|
||||
#define NOUVEAU_MSG(fmt, args...) do { \
|
||||
fprintf(stdout, "nouveau: "fmt, ##args); \
|
||||
fflush(stdout); \
|
||||
} while(0)
|
||||
|
||||
#define NOUVEAU_ERR(fmt, args...) do { \
|
||||
fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); \
|
||||
fflush(stderr); \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#include <util/u_memory.h>
|
||||
#include "nouveau_dri.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
|
||||
int
|
||||
nouveau_screen_init(struct nouveau_dri *nv_dri, int dev_fd,
|
||||
struct nouveau_screen *nv_screen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nouveau_device_open_existing(&nv_screen->device, 0,
|
||||
dev_fd, 0);
|
||||
if (ret) {
|
||||
NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nv_screen->front_offset = nv_dri->front_offset;
|
||||
nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8);
|
||||
nv_screen->front_cpp = nv_dri->bpp / 8;
|
||||
nv_screen->front_height = nv_dri->height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_screen_cleanup(struct nouveau_screen *nv_screen)
|
||||
{
|
||||
nouveau_device_close(&nv_screen->device);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef __NOUVEAU_SCREEN_H__
|
||||
#define __NOUVEAU_SCREEN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct nouveau_device;
|
||||
struct nouveau_dri;
|
||||
|
||||
struct nouveau_screen {
|
||||
struct nouveau_device *device;
|
||||
|
||||
uint32_t front_offset;
|
||||
uint32_t front_pitch;
|
||||
uint32_t front_cpp;
|
||||
uint32_t front_height;
|
||||
|
||||
void *nvc;
|
||||
};
|
||||
|
||||
int
|
||||
nouveau_screen_init(struct nouveau_dri *nv_dri, int dev_fd,
|
||||
struct nouveau_screen *nv_screen);
|
||||
|
||||
void
|
||||
nouveau_screen_cleanup(struct nouveau_screen *nv_screen);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#ifndef NOUVEAU_PIPE_WINSYS_H
|
||||
#define NOUVEAU_PIPE_WINSYS_H
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "nouveau_context.h"
|
||||
|
||||
struct nouveau_pipe_buffer {
|
||||
struct pipe_buffer base;
|
||||
struct nouveau_bo *bo;
|
||||
};
|
||||
|
||||
static INLINE struct nouveau_pipe_buffer *
|
||||
nouveau_pipe_buffer(struct pipe_buffer *buf)
|
||||
{
|
||||
return (struct nouveau_pipe_buffer *)buf;
|
||||
}
|
||||
|
||||
struct nouveau_pipe_winsys {
|
||||
struct pipe_winsys pws;
|
||||
|
||||
struct nouveau_context *nv;
|
||||
};
|
||||
|
||||
extern struct pipe_winsys *
|
||||
nouveau_create_pipe_winsys(struct nouveau_context *nv);
|
||||
|
||||
struct pipe_context *
|
||||
nouveau_create_softpipe(struct nouveau_context *nv);
|
||||
|
||||
struct pipe_context *
|
||||
nouveau_pipe_create(struct nouveau_context *nv);
|
||||
|
||||
/* Must be provided by clients of common code */
|
||||
extern void
|
||||
nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
|
||||
void *context_private);
|
||||
|
||||
struct pipe_surface *
|
||||
nouveau_surface_buffer_ref(struct nouveau_context *nv, struct pipe_buffer *pb,
|
||||
enum pipe_format format, int w, int h,
|
||||
unsigned pitch, struct pipe_texture **ppt);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
|
||||
* 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 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
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS 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.
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
*
|
||||
**************************************************************************/
|
||||
/*
|
||||
* Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
|
||||
*/
|
||||
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include <pipe/p_screen.h>
|
||||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_format.h>
|
||||
#include <softpipe/sp_winsys.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
struct nouveau_softpipe_winsys {
|
||||
struct softpipe_winsys sws;
|
||||
struct nouveau_context *nv;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return list of surface formats supported by this driver.
|
||||
*/
|
||||
static boolean
|
||||
nouveau_is_format_supported(struct softpipe_winsys *sws,
|
||||
enum pipe_format format)
|
||||
{
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
nouveau_create_softpipe(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_softpipe_winsys *nvsws;
|
||||
struct pipe_screen *pscreen;
|
||||
struct pipe_winsys *ws;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
ws = nouveau_create_pipe_winsys(nv);
|
||||
if (!ws)
|
||||
return NULL;
|
||||
pscreen = softpipe_create_screen(ws);
|
||||
if (!pscreen) {
|
||||
ws->destroy(ws);
|
||||
return NULL;
|
||||
}
|
||||
nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys);
|
||||
if (!nvsws) {
|
||||
ws->destroy(ws);
|
||||
pscreen->destroy(pscreen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nvsws->sws.is_format_supported = nouveau_is_format_supported;
|
||||
nvsws->nv = nv;
|
||||
|
||||
pipe = softpipe_create(pscreen, ws, &nvsws->sws);
|
||||
if (!pipe) {
|
||||
ws->destroy(ws);
|
||||
pscreen->destroy(pscreen);
|
||||
FREE(nvsws);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ LIBNAME = nouveau_dri.so
|
|||
MINIGLX_SOURCES =
|
||||
|
||||
PIPE_DRIVERS = \
|
||||
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
|
||||
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
|
||||
$(TOP)/src/gallium/drivers/nv04/libnv04.a \
|
||||
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
|
||||
$(TOP)/src/gallium/drivers/nv20/libnv20.a \
|
||||
|
|
@ -15,10 +15,10 @@ PIPE_DRIVERS = \
|
|||
$(TOP)/src/gallium/drivers/nv50/libnv50.a
|
||||
|
||||
DRIVER_SOURCES = \
|
||||
nouveau_context_dri.c \
|
||||
nouveau_screen_dri.c \
|
||||
nouveau_context.c \
|
||||
nouveau_screen.c \
|
||||
nouveau_swapbuffers.c \
|
||||
../common/libnouveaudrm.a
|
||||
nouveau_lock.c
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_GALLIUM_SOURCES) \
|
||||
|
|
|
|||
|
|
@ -5,23 +5,15 @@
|
|||
|
||||
#include <state_tracker/st_public.h>
|
||||
#include <state_tracker/st_context.h>
|
||||
#include <state_tracker/drm_api.h>
|
||||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_screen.h>
|
||||
|
||||
#include "../common/nouveau_winsys_pipe.h"
|
||||
#include "../common/nouveau_dri.h"
|
||||
#include "../common/nouveau_local.h"
|
||||
#include "nouveau_context_dri.h"
|
||||
#include "nouveau_screen_dri.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
static const struct dri_debug_control debug_control[] = {
|
||||
{ "bo", DEBUG_BO },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
int __nouveau_debug = 0;
|
||||
#endif
|
||||
#include "nouveau_drmif.h"
|
||||
|
||||
GLboolean
|
||||
nouveau_context_create(const __GLcontextModes *glVis,
|
||||
|
|
@ -29,34 +21,38 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
void *sharedContextPrivate)
|
||||
{
|
||||
__DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
|
||||
struct nouveau_screen_dri *nv_screen = driScrnPriv->private;
|
||||
struct nouveau_context_dri *nv = CALLOC_STRUCT(nouveau_context_dri);
|
||||
struct st_context *st_share = NULL;
|
||||
struct nouveau_context_dri *nv_share = NULL;
|
||||
struct nouveau_screen *nv_screen = driScrnPriv->private;
|
||||
struct nouveau_context *nv;
|
||||
struct pipe_context *pipe;
|
||||
struct st_context *st_share = NULL;
|
||||
|
||||
if (sharedContextPrivate) {
|
||||
st_share = ((struct nouveau_context_dri *)sharedContextPrivate)->st;
|
||||
nv_share = st_share->pipe->priv;
|
||||
if (sharedContextPrivate)
|
||||
st_share = ((struct nouveau_context *)sharedContextPrivate)->st;
|
||||
|
||||
nv = CALLOC_STRUCT(nouveau_context);
|
||||
if (!nv)
|
||||
return GL_FALSE;
|
||||
|
||||
{
|
||||
struct nouveau_device_priv *nvdev =
|
||||
nouveau_device(nv_screen->device);
|
||||
|
||||
nvdev->ctx = driContextPriv->hHWContext;
|
||||
nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock;
|
||||
}
|
||||
|
||||
if (nouveau_context_init(&nv_screen->base, driContextPriv->hHWContext,
|
||||
(drmLock *)&driScrnPriv->pSAREA->lock,
|
||||
&nv_share->base, &nv->base)) {
|
||||
pipe = drm_api_hooks.create_context(nv_screen->pscreen);
|
||||
if (!pipe) {
|
||||
FREE(nv);
|
||||
return GL_FALSE;
|
||||
}
|
||||
pipe->priv = nv;
|
||||
|
||||
pipe = nv->base.nvc->pctx[nv->base.pctx_id];
|
||||
driContextPriv->driverPrivate = (void *)nv;
|
||||
//nv->nv_screen = nv_screen;
|
||||
driContextPriv->driverPrivate = nv;
|
||||
nv->dri_screen = driScrnPriv;
|
||||
|
||||
driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
|
||||
nv->dri_screen->myNum, "nouveau");
|
||||
#ifdef DEBUG
|
||||
__nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
|
||||
debug_control);
|
||||
#endif
|
||||
|
||||
nv->st = st_create_context(pipe, glVis, st_share);
|
||||
return GL_TRUE;
|
||||
|
|
@ -65,15 +61,13 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
void
|
||||
nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
struct nouveau_context_dri *nv = driContextPriv->driverPrivate;
|
||||
struct nouveau_context *nv = driContextPriv->driverPrivate;
|
||||
|
||||
assert(nv);
|
||||
|
||||
st_finish(nv->st);
|
||||
st_destroy_context(nv->st);
|
||||
|
||||
nouveau_context_cleanup(&nv->base);
|
||||
|
||||
FREE(nv);
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +76,7 @@ nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
|
|||
__DRIdrawablePrivate *driDrawPriv,
|
||||
__DRIdrawablePrivate *driReadPriv)
|
||||
{
|
||||
struct nouveau_context_dri *nv;
|
||||
struct nouveau_context *nv;
|
||||
struct nouveau_framebuffer *draw, *read;
|
||||
|
||||
if (!driContextPriv) {
|
||||
|
|
@ -115,7 +109,7 @@ nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
|
|||
GLboolean
|
||||
nouveau_context_unbind(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
struct nouveau_context_dri *nv = driContextPriv->driverPrivate;
|
||||
struct nouveau_context *nv = driContextPriv->driverPrivate;
|
||||
(void)nv;
|
||||
|
||||
st_flush(nv->st, 0, NULL);
|
||||
|
|
@ -3,15 +3,16 @@
|
|||
|
||||
#include <dri_util.h>
|
||||
#include <xmlconfig.h>
|
||||
#include <nouveau/nouveau_winsys.h>
|
||||
#include "../common/nouveau_context.h"
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
|
||||
#define NOUVEAU_ERR(fmt, args...) debug_printf("%s: "fmt, __func__, ##args)
|
||||
|
||||
struct nouveau_framebuffer {
|
||||
struct st_framebuffer *stfb;
|
||||
};
|
||||
|
||||
struct nouveau_context_dri {
|
||||
struct nouveau_context base;
|
||||
struct nouveau_context {
|
||||
struct st_context *st;
|
||||
|
||||
/* DRI stuff */
|
||||
|
|
@ -21,6 +22,7 @@ struct nouveau_context_dri {
|
|||
driOptionCache dri_option_cache;
|
||||
drm_context_t drm_context;
|
||||
drmLock drm_lock;
|
||||
int locked;
|
||||
};
|
||||
|
||||
extern GLboolean nouveau_context_create(const __GLcontextModes *,
|
||||
|
|
@ -31,6 +33,10 @@ extern GLboolean nouveau_context_bind(__DRIcontextPrivate *,
|
|||
__DRIdrawablePrivate *read);
|
||||
extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *);
|
||||
|
||||
extern void nouveau_contended_lock(struct nouveau_context *nv);
|
||||
extern void LOCK_HARDWARE(struct nouveau_context *nv);
|
||||
extern void UNLOCK_HARDWARE(struct nouveau_context *nv);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int __nouveau_debug;
|
||||
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include <pipe/p_thread.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_drmif.h"
|
||||
|
||||
pipe_static_mutex(lockMutex);
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ pipe_static_mutex(lockMutex);
|
|||
void
|
||||
LOCK_HARDWARE(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_screen *nv_screen = nv->nv_screen;
|
||||
struct nouveau_screen *nv_screen = nv->dri_screen->private;
|
||||
struct nouveau_device *dev = nv_screen->device;
|
||||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
char __ret=0;
|
||||
|
|
@ -59,7 +60,7 @@ LOCK_HARDWARE(struct nouveau_context *nv)
|
|||
void
|
||||
UNLOCK_HARDWARE(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_screen *nv_screen = nv->nv_screen;
|
||||
struct nouveau_screen *nv_screen = nv->dri_screen->private;
|
||||
struct nouveau_device *dev = nv_screen->device;
|
||||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
|
||||
|
|
@ -5,12 +5,15 @@
|
|||
#include <pipe/p_context.h>
|
||||
#include <state_tracker/st_public.h>
|
||||
#include <state_tracker/st_cb_fbo.h>
|
||||
#include <nouveau_drm.h>
|
||||
#include "../common/nouveau_dri.h"
|
||||
#include "../common/nouveau_local.h"
|
||||
#include "nouveau_context_dri.h"
|
||||
#include "nouveau_screen_dri.h"
|
||||
#include <state_tracker/drm_api.h>
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_swapbuffers.h"
|
||||
#include "nouveau_dri.h"
|
||||
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_drmif.h"
|
||||
|
||||
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12
|
||||
#error nouveau_drm.h version does not match expected version
|
||||
|
|
@ -178,11 +181,58 @@ nouveau_fill_in_modes(__DRIscreenPrivate *psp,
|
|||
return configs;
|
||||
}
|
||||
|
||||
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_RENDER_TARGET;
|
||||
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 const __DRIconfig **
|
||||
nouveau_screen_create(__DRIscreenPrivate *psp)
|
||||
{
|
||||
struct nouveau_dri *nv_dri = psp->pDevPriv;
|
||||
struct nouveau_screen_dri *nv_screen;
|
||||
struct nouveau_screen *nv_screen;
|
||||
static const __DRIversion ddx_expected =
|
||||
{ 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
|
||||
static const __DRIversion dri_expected = { 4, 0, 0 };
|
||||
|
|
@ -210,17 +260,38 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
nv_screen = CALLOC_STRUCT(nouveau_screen_dri);
|
||||
nv_screen = CALLOC_STRUCT(nouveau_screen);
|
||||
if (!nv_screen)
|
||||
return NULL;
|
||||
|
||||
driParseOptionInfo(&nv_screen->option_cache,
|
||||
__driConfigOptions, __driNConfigOptions);
|
||||
nouveau_device_open_existing(&nv_screen->device, 0, psp->fd, 0);
|
||||
|
||||
if (nouveau_screen_init(nv_dri, psp->fd, &nv_screen->base)) {
|
||||
nv_screen->pscreen = drm_api_hooks.create_screen(psp->fd, 0);
|
||||
if (!nv_screen->pscreen) {
|
||||
FREE(nv_screen);
|
||||
return NULL;
|
||||
}
|
||||
nv_screen->pscreen->flush_frontbuffer = nouveau_flush_frontbuffer;
|
||||
|
||||
{
|
||||
enum pipe_format format;
|
||||
|
||||
if (nv_dri->bpp == 16)
|
||||
format = PIPE_FORMAT_R5G6B5_UNORM;
|
||||
else
|
||||
format = PIPE_FORMAT_A8R8G8B8_UNORM;
|
||||
|
||||
nv_screen->fb = dri_surface_from_handle(nv_screen->pscreen,
|
||||
nv_dri->front_offset,
|
||||
format,
|
||||
nv_dri->width,
|
||||
nv_dri->height,
|
||||
nv_dri->front_pitch *
|
||||
nv_dri->bpp / 8);
|
||||
}
|
||||
|
||||
driParseOptionInfo(&nv_screen->option_cache,
|
||||
__driConfigOptions, __driNConfigOptions);
|
||||
|
||||
nv_screen->driScrnPriv = psp;
|
||||
psp->private = (void *)nv_screen;
|
||||
|
|
@ -234,10 +305,9 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
|
|||
static void
|
||||
nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv)
|
||||
{
|
||||
struct nouveau_screen_dri *nv_screen = driScrnPriv->private;
|
||||
struct nouveau_screen *nv_screen = driScrnPriv->private;
|
||||
|
||||
driScrnPriv->private = NULL;
|
||||
nouveau_screen_cleanup(&nv_screen->base);
|
||||
FREE(nv_screen);
|
||||
}
|
||||
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
#ifndef __NOUVEAU_SCREEN_DRI_H__
|
||||
#define __NOUVEAU_SCREEN_DRI_H__
|
||||
|
||||
#include "../common/nouveau_screen.h"
|
||||
#include "xmlconfig.h"
|
||||
|
||||
struct nouveau_screen_dri {
|
||||
struct nouveau_screen base;
|
||||
struct nouveau_screen {
|
||||
__DRIscreenPrivate *driScrnPriv;
|
||||
driOptionCache option_cache;
|
||||
|
||||
struct nouveau_device *device;
|
||||
|
||||
struct pipe_screen *pscreen;
|
||||
struct pipe_surface *fb;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -7,23 +7,25 @@
|
|||
#include <state_tracker/st_context.h>
|
||||
#include <state_tracker/st_cb_fbo.h>
|
||||
|
||||
#include "../common/nouveau_local.h"
|
||||
#include "nouveau_context_dri.h"
|
||||
#include "nouveau_screen_dri.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_swapbuffers.h"
|
||||
|
||||
#include "nouveau_pushbuf.h"
|
||||
|
||||
void
|
||||
nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
|
||||
const drm_clip_rect_t *rect)
|
||||
{
|
||||
struct nouveau_context_dri *nv = dPriv->driContextPriv->driverPrivate;
|
||||
struct pipe_context *pipe = nv->base.nvc->pctx[nv->base.pctx_id];
|
||||
struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate;
|
||||
struct nouveau_screen *nv_screen = nv->dri_screen->private;
|
||||
struct pipe_context *pipe = nv->st->pipe;
|
||||
drm_clip_rect_t *pbox;
|
||||
int nbox, i;
|
||||
|
||||
LOCK_HARDWARE(&nv->base);
|
||||
LOCK_HARDWARE(nv);
|
||||
if (!dPriv->numClipRects) {
|
||||
UNLOCK_HARDWARE(&nv->base);
|
||||
UNLOCK_HARDWARE(nv);
|
||||
return;
|
||||
}
|
||||
pbox = dPriv->pClipRects;
|
||||
|
|
@ -39,12 +41,12 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
|
|||
w = pbox->x2 - pbox->x1;
|
||||
h = pbox->y2 - pbox->y1;
|
||||
|
||||
pipe->surface_copy(pipe, nv->base.frontbuffer,
|
||||
dx, dy, surf, sx, sy, w, h);
|
||||
pipe->surface_copy(pipe, nv_screen->fb, dx, dy, surf,
|
||||
sx, sy, w, h);
|
||||
}
|
||||
|
||||
FIRE_RING(nv->base.nvc->channel);
|
||||
UNLOCK_HARDWARE(&nv->base);
|
||||
pipe->flush(pipe, 0, NULL);
|
||||
UNLOCK_HARDWARE(nv);
|
||||
|
||||
if (nv->last_stamp != dPriv->lastStamp) {
|
||||
struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
|
||||
|
|
@ -86,19 +88,19 @@ nouveau_swap_buffers(__DRIdrawablePrivate *dPriv)
|
|||
}
|
||||
|
||||
void
|
||||
nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
|
||||
nouveau_flush_frontbuffer(struct pipe_screen *pscreen, struct pipe_surface *ps,
|
||||
void *context_private)
|
||||
{
|
||||
struct nouveau_context_dri *nv = context_private;
|
||||
struct nouveau_context *nv = context_private;
|
||||
__DRIdrawablePrivate *dPriv = nv->dri_drawable;
|
||||
|
||||
nouveau_copy_buffer(dPriv, surf, NULL);
|
||||
nouveau_copy_buffer(dPriv, ps, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_contended_lock(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_context_dri *nv_sub = (struct nouveau_context_dri*)nv;
|
||||
struct nouveau_context *nv_sub = (struct nouveau_context*)nv;
|
||||
__DRIdrawablePrivate *dPriv = nv_sub->dri_drawable;
|
||||
__DRIscreenPrivate *sPriv = nv_sub->dri_screen;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
#ifndef __NOUVEAU_SWAPBUFFERS_H__
|
||||
#define __NOUVEAU_SWAPBUFFERS_H__
|
||||
|
||||
extern void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *,
|
||||
const drm_clip_rect_t *);
|
||||
extern void nouveau_copy_sub_buffer(__DRIdrawablePrivate *,
|
||||
int x, int y, int w, int h);
|
||||
extern void nouveau_swap_buffers(__DRIdrawablePrivate *);
|
||||
void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *,
|
||||
const drm_clip_rect_t *);
|
||||
void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, int x, int y, int w, int h);
|
||||
void nouveau_swap_buffers(__DRIdrawablePrivate *);
|
||||
void nouveau_flush_frontbuffer(struct pipe_screen *, struct pipe_surface *,
|
||||
void *context_private);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
26
src/gallium/winsys/drm/nouveau/dri2/Makefile
Normal file
26
src/gallium/winsys/drm/nouveau/dri2/Makefile
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
TOP = ../../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = nouveau_dri2.so
|
||||
|
||||
PIPE_DRIVERS = \
|
||||
$(TOP)/src/gallium/state_trackers/dri2/libdri2drm.a \
|
||||
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
|
||||
$(TOP)/src/gallium/drivers/nv04/libnv04.a \
|
||||
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
|
||||
$(TOP)/src/gallium/drivers/nv20/libnv20.a \
|
||||
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
||||
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
||||
$(TOP)/src/gallium/drivers/nv50/libnv50.a
|
||||
|
||||
DRIVER_SOURCES =
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_GALLIUM_SOURCES) \
|
||||
$(DRIVER_SOURCES)
|
||||
|
||||
include ../../Makefile.template
|
||||
|
||||
DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
|
||||
|
||||
symlinks:
|
||||
13
src/gallium/winsys/drm/nouveau/drm/Makefile
Normal file
13
src/gallium/winsys/drm/nouveau/drm/Makefile
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
TOP = ../../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = nouveaudrm
|
||||
|
||||
C_SOURCES = nouveau_drm_api.c \
|
||||
nouveau_winsys_pipe.c \
|
||||
nouveau_winsys.c
|
||||
|
||||
LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
|
||||
LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
|
||||
|
||||
include ../../../../Makefile.template
|
||||
194
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
Normal file
194
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
#include "util/u_memory.h"
|
||||
|
||||
#include "nouveau_drm_api.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_channel.h"
|
||||
#include "nouveau_bo.h"
|
||||
|
||||
static struct pipe_screen *
|
||||
nouveau_drm_create_screen(int fd, int pciid)
|
||||
{
|
||||
struct pipe_winsys *ws;
|
||||
struct nouveau_winsys *nvws;
|
||||
struct nouveau_device *dev = NULL;
|
||||
struct pipe_screen *(*init)(struct pipe_winsys *,
|
||||
struct nouveau_winsys *);
|
||||
int ret;
|
||||
|
||||
ret = nouveau_device_open_existing(&dev, 0, fd, 0);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x00:
|
||||
init = nv04_screen_create;
|
||||
break;
|
||||
case 0x10:
|
||||
init = nv10_screen_create;
|
||||
break;
|
||||
case 0x20:
|
||||
init = nv20_screen_create;
|
||||
break;
|
||||
case 0x30:
|
||||
init = nv30_screen_create;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
init = nv40_screen_create;
|
||||
break;
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
case 0xa0:
|
||||
init = nv50_screen_create;
|
||||
break;
|
||||
default:
|
||||
debug_printf("%s: unknown chipset nv%02x\n", __func__,
|
||||
dev->chipset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ws = nouveau_pipe_winsys_new(dev);
|
||||
if (!ws) {
|
||||
nouveau_device_close(&dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nvws = nouveau_winsys_new(ws);
|
||||
if (!nvws) {
|
||||
ws->destroy(ws);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nouveau_pipe_winsys(ws)->pscreen = init(ws, nvws);
|
||||
if (!nouveau_pipe_winsys(ws)->pscreen) {
|
||||
ws->destroy(ws);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nouveau_pipe_winsys(ws)->pscreen;
|
||||
}
|
||||
|
||||
static struct pipe_context *
|
||||
nouveau_drm_create_context(struct pipe_screen *pscreen)
|
||||
{
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_screen(pscreen);
|
||||
struct pipe_context *(*init)(struct pipe_screen *, unsigned);
|
||||
unsigned chipset = nvpws->channel->device->chipset;
|
||||
int i;
|
||||
|
||||
switch (chipset & 0xf0) {
|
||||
case 0x00:
|
||||
init = nv04_create;
|
||||
break;
|
||||
case 0x10:
|
||||
init = nv10_create;
|
||||
break;
|
||||
case 0x20:
|
||||
init = nv20_create;
|
||||
break;
|
||||
case 0x30:
|
||||
init = nv30_create;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
init = nv40_create;
|
||||
break;
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
case 0xa0:
|
||||
init = nv50_create;
|
||||
break;
|
||||
default:
|
||||
debug_printf("%s: unknown chipset nv%02x\n", __func__, chipset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find a free slot for a pipe context, allocate a new one if needed */
|
||||
for (i = 0; i < nvpws->nr_pctx; i++) {
|
||||
if (nvpws->pctx[i] == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == nvpws->nr_pctx) {
|
||||
nvpws->nr_pctx++;
|
||||
nvpws->pctx = realloc(nvpws->pctx,
|
||||
sizeof(*nvpws->pctx) * nvpws->nr_pctx);
|
||||
}
|
||||
|
||||
nvpws->pctx[i] = init(pscreen, i);
|
||||
return nvpws->pctx[i];
|
||||
}
|
||||
|
||||
static boolean
|
||||
nouveau_drm_pb_from_pt(struct pipe_texture *pt, struct pipe_buffer **ppb,
|
||||
unsigned *stride)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
nouveau_drm_pb_from_handle(struct pipe_screen *pscreen, const char *name,
|
||||
unsigned handle)
|
||||
{
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_screen(pscreen);
|
||||
struct nouveau_device *dev = nvpws->channel->device;
|
||||
struct nouveau_pipe_buffer *nvpb;
|
||||
int ret;
|
||||
|
||||
nvpb = CALLOC_STRUCT(nouveau_pipe_buffer);
|
||||
if (!nvpb)
|
||||
return NULL;
|
||||
|
||||
ret = nouveau_bo_handle_ref(dev, handle, &nvpb->bo);
|
||||
if (ret) {
|
||||
debug_printf("%s: ref name 0x%08x failed with %d\n",
|
||||
__func__, handle, ret);
|
||||
FREE(nvpb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pipe_reference_init(&nvpb->base.reference, 1);
|
||||
nvpb->base.screen = pscreen;
|
||||
nvpb->base.alignment = 0;
|
||||
nvpb->base.usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
|
||||
PIPE_BUFFER_USAGE_CPU_READ_WRITE;
|
||||
nvpb->base.size = nvpb->bo->size;
|
||||
return &nvpb->base;
|
||||
}
|
||||
|
||||
static boolean
|
||||
nouveau_drm_handle_from_pb(struct pipe_screen *pscreen, struct pipe_buffer *pb,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct nouveau_pipe_buffer *nvpb = nouveau_pipe_buffer(pb);
|
||||
|
||||
if (!nvpb)
|
||||
return FALSE;
|
||||
|
||||
*handle = nvpb->bo->handle;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
nouveau_drm_name_from_pb(struct pipe_screen *pscreen, struct pipe_buffer *pb,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct nouveau_pipe_buffer *nvpb = nouveau_pipe_buffer(pb);
|
||||
|
||||
if (!nvpb)
|
||||
return FALSE;
|
||||
|
||||
return nouveau_bo_handle_get(nvpb->bo, handle) == 0;
|
||||
}
|
||||
|
||||
struct drm_api drm_api_hooks = {
|
||||
.create_screen = nouveau_drm_create_screen,
|
||||
.create_context = nouveau_drm_create_context,
|
||||
.buffer_from_texture = nouveau_drm_pb_from_pt,
|
||||
.buffer_from_handle = nouveau_drm_pb_from_handle,
|
||||
.handle_from_buffer = nouveau_drm_handle_from_pb,
|
||||
.global_handle_from_buffer = nouveau_drm_name_from_pb,
|
||||
};
|
||||
|
||||
5
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
Normal file
5
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef __NOUVEAU_DRM_API_H__
|
||||
#define __NOUVEAU_DRM_API_H__
|
||||
#include "state_tracker/drm_api.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
#include "util/u_memory.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
|
||||
static int
|
||||
nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count,
|
||||
struct nouveau_notifier **notify)
|
||||
{
|
||||
struct nouveau_context *nv = nvws->nv;
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws);
|
||||
|
||||
return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++,
|
||||
return nouveau_notifier_alloc(nvpws->channel, nvpws->next_handle++,
|
||||
count, notify);
|
||||
}
|
||||
|
||||
|
|
@ -20,12 +16,11 @@ static int
|
|||
nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass,
|
||||
struct nouveau_grobj **grobj)
|
||||
{
|
||||
struct nouveau_context *nv = nvws->nv;
|
||||
struct nouveau_channel *chan = nv->nvc->channel;
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws);
|
||||
struct nouveau_channel *chan = nvpws->channel;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++,
|
||||
grclass, grobj);
|
||||
ret = nouveau_grobj_alloc(chan, nvpws->next_handle++, grclass, grobj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -62,55 +57,18 @@ nouveau_pipe_get_bo(struct pipe_buffer *pb)
|
|||
return nouveau_pipe_buffer(pb)->bo;
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
nouveau_pipe_create(struct nouveau_context *nv)
|
||||
struct nouveau_winsys *
|
||||
nouveau_winsys_new(struct pipe_winsys *ws)
|
||||
{
|
||||
struct nouveau_channel_context *nvc = nv->nvc;
|
||||
struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys);
|
||||
struct pipe_screen *(*hws_create)(struct pipe_winsys *,
|
||||
struct nouveau_winsys *);
|
||||
struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned);
|
||||
struct pipe_winsys *ws;
|
||||
unsigned chipset = nv->nv_screen->device->chipset;
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
|
||||
struct nouveau_winsys *nvws;
|
||||
|
||||
nvws = CALLOC_STRUCT(nouveau_winsys);
|
||||
if (!nvws)
|
||||
return NULL;
|
||||
|
||||
switch (chipset & 0xf0) {
|
||||
case 0x00:
|
||||
hws_create = nv04_screen_create;
|
||||
hw_create = nv04_create;
|
||||
break;
|
||||
case 0x10:
|
||||
hws_create = nv10_screen_create;
|
||||
hw_create = nv10_create;
|
||||
break;
|
||||
case 0x20:
|
||||
hws_create = nv20_screen_create;
|
||||
hw_create = nv20_create;
|
||||
break;
|
||||
case 0x30:
|
||||
hws_create = nv30_screen_create;
|
||||
hw_create = nv30_create;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
hws_create = nv40_screen_create;
|
||||
hw_create = nv40_create;
|
||||
break;
|
||||
case 0x50:
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
hws_create = nv50_screen_create;
|
||||
hw_create = nv50_create;
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nvws->nv = nv;
|
||||
nvws->channel = nv->nvc->channel;
|
||||
nvws->ws = ws;
|
||||
nvws->channel = nvpws->channel;
|
||||
|
||||
nvws->res_init = nouveau_resource_init;
|
||||
nvws->res_alloc = nouveau_resource_alloc;
|
||||
|
|
@ -131,16 +89,6 @@ nouveau_pipe_create(struct nouveau_context *nv)
|
|||
|
||||
nvws->get_bo = nouveau_pipe_get_bo;
|
||||
|
||||
ws = nouveau_create_pipe_winsys(nv);
|
||||
|
||||
if (!nvc->pscreen) {
|
||||
nvc->pscreen = hws_create(ws, nvws);
|
||||
if (!nvc->pscreen) {
|
||||
NOUVEAU_ERR("Couldn't create hw screen\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id);
|
||||
return nvc->pctx[nv->pctx_id];
|
||||
return nvws;
|
||||
}
|
||||
|
||||
|
|
@ -2,11 +2,12 @@
|
|||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_inlines.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_bo.h"
|
||||
|
||||
static const char *
|
||||
nouveau_get_name(struct pipe_winsys *pws)
|
||||
{
|
||||
|
|
@ -14,9 +15,10 @@ nouveau_get_name(struct pipe_winsys *pws)
|
|||
}
|
||||
|
||||
static uint32_t
|
||||
nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
|
||||
nouveau_flags_from_usage(struct pipe_winsys *ws, unsigned usage)
|
||||
{
|
||||
struct nouveau_device *dev = nv->nv_screen->device;
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
|
||||
struct pipe_screen *pscreen = nvpws->pscreen;
|
||||
uint32_t flags = NOUVEAU_BO_LOCAL;
|
||||
|
||||
if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER)
|
||||
|
|
@ -28,7 +30,7 @@ nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
|
|||
if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
|
||||
flags |= NOUVEAU_BO_VRAM;
|
||||
|
||||
switch (dev->chipset & 0xf0) {
|
||||
switch (nvpws->channel->device->chipset & 0xf0) {
|
||||
case 0x50:
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
|
|
@ -42,12 +44,12 @@ nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
|
|||
}
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_VERTEX) {
|
||||
if (nv->cap.hw_vertex_buffer)
|
||||
if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF))
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
}
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_INDEX) {
|
||||
if (nv->cap.hw_index_buffer)
|
||||
if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF))
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
}
|
||||
|
||||
|
|
@ -55,12 +57,11 @@ nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
|
|||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
|
||||
nouveau_pipe_bo_create(struct pipe_winsys *ws, unsigned alignment,
|
||||
unsigned usage, unsigned size)
|
||||
{
|
||||
struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
|
||||
struct nouveau_context *nv = nvpws->nv;
|
||||
struct nouveau_device *dev = nv->nv_screen->device;
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
|
||||
struct nouveau_device *dev = nvpws->channel->device;
|
||||
struct nouveau_pipe_buffer *nvbuf;
|
||||
uint32_t flags;
|
||||
|
||||
|
|
@ -72,8 +73,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
|
|||
nvbuf->base.usage = usage;
|
||||
nvbuf->base.size = size;
|
||||
|
||||
flags = nouveau_flags_from_usage(nv, usage);
|
||||
|
||||
flags = nouveau_flags_from_usage(ws, usage);
|
||||
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
|
||||
FREE(nvbuf);
|
||||
return NULL;
|
||||
|
|
@ -83,10 +83,10 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
|
|||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
|
||||
nouveau_pipe_bo_user_create(struct pipe_winsys *ws, void *ptr, unsigned bytes)
|
||||
{
|
||||
struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
|
||||
struct nouveau_device *dev = nvpws->nv->nv_screen->device;
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
|
||||
struct nouveau_device *dev = nvpws->channel->device;
|
||||
struct nouveau_pipe_buffer *nvbuf;
|
||||
|
||||
nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
|
||||
|
|
@ -119,34 +119,11 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
|
|||
struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
|
||||
uint32_t map_flags = 0;
|
||||
|
||||
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
|
||||
/* Remove this when this code is modified to support DONTBLOCK
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & PIPE_BUFFER_USAGE_CPU_READ)
|
||||
map_flags |= NOUVEAU_BO_RD;
|
||||
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
|
||||
map_flags |= NOUVEAU_BO_WR;
|
||||
|
||||
#if 0
|
||||
if (flags & PIPE_BUFFER_USAGE_DISCARD &&
|
||||
!(flags & PIPE_BUFFER_USAGE_CPU_READ) &&
|
||||
nouveau_bo_busy(nvbuf->bo, map_flags)) {
|
||||
struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
|
||||
struct nouveau_context *nv = nvpws->nv;
|
||||
struct nouveau_device *dev = nv->nv_screen->device;
|
||||
struct nouveau_bo *rename;
|
||||
uint32_t flags = nouveau_flags_from_usage(nv, buf->usage);
|
||||
|
||||
if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) {
|
||||
nouveau_bo_ref(NULL, &nvbuf->bo);
|
||||
nvbuf->bo = rename;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nouveau_bo_map(nvbuf->bo, map_flags))
|
||||
return NULL;
|
||||
return nvbuf->bo->map;
|
||||
|
|
@ -182,70 +159,46 @@ nouveau_pipe_fence_finish(struct pipe_winsys *ws,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct pipe_surface *
|
||||
nouveau_surface_buffer_ref(struct nouveau_context *nv, struct pipe_buffer *pb,
|
||||
enum pipe_format format, int w, int h,
|
||||
unsigned pitch, struct pipe_texture **ppt)
|
||||
{
|
||||
struct pipe_screen *pscreen = nv->nvc->pscreen;
|
||||
struct pipe_texture tmpl, *pt;
|
||||
struct pipe_surface *ps;
|
||||
|
||||
memset(&tmpl, 0, sizeof(tmpl));
|
||||
tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
|
||||
NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
tmpl.target = PIPE_TEXTURE_2D;
|
||||
tmpl.width[0] = w;
|
||||
tmpl.height[0] = h;
|
||||
tmpl.depth[0] = 1;
|
||||
tmpl.format = format;
|
||||
pf_get_block(tmpl.format, &tmpl.block);
|
||||
tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w);
|
||||
tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h);
|
||||
|
||||
pt = pscreen->texture_blanket(pscreen, &tmpl, &pitch, pb);
|
||||
if (!pt)
|
||||
return NULL;
|
||||
|
||||
ps = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0,
|
||||
PIPE_BUFFER_USAGE_GPU_WRITE);
|
||||
|
||||
*ppt = pt;
|
||||
return ps;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_destroy(struct pipe_winsys *pws)
|
||||
nouveau_destroy(struct pipe_winsys *ws)
|
||||
{
|
||||
FREE(pws);
|
||||
struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
|
||||
|
||||
nouveau_device_close(&nvpws->channel->device);
|
||||
FREE(nvpws);
|
||||
}
|
||||
|
||||
struct pipe_winsys *
|
||||
nouveau_create_pipe_winsys(struct nouveau_context *nv)
|
||||
nouveau_pipe_winsys_new(struct nouveau_device *dev)
|
||||
{
|
||||
struct nouveau_pipe_winsys *nvpws;
|
||||
struct pipe_winsys *pws;
|
||||
int ret;
|
||||
|
||||
nvpws = CALLOC_STRUCT(nouveau_pipe_winsys);
|
||||
if (!nvpws)
|
||||
return NULL;
|
||||
nvpws->nv = nv;
|
||||
pws = &nvpws->pws;
|
||||
|
||||
pws->flush_frontbuffer = nouveau_flush_frontbuffer;
|
||||
ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
|
||||
&nvpws->channel);
|
||||
if (ret) {
|
||||
debug_printf("%s: error opening GPU channel: %d\n",
|
||||
__func__, ret);
|
||||
FREE(nvpws);
|
||||
return NULL;
|
||||
}
|
||||
nvpws->next_handle = 0x77000000;
|
||||
|
||||
pws->buffer_create = nouveau_pipe_bo_create;
|
||||
pws->buffer_destroy = nouveau_pipe_bo_del;
|
||||
pws->user_buffer_create = nouveau_pipe_bo_user_create;
|
||||
pws->buffer_map = nouveau_pipe_bo_map;
|
||||
pws->buffer_unmap = nouveau_pipe_bo_unmap;
|
||||
nvpws->base.buffer_create = nouveau_pipe_bo_create;
|
||||
nvpws->base.buffer_destroy = nouveau_pipe_bo_del;
|
||||
nvpws->base.user_buffer_create = nouveau_pipe_bo_user_create;
|
||||
nvpws->base.buffer_map = nouveau_pipe_bo_map;
|
||||
nvpws->base.buffer_unmap = nouveau_pipe_bo_unmap;
|
||||
|
||||
pws->fence_reference = nouveau_pipe_fence_reference;
|
||||
pws->fence_signalled = nouveau_pipe_fence_signalled;
|
||||
pws->fence_finish = nouveau_pipe_fence_finish;
|
||||
nvpws->base.fence_reference = nouveau_pipe_fence_reference;
|
||||
nvpws->base.fence_signalled = nouveau_pipe_fence_signalled;
|
||||
nvpws->base.fence_finish = nouveau_pipe_fence_finish;
|
||||
|
||||
pws->get_name = nouveau_get_name;
|
||||
pws->destroy = nouveau_destroy;
|
||||
|
||||
return &nvpws->pws;
|
||||
nvpws->base.get_name = nouveau_get_name;
|
||||
nvpws->base.destroy = nouveau_destroy;
|
||||
return &nvpws->base;
|
||||
}
|
||||
52
src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h
Normal file
52
src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef NOUVEAU_PIPE_WINSYS_H
|
||||
#define NOUVEAU_PIPE_WINSYS_H
|
||||
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
|
||||
#include "nouveau_device.h"
|
||||
|
||||
struct nouveau_pipe_buffer {
|
||||
struct pipe_buffer base;
|
||||
struct nouveau_bo *bo;
|
||||
};
|
||||
|
||||
static INLINE struct nouveau_pipe_buffer *
|
||||
nouveau_pipe_buffer(struct pipe_buffer *buf)
|
||||
{
|
||||
return (struct nouveau_pipe_buffer *)buf;
|
||||
}
|
||||
|
||||
struct nouveau_pipe_winsys {
|
||||
struct pipe_winsys base;
|
||||
|
||||
struct pipe_screen *pscreen;
|
||||
|
||||
struct nouveau_channel *channel;
|
||||
uint32_t next_handle;
|
||||
|
||||
unsigned nr_pctx;
|
||||
struct pipe_context **pctx;
|
||||
};
|
||||
|
||||
static INLINE struct nouveau_pipe_winsys *
|
||||
nouveau_pipe_winsys(struct pipe_winsys *ws)
|
||||
{
|
||||
return (struct nouveau_pipe_winsys *)ws;
|
||||
}
|
||||
|
||||
static INLINE struct nouveau_pipe_winsys *
|
||||
nouveau_screen(struct pipe_screen *pscreen)
|
||||
{
|
||||
return nouveau_pipe_winsys(pscreen->winsys);
|
||||
}
|
||||
|
||||
struct pipe_winsys *
|
||||
nouveau_pipe_winsys_new(struct nouveau_device *);
|
||||
|
||||
struct nouveau_winsys *
|
||||
nouveau_winsys_new(struct pipe_winsys *ws);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue