Merge remote branch 'origin/nv50-compiler'
[mesa.git] / src / gallium / drivers / nv50 / nv50_screen.c
index f37dd079acb0e3cb9336dbad6aa2ad81120236dc..49af9b59beb93a521ce81bf78344adf3e561afaa 100644 (file)
@@ -26,6 +26,7 @@
 #include "nv50_context.h"
 #include "nv50_screen.h"
 #include "nv50_resource.h"
+#include "nv50_program.h"
 
 #include "nouveau/nouveau_stateobj.h"
 
@@ -34,75 +35,38 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
                                enum pipe_format format,
                                enum pipe_texture_target target,
                                unsigned sample_count,
-                               unsigned tex_usage, unsigned geom_flags)
+                               unsigned usage, unsigned geom_flags)
 {
        if (sample_count > 1)
                return FALSE;
 
-       if (tex_usage & PIPE_BIND_RENDER_TARGET) {
+       if (!util_format_s3tc_enabled) {
                switch (format) {
-               case PIPE_FORMAT_B8G8R8X8_UNORM:
-               case PIPE_FORMAT_B8G8R8A8_UNORM:
-               case PIPE_FORMAT_B5G6R5_UNORM:
-               case PIPE_FORMAT_R16G16B16A16_SNORM:
-               case PIPE_FORMAT_R16G16B16A16_UNORM:
-               case PIPE_FORMAT_R32G32B32A32_FLOAT:
-               case PIPE_FORMAT_R16G16_SNORM:
-               case PIPE_FORMAT_R16G16_UNORM:
-                       return TRUE;
-               default:
-                       break;
-               }
-       } else
-       if (tex_usage & PIPE_BIND_DEPTH_STENCIL) {
-               switch (format) {
-               case PIPE_FORMAT_Z32_FLOAT:
-               case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-               case PIPE_FORMAT_Z24X8_UNORM:
-               case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
-                       return TRUE;
-               default:
-                       break;
-               }
-       } else {
-               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;
-                       }
-               }
-               switch (format) {
-               case PIPE_FORMAT_B8G8R8A8_UNORM:
-               case PIPE_FORMAT_B8G8R8X8_UNORM:
-               case PIPE_FORMAT_B8G8R8A8_SRGB:
-               case PIPE_FORMAT_B8G8R8X8_SRGB:
-               case PIPE_FORMAT_B5G5R5A1_UNORM:
-               case PIPE_FORMAT_B4G4R4A4_UNORM:
-               case PIPE_FORMAT_B5G6R5_UNORM:
-               case PIPE_FORMAT_L8_UNORM:
-               case PIPE_FORMAT_A8_UNORM:
-               case PIPE_FORMAT_I8_UNORM:
-               case PIPE_FORMAT_L8A8_UNORM:
-               case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-               case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
-               case PIPE_FORMAT_Z32_FLOAT:
-               case PIPE_FORMAT_R16G16B16A16_SNORM:
-               case PIPE_FORMAT_R16G16B16A16_UNORM:
-               case PIPE_FORMAT_R32G32B32A32_FLOAT:
-               case PIPE_FORMAT_R16G16_SNORM:
-               case PIPE_FORMAT_R16G16_UNORM:
-                       return TRUE;
+               case PIPE_FORMAT_DXT1_RGB:
+               case PIPE_FORMAT_DXT1_RGBA:
+               case PIPE_FORMAT_DXT3_RGBA:
+               case PIPE_FORMAT_DXT5_RGBA:
+                       return FALSE;
                default:
                        break;
                }
        }
 
-       return FALSE;
+       switch (format) {
+       case PIPE_FORMAT_Z16_UNORM:
+               if ((nouveau_screen(pscreen)->device->chipset & 0xf0) != 0xa0)
+                       return FALSE;
+               break;
+       default:
+               break;
+       }
+
+       /* transfers & shared are always supported */
+       usage &= ~(PIPE_BIND_TRANSFER_READ |
+                  PIPE_BIND_TRANSFER_WRITE |
+                  PIPE_BIND_SHARED);
+
+       return (nv50_format_table[format].usage & usage) == usage;
 }
 
 static int
@@ -142,6 +106,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
        case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
                return 1;
+       case PIPE_CAP_TEXTURE_SWIZZLE:
+               return 1;
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
                return 1;
        case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -165,10 +131,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 }
 
 static int
-nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum pipe_shader_cap param)
+nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
+                            enum pipe_shader_cap param)
 {
-       switch(shader)
-       {
+       switch(shader) {
        case PIPE_SHADER_FRAGMENT:
        case PIPE_SHADER_VERTEX:
        case PIPE_SHADER_GEOMETRY:
@@ -186,7 +152,7 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum
        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: /* need stack bo */
                return 4;
        case PIPE_SHADER_CAP_MAX_INPUTS: /* 128 / 4 with GP */
-               if(shader == PIPE_SHADER_GEOMETRY)
+               if (shader == PIPE_SHADER_GEOMETRY)
                        return 128 / 4;
                else
                        return 64 / 4;
@@ -197,7 +163,7 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum
        case PIPE_SHADER_CAP_MAX_PREDS: /* not yet handled */
                return 0;
        case PIPE_SHADER_CAP_MAX_TEMPS: /* no spilling atm */
-               return 128 / 4;
+               return NV50_CAP_MAX_PROGRAM_TEMPS;
        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
                return 1;
        default:
@@ -301,14 +267,23 @@ nv50_screen_relocs(struct nv50_screen *screen)
        }
 }
 
+#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS
+# define NOUVEAU_GETPARAM_GRAPH_UNITS 13
+#endif
+
+extern int nouveau_device_get_param(struct nouveau_device *dev,
+                                    uint64_t param, uint64_t *value);
+
 struct pipe_screen *
 nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 {
        struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
        struct nouveau_channel *chan;
        struct pipe_screen *pscreen;
+       uint64_t value;
        unsigned chipset = dev->chipset;
        unsigned tesla_class = 0;
+       unsigned stack_size, local_size, max_warps;
        int ret, i;
        const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
 
@@ -527,6 +502,41 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
        OUT_RING  (chan, 0x121 | (NV50_CB_PGP << 12));
        OUT_RING  (chan, 0x131 | (NV50_CB_PFP << 12));
 
+       /* shader stack */
+       nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
+
+       max_warps  = util_bitcount(value & 0xffff);
+       max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
+
+       stack_size = max_warps * 64 * 8;
+
+       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
+                            stack_size, &screen->stack_bo);
+       if (ret) {
+               nv50_screen_destroy(pscreen);
+               return NULL;
+       }
+       BEGIN_RING(chan, screen->tesla, NV50TCL_STACK_ADDRESS_HIGH, 3);
+       OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RING  (chan, 4);
+
+       local_size = (NV50_CAP_MAX_PROGRAM_TEMPS * 16) * max_warps * 32;
+
+       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
+                            local_size, &screen->local_bo);
+       if (ret) {
+               nv50_screen_destroy(pscreen);
+               return NULL;
+       }
+
+       local_size = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
+
+       BEGIN_RING(chan, screen->tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 3);
+       OUT_RELOCh(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCl(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RING  (chan, util_unsigned_logbase2(local_size / 8));
+
        /* Vertex array limits - max them out */
        for (i = 0; i < 16; i++) {
                BEGIN_RING(chan, screen->tesla,