On 1 August 2012 08:18, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 07/27/2012 10:35 AM, Paul Berry wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
EXT_framebuffer_multisample is a required subpart of<br>
ARB_framebuffer_object, which means that we must support it even on<br>
platforms that don't support MSAA.  Fortunately<br>
EXT_framebuffer_multisample allows for this by allowing GL_MAX_SAMPLES<br>
to be set to 1.<br>
<br>
This leads to a tricky quirk in the GL spec: since<br>
GlRenderbufferStorageMultisamp<u></u>les() accepts any value for its<br>
"samples" parameter up to and including GL_MAX_SAMPLES, that means<br>
that on platforms that don't support MSAA, GL_SAMPLES is allowed to be<br>
set to either 0 or 1.  On platforms that do support MSAA, GL_SAMPLES=1<br>
is not used; 0 means no MSAA, and 2 or higher means MSAA.<br>
<br>
In other words, GL_SAMPLES needs to be interpreted as follows:<br>
   =0  no MSAA (possible on all platforms)<br>
   =1  no MSAA (only possible on platforms where MSAA unsupported)<br>
   >1  MSAA (only possible on platforms where MSAA supported)<br>
<br>
This patch modifies all MSAA-related code to choose between<br>
multisampling and single-sampling based on the condition (GL_SAMPLES ><br>
1) instead of (GL_SAMPLES > 0) so that GL_SAMPLES=1 will be treated as<br>
"no MSAA".<br>
<br>
Note that since GL_SAMPLES=1 implies GL_SAMPLE_BUFFERS=1, we can no<br>
longer use GL_SAMPLE_BUFFERS to distinguish between MSAA and non-MSAA<br>
rendering.<br>
</blockquote>
<br></div>
It looks like you hit everything here.<br>
<br>
One question.  Should quantize_num_samples quantize 1 to 1 or to 4 (as it does now)?<br></blockquote><div><br>Based on my reading of the spec, and the behaviour of my nVidia card, requesting samples=1 on a system that supports MSAA should select the minimum supported number of samples (i.e. 2 for nVidia, 4 for Intel chips).  So I believe what we are doing is correct.<br>
<br>Thanks for the review.  I'll push the patches later today.<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
If we decide to change that, it can be a follow-on patch.  This series is<br>
<br>
Reviewed-by: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com" target="_blank">ian.d.romanick@intel.com</a>><div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
  src/mesa/drivers/dri/i965/brw_<u></u>blorp_blit.cpp       |   10 +++++-----<br>
  src/mesa/drivers/dri/i965/brw_<u></u>wm_surface_state.c   |    4 ++--<br>
  src/mesa/drivers/dri/i965/<u></u>gen6_blorp.cpp           |    6 +++---<br>
  src/mesa/drivers/dri/i965/<u></u>gen6_multisample_state.c |    3 ++-<br>
  src/mesa/drivers/dri/i965/<u></u>gen6_sf_state.c          |    2 +-<br>
  src/mesa/drivers/dri/i965/<u></u>gen6_wm_state.c          |    2 +-<br>
  src/mesa/drivers/dri/i965/<u></u>gen7_blorp.cpp           |    4 ++--<br>
  src/mesa/drivers/dri/i965/<u></u>gen7_sf_state.c          |    2 +-<br>
  src/mesa/drivers/dri/i965/<u></u>gen7_wm_state.c          |    2 +-<br>
  src/mesa/drivers/dri/i965/<u></u>gen7_wm_surface_state.c  |    4 ++--<br>
  src/mesa/drivers/dri/intel/<u></u>intel_mipmap_tree.c     |    6 +++---<br>
  11 files changed, 23 insertions(+), 22 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/<u></u>brw_blorp_blit.cpp<br>
index 296b99f..1206237 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>brw_blorp_blit.cpp<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>brw_blorp_blit.cpp<br>
@@ -1582,7 +1582,7 @@ inline intel_msaa_layout<br>
  compute_msaa_layout_for_<u></u>pipeline(struct brw_context *brw, unsigned num_samples,<br>
                                   intel_msaa_layout true_layout)<br>
  {<br>
-   if (num_samples == 0) {<br>
+   if (num_samples <= 1) {<br>
        /* When configuring the GPU for non-MSAA, we can still accommodate IMS<br>
         * format buffers, by transforming coordinates appropriately.<br>
         */<br>
@@ -1652,7 +1652,7 @@ brw_blorp_blit_params::brw_<u></u>blorp_blit_params(struct brw_context *brw,<br>
           dst.num_samples = 0;<br>
     }<br>
<br>
-   if (dst.map_stencil_as_y_tiled && dst.num_samples > 0) {<br>
+   if (dst.map_stencil_as_y_tiled && dst.num_samples > 1) {<br>
        /* If the destination surface is a W-tiled multisampled stencil buffer<br>
         * that we're mapping as Y tiled, then we need to arrange for the WM<br>
         * program to run once per sample rather than once per pixel, because<br>
@@ -1662,7 +1662,7 @@ brw_blorp_blit_params::brw_<u></u>blorp_blit_params(struct brw_context *brw,<br>
        wm_prog_key.persample_msaa_<u></u>dispatch = true;<br>
     }<br>
<br>
-   if (src.num_samples > 0 && dst.num_samples > 0) {<br>
+   if (src.num_samples > 0 && dst.num_samples > 1) {<br>
        /* We are blitting from a multisample buffer to a multisample buffer, so<br>
         * we must preserve samples within a pixel.  This means we have to<br>
         * arrange for the WM program to run once per sample rather than once<br>
@@ -1679,7 +1679,7 @@ brw_blorp_blit_params::brw_<u></u>blorp_blit_params(struct brw_context *brw,<br>
     GLenum base_format = _mesa_get_format_base_format(<u></u>src_mt->format);<br>
     if (base_format != GL_DEPTH_COMPONENT && /* TODO: what about depth/stencil? */<br>
         base_format != GL_STENCIL_INDEX &&<br>
-       src_mt->num_samples > 0 && dst_mt->num_samples == 0) {<br>
+       src_mt->num_samples > 1 && dst_mt->num_samples <= 1) {<br>
        /* We are downsampling a color buffer, so blend. */<br>
        wm_prog_key.blend = true;<br>
     }<br>
@@ -1717,7 +1717,7 @@ brw_blorp_blit_params::brw_<u></u>blorp_blit_params(struct brw_context *brw,<br>
     wm_push_consts.x_transform.<u></u>setup(src_x0, dst_x0, dst_x1, mirror_x);<br>
     wm_push_consts.y_transform.<u></u>setup(src_y0, dst_y0, dst_y1, mirror_y);<br>
<br>
-   if (dst.num_samples == 0 && dst_mt->num_samples > 0) {<br>
+   if (dst.num_samples <= 1 && dst_mt->num_samples > 1) {<br>
        /* We must expand the rectangle we send through the rendering pipeline,<br>
         * to account for the fact that we are mapping the destination region as<br>
         * single-sampled when it is in fact multisampled.  We must also align<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/<u></u>brw_wm_surface_state.c<br>
index 65ca2fc..f577f4c 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>brw_wm_surface_state.c<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>brw_wm_surface_state.c<br>
@@ -650,7 +650,7 @@ brw_get_surface_tiling_bits(<u></u>uint32_t tiling)<br>
  uint32_t<br>
  brw_get_surface_num_<u></u>multisamples(unsigned num_samples)<br>
  {<br>
-   if (num_samples > 0)<br>
+   if (num_samples > 1)<br>
        return BRW_SURFACE_MULTISAMPLECOUNT_<u></u>4;<br>
     else<br>
        return BRW_SURFACE_MULTISAMPLECOUNT_<u></u>1;<br>
@@ -992,7 +992,7 @@ brw_update_null_renderbuffer_<u></u>surface(struct brw_context *brw, unsigned int unit)<br>
     surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,<br>
                          6 * 4, 32, &brw->wm.surf_offset[unit]);<br>
<br>
-   if (fb->Visual.samples > 0) {<br>
+   if (fb->Visual.samples > 1) {<br>
        /* On Gen6, null render targets seem to cause GPU hangs when<br>
         * multisampling.  So work around this problem by rendering into dummy<br>
         * color buffer.<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>gen6_blorp.cpp b/src/mesa/drivers/dri/i965/<u></u>gen6_blorp.cpp<br>
index b134ab4..995b507 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>gen6_blorp.cpp<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>gen6_blorp.cpp<br>
@@ -415,7 +415,7 @@ gen6_blorp_emit_surface_state(<u></u>struct brw_context *brw,<br>
     uint32_t wm_surf_offset;<br>
     uint32_t width, height;<br>
     surface->get_miplevel_dims(&<u></u>width, &height);<br>
-   if (surface->num_samples > 0) { /* TODO: seems clumsy */<br>
+   if (surface->num_samples > 1) { /* TODO: seems clumsy */<br>
        width /= 2;<br>
        height /= 2;<br>
     }<br>
@@ -685,7 +685,7 @@ gen6_blorp_emit_sf_config(<u></u>struct brw_context *brw,<br>
               1 << GEN6_SF_URB_ENTRY_READ_LENGTH_<u></u>SHIFT |<br>
               0 << GEN6_SF_URB_ENTRY_READ_OFFSET_<u></u>SHIFT);<br>
     OUT_BATCH(0); /* dw2 */<br>
-   OUT_BATCH(params->num_samples > 0 ? GEN6_SF_MSRAST_ON_PATTERN : 0);<br>
+   OUT_BATCH(params->num_samples > 1 ? GEN6_SF_MSRAST_ON_PATTERN : 0);<br>
     for (int i = 0; i < 16; ++i)<br>
        OUT_BATCH(0);<br>
     ADVANCE_BATCH();<br>
@@ -744,7 +744,7 @@ gen6_blorp_emit_wm_config(<u></u>struct brw_context *brw,<br>
        dw5 |= GEN6_WM_DISPATCH_ENABLE; /* We are rendering */<br>
     }<br>
<br>
-   if (params->num_samples > 0) {<br>
+   if (params->num_samples > 1) {<br>
        dw6 |= GEN6_WM_MSRAST_ON_PATTERN;<br>
        if (prog_data && prog_data->persample_msaa_<u></u>dispatch)<br>
           dw6 |= GEN6_WM_MSDISPMODE_PERSAMPLE;<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>gen6_multisample_state.c b/src/mesa/drivers/dri/i965/<u></u>gen6_multisample_state.c<br>
index 68d28dd..64ac292 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>gen6_multisample_state.c<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>gen6_multisample_state.c<br>
@@ -42,6 +42,7 @@ gen6_emit_3dstate_multisample(<u></u>struct brw_context *brw,<br>
<br>
     switch (num_samples) {<br>
     case 0:<br>
+   case 1:<br>
        number_of_multisamples = MS_NUMSAMPLES_1;<br>
        break;<br>
     case 4:<br>
@@ -121,7 +122,7 @@ gen6_emit_3dstate_sample_mask(<u></u>struct brw_context *brw,<br>
<br>
     BEGIN_BATCH(2);<br>
     OUT_BATCH(_3DSTATE_SAMPLE_MASK << 16 | (2 - 2));<br>
-   if (num_samples > 0) {<br>
+   if (num_samples > 1) {<br>
        int coverage_int = (int) (num_samples * coverage + 0.5);<br>
        uint32_t coverage_bits = (1 << coverage_int) - 1;<br>
        if (coverage_invert)<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>gen6_sf_state.c b/src/mesa/drivers/dri/i965/<u></u>gen6_sf_state.c<br>
index 736e83a..c1bc252 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>gen6_sf_state.c<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>gen6_sf_state.c<br>
@@ -122,7 +122,7 @@ upload_sf_state(struct brw_context *brw)<br>
     int i;<br>
     /* _NEW_BUFFER */<br>
     bool render_to_fbo = _mesa_is_user_fbo(brw->intel.<u></u>ctx.DrawBuffer);<br>
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.<u></u>sampleBuffers;<br>
+   bool multisampled_fbo = ctx->DrawBuffer->Visual.<u></u>samples > 1;<br>
<br>
     int attr = 0, input_index = 0;<br>
     int urb_entry_read_offset = 1;<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>gen6_wm_state.c b/src/mesa/drivers/dri/i965/<u></u>gen6_wm_state.c<br>
index 63acbe3..dd43528 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>gen6_wm_state.c<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>gen6_wm_state.c<br>
@@ -99,7 +99,7 @@ upload_wm_state(struct brw_context *brw)<br>
     uint32_t dw2, dw4, dw5, dw6;<br>
<br>
     /* _NEW_BUFFERS */<br>
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.<u></u>sampleBuffers;<br>
+   bool multisampled_fbo = ctx->DrawBuffer->Visual.<u></u>samples > 1;<br>
<br>
      /* CACHE_NEW_WM_PROG */<br>
     if (brw->wm.prog_data->nr_params == 0) {<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>gen7_blorp.cpp b/src/mesa/drivers/dri/i965/<u></u>gen7_blorp.cpp<br>
index cc28d8c..fddc7a8 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>gen7_blorp.cpp<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>gen7_blorp.cpp<br>
@@ -373,7 +373,7 @@ gen7_blorp_emit_sf_config(<u></u>struct brw_context *brw,<br>
        OUT_BATCH(_3DSTATE_SF << 16 | (7 - 2));<br>
        OUT_BATCH(params->depth_format <<<br>
                  GEN7_SF_DEPTH_BUFFER_SURFACE_<u></u>FORMAT_SHIFT);<br>
-      OUT_BATCH(params->num_samples > 0 ? GEN6_SF_MSRAST_ON_PATTERN : 0);<br>
+      OUT_BATCH(params->num_samples > 1 ? GEN6_SF_MSRAST_ON_PATTERN : 0);<br>
        OUT_BATCH(0);<br>
        OUT_BATCH(0);<br>
        OUT_BATCH(0);<br>
@@ -432,7 +432,7 @@ gen7_blorp_emit_wm_config(<u></u>struct brw_context *brw,<br>
        dw1 |= GEN7_WM_DISPATCH_ENABLE; /* We are rendering */<br>
     }<br>
<br>
-      if (params->num_samples > 0) {<br>
+      if (params->num_samples > 1) {<br>
           dw1 |= GEN7_WM_MSRAST_ON_PATTERN;<br>
           if (prog_data && prog_data->persample_msaa_<u></u>dispatch)<br>
              dw2 |= GEN7_WM_MSDISPMODE_PERSAMPLE;<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>gen7_sf_state.c b/src/mesa/drivers/dri/i965/<u></u>gen7_sf_state.c<br>
index 2d258d2..871a8b7 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>gen7_sf_state.c<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>gen7_sf_state.c<br>
@@ -161,7 +161,7 @@ upload_sf_state(struct brw_context *brw)<br>
     float point_size;<br>
     /* _NEW_BUFFERS */<br>
     bool render_to_fbo = _mesa_is_user_fbo(brw->intel.<u></u>ctx.DrawBuffer);<br>
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.<u></u>sampleBuffers;<br>
+   bool multisampled_fbo = ctx->DrawBuffer->Visual.<u></u>samples > 1;<br>
<br>
     dw1 = GEN6_SF_STATISTICS_ENABLE |<br>
           GEN6_SF_VIEWPORT_TRANSFORM_<u></u>ENABLE;<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>gen7_wm_state.c b/src/mesa/drivers/dri/i965/<u></u>gen7_wm_state.c<br>
index e60027a..dc49a7d 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>gen7_wm_state.c<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>gen7_wm_state.c<br>
@@ -42,7 +42,7 @@ upload_wm_state(struct brw_context *brw)<br>
     uint32_t dw1, dw2;<br>
<br>
     /* _NEW_BUFFERS */<br>
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.<u></u>sampleBuffers;<br>
+   bool multisampled_fbo = ctx->DrawBuffer->Visual.<u></u>samples > 1;<br>
<br>
     dw1 = dw2 = 0;<br>
     dw1 |= GEN7_WM_STATISTICS_ENABLE;<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/<u></u>gen7_wm_surface_state.c<br>
index 2522276..e0b0732 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>gen7_wm_surface_state.c<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>gen7_wm_surface_state.c<br>
@@ -61,7 +61,7 @@ gen7_set_surface_msaa(struct gen7_surface_state *surf, unsigned num_samples,<br>
  {<br>
     if (num_samples > 4)<br>
        surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_<u></u>8;<br>
-   else if (num_samples > 0)<br>
+   else if (num_samples > 1)<br>
        surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_<u></u>4;<br>
     else<br>
        surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_<u></u>1;<br>
@@ -280,7 +280,7 @@ gen7_update_texture_surface(<u></u>struct gl_context *ctx, GLuint unit)<br>
<br>
     /* We don't support MSAA for textures. */<br>
     assert(!mt->array_spacing_<u></u>lod0);<br>
-   assert(mt->num_samples == 0);<br>
+   assert(mt->num_samples <= 1);<br>
<br>
     intel_miptree_get_dimensions_<u></u>for_image(firstImage, &width, &height, &depth);<br>
<br>
diff --git a/src/mesa/drivers/dri/intel/<u></u>intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/<u></u>intel_mipmap_tree.c<br>
index 3d15a8d..b92ae96 100644<br>
--- a/src/mesa/drivers/dri/intel/<u></u>intel_mipmap_tree.c<br>
+++ b/src/mesa/drivers/dri/intel/<u></u>intel_mipmap_tree.c<br>
@@ -128,7 +128,7 @@ intel_miptree_create_internal(<u></u>struct intel_context *intel,<br>
         intel->vtbl.is_hiz_depth_<u></u>format(intel, format)))) {<br>
        /* MSAA stencil surfaces always use IMS layout. */<br>
        enum intel_msaa_layout msaa_layout =<br>
-         num_samples > 0 ? INTEL_MSAA_LAYOUT_IMS : INTEL_MSAA_LAYOUT_NONE;<br>
+         num_samples > 1 ? INTEL_MSAA_LAYOUT_IMS : INTEL_MSAA_LAYOUT_NONE;<br>
        mt->stencil_mt = intel_miptree_create(intel,<br>
                                              mt->target,<br>
                                              MESA_FORMAT_S8,<br>
@@ -335,7 +335,7 @@ intel_miptree_create_for_<u></u>renderbuffer(struct intel_context *intel,<br>
     uint32_t depth = 1;<br>
     enum intel_msaa_layout msaa_layout = INTEL_MSAA_LAYOUT_NONE;<br>
<br>
-   if (num_samples > 0) {<br>
+   if (num_samples > 1) {<br>
        /* Adjust width/height/depth for MSAA */<br>
        msaa_layout = compute_msaa_layout(intel, format);<br>
        if (msaa_layout == INTEL_MSAA_LAYOUT_IMS) {<br>
@@ -383,7 +383,7 @@ intel_miptree_create_for_<u></u>renderbuffer(struct intel_context *intel,<br>
              height = ALIGN(height, 2) * 2;<br>
              break;<br>
           default:<br>
-            /* num_samples should already have been quantized to 0, 4, or<br>
+            /* num_samples should already have been quantized to 0, 1, 4, or<br>
               * 8.<br>
               */<br>
              assert(false);<br>
<br>
</blockquote>
<br>
<br>
</div></div></blockquote></div><br>