gallium: add caps for POSITION and FACE system values
[mesa.git] / src / gallium / drivers / nouveau / nvc0 / nvc0_surface.c
index 136a68cfcef1932b82d3b6d61fbe15c4b87a27b6..4e43c4e99fd042b4f8311913e37f9e29f2a86a9b 100644 (file)
@@ -67,7 +67,7 @@ nvc0_2d_format(enum pipe_format format, bool dst, bool dst_src_equal)
    case 1:
       return NV50_SURFACE_FORMAT_R8_UNORM;
    case 2:
-      return NV50_SURFACE_FORMAT_R16_UNORM;
+      return NV50_SURFACE_FORMAT_RG8_UNORM;
    case 4:
       return NV50_SURFACE_FORMAT_BGRA8_UNORM;
    case 8:
@@ -225,10 +225,14 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
    nv04_resource(dst)->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
 
    if (m2mf) {
+      struct nv50_miptree *src_mt = nv50_miptree(src);
+      struct nv50_miptree *dst_mt = nv50_miptree(dst);
       struct nv50_m2mf_rect drect, srect;
       unsigned i;
-      unsigned nx = util_format_get_nblocksx(src->format, src_box->width);
-      unsigned ny = util_format_get_nblocksy(src->format, src_box->height);
+      unsigned nx = util_format_get_nblocksx(src->format, src_box->width)
+         << src_mt->ms_x;
+      unsigned ny = util_format_get_nblocksy(src->format, src_box->height)
+         << src_mt->ms_y;
 
       nv50_m2mf_rect_setup(&drect, dst, dst_level, dstx, dsty, dstz);
       nv50_m2mf_rect_setup(&srect, src, src_level,
@@ -237,15 +241,15 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
       for (i = 0; i < src_box->depth; ++i) {
          nvc0->m2mf_copy_rect(nvc0, &drect, &srect, nx, ny);
 
-         if (nv50_miptree(dst)->layout_3d)
+         if (dst_mt->layout_3d)
             drect.z++;
          else
-            drect.base += nv50_miptree(dst)->layer_stride;
+            drect.base += dst_mt->layer_stride;
 
-         if (nv50_miptree(src)->layout_3d)
+         if (src_mt->layout_3d)
             srect.z++;
          else
-            srect.base += nv50_miptree(src)->layer_stride;
+            srect.base += src_mt->layer_stride;
       }
       return;
    }
@@ -284,6 +288,8 @@ nvc0_clear_render_target(struct pipe_context *pipe,
    struct nv04_resource *res = nv04_resource(sf->base.texture);
    unsigned z;
 
+   assert(dst->texture->target != PIPE_BUFFER);
+
    if (!PUSH_SPACE(push, 32 + sf->depth))
       return;
 
@@ -315,6 +321,7 @@ nvc0_clear_render_target(struct pipe_context *pipe,
       PUSH_DATA(push, dst->u.tex.first_layer + sf->depth);
       PUSH_DATA(push, mt->layer_stride >> 2);
       PUSH_DATA(push, dst->u.tex.first_layer);
+      IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), mt->ms_mode);
    } else {
       if (res->base.target == PIPE_BUFFER) {
          PUSH_DATA(push, 262144);
@@ -330,17 +337,22 @@ nvc0_clear_render_target(struct pipe_context *pipe,
       PUSH_DATA(push, 0);
 
       IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0);
+      IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0);
 
       /* tiled textures don't have to be fenced, they're not mapped directly */
       nvc0_resource_fence(res, NOUVEAU_BO_WR);
    }
 
+   IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
+
    BEGIN_NIC0(push, NVC0_3D(CLEAR_BUFFERS), sf->depth);
    for (z = 0; z < sf->depth; ++z) {
       PUSH_DATA (push, 0x3c |
                  (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
    }
 
+   IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
+
    nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
 }
 
@@ -462,6 +474,9 @@ nvc0_clear_buffer(struct pipe_context *pipe,
    PUSH_DATA (push, 0);
 
    IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0);
+
+   IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
 
    IMMED_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 0x3c);
 
@@ -479,6 +494,8 @@ nvc0_clear_buffer(struct pipe_context *pipe,
       IMMED_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 0x3c);
    }
 
+   IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
+
    nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence);
    nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence_wr);
    nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
@@ -493,57 +510,64 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
                          unsigned dstx, unsigned dsty,
                          unsigned width, unsigned height)
 {
-       struct nvc0_context *nvc0 = nvc0_context(pipe);
-       struct nouveau_pushbuf *push = nvc0->base.pushbuf;
-       struct nv50_miptree *mt = nv50_miptree(dst->texture);
-       struct nv50_surface *sf = nv50_surface(dst);
-       uint32_t mode = 0;
-       int unk = mt->base.base.target == PIPE_TEXTURE_2D;
-       unsigned z;
-
-       if (!PUSH_SPACE(push, 32 + sf->depth))
-               return;
-
-       PUSH_REFN (push, mt->base.bo, mt->base.domain | NOUVEAU_BO_WR);
-
-       if (clear_flags & PIPE_CLEAR_DEPTH) {
-               BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
-               PUSH_DATAf(push, depth);
-               mode |= NVC0_3D_CLEAR_BUFFERS_Z;
-       }
-
-       if (clear_flags & PIPE_CLEAR_STENCIL) {
-               BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
-               PUSH_DATA (push, stencil & 0xff);
-               mode |= NVC0_3D_CLEAR_BUFFERS_S;
-       }
-
-       BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
-       PUSH_DATA (push, ( width << 16) | dstx);
-       PUSH_DATA (push, (height << 16) | dsty);
-
-       BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
-       PUSH_DATAh(push, mt->base.address + sf->offset);
-       PUSH_DATA (push, mt->base.address + sf->offset);
-       PUSH_DATA (push, nvc0_format_table[dst->format].rt);
-       PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
-       PUSH_DATA (push, mt->layer_stride >> 2);
-       BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
-       PUSH_DATA (push, 1);
-       BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
-       PUSH_DATA (push, sf->width);
-       PUSH_DATA (push, sf->height);
-       PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
-       BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
-       PUSH_DATA (push, dst->u.tex.first_layer);
-
-       BEGIN_NIC0(push, NVC0_3D(CLEAR_BUFFERS), sf->depth);
-       for (z = 0; z < sf->depth; ++z) {
-               PUSH_DATA (push, mode |
-                          (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
-       }
-
-       nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
+   struct nvc0_context *nvc0 = nvc0_context(pipe);
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+   struct nv50_miptree *mt = nv50_miptree(dst->texture);
+   struct nv50_surface *sf = nv50_surface(dst);
+   uint32_t mode = 0;
+   int unk = mt->base.base.target == PIPE_TEXTURE_2D;
+   unsigned z;
+
+   assert(dst->texture->target != PIPE_BUFFER);
+
+   if (!PUSH_SPACE(push, 32 + sf->depth))
+      return;
+
+   PUSH_REFN (push, mt->base.bo, mt->base.domain | NOUVEAU_BO_WR);
+
+   if (clear_flags & PIPE_CLEAR_DEPTH) {
+      BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
+      PUSH_DATAf(push, depth);
+      mode |= NVC0_3D_CLEAR_BUFFERS_Z;
+   }
+
+   if (clear_flags & PIPE_CLEAR_STENCIL) {
+      BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
+      PUSH_DATA (push, stencil & 0xff);
+      mode |= NVC0_3D_CLEAR_BUFFERS_S;
+   }
+
+   BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
+   PUSH_DATA (push, ( width << 16) | dstx);
+   PUSH_DATA (push, (height << 16) | dsty);
+
+   BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
+   PUSH_DATAh(push, mt->base.address + sf->offset);
+   PUSH_DATA (push, mt->base.address + sf->offset);
+   PUSH_DATA (push, nvc0_format_table[dst->format].rt);
+   PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+   PUSH_DATA (push, mt->layer_stride >> 2);
+   BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
+   PUSH_DATA (push, sf->width);
+   PUSH_DATA (push, sf->height);
+   PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
+   BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
+   PUSH_DATA (push, dst->u.tex.first_layer);
+   IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), mt->ms_mode);
+
+   IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
+
+   BEGIN_NIC0(push, NVC0_3D(CLEAR_BUFFERS), sf->depth);
+   for (z = 0; z < sf->depth; ++z) {
+      PUSH_DATA (push, mode |
+                 (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
+   }
+
+   IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
+
+   nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
 }
 
 void
@@ -887,6 +911,7 @@ nvc0_blitctx_prepare_state(struct nvc0_blitctx *blit)
 
    /* zsa state */
    IMMED_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(DEPTH_BOUNDS_EN), 0);
    IMMED_NVC0(push, NVC0_3D(STENCIL_ENABLE), 0);
    IMMED_NVC0(push, NVC0_3D(ALPHA_TEST_ENABLE), 0);
 
@@ -1005,9 +1030,11 @@ nvc0_blitctx_post_blit(struct nvc0_blitctx *blit)
       nvc0->base.pipe.render_condition(&nvc0->base.pipe, nvc0->cond_query,
                                        nvc0->cond_cond, nvc0->cond_mode);
 
+   nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX_TMP);
    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(4, 0));
    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(4, 1));
+   nouveau_scratch_done(&nvc0->base);
 
    nvc0->dirty = blit->saved.dirty |
       (NVC0_NEW_FRAMEBUFFER | NVC0_NEW_SCISSOR | NVC0_NEW_SAMPLE_MASK |
@@ -1536,5 +1563,6 @@ nvc0_init_surface_functions(struct nvc0_context *nvc0)
    pipe->flush_resource = nvc0_flush_resource;
    pipe->clear_render_target = nvc0_clear_render_target;
    pipe->clear_depth_stencil = nvc0_clear_depth_stencil;
+   pipe->clear_texture = nv50_clear_texture;
    pipe->clear_buffer = nvc0_clear_buffer;
 }