[Mesa-dev] [PATCH 8/8] st/mesa: expose & set limits for AMD_framebuffer_multisample_advanced

Marek Olšák maraeo at gmail.com
Wed Aug 1 23:26:04 UTC 2018


From: Marek Olšák <marek.olsak at amd.com>

---
 src/mesa/state_tracker/st_extensions.c | 89 ++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index dbaf7f6f8fe..1c01495e937 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -593,20 +593,40 @@ get_max_samples_for_formats(struct pipe_screen *screen,
       for (f = 0; f < num_formats; f++) {
          if (screen->is_format_supported(screen, formats[f],
                                          PIPE_TEXTURE_2D, i, i, bind)) {
             return i;
          }
       }
    }
    return 0;
 }
 
+static unsigned
+get_max_samples_for_formats_advanced(struct pipe_screen *screen,
+                                     unsigned num_formats,
+                                     const enum pipe_format *formats,
+                                     unsigned max_samples,
+                                     unsigned num_storage_samples,
+                                     unsigned bind)
+{
+   unsigned i, f;
+
+   for (i = max_samples; i > 0; --i) {
+      for (f = 0; f < num_formats; f++) {
+         if (screen->is_format_supported(screen, formats[f], PIPE_TEXTURE_2D,
+                                         i, num_storage_samples, bind)) {
+            return i;
+         }
+      }
+   }
+   return 0;
+}
 
 /**
  * Use pipe_screen::get_param() to query PIPE_CAP_ values to determine
  * which GL extensions are supported.
  * Quite a few extensions are always supported because they are standard
  * features or can be built on top of other gallium features.
  * Some fine tuning may still be needed.
  */
 void st_init_extensions(struct pipe_screen *screen,
                         struct gl_constants *consts,
@@ -678,20 +698,21 @@ void st_init_extensions(struct pipe_screen *screen,
       { o(EXT_memory_object_fd),             PIPE_CAP_MEMOBJ                           },
       { o(EXT_semaphore),                    PIPE_CAP_FENCE_SIGNAL                     },
       { o(EXT_semaphore_fd),                 PIPE_CAP_FENCE_SIGNAL                     },
       { o(EXT_texture_array),                PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS         },
       { o(EXT_texture_filter_anisotropic),   PIPE_CAP_ANISOTROPIC_FILTER               },
       { o(EXT_texture_mirror_clamp),         PIPE_CAP_TEXTURE_MIRROR_CLAMP             },
       { o(EXT_texture_swizzle),              PIPE_CAP_TEXTURE_SWIZZLE                  },
       { o(EXT_transform_feedback),           PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS        },
       { o(EXT_window_rectangles),            PIPE_CAP_MAX_WINDOW_RECTANGLES            },
 
+      { o(AMD_framebuffer_multisample_advanced), PIPE_CAP_FRAMEBUFFER_MSAA_CONSTRAINTS },
       { o(AMD_pinned_memory),                PIPE_CAP_RESOURCE_FROM_USER_MEMORY        },
       { o(ATI_meminfo),                      PIPE_CAP_QUERY_MEMORY_INFO                },
       { o(AMD_seamless_cubemap_per_texture), PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE    },
       { o(ATI_texture_mirror_once),          PIPE_CAP_TEXTURE_MIRROR_CLAMP             },
       { o(MESA_tile_raster_order),           PIPE_CAP_TILE_RASTER_ORDER                },
       { o(NV_conditional_render),            PIPE_CAP_CONDITIONAL_RENDER               },
       { o(NV_fill_rectangle),                PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE      },
       { o(NV_primitive_restart),             PIPE_CAP_PRIMITIVE_RESTART                },
       { o(NV_texture_barrier),               PIPE_CAP_TEXTURE_BARRIER                  },
       { o(NVX_gpu_memory_info),              PIPE_CAP_QUERY_MEMORY_INFO                },
@@ -1095,20 +1116,88 @@ void st_init_extensions(struct pipe_screen *screen,
       consts->MaxIntegerSamples =
          get_max_samples_for_formats(screen, ARRAY_SIZE(int_formats),
                                      int_formats, consts->MaxSamples,
                                      PIPE_BIND_SAMPLER_VIEW);
 
       /* ARB_framebuffer_no_attachments, assume max no. of samples 32 */
       consts->MaxFramebufferSamples =
          get_max_samples_for_formats(screen, ARRAY_SIZE(void_formats),
                                      void_formats, 32,
                                      PIPE_BIND_RENDER_TARGET);
+
+      if (extensions->AMD_framebuffer_multisample_advanced) {
+         /* AMD_framebuffer_multisample_advanced */
+         /* This can be greater than storage samples. */
+         consts->MaxColorFramebufferSamples =
+            get_max_samples_for_formats_advanced(screen,
+                                                ARRAY_SIZE(color_formats),
+                                                color_formats, 16,
+                                                consts->MaxSamples,
+                                                PIPE_BIND_RENDER_TARGET);
+
+         /* If the driver supports N color samples, it means it supports
+          * N samples and N storage samples. N samples >= N storage
+          * samples.
+          */
+         consts->MaxColorFramebufferStorageSamples = consts->MaxSamples;
+         consts->MaxDepthStencilFramebufferSamples =
+            consts->MaxDepthTextureSamples;
+
+         assert(consts->MaxColorFramebufferSamples >=
+                consts->MaxDepthStencilFramebufferSamples);
+         assert(consts->MaxDepthStencilFramebufferSamples >=
+                consts->MaxColorFramebufferStorageSamples);
+
+         consts->NumSupportedMultisampleModes = 0;
+
+         unsigned depth_samples_supported = 0;
+
+         for (unsigned samples = 2;
+              samples <= consts->MaxDepthStencilFramebufferSamples;
+              samples++) {
+            if (screen->is_format_supported(screen, PIPE_FORMAT_Z32_FLOAT,
+                                            PIPE_TEXTURE_2D, samples, samples,
+                                            PIPE_BIND_DEPTH_STENCIL))
+               depth_samples_supported |= 1 << samples;
+         }
+
+         for (unsigned samples = 2;
+              samples <= consts->MaxColorFramebufferSamples;
+              samples++) {
+            for (unsigned depth_samples = 2;
+                 depth_samples <= samples; depth_samples++) {
+               if (!(depth_samples_supported & (1 << depth_samples)))
+                  continue;
+
+               for (unsigned storage_samples = 2;
+                    storage_samples <= depth_samples; storage_samples++) {
+                  if (screen->is_format_supported(screen,
+                                                  PIPE_FORMAT_R8G8B8A8_UNORM,
+                                                  PIPE_TEXTURE_2D,
+                                                  samples,
+                                                  storage_samples,
+                                                  PIPE_BIND_RENDER_TARGET)) {
+                     unsigned i = consts->NumSupportedMultisampleModes;
+
+                     assert(i < ARRAY_SIZE(consts->SupportedMultisampleModes));
+                     consts->SupportedMultisampleModes[i].NumColorSamples =
+                        samples;
+                     consts->SupportedMultisampleModes[i].NumColorStorageSamples =
+                        storage_samples;
+                     consts->SupportedMultisampleModes[i].NumDepthStencilSamples =
+                        depth_samples;
+                     consts->NumSupportedMultisampleModes++;
+                  }
+               }
+            }
+         }
+      }
    }
 
    if (consts->MaxSamples >= 2) {
       /* Real MSAA support */
       extensions->EXT_framebuffer_multisample = GL_TRUE;
       extensions->EXT_framebuffer_multisample_blit_scaled = GL_TRUE;
    }
    else if (consts->MaxSamples > 0 &&
             screen->get_param(screen, PIPE_CAP_FAKE_SW_MSAA)) {
       /* fake MSAA support */
-- 
2.17.1



More information about the mesa-dev mailing list