summaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_context.c60
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_context.h1
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c5
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c38
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h14
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nv04_surface.c32
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nv50_surface.c2
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);