mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 04:38:03 +02:00
nouveau: enable multi-context/single-channel support for nv40
This commit is contained in:
parent
0a12e4587c
commit
b560ed2444
11 changed files with 94 additions and 15 deletions
|
|
@ -54,20 +54,20 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *,
|
|||
unsigned chipset);
|
||||
|
||||
extern struct pipe_context *
|
||||
nv30_create(struct pipe_screen *);
|
||||
nv30_create(struct pipe_screen *, unsigned pctx_id);
|
||||
|
||||
extern struct pipe_screen *
|
||||
nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *,
|
||||
unsigned chipset);
|
||||
|
||||
extern struct pipe_context *
|
||||
nv40_create(struct pipe_screen *);
|
||||
nv40_create(struct pipe_screen *, unsigned pctx_id);
|
||||
|
||||
extern struct pipe_screen *
|
||||
nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *,
|
||||
unsigned chipset);
|
||||
|
||||
extern struct pipe_context *
|
||||
nv50_create(struct pipe_screen *);
|
||||
nv50_create(struct pipe_screen *, unsigned pctx_id);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ nv30_init_hwctx(struct nv30_context *nv30, int rankine_class)
|
|||
#define NV35TCL_CHIPSET_3X_MASK 0x000001e0
|
||||
|
||||
struct pipe_context *
|
||||
nv30_create(struct pipe_screen *screen)
|
||||
nv30_create(struct pipe_screen *screen, unsigned pctx_id)
|
||||
{
|
||||
struct pipe_winsys *pipe_winsys = screen->winsys;
|
||||
struct nouveau_winsys *nvws = nv30_screen(screen)->nvws;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ nv40_destroy(struct pipe_context *pipe)
|
|||
}
|
||||
|
||||
struct pipe_context *
|
||||
nv40_create(struct pipe_screen *pscreen)
|
||||
nv40_create(struct pipe_screen *pscreen, unsigned pctx_id)
|
||||
{
|
||||
struct nv40_screen *screen = nv40_screen(pscreen);
|
||||
struct pipe_winsys *ws = pscreen->winsys;
|
||||
|
|
@ -56,6 +56,7 @@ nv40_create(struct pipe_screen *pscreen)
|
|||
if (!nv40)
|
||||
return NULL;
|
||||
nv40->screen = screen;
|
||||
nv40->pctx_id = pctx_id;
|
||||
|
||||
nv40->chipset = chipset;
|
||||
nv40->nvws = nvws;
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ struct nv40_context {
|
|||
|
||||
struct nouveau_winsys *nvws;
|
||||
struct nv40_screen *screen;
|
||||
unsigned pctx_id;
|
||||
|
||||
struct draw_context *draw;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ struct nv40_screen {
|
|||
struct nouveau_winsys *nvws;
|
||||
unsigned chipset;
|
||||
|
||||
unsigned cur_pctx;
|
||||
|
||||
/* HW graphics objects */
|
||||
struct nouveau_grobj *curie;
|
||||
struct nouveau_notifier *sync;
|
||||
|
|
|
|||
|
|
@ -62,8 +62,18 @@ static void
|
|||
nv40_state_emit(struct nv40_context *nv40)
|
||||
{
|
||||
struct nv40_state *state = &nv40->state;
|
||||
struct nv40_screen *screen = nv40->screen;
|
||||
unsigned i, samplers;
|
||||
|
||||
if (nv40->pctx_id != screen->cur_pctx) {
|
||||
for (i = 0; i < NV40_STATE_MAX; i++) {
|
||||
if (screen->state[i] != state->hw[i] && state->hw[i])
|
||||
state->dirty |= (1ULL << i);
|
||||
}
|
||||
|
||||
screen->cur_pctx = nv40->pctx_id;
|
||||
}
|
||||
|
||||
while (state->dirty) {
|
||||
unsigned idx = ffsll(state->dirty) - 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ nv50_init_hwctx(struct nv50_context *nv50, int tesla_class)
|
|||
#define GRCLASS5097_CHIPSETS 0x00000000
|
||||
#define GRCLASS8297_CHIPSETS 0x00000010
|
||||
struct pipe_context *
|
||||
nv50_create(struct pipe_screen *pscreen)
|
||||
nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
|
||||
{
|
||||
struct pipe_winsys *pipe_winsys = pscreen->winsys;
|
||||
struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include "state_tracker/st_public.h"
|
||||
#include "state_tracker/st_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
|
|
@ -101,7 +102,8 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
struct nouveau_device_priv *nvdev;
|
||||
struct pipe_context *pipe = NULL;
|
||||
struct st_context *st_share = NULL;
|
||||
int ret;
|
||||
struct nouveau_channel_context *nvc = NULL;
|
||||
int i, ret;
|
||||
|
||||
if (sharedContextPrivate) {
|
||||
st_share = ((struct nouveau_context *)sharedContextPrivate)->st;
|
||||
|
|
@ -163,12 +165,56 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
nv->frontbuffer = fb_surf;
|
||||
}
|
||||
|
||||
nv->nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset);
|
||||
if (!nv->nvc) {
|
||||
NOUVEAU_ERR("Failed initialising GPU channel context\n");
|
||||
return GL_FALSE;
|
||||
/* Attempt to share a single channel between multiple contexts from
|
||||
* a single process.
|
||||
*/
|
||||
nvc = nv_screen->nvc;
|
||||
if (!nvc && st_share) {
|
||||
struct nouveau_context *snv = st_share->pipe->priv;
|
||||
if (snv) {
|
||||
nvc = snv->nvc;
|
||||
}
|
||||
}
|
||||
|
||||
/*XXX: temporary - disable multi-context/single-channel on non-NV4x */
|
||||
switch (nv->chipset & 0xf0) {
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
break;
|
||||
default:
|
||||
nvc = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nvc) {
|
||||
nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset);
|
||||
if (!nvc) {
|
||||
NOUVEAU_ERR("Failed initialising GPU context\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
nv_screen->nvc = nvc;
|
||||
}
|
||||
|
||||
nvc->refcount++;
|
||||
nv->nvc = nvc;
|
||||
|
||||
/* 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 (nv->chipset < 0x50)
|
||||
ret = nouveau_surface_init_nv04(nv);
|
||||
else
|
||||
|
|
@ -201,13 +247,18 @@ void
|
|||
nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
struct nouveau_context *nv = driContextPriv->driverPrivate;
|
||||
struct nouveau_channel_context *nvc = nv->nvc;
|
||||
|
||||
assert(nv);
|
||||
|
||||
st_flush(nv->st, PIPE_FLUSH_WAIT);
|
||||
st_destroy_context(nv->st);
|
||||
|
||||
nouveau_channel_context_destroy(nv->nvc);
|
||||
if (nv->pctx_id >= 0) {
|
||||
nvc->pctx[nv->pctx_id] = NULL;
|
||||
if (--nvc->refcount <= 0)
|
||||
nouveau_channel_context_destroy(nvc);
|
||||
}
|
||||
|
||||
free(nv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,13 @@ struct nouveau_framebuffer {
|
|||
};
|
||||
|
||||
struct nouveau_channel_context {
|
||||
struct pipe_screen *pscreen;
|
||||
int refcount;
|
||||
|
||||
unsigned cur_pctx;
|
||||
unsigned nr_pctx;
|
||||
struct pipe_context **pctx;
|
||||
|
||||
unsigned chipset;
|
||||
|
||||
struct nouveau_channel *channel;
|
||||
|
|
@ -51,6 +58,7 @@ struct nouveau_context {
|
|||
|
||||
/* Hardware context */
|
||||
struct nouveau_channel_context *nvc;
|
||||
int pctx_id;
|
||||
|
||||
/* pipe_surface accel */
|
||||
struct pipe_surface *surf_src, *surf_dst;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ struct nouveau_screen {
|
|||
uint32_t front_pitch;
|
||||
uint32_t front_cpp;
|
||||
uint32_t front_height;
|
||||
|
||||
void *nvc;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -70,11 +70,12 @@ nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr,
|
|||
struct pipe_context *
|
||||
nouveau_pipe_create(struct nouveau_context *nv)
|
||||
{
|
||||
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 *,
|
||||
unsigned chipset);
|
||||
struct pipe_context *(*hw_create)(struct pipe_screen *);
|
||||
struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned);
|
||||
struct pipe_winsys *ws;
|
||||
struct pipe_screen *pscreen;
|
||||
|
||||
|
|
@ -125,7 +126,10 @@ nouveau_pipe_create(struct nouveau_context *nv)
|
|||
nvws->surface_fill = nouveau_pipe_surface_fill;
|
||||
|
||||
ws = nouveau_create_pipe_winsys(nv);
|
||||
pscreen = hws_create(ws, nvws, nv->chipset);
|
||||
return hw_create(pscreen);
|
||||
|
||||
if (!nvc->pscreen)
|
||||
nvc->pscreen = hws_create(ws, nvws, nv->chipset);
|
||||
nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id);
|
||||
return nvc->pctx[nv->pctx_id];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue