nouveau: only advertise PIPE_FORMAT_DXT* if s3tc available
[mesa.git] / src / gallium / drivers / nvfx / nvfx_screen.c
index 0950dc87b410bfbc5e023512b957c8a9d25db502..c70f254f8c845123975db0c4918b354302341614 100644 (file)
@@ -1,5 +1,6 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_state.h"
+#include "util/u_format_s3tc.h"
 #include "util/u_simple_screen.h"
 
 #include "nouveau/nouveau_screen.h"
@@ -69,9 +70,6 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, int param)
                return 0;
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
                return !!screen->is_nv4x;
-       case NOUVEAU_CAP_HW_VTXBUF:
-       case NOUVEAU_CAP_HW_IDXBUF:
-               return !screen->force_swtnl;
        case PIPE_CAP_MAX_COMBINED_SAMPLERS:
                return 16;
        case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -148,6 +146,17 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen,
                }
        } else {
                switch (format) {
+               if (tex_usage & PIPE_BIND_SAMPLER_VIEW) {
+                       switch (format) {
+                       case PIPE_FORMAT_DXT1_RGB:
+                       case PIPE_FORMAT_DXT1_RGBA:
+                       case PIPE_FORMAT_DXT3_RGBA:
+                       case PIPE_FORMAT_DXT5_RGBA:
+                               return util_format_s3tc_enabled;
+                       default:
+                               break;
+                       }
+               }
                case PIPE_FORMAT_B8G8R8A8_UNORM:
                case PIPE_FORMAT_B8G8R8X8_UNORM:
                case PIPE_FORMAT_B5G5R5A1_UNORM:
@@ -159,10 +168,6 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen,
                case PIPE_FORMAT_L8A8_UNORM:
                case PIPE_FORMAT_Z16_UNORM:
                case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-               case PIPE_FORMAT_DXT1_RGB:
-               case PIPE_FORMAT_DXT1_RGBA:
-               case PIPE_FORMAT_DXT3_RGBA:
-               case PIPE_FORMAT_DXT5_RGBA:
                        return TRUE;
                /* TODO: does nv30 support this? */
                case PIPE_FORMAT_R16_SNORM:
@@ -286,8 +291,8 @@ static void nv40_screen_init(struct nvfx_screen *screen)
        OUT_RING(chan, 0x00000001);
 }
 
-static void
-nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
+static unsigned
+nvfx_screen_get_vertex_buffer_flags(struct nvfx_screen* screen)
 {
        int vram_hack_default = 0;
        int vram_hack;
@@ -313,17 +318,18 @@ nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
        }
 #endif
 
-       screen->vertex_buffer_flags = vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
+       return vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
 }
 
 struct pipe_screen *
 nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 {
+       static const unsigned query_sizes[] = {(4096 - 4 * 32) / 32, 3 * 1024 / 32, 2 * 1024 / 32, 1024 / 32};
        struct nvfx_screen *screen = CALLOC_STRUCT(nvfx_screen);
        struct nouveau_channel *chan;
        struct pipe_screen *pscreen;
        unsigned eng3d_class = 0;
-       int ret;
+       int ret, i;
 
        if (!screen)
                return NULL;
@@ -374,8 +380,16 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
        screen->force_swtnl = debug_get_bool_option("NOUVEAU_SWTNL", FALSE);
 
+       screen->vertex_buffer_reloc_flags = nvfx_screen_get_vertex_buffer_flags(screen);
+
+       /* surely both nv3x and nv44 support index buffers too: find out how and test that */
+       if(eng3d_class == NV40TCL)
+               screen->index_buffer_reloc_flags = screen->vertex_buffer_reloc_flags;
+
+       if(!screen->force_swtnl && screen->vertex_buffer_reloc_flags == screen->index_buffer_reloc_flags)
+               screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = screen->vertex_buffer_reloc_flags;
+
        nvfx_screen_init_resource_functions(pscreen);
-       nvfx_screen_init_buffer_functions(screen);
 
        ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
        if (ret) {
@@ -396,20 +410,28 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
        }
 
        /* Query objects */
-       ret = nouveau_notifier_alloc(chan, 0xbeef0302, 32, &screen->query);
+       for(i = 0; i < sizeof(query_sizes) / sizeof(query_sizes[0]); ++i)
+       {
+               ret = nouveau_notifier_alloc(chan, 0xbeef0302, query_sizes[i], &screen->query);
+               if(!ret)
+                       break;
+       }
+
        if (ret) {
                NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
                nvfx_screen_destroy(pscreen);
                return NULL;
        }
 
-       ret = nouveau_resource_init(&screen->query_heap, 0, 32);
+       ret = nouveau_resource_init(&screen->query_heap, 0, query_sizes[i]);
        if (ret) {
                NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
                nvfx_screen_destroy(pscreen);
                return NULL;
        }
 
+       LIST_INITHEAD(&screen->query_list);
+
        /* Vtxprog resources */
        if (nouveau_resource_init(&screen->vp_exec_heap, 0, screen->is_nv4x ? 512 : 256) ||
            nouveau_resource_init(&screen->vp_data_heap, 0, 256)) {