util: Make helper functions for pack/unpacking pixel rows.
[mesa.git] / src / gallium / drivers / nouveau / nv50 / nv50_surface.c
index a6c0bbc2671773edfc45ffb083f8809bb3dff3f8..34c2633916bd1d20b8252b073500ec810d74227e 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "util/u_inlines.h"
 #include "util/u_pack_color.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
 #include "util/u_math.h"
 #include "util/u_surface.h"
 
@@ -295,7 +295,7 @@ nv50_clear_render_target(struct pipe_context *pipe,
    PUSH_DATAf(push, color->f[2]);
    PUSH_DATAf(push, color->f[3]);
 
-   if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
+   if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0))
       return;
 
    PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -394,7 +394,7 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
       mode |= NV50_3D_CLEAR_BUFFERS_S;
    }
 
-   if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
+   if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0))
       return;
 
    PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -475,11 +475,11 @@ nv50_clear_texture(struct pipe_context *pipe,
 
       if (util_format_has_depth(desc)) {
          clear |= PIPE_CLEAR_DEPTH;
-         desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
+         util_format_unpack_z_float(res->format, &depth, data, 1);
       }
       if (util_format_has_stencil(desc)) {
          clear |= PIPE_CLEAR_STENCIL;
-         desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
+         util_format_unpack_s_8uint(res->format, &stencil, data, 1);
       }
       pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil,
                                 box->x, box->y, box->width, box->height, false);
@@ -672,10 +672,7 @@ nv50_clear_buffer_push(struct pipe_context *pipe,
       count -= nr;
    }
 
-   if (buf->mm) {
-      nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence);
-      nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence_wr);
-   }
+   nv50_resource_validate(buf, NOUVEAU_BO_WR);
 
    nouveau_bufctx_reset(nv50->bufctx, 0);
 }
@@ -727,6 +724,8 @@ nv50_clear_buffer(struct pipe_context *pipe,
       return;
    }
 
+   util_range_add(&buf->base, &buf->valid_buffer_range, offset, offset + size);
+
    assert(size % data_size == 0);
 
    if (offset & 0xff) {
@@ -747,12 +746,12 @@ nv50_clear_buffer(struct pipe_context *pipe,
    assert(width > 0);
 
    BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
-   PUSH_DATAf(push, color.f[0]);
-   PUSH_DATAf(push, color.f[1]);
-   PUSH_DATAf(push, color.f[2]);
-   PUSH_DATAf(push, color.f[3]);
+   PUSH_DATA (push, color.ui[0]);
+   PUSH_DATA (push, color.ui[1]);
+   PUSH_DATA (push, color.ui[2]);
+   PUSH_DATA (push, color.ui[3]);
 
-   if (nouveau_pushbuf_space(push, 32, 1, 0))
+   if (nouveau_pushbuf_space(push, 64, 1, 0))
       return;
 
    PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);
@@ -796,10 +795,7 @@ nv50_clear_buffer(struct pipe_context *pipe,
    BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
    PUSH_DATA (push, nv50->cond_condmode);
 
-   if (buf->mm) {
-      nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence);
-      nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence_wr);
-   }
+   nv50_resource_validate(buf, NOUVEAU_BO_WR);
 
    if (width * height != elements) {
       offset += width * height * data_size;
@@ -821,7 +817,7 @@ struct nv50_blitter
 
    struct nv50_tsc_entry sampler[2]; /* nearest, bilinear */
 
-   pipe_mutex mutex;
+   mtx_t mutex;
 };
 
 struct nv50_blitctx
@@ -896,6 +892,10 @@ nv50_blitter_make_fp(struct pipe_context *pipe,
    bool tex_s = false;
    bool cvt_un8 = false;
 
+   bool int_clamp = mode == NV50_BLIT_MODE_INT_CLAMP;
+   if (int_clamp)
+      mode = NV50_BLIT_MODE_PASS;
+
    if (mode != NV50_BLIT_MODE_PASS &&
        mode != NV50_BLIT_MODE_Z24X8 &&
        mode != NV50_BLIT_MODE_X8Z24)
@@ -940,6 +940,10 @@ nv50_blitter_make_fp(struct pipe_context *pipe,
                target, tc, ureg_DECL_sampler(ureg, 0));
    }
 
+   /* handle signed to unsigned integer conversions */
+   if (int_clamp)
+      ureg_UMIN(ureg, data, ureg_src(data), ureg_imm1u(ureg, 0x7fffffff));
+
    if (cvt_un8) {
       struct ureg_src mask;
       struct ureg_src scale;
@@ -1062,6 +1066,9 @@ nv50_blit_select_mode(const struct pipe_blit_info *info)
          return NV50_BLIT_MODE_XS;
       }
    default:
+      if (util_format_is_pure_uint(info->src.format) &&
+          util_format_is_pure_sint(info->dst.format))
+         return NV50_BLIT_MODE_INT_CLAMP;
       return NV50_BLIT_MODE_PASS;
    }
 }
@@ -1078,11 +1085,11 @@ nv50_blit_select_fp(struct nv50_blitctx *ctx, const struct pipe_blit_info *info)
    const unsigned mode = ctx->mode;
 
    if (!blitter->fp[targ][mode]) {
-      pipe_mutex_lock(blitter->mutex);
+      mtx_lock(&blitter->mutex);
       if (!blitter->fp[targ][mode])
          blitter->fp[targ][mode] =
             nv50_blitter_make_fp(&ctx->nv50->base.pipe, mode, ptarg);
-      pipe_mutex_unlock(blitter->mutex);
+      mtx_unlock(&blitter->mutex);
    }
    ctx->fp = blitter->fp[targ][mode];
 }
@@ -1349,7 +1356,6 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
    float x0, x1, y0, y1, z;
    float dz;
    float x_range, y_range;
-   float tri_x, tri_y;
 
    blit->mode = nv50_blit_select_mode(info);
    blit->color_mask = nv50_blit_derive_color_mask(info);
@@ -1370,14 +1376,11 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
    x_range = (float)info->src.box.width / (float)info->dst.box.width;
    y_range = (float)info->src.box.height / (float)info->dst.box.height;
 
-   tri_x = 16384 << nv50_miptree(dst)->ms_x;
-   tri_y = 16384 << nv50_miptree(dst)->ms_y;
-
    x0 = (float)info->src.box.x - x_range * (float)info->dst.box.x;
    y0 = (float)info->src.box.y - y_range * (float)info->dst.box.y;
 
-   x1 = x0 + tri_x * x_range;
-   y1 = y0 + tri_y * y_range;
+   x1 = x0 + 16384.0f * x_range;
+   y1 = y0 + 16384.0f * y_range;
 
    x0 *= (float)(1 << nv50_miptree(src)->ms_x);
    x1 *= (float)(1 << nv50_miptree(src)->ms_x);
@@ -1450,7 +1453,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
       PUSH_DATAf(push, y0);
       PUSH_DATAf(push, z);
       BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
-      PUSH_DATAf(push, tri_x);
+      PUSH_DATAf(push, 16384.0f);
       PUSH_DATAf(push, 0.0f);
       BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
       PUSH_DATAf(push, x0);
@@ -1458,7 +1461,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
       PUSH_DATAf(push, z);
       BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
       PUSH_DATAf(push, 0.0f);
-      PUSH_DATAf(push, tri_y);
+      PUSH_DATAf(push, 16384.0f);
       BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
       PUSH_DATA (push, 0);
    }
@@ -1662,6 +1665,13 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
    struct nouveau_pushbuf *push = nv50->base.pushbuf;
    bool eng3d = FALSE;
 
+   if (info->src.box.width == 0 || info->src.box.height == 0 ||
+       info->dst.box.width == 0 || info->dst.box.height == 0) {
+      pipe_debug_message(&nv50->base.debug, ERROR,
+                         "Blit with zero-size src or dst box");
+      return;
+   }
+
    if (util_format_is_depth_or_stencil(info->dst.resource->format)) {
       if (!(info->mask & PIPE_MASK_ZS))
          return;
@@ -1755,7 +1765,7 @@ nv50_blitter_create(struct nv50_screen *screen)
       return false;
    }
 
-   pipe_mutex_init(screen->blitter->mutex);
+   (void) mtx_init(&screen->blitter->mutex, mtx_plain);
 
    nv50_blitter_make_vp(screen->blitter);
    nv50_blitter_make_sampler(screen->blitter);
@@ -1780,7 +1790,7 @@ nv50_blitter_destroy(struct nv50_screen *screen)
       }
    }
 
-   pipe_mutex_destroy(blitter->mutex);
+   mtx_destroy(&blitter->mutex);
    FREE(blitter);
 }