<div dir="ltr">On 29 December 2012 04:35, Chris Forbes <span dir="ltr"><<a href="mailto:chrisf@ijw.co.nz" target="_blank">chrisf@ijw.co.nz</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
This is a bit nasty -- I've just (ab)used the existing multisample<br>
renderbuffer path.<br>
<br>
Also put the actual sample count from the mt back into the<br>
renderbuffer so core mesa can see what the driver actually gave it.<br>
<br>
Signed-off-by: Chris Forbes <<a href="mailto:chrisf@ijw.co.nz">chrisf@ijw.co.nz</a>><br>
---<br>
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |  2 ++<br>
 src/mesa/drivers/dri/intel/intel_fbo.c           |  3 ++-<br>
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c   | 30 ++++++++++++++++++++----<br>
 src/mesa/drivers/dri/intel/intel_mipmap_tree.h   |  2 ++<br>
 src/mesa/drivers/dri/intel/intel_tex.c           | 18 +++++++++++---<br>
 5 files changed, 47 insertions(+), 8 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
index 94c01cb..1c54d59 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
@@ -59,6 +59,8 @@ translate_tex_target(GLenum target)<br>
    case GL_TEXTURE_2D:<br>
    case GL_TEXTURE_2D_ARRAY_EXT:<br>
    case GL_TEXTURE_EXTERNAL_OES:<br>
+   case GL_TEXTURE_2D_MULTISAMPLE:<br>
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:<br>
       return BRW_SURFACE_2D;<br>
<br>
    case GL_TEXTURE_3D:<br>
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c<br>
index 6a66521..4cc2c00 100644<br>
--- a/src/mesa/drivers/dri/intel/intel_fbo.c<br>
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c<br>
@@ -270,7 +270,7 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer<br>
       return true;<br>
<br>
    irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,<br>
-                                                  width, height,<br>
+                                                  width, height, 1,<br>
                                                    rb->NumSamples);<br>
    if (!irb->mt)<br>
       return false;<br>
@@ -509,6 +509,7 @@ intel_renderbuffer_update_wrapper(struct intel_context *intel,<br>
    rb->_BaseFormat = image->_BaseFormat;<br>
    rb->Width = mt->level[level].width;<br>
    rb->Height = mt->level[level].height;<br>
+   rb->NumSamples = mt->num_samples;<br>
<br>
    rb->Delete = intel_delete_renderbuffer;<br>
    rb->AllocStorage = intel_nop_alloc_storage;<br>
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c<br>
index 9ae7bcc..989c1f6 100644<br>
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c<br>
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c<br>
@@ -404,6 +404,7 @@ intel_miptree_create_for_dri2_buffer(struct intel_context *intel,<br>
                                                           format,<br>
                                                           region->width,<br>
                                                           region->height,<br>
+                                                          1,<br>
                                                           num_samples);<br>
    if (!multisample_mt) {<br>
       intel_miptree_release(&singlesample_mt);<br>
@@ -427,10 +428,10 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,<br>
                                       gl_format format,<br>
                                       uint32_t width,<br>
                                       uint32_t height,<br>
+                                      uint32_t depth,<br>
                                       uint32_t num_samples)<br>
 {<br>
    struct intel_mipmap_tree *mt;<br>
-   uint32_t depth = 1;<br>
    enum intel_msaa_layout msaa_layout = INTEL_MSAA_LAYOUT_NONE;<br>
    const uint32_t singlesample_width = width;<br>
    const uint32_t singlesample_height = height;<br>
@@ -491,6 +492,7 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,<br>
          }<br>
       } else {<br>
          /* Non-interleaved */<br>
+         assert(depth == 1);  /* XXX: do we ever hit this path with multisample arrays? */<br></blockquote><div><br></div><div>Yeah, this assertion isn't going to work for Gen7's non-interleaved multisample arrays.<br>
<br>Note that the Intel hardware docs use the term "physical" to describe 
the dimensions of the data structure that stores the multisampled data 
(i.e. after width, height, and/or depth have been scaled up to account 
for the number of samples) and "logical" to describe the dimensions of 
the image from the client's point of view.  I think I'm going to start 
adopting that terminology for clarity.<br><br>Bearing that in mind, the way the format works for Gen7 is that for each logical plane requested by the client using the depth parameter, N contiguous physical planes are allocated by hardware, one for each sample.  So, for example, if the user allocates a buffer of depth 2 using 4x MSAA, the surface we allocate will need to have a physical depth of 8, with the first 4 physical planes corresponding to samples 0-3 of the logical plane having z coordinate 0, and the next 4 physical planes corresponding to samples 0-3 of the logical plane having z coordinate 1.  So I think what we need to do here is remove the assertion and update depth like so:<br>
<br></div><div>depth *= num_samples<br><br></div><div>(of course everything is going to look a little different assuming we move this logic into common code that's shared by intel_miptree_create_for{texture,renderbuffer}).<br>
<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          depth = num_samples;<br>
       }<br>
    }<br>
@@ -508,6 +510,7 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,<br>
    }<br>
<br>
    if (mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {<br>
+      assert(depth == 1);  /* XXX: multisample arrays interaction with MCS? */<br>
       ok = intel_miptree_alloc_mcs(intel, mt, num_samples);<br></blockquote><div><br></div><div>I don't think you need the assertion here--intel_miptree_alloc_mcs() reads the depth out of the miptree, so it should allocate the proper size buffer without us having to do any extra work here.<br>
<br>Having said that, I think I just discovered a bug: intel_miptree_alloc_mcs() allocates a surface whose depth is equal to mt->depth0, which is the physical depth.  But it should be using the logical depth, since the MCS buffer stores data per pixel, not per sample.  It's a fairly benign bug--it just means we're allocating more memory than we need--but embarrassing nonetheless.<br>
<br></div><div>I'm beginning to think that what we really ought to do is:<br></div><div>- Rename intel_mipmap_tree::{width,height,depth}0 to intel_mipmap_tree::physical_{width,height,depth}0 to clarify that they represent the width, height, and depth *after* appropriate multiplications have been made to account for the number of samples.<br>
</div><div>- Rename intel_mipmap_tree::singlesample_{width,height}0 to intel_mipmap_tree::logical_{width,height}0 to clarify that they represent the width and height of the surface from the client's point of view.<br>
</div><div>- Add intel_mipmap_tree::logical_depth0 to represent the depth of the surface from the client's point of view.<br></div><div>- Modify the code that initializes intel_mipmap_tree so that logical_{width,heigt,depth}0 are always initialized (at the moment they're only initialized for multisampled surfaces, and I think that leads to confusion).<br>
<br></div><div>Unless someone has objections, I'll try to submit a patch to do it ASAP (and fix the overallocation of MCS memory), and then hopefully we can rebase Chris's patches on top of it.<br></div><div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
       if (!ok)<br>
          goto fail;<br>
@@ -624,9 +627,27 @@ intel_miptree_match_image(struct intel_mipmap_tree *mt,<br>
     * minification.  This will also catch images not present in the<br>
     * tree, changed targets, etc.<br>
     */<br>
-   if (width != mt->level[level].width ||<br>
-       height != mt->level[level].height ||<br>
-       depth != mt->level[level].depth)<br>
+   if (mt->target == GL_TEXTURE_2D_MULTISAMPLE ||<br>
+         mt->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {<br>
+      /* nonzero level here is always bogus */<br>
+      assert(level == 0);<br>
+<br>
+      if (width != mt->singlesample_width0 ||<br>
+            height != mt->singlesample_height0 ||<br>
+            depth != mt->level[level].depth) {<br>
+         return false;<br>
+      }<br>
+   }<br>
+   else {<br>
+      /* all normal textures, renderbuffers, etc */<br>
+      if (width != mt->level[level].width ||<br>
+          height != mt->level[level].height ||<br>
+          depth != mt->level[level].depth) {<br>
+         return false;<br>
+      }<br>
+   }<br>
+<br>
+   if (image->TexObject->NumSamples != mt->num_samples)<br>
       return false;<br>
<br>
    return true;<br>
@@ -1644,6 +1665,7 @@ intel_miptree_map_multisample(struct intel_context *intel,<br>
                                                mt->format,<br>
                                                mt->singlesample_width0,<br>
                                                mt->singlesample_height0,<br>
+                                               1,<br>
                                                0 /*num_samples*/);<br>
       if (!mt->singlesample_mt)<br>
          goto fail;<br>
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h<br>
index eb4ad7f..3de0019 100644<br>
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h<br>
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h<br>
@@ -405,12 +405,14 @@ intel_miptree_create_for_dri2_buffer(struct intel_context *intel,<br>
  *     - The target is GL_TEXTURE_2D.<br>
  *     - There are no levels other than the base level 0.<br>
  *     - Depth is 1.<br>
+ *     XXX: this description is quite bogus now.<br>
  */<br>
 struct intel_mipmap_tree*<br>
 intel_miptree_create_for_renderbuffer(struct intel_context *intel,<br>
                                       gl_format format,<br>
                                       uint32_t width,<br>
                                       uint32_t height,<br>
+                                      uint32_t depth,<br>
                                       uint32_t num_samples);<br>
<br>
 /** \brief Assert that the level and layer are valid for the miptree. */<br>
diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c<br>
index fdf5812..5f0301c 100644<br>
--- a/src/mesa/drivers/dri/intel/intel_tex.c<br>
+++ b/src/mesa/drivers/dri/intel/intel_tex.c<br>
@@ -71,6 +71,7 @@ intel_alloc_texture_image_buffer(struct gl_context *ctx,<br>
    switch (texobj->Target) {<br>
    case GL_TEXTURE_3D:<br>
    case GL_TEXTURE_2D_ARRAY:<br>
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:<br>
       slices = image->Depth;<br>
       break;<br>
    case GL_TEXTURE_1D_ARRAY:<br>
@@ -91,9 +92,20 @@ intel_alloc_texture_image_buffer(struct gl_context *ctx,<br>
           __FUNCTION__, texobj, image->Level,<br>
           image->Width, image->Height, image->Depth, intel_texobj->mt);<br>
    } else {<br>
-      intel_image->mt = intel_miptree_create_for_teximage(intel, intel_texobj,<br>
-                                                          intel_image,<br>
-                                                          false);<br>
+<br>
+      if (texobj->NumSamples) {<br>
+         /* Treat multisample textures exactly like renderbuffers */<br>
+         intel_image->mt = intel_miptree_create_for_renderbuffer(intel,<br>
+               image->TexFormat, image->Width, image->Height, image->Depth,<br>
+               texobj->NumSamples);<br>
+         /* Renderbuffer path doesn't bother to set the mt's target, so do it here */<br>
+         intel_image->mt->target = texobj->Target;<br>
+      }<br>
+      else {<br>
+         intel_image->mt = intel_miptree_create_for_teximage(intel, intel_texobj,<br>
+                                                             intel_image,<br>
+                                                             false);<br>
+      }<br>
<br>
       /* Even if the object currently has a mipmap tree associated<br>
        * with it, this one is a more likely candidate to represent the<br>
<span class=""><font color="#888888">--<br>
1.8.0.3<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>