From: Marek Olšák <marek.ol...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev