llvmpipe: fixup multisample coverage masks for covered tiles
[mesa.git] / src / gallium / drivers / llvmpipe / lp_texture.c
index ca15d785055ad5b26edd464fa944808edc47a111..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) {
@@ -504,13 +509,14 @@ llvmpipe_resource_get_handle(struct pipe_screen *screen,
 }
 
 
-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,
@@ -768,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
@@ -824,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;
 }