diff options
Diffstat (limited to 'src/gallium/winsys/drm/nouveau')
7 files changed, 98 insertions, 54 deletions
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c index de4a90e25f7..70f005b8880 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c @@ -113,35 +113,6 @@ nouveau_context_init(struct nouveau_screen *nv_screen, nvdev->lock = sarea_lock; } - /*XXX: Hack up a fake region and buffer object for front buffer. - * This will go away with TTM, replaced with a simple reference - * of the front buffer handle passed to us by the DDX. - */ - { - struct pipe_surface *fb_surf; - struct nouveau_pipe_buffer *fb_buf; - - fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); - - nouveau_bo_fake(dev, nv_screen->front_offset, NOUVEAU_BO_VRAM, - nv_screen->front_pitch*nv_screen->front_height, - NULL, &fb_buf->bo); - - fb_surf = calloc(1, sizeof(struct pipe_surface)); - if (nv_screen->front_cpp == 2) - fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; - else - fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; - pf_get_block(fb_surf->format, &fb_surf->block); - fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; - fb_surf->height = nv_screen->front_height; - fb_surf->stride = fb_surf->width * fb_surf->block.size; - fb_surf->refcount = 1; - fb_surf->buffer = &fb_buf->base; - - nv->frontbuffer = fb_surf; - } - /* Attempt to share a single channel between multiple contexts from * a single process. */ @@ -229,8 +200,37 @@ nouveau_context_init(struct nouveau_screen *nv_screen, } } - pipe->priv = nv; + { + 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)); + fb_buf->base.refcount = 1; + fb_buf->base.usage = PIPE_BUFFER_USAGE_PIXEL; + + nouveau_bo_fake(dev, nv_screen->front_offset, NOUVEAU_BO_VRAM, + nv_screen->front_pitch*nv_screen->front_height, + NULL, &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; } diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h index d7199db3de6..6f6bdafe6bb 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h @@ -43,6 +43,7 @@ struct nouveau_context { int locked; struct nouveau_screen *nv_screen; struct pipe_surface *frontbuffer; + struct pipe_texture *frontbuffer_texture; struct { int hw_vertex_buffer; diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c index 3b2b86cd407..527c09cf6bb 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c @@ -65,8 +65,9 @@ nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr, struct pipe_buffer *buf, uint32_t data, uint32_t flags, uint32_t vor, uint32_t tor) { - return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, - nouveau_buffer(buf)->bo, + struct nouveau_bo *bo = ((struct nouveau_pipe_buffer *)buf)->bo; + + return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, bo, data, flags, vor, tor); } diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index 6f79e0800a4..c17d8a05e60 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -103,7 +103,7 @@ nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) static void nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf) { - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + struct nouveau_pipe_buffer *nvbuf = (void *)buf; nouveau_bo_ref(NULL, &nvbuf->bo); FREE(nvbuf); @@ -113,7 +113,7 @@ static void * nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags) { - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + struct nouveau_pipe_buffer *nvbuf = (void *)buf; uint32_t map_flags = 0; if (flags & PIPE_BUFFER_USAGE_CPU_READ) @@ -146,7 +146,7 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, static void nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) { - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + struct nouveau_pipe_buffer *nvbuf = (void *)buf; nouveau_bo_unmap(nvbuf->bo); } @@ -173,6 +173,38 @@ 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) { diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h index d97ffdf3373..b041a77e38b 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h @@ -10,10 +10,15 @@ struct nouveau_pipe_buffer { struct nouveau_bo *bo; }; +/* This is so horrible I should be shot - I promise I'll fix it properly + * tomorrow. Just to make the winsys build again however... The TG guys + * don't like to make life easy :) + */ static inline struct nouveau_pipe_buffer * -nouveau_buffer(struct pipe_buffer *buf) +nouveau_buffer(struct pipe_surface *ps) { - return (struct nouveau_pipe_buffer *)buf; + return *(struct nouveau_pipe_buffer **) + ((void *)ps->texture + sizeof(struct pipe_texture)); } struct nouveau_pipe_winsys { @@ -36,4 +41,9 @@ 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 diff --git a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c index b83f3475dfd..214c8437826 100644 --- a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c @@ -132,7 +132,7 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, assert(!(w & (w - 1)) && !(h & (h - 1))); BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); OUT_RING (chan, nv04_surface_format(dst->format) | @@ -140,7 +140,7 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(src)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); OUT_RING (chan, nv->nvc->NvSwzSurf->handle); @@ -148,7 +148,7 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, for (cy = 0; cy < h; cy += sub_h) { for (cx = 0; cx < w; cx += sub_w) { BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset + nv04_swizzle_bits(cx, cy) * dst->block.size, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -168,7 +168,7 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, OUT_RING (chan, src->stride | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, + OUT_RELOCl(chan, nouveau_buffer(src)->bo, src->offset + cy * src->stride + cx * src->block.size, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RING (chan, 0); @@ -193,9 +193,9 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, BEGIN_RING(chan, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src_offset, + OUT_RELOCl(chan, nouveau_buffer(src)->bo, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); OUT_RING (chan, src->stride); OUT_RING (chan, dst->stride); @@ -253,9 +253,9 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, if ((src->offset & 63) || (dst->offset & 63)) { BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(src)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); nv->surface_copy = nv04_surface_copy_m2mf; @@ -273,18 +273,18 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(src)->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, 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->stride << 16) | src->stride); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, + OUT_RELOCl(chan, nouveau_buffer(src)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); return 0; @@ -317,16 +317,16 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, } BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, 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->stride << 16) | dst->stride); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); diff --git a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c index d16f3a97d5d..540240cd23f 100644 --- a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c +++ b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c @@ -26,7 +26,7 @@ nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) { struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; + struct nouveau_bo *bo = nouveau_buffer(surf)->bo; int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); |