gallium: remove PIPE_SHADER_CAP_OUTPUT_READ
[mesa.git] / src / gallium / drivers / nvc0 / nvc0_screen.c
index a8bd09234c2c8d6b32b7d8780da70fa6ceb50b39..f7637eedc43dbab7bea78d152d61573229e8191d 100644 (file)
@@ -68,21 +68,20 @@ static int
 nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 {
    switch (param) {
-   case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
-   case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-      return 32;
    case PIPE_CAP_MAX_COMBINED_SAMPLERS:
-      return 64;
+      return 16 * PIPE_SHADER_TYPES; /* NOTE: should not count COMPUTE */
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
-      return 13;
-   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
-      return 10;
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
-      return 13;
+      return 15;
+   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+      return 12;
    case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
-      return 8192;
+      return 2048;
+   case PIPE_CAP_MIN_TEXEL_OFFSET:
+      return -8;
+   case PIPE_CAP_MAX_TEXEL_OFFSET:
+      return 7;
    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-   case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
    case PIPE_CAP_TEXTURE_SWIZZLE:
    case PIPE_CAP_TEXTURE_SHADOW_MAP:
    case PIPE_CAP_NPOT_TEXTURES:
@@ -92,22 +91,29 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
       return 0;
    case PIPE_CAP_TWO_SIDED_STENCIL:
-   case PIPE_CAP_DEPTH_CLAMP:
+   case PIPE_CAP_DEPTH_CLIP_DISABLE:
    case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
    case PIPE_CAP_POINT_SPRITE:
       return 1;
-   case PIPE_CAP_GLSL:
    case PIPE_CAP_SM3:
       return 1;
+   case PIPE_CAP_GLSL_FEATURE_LEVEL:
+      return 150;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       return 8;
-   case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL:
+   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
+   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
+   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
       return 1;
    case PIPE_CAP_TIMER_QUERY:
    case PIPE_CAP_OCCLUSION_QUERY:
+   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
       return 1;
-   case PIPE_CAP_STREAM_OUTPUT:
-      return 0;
+   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+      return 4;
+   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+      return 128;
    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
    case PIPE_CAP_INDEP_BLEND_ENABLE:
    case PIPE_CAP_INDEP_BLEND_FUNC:
@@ -124,7 +130,13 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_INSTANCEID:
    case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
    case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+   case PIPE_CAP_CONDITIONAL_RENDER:
+   case PIPE_CAP_TEXTURE_BARRIER:
+   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
       return 1;
+   case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
+   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
+      return 0; /* state trackers will know better */
    default:
       NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
       return 0;
@@ -155,11 +167,13 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
    case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
       return 16384;
    case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
-      return 4;
+      return 16;
    case PIPE_SHADER_CAP_MAX_INPUTS:
       if (shader == PIPE_SHADER_VERTEX)
          return 32;
-      return 0x300 / 16;
+      if (shader == PIPE_SHADER_FRAGMENT)
+         return (0x200 + 0x20 + 0x80) / 16; /* generic + colors + TexCoords */
+      return (0x200 + 0x40 + 0x80) / 16; /* without 0x60 for per-patch inputs */
    case PIPE_SHADER_CAP_MAX_CONSTS:
       return 65536 / 16;
    case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
@@ -179,9 +193,15 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
    case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
       return 1;
    case PIPE_SHADER_CAP_SUBROUTINES:
-      return 0; /* please inline, or provide function declarations */
+      return 1; /* but inlining everything, we need function declarations */
    case PIPE_SHADER_CAP_INTEGERS:
-      return 0;
+      return 1;
+   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
+      return 16; /* would be 32 in linked (OpenGL-style) mode */
+      /*
+   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLER_VIEWS:
+      return 32;
+      */
    default:
       NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
       return 0;
@@ -189,19 +209,20 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
 }
 
 static float
-nvc0_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param)
+nvc0_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
 {
    switch (param) {
-   case PIPE_CAP_MAX_LINE_WIDTH:
-   case PIPE_CAP_MAX_LINE_WIDTH_AA:
+   case PIPE_CAPF_MAX_LINE_WIDTH:
+   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
       return 10.0f;
-   case PIPE_CAP_MAX_POINT_WIDTH:
-   case PIPE_CAP_MAX_POINT_WIDTH_AA:
-      return 64.0f;
-   case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+   case PIPE_CAPF_MAX_POINT_WIDTH:
+      return 63.0f;
+   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
+      return 63.375f;
+   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
       return 16.0f;
-   case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
-      return 4.0f;
+   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
+      return 15.0f;
    default:
       NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
       return 0.0f;
@@ -217,7 +238,11 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
       nouveau_fence_wait(screen->base.fence.current);
       nouveau_fence_ref(NULL, &screen->base.fence.current);
    }
-   screen->base.channel->user_private = NULL;
+   if (screen->base.channel)
+      screen->base.channel->user_private = NULL;
+
+   if (screen->blitctx)
+      FREE(screen->blitctx);
 
    nouveau_bo_ref(NULL, &screen->text);
    nouveau_bo_ref(NULL, &screen->tls);
@@ -225,6 +250,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
    nouveau_bo_ref(NULL, &screen->fence.bo);
    nouveau_bo_ref(NULL, &screen->vfetch_cache);
 
+   nouveau_resource_destroy(&screen->lib_code);
    nouveau_resource_destroy(&screen->text_heap);
 
    if (screen->tic.entries)
@@ -326,16 +352,20 @@ nvc0_magic_3d_init(struct nouveau_channel *chan)
 }
 
 static void
-nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 sequence)
+nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
 {
    struct nvc0_screen *screen = nvc0_screen(pscreen);
    struct nouveau_channel *chan = screen->base.channel;
 
    MARK_RING (chan, 5, 2);
+
+   /* we need to do it after possible flush in MARK_RING */
+   *sequence = ++screen->base.fence.sequence;
+
    BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
    OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
    OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
-   OUT_RING  (chan, sequence);
+   OUT_RING  (chan, *sequence);
    OUT_RING  (chan, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
               (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT));
 }
@@ -355,7 +385,7 @@ nvc0_screen_fence_update(struct pipe_screen *pscreen)
    } while(0)
 
 struct pipe_screen *
-nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
+nvc0_screen_create(struct nouveau_device *dev)
 {
    struct nvc0_screen *screen;
    struct nouveau_channel *chan;
@@ -378,7 +408,6 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
    chan = screen->base.channel;
    chan->user_private = screen;
 
-   pscreen->winsys = ws;
    pscreen->destroy = nvc0_screen_destroy;
    pscreen->context_create = nvc0_create;
    pscreen->is_format_supported = nvc0_screen_is_format_supported;
@@ -446,6 +475,12 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
    BEGIN_RING(chan, RING_3D(COND_MODE), 1);
    OUT_RING  (chan, NVC0_3D_COND_MODE_ALWAYS);
 
+   if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) {
+      /* kill shaders after about 1 second (at 100 MHz) */
+      BEGIN_RING(chan, RING_3D(WATCHDOG_TIMER), 1);
+      OUT_RING  (chan, 0x17);
+   }
+
    BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
    OUT_RING  (chan, 1);
 
@@ -628,6 +663,9 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
    screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
 
+   if (!nvc0_blitctx_create(screen))
+      goto fail;
+
    nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
 
    return pscreen;
@@ -644,7 +682,7 @@ nvc0_screen_make_buffers_resident(struct nvc0_screen *screen)
 
    const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
 
-   MARK_RING(chan, 5, 5);
+   MARK_RING(chan, 0, 5);
    nouveau_bo_validate(chan, screen->text, flags);
    nouveau_bo_validate(chan, screen->uniforms, flags);
    nouveau_bo_validate(chan, screen->txc, flags);