Module: wine Branch: master Commit: b1429f931e816feee2f7b7fe065a393c4caa7960 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b1429f931e816feee2f7b7fe06...
Author: Matteo Bruni mbruni@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@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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;