https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d6ac0a71ade77d2496489…
commit d6ac0a71ade77d24964892390956db78bff3531e
Author:     Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Sun Jan 21 22:20:57 2018 +0100
Commit:     Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Sun Jan 21 22:20:57 2018 +0100
    [D3D9][WINED3D] Sync with Wine 3.0. CORE-14225
---
 dll/directx/wine/d3d9/d3d9_private.h          |     3 +-
 dll/directx/wine/d3d9/device.c                |    75 +-
 dll/directx/wine/d3d9/directx.c               |     3 +-
 dll/directx/wine/d3d9/query.c                 |     6 +-
 dll/directx/wine/d3d9/texture.c               |    24 +-
 dll/directx/wine/wined3d/arb_program_shader.c |    30 +-
 dll/directx/wine/wined3d/buffer.c             |    75 +-
 dll/directx/wine/wined3d/context.c            |   222 +-
 dll/directx/wine/wined3d/cs.c                 |   385 +-
 dll/directx/wine/wined3d/device.c             |   227 +-
 dll/directx/wine/wined3d/directx.c            |   185 +-
 dll/directx/wine/wined3d/drawprim.c           |   190 +-
 dll/directx/wine/wined3d/glsl_shader.c        |  1063 ++-
 dll/directx/wine/wined3d/query.c              |   102 +-
 dll/directx/wine/wined3d/resource.c           |   129 +-
 dll/directx/wine/wined3d/sampler.c            |     4 +-
 dll/directx/wine/wined3d/shader.c             |   196 +-
 dll/directx/wine/wined3d/shader_sm4.c         |    17 +-
 dll/directx/wine/wined3d/state.c              |   224 +-
 dll/directx/wine/wined3d/stateblock.c         |    26 +-
 dll/directx/wine/wined3d/surface.c            |   452 +-
 dll/directx/wine/wined3d/swapchain.c          |    13 +-
 dll/directx/wine/wined3d/texture.c            |   686 +-
 dll/directx/wine/wined3d/utils.c              |   562 +-
 dll/directx/wine/wined3d/vertexdeclaration.c  |     9 -
 dll/directx/wine/wined3d/view.c               |   153 +-
 dll/directx/wine/wined3d/wined3d.spec         |    14 +-
 dll/directx/wine/wined3d/wined3d_gl.h         |     6 +-
 dll/directx/wine/wined3d/wined3d_main.c       |    25 +-
 dll/directx/wine/wined3d/wined3d_private.h    |   304 +-
 media/doc/README.WINE                         |     4 +-
 sdk/include/reactos/wine/wgl.h                | 11400 +++++++++++-------------
 sdk/include/reactos/wine/wgl_driver.h         |  5819 ++++++------
 sdk/include/reactos/wine/wined3d.h            |    54 +-
 34 files changed, 10583 insertions(+), 12104 deletions(-)
diff --git a/dll/directx/wine/d3d9/d3d9_private.h b/dll/directx/wine/d3d9/d3d9_private.h
index 2649a5bc96..d34dd73137 100644
--- a/dll/directx/wine/d3d9/d3d9_private.h
+++ b/dll/directx/wine/d3d9/d3d9_private.h
@@ -37,7 +37,6 @@
 #define COBJMACROS
 #include <windef.h>
 #include <winbase.h>
-#include <winuser.h>
 #include <wingdi.h>
 #include <wine/debug.h>
@@ -104,6 +103,8 @@ struct d3d9_device
     BOOL in_scene;
     BOOL has_vertex_declaration;
+    unsigned int max_user_clip_planes;
+
     UINT implicit_swapchain_count;
     struct d3d9_swapchain **implicit_swapchains;
 };
diff --git a/dll/directx/wine/d3d9/device.c b/dll/directx/wine/d3d9/device.c
index 459a24ddf0..b3e085f34d 100644
--- a/dll/directx/wine/d3d9/device.c
+++ b/dll/directx/wine/d3d9/device.c
@@ -22,6 +22,8 @@
 #include "d3d9_private.h"
+#include <winuser.h>
+
 static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {}
 const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops =
@@ -236,8 +238,6 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct
wined3d_swapch
             =
wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat);
     swapchain_desc->flags
             = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) |
WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
-    if (is_gdi_compat_wined3dformat(swapchain_desc->backbuffer_format))
-        swapchain_desc->flags |= WINED3D_SWAPCHAIN_GDI_COMPATIBLE;
     swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
     swapchain_desc->swap_interval = present_parameters->PresentationInterval;
     swapchain_desc->auto_restore_display_mode = TRUE;
@@ -811,11 +811,13 @@ static HRESULT d3d9_device_get_swapchains(struct d3d9_device
*device)
 static HRESULT d3d9_device_reset(struct d3d9_device *device,
         D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode)
 {
+    BOOL extended = device->d3d_parent->extended;
     struct wined3d_swapchain_desc swapchain_desc;
     struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
-    if (!device->d3d_parent->extended && device->device_state ==
D3D9_DEVICE_STATE_LOST)
+
+    if (!extended && device->device_state == D3D9_DEVICE_STATE_LOST)
     {
         WARN("App not active, returning D3DERR_DEVICELOST.\n");
         return D3DERR_DEVICELOST;
@@ -830,8 +832,7 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
         wined3d_mode.scanline_ordering = mode->ScanLineOrdering;
     }
-    if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc,
present_parameters,
-            device->d3d_parent->extended))
+    if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc,
present_parameters, extended))
         return D3DERR_INVALIDCALL;
     wined3d_mutex_lock();
@@ -851,10 +852,16 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
     }
     if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device,
&swapchain_desc,
-            mode ? &wined3d_mode : NULL, reset_enum_callback,
!device->d3d_parent->extended)))
+            mode ? &wined3d_mode : NULL, reset_enum_callback, !extended)))
     {
         HeapFree(GetProcessHeap(), 0, device->implicit_swapchains);
+        if (!extended)
+        {
+            wined3d_device_set_render_state(device->wined3d_device,
WINED3D_RS_ZENABLE,
+                    !!swapchain_desc.enable_auto_depth_stencil);
+        }
+
         if (FAILED(hr = d3d9_device_get_swapchains(device)))
         {
             device->device_state = D3D9_DEVICE_STATE_NOT_RESET;
@@ -870,7 +877,7 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
             device->device_state = D3D9_DEVICE_STATE_OK;
         }
     }
-    else if (!device->d3d_parent->extended)
+    else if (!extended)
     {
         device->device_state = D3D9_DEVICE_STATE_NOT_RESET;
     }
@@ -1392,20 +1399,35 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex
*iface,
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
     struct d3d9_surface *src = unsafe_impl_from_IDirect3DSurface9(src_surface);
     struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+    struct wined3d_sub_resource_desc src_desc, dst_desc;
     struct wined3d_box src_box;
     HRESULT hr;
     TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point
%p.\n",
             iface, src_surface, src_rect, dst_surface, dst_point);
+    wined3d_mutex_lock();
+
+    wined3d_texture_get_sub_resource_desc(src->wined3d_texture,
src->sub_resource_idx, &src_desc);
+    wined3d_texture_get_sub_resource_desc(dst->wined3d_texture,
dst->sub_resource_idx, &dst_desc);
+    if (src_desc.format != dst_desc.format)
+    {
+        wined3d_mutex_unlock();
+        WARN("Surface formats (%#x/%#x) don't match.\n",
+                d3dformat_from_wined3dformat(src_desc.format),
+                d3dformat_from_wined3dformat(dst_desc.format));
+        return D3DERR_INVALIDCALL;
+    }
+
     if (src_rect)
         wined3d_box_set(&src_box, src_rect->left, src_rect->top,
src_rect->right, src_rect->bottom, 0, 1);
+    else
+        wined3d_box_set(&src_box, 0, 0, src_desc.width, src_desc.height, 0, 1);
-    wined3d_mutex_lock();
     hr = wined3d_device_copy_sub_resource_region(device->wined3d_device,
             wined3d_texture_get_resource(dst->wined3d_texture),
dst->sub_resource_idx, dst_point ? dst_point->x : 0,
             dst_point ? dst_point->y : 0, 0,
wined3d_texture_get_resource(src->wined3d_texture),
-            src->sub_resource_idx, src_rect ? &src_box : NULL);
+            src->sub_resource_idx, &src_box);
     wined3d_mutex_unlock();
     if (FAILED(hr))
@@ -2014,6 +2036,8 @@ static HRESULT WINAPI d3d9_device_SetClipPlane(IDirect3DDevice9Ex
*iface, DWORD
     TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);
+    index = min(index, device->max_user_clip_planes - 1);
+
     wined3d_mutex_lock();
     hr = wined3d_device_set_clip_plane(device->wined3d_device, index, (const struct
wined3d_vec4 *)plane);
     wined3d_mutex_unlock();
@@ -2028,6 +2052,8 @@ static HRESULT WINAPI d3d9_device_GetClipPlane(IDirect3DDevice9Ex
*iface, DWORD
     TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);
+    index = min(index, device->max_user_clip_planes - 1);
+
     wined3d_mutex_lock();
     hr = wined3d_device_get_clip_plane(device->wined3d_device, index, (struct
wined3d_vec4 *)plane);
     wined3d_mutex_unlock();
@@ -3547,9 +3573,12 @@ static HRESULT WINAPI
d3d9_device_CheckResourceResidency(IDirect3DDevice9Ex *ifa
 static HRESULT WINAPI d3d9_device_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT
max_latency)
 {
-    FIXME("iface %p, max_latency %u stub!\n", iface, max_latency);
+    TRACE("iface %p, max_latency %u.\n", iface, max_latency);
-    return E_NOTIMPL;
+    if (max_latency)
+        FIXME("Ignoring max_latency %u.\n", max_latency);
+
+    return S_OK;
 }
 static HRESULT WINAPI d3d9_device_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT
*max_latency)
@@ -3919,6 +3948,9 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct
wined3d_devic
     if (container_parent == device_parent)
         container_parent = &device->IDirect3DDevice9Ex_iface;
+    if (is_gdi_compat_wined3dformat(desc->format))
+        texture_flags |= WINED3D_TEXTURE_CREATE_GET_DC;
+
     if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1,
             texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, container_parent,
             &d3d9_null_wined3d_parent_ops, texture)))
@@ -3990,7 +4022,8 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent,
struct wine
         D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode)
 {
     struct wined3d_swapchain_desc *swapchain_desc;
-    UINT i, count = 1;
+    unsigned i, count = 1;
+    WINED3DCAPS caps;
     HRESULT hr;
     if (mode)
@@ -4003,22 +4036,18 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9
*parent, struct wine
     if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
     wined3d_mutex_lock();
-    hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
-            &device->device_parent, &device->wined3d_device);
-    if (FAILED(hr))
+    if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type, focus_window,
flags, 4,
+            &device->device_parent, &device->wined3d_device)))
     {
         WARN("Failed to create wined3d device, hr %#x.\n", hr);
         wined3d_mutex_unlock();
         return hr;
     }
+    wined3d_get_device_caps(wined3d, adapter, device_type, &caps);
+    device->max_user_clip_planes = caps.MaxUserClipPlanes;
     if (flags & D3DCREATE_ADAPTERGROUP_DEVICE)
-    {
-        WINED3DCAPS caps;
-
-        wined3d_get_device_caps(wined3d, adapter, device_type, &caps);
         count = caps.NumberOfAdaptersInGroup;
-    }
     if (flags & D3DCREATE_MULTITHREADED)
         wined3d_device_set_multithreaded(device->wined3d_device);
@@ -4069,8 +4098,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent,
struct wine
         }
     }
-    hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc);
-    if (FAILED(hr))
+    if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc)))
     {
         WARN("Failed to initialize 3D, hr %#x.\n", hr);
         wined3d_device_release_focus_window(device->wined3d_device);
@@ -4080,6 +4108,9 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent,
struct wine
         return hr;
     }
+    wined3d_device_set_render_state(device->wined3d_device,
+            WINED3D_RS_ZENABLE, !!swapchain_desc->enable_auto_depth_stencil);
+
     if (FAILED(hr = d3d9_device_get_swapchains(device)))
     {
         wined3d_device_uninit_3d(device->wined3d_device);
diff --git a/dll/directx/wine/d3d9/directx.c b/dll/directx/wine/d3d9/directx.c
index 9eec0abeca..ab153a9030 100644
--- a/dll/directx/wine/d3d9/directx.c
+++ b/dll/directx/wine/d3d9/directx.c
@@ -577,7 +577,8 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
 {
     DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE |
WINED3D_PIXEL_CENTER_INTEGER
             | WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR
-            | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING |
WINED3D_LIMIT_VIEWPORT;
+            | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING
+            | WINED3D_NORMALIZED_DEPTH_BIAS;
     if (!extended)
         flags |= WINED3D_VIDMEM_ACCOUNTING;
diff --git a/dll/directx/wine/d3d9/query.c b/dll/directx/wine/d3d9/query.c
index 90187566bd..8681502c49 100644
--- a/dll/directx/wine/d3d9/query.c
+++ b/dll/directx/wine/d3d9/query.c
@@ -184,7 +184,11 @@ HRESULT query_init(struct d3d9_query *query, struct d3d9_device
*device, D3DQUER
     if (type > D3DQUERYTYPE_MEMORYPRESSURE)
     {
-        WARN("Invalid query type %#x.\n", type);
+        if (type == 0x16)
+            FIXME("Undocumented query %#x created.\n", type);
+        else
+            WARN("Invalid query type %#x.\n", type);
+
         return D3DERR_NOTAVAILABLE;
     }
diff --git a/dll/directx/wine/d3d9/texture.c b/dll/directx/wine/d3d9/texture.c
index 5e9979a4ce..16909d6888 100644
--- a/dll/directx/wine/d3d9/texture.c
+++ b/dll/directx/wine/d3d9/texture.c
@@ -22,17 +22,17 @@
 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
 {
-    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture,
IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9
*iface)
 {
-    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture,
IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 static inline struct d3d9_texture
*impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
 {
-    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture,
IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID
riid, void **out)
@@ -270,13 +270,7 @@ static D3DTEXTUREFILTERTYPE WINAPI
d3d9_texture_2d_GetAutoGenFilterType(IDirect3
 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
 {
-    struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-
     TRACE("iface %p.\n", iface);
-
-    wined3d_mutex_lock();
-    wined3d_texture_generate_mipmaps(texture->wined3d_texture);
-    wined3d_mutex_unlock();
 }
 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level,
D3DSURFACE_DESC *desc)
@@ -655,13 +649,7 @@ static D3DTEXTUREFILTERTYPE WINAPI
d3d9_texture_cube_GetAutoGenFilterType(IDirec
 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
 {
-    struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-
     TRACE("iface %p.\n", iface);
-
-    wined3d_mutex_lock();
-    wined3d_texture_generate_mipmaps(texture->wined3d_texture);
-    wined3d_mutex_unlock();
 }
 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT
level, D3DSURFACE_DESC *desc)
@@ -1052,13 +1040,7 @@ static D3DTEXTUREFILTERTYPE WINAPI
d3d9_texture_3d_GetAutoGenFilterType(IDirect3
 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
 {
-    struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-
     TRACE("iface %p.\n", iface);
-
-    wined3d_mutex_lock();
-    wined3d_texture_generate_mipmaps(texture->wined3d_texture);
-    wined3d_mutex_unlock();
 }
 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT
level, D3DVOLUME_DESC *desc)
diff --git a/dll/directx/wine/wined3d/arb_program_shader.c
b/dll/directx/wine/wined3d/arb_program_shader.c
index ba5ccb38ca..00a260f21d 100644
--- a/dll/directx/wine/wined3d/arb_program_shader.c
+++ b/dll/directx/wine/wined3d/arb_program_shader.c
@@ -872,7 +872,7 @@ static void shader_generate_arb_declarations(const struct
wined3d_shader *shader
     /* After subtracting privately used constants from the hardware limit(they are loaded
as
      * local constants), make sure the shader doesn't violate the env constant limit
      */
-    if(pshader)
+    if (pshader)
     {
         max_constantsF = min(max_constantsF, gl_info->limits.arb_ps_float_constants);
     }
@@ -900,10 +900,7 @@ static void shader_generate_arb_declarations(const struct
wined3d_shader *shader
     {
         for (i = 0; i < max_constantsF; ++i)
         {
-            DWORD idx, mask;
-            idx = i >> 5;
-            mask = 1u << (i & 0x1fu);
-            if (!shader_constant_is_local(shader, i) && (reg_maps->constf[idx]
& mask))
+            if (!shader_constant_is_local(shader, i) &&
wined3d_extract_bits(reg_maps->constf, i, 1))
             {
                 shader_addline(buffer, "PARAM C%d = program.env[%d];\n",i, i);
             }
@@ -1188,8 +1185,6 @@ static void shader_arb_get_register_name(const struct
wined3d_shader_instruction
                 sprintf(register_name, "%s",
rastout_reg_names[reg->idx[0].offset]);
             break;
-        case WINED3DSPR_DEPTHOUT_GREATER_EQUAL:
-        case WINED3DSPR_DEPTHOUT_LESS_EQUAL:
         case WINED3DSPR_DEPTHOUT:
             strcpy(register_name, "result.depth");
             break;
@@ -4490,7 +4485,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state
*state,
     int i;
     WORD int_skip;
-    find_vs_compile_args(state, shader, context->stream_info.swizzle_map,
&args->super, d3d_info);
+    find_vs_compile_args(state, shader, context->stream_info.swizzle_map,
&args->super, context);
     args->clip.boolclip_compare = 0;
     if (use_ps(state))
@@ -5089,6 +5084,7 @@ static const SHADER_HANDLER
shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_DSY                              */ shader_hw_dsy,
     /* WINED3DSIH_DSY_COARSE                       */ NULL,
     /* WINED3DSIH_DSY_FINE                         */ NULL,
+    /* WINED3DSIH_EVAL_SAMPLE_INDEX                */ NULL,
     /* WINED3DSIH_ELSE                             */ shader_hw_else,
     /* WINED3DSIH_EMIT                             */ NULL,
     /* WINED3DSIH_EMIT_STREAM                      */ NULL,
@@ -7705,6 +7701,14 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info
*gl_info,
     if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
         return FALSE;
+    if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id ==
src_format->id)
+    {
+        if (dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL))
+            blit_op = WINED3D_BLIT_OP_DEPTH_BLIT;
+        else
+            blit_op = WINED3D_BLIT_OP_COLOR_BLIT;
+    }
+
     switch (blit_op)
     {
         case WINED3D_BLIT_OP_COLOR_BLIT_CKEY:
@@ -7778,7 +7782,7 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info
*gl_info,
     }
 }
-static void arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
+static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
         struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD
src_location,
         const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location,
const RECT *dst_rect,
         const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type
filter)
@@ -7796,9 +7800,8 @@ static void arbfp_blitter_blit(struct wined3d_blitter *blitter, enum
wined3d_bli
             dst_texture->resource.pool, dst_texture->resource.format,
dst_location))
     {
         if ((next = blitter->next))
-            next->ops->blitter_blit(next, op, context, src_surface, src_location,
+            return next->ops->blitter_blit(next, op, context, src_surface,
src_location,
                     src_rect, dst_surface, dst_location, dst_rect, color_key, filter);
-        return;
     }
     arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter);
@@ -7873,6 +7876,8 @@ static void arbfp_blitter_blit(struct wined3d_blitter *blitter, enum
wined3d_bli
     if (wined3d_settings.strict_draw_ordering
             || (dst_texture->swapchain &&
(dst_texture->swapchain->front_buffer == dst_texture)))
         context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across
contexts. */
+
+    return dst_location;
 }
 static void arbfp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device
*device,
@@ -7905,6 +7910,9 @@ void wined3d_arbfp_blitter_create(struct wined3d_blitter **next,
const struct wi
     if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
         return;
+    if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+        return;
+
     if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
     {
         ERR("Failed to allocate blitter.\n");
diff --git a/dll/directx/wine/wined3d/buffer.c b/dll/directx/wine/wined3d/buffer.c
index 02d081d938..0e8f5a3e01 100644
--- a/dll/directx/wine/wined3d/buffer.c
+++ b/dll/directx/wine/wined3d/buffer.c
@@ -529,7 +529,7 @@ ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer)
 /* Context activation is done by the caller. */
 static void wined3d_buffer_upload_ranges(struct wined3d_buffer *buffer, struct
wined3d_context *context,
-        const void *data, unsigned int range_count, const struct wined3d_map_range
*ranges)
+        const void *data, unsigned int data_offset, unsigned int range_count, const
struct wined3d_map_range *ranges)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_map_range *range;
@@ -540,7 +540,7 @@ static void wined3d_buffer_upload_ranges(struct wined3d_buffer
*buffer, struct w
     {
         range = &ranges[range_count];
         GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint,
-                range->offset, range->size, (BYTE *)data + range->offset));
+                range->offset, range->size, (BYTE *)data + range->offset -
data_offset));
     }
     checkGLcall("glBufferSubData");
 }
@@ -596,7 +596,7 @@ static void buffer_conversion_upload(struct wined3d_buffer *buffer,
struct wined
         }
     }
-    wined3d_buffer_upload_ranges(buffer, context, data, buffer->modified_areas,
buffer->maps);
+    wined3d_buffer_upload_ranges(buffer, context, data, 0, buffer->modified_areas,
buffer->maps);
     HeapFree(GetProcessHeap(), 0, data);
 }
@@ -680,7 +680,7 @@ BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
         case WINED3D_LOCATION_BUFFER:
             if (!buffer->conversion_map)
                 wined3d_buffer_upload_ranges(buffer, context,
buffer->resource.heap_memory,
-                        buffer->modified_areas, buffer->maps);
+                        0, buffer->modified_areas, buffer->maps);
             else
                 buffer_conversion_upload(buffer, context);
             break;
@@ -1212,41 +1212,23 @@ void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer,
unsigned int dst_off
     wined3d_buffer_invalidate_range(dst_buffer, ~dst_location, dst_offset, size);
 }
-HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer,
+void wined3d_buffer_upload_data(struct wined3d_buffer *buffer, struct wined3d_context
*context,
         const struct wined3d_box *box, const void *data)
 {
-    UINT offset, size;
-#if defined(STAGING_CSMT)
-    DWORD flags = 0;
-#endif /* STAGING_CSMT */
-    HRESULT hr;
-    BYTE *ptr;
+    struct wined3d_map_range range;
     if (box)
     {
-        offset = box->left;
-        size = box->right - box->left;
+        range.offset = box->left;
+        range.size = box->right - box->left;
     }
     else
     {
-        offset = 0;
-        size = buffer->resource.size;
+        range.offset = 0;
+        range.size = buffer->resource.size;
     }
-#if !defined(STAGING_CSMT)
-    if (FAILED(hr = wined3d_buffer_map(buffer, offset, size, &ptr, 0)))
-#else  /* STAGING_CSMT */
-    if (offset == 0 && size == buffer->resource.size)
-        flags = WINED3D_MAP_DISCARD;
-
-    if (FAILED(hr = wined3d_buffer_map(buffer, offset, size, &ptr, flags)))
-#endif /* STAGING_CSMT */
-        return hr;
-
-    memcpy(ptr, data, size);
-
-    wined3d_buffer_unmap(buffer);
-    return WINED3D_OK;
+    wined3d_buffer_upload_ranges(buffer, context, data, range.offset, 1, &range);
 }
 static ULONG buffer_resource_incref(struct wined3d_resource *resource)
@@ -1294,24 +1276,6 @@ static HRESULT buffer_resource_sub_resource_map(struct
wined3d_resource *resourc
     return wined3d_buffer_map(buffer, offset, size, (BYTE **)&map_desc->data,
flags);
 }
-static HRESULT buffer_resource_sub_resource_map_info(struct wined3d_resource *resource,
unsigned int sub_resource_idx,
-        struct wined3d_map_info *info, DWORD flags)
-{
-    struct wined3d_buffer *buffer = buffer_from_resource(resource);
-
-    if (sub_resource_idx)
-    {
-        WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
-        return E_INVALIDARG;
-    }
-
-    info->row_pitch   = buffer->desc.byte_width;
-    info->slice_pitch = buffer->desc.byte_width;
-    info->size        = buffer->resource.size;
-
-    return WINED3D_OK;
-}
-
 static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource,
unsigned int sub_resource_idx)
 {
     if (sub_resource_idx)
@@ -1331,7 +1295,6 @@ static const struct wined3d_resource_ops buffer_resource_ops =
     buffer_resource_preload,
     buffer_unload,
     buffer_resource_sub_resource_map,
-    buffer_resource_sub_resource_map_info,
     buffer_resource_sub_resource_unmap,
 };
@@ -1452,7 +1415,6 @@ HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device,
const struct
         struct wined3d_buffer **buffer)
 {
     struct wined3d_buffer *object;
-    enum wined3d_pool pool;
     HRESULT hr;
     TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer
%p.\n",
@@ -1463,21 +1425,8 @@ HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device,
const struct
     FIXME("Ignoring access flags (pool).\n");
-    /* Some applications map the whole buffer even if they
-     * only update a small portion of it. If we pin such a
-     * buffer into system memory things get very slow as
-     * we upload the whole buffer even though just parts of
-     * it changed. Most drivers can handle this case more
-     * efficient using the OpenGL map functions. Applications
-     * affected by this problem are Banished and Witcher 3.
-     */
-    if (desc->byte_width > 0x10000)
-        pool = WINED3D_POOL_DEFAULT;
-    else
-        pool = WINED3D_POOL_MANAGED;
-
     if (FAILED(hr = buffer_init(object, device, desc->byte_width, desc->usage,
WINED3DFMT_UNKNOWN,
-            pool, desc->bind_flags, data, parent, parent_ops)))
+            WINED3D_POOL_MANAGED, desc->bind_flags, data, parent, parent_ops)))
     {
         WARN("Failed to initialize buffer, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c
index 80164c0011..bd0ae564fb 100644
--- a/dll/directx/wine/wined3d/context.c
+++ b/dll/directx/wine/wined3d/context.c
@@ -131,8 +131,7 @@ static void context_attach_gl_texture_fbo(struct wined3d_context
*context,
         gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment,
                 resource->object, resource->level);
     }
-    else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target ==
GL_TEXTURE_2D_ARRAY ||
-            resource->target == GL_TEXTURE_3D)
+    else if (resource->target == GL_TEXTURE_2D_ARRAY || resource->target ==
GL_TEXTURE_3D)
     {
         if (!gl_info->fbo_ops.glFramebufferTextureLayer)
         {
@@ -143,12 +142,6 @@ static void context_attach_gl_texture_fbo(struct wined3d_context
*context,
         gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment,
                 resource->object, resource->level, resource->layer);
     }
-    else if (resource->target == GL_TEXTURE_1D)
-    {
-        gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment,
-                resource->target, resource->object, resource->level);
-        checkGLcall("glFramebufferTexture1D()");
-    }
     else
     {
         gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment,
@@ -288,7 +281,7 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info
*gl_info, G
             unsigned int i;
             tex_type_str = NULL;
-            for (i = 0; i < sizeof(texture_type) / sizeof(*texture_type); ++i)
+            for (i = 0; i < ARRAY_SIZE(texture_type); ++i)
             {
                 if (!gl_info->supported[texture_type[i].extension])
                     continue;
@@ -1706,7 +1699,6 @@ void context_bind_dummy_textures(const struct wined3d_device
*device, const stru
         GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i));
         checkGLcall("glActiveTexture");
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D,
device->dummy_textures.tex_1d);
         gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D,
device->dummy_textures.tex_2d);
         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
@@ -1722,10 +1714,7 @@ void context_bind_dummy_textures(const struct wined3d_device
*device, const stru
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY,
device->dummy_textures.tex_cube_array);
         if (gl_info->supported[EXT_TEXTURE_ARRAY])
-        {
-            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY,
device->dummy_textures.tex_1d_array);
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY,
device->dummy_textures.tex_2d_array);
-        }
         if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER,
device->dummy_textures.tex_buffer);
@@ -2326,10 +2315,13 @@ static void set_blit_dimension(const struct wined3d_gl_info
*gl_info, UINT width
                -1.0,         -1.0, -1.0, 1.0,
     };
-    gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
-    checkGLcall("glMatrixMode(GL_PROJECTION)");
-    gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
-    checkGLcall("glLoadMatrixd");
+    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+    {
+        gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+        checkGLcall("glMatrixMode(GL_PROJECTION)");
+        gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
+        checkGLcall("glLoadMatrixd");
+    }
     gl_info->gl_ops.gl.p_glViewport(0, 0, width, height);
     checkGLcall("glViewport");
 }
@@ -2355,6 +2347,33 @@ static void context_get_rt_size(const struct wined3d_context
*context, SIZE *siz
     size->cy = wined3d_texture_get_level_height(rt, level);
 }
+void context_enable_clip_distances(struct wined3d_context *context, unsigned int
enable_mask)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned int clip_distance_count = gl_info->limits.user_clip_distances;
+    unsigned int i, disable_mask, current_mask;
+
+    disable_mask = ~enable_mask;
+    enable_mask &= (1u << clip_distance_count) - 1;
+    disable_mask &= (1u << clip_distance_count) - 1;
+    current_mask = context->clip_distance_mask;
+    context->clip_distance_mask = enable_mask;
+
+    enable_mask &= ~current_mask;
+    for (i = 0; enable_mask; enable_mask >>= 1, ++i)
+    {
+        if (enable_mask & 1)
+            gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i);
+    }
+    disable_mask &= current_mask;
+    for (i = 0; disable_mask; disable_mask >>= 1, ++i)
+    {
+        if (disable_mask & 1)
+            gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
+    }
+    checkGLcall("toggle clip distances");
+}
+
 /*****************************************************************************
  * SetupForBlit
  *
@@ -2374,10 +2393,10 @@ static void context_get_rt_size(const struct wined3d_context
*context, SIZE *siz
 /* Context activation is done by the caller. */
 static void SetupForBlit(const struct wined3d_device *device, struct wined3d_context
*context)
 {
-    int i;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     DWORD sampler;
     SIZE rt_size;
+    int i;
     TRACE("Setting up context %p for blitting\n", context);
@@ -2398,17 +2417,46 @@ static void SetupForBlit(const struct wined3d_device *device,
struct wined3d_con
     }
     context->last_was_blit = TRUE;
-    /* Disable all textures. The caller can then bind a texture it wants to blit
-     * from
-     *
-     * The blitting code uses (for now) the fixed function pipeline, so make sure to
reset all fixed
-     * function texture unit. No need to care for higher samplers
-     */
-    for (i = gl_info->limits.textures - 1; i > 0 ; --i)
+    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
     {
-        sampler = context->rev_tex_unit_map[i];
-        context_active_texture(context, gl_info, i);
+        /* Disable all textures. The caller can then bind a texture it wants to blit
+         * from
+         *
+         * The blitting code uses (for now) the fixed function pipeline, so make sure to
reset all fixed
+         * function texture unit. No need to care for higher samplers
+         */
+        for (i = gl_info->limits.textures - 1; i > 0 ; --i)
+        {
+            sampler = context->rev_tex_unit_map[i];
+            context_active_texture(context, gl_info, i);
+
+            if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+            {
+                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+                checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
+            }
+            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+            checkGLcall("glDisable GL_TEXTURE_3D");
+            if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+            {
+                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+                checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
+            }
+            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+            checkGLcall("glDisable GL_TEXTURE_2D");
+            gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_REPLACE);
+            checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_REPLACE);");
+
+            if (sampler != WINED3D_UNMAPPED_STAGE)
+            {
+                if (sampler < MAX_TEXTURES)
+                    context_invalidate_state(context, STATE_TEXTURESTAGE(sampler,
WINED3D_TSS_COLOR_OP));
+                context_invalidate_state(context, STATE_SAMPLER(sampler));
+            }
+        }
+
+        context_active_texture(context, gl_info, 0);
         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
         {
             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
@@ -2425,50 +2473,43 @@ static void SetupForBlit(const struct wined3d_device *device,
struct wined3d_con
         checkGLcall("glDisable GL_TEXTURE_2D");
         gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_REPLACE);
-        checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_REPLACE);");
-        if (sampler != WINED3D_UNMAPPED_STAGE)
+        gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
+        checkGLcall("glMatrixMode(GL_TEXTURE)");
+        gl_info->gl_ops.gl.p_glLoadIdentity();
+        checkGLcall("glLoadIdentity()");
+
+        if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
         {
-            if (sampler < MAX_TEXTURES)
-                context_invalidate_state(context, STATE_TEXTURESTAGE(sampler,
WINED3D_TSS_COLOR_OP));
-            context_invalidate_state(context, STATE_SAMPLER(sampler));
+            gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
+                    GL_TEXTURE_LOD_BIAS_EXT, 0.0f);
+            checkGLcall("glTexEnvf GL_TEXTURE_LOD_BIAS_EXT ...");
         }
+
+        /* Setup transforms */
+        gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+        checkGLcall("glMatrixMode(GL_MODELVIEW)");
+        gl_info->gl_ops.gl.p_glLoadIdentity();
+        checkGLcall("glLoadIdentity()");
+        context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+
+        /* Other misc states */
+        gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+        checkGLcall("glDisable(GL_ALPHA_TEST)");
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
+        gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+        checkGLcall("glDisable GL_LIGHTING");
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING));
+        glDisableWINE(GL_FOG);
+        checkGLcall("glDisable GL_FOG");
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
     }
+
     if (gl_info->supported[ARB_SAMPLER_OBJECTS])
         GL_EXTCALL(glBindSampler(0, 0));
     context_active_texture(context, gl_info, 0);
     sampler = context->rev_tex_unit_map[0];
-
-    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
-    {
-        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-        checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
-    }
-    gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
-    checkGLcall("glDisable GL_TEXTURE_3D");
-    if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
-    {
-        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
-        checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
-    }
-    gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
-    checkGLcall("glDisable GL_TEXTURE_2D");
-
-    gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-    gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
-    checkGLcall("glMatrixMode(GL_TEXTURE)");
-    gl_info->gl_ops.gl.p_glLoadIdentity();
-    checkGLcall("glLoadIdentity()");
-
-    if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
-    {
-        gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
-                GL_TEXTURE_LOD_BIAS_EXT, 0.0f);
-        checkGLcall("glTexEnvf GL_TEXTURE_LOD_BIAS_EXT ...");
-    }
-
     if (sampler != WINED3D_UNMAPPED_STAGE)
     {
         if (sampler < MAX_TEXTURES)
@@ -2480,18 +2521,9 @@ static void SetupForBlit(const struct wined3d_device *device,
struct wined3d_con
     }
     /* Other misc states */
-    gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
-    checkGLcall("glDisable(GL_ALPHA_TEST)");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
-    gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
-    checkGLcall("glDisable GL_LIGHTING");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING));
     gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
     checkGLcall("glDisable GL_DEPTH_TEST");
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
-    glDisableWINE(GL_FOG);
-    checkGLcall("glDisable GL_FOG");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
     gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
     checkGLcall("glDisable GL_BLEND");
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
@@ -2512,8 +2544,10 @@ static void SetupForBlit(const struct wined3d_device *device,
struct wined3d_con
     }
     gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
     checkGLcall("glColorMask");
-    for (i = 0; i < MAX_RENDER_TARGETS; ++i)
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
     if (gl_info->supported[EXT_SECONDARY_COLOR])
     {
         gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
@@ -2521,22 +2555,10 @@ static void SetupForBlit(const struct wined3d_device *device,
struct wined3d_con
         checkGLcall("glDisable(GL_COLOR_SUM_EXT)");
     }
-    /* Setup transforms */
-    gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
-    checkGLcall("glMatrixMode(GL_MODELVIEW)");
-    gl_info->gl_ops.gl.p_glLoadIdentity();
-    checkGLcall("glLoadIdentity()");
-    context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
-
     context->last_was_rhw = TRUE;
     context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
-    gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip
plane 0)");
-    gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip
plane 1)");
-    gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip
plane 2)");
-    gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip
plane 3)");
-    gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip
plane 4)");
-    gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip
plane 5)");
+    context_enable_clip_distances(context, 0);
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
     /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */
@@ -2673,14 +2695,6 @@ void context_bind_texture(struct wined3d_context *context, GLenum
target, GLuint
             case GL_NONE:
                 /* nothing to do */
                 break;
-            case GL_TEXTURE_1D:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D,
device->dummy_textures.tex_1d);
-                checkGLcall("glBindTexture");
-                break;
-            case GL_TEXTURE_1D_ARRAY:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY,
device->dummy_textures.tex_1d_array);
-                checkGLcall("glBindTexture");
-                break;
             case GL_TEXTURE_2D:
                 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D,
device->dummy_textures.tex_2d);
                 checkGLcall("glBindTexture");
@@ -3086,16 +3100,8 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context
*context, const
     else if (!context->render_offscreen)
         return context_generate_rt_mask_from_resource(rts[0]->resource);
-    /* If we attach more buffers than supported in dual blend mode, the NVIDIA
-     * driver generates the following error:
-     *      GL_INVALID_OPERATION error generated. State(s) are invalid: blend.
-     * DX11 does not treat this configuration as invalid, so disable the unused ones.
-     */
     rt_mask = ps ? ps->reg_maps.rt_mask : 1;
-    if (wined3d_dualblend_enabled(state, context->gl_info))
-        rt_mask &= context->d3d_info->valid_dual_rt_mask;
-    else
-        rt_mask &= context->d3d_info->valid_rt_mask;
+    rt_mask &= context->d3d_info->valid_rt_mask;
     rt_mask_bits = rt_mask;
     i = 0;
     while (rt_mask_bits)
@@ -4008,6 +4014,16 @@ void context_apply_compute_state(struct wined3d_context *context,
         context->update_unordered_access_view_bindings = 1;
     }
+    /* Updates to currently bound render targets aren't necessarily coherent
+     * between the graphics and compute pipelines. Unbind any currently bound
+     * FBO here to ensure preceding updates to its attachments by the graphics
+     * pipeline are visible to the compute pipeline.
+     *
+     * Without this, the bloom effect in Nier:Automata is too bright on the
+     * Mesa radeonsi driver, and presumably on other Mesa based drivers. */
+    context_bind_fbo(context, GL_FRAMEBUFFER, 0);
+    context_invalidate_state(context, STATE_FRAMEBUFFER);
+
     context->last_was_blit = FALSE;
 }
diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c
index 2ef67aaade..d264d1c940 100644
--- a/dll/directx/wine/wined3d/cs.c
+++ b/dll/directx/wine/wined3d/cs.c
@@ -69,7 +69,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION,
     WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW,
     WINED3D_CS_OP_COPY_UAV_COUNTER,
-    WINED3D_CS_OP_COPY_SUB_RESOURCE,
+    WINED3D_CS_OP_GENERATE_MIPMAPS,
     WINED3D_CS_OP_STOP,
 };
@@ -396,9 +396,6 @@ struct wined3d_cs_update_sub_resource
     unsigned int sub_resource_idx;
     struct wined3d_box box;
     struct wined3d_sub_resource_data data;
-#if defined(STAGING_CSMT)
-    BYTE copy_data[1];
-#endif /* STAGING_CSMT */
 };
 struct wined3d_cs_add_dirty_texture_region
@@ -423,15 +420,10 @@ struct wined3d_cs_copy_uav_counter
     struct wined3d_unordered_access_view *view;
 };
-struct wined3d_cs_copy_sub_resource
+struct wined3d_cs_generate_mipmaps
 {
     enum wined3d_cs_op opcode;
-    struct wined3d_resource *dst_resource;
-    unsigned int dst_sub_resource_idx;
-    struct wined3d_box dst_box;
-    struct wined3d_resource *src_resource;
-    unsigned int src_sub_resource_idx;
-    struct wined3d_box src_box;
+    struct wined3d_shader_resource_view *view;
 };
 struct wined3d_cs_stop
@@ -766,10 +758,24 @@ void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs,
 static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
 {
+    const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
     struct wined3d_state *state = &cs->state;
     const struct wined3d_cs_draw *op = data;
+    int load_base_vertex_idx;
     unsigned int i;
+    /* ARB_draw_indirect always supports a base vertex offset. */
+    if (!op->parameters.indirect &&
!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
+        load_base_vertex_idx = op->parameters.u.direct.base_vertex_idx;
+    else
+        load_base_vertex_idx = 0;
+
+    if (state->load_base_vertex_index != load_base_vertex_idx)
+    {
+        state->load_base_vertex_index = load_base_vertex_idx;
+        device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX);
+    }
+
     if (state->gl_primitive_type != op->primitive_type)
     {
         if (state->gl_primitive_type == GL_POINTS || op->primitive_type ==
GL_POINTS)
@@ -778,26 +784,14 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void
*data)
     }
     state->gl_patch_vertices = op->patch_vertex_count;
-    if (!op->parameters.indirect)
-    {
-        const struct wined3d_direct_draw_parameters *p = &op->parameters.u.direct;
-
-        if
(!cs->device->adapter->gl_info.supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]
-                && state->load_base_vertex_index != p->base_vertex_idx)
-        {
-            state->load_base_vertex_index = p->base_vertex_idx;
-            device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX);
-        }
-    }
-
     draw_primitive(cs->device, state, &op->parameters);
     if (op->parameters.indirect)
     {
-        const struct wined3d_indirect_draw_parameters *p =
&op->parameters.u.indirect;
-
-        wined3d_resource_release(&p->buffer->resource);
+        struct wined3d_buffer *buffer = op->parameters.u.indirect.buffer;
+        wined3d_resource_release(&buffer->resource);
     }
+
     if (op->parameters.indexed)
         wined3d_resource_release(&state->index_buffer->resource);
     for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
@@ -815,7 +809,7 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void
*data)
         if (state->textures[i])
             wined3d_resource_release(&state->textures[i]->resource);
     }
-    for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
+    for (i = 0; i < gl_info->limits.buffers; ++i)
     {
         if (state->fb->render_targets[i])
             wined3d_resource_release(state->fb->render_targets[i]->resource);
@@ -827,26 +821,11 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void
*data)
             state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]);
 }
-void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int
patch_vertex_count,
-        int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
-        unsigned int start_instance, unsigned int instance_count, BOOL indexed)
+static void acquire_graphics_pipeline_resources(const struct wined3d_state *state,
+        BOOL indexed, const struct wined3d_gl_info *gl_info)
 {
-    const struct wined3d_state *state = &cs->device->state;
-    struct wined3d_cs_draw *op;
     unsigned int i;
-    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
-    op->opcode = WINED3D_CS_OP_DRAW;
-    op->primitive_type = primitive_type;
-    op->patch_vertex_count = patch_vertex_count;
-    op->parameters.indirect = FALSE;
-    op->parameters.u.direct.base_vertex_idx = base_vertex_idx;
-    op->parameters.u.direct.start_idx = start_idx;
-    op->parameters.u.direct.index_count = index_count;
-    op->parameters.u.direct.start_instance = start_instance;
-    op->parameters.u.direct.instance_count = instance_count;
-    op->parameters.indexed = indexed;
-
     if (indexed)
         wined3d_resource_acquire(&state->index_buffer->resource);
     for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
@@ -864,7 +843,7 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum
primitive_type, unsigned
         if (state->textures[i])
             wined3d_resource_acquire(&state->textures[i]->resource);
     }
-    for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
+    for (i = 0; i < gl_info->limits.buffers; ++i)
     {
         if (state->fb->render_targets[i])
             wined3d_resource_acquire(state->fb->render_targets[i]->resource);
@@ -874,6 +853,29 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum
primitive_type, unsigned
     acquire_shader_resources(state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE));
     acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_PIXEL],
             state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]);
+}
+
+void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int
patch_vertex_count,
+        int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
+        unsigned int start_instance, unsigned int instance_count, BOOL indexed)
+{
+    const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
+    const struct wined3d_state *state = &cs->device->state;
+    struct wined3d_cs_draw *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_DRAW;
+    op->primitive_type = primitive_type;
+    op->patch_vertex_count = patch_vertex_count;
+    op->parameters.indirect = FALSE;
+    op->parameters.u.direct.base_vertex_idx = base_vertex_idx;
+    op->parameters.u.direct.start_idx = start_idx;
+    op->parameters.u.direct.index_count = index_count;
+    op->parameters.u.direct.start_instance = start_instance;
+    op->parameters.u.direct.instance_count = instance_count;
+    op->parameters.indexed = indexed;
+
+    acquire_graphics_pipeline_resources(state, indexed, gl_info);
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
@@ -881,9 +883,9 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum
primitive_type, unsigned
 void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, GLenum primitive_type, unsigned
int patch_vertex_count,
         struct wined3d_buffer *buffer, unsigned int offset, BOOL indexed)
 {
+    const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
     const struct wined3d_state *state = &cs->device->state;
     struct wined3d_cs_draw *op;
-    unsigned int i;
     op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
     op->opcode = WINED3D_CS_OP_DRAW;
@@ -894,36 +896,9 @@ void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, GLenum
primitive_type,
     op->parameters.u.indirect.offset = offset;
     op->parameters.indexed = indexed;
+    acquire_graphics_pipeline_resources(state, indexed, gl_info);
     wined3d_resource_acquire(&buffer->resource);
-    if (indexed)
-        wined3d_resource_acquire(&state->index_buffer->resource);
-    for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
-    {
-        if (state->streams[i].buffer)
-            wined3d_resource_acquire(&state->streams[i].buffer->resource);
-    }
-    for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i)
-    {
-        if (state->stream_output[i].buffer)
-
wined3d_resource_acquire(&state->stream_output[i].buffer->resource);
-    }
-    for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
-    {
-        if (state->textures[i])
-            wined3d_resource_acquire(&state->textures[i]->resource);
-    }
-    for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
-    {
-        if (state->fb->render_targets[i])
-            wined3d_resource_acquire(state->fb->render_targets[i]->resource);
-    }
-    if (state->fb->depth_stencil)
-        wined3d_resource_acquire(state->fb->depth_stencil->resource);
-    acquire_shader_resources(state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE));
-    acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_PIXEL],
-            state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]);
-
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
@@ -945,6 +920,7 @@ void wined3d_cs_emit_flush(struct wined3d_cs *cs)
     op->opcode = WINED3D_CS_OP_FLUSH;
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+    cs->queries_flushed = TRUE;
 }
 static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data)
@@ -1054,8 +1030,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs
*cs, const
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
     }
-    else if (prev && (prev->format_flags & WINED3DFMT_FLAG_FLOAT)
-            != (op->view->format_flags & WINED3DFMT_FLAG_FLOAT))
+    else if (prev && prev->format->depth_bias_scale !=
op->view->format->depth_bias_scale)
     {
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
     }
@@ -1931,6 +1906,7 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct
wined3d_query *qu
     op->flags = flags;
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+    cs->queries_flushed = FALSE;
 }
 static void wined3d_cs_exec_preload_resource(struct wined3d_cs *cs, const void *data)
@@ -2073,14 +2049,14 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs
*cs, const void *
         struct wined3d_context *context;
         struct wined3d_bo_address addr;
-        if (op->flags)
+        if (op->flags & ~WINED3D_BLT_RAW)
         {
             FIXME("Flags %#x not implemented for %s resources.\n",
                     op->flags, debug_d3dresourcetype(op->dst_resource->type));
             goto error;
         }
-        if (op->src_resource->format != op->dst_resource->format)
+        if (!(op->flags & WINED3D_BLT_RAW) &&
op->src_resource->format != op->dst_resource->format)
         {
             FIXME("Format conversion not implemented for %s resources.\n",
                     debug_d3dresourcetype(op->dst_resource->type));
@@ -2176,6 +2152,8 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct
wined3d_reso
     op->flags = flags;
     if (fx)
         op->fx = *fx;
+    else
+        memset(&op->fx, 0, sizeof(op->fx));
     op->filter = filter;
     wined3d_resource_acquire(dst_resource);
@@ -2199,11 +2177,18 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs
*cs, const voi
     if (op->resource->type == WINED3D_RTYPE_BUFFER)
     {
         struct wined3d_buffer *buffer = buffer_from_resource(op->resource);
-        HRESULT hr;
-        if (FAILED(hr = wined3d_buffer_upload_data(buffer, box, op->data.data)))
-            WARN("Failed to update buffer data, hr %#x.\n", hr);
+        context = context_acquire(op->resource->device, NULL, 0);
+        if (!wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER))
+        {
+            ERR("Failed to load buffer location.\n");
+            context_release(context);
+            goto done;
+        }
+        wined3d_buffer_upload_data(buffer, context, box, op->data.data);
+        wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER);
+        context_release(context);
         goto done;
     }
@@ -2244,53 +2229,6 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs,
struct wined3d_r
         unsigned int slice_pitch)
 {
     struct wined3d_cs_update_sub_resource *op;
-#if defined(STAGING_CSMT)
-    size_t data_size, size;
-
-    if (resource->type != WINED3D_RTYPE_BUFFER && resource->format_flags
& WINED3DFMT_FLAG_BLOCKS)
-        goto no_async;
-
-    data_size = 0;
-    switch (resource->type)
-    {
-        case WINED3D_RTYPE_TEXTURE_3D:
-            data_size += (box->back - box->front - 1) * slice_pitch;
-            /* fall-through */
-        case WINED3D_RTYPE_TEXTURE_2D:
-            data_size += (box->bottom - box->top - 1) * row_pitch;
-            /* fall-through */
-        case WINED3D_RTYPE_TEXTURE_1D:
-            data_size += (box->right - box->left) *
resource->format->byte_count;
-            break;
-        case WINED3D_RTYPE_BUFFER:
-            data_size = box->right - box->left;
-            break;
-        case WINED3D_RTYPE_NONE:
-            return;
-    }
-
-    size = FIELD_OFFSET(struct wined3d_cs_update_sub_resource, copy_data[data_size]);
-    if (!cs->ops->check_space(cs, size, WINED3D_CS_QUEUE_DEFAULT))
-        goto no_async;
-
-    op = cs->ops->require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT);
-    op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
-    op->resource = resource;
-    op->sub_resource_idx = sub_resource_idx;
-    op->box = *box;
-    op->data.row_pitch = row_pitch;
-    op->data.slice_pitch = slice_pitch;
-    op->data.data = op->copy_data;
-    memcpy(op->copy_data, data, data_size);
-
-    wined3d_resource_acquire(resource);
-
-    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
-    return;
-
-no_async:
-    wined3d_resource_wait_idle(resource);
-#endif /* STAGING_CSMT */
     op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP);
     op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
@@ -2304,10 +2242,8 @@ no_async:
     wined3d_resource_acquire(resource);
     cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP);
-#if !defined(STAGING_CSMT)
     /* The data pointer may go away, so we need to wait until it is read.
      * Copying the data may be faster if it's small. */
-#endif /* STAGING_CSMT */
     cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP);
 }
@@ -2386,7 +2322,6 @@ static void wined3d_cs_exec_copy_uav_counter(struct wined3d_cs *cs,
const void *
     context_release(context);
     wined3d_resource_release(&op->buffer->resource);
-    wined3d_resource_release(view->resource);
 }
 void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer
*dst_buffer,
@@ -2401,149 +2336,28 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs,
struct wined3d_buff
     op->view = uav;
     wined3d_resource_acquire(&dst_buffer->resource);
-    wined3d_resource_acquire(uav->resource);
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
-static void wined3d_cs_exec_copy_sub_resource(struct wined3d_cs *cs, const void *data)
+static void wined3d_cs_exec_generate_mipmaps(struct wined3d_cs *cs, const void *data)
 {
-    struct wined3d_cs_copy_sub_resource *op = (void*)data;
-
-    if (op->dst_resource->type == WINED3D_RTYPE_BUFFER)
-    {
-        wined3d_buffer_copy(buffer_from_resource(op->dst_resource),
op->dst_box.left,
-                buffer_from_resource(op->src_resource), op->src_box.left,
-                op->src_box.right - op->src_box.left);
-    }
-    else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_1D ||
-            op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D ||
-            op->dst_resource->type == WINED3D_RTYPE_TEXTURE_3D)
-    {
-        struct wined3d_texture *dst_texture, *src_texture;
-        struct gl_texture *gl_tex_src, *gl_tex_dst;
-        unsigned int update_w, update_h, update_d;
-        const struct wined3d_gl_info *gl_info;
-        unsigned int src_level, src_layer;
-        unsigned int dst_level, dst_layer;
-        struct wined3d_context *context;
-        BOOL partial_update = FALSE;
-
-        update_w = op->dst_box.right - op->dst_box.left;
-        update_h = op->dst_box.bottom - op->dst_box.top;
-        update_d = op->dst_box.back - op->dst_box.front;
-
-        dst_texture = texture_from_resource(op->dst_resource);
-        src_texture = texture_from_resource(op->src_resource);
-
-        context = context_acquire(cs->device, NULL, 0);
-        gl_info = context->gl_info;
-
-        if (!wined3d_texture_load_location(src_texture, op->src_sub_resource_idx,
context, WINED3D_LOCATION_TEXTURE_RGB))
-        {
-            FIXME("Failed to load source sub-resource into
WINED3D_LOCATION_TEXTURE_RGB.\n");
-            context_release(context);
-            goto error;
-        }
-
-        src_level = op->src_sub_resource_idx % src_texture->level_count;
-        src_layer = op->src_sub_resource_idx / src_texture->level_count;
-        dst_level = op->dst_sub_resource_idx % dst_texture->level_count;
-        dst_layer = op->dst_sub_resource_idx / dst_texture->level_count;
-
-        switch (op->dst_resource->type)
-        {
-            case WINED3D_RTYPE_TEXTURE_3D:
-                partial_update |= (update_d !=
wined3d_texture_get_level_depth(dst_texture, dst_level));
-            case WINED3D_RTYPE_TEXTURE_2D:
-                partial_update |= (update_h !=
wined3d_texture_get_level_height(dst_texture, dst_level));
-            case WINED3D_RTYPE_TEXTURE_1D:
-                partial_update |= (update_w !=
wined3d_texture_get_level_width(dst_texture, dst_level));
-            default:
-                break;
-        }
-
-        if (!partial_update)
-        {
-            wined3d_texture_prepare_texture(dst_texture, context, FALSE);
-        }
-        else if (!wined3d_texture_load_location(dst_texture, op->dst_sub_resource_idx,
context, WINED3D_LOCATION_TEXTURE_RGB))
-        {
-            FIXME("Failed to load destination sub-resource.\n");
-            context_release(context);
-            goto error;
-        }
-
-        switch (op->dst_resource->type)
-        {
-            case WINED3D_RTYPE_TEXTURE_1D:
-                op->src_box.top = src_layer;
-                op->dst_box.top = dst_layer;
-                break;
-            case WINED3D_RTYPE_TEXTURE_2D:
-                op->src_box.front = src_layer;
-                op->dst_box.front = dst_layer;
-                break;
-            default:
-                break;
-        }
-
-        gl_tex_src = wined3d_texture_get_gl_texture(src_texture, FALSE);
-        gl_tex_dst = wined3d_texture_get_gl_texture(dst_texture, FALSE);
-
-        GL_EXTCALL(glCopyImageSubData(gl_tex_src->name, src_texture->target,
src_level,
-                op->src_box.left, op->src_box.top, op->src_box.front,
-                gl_tex_dst->name, dst_texture->target, dst_level,
-                op->dst_box.left, op->dst_box.top, op->dst_box.front,
-                update_w, update_h, update_d));
-        checkGLcall("Copy texture content");
+    const struct wined3d_cs_generate_mipmaps *op = data;
+    struct wined3d_shader_resource_view *view = op->view;
-        wined3d_texture_validate_location(dst_texture, op->dst_sub_resource_idx,
WINED3D_LOCATION_TEXTURE_RGB);
-        wined3d_texture_invalidate_location(dst_texture, op->dst_sub_resource_idx,
~WINED3D_LOCATION_TEXTURE_RGB);
-
-        context_release(context);
-    }
-    else
-    {
-        FIXME("Not implemented for %s resources.\n",
debug_d3dresourcetype(op->dst_resource->type));
-    }
-
-error:
-    wined3d_resource_release(op->src_resource);
-    wined3d_resource_release(op->dst_resource);
+    shader_resource_view_generate_mipmaps(view);
+    wined3d_resource_release(view->resource);
 }
-void wined3d_cs_emit_copy_sub_resource(struct wined3d_cs *cs, struct wined3d_resource
*dst_resource,
-        unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct
wined3d_resource *src_resource,
-        unsigned int src_sub_resource_idx, const struct wined3d_box *src_box)
+void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct
wined3d_shader_resource_view *view)
 {
-    const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
-    struct wined3d_cs_blt_sub_resource *op;
-
-    if (!gl_info->supported[ARB_TEXTURE_VIEW] &&
src_resource->format->id != dst_resource->format->id)
-    {
-        FIXME("ARB_TEXTURE_VIEW not supported, cannot copy sub-resource.\n");
-        return;
-    }
-
-    if (!gl_info->supported[ARB_COPY_IMAGE])
-    {
-        wined3d_cs_emit_blt_sub_resource(cs, dst_resource, dst_sub_resource_idx, dst_box,
-                src_resource, src_sub_resource_idx, src_box, 0, NULL,
WINED3D_TEXF_POINT);
-        return;
-    }
+    struct wined3d_cs_generate_mipmaps *op;
     op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
-    op->opcode = WINED3D_CS_OP_COPY_SUB_RESOURCE;
-    op->dst_resource = dst_resource;
-    op->dst_sub_resource_idx = dst_sub_resource_idx;
-    op->dst_box = *dst_box;
-    op->src_resource = src_resource;
-    op->src_sub_resource_idx = src_sub_resource_idx;
-    op->src_box = *src_box;
+    op->opcode = WINED3D_CS_OP_GENERATE_MIPMAPS;
+    op->view = view;
-    wined3d_resource_acquire(dst_resource);
-    wined3d_resource_acquire(src_resource);
+    wined3d_resource_acquire(view->resource);
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
@@ -2606,16 +2420,9 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs
*cs, const void
     /* WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION    */
wined3d_cs_exec_add_dirty_texture_region,
     /* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */
wined3d_cs_exec_clear_unordered_access_view,
     /* WINED3D_CS_OP_COPY_UAV_COUNTER            */ wined3d_cs_exec_copy_uav_counter,
-    /* WINED3D_CS_OP_COPY_SUB_RESOURCE           */ wined3d_cs_exec_copy_sub_resource,
+    /* WINED3D_CS_OP_GENERATE_MIPMAPS            */ wined3d_cs_exec_generate_mipmaps,
 };
-#if defined(STAGING_CSMT)
-static BOOL wined3d_cs_st_check_space(struct wined3d_cs *cs, size_t size, enum
wined3d_cs_queue_id queue_id)
-{
-    return TRUE;
-}
-
-#endif /* STAGING_CSMT */
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum
wined3d_cs_queue_id queue_id)
 {
     if (size > (cs->data_size - cs->end))
@@ -2669,9 +2476,6 @@ static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum
wined3d_cs_queue_id
 static const struct wined3d_cs_ops wined3d_cs_st_ops =
 {
-#if defined(STAGING_CSMT)
-    wined3d_cs_st_check_space,
-#endif /* STAGING_CSMT */
     wined3d_cs_st_require_space,
     wined3d_cs_st_submit,
     wined3d_cs_st_finish,
@@ -2708,21 +2512,6 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum
wined3d_cs_queue_id
     wined3d_cs_queue_submit(&cs->queue[queue_id], cs);
 }
-#if defined(STAGING_CSMT)
-static BOOL wined3d_cs_queue_check_space(struct wined3d_cs_queue *queue, size_t size)
-{
-    size_t queue_size = ARRAY_SIZE(queue->data);
-    size_t header_size, packet_size, remaining;
-
-    header_size = FIELD_OFFSET(struct wined3d_cs_packet, data[0]);
-    size = (size + header_size - 1) & ~(header_size - 1);
-    packet_size = FIELD_OFFSET(struct wined3d_cs_packet, data[size]);
-
-    remaining = queue_size - queue->head;
-    return (remaining >= packet_size);
-}
-
-#endif /* STAGING_CSMT */
 static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size,
struct wined3d_cs *cs)
 {
     size_t queue_size = ARRAY_SIZE(queue->data);
@@ -2784,16 +2573,6 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue
*queue, size
     return packet->data;
 }
-#if defined(STAGING_CSMT)
-static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum
wined3d_cs_queue_id queue_id)
-{
-    if (cs->thread_id == GetCurrentThreadId())
-        return wined3d_cs_st_check_space(cs, size, queue_id);
-
-    return wined3d_cs_queue_check_space(&cs->queue[queue_id], size);
-}
-
-#endif /* STAGING_CSMT */
 static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum
wined3d_cs_queue_id queue_id)
 {
     if (cs->thread_id == GetCurrentThreadId())
@@ -2816,9 +2595,6 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum
wined3d_cs_queue_id
 static const struct wined3d_cs_ops wined3d_cs_mt_ops =
 {
-#if defined(STAGING_CSMT)
-    wined3d_cs_mt_check_space,
-#endif /* STAGING_CSMT */
     wined3d_cs_mt_require_space,
     wined3d_cs_mt_submit,
     wined3d_cs_mt_finish,
@@ -2866,11 +2642,16 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
     unsigned int spin_count = 0;
     struct wined3d_cs *cs = ctx;
     enum wined3d_cs_op opcode;
+    HMODULE wined3d_module;
     unsigned int poll = 0;
     LONG tail;
     TRACE("Started.\n");
+    /* Copy the module handle to a local variable to avoid racing with the
+     * thread freeing "cs" before the FreeLibraryAndExitThread() call. */
+    wined3d_module = cs->wined3d_module;
+
     list_init(&cs->query_poll_list);
     cs->thread_id = GetCurrentThreadId();
     for (;;)
@@ -2918,7 +2699,7 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
     cs->queue[WINED3D_CS_QUEUE_MAP].tail = cs->queue[WINED3D_CS_QUEUE_MAP].head;
     cs->queue[WINED3D_CS_QUEUE_DEFAULT].tail =
cs->queue[WINED3D_CS_QUEUE_DEFAULT].head;
     TRACE("Stopped.\n");
-    FreeLibraryAndExitThread(cs->wined3d_module, 0);
+    FreeLibraryAndExitThread(wined3d_module, 0);
 }
 struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c
index 224324ebde..fdc4f957af 100644
--- a/dll/directx/wine/wined3d/device.c
+++ b/dll/directx/wine/wined3d/device.c
@@ -374,8 +374,10 @@ void device_clear_render_targets(struct wined3d_device *device, UINT
rt_count, c
         }
         gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-        for (i = 0; i < MAX_RENDER_TARGETS; ++i)
-            context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
         gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b,
color->a);
         checkGLcall("glClearColor");
         clear_mask = clear_mask | GL_COLOR_BUFFER_BIT;
@@ -478,7 +480,7 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
         state_cleanup(&device->state);
-        for (i = 0; i < sizeof(device->multistate_funcs) /
sizeof(device->multistate_funcs[0]); ++i)
+        for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
         {
             HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
             device->multistate_funcs[i] = NULL;
@@ -610,17 +612,6 @@ static void create_dummy_textures(struct wined3d_device *device,
struct wined3d_
      * to each texture stage when the currently set D3D texture is NULL. */
     context_active_texture(context, gl_info, 0);
-    gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_1d);
-    checkGLcall("glGenTextures");
-    TRACE("Dummy 1D texture given name %u.\n",
device->dummy_textures.tex_1d);
-
-    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D,
device->dummy_textures.tex_1d);
-    checkGLcall("glBindTexture");
-
-    gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 1, 0,
-            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
-    checkGLcall("glTexImage1D");
-
     gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_2d);
     checkGLcall("glGenTextures");
     TRACE("Dummy 2D texture given name %u.\n",
device->dummy_textures.tex_2d);
@@ -697,17 +688,6 @@ static void create_dummy_textures(struct wined3d_device *device,
struct wined3d_
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
     {
-        gl_info->gl_ops.gl.p_glGenTextures(1,
&device->dummy_textures.tex_1d_array);
-        checkGLcall("glGenTextures");
-        TRACE("Dummy 1D array texture given name %u.\n",
device->dummy_textures.tex_1d_array);
-
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY,
device->dummy_textures.tex_1d_array);
-        checkGLcall("glBindTexture");
-
-        gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA8, 1, 1, 0,
-                GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
-        checkGLcall("glTexImage2D");
-
         gl_info->gl_ops.gl.p_glGenTextures(1,
&device->dummy_textures.tex_2d_array);
         checkGLcall("glGenTextures");
         TRACE("Dummy 2D array texture given name %u.\n",
device->dummy_textures.tex_2d_array);
@@ -755,10 +735,7 @@ static void destroy_dummy_textures(struct wined3d_device *device,
struct wined3d
         gl_info->gl_ops.gl.p_glDeleteTextures(1,
&device->dummy_textures.tex_buffer);
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
-    {
         gl_info->gl_ops.gl.p_glDeleteTextures(1,
&device->dummy_textures.tex_2d_array);
-        gl_info->gl_ops.gl.p_glDeleteTextures(1,
&device->dummy_textures.tex_1d_array);
-    }
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
         gl_info->gl_ops.gl.p_glDeleteTextures(1,
&device->dummy_textures.tex_cube_array);
@@ -773,7 +750,6 @@ static void destroy_dummy_textures(struct wined3d_device *device,
struct wined3d
         gl_info->gl_ops.gl.p_glDeleteTextures(1,
&device->dummy_textures.tex_rect);
     gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d);
-    gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_1d);
     checkGLcall("Delete dummy textures");
@@ -965,7 +941,7 @@ void CDECL wined3d_device_release_focus_window(struct wined3d_device
*device)
 static void device_init_swapchain_state(struct wined3d_device *device, struct
wined3d_swapchain *swapchain)
 {
-    BOOL ds_enable = !!swapchain->desc.enable_auto_depth_stencil;
+    BOOL ds_enable = swapchain->desc.enable_auto_depth_stencil;
     unsigned int i;
     if (device->fb.render_targets)
@@ -979,7 +955,6 @@ static void device_init_swapchain_state(struct wined3d_device *device,
struct wi
     }
     wined3d_device_set_depth_stencil_view(device, ds_enable ?
device->auto_depth_stencil_view : NULL);
-    wined3d_device_set_render_state(device, WINED3D_RS_ZENABLE, ds_enable);
 }
 static void wined3d_device_delete_opengl_contexts_cs(void *object)
@@ -1046,6 +1021,7 @@ static void wined3d_device_create_primary_opengl_context_cs(void
*object)
     wined3d_ffp_blitter_create(&device->blitter,
&device->adapter->gl_info);
     wined3d_arbfp_blitter_create(&device->blitter, device);
     wined3d_fbo_blitter_create(&device->blitter,
&device->adapter->gl_info);
+    wined3d_raw_blitter_create(&device->blitter,
&device->adapter->gl_info);
     swapchain = device->swapchains[0];
     target = swapchain->back_buffers ? swapchain->back_buffers[0] :
swapchain->front_buffer;
@@ -1223,9 +1199,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device
*device)
     wine_rb_clear(&device->samplers, device_free_sampler, NULL);
-#if defined(STAGING_CSMT)
-    context_set_current(NULL);
-#endif /* STAGING_CSMT */
     wined3d_device_delete_opengl_contexts(device);
     if (device->fb.depth_stencil)
@@ -1311,33 +1284,8 @@ void CDECL wined3d_device_set_multithreaded(struct wined3d_device
*device)
 UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device *device)
 {
-    /* const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; */
-
     TRACE("device %p.\n", device);
-    /* We can not acquire the context unless there is a swapchain. */
-    /*
-    if (device->swapchains && gl_info->supported[NVX_GPU_MEMORY_INFO]
&&
-            !wined3d_settings.emulated_textureram)
-    {
-        GLint vram_free_kb;
-        UINT64 vram_free;
-
-        struct wined3d_context *context = context_acquire(device, NULL, 0);
-
gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX,
&vram_free_kb);
-        vram_free = (UINT64)vram_free_kb * 1024;
-        context_release(context);
-
-        TRACE("Total 0x%s bytes. emulation 0x%s left, driver 0x%s left.\n",
-                wine_dbgstr_longlong(device->adapter->vram_bytes),
-                wine_dbgstr_longlong(device->adapter->vram_bytes -
device->adapter->vram_bytes_used),
-                wine_dbgstr_longlong(vram_free));
-
-        vram_free = min(vram_free, device->adapter->vram_bytes -
device->adapter->vram_bytes_used);
-        return min(UINT_MAX, vram_free);
-    }
-    */
-
     TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n",
             wine_dbgstr_longlong(device->adapter->vram_bytes),
             wine_dbgstr_longlong(device->adapter->vram_bytes_used),
@@ -1800,7 +1748,6 @@ HRESULT CDECL wined3d_device_set_clip_plane(struct wined3d_device
*device,
 {
     TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane);
-    /* Validate plane_idx. */
     if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances)
     {
         TRACE("Application has requested clipplane this device doesn't
support.\n");
@@ -1829,7 +1776,6 @@ HRESULT CDECL wined3d_device_get_clip_plane(const struct
wined3d_device *device,
 {
     TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane);
-    /* Validate plane_idx. */
     if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances)
     {
         TRACE("Application has requested clipplane this device doesn't
support.\n");
@@ -2076,7 +2022,7 @@ void CDECL wined3d_device_set_sampler_state(struct wined3d_device
*device,
     if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <=
WINED3DVERTEXTEXTURESAMPLER3)
         sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
-    if (sampler_idx >= sizeof(device->state.sampler_states) /
sizeof(*device->state.sampler_states))
+    if (sampler_idx >= ARRAY_SIZE(device->state.sampler_states))
     {
         WARN("Invalid sampler %u.\n", sampler_idx);
         return; /* Windows accepts overflowing this array ... we do not. */
@@ -2111,7 +2057,7 @@ DWORD CDECL wined3d_device_get_sampler_state(const struct
wined3d_device *device
     if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <=
WINED3DVERTEXTEXTURESAMPLER3)
         sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
-    if (sampler_idx >= sizeof(device->state.sampler_states) /
sizeof(*device->state.sampler_states))
+    if (sampler_idx >= ARRAY_SIZE(device->state.sampler_states))
     {
         WARN("Invalid sampler %u.\n", sampler_idx);
         return 0; /* Windows accepts overflowing this array ... we do not. */
@@ -3467,7 +3413,7 @@ HRESULT CDECL wined3d_device_set_texture(struct wined3d_device
*device,
         stage -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
     /* Windows accepts overflowing this array... we do not. */
-    if (stage >= sizeof(device->state.textures) /
sizeof(*device->state.textures))
+    if (stage >= ARRAY_SIZE(device->state.textures))
     {
         WARN("Ignoring invalid stage %u.\n", stage);
         return WINED3D_OK;
@@ -3511,7 +3457,7 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const
struct wined3d_d
     if (stage >= WINED3DVERTEXTEXTURESAMPLER0 && stage <=
WINED3DVERTEXTEXTURESAMPLER3)
         stage -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
-    if (stage >= sizeof(device->state.textures) /
sizeof(*device->state.textures))
+    if (stage >= ARRAY_SIZE(device->state.textures))
     {
         WARN("Ignoring invalid stage %u.\n", stage);
         return NULL; /* Windows accepts overflowing this array ... we do not. */
@@ -3522,17 +3468,10 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const
struct wined3d_d
 HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device,
WINED3DCAPS *caps)
 {
-    HRESULT hr;
-
     TRACE("device %p, caps %p.\n", device, caps);
-    hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
+    return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
             device->create_parms.device_type, caps);
-
-    if (SUCCEEDED(hr) && use_software_vertex_processing(device))
-        caps->MaxVertexBlendMatrixIndex = 255;
-
-    return hr;
 }
 HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT
swapchain_idx,
@@ -3962,15 +3901,31 @@ HRESULT CDECL wined3d_device_validate_device(const struct
wined3d_device *device
 void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device,
BOOL software)
 {
+    static BOOL warned;
+
     TRACE("device %p, software %#x.\n", device, software);
+    if (!warned)
+    {
+        FIXME("device %p, software %#x stub!\n", device, software);
+        warned = TRUE;
+    }
+
     device->softwareVertexProcessing = software;
 }
 BOOL CDECL wined3d_device_get_software_vertex_processing(const struct wined3d_device
*device)
 {
+    static BOOL warned;
+
     TRACE("device %p.\n", device);
+    if (!warned)
+    {
+        TRACE("device %p stub!\n", device);
+        warned = TRUE;
+    }
+
     return device->softwareVertexProcessing;
 }
@@ -4027,12 +3982,6 @@ void CDECL wined3d_device_copy_uav_counter(struct wined3d_device
*device,
     TRACE("device %p, dst_buffer %p, offset %u, uav %p.\n",
             device, dst_buffer, offset, uav);
-    if (offset + sizeof(GLuint) > dst_buffer->resource.size)
-    {
-        WARN("Offset %u too large.\n", offset);
-        return;
-    }
-
     wined3d_cs_emit_copy_uav_counter(device->cs, dst_buffer, offset, uav);
 }
@@ -4069,12 +4018,10 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device
*device,
         return;
     }
-    if (src_resource->format->id != dst_resource->format->id &&
-            (src_resource->format->typeless_id !=
dst_resource->format->typeless_id ||
-            src_resource->format->gl_view_class !=
dst_resource->format->gl_view_class ||
-            !src_resource->format->typeless_id))
+    if (src_resource->format->typeless_id !=
dst_resource->format->typeless_id
+            || (!src_resource->format->typeless_id &&
src_resource->format->id != dst_resource->format->id))
     {
-        WARN("Resource formats (%s / %s) don't match.\n",
+        WARN("Resource formats %s and %s are incompatible.\n",
                 debug_d3dformat(dst_resource->format->id),
                 debug_d3dformat(src_resource->format->id));
         return;
@@ -4083,7 +4030,8 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device
*device,
     if (dst_resource->type == WINED3D_RTYPE_BUFFER)
     {
         wined3d_box_set(&box, 0, 0, src_resource->size, 1, 0, 1);
-        wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, 0, &box,
src_resource, 0, &box);
+        wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, 0, &box,
+                src_resource, 0, &box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT);
         return;
     }
@@ -4109,7 +4057,8 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device
*device,
         {
             unsigned int idx = j * dst_texture->level_count + i;
-            wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, idx, &box,
src_resource, idx, &box);
+            wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, idx, &box,
+                    src_resource, idx, &box, WINED3D_BLT_RAW, NULL,
WINED3D_TEXF_POINT);
         }
     }
 }
@@ -4140,12 +4089,10 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct
wined3d_device *dev
         return WINED3DERR_INVALIDCALL;
     }
-    if (src_resource->format->id != dst_resource->format->id &&
-            (src_resource->format->typeless_id !=
dst_resource->format->typeless_id ||
-            src_resource->format->gl_view_class !=
dst_resource->format->gl_view_class ||
-            !src_resource->format->typeless_id))
+    if (src_resource->format->typeless_id !=
dst_resource->format->typeless_id
+            || (!src_resource->format->typeless_id &&
src_resource->format->id != dst_resource->format->id))
     {
-        WARN("Resource formats (%s / %s) don't match.\n",
+        WARN("Resource formats %s and %s are incompatible.\n",
                 debug_d3dformat(dst_resource->format->id),
                 debug_d3dformat(src_resource->format->id));
         return WINED3DERR_INVALIDCALL;
@@ -4167,7 +4114,10 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct
wined3d_device *dev
         if (!src_box)
         {
-            wined3d_box_set(&b, 0, 0, src_resource->size, 1, 0, 1);
+            unsigned int dst_w;
+
+            dst_w = dst_resource->size - dst_x;
+            wined3d_box_set(&b, 0, 0, min(src_resource->size, dst_w), 1, 0, 1);
             src_box = &b;
         }
         else if ((src_box->left >= src_box->right
@@ -4206,7 +4156,6 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct
wined3d_device *dev
             return WINED3DERR_INVALIDCALL;
         }
-#if !defined(STAGING_CSMT)
         if (dst_texture->sub_resources[dst_sub_resource_idx].map_count)
         {
             WARN("Destination sub-resource %u is mapped.\n",
dst_sub_resource_idx);
@@ -4217,25 +4166,20 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct
wined3d_device *dev
         {
             WARN("Source sub-resource %u is mapped.\n", src_sub_resource_idx);
             return WINED3DERR_INVALIDCALL;
-#else  /* STAGING_CSMT */
-        if (dst_texture->sub_resources[dst_sub_resource_idx].map_count ||
-            src_texture->sub_resources[src_sub_resource_idx].map_count)
-        {
-            struct wined3d_device *device = dst_texture->resource.device;
-            device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
-            if (dst_texture->sub_resources[dst_sub_resource_idx].map_count ||
-                src_texture->sub_resources[src_sub_resource_idx].map_count)
-            {
-                WARN("Destination or source sub-resource is mapped.\n");
-                return WINEDDERR_SURFACEBUSY;
-            }
-#endif /* STAGING_CSMT */
         }
         if (!src_box)
         {
-            wined3d_box_set(&b, 0, 0, wined3d_texture_get_level_width(src_texture,
src_level),
-                    wined3d_texture_get_level_height(src_texture, src_level), 0, 1);
+            unsigned int src_w, src_h, dst_w, dst_h, dst_level;
+
+            src_w = wined3d_texture_get_level_width(src_texture, src_level);
+            src_h = wined3d_texture_get_level_height(src_texture, src_level);
+
+            dst_level = dst_sub_resource_idx % dst_texture->level_count;
+            dst_w = wined3d_texture_get_level_width(dst_texture, dst_level) - dst_x;
+            dst_h = wined3d_texture_get_level_height(dst_texture, dst_level) - dst_y;
+
+            wined3d_box_set(&b, 0, 0, min(src_w, dst_w), min(src_h, dst_h), 0, 1);
             src_box = &b;
         }
         else if (FAILED(wined3d_texture_check_box_dimensions(src_texture, src_level,
src_box)))
@@ -4259,8 +4203,8 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct
wined3d_device *dev
         return WINED3DERR_INVALIDCALL;
     }
-    wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, dst_sub_resource_idx,
&dst_box,
-            src_resource, src_sub_resource_idx, src_box);
+    wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx,
&dst_box,
+            src_resource, src_sub_resource_idx, src_box, WINED3D_BLT_RAW, NULL,
WINED3D_TEXF_POINT);
     return WINED3D_OK;
 }
@@ -4287,8 +4231,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device
*device, str
         height = 1;
         depth = 1;
     }
-    else if (resource->type == WINED3D_RTYPE_TEXTURE_1D ||
-            resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type ==
WINED3D_RTYPE_TEXTURE_3D)
+    else if (resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type ==
WINED3D_RTYPE_TEXTURE_3D)
     {
         struct wined3d_texture *texture = texture_from_resource(resource);
         unsigned int level;
@@ -4323,10 +4266,8 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device
*device, str
         return;
     }
-#if !defined(STAGING_CSMT)
     wined3d_resource_wait_idle(resource);
-#endif /* STAGING_CSMT */
     wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box,
data, row_pitch, depth_pitch);
 }
@@ -5054,7 +4995,6 @@ void device_resource_released(struct wined3d_device *device, struct
wined3d_reso
     switch (type)
     {
-        case WINED3D_RTYPE_TEXTURE_1D:
         case WINED3D_RTYPE_TEXTURE_2D:
         case WINED3D_RTYPE_TEXTURE_3D:
             for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
@@ -5187,7 +5127,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d
*wined3d,
     return WINED3D_OK;
 err:
-    for (i = 0; i < sizeof(device->multistate_funcs) /
sizeof(device->multistate_funcs[0]); ++i)
+    for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
     {
         HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
     }
@@ -5275,58 +5215,3 @@ LRESULT device_process_message(struct wined3d_device *device, HWND
window, BOOL
     else
         return CallWindowProcA(proc, window, message, wparam, lparam);
 }
-#if defined(STAGING_CSMT)
-
-/* Context activation is done by the caller */
-struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size,
GLenum gl_usage,
-        GLenum type_hint, struct wined3d_context *context)
-{
-    struct wined3d_gl_bo *ret;
-    const struct wined3d_gl_info *gl_info;
-
-    TRACE("device %p, size %u, gl_usage %u, type_hint %u\n", device, size,
gl_usage,
-            type_hint);
-
-    ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
-    if(!ret)
-        return NULL;
-    ret->type_hint = type_hint;
-    ret->size = size;
-    ret->usage = gl_usage;
-
-    gl_info = context->gl_info;
-
-    GL_EXTCALL(glGenBuffers(1, &ret->name));
-    if (type_hint == GL_ELEMENT_ARRAY_BUFFER)
-        context_invalidate_state(context, STATE_INDEXBUFFER);
-    GL_EXTCALL(glBindBuffer(type_hint, ret->name));
-    GL_EXTCALL(glBufferData(type_hint, size, NULL, gl_usage));
-    GL_EXTCALL(glBindBuffer(type_hint, 0));
-    checkGLcall("Create buffer object");
-
-    TRACE("Successfully created and set up buffer %u\n", ret->name);
-    return ret;
-}
-
-/* Context activation is done by the caller */
-static void wined3d_device_destroy_bo(struct wined3d_device *device, const struct
wined3d_context *context,
-        struct wined3d_gl_bo *bo)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name);
-
-    GL_EXTCALL(glDeleteBuffers(1, &bo->name));
-    checkGLcall("glDeleteBuffers");
-
-    HeapFree(GetProcessHeap(), 0, bo);
-}
-
-/* Context activation is done by the caller */
-void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo,
-        const struct wined3d_context *context)
-{
-    TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name);
-
-    wined3d_device_destroy_bo(device, context, bo);
-}
-#endif /* STAGING_CSMT */
diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c
index fa09d60b62..40262bbe59 100644
--- a/dll/directx/wine/wined3d/directx.c
+++ b/dll/directx/wine/wined3d/directx.c
@@ -116,9 +116,9 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_conservative_depth",           ARB_CONSERVATIVE_DEPTH        },
     {"GL_ARB_copy_buffer",                  ARB_COPY_BUFFER               },
     {"GL_ARB_copy_image",                   ARB_COPY_IMAGE                },
+    {"GL_ARB_cull_distance",                ARB_CULL_DISTANCE             },
     {"GL_ARB_debug_output",                 ARB_DEBUG_OUTPUT              },
     {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT        },
-    {"GL_ARB_depth_clamp",                  ARB_DEPTH_CLAMP               },
     {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE             },
     {"GL_ARB_derivative_control",           ARB_DERIVATIVE_CONTROL        },
     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS              },
@@ -176,6 +176,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_texture_cube_map_array",       ARB_TEXTURE_CUBE_MAP_ARRAY    },
     {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE       },
     {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3          },
+    {"GL_ARB_texture_filter_anisotropic",   ARB_TEXTURE_FILTER_ANISOTROPIC},
     {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT             },
     {"GL_ARB_texture_gather",               ARB_TEXTURE_GATHER            },
     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT   },
@@ -234,7 +235,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_EXT_texture_compression_s3tc",     EXT_TEXTURE_COMPRESSION_S3TC  },
     {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE       },
     {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3          },
-    {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC},
+    {"GL_EXT_texture_filter_anisotropic",   ARB_TEXTURE_FILTER_ANISOTROPIC},
     {"GL_EXT_texture_integer",              EXT_TEXTURE_INTEGER           },
     {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS          },
     {"GL_EXT_texture_mirror_clamp",         EXT_TEXTURE_MIRROR_CLAMP      },
@@ -264,7 +265,6 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2            },
     {"GL_NV_vertex_program2_option",        NV_VERTEX_PROGRAM2_OPTION     },
     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3            },
-    {"GL_NVX_gpu_memory_info",              NVX_GPU_MEMORY_INFO           },
     /* SGI */
     {"GL_SGIS_generate_mipmap",             SGIS_GENERATE_MIPMAP          },
@@ -581,7 +581,7 @@ static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
         0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
         0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
     };
-    unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
+    unsigned int check[ARRAY_SIZE(pattern)];
     /* No PBO -> No point in testing them. */
     if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
@@ -1338,7 +1338,6 @@ static const struct gpu_description gpu_description_table[] =
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX550,     "NVIDIA GeForce GTX 550
Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT555M,     "NVIDIA GeForce GT
555M",           DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560TI,   "NVIDIA GeForce GTX 560
Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560M,    "NVIDIA GeForce GTX
560M",          DRIVER_NVIDIA_GEFORCE8,  3072},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560,     "NVIDIA GeForce GTX
560",           DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX570,     "NVIDIA GeForce GTX
570",           DRIVER_NVIDIA_GEFORCE8,  1280},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX580,     "NVIDIA GeForce GTX
580",           DRIVER_NVIDIA_GEFORCE8,  1536},
@@ -1486,6 +1485,7 @@ static const struct gpu_description gpu_description_table[] =
     {HW_VENDOR_INTEL,      CARD_INTEL_IVBS,                "Intel(R) HD Graphics
Family",                               DRIVER_INTEL_HD4000,  1536},
     {HW_VENDOR_INTEL,      CARD_INTEL_HWD,                 "Intel(R) HD Graphics
4600",                                 DRIVER_INTEL_HD4000,  1536},
     {HW_VENDOR_INTEL,      CARD_INTEL_HWM,                 "Intel(R) HD Graphics
4600",                                 DRIVER_INTEL_HD4000,  1536},
+    {HW_VENDOR_INTEL,      CARD_INTEL_HD5000,              "Intel(R) HD Graphics
5000",                                 DRIVER_INTEL_HD4000,  1536},
     {HW_VENDOR_INTEL,      CARD_INTEL_I5100_1,             "Intel(R) Iris(TM)
Graphics 5100",                           DRIVER_INTEL_HD4000,  1536},
     {HW_VENDOR_INTEL,      CARD_INTEL_I5100_2,             "Intel(R) Iris(TM)
Graphics 5100",                           DRIVER_INTEL_HD4000,  1536},
     {HW_VENDOR_INTEL,      CARD_INTEL_I5100_3,             "Intel(R) Iris(TM)
Graphics 5100",                           DRIVER_INTEL_HD4000,  1536},
@@ -1527,7 +1527,7 @@ static const struct driver_version_information
*get_driver_version_info(enum win
     unsigned int i;
     TRACE("Looking up version info for driver=%d driver_model=%d\n", driver,
driver_model);
-    for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0]));
i++)
+    for (i = 0; i < ARRAY_SIZE(driver_version_table); ++i)
     {
         const struct driver_version_information *entry = &driver_version_table[i];
@@ -1547,7 +1547,7 @@ static const struct gpu_description *get_gpu_description(enum
wined3d_pci_vendor
 {
     unsigned int i;
-    for (i = 0; i < (sizeof(gpu_description_table) / sizeof(*gpu_description_table));
++i)
+    for (i = 0; i < ARRAY_SIZE(gpu_description_table); ++i)
     {
         if (vendor == gpu_description_table[i].vendor && device ==
gpu_description_table[i].card)
             return &gpu_description_table[i];
@@ -1576,15 +1576,6 @@ static const struct gpu_description *query_gpu_description(const
struct wined3d_
         TRACE("Card reports vendor PCI ID 0x%04x, device PCI ID 0x%04x, 0x%s bytes
of video memory.\n",
                 vendor, device, wine_dbgstr_longlong(*vram_bytes));
     }
-    else if (gl_info->supported[NVX_GPU_MEMORY_INFO])
-    {
-        GLint vram_kb;
-        gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX,
&vram_kb);
-
-        *vram_bytes = (UINT64)vram_kb * 1024;
-        TRACE("Got 0x%s as video memory from NVX_GPU_MEMORY_INFO extension.\n",
-                wine_dbgstr_longlong(*vram_bytes));
-    }
     if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
     {
@@ -1696,13 +1687,11 @@ static void init_driver_info(struct wined3d_driver_info
*driver_info,
      * In order to avoid this application bug we limit the amount of video memory
      * to LONG_MAX for older Windows versions.
      */
-#ifdef __i386__
     if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes >
LONG_MAX)
     {
         TRACE("Limiting amount of video memory to %#lx bytes for OS version older
than Vista.\n", LONG_MAX);
         driver_info->vram_bytes = LONG_MAX;
     }
-#endif
     /* Try to obtain driver version information for the current Windows version. This
fails in
      * some cases:
@@ -1744,7 +1733,7 @@ static void fixup_extensions(struct wined3d_gl_info *gl_info, struct
wined3d_cap
 {
     unsigned int i;
-    for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
+    for (i = 0; i < ARRAY_SIZE(quirk_table); ++i)
     {
         if (!quirk_table[i].match(gl_info, ctx, gl_renderer, gl_vendor, card_vendor,
device)) continue;
         TRACE("Applying driver quirk \"%s\".\n",
quirk_table[i].description);
@@ -1799,7 +1788,6 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct
wined3d_gl_in
         return GL_VENDOR_FGLRX;
     if (strstr(gl_vendor_string, "Mesa")
-            || strstr(gl_vendor_string, "Brian Paul")
             || strstr(gl_vendor_string, "X.Org")
             || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
             || strstr(gl_vendor_string, "DRI R300 Project")
@@ -1954,7 +1942,6 @@ cards_nvidia_binary[] =
     {"GTX 580",                     CARD_NVIDIA_GEFORCE_GTX580},    /* Geforce
500 - highend */
     {"GTX 570",                     CARD_NVIDIA_GEFORCE_GTX570},    /* Geforce
500 - midend high */
     {"GTX 560 Ti",                  CARD_NVIDIA_GEFORCE_GTX560TI},  /* Geforce
500 - midend */
-    {"GTX 560M",                    CARD_NVIDIA_GEFORCE_GTX560M},   /* Geforce
500 - midend mobile */
     {"GTX 560",                     CARD_NVIDIA_GEFORCE_GTX560},    /* Geforce
500 - midend */
     {"GT 555M",                     CARD_NVIDIA_GEFORCE_GT555M},    /* Geforce
500 - midend mobile */
     {"GTX 550 Ti",                  CARD_NVIDIA_GEFORCE_GTX550},    /* Geforce
500 - midend */
@@ -2167,6 +2154,7 @@ cards_intel[] =
     /* Haswell */
     {"Iris Pro 5200",               CARD_INTEL_IP5200_1},
     {"Iris 5100",                   CARD_INTEL_I5100_1},
+    {"HD Graphics 5000",            CARD_INTEL_HD5000}, /* MacOS */
     {"Haswell Mobile",              CARD_INTEL_HWM},
     {"Iris OpenGL Engine",          CARD_INTEL_HWM},    /* MacOS */
     /* Ivybridge */
@@ -2494,16 +2482,16 @@ static const struct
 card_vendor_table[] =
 {
     {HW_VENDOR_AMD,         "AMD",      amd_gl_vendor_table,
-            sizeof(amd_gl_vendor_table) / sizeof(*amd_gl_vendor_table),
+            ARRAY_SIZE(amd_gl_vendor_table),
             card_fallback_amd},
     {HW_VENDOR_NVIDIA,      "Nvidia",   nvidia_gl_vendor_table,
-            sizeof(nvidia_gl_vendor_table) / sizeof(*nvidia_gl_vendor_table),
+            ARRAY_SIZE(nvidia_gl_vendor_table),
             card_fallback_nvidia},
     {HW_VENDOR_VMWARE,      "VMware",   vmware_gl_vendor_table,
-            sizeof(vmware_gl_vendor_table) / sizeof(*vmware_gl_vendor_table),
+            ARRAY_SIZE(vmware_gl_vendor_table),
             card_fallback_amd},
     {HW_VENDOR_INTEL,       "Intel",    intel_gl_vendor_table,
-            sizeof(intel_gl_vendor_table) / sizeof(*intel_gl_vendor_table),
+            ARRAY_SIZE(intel_gl_vendor_table),
             card_fallback_intel},
 };
@@ -2565,7 +2553,7 @@ static enum wined3d_pci_device wined3d_guess_card(const struct
shader_caps *shad
     enum wined3d_d3d_level d3d_level = d3d_level_from_caps(shader_caps, fragment_caps,
glsl_version);
     enum wined3d_pci_device device;
-    for (i = 0; i < (sizeof(card_vendor_table) / sizeof(*card_vendor_table)); ++i)
+    for (i = 0; i < ARRAY_SIZE(card_vendor_table); ++i)
     {
         if (card_vendor_table[i].card_vendor != *card_vendor)
             continue;
@@ -3524,12 +3512,6 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info
*gl_info)
         gl_info->limits.buffers = gl_max;
         TRACE("Max draw buffers: %u.\n", gl_max);
     }
-    if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED])
-    {
-        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS,
&gl_max);
-        gl_info->limits.dual_buffers = gl_max;
-        TRACE("Max dual source draw buffers: %u.\n", gl_max);
-    }
     if (gl_info->supported[ARB_MULTITEXTURE])
     {
         if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
@@ -3625,9 +3607,9 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info
*gl_info)
         gl_info->limits.texture3d_size = gl_max;
         TRACE("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
     }
-    if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+    if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
     {
-        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
&gl_max);
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY,
&gl_max);
         gl_info->limits.anisotropy = gl_max;
         TRACE("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
     }
@@ -3906,6 +3888,8 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter
*adapter,
         {ARB_ES2_COMPATIBILITY,            MAKEDWORD_VERSION(4, 1)},
         {ARB_VIEWPORT_ARRAY,               MAKEDWORD_VERSION(4, 1)},
+        {ARB_BASE_INSTANCE,                MAKEDWORD_VERSION(4, 2)},
+        {ARB_CONSERVATIVE_DEPTH,           MAKEDWORD_VERSION(4, 2)},
         {ARB_INTERNALFORMAT_QUERY,         MAKEDWORD_VERSION(4, 2)},
         {ARB_MAP_BUFFER_ALIGNMENT,         MAKEDWORD_VERSION(4, 2)},
         {ARB_SHADER_ATOMIC_COUNTERS,       MAKEDWORD_VERSION(4, 2)},
@@ -3932,9 +3916,11 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter
*adapter,
         {ARB_CLEAR_TEXTURE,                MAKEDWORD_VERSION(4, 4)},
         {ARB_CLIP_CONTROL,                 MAKEDWORD_VERSION(4, 5)},
+        {ARB_CULL_DISTANCE,                MAKEDWORD_VERSION(4, 5)},
         {ARB_DERIVATIVE_CONTROL,           MAKEDWORD_VERSION(4, 5)},
         {ARB_PIPELINE_STATISTICS_QUERY,    MAKEDWORD_VERSION(4, 6)},
+        {ARB_TEXTURE_FILTER_ANISOTROPIC,   MAKEDWORD_VERSION(4, 6)},
     };
     struct wined3d_driver_info *driver_info = &adapter->driver_info;
     const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
@@ -4004,13 +3990,11 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter
*adapter,
             ERR("Received a NULL GL_EXTENSIONS.\n");
             return FALSE;
         }
-        parse_extension_string(gl_info, gl_extensions, gl_extension_map,
-                sizeof(gl_extension_map) / sizeof(*gl_extension_map));
+        parse_extension_string(gl_info, gl_extensions, gl_extension_map,
ARRAY_SIZE(gl_extension_map));
     }
     else
     {
-        enumerate_gl_extensions(gl_info, gl_extension_map,
-                sizeof(gl_extension_map) / sizeof(*gl_extension_map));
+        enumerate_gl_extensions(gl_info, gl_extension_map, ARRAY_SIZE(gl_extension_map));
     }
     hdc = wglGetCurrentDC();
@@ -4020,8 +4004,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter
*adapter,
     if (!WGL_Extensions)
         WARN("WGL extensions not supported.\n");
     else
-        parse_extension_string(gl_info, WGL_Extensions, wgl_extension_map,
-                sizeof(wgl_extension_map) / sizeof(*wgl_extension_map));
+        parse_extension_string(gl_info, WGL_Extensions, wgl_extension_map,
ARRAY_SIZE(wgl_extension_map));
     for (i = 0; i < ARRAY_SIZE(core_extensions); ++i)
     {
@@ -4233,9 +4216,17 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter
*adapter,
     if (gl_info->supported[ARB_TEXTURE_STORAGE] &&
gl_info->supported[APPLE_YCBCR_422])
     {
         /* AFAIK APPLE_ycbcr_422 is only available in legacy contexts so we shouldn't
ever hit this. */
-        FIXME("Disabling APPLE_ycbcr_422 because of ARB_texture_storage.\n");
+        ERR("Disabling APPLE_ycbcr_422 because of ARB_texture_storage.\n");
         gl_info->supported[APPLE_YCBCR_422] = FALSE;
     }
+    if (gl_info->supported[ARB_DRAW_INDIRECT] &&
!gl_info->supported[ARB_BASE_INSTANCE])
+    {
+        /* If ARB_base_instance is not supported the baseInstance field
+         * in indirect draw parameters must be 0 or behavior is undefined.
+         */
+        WARN("Disabling ARB_draw_indirect because ARB_base_instance is not
supported.\n");
+        gl_info->supported[ARB_DRAW_INDIRECT] = FALSE;
+    }
     wined3d_adapter_init_limits(gl_info);
@@ -4293,10 +4284,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter
*adapter,
     for (i = 0; i < gl_info->limits.buffers; ++i)
         adapter->d3d_info.valid_rt_mask |= (1u << i);
-    adapter->d3d_info.valid_dual_rt_mask = 0;
-    for (i = 0; i < gl_info->limits.dual_buffers; ++i)
-        adapter->d3d_info.valid_dual_rt_mask |= (1u << i);
-
     if (!adapter->d3d_info.shader_color_key)
     {
         /* We do not want to deal with re-creating immutable texture storage for color
keying emulation. */
@@ -5257,6 +5244,13 @@ static BOOL wined3d_check_surface_capability(const struct
wined3d_format *format
         return TRUE;
     }
+    if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_EXTENSION |
WINED3DFMT_FLAG_TEXTURE))
+            == (WINED3DFMT_FLAG_EXTENSION | WINED3DFMT_FLAG_TEXTURE))
+    {
+        TRACE("[OK]\n");
+        return TRUE;
+    }
+
     /* Reject other formats */
     TRACE("[FAILED]\n");
     return FALSE;
@@ -5276,10 +5270,9 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d
*wined3d, UINT ad
 {
     const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
-    const struct wined3d_format *adapter_format = wined3d_get_format(gl_info,
adapter_format_id,
-            WINED3DUSAGE_RENDERTARGET);
-    const struct wined3d_format *format = wined3d_get_format(gl_info, check_format_id,
usage);
+    const struct wined3d_format *adapter_format, *format;
     enum wined3d_gl_resource_type gl_type, gl_type_end;
+    BOOL mipmap_autogen_supported;
     DWORD format_flags = 0;
     DWORD allowed_usage;
@@ -5292,28 +5285,18 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d
*wined3d, UINT ad
     if (adapter_idx >= wined3d->adapter_count)
         return WINED3DERR_INVALIDCALL;
+    adapter_format = wined3d_get_format(gl_info, adapter_format_id,
WINED3DUSAGE_RENDERTARGET);
+    format = wined3d_get_format(gl_info, check_format_id, usage);
+
     switch (resource_type)
     {
         case WINED3D_RTYPE_NONE:
             allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                     | WINED3DUSAGE_RENDERTARGET;
-            gl_type = WINED3D_GL_RES_TYPE_TEX_1D;
+            gl_type = WINED3D_GL_RES_TYPE_TEX_2D;
             gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
             break;
-        case WINED3D_RTYPE_TEXTURE_1D:
-            allowed_usage = WINED3DUSAGE_DYNAMIC
-                    | WINED3DUSAGE_SOFTWAREPROCESSING
-                    | WINED3DUSAGE_TEXTURE
-                    | WINED3DUSAGE_QUERY_FILTER
-                    | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
-                    | WINED3DUSAGE_QUERY_SRGBREAD
-                    | WINED3DUSAGE_QUERY_SRGBWRITE
-                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE
-                    | WINED3DUSAGE_QUERY_WRAPANDMIP;
-            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_1D;
-            break;
-
         case WINED3D_RTYPE_TEXTURE_2D:
             allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                     | WINED3DUSAGE_RENDERTARGET
@@ -5370,12 +5353,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d
*wined3d, UINT ad
             gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
             break;
-        case WINED3D_RTYPE_BUFFER:
-            allowed_usage = WINED3DUSAGE_DYNAMIC
-                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE;
-            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_BUFFER;
-            break;
-
         default:
             FIXME("Unhandled resource type %s.\n",
debug_d3dresourcetype(resource_type));
             return WINED3DERR_NOTAVAILABLE;
@@ -5409,12 +5386,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d
*wined3d, UINT ad
         return WINED3DERR_NOTAVAILABLE;
     }
-    if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) &&
!gl_info->supported[SGIS_GENERATE_MIPMAP])
-    {
-        TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning
WINED3DOK_NOAUTOGEN.\n");
-        return WINED3DOK_NOAUTOGEN;
-    }
-
+    mipmap_autogen_supported = gl_info->supported[SGIS_GENERATE_MIPMAP];
     for (; gl_type <= gl_type_end; ++gl_type)
     {
         if ((format->flags[gl_type] & format_flags) != format_flags)
@@ -5443,6 +5415,18 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d
*wined3d, UINT ad
                     debug_d3dformat(check_format_id));
             return WINED3DERR_NOTAVAILABLE;
         }
+
+        if ((format->flags[gl_type] & (WINED3DFMT_FLAG_RENDERTARGET |
WINED3DFMT_FLAG_FILTERING))
+                != (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING))
+        {
+            mipmap_autogen_supported = FALSE;
+        }
+    }
+
+    if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_autogen_supported)
+    {
+        TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning
WINED3DOK_NOAUTOGEN.\n");
+        return WINED3DOK_NOAUTOGEN;
     }
     return WINED3D_OK;
@@ -5678,7 +5662,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d,
UINT adapte
                                      WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
                                      WINED3DPRASTERCAPS_DEPTHBIAS;
-    if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+    if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
     {
         caps->RasterCaps  |= WINED3DPRASTERCAPS_ANISOTROPY    |
                              WINED3DPRASTERCAPS_ZBIAS         |
@@ -5797,7 +5781,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d,
UINT adapte
                                WINED3DPTFILTERCAPS_MIPNEAREST       |
                                WINED3DPTFILTERCAPS_NEAREST;
-    if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+    if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
     {
         caps->TextureFilterCaps  |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
                                     WINED3DPTFILTERCAPS_MINFANISOTROPIC;
@@ -5818,7 +5802,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d,
UINT adapte
                                        WINED3DPTFILTERCAPS_MIPNEAREST       |
                                        WINED3DPTFILTERCAPS_NEAREST;
-        if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+        if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
         {
             caps->CubeTextureFilterCaps  |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
@@ -5978,10 +5962,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d
*wined3d, UINT adapte
     caps->MaxUserClipPlanes                = vertex_caps.max_user_clip_planes;
     caps->MaxActiveLights                  = vertex_caps.max_active_lights;
     caps->MaxVertexBlendMatrices           = vertex_caps.max_vertex_blend_matrices;
-    if (device_type == WINED3D_DEVICE_TYPE_HAL)
-        caps->MaxVertexBlendMatrixIndex    =
vertex_caps.max_vertex_blend_matrix_index;
-    else
-        caps->MaxVertexBlendMatrixIndex    = 255;
+    caps->MaxVertexBlendMatrixIndex        =
vertex_caps.max_vertex_blend_matrix_index;
     caps->VertexProcessingCaps             = vertex_caps.vertex_processing_caps;
     caps->FVFCaps                          = vertex_caps.fvf_caps;
     caps->RasterCaps                      |= vertex_caps.raster_caps;
@@ -6550,30 +6531,35 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter
*adapter, HDC dc
     }
 }
-static BOOL has_extension(const char *list, const char *ext)
+static DWORD get_max_gl_version(const struct wined3d_gl_info *gl_info, DWORD flags)
 {
-    size_t len = strlen(ext);
-    while (list)
-    {
-        while (*list == ' ') list++;
-        if (!strncmp(list, ext, len) && (!list[len] || list[len] == ' '))
return TRUE;
-        list = strchr(list, ' ');
-    }
-    return FALSE;
+    const char *gl_vendor, *gl_renderer;
+
+    if (wined3d_settings.explicit_gl_version || (flags &
WINED3D_PIXEL_CENTER_INTEGER))
+        return wined3d_settings.max_gl_version;
+
+    gl_vendor = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR);
+    gl_renderer = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER);
+    if (!gl_vendor || !gl_renderer
+            || wined3d_guess_card_vendor(gl_vendor, gl_renderer) == HW_VENDOR_NVIDIA)
+        return wined3d_settings.max_gl_version;
+
+    return MAKEDWORD_VERSION(4, 4);
 }
 static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD
wined3d_creation_flags)
 {
     static const DWORD supported_gl_versions[] =
     {
+        MAKEDWORD_VERSION(4, 4),
         MAKEDWORD_VERSION(3, 2),
         MAKEDWORD_VERSION(1, 0),
     };
     struct wined3d_gl_info *gl_info = &adapter->gl_info;
     struct wined3d_caps_gl_ctx caps_gl_ctx = {0};
-    DWORD max_gl_version = wined3d_settings.max_gl_version;
-    DISPLAY_DEVICEW display_device;
     unsigned int i;
+    DISPLAY_DEVICEW display_device;
+    DWORD max_gl_version;
     TRACE("adapter %p, ordinal %u.\n", adapter, ordinal);
@@ -6618,16 +6604,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter,
UINT ordinal,
         return FALSE;
     }
-    if (wined3d_creation_flags & WINED3D_REQUEST_D3D10)
-    {
-        const char *gl_extensions = (const char
*)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
-        if (!has_extension(gl_extensions, "GL_ARB_compatibility"))
-        {
-            ERR_(winediag)("GL_ARB_compatibility not supported, requesting context
with GL version 3.2.\n");
-            max_gl_version = MAKEDWORD_VERSION(3, 2);
-        }
-    }
-
+    max_gl_version = get_max_gl_version(gl_info, wined3d_creation_flags);
     for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
     {
         if (supported_gl_versions[i] <= max_gl_version)
@@ -6681,10 +6658,6 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter,
UINT ordinal,
         return FALSE;
     }
-    gl_info->fixed_polyoffset_scale =
wined3d_adapter_find_polyoffset_scale(&caps_gl_ctx, GL_DEPTH_COMPONENT);
-    if (gl_info->supported[ARB_DEPTH_BUFFER_FLOAT])
-        gl_info->float_polyoffset_scale =
wined3d_adapter_find_polyoffset_scale(&caps_gl_ctx, GL_DEPTH32F_STENCIL8);
-
     adapter->vram_bytes = adapter->driver_info.vram_bytes;
     adapter->vram_bytes_used = 0;
     TRACE("Emulating 0x%s bytes of video ram.\n",
wine_dbgstr_longlong(adapter->vram_bytes));
diff --git a/dll/directx/wine/wined3d/drawprim.c b/dll/directx/wine/wined3d/drawprim.c
index e876ba3368..fa6d508327 100644
--- a/dll/directx/wine/wined3d/drawprim.c
+++ b/dll/directx/wine/wined3d/drawprim.c
@@ -162,133 +162,6 @@ static void draw_primitive_arrays(struct wined3d_context *context,
const struct
     }
 }
-/* Context activation is done by the caller. */
-static void draw_primitive_arrays_indirect(struct wined3d_context *context, const struct
wined3d_state *state,
-        const void *idx_data, unsigned int idx_size, struct wined3d_buffer *buffer,
unsigned int offset)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-
-    if (!gl_info->supported[ARB_DRAW_INDIRECT])
-    {
-        FIXME("Indirect draw not supported.\n");
-        return;
-    }
-
-    wined3d_buffer_load(buffer, context, state);
-    GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->buffer_object));
-
-    if (idx_size)
-    {
-        GLenum idx_type = (idx_size == 2) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
-
-        GL_EXTCALL(glDrawElementsIndirect(state->gl_primitive_type, idx_type,
-                (const BYTE *)NULL + offset));
-    }
-    else
-    {
-        GL_EXTCALL(glDrawArraysIndirect(state->gl_primitive_type,
-                (const BYTE *)NULL + offset));
-    }
-
-    GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0));
-    checkGLcall("draw indirect");
-}
-
-static const BYTE *software_vertex_blending(struct wined3d_context *context,
-        const struct wined3d_state *state, const struct wined3d_stream_info *si,
-        unsigned int element_idx, unsigned int stride_idx, float *result)
-{
-#define SI_FORMAT(idx) (si->elements[(idx)].format->emit_idx)
-#define SI_PTR(idx1, idx2) (si->elements[(idx1)].data.addr +
si->elements[(idx1)].stride * (idx2))
-
-    const float *data = (const float *)SI_PTR(element_idx, stride_idx);
-    float vector[4] = {0.0f, 0.0f, 0.0f, 1.0f};
-    float cur_weight, weight_sum = 0.0f;
-    struct wined3d_matrix m;
-    const BYTE *blend_index;
-    const float *weights;
-    int i, num_weights;
-
-    if (element_idx != WINED3D_FFP_POSITION && element_idx != WINED3D_FFP_NORMAL)
-        return (BYTE *)data;
-
-    if (!use_indexed_vertex_blending(state, si) ||
!use_software_vertex_processing(context->device))
-        return (BYTE *)data;
-
-    if (!si->elements[WINED3D_FFP_BLENDINDICES].data.addr ||
-        !si->elements[WINED3D_FFP_BLENDWEIGHT].data.addr)
-    {
-        FIXME("no blend indices / weights set\n");
-        return (BYTE *)data;
-    }
-
-    if (SI_FORMAT(WINED3D_FFP_BLENDINDICES) != WINED3D_FFP_EMIT_UBYTE4)
-    {
-        FIXME("unsupported blend index format: %u\n",
SI_FORMAT(WINED3D_FFP_BLENDINDICES));
-        return (BYTE *)data;
-    }
-
-    /* FIXME: validate weight format */
-    switch (state->render_states[WINED3D_RS_VERTEXBLEND])
-    {
-        case WINED3D_VBF_0WEIGHTS: num_weights = 0; break;
-        case WINED3D_VBF_1WEIGHTS: num_weights = 1; break;
-        case WINED3D_VBF_2WEIGHTS: num_weights = 2; break;
-        case WINED3D_VBF_3WEIGHTS: num_weights = 3; break;
-        default:
-            FIXME("unsupported vertex blend render state: %u\n",
state->render_states[WINED3D_RS_VERTEXBLEND]);
-            return (BYTE *)data;
-    }
-
-    switch (SI_FORMAT(element_idx))
-    {
-        case WINED3D_FFP_EMIT_FLOAT4: vector[3] = data[3];
-        case WINED3D_FFP_EMIT_FLOAT3: vector[2] = data[2];
-        case WINED3D_FFP_EMIT_FLOAT2: vector[1] = data[1];
-        case WINED3D_FFP_EMIT_FLOAT1: vector[0] = data[0]; break;
-        default:
-            FIXME("unsupported value format: %u\n", SI_FORMAT(element_idx));
-            return (BYTE *)data;
-    }
-
-    blend_index = SI_PTR(WINED3D_FFP_BLENDINDICES, stride_idx);
-    weights = (const float *)SI_PTR(WINED3D_FFP_BLENDWEIGHT, stride_idx);
-    result[0] = result[1] = result[2] = result[3] = 0.0f;
-
-    for (i = 0; i < num_weights + 1; i++)
-    {
-        cur_weight = (i < num_weights) ? weights[i] : 1.0f - weight_sum;
-        get_modelview_matrix(context, state, blend_index[i], &m);
-
-        if (element_idx == WINED3D_FFP_POSITION)
-        {
-            result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._21 + vector[2]
* m._31 + vector[3] * m._41);
-            result[1] += cur_weight * (vector[0] * m._12 + vector[1] * m._22 + vector[2]
* m._32 + vector[3] * m._42);
-            result[2] += cur_weight * (vector[0] * m._13 + vector[1] * m._23 + vector[2]
* m._33 + vector[3] * m._43);
-            result[3] += cur_weight * (vector[0] * m._14 + vector[1] * m._24 + vector[2]
* m._34 + vector[3] * m._44);
-        }
-        else
-        {
-            if (context->d3d_info->wined3d_creation_flags &
WINED3D_LEGACY_FFP_LIGHTING)
-                invert_matrix_3d(&m, &m);
-            else
-                invert_matrix(&m, &m);
-
-            /* multiply with transposed M */
-            result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._12 + vector[2]
* m._13);
-            result[1] += cur_weight * (vector[0] * m._21 + vector[1] * m._22 + vector[2]
* m._23);
-            result[2] += cur_weight * (vector[0] * m._31 + vector[1] * m._32 + vector[2]
* m._33);
-        }
-
-        weight_sum += weights[i];
-    }
-
-#undef SI_FORMAT
-#undef SI_PTR
-
-    return (BYTE *)result;
-}
-
 static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size,
         unsigned int base_vertex_idx, unsigned int start_idx, unsigned int vertex_idx)
 {
@@ -317,7 +190,6 @@ static void draw_primitive_immediate_mode(struct wined3d_context
*context, const
     BOOL specular_fog = FALSE;
     BOOL ps = use_ps(state);
     const void *ptr;
-    float tmp[4];
     static unsigned int once;
@@ -354,7 +226,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context
*context, const
                 if (!(use_map & 1u << element_idx))
                     continue;
-                ptr = software_vertex_blending(context, state, si, element_idx,
stride_idx, tmp);
+                ptr = si->elements[element_idx].data.addr +
si->elements[element_idx].stride * stride_idx;
ops->generic[si->elements[element_idx].format->emit_idx](element_idx, ptr);
             }
         }
@@ -466,7 +338,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context
*context, const
         if (normal)
         {
-            ptr = software_vertex_blending(context, state, si, WINED3D_FFP_NORMAL,
stride_idx, tmp);
+            ptr = normal + stride_idx * si->elements[WINED3D_FFP_NORMAL].stride;
             ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptr);
         }
@@ -511,7 +383,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context
*context, const
         if (position)
         {
-            ptr = software_vertex_blending(context, state, si, WINED3D_FFP_POSITION,
stride_idx, tmp);
+            ptr = position + stride_idx * si->elements[WINED3D_FFP_POSITION].stride;
ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptr);
         }
     }
@@ -520,6 +392,39 @@ static void draw_primitive_immediate_mode(struct wined3d_context
*context, const
     checkGLcall("glEnd and previous calls");
 }
+static void draw_indirect(struct wined3d_context *context, const struct wined3d_state
*state,
+        const struct wined3d_indirect_draw_parameters *parameters, unsigned int idx_size)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct wined3d_buffer *buffer = parameters->buffer;
+
+    if (!gl_info->supported[ARB_DRAW_INDIRECT])
+    {
+        FIXME("OpenGL implementation does not support indirect draws.\n");
+        return;
+    }
+
+    GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->buffer_object));
+
+    if (idx_size)
+    {
+        GLenum idx_type = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
+        if (state->index_offset)
+            FIXME("Ignoring index offset %u.\n", state->index_offset);
+        GL_EXTCALL(glDrawElementsIndirect(state->gl_primitive_type, idx_type,
+                (void *)(GLintptr)parameters->offset));
+    }
+    else
+    {
+        GL_EXTCALL(glDrawArraysIndirect(state->gl_primitive_type,
+                (void *)(GLintptr)parameters->offset));
+    }
+
+    GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0));
+
+    checkGLcall("draw indirect");
+}
+
 static void remove_vbos(struct wined3d_context *context,
         const struct wined3d_state *state, struct wined3d_stream_info *s)
 {
@@ -637,7 +542,7 @@ void draw_primitive(struct wined3d_device *device, const struct
wined3d_state *s
         if (!(rtv = fb->render_targets[i]) || rtv->format->id ==
WINED3DFMT_NULL)
             continue;
-        if (state->render_states[WINED3D_RS_COLORWRITE(i)])
+        if (state->render_states[WINED3D_RS_COLORWRITEENABLE])
         {
             wined3d_rendertarget_view_load_location(rtv, context,
rtv->resource->draw_binding);
             wined3d_rendertarget_view_invalidate_location(rtv,
~rtv->resource->draw_binding);
@@ -663,6 +568,9 @@ void draw_primitive(struct wined3d_device *device, const struct
wined3d_state *s
             wined3d_rendertarget_view_prepare_location(dsv, context, location);
     }
+    if (parameters->indirect)
+        wined3d_buffer_load(parameters->u.indirect.buffer, context, state);
+
     if (!context_apply_draw_state(context, device, state))
     {
         context_release(context);
@@ -726,11 +634,6 @@ void draw_primitive(struct wined3d_device *device, const struct
wined3d_state *s
                 WARN_(d3d_perf)("Using software emulation because manual fog
coordinates are provided.\n");
             emulation = TRUE;
         }
-        else if (use_indexed_vertex_blending(state, stream_info) &&
use_software_vertex_processing(context->device))
-        {
-            WARN_(d3d_perf)("Using software emulation because application requested
SVP.\n");
-            emulation = TRUE;
-        }
         if (emulation)
         {
@@ -744,7 +647,7 @@ void draw_primitive(struct wined3d_device *device, const struct
wined3d_state *s
     {
         const struct wined3d_shader *shader =
state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
-        if (shader->u.gs.so_desc.rasterizer_stream_idx ==
WINED3D_NO_RASTERIZER_STREAM)
+        if (is_rasterization_disabled(shader))
         {
             glEnable(GL_RASTERIZER_DISCARD);
             checkGLcall("enable rasterizer discard");
@@ -774,11 +677,10 @@ void draw_primitive(struct wined3d_device *device, const struct
wined3d_state *s
     if (parameters->indirect)
     {
-        if (context->use_immediate_mode_draw || emulation)
-            FIXME("Indirect draw with immediate mode/emulation is not
supported.\n");
+        if (!context->use_immediate_mode_draw && !emulation)
+            draw_indirect(context, state, ¶meters->u.indirect, idx_size);
         else
-            draw_primitive_arrays_indirect(context, state, idx_data, idx_size,
-                    parameters->u.indirect.buffer, parameters->u.indirect.offset);
+            FIXME("Indirect draws with immediate mode/emulation are not
supported.\n");
     }
     else
     {
@@ -845,6 +747,9 @@ void dispatch_compute(struct wined3d_device *device, const struct
wined3d_state
         return;
     }
+    if (parameters->indirect)
+        wined3d_buffer_load(parameters->u.indirect.buffer, context, state);
+
     context_apply_compute_state(context, device, state);
     if (!state->shader[WINED3D_SHADER_TYPE_COMPUTE])
@@ -859,7 +764,6 @@ void dispatch_compute(struct wined3d_device *device, const struct
wined3d_state
         const struct wined3d_indirect_dispatch_parameters *indirect =
¶meters->u.indirect;
         struct wined3d_buffer *buffer = indirect->buffer;
-        wined3d_buffer_load(buffer, context, state);
         GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer->buffer_object));
         GL_EXTCALL(glDispatchComputeIndirect((GLintptr)indirect->offset));
         GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0));
diff --git a/dll/directx/wine/wined3d/glsl_shader.c
b/dll/directx/wine/wined3d/glsl_shader.c
index 6d17358dac..3796865340 100644
--- a/dll/directx/wine/wined3d/glsl_shader.c
+++ b/dll/directx/wine/wined3d/glsl_shader.c
@@ -82,7 +82,6 @@ struct glsl_sample_function
     enum wined3d_data_type data_type;
     BOOL output_single_component;
     unsigned int offset_size;
-    enum wined3d_shader_resource_type emulate_lod;
 };
 enum heap_node_op
@@ -135,9 +134,9 @@ struct glsl_vs_program
     GLint uniform_b_locations[WINED3D_MAX_CONSTS_B];
     GLint pos_fixup_location;
-    GLint modelview_matrix_location[MAX_VERTEX_INDEX_BLENDS];
-    GLint normal_matrix_location[MAX_VERTEX_INDEX_BLENDS];
+    GLint modelview_matrix_location[MAX_VERTEX_BLENDS];
     GLint projection_matrix_location;
+    GLint normal_matrix_location;
     GLint texture_matrix_location[MAX_TEXTURES];
     GLint material_ambient_location;
     GLint material_diffuse_location;
@@ -233,7 +232,10 @@ struct glsl_shader_prog_link
     struct glsl_cs_program cs;
     GLuint id;
     DWORD constant_update_mask;
-    UINT constant_version;
+    unsigned int constant_version;
+    DWORD shader_controlled_clip_distances : 1;
+    DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */
+    DWORD padding : 23;
 };
 struct glsl_program_key
@@ -258,6 +260,7 @@ struct glsl_context_data
 {
     struct glsl_shader_prog_link *glsl_program;
     GLenum vertex_color_clamp;
+    BOOL rasterization_disabled;
 };
 struct glsl_ps_compiled_shader
@@ -378,7 +381,9 @@ static const char *shader_glsl_get_prefix(enum wined3d_shader_type
type)
 static unsigned int shader_glsl_get_version(const struct wined3d_gl_info *gl_info)
 {
-    if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50))
+    if (gl_info->glsl_version >= MAKEDWORD_VERSION(4, 40))
+        return 440;
+    else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50))
         return 150;
     else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30))
         return 130;
@@ -828,12 +833,23 @@ static void shader_glsl_generate_transform_feedback_varyings(const
struct wined3
             if (e->component_idx || e->component_count != 4)
             {
-                FIXME("Unsupported component range %u-%u.\n",
e->component_idx, e->component_count);
-                continue;
-            }
+                if (so_desc->rasterizer_stream_idx != WINED3D_NO_RASTERIZER_STREAM)
+                {
+                    FIXME("Unsupported component range %u-%u.\n",
e->component_idx, e->component_count);
+                    append_transform_feedback_skip_components(varyings, &count,
+                            &strings, &length, buffer, e->component_count);
+                    continue;
+                }
-            string_buffer_sprintf(buffer, "shader_in_out.reg[%u]",
e->register_idx);
-            append_transform_feedback_varying(varyings, &count, &strings,
&length, buffer);
+                string_buffer_sprintf(buffer, "shader_in_out.reg%u_%u_%u",
+                        e->register_idx, e->component_idx, e->component_idx +
e->component_count - 1);
+                append_transform_feedback_varying(varyings, &count, &strings,
&length, buffer);
+            }
+            else
+            {
+                string_buffer_sprintf(buffer, "shader_in_out.reg%u",
e->register_idx);
+                append_transform_feedback_varying(varyings, &count, &strings,
&length, buffer);
+            }
         }
         if (buffer_idx < so_desc->buffer_stride_count
@@ -1212,6 +1228,320 @@ static void shader_glsl_load_np2fixup_constants(const struct
glsl_ps_program *ps
     GL_EXTCALL(glUniform4fv(ps->np2_fixup_location,
ps->np2_fixup_info->num_consts, &np2fixup_constants[0].sx));
 }
+/* Taken and adapted from Mesa. */
+static BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in)
+{
+    float pos, neg, t, det;
+    struct wined3d_matrix temp;
+
+    /* Calculate the determinant of upper left 3x3 submatrix and
+     * determine if the matrix is singular. */
+    pos = neg = 0.0f;
+    t =  in->_11 * in->_22 * in->_33;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+
+    t =  in->_21 * in->_32 * in->_13;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+    t =  in->_31 * in->_12 * in->_23;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+
+    t = -in->_31 * in->_22 * in->_13;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+    t = -in->_21 * in->_12 * in->_33;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+
+    t = -in->_11 * in->_32 * in->_23;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+
+    det = pos + neg;
+
+    if (fabsf(det) < 1e-25f)
+        return FALSE;
+
+    det = 1.0f / det;
+    temp._11 =  (in->_22 * in->_33 - in->_32 * in->_23) * det;
+    temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det;
+    temp._13 =  (in->_12 * in->_23 - in->_22 * in->_13) * det;
+    temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det;
+    temp._22 =  (in->_11 * in->_33 - in->_31 * in->_13) * det;
+    temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det;
+    temp._31 =  (in->_21 * in->_32 - in->_31 * in->_22) * det;
+    temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det;
+    temp._33 =  (in->_11 * in->_22 - in->_21 * in->_12) * det;
+
+    *out = temp;
+    return TRUE;
+}
+
+static void swap_rows(float **a, float **b)
+{
+    float *tmp = *a;
+
+    *a = *b;
+    *b = tmp;
+}
+
+static BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m)
+{
+    float wtmp[4][8];
+    float m0, m1, m2, m3, s;
+    float *r0, *r1, *r2, *r3;
+
+    r0 = wtmp[0];
+    r1 = wtmp[1];
+    r2 = wtmp[2];
+    r3 = wtmp[3];
+
+    r0[0] = m->_11;
+    r0[1] = m->_12;
+    r0[2] = m->_13;
+    r0[3] = m->_14;
+    r0[4] = 1.0f;
+    r0[5] = r0[6] = r0[7] = 0.0f;
+
+    r1[0] = m->_21;
+    r1[1] = m->_22;
+    r1[2] = m->_23;
+    r1[3] = m->_24;
+    r1[5] = 1.0f;
+    r1[4] = r1[6] = r1[7] = 0.0f;
+
+    r2[0] = m->_31;
+    r2[1] = m->_32;
+    r2[2] = m->_33;
+    r2[3] = m->_34;
+    r2[6] = 1.0f;
+    r2[4] = r2[5] = r2[7] = 0.0f;
+
+    r3[0] = m->_41;
+    r3[1] = m->_42;
+    r3[2] = m->_43;
+    r3[3] = m->_44;
+    r3[7] = 1.0f;
+    r3[4] = r3[5] = r3[6] = 0.0f;
+
+    /* Choose pivot - or die. */
+    if (fabsf(r3[0]) > fabsf(r2[0]))
+        swap_rows(&r3, &r2);
+    if (fabsf(r2[0]) > fabsf(r1[0]))
+        swap_rows(&r2, &r1);
+    if (fabsf(r1[0]) > fabsf(r0[0]))
+        swap_rows(&r1, &r0);
+    if (r0[0] == 0.0f)
+        return FALSE;
+
+    /* Eliminate first variable. */
+    m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0];
+    s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
+    s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
+    s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
+    s = r0[4];
+    if (s != 0.0f)
+    {
+        r1[4] -= m1 * s;
+        r2[4] -= m2 * s;
+        r3[4] -= m3 * s;
+    }
+    s = r0[5];
+    if (s != 0.0f)
+    {
+        r1[5] -= m1 * s;
+        r2[5] -= m2 * s;
+        r3[5] -= m3 * s;
+    }
+    s = r0[6];
+    if (s != 0.0f)
+    {
+        r1[6] -= m1 * s;
+        r2[6] -= m2 * s;
+        r3[6] -= m3 * s;
+    }
+    s = r0[7];
+    if (s != 0.0f)
+    {
+        r1[7] -= m1 * s;
+        r2[7] -= m2 * s;
+        r3[7] -= m3 * s;
+    }
+
+    /* Choose pivot - or die. */
+    if (fabsf(r3[1]) > fabsf(r2[1]))
+        swap_rows(&r3, &r2);
+    if (fabsf(r2[1]) > fabsf(r1[1]))
+        swap_rows(&r2, &r1);
+    if (r1[1] == 0.0f)
+        return FALSE;
+
+    /* Eliminate second variable. */
+    m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1];
+    r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
+    r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
+    s = r1[4];
+    if (s != 0.0f)
+    {
+        r2[4] -= m2 * s;
+        r3[4] -= m3 * s;
+    }
+    s = r1[5];
+    if (s != 0.0f)
+    {
+        r2[5] -= m2 * s;
+        r3[5] -= m3 * s;
+    }
+    s = r1[6];
+    if (s != 0.0f)
+    {
+        r2[6] -= m2 * s;
+        r3[6] -= m3 * s;
+    }
+    s = r1[7];
+    if (s != 0.0f)
+    {
+        r2[7] -= m2 * s;
+        r3[7] -= m3 * s;
+    }
+
+    /* Choose pivot - or die. */
+    if (fabsf(r3[2]) > fabsf(r2[2]))
+        swap_rows(&r3, &r2);
+    if (r2[2] == 0.0f)
+        return FALSE;
+
+    /* Eliminate third variable. */
+    m3 = r3[2] / r2[2];
+    r3[3] -= m3 * r2[3];
+    r3[4] -= m3 * r2[4];
+    r3[5] -= m3 * r2[5];
+    r3[6] -= m3 * r2[6];
+    r3[7] -= m3 * r2[7];
+
+    /* Last check. */
+    if (r3[3] == 0.0f)
+        return FALSE;
+
+    /* Back substitute row 3. */
+    s = 1.0f / r3[3];
+    r3[4] *= s;
+    r3[5] *= s;
+    r3[6] *= s;
+    r3[7] *= s;
+
+    /* Back substitute row 2. */
+    m2 = r2[3];
+    s = 1.0f / r2[2];
+    r2[4] = s * (r2[4] - r3[4] * m2);
+    r2[5] = s * (r2[5] - r3[5] * m2);
+    r2[6] = s * (r2[6] - r3[6] * m2);
+    r2[7] = s * (r2[7] - r3[7] * m2);
+    m1 = r1[3];
+    r1[4] -= r3[4] * m1;
+    r1[5] -= r3[5] * m1;
+    r1[6] -= r3[6] * m1;
+    r1[7] -= r3[7] * m1;
+    m0 = r0[3];
+    r0[4] -= r3[4] * m0;
+    r0[5] -= r3[5] * m0;
+    r0[6] -= r3[6] * m0;
+    r0[7] -= r3[7] * m0;
+
+    /* Back substitute row 1. */
+    m1 = r1[2];
+    s = 1.0f / r1[1];
+    r1[4] = s * (r1[4] - r2[4] * m1);
+    r1[5] = s * (r1[5] - r2[5] * m1);
+    r1[6] = s * (r1[6] - r2[6] * m1);
+    r1[7] = s * (r1[7] - r2[7] * m1);
+    m0 = r0[2];
+    r0[4] -= r2[4] * m0;
+    r0[5] -= r2[5] * m0;
+    r0[6] -= r2[6] * m0;
+    r0[7] -= r2[7] * m0;
+
+    /* Back substitute row 0. */
+    m0 = r0[1];
+    s = 1.0f / r0[0];
+    r0[4] = s * (r0[4] - r1[4] * m0);
+    r0[5] = s * (r0[5] - r1[5] * m0);
+    r0[6] = s * (r0[6] - r1[6] * m0);
+    r0[7] = s * (r0[7] - r1[7] * m0);
+
+    out->_11 = r0[4];
+    out->_12 = r0[5];
+    out->_13 = r0[6];
+    out->_14 = r0[7];
+    out->_21 = r1[4];
+    out->_22 = r1[5];
+    out->_23 = r1[6];
+    out->_24 = r1[7];
+    out->_31 = r2[4];
+    out->_32 = r2[5];
+    out->_33 = r2[6];
+    out->_34 = r2[7];
+    out->_41 = r3[4];
+    out->_42 = r3[5];
+    out->_43 = r3[6];
+    out->_44 = r3[7];
+
+    return TRUE;
+}
+
+static void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m)
+{
+    struct wined3d_matrix temp;
+    unsigned int i, j;
+
+    for (i = 0; i < 4; ++i)
+        for (j = 0; j < 4; ++j)
+            (&temp._11)[4 * j + i] = (&m->_11)[4 * i + j];
+
+    *out = temp;
+}
+
+static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_context
*context,
+        const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    float mat[3 * 3];
+    struct wined3d_matrix mv;
+    unsigned int i, j;
+
+    if (prog->vs.normal_matrix_location == -1)
+        return;
+
+    get_modelview_matrix(context, state, 0, &mv);
+    if (context->d3d_info->wined3d_creation_flags &
WINED3D_LEGACY_FFP_LIGHTING)
+        invert_matrix_3d(&mv, &mv);
+    else
+        invert_matrix(&mv, &mv);
+    /* Tests show that singular modelview matrices are used unchanged as normal
+     * matrices on D3D3 and older. There seems to be no clearly consistent
+     * behavior on newer D3D versions so always follow older ddraw behavior. */
+    for (i = 0; i < 3; ++i)
+        for (j = 0; j < 3; ++j)
+            mat[i * 3 + j] = (&mv._11)[j * 4 + i];
+
+    GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location, 1, FALSE, mat));
+    checkGLcall("glUniformMatrix3fv");
+}
+
 static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context
*context,
         const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link
*prog)
 {
@@ -1382,13 +1712,18 @@ static void shader_glsl_clip_plane_uniform(const struct
wined3d_context *context
         const struct wined3d_state *state, unsigned int index, struct
glsl_shader_prog_link *prog)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct wined3d_matrix matrix;
     struct wined3d_vec4 plane;
+    plane = state->clip_planes[index];
+
     /* Clip planes are affected by the view transform in d3d for FFP draws. */
     if (!use_vs(state))
-        multiply_vector_matrix(&plane, &state->clip_planes[index],
&state->transforms[WINED3D_TS_VIEW]);
-    else
-        plane = state->clip_planes[index];
+    {
+        invert_matrix(&matrix, &state->transforms[WINED3D_TS_VIEW]);
+        transpose_matrix(&matrix, &matrix);
+        multiply_vector_matrix(&plane, &plane, &matrix);
+    }
     GL_EXTCALL(glUniform4fv(prog->vs.clip_planes_location + index, 1, &plane.x));
 }
@@ -1404,23 +1739,6 @@ static void shader_glsl_load_color_key_constant(const struct
glsl_ps_program *ps
     GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r));
 }
-/* Context activation is done by the caller. */
-static void get_normal_matrix(struct wined3d_context *context, struct wined3d_matrix
*mat, float *normal)
-{
-    int i, j;
-
-    if (context->d3d_info->wined3d_creation_flags &
WINED3D_LEGACY_FFP_LIGHTING)
-        invert_matrix_3d(mat, mat);
-    else
-        invert_matrix(mat, mat);
-    /* Tests show that singular modelview matrices are used unchanged as normal
-     * matrices on D3D3 and older. There seems to be no clearly consistent
-     * behavior on newer D3D versions so always follow older ddraw behavior. */
-    for (i = 0; i < 3; ++i)
-        for (j = 0; j < 3; ++j)
-            normal[i * 3 + j] = (&mat->_11)[j * 4 + i];
-}
-
 /* Context activation is done by the caller (state handler). */
 static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
*context,
         const struct wined3d_state *state)
@@ -1431,7 +1749,6 @@ static void shader_glsl_load_constants(void *shader_priv, struct
wined3d_context
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_priv *priv = shader_priv;
     float position_fixup[4];
-    float normal[3 * 3];
     DWORD update_mask;
     struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
@@ -1486,29 +1803,21 @@ static void shader_glsl_load_constants(void *shader_priv, struct
wined3d_context
         GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE,
&mat._11));
         checkGLcall("glUniformMatrix4fv");
-        get_normal_matrix(context, &mat, normal);
-        GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[0], 1, FALSE,
normal));
-        checkGLcall("glUniformMatrix3fv");
+        shader_glsl_ffp_vertex_normalmatrix_uniform(context, state, prog);
     }
     if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND)
     {
         struct wined3d_matrix mat;
-        for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i)
+        for (i = 1; i < MAX_VERTEX_BLENDS; ++i)
         {
             if (prog->vs.modelview_matrix_location[i] == -1)
                 break;
-            if (!(update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i)))
-                continue;
             get_modelview_matrix(context, state, i, &mat);
             GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1,
FALSE, &mat._11));
             checkGLcall("glUniformMatrix4fv");
-
-            get_normal_matrix(context, &mat, normal);
-            GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[i], 1,
FALSE, normal));
-            checkGLcall("glUniformMatrix3fv");
         }
     }
@@ -1839,22 +2148,97 @@ static const char *shader_glsl_shader_output_name(const struct
wined3d_gl_info *
     return shader_glsl_use_interface_blocks(gl_info) ? "shader_out.reg" :
"ps_link";
 }
+static const char *shader_glsl_interpolation_qualifiers(enum
wined3d_shader_interpolation_mode mode)
+{
+    switch (mode)
+    {
+        case WINED3DSIM_CONSTANT:
+            return "flat";
+        case WINED3DSIM_LINEAR_NOPERSPECTIVE:
+            return "noperspective";
+        default:
+            FIXME("Unhandled interpolation mode %#x.\n", mode);
+        case WINED3DSIM_NONE:
+        case WINED3DSIM_LINEAR:
+            return "";
+    }
+}
+
+static enum wined3d_shader_interpolation_mode wined3d_extract_interpolation_mode(
+        const DWORD *packed_interpolation_mode, unsigned int register_idx)
+{
+    return wined3d_extract_bits(packed_interpolation_mode,
+            register_idx * WINED3D_PACKED_INTERPOLATION_BIT_COUNT,
WINED3D_PACKED_INTERPOLATION_BIT_COUNT);
+}
+
 static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_info,
-        struct wined3d_string_buffer *buffer, unsigned int element_count)
+        struct wined3d_string_buffer *buffer, unsigned int element_count,
+        const DWORD *interpolation_mode, BOOL unroll)
 {
+    enum wined3d_shader_interpolation_mode mode;
+    unsigned int i;
+
     if (shader_glsl_use_interface_blocks(gl_info))
-        shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; }
shader_in;\n", element_count);
+    {
+        if (unroll)
+        {
+            shader_addline(buffer, "in shader_in_out {\n");
+            for (i = 0; i < element_count; ++i)
+            {
+                mode = wined3d_extract_interpolation_mode(interpolation_mode, i);
+                shader_addline(buffer, "%s vec4 reg%u;\n",
shader_glsl_interpolation_qualifiers(mode), i);
+            }
+            shader_addline(buffer, "} shader_in;\n");
+        }
+        else
+        {
+            shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; }
shader_in;\n", element_count);
+        }
+    }
     else
+    {
         declare_in_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n",
element_count);
+    }
 }
 static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_info,
-        struct wined3d_string_buffer *buffer, unsigned int element_count)
+        struct wined3d_string_buffer *buffer, unsigned int element_count, BOOL
rasterizer_setup,
+        const DWORD *interpolation_mode)
 {
+    enum wined3d_shader_interpolation_mode mode;
+    unsigned int i;
+
     if (shader_glsl_use_interface_blocks(gl_info))
-        shader_addline(buffer, "out shader_in_out { vec4 reg[%u]; }
shader_out;\n", element_count);
+    {
+        if (rasterizer_setup)
+        {
+            shader_addline(buffer, "out shader_in_out {\n");
+            for (i = 0; i < element_count; ++i)
+            {
+                const char *interpolation_qualifiers = "";
+                if (needs_interpolation_qualifiers_for_shader_outputs(gl_info))
+                {
+                    mode = wined3d_extract_interpolation_mode(interpolation_mode, i);
+                    interpolation_qualifiers =
shader_glsl_interpolation_qualifiers(mode);
+                }
+                shader_addline(buffer, "%s vec4 reg%u;\n",
interpolation_qualifiers, i);
+            }
+            shader_addline(buffer, "} shader_out;\n");
+        }
+        else
+        {
+            shader_addline(buffer, "out shader_in_out { vec4 reg[%u]; }
shader_out;\n", element_count);
+        }
+    }
     else
+    {
         declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n",
element_count);
+    }
+}
+
+static const char *get_fragment_output(const struct wined3d_gl_info *gl_info)
+{
+    return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" :
"ps_out";
 }
 static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type
primitive_type)
@@ -2184,13 +2568,6 @@ static void shader_generate_glsl_declarations(const struct
wined3d_context *cont
                     sampler_type = "samplerCube";
                 break;
-            case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY:
-                if (shadow_sampler)
-                    sampler_type = "sampler1DArrayShadow";
-                else
-                    sampler_type = "sampler1DArray";
-                break;
-
             case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
                 if (shadow_sampler)
                     sampler_type = "sampler2DArrayShadow";
@@ -2347,12 +2724,6 @@ static void shader_generate_glsl_declarations(const struct
wined3d_context *cont
     }
 }
-/*****************************************************************************
- * Functions to generate GLSL strings from DirectX Shader bytecode begin here.
- *
- * For more information, see 
http://wiki.winehq.org/DirectX-Shaders
- ****************************************************************************/
-
 /* Prototypes */
 static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
         const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct
glsl_src_param *glsl_src);
@@ -2441,7 +2812,8 @@ static void shader_glsl_fixup_scalar_register_variable(char
*register_name,
 /** Writes the GLSL variable name that corresponds to the register that the
  * DX opcode parameter is trying to access */
 static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg,
-        char *register_name, BOOL *is_color, const struct wined3d_shader_instruction
*ins)
+        enum wined3d_data_type data_type, char *register_name, BOOL *is_color,
+        const struct wined3d_shader_instruction *ins)
 {
     /* oPos, oFog and oPts in D3D */
     static const char * const hwrastout_reg_names[] = {"vs_out[10]",
"vs_out[11].x", "vs_out[11].y"};
@@ -2473,10 +2845,18 @@ static void shader_glsl_get_register_name(const struct
wined3d_shader_register *
                 struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
                 if (reg->idx[0].rel_addr)
-                    FIXME("VS3+ input registers relative addressing.\n");
+                    FIXME("VS3 input registers relative addressing.\n");
                 if (priv->cur_vs_args->swizzle_map & (1u <<
reg->idx[0].offset))
                     *is_color = TRUE;
-                sprintf(register_name, "%s_in%u", prefix,
reg->idx[0].offset);
+                if (reg->idx[0].rel_addr)
+                {
+                    sprintf(register_name, "%s_in[%s + %u]",
+                            prefix, rel_param0.param_str, reg->idx[0].offset);
+                }
+                else
+                {
+                    sprintf(register_name, "%s_in%u", prefix,
reg->idx[0].offset);
+                }
                 break;
             }
@@ -2610,22 +2990,20 @@ static void shader_glsl_get_register_name(const struct
wined3d_shader_register *
             break;
         case WINED3DSPR_COLOROUT:
-            /* FIXME: should check dual_buffers when dual blending is enabled */
             if (reg->idx[0].offset >= gl_info->limits.buffers)
                 WARN("Write to render target %u, only %d supported.\n",
                         reg->idx[0].offset, gl_info->limits.buffers);
-            sprintf(register_name, needs_legacy_glsl_syntax(gl_info) ?
"gl_FragData[%u]" : "ps_out%u",
-                    reg->idx[0].offset);
+            sprintf(register_name, "%s[%u]", get_fragment_output(gl_info),
reg->idx[0].offset);
             break;
         case WINED3DSPR_RASTOUT:
             sprintf(register_name, "%s",
hwrastout_reg_names[reg->idx[0].offset]);
             break;
-        case WINED3DSPR_DEPTHOUT_GREATER_EQUAL:
-        case WINED3DSPR_DEPTHOUT_LESS_EQUAL:
         case WINED3DSPR_DEPTHOUT:
+        case WINED3DSPR_DEPTHOUTGE:
+        case WINED3DSPR_DEPTHOUTLE:
             sprintf(register_name, "gl_FragDepth");
             break;
@@ -2668,7 +3046,7 @@ static void shader_glsl_get_register_name(const struct
wined3d_shader_register *
             switch (reg->immconst_type)
             {
                 case WINED3D_IMMCONST_SCALAR:
-                    switch (reg->data_type)
+                    switch (data_type)
                     {
                         case WINED3D_DATA_FLOAT:
                             if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
@@ -2685,13 +3063,13 @@ static void shader_glsl_get_register_name(const struct
wined3d_shader_register *
                             sprintf(register_name, "%#xu",
reg->u.immconst_data[0]);
                             break;
                         default:
-                            sprintf(register_name, "<unhandled data type
%#x>", reg->data_type);
+                            sprintf(register_name, "<unhandled data type
%#x>", data_type);
                             break;
                     }
                     break;
                 case WINED3D_IMMCONST_VEC4:
-                    switch (reg->data_type)
+                    switch (data_type)
                     {
                         case WINED3D_DATA_FLOAT:
                             if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
@@ -2723,7 +3101,7 @@ static void shader_glsl_get_register_name(const struct
wined3d_shader_register *
                                     reg->u.immconst_data[2],
reg->u.immconst_data[3]);
                             break;
                         default:
-                            sprintf(register_name, "<unhandled data type
%#x>", reg->data_type);
+                            sprintf(register_name, "<unhandled data type
%#x>", data_type);
                             break;
                     }
                     break;
@@ -2967,7 +3345,7 @@ static void shader_glsl_add_src_param_ext(const struct
wined3d_shader_instructio
     glsl_src->param_str[0] = '\0';
     swizzle_str[0] = '\0';
-    shader_glsl_get_register_name(&wined3d_src->reg, glsl_src->reg_name,
&is_color, ins);
+    shader_glsl_get_register_name(&wined3d_src->reg, data_type,
glsl_src->reg_name, &is_color, ins);
     shader_glsl_get_swizzle(wined3d_src, is_color, mask, swizzle_str);
     switch (wined3d_src->reg.type)
@@ -3014,7 +3392,8 @@ static DWORD shader_glsl_add_dst_param(const struct
wined3d_shader_instruction *
     glsl_dst->mask_str[0] = '\0';
     glsl_dst->reg_name[0] = '\0';
-    shader_glsl_get_register_name(&wined3d_dst->reg, glsl_dst->reg_name,
&is_color, ins);
+    shader_glsl_get_register_name(&wined3d_dst->reg,
wined3d_dst->reg.data_type,
+            glsl_dst->reg_name, &is_color, ins);
     return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str);
 }
@@ -3131,7 +3510,6 @@ static void shader_glsl_get_sample_function(const struct
wined3d_shader_context
     enum wined3d_shader_resource_type resource_type =
ctx->reg_maps->resource_info[resource_idx].type;
     struct shader_glsl_ctx_priv *priv = ctx->backend_data;
     const struct wined3d_gl_info *gl_info = ctx->gl_info;
-    BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
     BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args,
resource_idx, sampler_idx);
     BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
     BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
@@ -3144,7 +3522,6 @@ static void shader_glsl_get_sample_function(const struct
wined3d_shader_context
     unsigned int coord_size, deriv_size;
     sample_function->data_type =
ctx->reg_maps->resource_info[resource_idx].data_type;
-    sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE;
     if (resource_type >= ARRAY_SIZE(resource_type_info))
     {
@@ -3156,30 +3533,7 @@ static void shader_glsl_get_sample_function(const struct
wined3d_shader_context
     if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
         projected = FALSE;
-    if (shadow && lod)
-    {
-        switch (resource_type)
-        {
-            /* emulate textureLod(sampler2DArrayShadow, ...) using textureGradOffset */
-            case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
-                sample_function->emulate_lod = resource_type;
-                grad = offset = TRUE;
-                lod = FALSE;
-                break;
-
-            /* emulate textureLod(samplerCubeShadow, ...) using shadowCubeGrad */
-            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
-                sample_function->emulate_lod = resource_type;
-                grad = legacy_syntax = TRUE;
-                lod = FALSE;
-                break;
-
-            default:
-                break;
-        }
-    }
-
-    if (legacy_syntax)
+    if (needs_legacy_glsl_syntax(gl_info))
     {
         if (shadow)
             base = "shadow";
@@ -3219,7 +3573,7 @@ static void shader_glsl_get_sample_function(const struct
wined3d_shader_context
     sample_function->offset_size = offset ? deriv_size : 0;
     sample_function->coord_mask = (1u << coord_size) - 1;
     sample_function->deriv_mask = (1u << deriv_size) - 1;
-    sample_function->output_single_component = shadow && !legacy_syntax;
+    sample_function->output_single_component = shadow &&
!needs_legacy_glsl_syntax(gl_info);
 }
 static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx,
@@ -3331,7 +3685,7 @@ static void shader_glsl_color_correction(const struct
wined3d_shader_instruction
     char reg_name[256];
     BOOL is_color;
-    shader_glsl_get_register_name(&ins->dst[0].reg, reg_name, &is_color, ins);
+    shader_glsl_get_register_name(&ins->dst[0].reg, ins->dst[0].reg.data_type,
reg_name, &is_color, ins);
     shader_glsl_color_correction_ext(ins->ctx->buffer, reg_name,
ins->dst[0].write_mask, fixup);
 }
@@ -3340,7 +3694,6 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const
struct wined3d_
         const char *dx, const char *dy, const char *bias, const struct
wined3d_shader_texel_offset *offset,
         const char *coord_reg_fmt, ...)
 {
-    static const struct wined3d_shader_texel_offset dummy_offset = {0, 0, 0};
     const struct wined3d_shader_version *version =
&ins->ctx->reg_maps->shader_version;
     char dst_swizzle[6];
     struct color_fixup_desc fixup;
@@ -3409,26 +3762,6 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const
struct wined3d_
                 break;
         }
     }
-    if (sample_function->emulate_lod)
-    {
-        if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod
level %s\n", bias);
-        switch (sample_function->emulate_lod)
-        {
-            case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
-                if (!dx) dx = "vec2(0.0, 0.0)";
-                if (!dy) dy = "vec2(0.0, 0.0)";
-                break;
-
-            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
-                if (!dx) dx = "vec3(0.0, 0.0, 0.0)";
-                if (!dy) dy = "vec3(0.0, 0.0, 0.0)";
-                break;
-
-            default:
-                break;
-        }
-        if (!offset) offset = &dummy_offset;
-    }
     if (dx && dy)
         shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy);
     else if (bias)
@@ -4750,13 +5083,20 @@ static void shader_glsl_default(const struct
wined3d_shader_instruction *ins)
     shader_addline(ins->ctx->buffer, "default:\n");
 }
-static void shader_glsl_if(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_generate_conditional_op(const struct wined3d_shader_instruction
*ins,
+        const char *op)
 {
-    const char *condition = (ins->flags == WINED3D_SHADER_CONDITIONAL_OP_NZ) ?
"bool" : "!bool";
-    struct glsl_src_param src0_param;
+    struct glsl_src_param src_param;
+    const char *condition;
-    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0,
&src0_param);
-    shader_addline(ins->ctx->buffer, "if (%s(%s)) {\n", condition,
src0_param.param_str);
+    condition = ins->flags == WINED3D_SHADER_CONDITIONAL_OP_NZ ? "bool" :
"!bool";
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0,
&src_param);
+    shader_addline(ins->ctx->buffer, "if (%s(%s)) %s\n", condition,
src_param.param_str, op);
+}
+
+static void shader_glsl_if(const struct wined3d_shader_instruction *ins)
+{
+    shader_glsl_generate_conditional_op(ins, "{");
 }
 static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins)
@@ -4810,22 +5150,19 @@ static void shader_glsl_breakc(const struct
wined3d_shader_instruction *ins)
 static void shader_glsl_conditional_op(const struct wined3d_shader_instruction *ins)
 {
-    const char *condition = (ins->flags == WINED3D_SHADER_CONDITIONAL_OP_NZ) ?
"bool" : "!bool";
-    struct glsl_src_param src_param;
     const char *op;
     switch (ins->handler_idx)
     {
-        case WINED3DSIH_BREAKP: op = "break"; break;
-        case WINED3DSIH_CONTINUEP: op = "continue"; break;
-        case WINED3DSIH_RETP: op = "return"; break;
+        case WINED3DSIH_BREAKP: op = "break;"; break;
+        case WINED3DSIH_CONTINUEP: op = "continue;"; break;
+        case WINED3DSIH_RETP: op = "return;"; break;
         default:
             ERR("Unhandled opcode %#x.\n", ins->handler_idx);
             return;
     }
-    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0,
&src_param);
-    shader_addline(ins->ctx->buffer, "if (%s(%s)) %s;\n", condition,
src_param.param_str, op);
+    shader_glsl_generate_conditional_op(ins, op);
 }
 static void shader_glsl_continue(const struct wined3d_shader_instruction *ins)
@@ -5704,9 +6041,41 @@ static void shader_glsl_sample(const struct
wined3d_shader_instruction *ins)
     shader_glsl_release_sample_function(ins->ctx, &sample_function);
 }
+/* GLSL doesn't provide a function to sample from level zero with depth
+ * comparison for array textures and cube textures. We use textureGrad*()
+ * to implement sample_c_lz.
+ */
+static void shader_glsl_gen_sample_c_lz(const struct wined3d_shader_instruction *ins,
+        unsigned int sampler_bind_idx, const struct glsl_sample_function
*sample_function,
+        unsigned int coord_size, const char *coord_param, const char *ref_param)
+{
+    const struct wined3d_shader_version *version =
&ins->ctx->reg_maps->shader_version;
+    unsigned int deriv_size = wined3d_popcount(sample_function->deriv_mask);
+    const struct wined3d_shader_texel_offset *offset = &ins->texel_offset;
+    struct wined3d_string_buffer *buffer = ins->ctx->buffer;
+    char dst_swizzle[6];
+
+    WARN("Emitting textureGrad() for sample_c_lz.\n");
+
+    shader_glsl_swizzle_to_str(WINED3DSP_NOSWIZZLE, FALSE, ins->dst[0].write_mask,
dst_swizzle);
+    shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0],
sample_function->data_type);
+    shader_addline(buffer, "vec4(textureGrad%s(%s_sampler%u, vec%u(%s, %s),
vec%u(0.0), vec%u(0.0)",
+            sample_function->offset_size ? "Offset" : "",
+            shader_glsl_get_prefix(version->type), sampler_bind_idx,
+            coord_size, coord_param, ref_param, deriv_size, deriv_size);
+    if (sample_function->offset_size)
+    {
+        int offset_immdata[4] = {offset->u, offset->v, offset->w};
+        shader_addline(buffer, ", ");
+        shader_glsl_append_imm_ivec(buffer, offset_immdata,
sample_function->offset_size);
+    }
+    shader_addline(buffer, "))%s);\n", dst_swizzle);
+}
+
 static void shader_glsl_sample_c(const struct wined3d_shader_instruction *ins)
 {
     unsigned int resource_idx, sampler_idx, sampler_bind_idx;
+    const struct wined3d_shader_resource_info *resource_info;
     struct glsl_src_param coord_param, compare_param;
     struct glsl_sample_function sample_function;
     const char *lod_param = NULL;
@@ -5722,6 +6091,8 @@ static void shader_glsl_sample_c(const struct
wined3d_shader_instruction *ins)
     if (wined3d_shader_instruction_has_texel_offset(ins))
         flags |= WINED3D_GLSL_SAMPLE_OFFSET;
+    if (!(resource_info = shader_glsl_get_resource_info(ins, &ins->src[1].reg)))
+        return;
     resource_idx = ins->src[1].reg.idx[0].offset;
     sampler_idx = ins->src[2].reg.idx[0].offset;
@@ -5730,9 +6101,19 @@ static void shader_glsl_sample_c(const struct
wined3d_shader_instruction *ins)
     shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask
>> 1, &coord_param);
     shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0,
&compare_param);
     sampler_bind_idx =
shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx,
sampler_idx);
-    shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function,
WINED3DSP_NOSWIZZLE,
-            NULL, NULL, lod_param, &ins->texel_offset, "vec%u(%s, %s)",
-            coord_size, coord_param.param_str, compare_param.param_str);
+    if (ins->handler_idx == WINED3DSIH_SAMPLE_C_LZ
+            && (resource_info->type == WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY
+            || resource_info->type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE))
+    {
+        shader_glsl_gen_sample_c_lz(ins, sampler_bind_idx, &sample_function,
+                coord_size, coord_param.param_str, compare_param.param_str);
+    }
+    else
+    {
+        shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function,
WINED3DSP_NOSWIZZLE,
+                NULL, NULL, lod_param, &ins->texel_offset, "vec%u(%s,
%s)",
+                coord_size, coord_param.param_str, compare_param.param_str);
+    }
     shader_glsl_release_sample_function(ins->ctx, &sample_function);
 }
@@ -6242,10 +6623,7 @@ static void shader_glsl_texkill(const struct
wined3d_shader_instruction *ins)
 {
     if (ins->ctx->reg_maps->shader_version.major >= 4)
     {
-        struct glsl_src_param src_param;
-
-        shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0,
&src_param);
-        shader_addline(ins->ctx->buffer, "if (bool(%s)) discard;\n",
src_param.param_str);
+        shader_glsl_generate_conditional_op(ins, "discard;");
     }
     else
     {
@@ -6295,7 +6673,7 @@ static void shader_glsl_dp2add(const struct
wined3d_shader_instruction *ins)
 static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct
wined3d_string_buffer *buffer,
         const struct wined3d_shader_signature *input_signature,
         const struct wined3d_shader_reg_maps *reg_maps,
-        const struct ps_compile_args *args, const struct wined3d_gl_info *gl_info)
+        const struct ps_compile_args *args, const struct wined3d_gl_info *gl_info, BOOL
unroll)
 {
     unsigned int i;
@@ -6342,7 +6720,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader
*shader, struct w
             {
                 if (input->sysval_semantic)
                     FIXME("Unhandled sysval semantic %#x.\n",
input->sysval_semantic);
-                shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n",
+                shader_addline(buffer, unroll ? "ps_in[%u]%s = %s%u%s;\n" :
"ps_in[%u]%s = %s[%u]%s;\n",
                         shader->u.ps.input_reg_map[input->register_idx], reg_mask,
                         shader_glsl_shader_input_name(gl_info),
                         shader->u.ps.input_reg_map[input->register_idx], reg_mask);
@@ -6536,7 +6914,8 @@ static void shader_glsl_setup_vs3_output(struct shader_glsl_priv
*priv,
 static void shader_glsl_setup_sm4_shader_output(struct shader_glsl_priv *priv,
         unsigned int input_count, const struct wined3d_shader_signature
*output_signature,
-        const struct wined3d_shader_reg_maps *reg_maps_out, const char
*output_variable_name)
+        const struct wined3d_shader_reg_maps *reg_maps_out, const char
*output_variable_name,
+        BOOL rasterizer_setup)
 {
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
     char reg_mask[6];
@@ -6557,11 +6936,34 @@ static void shader_glsl_setup_sm4_shader_output(struct
shader_glsl_priv *priv,
         shader_glsl_write_mask_to_str(output->mask, reg_mask);
-        shader_addline(buffer, "%s.reg[%u]%s = outputs[%u]%s;\n",
+        shader_addline(buffer,
+                rasterizer_setup ? "%s.reg%u%s = outputs[%u]%s;\n" :
"%s.reg[%u]%s = outputs[%u]%s;\n",
                 output_variable_name, output->register_idx, reg_mask,
output->register_idx, reg_mask);
     }
 }
+static void shader_glsl_generate_clip_or_cull_distances(struct wined3d_string_buffer
*buffer,
+        const struct wined3d_shader_signature_element *element, DWORD
clip_or_cull_distance_mask)
+{
+    unsigned int i, clip_or_cull_index;
+    const char *name;
+    char reg_mask[6];
+
+    name = element->sysval_semantic == WINED3D_SV_CLIP_DISTANCE ? "Clip" :
"Cull";
+    /* Assign consecutive indices starting from 0. */
+    clip_or_cull_index = element->semantic_idx ?
wined3d_popcount(clip_or_cull_distance_mask & 0xf) : 0;
+    for (i = 0; i < 4; ++i)
+    {
+        if (!(element->mask & (WINED3DSP_WRITEMASK_0 << i)))
+            continue;
+
+        shader_glsl_write_mask_to_str(WINED3DSP_WRITEMASK_0 << i, reg_mask);
+        shader_addline(buffer, "gl_%sDistance[%u] = outputs[%u]%s;\n",
+                name, clip_or_cull_index, element->register_idx, reg_mask);
+        ++clip_or_cull_index;
+    }
+}
+
 static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv,
         const struct wined3d_gl_info *gl_info, const DWORD *map,
         const struct wined3d_shader_signature *input_signature,
@@ -6571,7 +6973,7 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct
shader_glsl_priv *priv
 {
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
     const char *semantic_name;
-    UINT semantic_idx;
+    unsigned int semantic_idx;
     char reg_mask[6];
     unsigned int i;
@@ -6605,6 +7007,14 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct
shader_glsl_priv *priv
             shader_addline(buffer, "gl_Layer =
floatBitsToInt(outputs[%u])%s;\n",
                     output->register_idx, reg_mask);
         }
+        else if (output->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
+        {
+            shader_glsl_generate_clip_or_cull_distances(buffer, output,
reg_maps_out->clip_distance_mask);
+        }
+        else if (output->sysval_semantic == WINED3D_SV_CULL_DISTANCE)
+        {
+            shader_glsl_generate_clip_or_cull_distances(buffer, output,
reg_maps_out->cull_distance_mask);
+        }
         else if (output->sysval_semantic)
         {
             FIXME("Unhandled sysval semantic %#x.\n",
output->sysval_semantic);
@@ -6616,7 +7026,7 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct
shader_glsl_priv *priv
         shader_glsl_setup_vs3_output(priv, gl_info, map, input_signature, reg_maps_in,
                 output_signature, reg_maps_out);
     else
-        shader_glsl_setup_sm4_shader_output(priv, input_count, output_signature,
reg_maps_out, "shader_out");
+        shader_glsl_setup_sm4_shader_output(priv, input_count, output_signature,
reg_maps_out, "shader_out", TRUE);
 }
 /* Context activation is done by the caller. */
@@ -6748,7 +7158,7 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct
shader_glsl
     {
         unsigned int in_count = min(vec4_varyings(ps_major, gl_info),
ps->limits->packed_input);
-        shader_glsl_declare_shader_outputs(gl_info, buffer, in_count);
+        shader_glsl_declare_shader_outputs(gl_info, buffer, in_count, FALSE, NULL);
         shader_addline(buffer, "void setup_vs_output(in vec4
outputs[%u])\n{\n", vs->limits->packed_output);
         shader_glsl_setup_sm3_rasterizer_input(priv, gl_info, ps->u.ps.input_reg_map,
&ps->input_signature,
                 &ps->reg_maps, 0, &vs->output_signature,
&vs->reg_maps, per_vertex_point_size);
@@ -6763,9 +7173,78 @@ static GLuint
shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
     return ret;
 }
+static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *priv,
+        const struct wined3d_shader *shader, const struct wined3d_stream_output_desc
*so_desc)
+{
+    struct wined3d_string_buffer *buffer = &priv->shader_buffer;
+    unsigned int i;
+
+    shader_addline(buffer, "out shader_in_out\n{\n");
+    for (i = 0; i < so_desc->element_count; ++i)
+    {
+        const struct wined3d_stream_output_element *e = &so_desc->elements[i];
+
+        if (e->stream_idx)
+        {
+            FIXME("Unhandled stream %u.\n", e->stream_idx);
+            continue;
+        }
+        if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
+            continue;
+
+        if (e->component_idx || e->component_count != 4)
+        {
+            if (e->component_count == 1)
+                shader_addline(buffer, "float");
+            else
+                shader_addline(buffer, "vec%u", e->component_count);
+            shader_addline(buffer, " reg%u_%u_%u;\n",
+                    e->register_idx, e->component_idx, e->component_idx +
e->component_count - 1);
+        }
+        else
+        {
+            shader_addline(buffer, "vec4 reg%u;\n", e->register_idx);
+        }
+    }
+    shader_addline(buffer, "} shader_out;\n");
+
+    shader_addline(buffer, "void setup_gs_output(in vec4 outputs[%u])\n{\n",
+            shader->limits->packed_output);
+    for (i = 0; i < so_desc->element_count; ++i)
+    {
+        const struct wined3d_stream_output_element *e = &so_desc->elements[i];
+
+        if (e->stream_idx)
+        {
+            FIXME("Unhandled stream %u.\n", e->stream_idx);
+            continue;
+        }
+        if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
+            continue;
+
+        if (e->component_idx || e->component_count != 4)
+        {
+            DWORD write_mask;
+            char str_mask[6];
+
+            write_mask = ((1u << e->component_count) - 1) <<
e->component_idx;
+            shader_glsl_write_mask_to_str(write_mask, str_mask);
+            shader_addline(buffer, "shader_out.reg%u_%u_%u = outputs[%u]%s;\n",
+                    e->register_idx, e->component_idx, e->component_idx +
e->component_count - 1,
+                    e->register_idx, str_mask);
+        }
+        else
+        {
+            shader_addline(buffer, "shader_out.reg%u = outputs[%u];\n",
+                    e->register_idx, e->register_idx);
+        }
+    }
+    shader_addline(buffer, "}\n");
+}
+
 static void shader_glsl_generate_sm4_output_setup(struct shader_glsl_priv *priv,
         const struct wined3d_shader *shader, unsigned int input_count,
-        const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup)
+        const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup, const DWORD
*interpolation_mode)
 {
     const char *prefix = shader_glsl_get_prefix(shader->reg_maps.shader_version.type);
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
@@ -6774,7 +7253,7 @@ static void shader_glsl_generate_sm4_output_setup(struct
shader_glsl_priv *priv,
         input_count = min(vec4_varyings(4, gl_info), input_count);
     if (input_count)
-        shader_glsl_declare_shader_outputs(gl_info, buffer, input_count);
+        shader_glsl_declare_shader_outputs(gl_info, buffer, input_count,
rasterizer_setup, interpolation_mode);
     shader_addline(buffer, "void setup_%s_output(in vec4 outputs[%u])\n{\n",
             prefix, shader->limits->packed_output);
@@ -6784,7 +7263,7 @@ static void shader_glsl_generate_sm4_output_setup(struct
shader_glsl_priv *priv,
                 NULL, input_count, &shader->output_signature,
&shader->reg_maps, FALSE);
     else
         shader_glsl_setup_sm4_shader_output(priv, input_count,
&shader->output_signature,
-                &shader->reg_maps, "shader_out");
+                &shader->reg_maps, "shader_out", rasterizer_setup);
     shader_addline(buffer, "}\n");
 }
@@ -6865,20 +7344,20 @@ static void shader_glsl_generate_patch_constant_setup(struct
wined3d_string_buff
 static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer
*buffer,
         const struct wined3d_gl_info *gl_info)
 {
-    const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" :
"ps_out0";
+    const char *output = get_fragment_output(gl_info);
-    shader_addline(buffer, "tmp0.xyz = pow(%s.xyz, vec3(srgb_const0.x));\n",
output);
+    shader_addline(buffer, "tmp0.xyz = pow(%s[0].xyz, vec3(srgb_const0.x));\n",
output);
     shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) -
vec3(srgb_const0.z);\n");
-    shader_addline(buffer, "tmp1.xyz = %s.xyz * vec3(srgb_const0.w);\n",
output);
-    shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s.xyz,
vec3(srgb_const1.x));\n", output);
-    shader_addline(buffer, "%s.xyz = mix(tmp0.xyz, tmp1.xyz,
vec3(srgb_compare));\n", output);
-    shader_addline(buffer, "%s = clamp(%s, 0.0, 1.0);\n", output, output);
+    shader_addline(buffer, "tmp1.xyz = %s[0].xyz * vec3(srgb_const0.w);\n",
output);
+    shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s[0].xyz,
vec3(srgb_const1.x));\n", output);
+    shader_addline(buffer, "%s[0].xyz = mix(tmp0.xyz, tmp1.xyz,
vec3(srgb_compare));\n", output);
+    shader_addline(buffer, "%s[0] = clamp(%s[0], 0.0, 1.0);\n", output,
output);
 }
 static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode)
 {
-    const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" :
"ps_out0";
+    const char *output = get_fragment_output(gl_info);
     switch (mode)
     {
@@ -6903,15 +7382,13 @@ static void shader_glsl_generate_fog_code(struct
wined3d_string_buffer *buffer,
             return;
     }
-    shader_addline(buffer, "%s.xyz = mix(ffp_fog.color.xyz, %s.xyz, clamp(fog, 0.0,
1.0));\n",
+    shader_addline(buffer, "%s[0].xyz = mix(ffp_fog.color.xyz, %s[0].xyz, clamp(fog,
0.0, 1.0));\n",
             output, output);
 }
 static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func)
 {
-    const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" :
"ps_out0";
-
     /* alpha_func is the PASS condition, not the DISCARD condition. Instead of
      * flipping all the operators here, just negate the comparison below. */
     static const char * const comparison_operator[] =
@@ -6930,14 +7407,16 @@ static void shader_glsl_generate_alpha_test(struct
wined3d_string_buffer *buffer
         return;
     if (alpha_func != WINED3D_CMP_NEVER)
-        shader_addline(buffer, "if (!(%s.a %s alpha_test_ref))\n",
-                output, comparison_operator[alpha_func - WINED3D_CMP_NEVER]);
+        shader_addline(buffer, "if (!(%s[0].a %s alpha_test_ref))\n",
+                get_fragment_output(gl_info), comparison_operator[alpha_func -
WINED3D_CMP_NEVER]);
     shader_addline(buffer, "    discard;\n");
 }
 static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info)
 {
+    if (gl_info->supported[ARB_CULL_DISTANCE])
+        shader_addline(buffer, "#extension GL_ARB_cull_distance : enable\n");
     if (gl_info->supported[ARB_GPU_SHADER5])
         shader_addline(buffer, "#extension GL_ARB_gpu_shader5 : enable\n");
     if (gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS])
@@ -6973,11 +7452,10 @@ static void shader_glsl_generate_ps_epilogue(const struct
wined3d_gl_info *gl_in
         const struct ps_compile_args *args)
 {
     const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
-    const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" :
"ps_out0";
     /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */
     if (reg_maps->shader_version.major < 2)
-        shader_addline(buffer, "%s = R0;\n", output);
+        shader_addline(buffer, "%s[0] = R0;\n", get_fragment_output(gl_info));
     if (args->srgb_correction)
         shader_glsl_generate_srgb_write_correction(buffer, gl_info);
@@ -7013,6 +7491,8 @@ static GLuint shader_glsl_generate_pshader(const struct
wined3d_context *context
     shader_glsl_add_version_declaration(buffer, gl_info);
     shader_glsl_enable_extensions(buffer, gl_info);
+    if (gl_info->supported[ARB_CONSERVATIVE_DEPTH])
+        shader_addline(buffer, "#extension GL_ARB_conservative_depth :
enable\n");
     if (gl_info->supported[ARB_DERIVATIVE_CONTROL])
         shader_addline(buffer, "#extension GL_ARB_derivative_control :
enable\n");
     if (shader_glsl_use_explicit_attrib_location(gl_info))
@@ -7027,17 +7507,15 @@ static GLuint shader_glsl_generate_pshader(const struct
wined3d_context *context
      * nvidia drivers write a warning if we don't do so. */
     if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
         shader_addline(buffer, "#extension GL_ARB_texture_rectangle :
enable\n");
-    if (gl_info->supported[ARB_CONSERVATIVE_DEPTH] &&
shader->u.ps.depth_compare)
-        shader_addline(buffer, "#extension GL_ARB_conservative_depth :
enable\n");
     /* Base Declarations */
     shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
     if (gl_info->supported[ARB_CONSERVATIVE_DEPTH])
     {
-        if (shader->u.ps.depth_compare == WINED3DSPR_DEPTHOUT_GREATER_EQUAL)
+        if (shader->u.ps.depth_output == WINED3DSPR_DEPTHOUTGE)
             shader_addline(buffer, "layout (depth_greater) out float
gl_FragDepth;\n");
-        else if (shader->u.ps.depth_compare == WINED3DSPR_DEPTHOUT_LESS_EQUAL)
+        else if (shader->u.ps.depth_output == WINED3DSPR_DEPTHOUTLE)
             shader_addline(buffer, "layout (depth_less) out float
gl_FragDepth;\n");
     }
@@ -7110,7 +7588,8 @@ static GLuint shader_glsl_generate_pshader(const struct
wined3d_context *context
         unsigned int in_count = min(vec4_varyings(version->major, gl_info),
shader->limits->packed_input);
         if (args->vp_mode == vertexshader && reg_maps->input_registers)
-            shader_glsl_declare_shader_inputs(gl_info, buffer, in_count);
+            shader_glsl_declare_shader_inputs(gl_info, buffer, in_count,
+                    shader->u.ps.interpolation_mode, version->major >= 4);
         shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
     }
@@ -7166,24 +7645,9 @@ static GLuint shader_glsl_generate_pshader(const struct
wined3d_context *context
     if (!needs_legacy_glsl_syntax(gl_info))
     {
-        if (args->dual_source_blend)
-        {
-            for (i = 0; i < gl_info->limits.dual_buffers * 2; i++)
-            {
-                if (shader_glsl_use_explicit_attrib_location(gl_info))
-                    shader_addline(buffer, "layout(location = %u, index = %u)
", i / 2, i % 2);
-                shader_addline(buffer, "out vec4 ps_out%u;\n", i);
-            }
-        }
-        else
-        {
-            for (i = 0; i < gl_info->limits.buffers; i++)
-            {
-                if (shader_glsl_use_explicit_attrib_location(gl_info))
-                    shader_addline(buffer, "layout(location = %u) ", i);
-                shader_addline(buffer, "out vec4 ps_out%u;\n", i);
-            }
-        }
+        if (shader_glsl_use_explicit_attrib_location(gl_info))
+            shader_addline(buffer, "layout(location = 0) ");
+        shader_addline(buffer, "out vec4 ps_out[%u];\n",
gl_info->limits.buffers);
     }
     if (shader->limits->constant_float + extra_constants_needed >=
gl_info->limits.glsl_ps_float_constants)
@@ -7256,7 +7720,8 @@ static GLuint shader_glsl_generate_pshader(const struct
wined3d_context *context
     /* Pack 3.0 inputs */
     if (reg_maps->shader_version.major >= 3)
-        shader_glsl_input_pack(shader, buffer, &shader->input_signature, reg_maps,
args, gl_info);
+        shader_glsl_input_pack(shader, buffer, &shader->input_signature, reg_maps,
args, gl_info,
+                reg_maps->shader_version.major >= 4);
     /* Base Shader Body */
     if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL,
NULL)))
@@ -7380,11 +7845,21 @@ static GLuint shader_glsl_generate_vshader(const struct
wined3d_context *context
     if (reg_maps->shader_version.major >= 4)
         shader_glsl_generate_sm4_output_setup(priv, shader,
args->next_shader_input_count,
-                gl_info, args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL);
+                gl_info, args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL,
args->interpolation_mode);
     shader_addline(buffer, "void main()\n{\n");
-    /* Base Shader Body */
+    if (reg_maps->input_rel_addressing)
+    {
+        unsigned int highest_input_register =
wined3d_log2i(reg_maps->input_registers);
+        shader_addline(buffer, "vec4 vs_in[%u];\n", highest_input_register +
1);
+        for (i = 0; i < shader->input_signature.element_count; ++i)
+        {
+            const struct wined3d_shader_signature_element *e =
&shader->input_signature.elements[i];
+            shader_addline(buffer, "vs_in[%u] = vs_in%u;\n",
e->register_idx, e->register_idx);
+        }
+    }
+
     if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL,
NULL)))
         return 0;
@@ -7485,7 +7960,7 @@ static GLuint shader_glsl_generate_hull_shader(const struct
wined3d_context *con
         shader_addline(buffer, "void setup_hs_output(in vec4
outputs[%u])\n{\n",
                 shader->limits->packed_output);
         shader_glsl_setup_sm4_shader_output(priv, shader->limits->packed_output,
&shader->output_signature,
-                &shader->reg_maps, "shader_out[gl_InvocationID]");
+                &shader->reg_maps, "shader_out[gl_InvocationID]",
FALSE);
         shader_addline(buffer, "}\n");
     }
@@ -7621,7 +8096,7 @@ static GLuint shader_glsl_generate_domain_shader(const struct
wined3d_context *c
         shader_addline(buffer, "uniform vec4 pos_fixup;\n");
     shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info,
-            args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL);
+            args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL,
args->interpolation_mode);
     shader_glsl_generate_patch_constant_setup(buffer,
&shader->patch_constant_signature, TRUE);
     shader_addline(buffer, "void main()\n{\n");
@@ -7670,7 +8145,15 @@ static GLuint shader_glsl_generate_geometry_shader(const struct
wined3d_context
     if (!gl_info->supported[ARB_CLIP_CONTROL])
         shader_addline(buffer, "uniform vec4 pos_fixup;\n");
-    shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info,
TRUE);
+    if (is_rasterization_disabled(shader))
+    {
+        shader_glsl_generate_stream_output_setup(priv, shader,
&shader->u.gs.so_desc);
+    }
+    else
+    {
+        shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count,
+                gl_info, TRUE, args->interpolation_mode);
+    }
     shader_addline(buffer, "void main()\n{\n");
     if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL,
NULL)))
         return 0;
@@ -8234,7 +8717,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct
shader_glsl_priv *pr
     {
         {"vec4", "ffp_attrib_position"},        /*
WINED3D_FFP_POSITION */
         {"vec4", "ffp_attrib_blendweight"},     /*
WINED3D_FFP_BLENDWEIGHT */
-        {"vec4", "ffp_attrib_blendindices"},    /*
WINED3D_FFP_BLENDINDICES */
+        /* TODO: Indexed vertex blending */
+        {"float", ""},                          /*
WINED3D_FFP_BLENDINDICES */
         {"vec3", "ffp_attrib_normal"},          /* WINED3D_FFP_NORMAL
*/
         {"float", "ffp_attrib_psize"},          /* WINED3D_FFP_PSIZE
*/
         {"vec4", "ffp_attrib_diffuse"},         /*
WINED3D_FFP_DIFFUSE */
@@ -8246,7 +8730,6 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct
shader_glsl_priv *pr
     BOOL legacy_lighting = priv->legacy_lighting;
     GLuint shader_obj;
     unsigned int i;
-    char var[64];
     string_buffer_clear(buffer);
@@ -8265,9 +8748,9 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct
shader_glsl_priv *pr
     }
     shader_addline(buffer, "\n");
-    shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n",
MAX_VERTEX_INDEX_BLENDS);
-    shader_addline(buffer, "uniform mat3 ffp_normal_matrix[%u];\n",
MAX_VERTEX_INDEX_BLENDS);
+    shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n",
MAX_VERTEX_BLENDS);
     shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n");
+    shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n");
     shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n",
MAX_TEXTURES);
     shader_addline(buffer, "uniform struct\n{\n");
@@ -8352,22 +8835,12 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct
shader_glsl_priv *pr
     }
     else
     {
-        if (!settings->sw_blending)
-        {
-            for (i = 0; i < settings->vertexblends; ++i)
-                shader_addline(buffer, "ffp_attrib_blendweight[%u] -=
ffp_attrib_blendweight[%u];\n", settings->vertexblends, i);
+        for (i = 0; i < settings->vertexblends; ++i)
+            shader_addline(buffer, "ffp_attrib_blendweight[%u] -=
ffp_attrib_blendweight[%u];\n", settings->vertexblends, i);
-            shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
-            for (i = 0; i < settings->vertexblends + 1; ++i)
-            {
-                sprintf(var, settings->vb_indices ?
"int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
-                shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] *
(ffp_modelview_matrix[%s] * ffp_attrib_position);\n", i, var);
-            }
-        }
-        else
-        {
-            shader_addline(buffer, "vec4 ec_pos = ffp_attrib_position;\n");
-        }
+        shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
+        for (i = 0; i < settings->vertexblends + 1; ++i)
+            shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] *
(ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i);
         shader_addline(buffer, "gl_Position = ffp_projection_matrix *
ec_pos;\n");
         if (settings->clipping)
@@ -8384,17 +8857,14 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct
shader_glsl_priv *pr
     shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
     if (settings->normal)
     {
-        if (!settings->sw_blending)
+        if (!settings->vertexblends)
         {
-            for (i = 0; i < settings->vertexblends + 1; ++i)
-            {
-                sprintf(var, settings->vb_indices ?
"int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
-                shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] *
(ffp_normal_matrix[%s] * ffp_attrib_normal);\n", i, var);
-            }
+            shader_addline(buffer, "normal = ffp_normal_matrix *
ffp_attrib_normal;\n");
         }
         else
         {
-            shader_addline(buffer, "normal = ffp_attrib_normal;\n");
+            for (i = 0; i < settings->vertexblends + 1; ++i)
+                shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] *
(mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i);
         }
         if (settings->normalize)
@@ -8760,7 +9230,6 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer
*buffer, un
 static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *priv,
         const struct ffp_frag_settings *settings, const struct wined3d_context *context)
 {
-    const char *output = needs_legacy_glsl_syntax(context->gl_info) ?
"gl_FragData[0]" : "ps_out0";
     struct wined3d_string_buffer *tex_reg_name =
string_buffer_get(&priv->string_buffers);
     enum wined3d_cmp_func alpha_test_func = settings->alpha_test_func + 1;
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
@@ -8849,7 +9318,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct
shader_glsl_priv *
     {
         if (shader_glsl_use_explicit_attrib_location(gl_info))
             shader_addline(buffer, "layout(location = 0) ");
-        shader_addline(buffer, "out vec4 ps_out0;\n");
+        shader_addline(buffer, "out vec4 ps_out[1];\n");
     }
     shader_addline(buffer, "vec4 tmp0, tmp1;\n");
@@ -9180,7 +9649,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct
shader_glsl_priv *
         }
     }
-    shader_addline(buffer, "%s = ffp_varying_specular * specular_enable +
ret;\n", output);
+    shader_addline(buffer, "%s[0] = ffp_varying_specular * specular_enable +
ret;\n",
+            get_fragment_output(gl_info));
     if (settings->sRGB_write)
         shader_glsl_generate_srgb_write_correction(buffer, gl_info);
@@ -9267,17 +9737,13 @@ static void shader_glsl_init_vs_uniform_locations(const struct
wined3d_gl_info *
     vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id,
"pos_fixup"));
-    for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i)
+    for (i = 0; i < MAX_VERTEX_BLENDS; ++i)
     {
         string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i);
         vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id,
name->buffer));
     }
-    for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i)
-    {
-        string_buffer_sprintf(name, "ffp_normal_matrix[%u]", i);
-        vs->normal_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id,
name->buffer));
-    }
     vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id,
"ffp_projection_matrix"));
+    vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id,
"ffp_normal_matrix"));
     for (i = 0; i < MAX_TEXTURES; ++i)
     {
         string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i);
@@ -9447,6 +9913,7 @@ static HRESULT shader_glsl_compile_compute_shader(struct
shader_glsl_priv *priv,
     entry->ps.id = 0;
     entry->cs.id = shader_id;
     entry->constant_version = 0;
+    entry->shader_controlled_clip_distances = 0;
     entry->ps.np2_fixup_info = NULL;
     add_glsl_program_entry(priv, entry);
@@ -9521,11 +9988,12 @@ static void set_glsl_compute_shader_program(const struct
wined3d_context *contex
 static void set_glsl_shader_program(const struct wined3d_context *context, const struct
wined3d_state *state,
         struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data)
 {
-    const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    const struct wined3d_shader *pre_rasterization_shader;
     const struct ps_np2fixup_info *np2fixup_info = NULL;
-    struct glsl_shader_prog_link *entry = NULL;
     struct wined3d_shader *hshader, *dshader, *gshader;
+    struct glsl_shader_prog_link *entry = NULL;
     struct wined3d_shader *vshader = NULL;
     struct wined3d_shader *pshader = NULL;
     GLuint reorder_shader_id = 0;
@@ -9537,7 +10005,7 @@ static void set_glsl_shader_program(const struct wined3d_context
*context, const
     GLuint ds_id = 0;
     GLuint gs_id = 0;
     GLuint ps_id = 0;
-    struct list *ps_list = NULL, *vs_list = NULL;
+    struct list *ps_list, *vs_list;
     WORD attribs_map;
     struct wined3d_string_buffer *tmp_name;
@@ -9555,7 +10023,7 @@ static void set_glsl_shader_program(const struct wined3d_context
*context, const
         vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
-        find_vs_compile_args(state, vshader, context->stream_info.swizzle_map,
&vs_compile_args, d3d_info);
+        find_vs_compile_args(state, vshader, context->stream_info.swizzle_map,
&vs_compile_args, context);
         vs_id = find_glsl_vshader(context, priv, vshader, &vs_compile_args);
         vs_list = &vshader->linked_programs;
     }
@@ -9598,11 +10066,17 @@ static void set_glsl_shader_program(const struct wined3d_context
*context, const
     {
         struct gs_compile_args args;
-        find_gs_compile_args(state, gshader, &args);
+        find_gs_compile_args(state, gshader, &args, context);
         gs_id = find_glsl_geometry_shader(context, priv, gshader, &args);
     }
-    if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL))
&& ctx_data->glsl_program)
+    /* A pixel shader is not used when rasterization is disabled. */
+    if (is_rasterization_disabled(gshader))
+    {
+        ps_id = 0;
+        ps_list = NULL;
+    }
+    else if (!(context->shader_update_mask & (1u <<
WINED3D_SHADER_TYPE_PIXEL)) && ctx_data->glsl_program)
     {
         ps_id = ctx_data->glsl_program->ps.id;
         ps_list = &ctx_data->glsl_program->ps.shader_entry;
@@ -9657,6 +10131,7 @@ static void set_glsl_shader_program(const struct wined3d_context
*context, const
     entry->ps.id = ps_id;
     entry->cs.id = 0;
     entry->constant_version = 0;
+    entry->shader_controlled_clip_distances = 0;
     entry->ps.np2_fixup_info = np2fixup_info;
     /* Add the hash table entry */
     add_glsl_program_entry(priv, entry);
@@ -9728,26 +10203,8 @@ static void set_glsl_shader_program(const struct wined3d_context
*context, const
         if (!needs_legacy_glsl_syntax(gl_info))
         {
-            char var[12];
-
-            if (wined3d_dualblend_enabled(state, gl_info))
-            {
-                for (i = 0; i < gl_info->limits.dual_buffers * 2; i++)
-                {
-                    sprintf(var, "ps_out%u", i);
-                    GL_EXTCALL(glBindFragDataLocationIndexed(program_id, i / 2, i % 2,
var));
-                    checkGLcall("glBindFragDataLocationIndexed");
-                }
-            }
-            else
-            {
-                for (i = 0; i < gl_info->limits.buffers; i++)
-                {
-                    sprintf(var, "ps_out%u", i);
-                    GL_EXTCALL(glBindFragDataLocation(program_id, i, var));
-                    checkGLcall("glBindFragDataLocation");
-                }
-            }
+            GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out"));
+            checkGLcall("glBindFragDataLocation");
         }
     }
@@ -9801,7 +10258,15 @@ static void set_glsl_shader_program(const struct wined3d_context
*context, const
     shader_glsl_init_gs_uniform_locations(gl_info, priv, program_id, &entry->gs);
     shader_glsl_init_ps_uniform_locations(gl_info, priv, program_id, &entry->ps,
             pshader ? pshader->limits->constant_float : 0);
-    checkGLcall("Find glsl program uniform locations");
+    checkGLcall("find glsl program uniform locations");
+
+    pre_rasterization_shader = gshader ? gshader : dshader ? dshader : vshader;
+    if (pre_rasterization_shader &&
pre_rasterization_shader->reg_maps.shader_version.major >= 4)
+    {
+        unsigned int clip_distance_count =
wined3d_popcount(pre_rasterization_shader->reg_maps.clip_distance_mask);
+        entry->shader_controlled_clip_distances = 1;
+        entry->clip_distance_mask = (1u << clip_distance_count) - 1;
+    }
     if (needs_legacy_glsl_syntax(gl_info))
     {
@@ -9846,7 +10311,7 @@ static void set_glsl_shader_program(const struct wined3d_context
*context, const
         entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW
                 | WINED3D_SHADER_CONST_FFP_PROJ;
-        for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i)
+        for (i = 1; i < MAX_VERTEX_BLENDS; ++i)
         {
             if (entry->vs.modelview_matrix_location[i] != -1)
             {
@@ -9957,6 +10422,7 @@ static void shader_glsl_select(void *shader_priv, struct
wined3d_context *contex
     struct glsl_context_data *ctx_data = context->shader_backend_data;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_priv *priv = shader_priv;
+    struct glsl_shader_prog_link *glsl_program;
     GLenum current_vertex_color_clamp;
     GLuint program_id, prev_id;
@@ -9964,13 +10430,15 @@ static void shader_glsl_select(void *shader_priv, struct
wined3d_context *contex
     priv->fragment_pipe->enable_extension(gl_info, !use_ps(state));
     prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0;
-
     set_glsl_shader_program(context, state, priv, ctx_data);
+    glsl_program = ctx_data->glsl_program;
-    if (ctx_data->glsl_program)
+    if (glsl_program)
     {
-        program_id = ctx_data->glsl_program->id;
-        current_vertex_color_clamp = ctx_data->glsl_program->vs.vertex_color_clamp;
+        program_id = glsl_program->id;
+        current_vertex_color_clamp = glsl_program->vs.vertex_color_clamp;
+        if (glsl_program->shader_controlled_clip_distances)
+            context_enable_clip_distances(context, glsl_program->clip_distance_mask);
     }
     else
     {
@@ -9999,8 +10467,8 @@ static void shader_glsl_select(void *shader_priv, struct
wined3d_context *contex
         GL_EXTCALL(glUseProgram(program_id));
         checkGLcall("glUseProgram");
-        if (program_id)
-            context->constant_update_mask |=
ctx_data->glsl_program->constant_update_mask;
+        if (glsl_program)
+            context->constant_update_mask |= glsl_program->constant_update_mask;
     }
     context->shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE);
@@ -10441,7 +10909,9 @@ static unsigned int shader_glsl_get_shader_model(const struct
wined3d_gl_info *g
     if (shader_model_4
             && gl_info->supported[ARB_COMPUTE_SHADER]
+            && gl_info->supported[ARB_CULL_DISTANCE]
             && gl_info->supported[ARB_DERIVATIVE_CONTROL]
+            && gl_info->supported[ARB_DRAW_INDIRECT]
             && gl_info->supported[ARB_GPU_SHADER5]
             && gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS]
             && gl_info->supported[ARB_SHADER_IMAGE_LOAD_STORE]
@@ -10560,7 +11030,7 @@ static const SHADER_HANDLER
shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_DCL_INPUT                        */ shader_glsl_nop,
     /* WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT    */ shader_glsl_nop,
     /* WINED3DSIH_DCL_INPUT_PRIMITIVE              */ shader_glsl_nop,
-    /* WINED3DSIH_DCL_INPUT_PS                     */ NULL,
+    /* WINED3DSIH_DCL_INPUT_PS                     */ shader_glsl_nop,
     /* WINED3DSIH_DCL_INPUT_PS_SGV                 */ NULL,
     /* WINED3DSIH_DCL_INPUT_PS_SIV                 */ NULL,
     /* WINED3DSIH_DCL_INPUT_SGV                    */ shader_glsl_nop,
@@ -10601,6 +11071,7 @@ static const SHADER_HANDLER
shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_DSY                              */ shader_glsl_map2gl,
     /* WINED3DSIH_DSY_COARSE                       */ shader_glsl_map2gl,
     /* WINED3DSIH_DSY_FINE                         */ shader_glsl_map2gl,
+    /* WINED3DSIH_EVAL_SAMPLE_INDEX                */ NULL,
     /* WINED3DSIH_ELSE                             */ shader_glsl_else,
     /* WINED3DSIH_EMIT                             */ shader_glsl_emit,
     /* WINED3DSIH_EMIT_STREAM                      */ shader_glsl_emit,
@@ -10808,7 +11279,7 @@ static void glsl_vertex_pipe_vp_get_caps(const struct
wined3d_gl_info *gl_info,
     caps->ffp_generic_attributes = TRUE;
     caps->max_active_lights = MAX_ACTIVE_LIGHTS;
     caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;
-    caps->max_vertex_blend_matrix_index = MAX_VERTEX_INDEX_BLENDS - 1;
+    caps->max_vertex_blend_matrix_index = 0;
     caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN
             | WINED3DVTXPCAPS_MATERIALSOURCE7
             | WINED3DVTXPCAPS_VERTEXFOG
@@ -10967,6 +11438,14 @@ static void glsl_vertex_pipe_hs(struct wined3d_context *context,
 static void glsl_vertex_pipe_geometry_shader(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
+    struct glsl_context_data *ctx_data = context->shader_backend_data;
+    BOOL rasterization_disabled;
+
+    rasterization_disabled =
is_rasterization_disabled(state->shader[WINED3D_SHADER_TYPE_GEOMETRY]);
+    if (ctx_data->rasterization_disabled != rasterization_disabled)
+        context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
+    ctx_data->rasterization_disabled = rasterization_disabled;
+
     if (state->shader[WINED3D_SHADER_TYPE_DOMAIN])
         context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_DOMAIN;
     else if (state->shader[WINED3D_SHADER_TYPE_VERTEX]
@@ -10995,8 +11474,7 @@ static void glsl_vertex_pipe_world(struct wined3d_context
*context,
 static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
-    int i = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
-    context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i);
+    context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND;
 }
 static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct
wined3d_state *state, DWORD state_id)
@@ -11152,54 +11630,6 @@ static const struct StateEntryTemplate
glsl_vertex_pipe_vp_states[] =
     {STATE_CLIPPLANE(6),                                         {STATE_CLIPPLANE(6),
clipplane              }, WINED3D_GL_EXT_NONE          },
     {STATE_CLIPPLANE(7),                                         {STATE_CLIPPLANE(7),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
     {STATE_CLIPPLANE(7),                                         {STATE_CLIPPLANE(7),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(8),                                         {STATE_CLIPPLANE(8),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(8),                                         {STATE_CLIPPLANE(8),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(9),                                         {STATE_CLIPPLANE(9),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(9),                                         {STATE_CLIPPLANE(9),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(10),                                        {STATE_CLIPPLANE(10),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(10),                                        {STATE_CLIPPLANE(10),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(11),                                        {STATE_CLIPPLANE(11),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(11),                                        {STATE_CLIPPLANE(11),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(12),                                        {STATE_CLIPPLANE(12),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(12),                                        {STATE_CLIPPLANE(12),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(13),                                        {STATE_CLIPPLANE(13),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(13),                                        {STATE_CLIPPLANE(13),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(14),                                        {STATE_CLIPPLANE(14),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(14),                                        {STATE_CLIPPLANE(14),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(15),                                        {STATE_CLIPPLANE(15),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(15),                                        {STATE_CLIPPLANE(15),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(16),                                        {STATE_CLIPPLANE(16),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(16),                                        {STATE_CLIPPLANE(16),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(17),                                        {STATE_CLIPPLANE(17),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(17),                                        {STATE_CLIPPLANE(17),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(18),                                        {STATE_CLIPPLANE(18),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(18),                                        {STATE_CLIPPLANE(18),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(19),                                        {STATE_CLIPPLANE(19),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(19),                                        {STATE_CLIPPLANE(19),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(20),                                        {STATE_CLIPPLANE(20),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(20),                                        {STATE_CLIPPLANE(20),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(21),                                        {STATE_CLIPPLANE(21),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(21),                                        {STATE_CLIPPLANE(21),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(22),                                        {STATE_CLIPPLANE(22),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(22),                                        {STATE_CLIPPLANE(22),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(23),                                        {STATE_CLIPPLANE(23),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(23),                                        {STATE_CLIPPLANE(23),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(24),                                        {STATE_CLIPPLANE(24),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(24),                                        {STATE_CLIPPLANE(24),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(25),                                        {STATE_CLIPPLANE(25),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(25),                                        {STATE_CLIPPLANE(25),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(26),                                        {STATE_CLIPPLANE(26),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(26),                                        {STATE_CLIPPLANE(26),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(27),                                        {STATE_CLIPPLANE(27),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(27),                                        {STATE_CLIPPLANE(27),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(28),                                        {STATE_CLIPPLANE(28),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(28),                                        {STATE_CLIPPLANE(28),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(29),                                        {STATE_CLIPPLANE(29),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(29),                                        {STATE_CLIPPLANE(29),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(30),                                        {STATE_CLIPPLANE(30),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(30),                                        {STATE_CLIPPLANE(30),
clipplane              }, WINED3D_GL_EXT_NONE          },
-    {STATE_CLIPPLANE(31),                                        {STATE_CLIPPLANE(31),
glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130         },
-    {STATE_CLIPPLANE(31),                                        {STATE_CLIPPLANE(31),
clipplane              }, WINED3D_GL_EXT_NONE          },
     /* Lights */
     {STATE_LIGHT_TYPE,
{STATE_RENDER(WINED3D_RS_FOGENABLE),                         NULL                   },
WINED3D_GL_EXT_NONE          },
     {STATE_ACTIVELIGHT(0),                                       {STATE_ACTIVELIGHT(0),
glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE          },
@@ -11227,11 +11657,6 @@ static const struct StateEntryTemplate
glsl_vertex_pipe_vp_states[] =
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)),
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)),                glsl_vertex_pipe_vertexblend
}, WINED3D_GL_EXT_NONE    },
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)),
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)),                glsl_vertex_pipe_vertexblend
}, WINED3D_GL_EXT_NONE    },
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)),
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)),                glsl_vertex_pipe_vertexblend
}, WINED3D_GL_EXT_NONE    },
-    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)),
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)),                glsl_vertex_pipe_vertexblend
}, WINED3D_GL_EXT_NONE    },
-    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)),
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)),                glsl_vertex_pipe_vertexblend
}, WINED3D_GL_EXT_NONE    },
-    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)),
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)),                glsl_vertex_pipe_vertexblend
}, WINED3D_GL_EXT_NONE    },
-    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)),
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)),                glsl_vertex_pipe_vertexblend
}, WINED3D_GL_EXT_NONE    },
-    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)),
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)),                glsl_vertex_pipe_vertexblend
}, WINED3D_GL_EXT_NONE    },
     {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0,
WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE
},
     {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1,
WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE
},
     {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2,
WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE
},
diff --git a/dll/directx/wine/wined3d/query.c b/dll/directx/wine/wined3d/query.c
index 428e841d4e..fe175d1a6d 100644
--- a/dll/directx/wine/wined3d/query.c
+++ b/dll/directx/wine/wined3d/query.c
@@ -387,7 +387,7 @@ HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query,
     }
     else if (query->counter_main != query->counter_retrieved)
     {
-        if (flags & WINED3DGETDATA_FLUSH)
+        if (flags & WINED3DGETDATA_FLUSH &&
!query->device->cs->queries_flushed)
             wined3d_cs_emit_flush(query->device->cs);
         return S_FALSE;
     }
@@ -911,34 +911,6 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query
*query, DWORD
     return poll;
 }
-static BOOL wined3d_statistics_query_ops_poll(struct wined3d_query *query, DWORD flags)
-{
-    TRACE("query %p, flags %#x.\n", query, flags);
-
-    return TRUE;
-}
-
-static BOOL wined3d_statistics_query_ops_issue(struct wined3d_query *query, DWORD flags)
-{
-    FIXME("query %p, flags %#x.\n", query, flags);
-
-    return FALSE;
-}
-
-static BOOL wined3d_overflow_query_ops_poll(struct wined3d_query *query, DWORD flags)
-{
-    TRACE("query %p, flags %#x.\n", query, flags);
-
-    return TRUE;
-}
-
-static BOOL wined3d_overflow_query_ops_issue(struct wined3d_query *query, DWORD flags)
-{
-    FIXME("query %p, flags %#x.\n", query, flags);
-
-    return FALSE;
-}
-
 static void wined3d_event_query_ops_destroy(struct wined3d_query *query)
 {
     struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
@@ -1223,72 +1195,6 @@ static HRESULT wined3d_pipeline_query_create(struct wined3d_device
*device,
     return WINED3D_OK;
 }
-static void wined3d_statistics_query_ops_destroy(struct wined3d_query *query)
-{
-    HeapFree(GetProcessHeap(), 0, query);
-}
-
-static const struct wined3d_query_ops statistics_query_ops =
-{
-    wined3d_statistics_query_ops_poll,
-    wined3d_statistics_query_ops_issue,
-    wined3d_statistics_query_ops_destroy,
-};
-
-static HRESULT wined3d_statistics_query_create(struct wined3d_device *device,
-        enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops
*parent_ops,
-        struct wined3d_query **query)
-{
-    static const struct wined3d_query_data_so_statistics statistics = { 1, 1 };
-    struct wined3d_query *object;
-
-    FIXME("device %p, type %#x, parent %p, query %p.\n", device, type, parent,
query);
-
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
-        return E_OUTOFMEMORY;
-
-    wined3d_query_init(object, device, type, &statistics,
-            sizeof(statistics), &statistics_query_ops, parent, parent_ops);
-
-    TRACE("Created query %p.\n", object);
-    *query = object;
-
-    return WINED3D_OK;
-}
-
-static void wined3d_overflow_query_ops_destroy(struct wined3d_query *query)
-{
-    HeapFree(GetProcessHeap(), 0, query);
-}
-
-static const struct wined3d_query_ops overflow_query_ops =
-{
-    wined3d_overflow_query_ops_poll,
-    wined3d_overflow_query_ops_issue,
-    wined3d_overflow_query_ops_destroy,
-};
-
-static HRESULT wined3d_overflow_query_create(struct wined3d_device *device,
-        enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops
*parent_ops,
-        struct wined3d_query **query)
-{
-    static const BOOL overflow = FALSE;
-    struct wined3d_query *object;
-
-    FIXME("device %p, type %#x, parent %p, query %p.\n", device, type, parent,
query);
-
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
-        return E_OUTOFMEMORY;
-
-    wined3d_query_init(object, device, type, &overflow,
-            sizeof(overflow), &overflow_query_ops, parent, parent_ops);
-
-    TRACE("Created query %p.\n", object);
-    *query = object;
-
-    return WINED3D_OK;
-}
-
 HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type
type,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query
**query)
 {
@@ -1319,12 +1225,6 @@ HRESULT CDECL wined3d_query_create(struct wined3d_device *device,
enum wined3d_q
         case WINED3D_QUERY_TYPE_PIPELINE_STATISTICS:
             return wined3d_pipeline_query_create(device, type, parent, parent_ops,
query);
-        case WINED3D_QUERY_TYPE_SO_STATISTICS:
-            return wined3d_statistics_query_create(device, type, parent, parent_ops,
query);
-
-        case WINED3D_QUERY_TYPE_SO_OVERFLOW:
-            return wined3d_overflow_query_create(device, type, parent, parent_ops,
query);
-
         default:
             FIXME("Unhandled query type %#x.\n", type);
             return WINED3DERR_NOTAVAILABLE;
diff --git a/dll/directx/wine/wined3d/resource.c b/dll/directx/wine/wined3d/resource.c
index ffce012503..0788146106 100644
--- a/dll/directx/wine/wined3d/resource.c
+++ b/dll/directx/wine/wined3d/resource.c
@@ -48,7 +48,7 @@ static DWORD resource_access_from_pool(enum wined3d_pool pool)
 static void resource_check_usage(DWORD usage)
 {
-    static DWORD handled = WINED3DUSAGE_RENDERTARGET
+    static const DWORD handled = WINED3DUSAGE_RENDERTARGET
             | WINED3DUSAGE_DEPTHSTENCIL
             | WINED3DUSAGE_WRITEONLY
             | WINED3DUSAGE_DYNAMIC
@@ -66,10 +66,7 @@ static void resource_check_usage(DWORD usage)
      * driver. */
     if (usage & ~handled)
-    {
         FIXME("Unhandled usage flags %#x.\n", usage & ~handled);
-        handled |= usage;
-    }
     if ((usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY)) ==
WINED3DUSAGE_DYNAMIC)
         WARN_(d3d_perf)("WINED3DUSAGE_DYNAMIC used without
WINED3DUSAGE_WRITEONLY.\n");
 }
@@ -96,7 +93,6 @@ HRESULT resource_init(struct wined3d_resource *resource, struct
wined3d_device *
     resource_types[] =
     {
         {WINED3D_RTYPE_BUFFER,      0,
WINED3D_GL_RES_TYPE_BUFFER},
-        {WINED3D_RTYPE_TEXTURE_1D,  0,
WINED3D_GL_RES_TYPE_TEX_1D},
         {WINED3D_RTYPE_TEXTURE_2D,  0,
WINED3D_GL_RES_TYPE_TEX_2D},
         {WINED3D_RTYPE_TEXTURE_2D,  0,
WINED3D_GL_RES_TYPE_TEX_RECT},
         {WINED3D_RTYPE_TEXTURE_2D,  0,
WINED3D_GL_RES_TYPE_RB},
@@ -337,17 +333,19 @@ static DWORD wined3d_resource_sanitise_map_flags(const struct
wined3d_resource *
             return 0;
         }
     }
-    else if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
-            == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+    else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
     {
-        WARN("WINED3D_MAP_DISCARD and WINED3D_MAP_NOOVERWRITE used together,
ignoring.\n");
-        return 0;
-    }
-    else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)
-            && !(resource->usage & WINED3DUSAGE_DYNAMIC))
-    {
-        WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
-        return 0;
+        if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
+        {
+            WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer,
ignoring.\n");
+            return 0;
+        }
+        if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+                == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+        {
+            WARN("WINED3D_MAP_NOOVERWRITE used with WINED3D_MAP_DISCARD, ignoring
WINED3D_MAP_DISCARD.\n");
+            flags &= ~WINED3D_MAP_DISCARD;
+        }
     }
     return flags;
@@ -365,14 +363,6 @@ HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource,
unsigned i
     return wined3d_cs_map(resource->device->cs, resource, sub_resource_idx,
map_desc, box, flags);
 }
-HRESULT CDECL wined3d_resource_map_info(struct wined3d_resource *resource, unsigned int
sub_resource_idx,
-        struct wined3d_map_info *info, DWORD flags)
-{
-    TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx);
-
-    return resource->resource_ops->resource_map_info(resource, sub_resource_idx,
info, flags);
-}
-
 HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int
sub_resource_idx)
 {
     TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx);
@@ -380,99 +370,6 @@ HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource
*resource, unsigned
     return wined3d_cs_unmap(resource->device->cs, resource, sub_resource_idx);
 }
-UINT CDECL wined3d_resource_update_info(struct wined3d_resource *resource, unsigned int
sub_resource_idx,
-        const struct wined3d_box *box, unsigned int row_pitch, unsigned int depth_pitch)
-{
-    unsigned int width, height, depth;
-    struct wined3d_box b;
-    UINT data_size;
-
-    TRACE("resource %p, sub_resource_idx %u, box %s, row_pitch %u, depth_pitch
%u.\n",
-            resource, sub_resource_idx, debug_box(box), row_pitch, depth_pitch);
-
-    if (resource->type == WINED3D_RTYPE_BUFFER)
-    {
-        if (sub_resource_idx > 0)
-        {
-            WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
-            return 0;
-        }
-
-        width = resource->size;
-        height = 1;
-        depth = 1;
-    }
-    else if (resource->type == WINED3D_RTYPE_TEXTURE_1D ||
-            resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type ==
WINED3D_RTYPE_TEXTURE_3D)
-    {
-        struct wined3d_texture *texture = texture_from_resource(resource);
-        unsigned int level;
-
-        if (sub_resource_idx >= texture->level_count * texture->layer_count)
-        {
-            WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
-            return 0;
-        }
-
-        level = sub_resource_idx % texture->level_count;
-        width = wined3d_texture_get_level_width(texture, level);
-        height = wined3d_texture_get_level_height(texture, level);
-        depth = wined3d_texture_get_level_depth(texture, level);
-    }
-    else
-    {
-        FIXME("Not implemented for %s resources.\n",
debug_d3dresourcetype(resource->type));
-        return 0;
-    }
-
-    if (!box)
-    {
-        wined3d_box_set(&b, 0, 0, width, height, 0, depth);
-        box = &b;
-    }
-    else if (box->left >= box->right || box->right > width
-            || box->top >= box->bottom || box->bottom > height
-            || box->front >= box->back || box->back > depth)
-    {
-        WARN("Invalid box %s specified.\n", debug_box(box));
-        return 0;
-    }
-
-    if (resource->format_flags & WINED3DFMT_FLAG_BLOCKS)
-    {
-        if (resource->type != WINED3D_RTYPE_TEXTURE_2D)
-        {
-            FIXME("Calculation of block formats not implemented for %s
resources.\n", debug_d3dresourcetype(resource->type));
-            return 0;
-        }
-
-        height  = (box->bottom - box->top  + resource->format->block_height -
1) / resource->format->block_height;
-        width   = (box->right  - box->left + resource->format->block_width  -
1) / resource->format->block_width;
-        return (height - 1) * row_pitch + width *
resource->format->block_byte_count;
-    }
-
-    data_size = 0;
-    switch (resource->type)
-    {
-        case WINED3D_RTYPE_TEXTURE_3D:
-            data_size += (box->back - box->front - 1) * depth_pitch;
-            /* fall-through */
-        case WINED3D_RTYPE_TEXTURE_2D:
-            data_size += (box->bottom - box->top - 1) * row_pitch;
-            /* fall-through */
-        case WINED3D_RTYPE_TEXTURE_1D:
-            data_size += (box->right - box->left) *
resource->format->byte_count;
-            break;
-        case WINED3D_RTYPE_BUFFER:
-            data_size = box->right - box->left;
-            break;
-        case WINED3D_RTYPE_NONE:
-            break;
... 22194 lines suppressed ...