i965/msaa: Treat GL_SAMPLES=1 as equivalent to GL_SAMPLES=0.
authorPaul Berry <stereotype441@gmail.com>
Fri, 27 Jul 2012 01:01:28 +0000 (18:01 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 1 Aug 2012 19:45:15 +0000 (12:45 -0700)
EXT_framebuffer_multisample is a required subpart of
ARB_framebuffer_object, which means that we must support it even on
platforms that don't support MSAA.  Fortunately
EXT_framebuffer_multisample allows for this by allowing GL_MAX_SAMPLES
to be set to 1.

This leads to a tricky quirk in the GL spec: since
GlRenderbufferStorageMultisamples() accepts any value for its
"samples" parameter up to and including GL_MAX_SAMPLES, that means
that on platforms that don't support MSAA, GL_SAMPLES is allowed to be
set to either 0 or 1.  On platforms that do support MSAA, GL_SAMPLES=1
is not used; 0 means no MSAA, and 2 or higher means MSAA.

In other words, GL_SAMPLES needs to be interpreted as follows:
  =0  no MSAA (possible on all platforms)
  =1  no MSAA (only possible on platforms where MSAA unsupported)
  >1  MSAA (only possible on platforms where MSAA supported)

This patch modifies all MSAA-related code to choose between
multisampling and single-sampling based on the condition (GL_SAMPLES >
1) instead of (GL_SAMPLES > 0) so that GL_SAMPLES=1 will be treated as
"no MSAA".

Note that since GL_SAMPLES=1 implies GL_SAMPLE_BUFFERS=1, we can no
longer use GL_SAMPLE_BUFFERS to distinguish between MSAA and non-MSAA
rendering.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen6_blorp.cpp
src/mesa/drivers/dri/i965/gen6_multisample_state.c
src/mesa/drivers/dri/i965/gen6_sf_state.c
src/mesa/drivers/dri/i965/gen6_wm_state.c
src/mesa/drivers/dri/i965/gen7_blorp.cpp
src/mesa/drivers/dri/i965/gen7_sf_state.c
src/mesa/drivers/dri/i965/gen7_wm_state.c
src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.c

index 296b99f762e083059a88d86d014b770640606575..1206237a71b67c339401ca14d6e6f57efb6a4a29 100644 (file)
@@ -1582,7 +1582,7 @@ inline intel_msaa_layout
 compute_msaa_layout_for_pipeline(struct brw_context *brw, unsigned num_samples,
                                  intel_msaa_layout true_layout)
 {
-   if (num_samples == 0) {
+   if (num_samples <= 1) {
       /* When configuring the GPU for non-MSAA, we can still accommodate IMS
        * format buffers, by transforming coordinates appropriately.
        */
@@ -1652,7 +1652,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
          dst.num_samples = 0;
    }
 
-   if (dst.map_stencil_as_y_tiled && dst.num_samples > 0) {
+   if (dst.map_stencil_as_y_tiled && dst.num_samples > 1) {
       /* If the destination surface is a W-tiled multisampled stencil buffer
        * that we're mapping as Y tiled, then we need to arrange for the WM
        * program to run once per sample rather than once per pixel, because
@@ -1662,7 +1662,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
       wm_prog_key.persample_msaa_dispatch = true;
    }
 
-   if (src.num_samples > 0 && dst.num_samples > 0) {
+   if (src.num_samples > 0 && dst.num_samples > 1) {
       /* We are blitting from a multisample buffer to a multisample buffer, so
        * we must preserve samples within a pixel.  This means we have to
        * arrange for the WM program to run once per sample rather than once
@@ -1679,7 +1679,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
    GLenum base_format = _mesa_get_format_base_format(src_mt->format);
    if (base_format != GL_DEPTH_COMPONENT && /* TODO: what about depth/stencil? */
        base_format != GL_STENCIL_INDEX &&
-       src_mt->num_samples > 0 && dst_mt->num_samples == 0) {
+       src_mt->num_samples > 1 && dst_mt->num_samples <= 1) {
       /* We are downsampling a color buffer, so blend. */
       wm_prog_key.blend = true;
    }
@@ -1717,7 +1717,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
    wm_push_consts.x_transform.setup(src_x0, dst_x0, dst_x1, mirror_x);
    wm_push_consts.y_transform.setup(src_y0, dst_y0, dst_y1, mirror_y);
 
-   if (dst.num_samples == 0 && dst_mt->num_samples > 0) {
+   if (dst.num_samples <= 1 && dst_mt->num_samples > 1) {
       /* We must expand the rectangle we send through the rendering pipeline,
        * to account for the fact that we are mapping the destination region as
        * single-sampled when it is in fact multisampled.  We must also align
index 099668eae9ce351e69d447e4f43a658a1c27703d..366446241b02eb11fe6e7cb4246ebf61a22157a0 100644 (file)
@@ -645,7 +645,7 @@ brw_get_surface_tiling_bits(uint32_t tiling)
 uint32_t
 brw_get_surface_num_multisamples(unsigned num_samples)
 {
-   if (num_samples > 0)
+   if (num_samples > 1)
       return BRW_SURFACE_MULTISAMPLECOUNT_4;
    else
       return BRW_SURFACE_MULTISAMPLECOUNT_1;
@@ -987,7 +987,7 @@ brw_update_null_renderbuffer_surface(struct brw_context *brw, unsigned int unit)
    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
                          6 * 4, 32, &brw->wm.surf_offset[unit]);
 
-   if (fb->Visual.samples > 0) {
+   if (fb->Visual.samples > 1) {
       /* On Gen6, null render targets seem to cause GPU hangs when
        * multisampling.  So work around this problem by rendering into dummy
        * color buffer.
index b134ab46809f29328e1f215d71551726637b0729..995b50781a2a0c0e4288a0d799a4cdcbc5d6b0d4 100644 (file)
@@ -415,7 +415,7 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
    uint32_t wm_surf_offset;
    uint32_t width, height;
    surface->get_miplevel_dims(&width, &height);
-   if (surface->num_samples > 0) { /* TODO: seems clumsy */
+   if (surface->num_samples > 1) { /* TODO: seems clumsy */
       width /= 2;
       height /= 2;
    }
@@ -685,7 +685,7 @@ gen6_blorp_emit_sf_config(struct brw_context *brw,
              1 << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT |
              0 << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT);
    OUT_BATCH(0); /* dw2 */
-   OUT_BATCH(params->num_samples > 0 ? GEN6_SF_MSRAST_ON_PATTERN : 0);
+   OUT_BATCH(params->num_samples > 1 ? GEN6_SF_MSRAST_ON_PATTERN : 0);
    for (int i = 0; i < 16; ++i)
       OUT_BATCH(0);
    ADVANCE_BATCH();
@@ -744,7 +744,7 @@ gen6_blorp_emit_wm_config(struct brw_context *brw,
       dw5 |= GEN6_WM_DISPATCH_ENABLE; /* We are rendering */
    }
 
-   if (params->num_samples > 0) {
+   if (params->num_samples > 1) {
       dw6 |= GEN6_WM_MSRAST_ON_PATTERN;
       if (prog_data && prog_data->persample_msaa_dispatch)
          dw6 |= GEN6_WM_MSDISPMODE_PERSAMPLE;
index 68d28dd9b451ff6863245f678e0c562eb1150ef6..64ac292a8087a543198df8782cc4c42c7bcb24a0 100644 (file)
@@ -42,6 +42,7 @@ gen6_emit_3dstate_multisample(struct brw_context *brw,
 
    switch (num_samples) {
    case 0:
+   case 1:
       number_of_multisamples = MS_NUMSAMPLES_1;
       break;
    case 4:
@@ -121,7 +122,7 @@ gen6_emit_3dstate_sample_mask(struct brw_context *brw,
 
    BEGIN_BATCH(2);
    OUT_BATCH(_3DSTATE_SAMPLE_MASK << 16 | (2 - 2));
-   if (num_samples > 0) {
+   if (num_samples > 1) {
       int coverage_int = (int) (num_samples * coverage + 0.5);
       uint32_t coverage_bits = (1 << coverage_int) - 1;
       if (coverage_invert)
index 736e83ae2b3de4da1ca9db78ad779f9113ba37c0..c1bc252cb0f51e316af272247a2c8dd88667f3f1 100644 (file)
@@ -122,7 +122,7 @@ upload_sf_state(struct brw_context *brw)
    int i;
    /* _NEW_BUFFER */
    bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer);
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.sampleBuffers;
+   bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
 
    int attr = 0, input_index = 0;
    int urb_entry_read_offset = 1;
index 63acbe3c110f69ee6515a4277bebe2a9fcf15632..dd435286dee1955c6ec4b55235eddae959ff095a 100644 (file)
@@ -99,7 +99,7 @@ upload_wm_state(struct brw_context *brw)
    uint32_t dw2, dw4, dw5, dw6;
 
    /* _NEW_BUFFERS */
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.sampleBuffers;
+   bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
 
     /* CACHE_NEW_WM_PROG */
    if (brw->wm.prog_data->nr_params == 0) {
index 66eb2c8909c803f4330f72e9cd74bdc84420edd9..a65a975ed12bafb9dd7fbd2391fc9fff57eda75e 100644 (file)
@@ -373,7 +373,7 @@ gen7_blorp_emit_sf_config(struct brw_context *brw,
       OUT_BATCH(_3DSTATE_SF << 16 | (7 - 2));
       OUT_BATCH(params->depth_format <<
                 GEN7_SF_DEPTH_BUFFER_SURFACE_FORMAT_SHIFT);
-      OUT_BATCH(params->num_samples > 0 ? GEN6_SF_MSRAST_ON_PATTERN : 0);
+      OUT_BATCH(params->num_samples > 1 ? GEN6_SF_MSRAST_ON_PATTERN : 0);
       OUT_BATCH(0);
       OUT_BATCH(0);
       OUT_BATCH(0);
@@ -432,7 +432,7 @@ gen7_blorp_emit_wm_config(struct brw_context *brw,
       dw1 |= GEN7_WM_DISPATCH_ENABLE; /* We are rendering */
    }
 
-      if (params->num_samples > 0) {
+      if (params->num_samples > 1) {
          dw1 |= GEN7_WM_MSRAST_ON_PATTERN;
          if (prog_data && prog_data->persample_msaa_dispatch)
             dw2 |= GEN7_WM_MSDISPMODE_PERSAMPLE;
index 2d258d2f1be19a007ab1384f7b914616d85a71ac..871a8b753a3a2720b62923ecdb36ede8091560f1 100644 (file)
@@ -161,7 +161,7 @@ upload_sf_state(struct brw_context *brw)
    float point_size;
    /* _NEW_BUFFERS */
    bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer);
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.sampleBuffers;
+   bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
 
    dw1 = GEN6_SF_STATISTICS_ENABLE |
          GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;
index e60027ad5e278f1271065f1b3769b79948f1df41..dc49a7dfe2af4383ff83a60367ad1c8b5669f0e8 100644 (file)
@@ -42,7 +42,7 @@ upload_wm_state(struct brw_context *brw)
    uint32_t dw1, dw2;
 
    /* _NEW_BUFFERS */
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.sampleBuffers;
+   bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
 
    dw1 = dw2 = 0;
    dw1 |= GEN7_WM_STATISTICS_ENABLE;
index 62d2be8665893ae02c8cbc200b3c2559a4627050..20e76e32f2ffdacc3bb048bf4a9f99df7052fd89 100644 (file)
@@ -61,7 +61,7 @@ gen7_set_surface_msaa(struct gen7_surface_state *surf, unsigned num_samples,
 {
    if (num_samples > 4)
       surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_8;
-   else if (num_samples > 0)
+   else if (num_samples > 1)
       surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_4;
    else
       surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_1;
@@ -280,7 +280,7 @@ gen7_update_texture_surface(struct gl_context *ctx, GLuint unit)
 
    /* We don't support MSAA for textures. */
    assert(!mt->array_spacing_lod0);
-   assert(mt->num_samples == 0);
+   assert(mt->num_samples <= 1);
 
    intel_miptree_get_dimensions_for_image(firstImage, &width, &height, &depth);
 
index 53bc23f2d08ae2b7803eaa28a3930fb702f74a5a..9f349d00a5f6ed62fa5ad4200f19ed8c6edc4478 100644 (file)
@@ -128,7 +128,7 @@ intel_miptree_create_internal(struct intel_context *intel,
         intel->vtbl.is_hiz_depth_format(intel, format)))) {
       /* MSAA stencil surfaces always use IMS layout. */
       enum intel_msaa_layout msaa_layout =
-         num_samples > 0 ? INTEL_MSAA_LAYOUT_IMS : INTEL_MSAA_LAYOUT_NONE;
+         num_samples > 1 ? INTEL_MSAA_LAYOUT_IMS : INTEL_MSAA_LAYOUT_NONE;
       mt->stencil_mt = intel_miptree_create(intel,
                                             mt->target,
                                             MESA_FORMAT_S8,
@@ -335,7 +335,7 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,
    uint32_t depth = 1;
    enum intel_msaa_layout msaa_layout = INTEL_MSAA_LAYOUT_NONE;
 
-   if (num_samples > 0) {
+   if (num_samples > 1) {
       /* Adjust width/height/depth for MSAA */
       msaa_layout = compute_msaa_layout(intel, format);
       if (msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
@@ -383,7 +383,7 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,
             height = ALIGN(height, 2) * 2;
             break;
          default:
-            /* num_samples should already have been quantized to 0, 4, or
+            /* num_samples should already have been quantized to 0, 1, 4, or
              * 8.
              */
             assert(false);