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,
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;
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;
- }
- 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);
+ nv->nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset);
+ if (!nv->nvc) {
+ NOUVEAU_ERR("Failed initialising GPU channel context\n");
return GL_FALSE;
}
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);
+ nouveau_channel_context_destroy(nv->nvc);
free(nv);
}
struct st_framebuffer *stfb;
};
+struct nouveau_channel_context {
+ 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;
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;
/* pipe_surface accel */
struct pipe_surface *surf_src, *surf_dst;
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 *);
#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); \
#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
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) {
{
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);
}
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;
}
}
nvws->nv = nv;
- nvws->channel = nv->channel;
+ nvws->channel = nv->nvc->channel;
nvws->res_init = nouveau_resource_init;
nvws->res_alloc = nouveau_resource_alloc;
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;
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;
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)
* 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;
}
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;
}
static void
nv04_surface_copy_done(struct nouveau_context *nv)
{
- FIRE_RING();
+ FIRE_RING(nv->nvc->channel);
}
static int
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) {
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;
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);
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;
}
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
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);
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;