llvmpipe: fixup multisample coverage masks for covered tiles
[mesa.git] / src / gallium / drivers / llvmpipe / lp_texture.c
index 4dc7eb39f8f7606c1d9d5d692f28c0baa59f058e..fa7a1ff1129c065f7971ed91e3b050e229a25059 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "util/u_inlines.h"
 #include "util/u_cpu_detect.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "util/simple_list.h"
@@ -76,6 +76,8 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
    unsigned depth = pt->depth0;
    uint64_t total_size = 0;
    unsigned layers = pt->array_size;
+   unsigned num_samples = util_res_sample_count(pt);
+
    /* XXX:
     * This alignment here (same for displaytarget) was added for the purpose of
     * ARB_map_buffer_alignment. I am not convinced it's needed for non-buffer
@@ -166,6 +168,9 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
       depth = u_minify(depth, 1);
    }
 
+   lpr->sample_stride = total_size;
+   total_size *= num_samples;
+
    if (allocate) {
       lpr->tex_data = align_malloc(total_size, mip_align);
       if (!lpr->tex_data) {
@@ -187,7 +192,7 @@ fail:
  * Check the size of the texture specified by 'res'.
  * \return TRUE if OK, FALSE if too large.
  */
-static boolean
+static bool
 llvmpipe_can_create_resource(struct pipe_screen *screen,
                              const struct pipe_resource *res)
 {
@@ -486,7 +491,7 @@ no_lpr:
 }
 
 
-static boolean
+static bool
 llvmpipe_resource_get_handle(struct pipe_screen *screen,
                              struct pipe_context *ctx,
                             struct pipe_resource *pt,
@@ -498,19 +503,20 @@ llvmpipe_resource_get_handle(struct pipe_screen *screen,
 
    assert(lpr->dt);
    if (!lpr->dt)
-      return FALSE;
+      return false;
 
    return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle);
 }
 
 
-static void *
-llvmpipe_transfer_map( struct pipe_context *pipe,
-                       struct pipe_resource *resource,
-                       unsigned level,
-                       unsigned usage,
-                       const struct pipe_box *box,
-                       struct pipe_transfer **transfer )
+void *
+llvmpipe_transfer_map_ms( struct pipe_context *pipe,
+                          struct pipe_resource *resource,
+                          unsigned level,
+                          unsigned usage,
+                          unsigned sample,
+                          const struct pipe_box *box,
+                          struct pipe_transfer **transfer )
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
@@ -615,9 +621,20 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
       box->y / util_format_get_blockheight(format) * pt->stride +
       box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
 
+   map += sample * lpr->sample_stride;
    return map;
 }
 
+static void *
+llvmpipe_transfer_map( struct pipe_context *pipe,
+                       struct pipe_resource *resource,
+                       unsigned level,
+                       unsigned usage,
+                       const struct pipe_box *box,
+                       struct pipe_transfer **transfer )
+{
+   return llvmpipe_transfer_map_ms(pipe, resource, level, usage, 0, box, transfer);
+}
 
 static void
 llvmpipe_transfer_unmap(struct pipe_context *pipe,
@@ -647,7 +664,8 @@ llvmpipe_is_resource_referenced( struct pipe_context *pipe,
    if (!(presource->bind & (PIPE_BIND_DEPTH_STENCIL |
                             PIPE_BIND_RENDER_TARGET |
                             PIPE_BIND_SAMPLER_VIEW |
-                            PIPE_BIND_SHADER_BUFFER)))
+                            PIPE_BIND_SHADER_BUFFER |
+                            PIPE_BIND_SHADER_IMAGE)))
       return LP_UNREFERENCED;
 
    return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
@@ -767,6 +785,13 @@ llvmpipe_resource_size(const struct pipe_resource *resource)
    return size;
 }
 
+static void
+llvmpipe_memory_barrier(struct pipe_context *pipe,
+                       unsigned flags)
+{
+   /* this may be an overly large hammer for this nut. */
+   llvmpipe_finish(pipe, "barrier");
+}
 
 #ifdef DEBUG
 void
@@ -823,4 +848,6 @@ llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
    pipe->transfer_flush_region = u_default_transfer_flush_region;
    pipe->buffer_subdata = u_default_buffer_subdata;
    pipe->texture_subdata = u_default_texture_subdata;
+
+   pipe->memory_barrier = llvmpipe_memory_barrier;
 }