diff options
Diffstat (limited to 'src/gallium/winsys')
26 files changed, 754 insertions, 309 deletions
diff --git a/src/gallium/winsys/Makefile b/src/gallium/winsys/Makefile new file mode 100644 index 0000000000..3dc5ea5744 --- /dev/null +++ b/src/gallium/winsys/Makefile @@ -0,0 +1,20 @@ +TOP = ../../.. +include $(TOP)/configs/current + + +SUBDIRS = $(GALLIUM_WINSYS_DIRS) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript new file mode 100644 index 0000000000..635a68eea2 --- /dev/null +++ b/src/gallium/winsys/SConscript @@ -0,0 +1,11 @@ +Import('*') + +if dri: + SConscript([ + 'dri/SConscript', + ]) + +if 'xlib' in env['drivers'] and not dri: + SConscript([ + 'xlib/SConscript', + ]) diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 2a261ed669..3bc1fdd4d4 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -1,7 +1,9 @@ # -*-makefile-*- -MESA_MODULES = $(TOP)/src/mesa/libmesa.a - +MESA_MODULES = \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + COMMON_GALLIUM_SOURCES = \ $(TOP)/src/mesa/drivers/dri/common/utils.c \ $(TOP)/src/mesa/drivers/dri/common/vblank.c \ @@ -23,8 +25,9 @@ WINOBJ= WINLIB= INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) -OBJECTS = $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) else # miniglx diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript new file mode 100644 index 0000000000..8c56ce917c --- /dev/null +++ b/src/gallium/winsys/dri/SConscript @@ -0,0 +1,51 @@ +Import('*') + +drienv = env.Clone() + +drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', +]) + +drienv.ParseConfig('pkg-config --cflags --libs libdrm') + +COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', +] + +COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', +] + +Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', +]) + +# TODO: Installation +#install: $(LIBNAME) +# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) +# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + +SConscript([ + 'intel/SConscript', +]) diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index a7cc10450e..0ad19d42a8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -9,11 +9,6 @@ env.Append(CPPPATH = [ #MINIGLX_SOURCES = server/intel_dri.c -pipe_drivers = [ - softpipe, - i915simple -] - DRIVER_SOURCES = [ 'intel_winsys_pipe.c', 'intel_winsys_softpipe.c', @@ -31,11 +26,14 @@ sources = \ COMMON_BM_SOURCES + \ DRIVER_SOURCES -# DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ -# && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +drivers = [ + softpipe, + i915simple +] +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = pipe_drivers + env['LIBS'], + LIBS = drivers + mesa + auxiliaries + env['LIBS'], )
\ No newline at end of file diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 49e04d81ec..5830b88b37 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -26,6 +26,7 @@ **************************************************************************/ #include <errno.h> +#include <stdio.h> #include "intel_batchbuffer.h" #include "intel_context.h" #include "intel_screen.h" diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index 82feafa21f..caf6870a3c 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -28,6 +28,7 @@ #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H +#include "pipe/p_debug.h" #include "pipe/p_compiler.h" #include "dri_bufmgr.h" diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c index 33b56817f6..ce154c7b88 100644 --- a/src/gallium/winsys/dri/intel/intel_batchpool.c +++ b/src/gallium/winsys/dri/intel/intel_batchpool.c @@ -36,9 +36,12 @@ #include <xf86drm.h> #include <stdlib.h> +#include <stdio.h> #include <errno.h> -#include "imports.h" -#include "glthread.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_thread.h" + #include "dri_bufpool.h" #include "dri_bufmgr.h" #include "intel_batchpool.h" @@ -196,7 +199,7 @@ pool_create(struct _DriBufferPool *pool, _glthread_LOCK_MUTEX(p->mutex); if (p->numFree == 0) - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); if (p->numFree == 0) { fprintf(stderr, "Out of fixed size buffer objects\n"); @@ -278,7 +281,7 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, return -EBUSY; } - buf->mapped = GL_TRUE; + buf->mapped = TRUE; *virtual = (unsigned char *) p->virtual + buf->start; _glthread_UNLOCK_MUTEX(p->mutex); return 0; @@ -361,7 +364,7 @@ pool_validate(struct _DriBufferPool *pool, void *private) BBuf *buf = (BBuf *) private; BPool *p = buf->parent; _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = GL_TRUE; + buf->unfenced = TRUE; _glthread_UNLOCK_MUTEX(p->mutex); return 0; } @@ -379,7 +382,7 @@ pool_takedown(struct _DriBufferPool *pool) while ((p->numFree < p->numTot) && p->numDelayed) { _glthread_UNLOCK_MUTEX(p->mutex); sched_yield(); - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); _glthread_LOCK_MUTEX(p->mutex); } diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index c033f2a592..79b320c6bf 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -188,7 +188,8 @@ intelCreateContext(const __GLcontextModes * visual, /* * Pipe-related setup */ - if (!getenv("INTEL_HW")) { + if (getenv("INTEL_SP")) { + /* use softpipe driver instead of hw */ pipe = intel_create_softpipe( intel, intelScreen->winsys ); } else { diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index b01370c049..45430984d8 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -30,6 +30,9 @@ #include "drm.h" + +#include "pipe/p_debug.h" + #include "intel_screen.h" #include "i915_drm.h" diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 0ed3890e93..2def1afc31 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -40,6 +40,7 @@ #include "pipe/p_util.h" #include "i915simple/i915_winsys.h" +#include "i915simple/i915_screen.h" struct intel_i915_winsys { @@ -135,6 +136,7 @@ intel_create_i915simple( struct intel_context *intel, struct pipe_winsys *winsys ) { struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); + struct pipe_screen *screen; /* Fill in this struct with callbacks that i915simple will need to * communicate with the window system, buffer manager, etc. @@ -146,9 +148,11 @@ intel_create_i915simple( struct intel_context *intel, iws->winsys.batch_finish = intel_i915_batch_finish; iws->intel = intel; + screen = i915_create_screen(winsys, intel->intelScreen->deviceID); + /* Create the i915simple context: */ - return i915_create( winsys, - &iws->winsys, - intel->intelScreen->deviceID ); + return i915_create_context( screen, + winsys, + &iws->winsys ); } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c index 9e483bdc9f..0bc2dc4002 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -68,6 +68,7 @@ intel_create_softpipe( struct intel_context *intel, struct pipe_winsys *winsys ) { struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + struct pipe_screen *screen = softpipe_create_screen(winsys); /* Fill in this struct with callbacks that softpipe will need to * communicate with the window system, buffer manager, etc. @@ -77,5 +78,5 @@ intel_create_softpipe( struct intel_context *intel, /* Create the softpipe context: */ - return softpipe_create( winsys, &isws->sws ); + return softpipe_create( screen, winsys, &isws->sws ); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 01fada5b89..dc852c9f49 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -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" @@ -21,6 +22,75 @@ static const struct dri_debug_control debug_control[] = { int __nouveau_debug = 0; #endif +static void +nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) +{ + nouveau_grobj_free(&nvc->NvNull); + nouveau_grobj_free(&nvc->NvCtxSurf2D); + nouveau_grobj_free(&nvc->NvImageBlit); + nouveau_grobj_free(&nvc->NvGdiRect); + nouveau_grobj_free(&nvc->NvM2MF); + nouveau_grobj_free(&nvc->Nv2D); + + nouveau_notifier_free(&nvc->sync_notifier); + + nouveau_channel_free(&nvc->channel); + + FREE(nvc); +} + +static struct nouveau_channel_context * +nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) +{ + struct nouveau_channel_context *nvc; + int ret; + + nvc = CALLOC_STRUCT(nouveau_channel_context); + if (!nvc) + return NULL; + nvc->chipset = chipset; + + if ((ret = nouveau_channel_alloc(nvdev, 0x8003d001, 0x8003d002, + &nvc->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + if ((ret = nouveau_grobj_alloc(nvc->channel, 0x00000000, 0x30, + &nvc->NvNull))) { + NOUVEAU_ERR("Error creating NULL object: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + nvc->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, + &nvc->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + switch (chipset) { + case 0x50: + case 0x80: + ret = nouveau_surface_channel_create_nv50(nvc); + break; + default: + ret = nouveau_surface_channel_create_nv04(nvc); + break; + } + + if (ret) { + NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + return nvc; +} + GLboolean nouveau_context_create(const __GLcontextModes *glVis, __DRIcontextPrivate *driContextPriv, @@ -32,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; @@ -45,13 +116,6 @@ nouveau_context_create(const __GLcontextModes *glVis, return GL_FALSE; } - if ((ret = nouveau_channel_alloc(nv_screen->device, - 0x8003d001, 0x8003d002, - &nv->channel))) { - NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); - return GL_FALSE; - } - driContextPriv->driverPrivate = (void *)nv; nv->nv_screen = nv_screen; nv->dri_screen = driScrnPriv; @@ -101,19 +165,56 @@ nouveau_context_create(const __GLcontextModes *glVis, nv->frontbuffer = fb_surf; } - if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30, - &nv->NvNull))) { - NOUVEAU_ERR("Error creating NULL object: %d\n", ret); - 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; + } } - nv->next_handle = 0x80000000; - if ((ret = nouveau_notifier_alloc(nv->channel, nv->next_handle++, 1, - &nv->sync_notifier))) { - NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); - return GL_FALSE; + /*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 @@ -146,15 +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_grobj_free(&nv->NvCtxSurf2D); - nouveau_grobj_free(&nv->NvImageBlit); - nouveau_channel_free(&nv->channel); + if (nv->pctx_id >= 0) { + nvc->pctx[nv->pctx_id] = NULL; + if (--nvc->refcount <= 0) + nouveau_channel_context_destroy(nvc); + } free(nv); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 5805f969ba..92f551855a 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -13,6 +13,32 @@ struct nouveau_framebuffer { struct st_framebuffer *stfb; }; +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; + + struct nouveau_notifier *sync_notifier; + + struct nouveau_grobj *NvNull; + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvM2MF; + struct nouveau_grobj *Nv2D; + + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; +}; + struct nouveau_context { struct st_context *st; @@ -31,17 +57,8 @@ struct nouveau_context { struct pipe_surface *frontbuffer; /* Hardware context */ - struct nouveau_channel *channel; - struct nouveau_notifier *sync_notifier; - struct nouveau_grobj *NvNull; - struct nouveau_grobj *NvCtxSurf2D; - struct nouveau_grobj *NvImageBlit; - struct nouveau_grobj *NvGdiRect; - struct nouveau_grobj *NvM2MF; - struct nouveau_grobj *Nv2D; - uint32_t next_handle; - uint32_t next_subchannel; - uint32_t next_sequence; + struct nouveau_channel_context *nvc; + int pctx_id; /* pipe_surface accel */ struct pipe_surface *surf_src, *surf_dst; @@ -80,6 +97,10 @@ extern int __nouveau_debug; extern void LOCK_HARDWARE(struct nouveau_context *); extern void UNLOCK_HARDWARE(struct nouveau_context *); +extern int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); +extern int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); extern int nouveau_surface_init_nv04(struct nouveau_context *); extern int nouveau_surface_init_nv50(struct nouveau_context *); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h index 59febca292..f7d91fc748 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -1,8 +1,11 @@ #ifndef __NOUVEAU_LOCAL_H__ #define __NOUVEAU_LOCAL_H__ +#include "pipe/p_compiler.h" #include <stdio.h> +struct pipe_buffer; + /* Debug output */ #define NOUVEAU_MSG(fmt, args...) do { \ fprintf(stdout, "nouveau: "fmt, ##args); \ @@ -24,66 +27,90 @@ #define NOUVEAU_DMA_TIMEOUT 2000 /* Push buffer access macros */ -#define OUT_RING(data) do { \ - (*nv->channel->pushbuf->cur++) = (data); \ -} while(0) - -#define OUT_RINGp(src,size) do { \ - memcpy(nv->channel->pushbuf->cur, (src), (size)<<2); \ - nv->channel->pushbuf->cur += (size); \ -} while(0) - -#define OUT_RINGf(data) do { \ - union { float v; uint32_t u; } c; \ - c.v = (data); \ - OUT_RING(c.u); \ -} while(0) - -#define FIRE_RING() do { \ - nouveau_pushbuf_flush(nv->channel, 0); \ -} while(0) - -#define BEGIN_RING_GR(obj,mthd,size) do { \ - if (nv->channel->pushbuf->remaining < ((size) + 1)) \ - nouveau_pushbuf_flush(nv->channel, ((size) + 1)); \ - OUT_RING(((obj)->subc << 13) | ((size) << 18) | (mthd)); \ - nv->channel->pushbuf->remaining -= ((size) + 1); \ -} while(0) - -#define BEGIN_RING(obj,mthd,size) do { \ - BEGIN_RING_GR(nv->obj, (mthd), (size)); \ -} while(0) - -#define BIND_RING(o,s) do { \ - nv->o->subc = (s); \ - BEGIN_RING(o, 0x0000, 1); \ - OUT_RING (nv->o->handle); \ -} while(0) - -#define OUT_RELOC(buf,data,flags,vor,tor) do { \ - nouveau_pipe_emit_reloc(nv->channel, nv->channel->pushbuf->cur++, \ - buf, (data), (flags), (vor), (tor)); \ -} while(0) +static INLINE void +OUT_RING(struct nouveau_channel *chan, unsigned data) +{ + *(chan->pushbuf->cur++) = (data); +} + +static INLINE void +OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) +{ + memcpy(chan->pushbuf->cur, data, size * 4); + chan->pushbuf->cur += size; +} + +static INLINE void +OUT_RINGf(struct nouveau_channel *chan, float f) +{ + union { uint32_t i; float f; } c; + c.f = f; + OUT_RING(chan, c.i); +} + +static INLINE void +BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, + unsigned mthd, unsigned size) +{ + if (chan->pushbuf->remaining < (size + 1)) + nouveau_pushbuf_flush(chan, (size + 1)); + OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); + chan->pushbuf->remaining -= (size + 1); +} + +static INLINE void +FIRE_RING(struct nouveau_channel *chan) +{ + nouveau_pushbuf_flush(chan, 0); +} + +static INLINE void +BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) +{ + gr->subc = subc; + BEGIN_RING(chan, gr, 0x0000, 1); + OUT_RING (chan, gr->handle); +} + +static INLINE void +OUT_RELOC(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + nouveau_pipe_emit_reloc(chan, chan->pushbuf->cur++, buf, + data, flags, vor, tor); +} /* Raw data + flags depending on FB/TT buffer */ -#define OUT_RELOCd(bo,data,flags,vor,tor) do { \ - OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor)); \ -} while(0) +static INLINE void +OUT_RELOCd(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + OUT_RELOC(chan, buf, data, flags | NOUVEAU_BO_OR, vor, tor); +} /* FB/TT object handle */ -#define OUT_RELOCo(bo,flags) do { \ - OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \ - nv->channel->vram->handle, nv->channel->gart->handle); \ -} while(0) +static INLINE void +OUT_RELOCo(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned flags) +{ + OUT_RELOC(chan, buf, 0, flags | NOUVEAU_BO_OR, + chan->vram->handle, chan->gart->handle); +} /* Low 32-bits of offset */ -#define OUT_RELOCl(bo,delta,flags) do { \ - OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0); \ -} while(0) +static INLINE void +OUT_RELOCl(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_LOW, 0, 0); +} /* High 32-bits of offset */ -#define OUT_RELOCh(bo,delta,flags) do { \ - OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0); \ -} while(0) +static INLINE void +OUT_RELOCh(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_HIGH, 0, 0); +} #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.h b/src/gallium/winsys/dri/nouveau/nouveau_screen.h index 019823bd44..e9da202690 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.h @@ -14,6 +14,8 @@ struct nouveau_screen { uint32_t front_pitch; uint32_t front_cpp; uint32_t front_height; + + void *nvc; }; #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c index 91bf243f42..70e0104e83 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c @@ -42,7 +42,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, nv->surface_copy(nv, dx, dy, sx, sy, w, h); } - FIRE_RING(); + FIRE_RING(nv->nvc->channel); UNLOCK_HARDWARE(nv); if (nv->last_stamp != dPriv->lastStamp) { diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 2ca05d84c6..87619bdcfb 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -11,7 +11,7 @@ nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, { struct nouveau_context *nv = nvws->nv; - return nouveau_notifier_alloc(nv->channel, nv->next_handle++, + return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++, count, notify); } @@ -20,17 +20,16 @@ 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; int ret; - ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, + ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++, grclass, grobj); if (ret) return ret; - (*grobj)->subc = nv->next_subchannel++; - assert((*grobj)->subc <= 7); - BEGIN_RING_GR(*grobj, 0x0000, 1); - OUT_RING ((*grobj)->handle); + assert(nv->nvc->next_subchannel < 7); + BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); return 0; } @@ -71,24 +70,31 @@ 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_context *(*hw_create)(struct pipe_winsys *, + struct pipe_screen *(*hws_create)(struct pipe_winsys *, struct nouveau_winsys *, - unsigned); + unsigned chipset); + struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); + struct pipe_winsys *ws; + struct pipe_screen *pscreen; if (!nvws) return NULL; switch (nv->chipset & 0xf0) { 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: + hws_create = nv50_screen_create; hw_create = nv50_create; break; default: @@ -97,7 +103,7 @@ nouveau_pipe_create(struct nouveau_context *nv) } nvws->nv = nv; - nvws->channel = nv->channel; + nvws->channel = nv->nvc->channel; nvws->res_init = nouveau_resource_init; nvws->res_alloc = nouveau_resource_alloc; @@ -119,6 +125,11 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_copy = nouveau_pipe_surface_copy; nvws->surface_fill = nouveau_pipe_surface_fill; - return hw_create(nouveau_create_pipe_winsys(nv), nvws, nv->chipset); + ws = nouveau_create_pipe_winsys(nv); + + 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]; } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c index 0e1b4273d1..704f6c7750 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c @@ -61,23 +61,25 @@ nouveau_is_format_supported(struct softpipe_winsys *sws, uint format) return FALSE; } - - struct pipe_context * nouveau_create_softpipe(struct nouveau_context *nv) { - struct nouveau_softpipe_winsys *nvsws; - - nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); - - /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. - */ - nvsws->sws.is_format_supported = nouveau_is_format_supported; - nvsws->nv = nv; + struct nouveau_softpipe_winsys *nvsws; + struct pipe_screen *pscreen; + struct pipe_winsys *ws; + + ws = nouveau_create_pipe_winsys(nv); + if (!ws) + return NULL; + pscreen = softpipe_create_screen(ws); + + nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); + if (!nvsws) + return NULL; + + nvsws->sws.is_format_supported = nouveau_is_format_supported; + nvsws->nv = nv; - /* Create the softpipe context: - */ - return softpipe_create(nouveau_create_pipe_winsys(nv), &nvsws->sws); + return softpipe_create(pscreen, ws, &nvsws->sws); } diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index fe1ea4ed70..cdcd71eaad 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -30,6 +30,7 @@ static void nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { + struct nouveau_channel *chan = nv->nvc->channel; struct pipe_surface *dst = nv->surf_dst; struct pipe_surface *src = nv->surf_src; unsigned dst_offset, src_offset; @@ -40,17 +41,18 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, while (h) { int count = (h > 2047) ? 2047 : h; - BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM | + BEGIN_RING(chan, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, src->buffer, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(dst->buffer, dst_offset, NOUVEAU_BO_VRAM | + OUT_RELOCl(chan, dst->buffer, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (src->pitch * src->cpp); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (w * src->cpp); - OUT_RING (count); - OUT_RING (0x0101); - OUT_RING (0); + OUT_RING (chan, src->pitch * src->cpp); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, w * src->cpp); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); h -= count; src_offset += src->pitch * src->cpp * count; @@ -62,16 +64,19 @@ static void nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { - BEGIN_RING(NvImageBlit, 0x0300, 3); - OUT_RING ((sy << 16) | sx); - OUT_RING ((dy << 16) | dx); - OUT_RING (( h << 16) | w); + struct nouveau_channel *chan = nv->nvc->channel; + + BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3); + OUT_RING (chan, (sy << 16) | sx); + OUT_RING (chan, (dy << 16) | dx); + OUT_RING (chan, ( h << 16) | w); } static int nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct pipe_surface *src) { + struct nouveau_channel *chan = nv->nvc->channel; int format; if (src->cpp != dst->cpp) @@ -81,12 +86,12 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, * to NV_MEMORY_TO_MEMORY_FORMAT in this case. */ if ((src->offset & 63) || (dst->offset & 63)) { - BEGIN_RING(NvM2MF, + BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | - NOUVEAU_BO_WR); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_GART | + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_GART | + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); nv->surface_copy = nv04_surface_copy_m2mf; nv->surf_dst = dst; @@ -101,15 +106,20 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, } nv->surface_copy = nv04_surface_copy_blit; - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (format); - OUT_RING (((dst->pitch * dst->cpp) << 16) | (src->pitch * src->cpp)); - OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, format); + OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | + (src->pitch * src->cpp)); + OUT_RELOCl(chan, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); return 0; } @@ -117,7 +127,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, static void nv04_surface_copy_done(struct nouveau_context *nv) { - FIRE_RING(); + FIRE_RING(nv->nvc->channel); } static int @@ -125,6 +135,9 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, unsigned dx, unsigned dy, unsigned w, unsigned h, unsigned value) { + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D; + struct nouveau_grobj *rect = nv->nvc->NvGdiRect; int cs2d_format, gdirect_format; if ((cs2d_format = nv04_surface_format(dst->cpp)) < 0) { @@ -137,86 +150,99 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, return 1; } - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (cs2d_format); - OUT_RING (((dst->pitch * dst->cpp) << 16) | (dst->pitch * dst->cpp)); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); - OUT_RING (gdirect_format); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); - OUT_RING (value); - BEGIN_RING(NvGdiRect, + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, cs2d_format); + OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | + (dst->pitch * dst->cpp)); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (chan, gdirect_format); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (chan, value); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); - OUT_RING ((dx << 16) | dy); - OUT_RING (( w << 16) | h); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); - FIRE_RING(); + FIRE_RING(chan); return 0; } int -nouveau_surface_init_nv04(struct nouveau_context *nv) +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) { + struct nouveau_channel *chan = nvc->channel; unsigned class; int ret; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, 0x39, - &nv->NvM2MF))) { + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, + &nvc->NvM2MF))) { NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); return 1; } - BIND_RING (NvM2MF, nv->next_subchannel++); - BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - - class = nv->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : - NV10_CONTEXT_SURFACES_2D; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, - &nv->NvCtxSurf2D))) { + BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + + class = nvc->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : + NV10_CONTEXT_SURFACES_2D; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvCtxSurf2D))) { NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); return 1; } - BIND_RING (NvCtxSurf2D, nv->next_subchannel++); - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RING (nv->channel->vram->handle); - OUT_RING (nv->channel->vram->handle); - - class = nv->chipset < 0x10 ? NV04_IMAGE_BLIT : - NV12_IMAGE_BLIT; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, - &nv->NvImageBlit))) { + BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RING (chan, nvc->channel->vram->handle); + OUT_RING (chan, nvc->channel->vram->handle); + + class = nvc->chipset < 0x10 ? NV04_IMAGE_BLIT : + NV12_IMAGE_BLIT; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvImageBlit))) { NOUVEAU_ERR("Error creating blit object: %d\n", ret); return 1; } - BIND_RING (NvImageBlit, nv->next_subchannel++); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); - OUT_RING (nv->NvCtxSurf2D->handle); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); - OUT_RING (NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); + OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); class = NV04_GDI_RECTANGLE_TEXT; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, - &nv->NvGdiRect))) { + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvGdiRect))) { NOUVEAU_ERR("Error creating rect object: %d\n", ret); return 1; } - BIND_RING (NvGdiRect, nv->next_subchannel++); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); - OUT_RING (nv->NvCtxSurf2D->handle); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); - OUT_RING (NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); - OUT_RING (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); + BEGIN_RING(chan, nvc->NvGdiRect, + NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + return 0; +} + +int +nouveau_surface_init_nv04(struct nouveau_context *nv) +{ nv->surface_copy_prep = nv04_surface_copy_prep; nv->surface_copy = nv04_surface_copy_blit; nv->surface_copy_done = nv04_surface_copy_done; diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index 15a1002861..5d74fb8d2b 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -19,6 +19,8 @@ static int nv50_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct pipe_surface *src) { + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; int surf_format; assert(src->cpp == dst->cpp); @@ -26,34 +28,38 @@ nv50_surface_copy_prep(struct nouveau_context *nv, surf_format = nv50_format(dst->cpp); assert(surf_format >= 0); - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); - OUT_RING (0); - OUT_RING (0); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - - BEGIN_RING(Nv2D, NV50_2D_SRC_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_SRC_PITCH, 5); - OUT_RING (src->pitch * src->cpp); - OUT_RING (src->pitch); - OUT_RING (src->height); - OUT_RELOCh(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + OUT_RELOCh(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + + BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5); + OUT_RING (chan, src->pitch * src->cpp); + OUT_RING (chan, src->pitch); + OUT_RING (chan, src->height); + OUT_RELOCh(chan, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); return 0; } @@ -62,27 +68,30 @@ static void nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { - BEGIN_RING(Nv2D, 0x0110, 1); - OUT_RING (0); - BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12); - OUT_RING (dx); - OUT_RING (dy); - OUT_RING (w); - OUT_RING (h); - OUT_RING (0); - OUT_RING (1); - OUT_RING (0); - OUT_RING (1); - OUT_RING (0); - OUT_RING (sx); - OUT_RING (0); - OUT_RING (sy); + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + + BEGIN_RING(chan, eng2d, 0x0110, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, w); + OUT_RING (chan, h); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, sx); + OUT_RING (chan, 0); + OUT_RING (chan, sy); } static void nv50_surface_copy_done(struct nouveau_context *nv) { - FIRE_RING(); + FIRE_RING(nv->nvc->channel); } static int @@ -90,6 +99,8 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, unsigned dx, unsigned dy, unsigned w, unsigned h, unsigned value) { + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; int surf_format, rect_format; surf_format = nv50_format(dst->cpp); @@ -100,57 +111,65 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, if (rect_format < 0) return 1; - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY1, 1); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); - OUT_RING (0); - OUT_RING (0); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - - BEGIN_RING(Nv2D, 0x0580, 3); - OUT_RING (4); - OUT_RING (rect_format); - OUT_RING (value); - - BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4); - OUT_RING (dx); - OUT_RING (dy); - OUT_RING (dx + w); - OUT_RING (dy + h); - - FIRE_RING(); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + OUT_RELOCh(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + + BEGIN_RING(chan, eng2d, 0x0580, 3); + OUT_RING (chan, 4); + OUT_RING (chan, rect_format); + OUT_RING (chan, value); + + BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, dx + w); + OUT_RING (chan, dy + h); + + FIRE_RING(chan); return 0; } int -nouveau_surface_init_nv50(struct nouveau_context *nv) +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) { int ret; - ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D, - &nv->Nv2D); + ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D, + &nvc->Nv2D); if (ret) return ret; - BIND_RING (Nv2D, 0); - BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RING (nv->channel->vram->handle); - OUT_RING (nv->channel->vram->handle); - BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1); - OUT_RING (NV50_2D_OPERATION_SRCCOPY); + BIND_RING (nvc->channel, nvc->Nv2D, 0); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_NOTIFY, 1); + OUT_RING (nvc->channel, nvc->sync_notifier->handle); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RING (nvc->channel, nvc->channel->vram->handle); + OUT_RING (nvc->channel, nvc->channel->vram->handle); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_OPERATION, 1); + OUT_RING (nvc->channel, NV50_2D_OPERATION_SRCCOPY); + + return 0; +} +int +nouveau_surface_init_nv50(struct nouveau_context *nv) +{ nv->surface_copy_prep = nv50_surface_copy_prep; nv->surface_copy = nv50_surface_copy; nv->surface_copy_done = nv50_surface_copy_done; diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile new file mode 100644 index 0000000000..c443330942 --- /dev/null +++ b/src/gallium/winsys/xlib/Makefile @@ -0,0 +1,93 @@ +# src/gallium/winsys/xlib/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + + +GL_MAJOR = 1 +GL_MINOR = 5 +GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary + +XLIB_WINSYS_SOURCES = \ + glxapi.c \ + fakeglx.c \ + xfonts.c \ + xm_api.c \ + xm_winsys.c \ + xm_winsys_aub.c \ + brw_aub.c + +XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o) + + +ifeq ($(CONFIG_NAME), linux-cell) +# The SPU code is in a separate .a file, unfortunately +CELL_SPU_LIB = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a +endif + +LIBS = \ + $(GALLIUM_DRIVERS) \ + $(TOP)/src/mesa/libglapi.a \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) \ + $(CELL_SPU_LIB) \ + + +.SUFFIXES : .cpp + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ + + + +default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) + + +# Make the libGL.so library +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(GL_LIB) \ + -linker "$(CC)" \ + -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ + -install $(TOP)/$(LIB_DIR) \ + $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \ + --start-group $(LIBS) --end-group $(GL_LIB_DEPS) + + +depend: $(ALL_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend # workaround oops on gutsy?!? + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + > /dev/null 2>/dev/null + + +install: default + $(INSTALL) -d $(INSTALL_DIR)/include/GL + $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL + @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ + $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ + fi + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h + +clean: + -rm -f *.o + + +include depend diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript new file mode 100644 index 0000000000..c38b5be52c --- /dev/null +++ b/src/gallium/winsys/xlib/SConscript @@ -0,0 +1,34 @@ +####################################################################### +# SConscript for xlib winsys + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', +]) + +sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', +] + +drivers = [ + softpipe, + i915simple, + i965simple, +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], +) diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 541d50c6e4..10eedd8402 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -29,11 +29,13 @@ * Keith Whitwell <keith@tungstengraphics.com> */ +#include <stdio.h> +#include <stdlib.h> #include "brw_aub.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "imports.h" -//#include "intel_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" struct brw_aubfile { @@ -350,9 +352,9 @@ struct brw_aubfile *brw_aubfile_create( void ) i++; - if (_mesa_getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); - _mesa_printf("--> Aub file: %s\n", filename); + if (getenv("INTEL_AUBFILE")) { + val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } else { @@ -360,12 +362,12 @@ struct brw_aubfile *brw_aubfile_create( void ) if (val < 0 || val > sizeof(filename)) strcpy(filename, "default.aub"); - _mesa_printf("--> Aub file: %s\n", filename); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } if (!aubfile->file) { - _mesa_printf("couldn't open aubfile\n"); + debug_printf("couldn't open aubfile\n"); exit(1); } diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 8da596d419..018cf01cd6 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -36,6 +36,8 @@ #include "glxheader.h" #include "xmesaP.h" +#undef ASSERT + #include "pipe/p_winsys.h" #include "pipe/p_format.h" #include "pipe/p_context.h" @@ -45,6 +47,7 @@ #ifdef GALLIUM_CELL #include "cell/ppu/cell_context.h" +#include "cell/ppu/cell_screen.h" #include "cell/ppu/cell_winsys.h" #else #define TILE_SIZE 32 /* avoid compilation errors */ @@ -448,7 +451,8 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) #ifdef GALLIUM_CELL if (!getenv("GALLIUM_NOCELL")) { struct cell_winsys *cws = cell_get_winsys(pixelformat); - pipe = cell_create_context(pws, cws); + struct pipe_screen *screen = cell_create_screen(pws); + pipe = cell_create_context(screen, cws); if (pipe) pipe->priv = xmesa; return pipe; @@ -457,7 +461,8 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) #endif { struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); - pipe = softpipe_create( pws, spws ); + struct pipe_screen *screen = softpipe_create_screen(pws); + pipe = softpipe_create( screen, pws, spws ); if (pipe) pipe->priv = xmesa; diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index dbfd37bda2..d55d8c39eb 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -40,6 +40,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "i965simple/brw_winsys.h" +#include "i965simple/brw_screen.h" #include "brw_aub.h" #include "xm_winsys_aub.h" @@ -565,6 +566,7 @@ struct pipe_context * xmesa_create_i965simple( struct pipe_winsys *winsys ) { struct aub_brw_winsys *iws = CALLOC_STRUCT( aub_brw_winsys ); + struct pipe_screen *screen = brw_create_screen(winsys, 0/* XXX pci_id */); /* Fill in this struct with callbacks that i965simple will need to * communicate with the window system, buffer manager, etc. @@ -583,7 +585,7 @@ xmesa_create_i965simple( struct pipe_winsys *winsys ) /* Create the i965simple context: */ - return brw_create( winsys, + return brw_create( screen, &iws->winsys, 0 ); } |