nouveau: use nv04_surface_copy_swizzle only for POT sizes
[mesa.git] / src / gallium / drivers / nv04 / nv04_screen.c
index 3966a29ffa9d7a14e4b0a046d3ca32001dcfd787..ff2febb668e253662d4d0ee0b653ac3b12ec3017 100644 (file)
@@ -1,25 +1,9 @@
 #include "pipe/p_screen.h"
+#include "pipe/p_inlines.h"
 
 #include "nv04_context.h"
 #include "nv04_screen.h"
 
-static const char *
-nv04_screen_get_name(struct pipe_screen *screen)
-{
-       struct nv04_screen *nv04screen = nv04_screen(screen);
-       struct nouveau_device *dev = nv04screen->nvws->channel->device;
-       static char buffer[128];
-
-       snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
-       return buffer;
-}
-
-static const char *
-nv04_screen_get_vendor(struct pipe_screen *screen)
-{
-       return "nouveau";
-}
-
 static int
 nv04_screen_get_param(struct pipe_screen *screen, int param)
 {
@@ -50,6 +34,19 @@ nv04_screen_get_param(struct pipe_screen *screen, int param)
                return 0;
        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
                return 0;
+       case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+               return 0;
+       case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
+               return 0;
+       case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
+               return 1;
+       case PIPE_CAP_TGSI_CONT_SUPPORTED:
+               return 0;
+       case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+               return 0;
+       case NOUVEAU_CAP_HW_VTXBUF:
+       case NOUVEAU_CAP_HW_IDXBUF:
+               return 0;
        default:
                NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
                return 0;
@@ -86,6 +83,13 @@ nv04_screen_is_format_supported(struct pipe_screen *screen,
                switch (format) {
                case PIPE_FORMAT_A8R8G8B8_UNORM:
                case PIPE_FORMAT_R5G6B5_UNORM: 
+                       return TRUE;
+               default:
+                       break;
+               }
+       } else
+       if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
+               switch (format) {
                case PIPE_FORMAT_Z16_UNORM:
                        return TRUE;
                default:
@@ -108,56 +112,59 @@ nv04_screen_is_format_supported(struct pipe_screen *screen,
        return FALSE;
 }
 
-static void *
-nv04_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
-                unsigned flags )
-{
-       struct pipe_winsys *ws = screen->winsys;
-       void *map;
-
-       map = ws->buffer_map(ws, surface->buffer, flags);
-       if (!map)
-               return NULL;
-
-       return map + surface->offset;
-}
-
-static void
-nv04_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
-{
-       struct pipe_winsys *ws = screen->winsys;
-
-       ws->buffer_unmap(ws, surface->buffer);
-}
-
 static void
 nv04_screen_destroy(struct pipe_screen *pscreen)
 {
        struct nv04_screen *screen = nv04_screen(pscreen);
-       struct nouveau_winsys *nvws = screen->nvws;
 
-       nvws->notifier_free(&screen->sync);
-       nvws->grobj_free(&screen->fahrenheit);
+       nouveau_notifier_free(&screen->sync);
+       nouveau_grobj_free(&screen->fahrenheit);
+       nv04_surface_2d_takedown(&screen->eng2d);
 
        FREE(pscreen);
 }
 
+static struct pipe_buffer *
+nv04_surface_buffer(struct pipe_surface *surf)
+{
+       struct nv04_miptree *mt = (struct nv04_miptree *)surf->texture;
+
+       return mt->buffer;
+}
+
 struct pipe_screen *
-nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
+nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 {
        struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen);
+       struct nouveau_channel *chan;
+       struct pipe_screen *pscreen;
        unsigned fahrenheit_class = 0, sub3d_class = 0;
-       unsigned chipset = nvws->channel->device->chipset;
        int ret;
 
        if (!screen)
                return NULL;
-       screen->nvws = nvws;
+       pscreen = &screen->base.base;
+
+       ret = nouveau_screen_init(&screen->base, dev);
+       if (ret) {
+               nv04_screen_destroy(pscreen);
+               return NULL;
+       }
+       chan = screen->base.channel;
 
-       if (chipset>=0x20) {
+       pscreen->winsys = ws;
+       pscreen->destroy = nv04_screen_destroy;
+       pscreen->get_param = nv04_screen_get_param;
+       pscreen->get_paramf = nv04_screen_get_paramf;
+       pscreen->is_format_supported = nv04_screen_is_format_supported;
+
+       nv04_screen_init_miptree_functions(pscreen);
+       nv04_screen_init_transfer_functions(pscreen);
+
+       if (dev->chipset >= 0x20) {
                fahrenheit_class = 0;
                sub3d_class = 0;
-       } else if (chipset>=0x10) {
+       } else if (dev->chipset >= 0x10) {
                fahrenheit_class = NV10_DX5_TEXTURED_TRIANGLE;
                sub3d_class = NV10_CONTEXT_SURFACES_3D;
        } else {
@@ -166,47 +173,40 @@ nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
        }
 
        if (!fahrenheit_class) {
-               NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", chipset);
+               NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", dev->chipset);
                return NULL;
        }
 
        /* 3D object */
-       ret = nvws->grobj_alloc(nvws, fahrenheit_class, &screen->fahrenheit);
+       ret = nouveau_grobj_alloc(chan, 0xbeef0001, fahrenheit_class,
+                                 &screen->fahrenheit);
        if (ret) {
                NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
                return NULL;
        }
+       BIND_RING(chan, screen->fahrenheit, 7);
 
        /* 3D surface object */
-       ret = nvws->grobj_alloc(nvws, sub3d_class, &screen->context_surfaces_3d);
+       ret = nouveau_grobj_alloc(chan, 0xbeef0002, sub3d_class,
+                                 &screen->context_surfaces_3d);
        if (ret) {
                NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret);
                return NULL;
        }
+       BIND_RING(chan, screen->context_surfaces_3d, 6);
+
+       /* 2D engine setup */
+       screen->eng2d = nv04_surface_2d_init(&screen->base);
+       screen->eng2d->buf = nv04_surface_buffer;
 
        /* Notifier for sync purposes */
-       ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
+       ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
        if (ret) {
                NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
-               nv04_screen_destroy(&screen->pipe);
+               nv04_screen_destroy(pscreen);
                return NULL;
        }
 
-       screen->pipe.winsys = ws;
-       screen->pipe.destroy = nv04_screen_destroy;
-
-       screen->pipe.get_name = nv04_screen_get_name;
-       screen->pipe.get_vendor = nv04_screen_get_vendor;
-       screen->pipe.get_param = nv04_screen_get_param;
-       screen->pipe.get_paramf = nv04_screen_get_paramf;
-
-       screen->pipe.is_format_supported = nv04_screen_is_format_supported;
-
-       screen->pipe.surface_map = nv04_surface_map;
-       screen->pipe.surface_unmap = nv04_surface_unmap;
-
-       nv04_screen_init_miptree_functions(&screen->pipe);
-
-       return &screen->pipe;
+       return pscreen;
 }