Matteo Bruni : wined3d: Add a real implementation of wined3d_check_device_multisample_type().

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jan 28 10:06:46 CST 2016


Module: wine
Branch: master
Commit: b1429f931e816feee2f7b7fe065a393c4caa7960
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b1429f931e816feee2f7b7fe065a393c4caa7960

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Thu Jan 28 00:15:43 2016 +0100

wined3d: Add a real implementation of wined3d_check_device_multisample_type().

Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/directx.c         | 37 ++++++++++++++++++++-----------------
 dlls/wined3d/surface.c         | 26 +++++++++++++++++++++++++-
 dlls/wined3d/utils.c           | 31 ++++++++++++++++++++++++++++++-
 dlls/wined3d/wined3d_private.h |  2 ++
 4 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 9faf4ec..c7b63f1 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -4408,36 +4408,39 @@ HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3
         enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed,
         enum wined3d_multisample_type multisample_type, DWORD *quality_levels)
 {
-    const struct wined3d_gl_info *gl_info;
+    const struct wined3d_gl_info *gl_info = &wined3d->adapters[adapter_idx].gl_info;
+    const struct wined3d_format *format = wined3d_get_format(gl_info, surface_format_id);
+    HRESULT hr = WINED3D_OK;
 
-    TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s,\n"
+    TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s, "
             "windowed %#x, multisample_type %#x, quality_levels %p.\n",
             wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(surface_format_id),
             windowed, multisample_type, quality_levels);
 
     if (adapter_idx >= wined3d->adapter_count)
         return WINED3DERR_INVALIDCALL;
+    if (surface_format_id == WINED3DFMT_UNKNOWN)
+        return WINED3DERR_INVALIDCALL;
+    if (multisample_type < WINED3D_MULTISAMPLE_NONE || multisample_type > WINED3D_MULTISAMPLE_16_SAMPLES)
+        return WINED3DERR_INVALIDCALL;
 
-    gl_info = &wined3d->adapters[adapter_idx].gl_info;
+    if (multisample_type && !(format->multisample_types & 1u << (multisample_type - 1)))
+        hr = WINED3DERR_NOTAVAILABLE;
 
-    if (multisample_type > gl_info->limits.samples)
+    if (SUCCEEDED(hr) || (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE && format->multisample_types))
     {
-        TRACE("Returning not supported.\n");
         if (quality_levels)
-            *quality_levels = 0;
-
-        return WINED3DERR_NOTAVAILABLE;
-    }
-
-    if (quality_levels)
-    {
-        if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
-            *quality_levels = wined3d_log2i(gl_info->limits.samples);
-        else
-            *quality_levels = 1;
+        {
+            if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
+                *quality_levels = wined3d_popcount(format->multisample_types);
+            else
+                *quality_levels = 1;
+        }
+        return WINED3D_OK;
     }
 
-    return WINED3D_OK;
+    TRACE("Returning not supported.\n");
+    return hr;
 }
 
 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 48ff005..145e2c1 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2863,10 +2863,34 @@ static void surface_prepare_rb(struct wined3d_surface *surface, const struct win
          *
          * AMD has a similar feature called Enhanced Quality Anti-Aliasing (EQAA),
          * but it does not have an equivalent OpenGL extension. */
+
+        /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality levels
+         * as the count of advertised multisample types for the surface format. */
         if (surface->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
-            samples = 1u << (surface->resource.multisample_quality + 1);
+        {
+            const struct wined3d_format *format = surface->resource.format;
+            unsigned int i, count = 0;
+
+            for (i = 0; i < sizeof(format->multisample_types) * 8; ++i)
+            {
+                if (format->multisample_types & 1u << i)
+                {
+                    if (surface->resource.multisample_quality == count++)
+                        break;
+                }
+            }
+            if (i == sizeof(format->multisample_types) * 8)
+            {
+                WARN("Unsupported quality level %u requested for WINED3D_MULTISAMPLE_NON_MASKABLE.\n",
+                        surface->resource.multisample_quality);
+                i = 1;
+            }
+            samples = i + 1;
+        }
         else
+        {
             samples = surface->resource.multisample_type;
+        }
 
         gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_multisample);
         gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_multisample);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 28a3216..6c2d08b 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -2162,10 +2162,11 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx)
 
 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
 {
+    GLint count, multisample_types[MAX_MULTISAMPLE_TYPES];
     struct fragment_caps fragment_caps;
     struct shader_caps shader_caps;
     BOOL srgb_write;
-    unsigned int i;
+    unsigned int i, j, max_log2;
 
     adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
     adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
@@ -2284,6 +2285,34 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
             }
         }
 
+        if (format->glInternal && format->flags[WINED3D_GL_RES_TYPE_RB]
+                & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+        {
+            if (gl_info->supported[ARB_INTERNALFORMAT_QUERY])
+            {
+                GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal,
+                        GL_NUM_SAMPLE_COUNTS, 1, &count));
+                checkGLcall("glGetInternalformativ(GL_NUM_SAMPLE_COUNTS)");
+                count = min(count, MAX_MULTISAMPLE_TYPES);
+                GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal,
+                        GL_SAMPLES, count, multisample_types));
+                checkGLcall("glGetInternalformativ(GL_SAMPLES)");
+                for (j = 0; j < count; ++j)
+                {
+                    if (multisample_types[j] > sizeof(format->multisample_types) * 8)
+                        continue;
+                    format->multisample_types |= 1u << (multisample_types[j] - 1);
+                }
+            }
+            else
+            {
+                max_log2 = wined3d_log2i(min(gl_info->limits.samples,
+                        sizeof(format->multisample_types) * 8));
+                for (j = 1; j <= max_log2; ++j)
+                    format->multisample_types |= 1u << ((1u << j) - 1);
+            }
+        }
+
         /* Texture conversion stuff */
         format->convert = format_texture_info[i].convert;
         format->conv_byte_count = format_texture_info[i].conv_byte_count;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 5f91dc4..0287088 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -185,6 +185,7 @@ void wined3d_rb_free(void *ptr) DECLSPEC_HIDDEN;
 #define MAX_SAMPLER_OBJECTS         16
 #define MAX_SHADER_RESOURCE_VIEWS   128
 #define MAX_VERTEX_BLENDS           4
+#define MAX_MULTISAMPLE_TYPES       8
 
 struct min_lookup
 {
@@ -3271,6 +3272,7 @@ struct wined3d_format
     GLint glFormat;
     GLint glType;
     UINT  conv_byte_count;
+    DWORD multisample_types;
     unsigned int flags[WINED3D_GL_RES_TYPE_COUNT];
     struct wined3d_rational height_scale;
     struct color_fixup_desc color_fixup;




More information about the wine-cvs mailing list