[D3D8][D3D9][DDRAW][D3DCOMPILER_43][WINED3D] Revert to Wine Staging 3.3
authorJoachim Henze <Joachim.Henze@reactos.org>
Thu, 3 Oct 2019 16:38:29 +0000 (18:38 +0200)
committerJoachim Henze <Joachim.Henze@reactos.org>
Thu, 3 Oct 2019 16:38:29 +0000 (18:38 +0200)
Avoid regressions CORE-14955 "Ddraw fullscreen crashes" and CORE-15652

This brings us back to before guilty commit 0.4.10-dev-55-g
7af3969e9fe68b5f55a088f93a6b69570822c733

and therefore downgrades
dll/directx/wine/
D3D8,D3D9,DDRAW,D3DCOMPILER_43,WINED3D
to WineStaging 3.3.
Also downgrades related header sdk/include/reactos/wine/wined3d.h
and for the first time also media/doc/README.WINE

Same versions of these dlls we had in every ros rls since 0.4.10rls.
Amine Khaldi agreed to perform this revert also for master now.

Purpose of this revert is to fix crashes when Ddraw apps switch
into fullscreen with VBEMP and inbuilt Mesa.
I tested, before:
 DxDiag crashed when switching to fullscreen (CORE-14955),
 Diablo II crashed immediately (CORE-15652),
 Monster-Truck-Madness 2 demo crashed after main menu

Afterwards all of these apps do run.
DXTN does still work after that, even with VBEMP and inbuilt Mesa.

squashed commit of 0.4.13-RC-2-g
67dd70e5ef0acc09495c8a0853cf2a1161f65101
and 0.4.13-RC-3-g
9f1e2cd172f3bf14da6b1c288fdc1dc3980cc63d

47 files changed:
dll/directx/wine/d3d8/CMakeLists.txt
dll/directx/wine/d3d8/d3d8_private.h
dll/directx/wine/d3d8/device.c
dll/directx/wine/d3d8/directx.c
dll/directx/wine/d3d8/swapchain.c
dll/directx/wine/d3d9/CMakeLists.txt
dll/directx/wine/d3d9/d3d9_private.h
dll/directx/wine/d3d9/device.c
dll/directx/wine/d3d9/directx.c
dll/directx/wine/d3d9/swapchain.c
dll/directx/wine/d3d9/texture.c
dll/directx/wine/d3dcompiler_43/CMakeLists.txt
dll/directx/wine/ddraw/CMakeLists.txt
dll/directx/wine/ddraw/ddraw.c
dll/directx/wine/ddraw/ddraw_private.h
dll/directx/wine/ddraw/device.c
dll/directx/wine/ddraw/executebuffer.c
dll/directx/wine/ddraw/palette.c
dll/directx/wine/ddraw/surface.c
dll/directx/wine/ddraw/utils.c
dll/directx/wine/ddraw/viewport.c
dll/directx/wine/wined3d/CMakeLists.txt
dll/directx/wine/wined3d/arb_program_shader.c
dll/directx/wine/wined3d/ati_fragment_shader.c
dll/directx/wine/wined3d/buffer.c
dll/directx/wine/wined3d/context.c
dll/directx/wine/wined3d/cs.c
dll/directx/wine/wined3d/device.c
dll/directx/wine/wined3d/directx.c
dll/directx/wine/wined3d/glsl_shader.c
dll/directx/wine/wined3d/nvidia_texture_shader.c
dll/directx/wine/wined3d/resource.c
dll/directx/wine/wined3d/shader.c
dll/directx/wine/wined3d/shader_sm4.c
dll/directx/wine/wined3d/state.c
dll/directx/wine/wined3d/stateblock.c
dll/directx/wine/wined3d/surface.c
dll/directx/wine/wined3d/swapchain.c
dll/directx/wine/wined3d/texture.c
dll/directx/wine/wined3d/utils.c
dll/directx/wine/wined3d/view.c
dll/directx/wine/wined3d/wined3d.spec
dll/directx/wine/wined3d/wined3d_gl.h
dll/directx/wine/wined3d/wined3d_main.c
dll/directx/wine/wined3d/wined3d_private.h
media/doc/README.WINE
sdk/include/reactos/wine/wined3d.h

index d3d49e2..09d7a6c 100644 (file)
@@ -19,7 +19,7 @@ list(APPEND SOURCE
     volume.c
     precomp.h)
 
-add_library(d3d8 MODULE
+add_library(d3d8 SHARED
     ${SOURCE}
     guid.c
     version.rc
index 3fbc096..cba5dd6 100644 (file)
@@ -166,11 +166,10 @@ struct d3d8_swapchain
     LONG refcount;
     struct wined3d_swapchain *wined3d_swapchain;
     IDirect3DDevice8 *parent_device;
-    unsigned int swap_interval;
 };
 
 HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc,
-        unsigned int swap_interval, struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN;
+        struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN;
 
 struct d3d8_surface
 {
index 616886b..5daf6f4 100644 (file)
@@ -209,7 +209,7 @@ static D3DSWAPEFFECT d3dswapeffect_from_wined3dswapeffect(enum wined3d_swap_effe
 }
 
 static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
-        const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval)
+        const struct wined3d_swapchain_desc *swapchain_desc)
 {
     present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width;
     present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height;
@@ -224,7 +224,7 @@ static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS
             = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
     present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK;
     present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
-    present_parameters->FullScreen_PresentationInterval = presentation_interval;
+    present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval;
 }
 
 static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect)
@@ -245,27 +245,6 @@ static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFE
     }
 }
 
-static enum wined3d_swap_interval wined3dswapinterval_from_d3d(DWORD interval)
-{
-    switch (interval)
-    {
-        case D3DPRESENT_INTERVAL_IMMEDIATE:
-            return WINED3D_SWAP_INTERVAL_IMMEDIATE;
-        case D3DPRESENT_INTERVAL_ONE:
-            return WINED3D_SWAP_INTERVAL_ONE;
-        case D3DPRESENT_INTERVAL_TWO:
-            return WINED3D_SWAP_INTERVAL_TWO;
-        case D3DPRESENT_INTERVAL_THREE:
-            return WINED3D_SWAP_INTERVAL_THREE;
-        case D3DPRESENT_INTERVAL_FOUR:
-            return WINED3D_SWAP_INTERVAL_FOUR;
-        default:
-            FIXME("Unhandled presentation interval %#x.\n", interval);
-        case D3DPRESENT_INTERVAL_DEFAULT:
-            return WINED3D_SWAP_INTERVAL_DEFAULT;
-    }
-}
-
 static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
         const D3DPRESENT_PARAMETERS *present_parameters)
 {
@@ -282,20 +261,6 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
         WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount);
         return FALSE;
     }
-    switch (present_parameters->FullScreen_PresentationInterval)
-    {
-        case D3DPRESENT_INTERVAL_DEFAULT:
-        case D3DPRESENT_INTERVAL_ONE:
-        case D3DPRESENT_INTERVAL_TWO:
-        case D3DPRESENT_INTERVAL_THREE:
-        case D3DPRESENT_INTERVAL_FOUR:
-        case D3DPRESENT_INTERVAL_IMMEDIATE:
-            break;
-        default:
-            WARN("Invalid presentation interval %#x.\n",
-                    present_parameters->FullScreen_PresentationInterval);
-            return FALSE;
-    }
 
     swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
     swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
@@ -313,6 +278,7 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
     swapchain_desc->flags
             = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
     swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
+    swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval;
     swapchain_desc->auto_restore_display_mode = TRUE;
 
     if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK)
@@ -328,7 +294,7 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps)
     caps->Caps                      = wined3d_caps->Caps;
     caps->Caps2                     = wined3d_caps->Caps2;
     caps->Caps3                     = wined3d_caps->Caps3;
-    caps->PresentationIntervals     = D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE;
+    caps->PresentationIntervals     = wined3d_caps->PresentationIntervals;
     caps->CursorCaps                = wined3d_caps->CursorCaps;
     caps->DevCaps                   = wined3d_caps->DevCaps;
     caps->PrimitiveMiscCaps         = wined3d_caps->PrimitiveMiscCaps;
@@ -377,57 +343,6 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps)
     caps->PixelShaderVersion        = wined3d_caps->PixelShaderVersion;
     caps->MaxPixelShaderValue       = wined3d_caps->PixelShader1xMaxValue;
 
-    caps->Caps2 &= D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_CANRENDERWINDOWED
-            | D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_FULLSCREENGAMMA
-            | D3DCAPS2_NO2DDURING3DSCENE | D3DCAPS2_RESERVED;
-    caps->Caps3 &= D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | D3DCAPS3_RESERVED;
-    caps->PrimitiveMiscCaps &= D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP
-            | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW
-            | D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
-            | D3DPMISCCAPS_CLIPTLVERTS | D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_BLENDOP
-            | D3DPMISCCAPS_NULLREFERENCE;
-    caps->RasterCaps &= D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST
-            | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_ANTIALIASEDGES
-            | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR
-            | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER
-            | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE
-            | D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE;
-    caps->SrcBlendCaps &= D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
-            | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
-            | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
-            | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
-            | D3DPBLENDCAPS_BOTHINVSRCALPHA;
-    caps->DestBlendCaps &= D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
-            | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
-            | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
-            | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
-            | D3DPBLENDCAPS_BOTHINVSRCALPHA;
-    caps->TextureCaps &= D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA
-            | D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE
-            | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_NONPOW2CONDITIONAL
-            | D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP
-            | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP
-            | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2;
-    caps->TextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
-            | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT
-            | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
-            | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC
-            | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC;
-    caps->CubeTextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
-            | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT
-            | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
-            | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC
-            | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC;
-    caps->VolumeTextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
-            | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT
-            | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
-            | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC
-            | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC;
-    caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED;
-    caps->VertexProcessingCaps &= D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7
-            | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER
-            | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_NO_VSDT_UBYTE4;
-
     /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
     if (caps->PixelShaderVersion)
         caps->PixelShaderVersion = D3DPS_VERSION(1, 4);
@@ -438,6 +353,8 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps)
     else
         caps->VertexShaderVersion = D3DVS_VERSION(0, 0);
     caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
+
+    caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED;
 }
 
 /* Handle table functions */
@@ -781,8 +698,7 @@ static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if
     struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
     struct wined3d_swapchain_desc desc;
     struct d3d8_swapchain *object;
-    unsigned int swap_interval;
-    unsigned int i, count;
+    UINT i, count;
     HRESULT hr;
 
     TRACE("iface %p, present_parameters %p, swapchain %p.\n",
@@ -814,11 +730,9 @@ static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if
 
     if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters))
         return D3DERR_INVALIDCALL;
-    swap_interval = wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval);
-    if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, swap_interval, &object)))
+    if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object)))
         *swapchain = &object->IDirect3DSwapChain8_iface;
-    present_parameters_from_wined3d_swapchain_desc(present_parameters,
-            &desc, present_parameters->FullScreen_PresentationInterval);
+    present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
 
     return hr;
 }
@@ -892,8 +806,6 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface,
             NULL, reset_enum_callback, TRUE)))
     {
         present_parameters->BackBufferCount = swapchain_desc.backbuffer_count;
-        device->implicit_swapchain->swap_interval
-                = wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval);
         wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
         wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE,
                 !!swapchain_desc.enable_auto_depth_stencil);
@@ -1619,30 +1531,10 @@ static HRESULT WINAPI d3d8_device_MultiplyTransform(IDirect3DDevice8 *iface,
 static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport)
 {
     struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
-    struct wined3d_sub_resource_desc rt_desc;
-    struct wined3d_rendertarget_view *rtv;
-    struct d3d8_surface *surface;
     struct wined3d_viewport vp;
 
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
-    wined3d_mutex_lock();
-    if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
-    {
-        wined3d_mutex_unlock();
-        return D3DERR_NOTFOUND;
-    }
-    surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
-    wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
-
-    if (viewport->X > rt_desc.width || viewport->Width > rt_desc.width - viewport->X
-            || viewport->Y > rt_desc.height || viewport->Height > rt_desc.height - viewport->Y)
-    {
-        WARN("Invalid viewport, returning D3DERR_INVALIDCALL.\n");
-        wined3d_mutex_unlock();
-        return D3DERR_INVALIDCALL;
-    }
-
     vp.x = viewport->X;
     vp.y = viewport->Y;
     vp.width = viewport->Width;
@@ -1650,7 +1542,8 @@ static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3D
     vp.min_z = viewport->MinZ;
     vp.max_z = viewport->MaxZ;
 
-    wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
+    wined3d_mutex_lock();
+    wined3d_device_set_viewport(device->wined3d_device, &vp);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -1664,7 +1557,7 @@ static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8 *iface, D3DVIEWPO
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
     wined3d_mutex_lock();
-    wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport);
+    wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
     wined3d_mutex_unlock();
 
     viewport->X = wined3d_viewport.x;
@@ -2187,11 +2080,9 @@ static HRESULT WINAPI d3d8_device_ValidateDevice(IDirect3DDevice8 *iface, DWORD
 static HRESULT WINAPI d3d8_device_GetInfo(IDirect3DDevice8 *iface,
         DWORD info_id, void *info, DWORD info_size)
 {
-    TRACE("iface %p, info_id %#x, info %p, info_size %u.\n", iface, info_id, info, info_size);
+    FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface, info_id, info, info_size);
 
-    if (info_id < 4)
-        return E_FAIL;
-    return S_FALSE;
+    return D3D_OK;
 }
 
 static HRESULT WINAPI d3d8_device_SetPaletteEntries(IDirect3DDevice8 *iface,
@@ -3271,40 +3162,40 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa
         InterlockedCompareExchange(&device->device_state, D3D8_DEVICE_STATE_NOT_RESET, D3D8_DEVICE_STATE_LOST);
 }
 
-static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent,
-        enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
         void **parent, const struct wined3d_parent_ops **parent_ops)
 {
-    TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
-            device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops);
+    struct d3d8_surface *d3d_surface;
 
-    if (type == WINED3D_RTYPE_TEXTURE_2D)
-    {
-        struct d3d8_surface *d3d_surface;
+    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
-        if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
-            return E_OUTOFMEMORY;
+    if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
+        return E_OUTOFMEMORY;
 
-        surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
-        *parent = d3d_surface;
-        TRACE("Created surface %p.\n", d3d_surface);
-    }
-    else if (type == WINED3D_RTYPE_TEXTURE_3D)
-    {
-        struct d3d8_volume *d3d_volume;
+    surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
+    *parent = d3d_surface;
+    TRACE("Created surface %p.\n", d3d_surface);
 
-        if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
-            return E_OUTOFMEMORY;
+    return D3D_OK;
+}
 
-        volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
-        *parent = d3d_volume;
-        TRACE("Created volume %p.\n", d3d_volume);
-    }
-    else
-    {
-        ERR("Unhandled resource type %#x.\n", type);
-        return E_FAIL;
-    }
+static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+        void **parent, const struct wined3d_parent_ops **parent_ops)
+{
+    struct d3d8_volume *d3d_volume;
+
+    TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
+
+    if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
+        return E_OUTOFMEMORY;
+
+    volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
+    *parent = d3d_volume;
+    TRACE("Created volume %p.\n", d3d_volume);
 
     return D3D_OK;
 }
@@ -3343,7 +3234,7 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent
 
     TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain);
 
-    if (FAILED(hr = d3d8_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT, &d3d_swapchain)))
+    if (FAILED(hr = d3d8_swapchain_create(device, desc, &d3d_swapchain)))
     {
         WARN("Failed to create swapchain, hr %#x.\n", hr);
         *swapchain = NULL;
@@ -3362,7 +3253,8 @@ static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops =
     device_parent_wined3d_device_created,
     device_parent_mode_changed,
     device_parent_activate,
-    device_parent_texture_sub_resource_created,
+    device_parent_surface_created,
+    device_parent_volume_created,
     device_parent_create_swapchain_texture,
     device_parent_create_swapchain,
 };
@@ -3464,8 +3356,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
     wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
     wined3d_mutex_unlock();
 
-    present_parameters_from_wined3d_swapchain_desc(parameters,
-            &swapchain_desc, parameters->FullScreen_PresentationInterval);
+    present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc);
 
     device->declArraySize = 16;
     if (!(device->decls = heap_alloc(device->declArraySize * sizeof(*device->decls))))
@@ -3477,8 +3368,6 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
 
     wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0);
     device->implicit_swapchain = wined3d_swapchain_get_parent(wined3d_swapchain);
-    device->implicit_swapchain->swap_interval
-            = wined3dswapinterval_from_d3d(parameters->FullScreen_PresentationInterval);
 
     device->d3d_parent = &parent->IDirect3D8_iface;
     IDirect3D8_AddRef(device->d3d_parent);
index 68300c0..6e8f93a 100644 (file)
@@ -417,7 +417,7 @@ BOOL d3d8_init(struct d3d8 *d3d8)
     DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
             | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
             | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART
-            | WINED3D_LEGACY_CUBEMAP_FILTERING;
+            | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT;
 
     d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
     d3d8->refcount = 1;
index 39e3b23..3a588b5 100644 (file)
@@ -105,7 +105,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
-            src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0);
+            src_rect, dst_rect, dst_window_override, 0, 0);
     wined3d_mutex_unlock();
 
     return hr;
@@ -167,13 +167,12 @@ static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops =
 };
 
 static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_device *device,
-        struct wined3d_swapchain_desc *desc, unsigned int swap_interval)
+        struct wined3d_swapchain_desc *desc)
 {
     HRESULT hr;
 
     swapchain->refcount = 1;
     swapchain->IDirect3DSwapChain8_iface.lpVtbl = &d3d8_swapchain_vtbl;
-    swapchain->swap_interval = swap_interval;
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
@@ -193,7 +192,7 @@ static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_devi
 }
 
 HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc,
-        unsigned int swap_interval, struct d3d8_swapchain **swapchain)
+        struct d3d8_swapchain **swapchain)
 {
     struct d3d8_swapchain *object;
     HRESULT hr;
@@ -201,7 +200,7 @@ HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapcha
     if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    if (FAILED(hr = swapchain_init(object, device, desc, swap_interval)))
+    if (FAILED(hr = swapchain_init(object, device, desc)))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
         heap_free(object);
index 14dd3e6..223606b 100644 (file)
@@ -21,7 +21,7 @@ list(APPEND SOURCE
     volume.c
     precomp.h)
 
-add_library(d3d9 MODULE
+add_library(d3d9 SHARED
     ${SOURCE}
     guid.c
     version.rc
index 4086613..094707a 100644 (file)
@@ -55,7 +55,7 @@ BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
 unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) DECLSPEC_HIDDEN;
 void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
-        const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) DECLSPEC_HIDDEN;
+        const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN;
 void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN;
 
 struct d3d9
@@ -99,6 +99,7 @@ struct d3d9_device
     UINT index_buffer_size;
     UINT index_buffer_pos;
 
+    struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS];
     struct d3d9_surface *render_targets[D3D_MAX_SIMULTANEOUS_RENDERTARGETS];
 
     LONG device_state;
@@ -148,11 +149,10 @@ struct d3d9_swapchain
     LONG refcount;
     struct wined3d_swapchain *wined3d_swapchain;
     IDirect3DDevice9Ex *parent_device;
-    unsigned int swap_interval;
 };
 
 HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc,
-        unsigned int swap_interval, struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN;
+        struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN;
 
 struct d3d9_surface
 {
index 2f3ad28..bc73699 100644 (file)
@@ -231,7 +231,7 @@ static D3DSWAPEFFECT d3dswapeffect_from_wined3dswapeffect(enum wined3d_swap_effe
 }
 
 void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
-        const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval)
+        const struct wined3d_swapchain_desc *swapchain_desc)
 {
     present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width;
     present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height;
@@ -247,7 +247,7 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese
             = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
     present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK;
     present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
-    present_parameters->PresentationInterval = presentation_interval;
+    present_parameters->PresentationInterval = swapchain_desc->swap_interval;
 }
 
 static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect)
@@ -270,27 +270,6 @@ static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFE
     }
 }
 
-static enum wined3d_swap_interval wined3dswapinterval_from_d3d(DWORD interval)
-{
-    switch (interval)
-    {
-        case D3DPRESENT_INTERVAL_IMMEDIATE:
-            return WINED3D_SWAP_INTERVAL_IMMEDIATE;
-        case D3DPRESENT_INTERVAL_ONE:
-            return WINED3D_SWAP_INTERVAL_ONE;
-        case D3DPRESENT_INTERVAL_TWO:
-            return WINED3D_SWAP_INTERVAL_TWO;
-        case D3DPRESENT_INTERVAL_THREE:
-            return WINED3D_SWAP_INTERVAL_THREE;
-        case D3DPRESENT_INTERVAL_FOUR:
-            return WINED3D_SWAP_INTERVAL_FOUR;
-        default:
-            FIXME("Unhandled presentation interval %#x.\n", interval);
-        case D3DPRESENT_INTERVAL_DEFAULT:
-            return WINED3D_SWAP_INTERVAL_DEFAULT;
-    }
-}
-
 static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
         const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended)
 {
@@ -309,19 +288,6 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
         WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount);
         return FALSE;
     }
-    switch (present_parameters->PresentationInterval)
-    {
-        case D3DPRESENT_INTERVAL_DEFAULT:
-        case D3DPRESENT_INTERVAL_ONE:
-        case D3DPRESENT_INTERVAL_TWO:
-        case D3DPRESENT_INTERVAL_THREE:
-        case D3DPRESENT_INTERVAL_FOUR:
-        case D3DPRESENT_INTERVAL_IMMEDIATE:
-            break;
-        default:
-            WARN("Invalid presentation interval %#x.\n", present_parameters->PresentationInterval);
-            return FALSE;
-    }
 
     swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
     swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
@@ -339,6 +305,7 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
     swapchain_desc->flags
             = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
     swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
+    swapchain_desc->swap_interval = present_parameters->PresentationInterval;
     swapchain_desc->auto_restore_display_mode = TRUE;
 
     if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK)
@@ -363,7 +330,7 @@ void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps)
     caps->Caps                              = wined3d_caps->Caps;
     caps->Caps2                             = wined3d_caps->Caps2;
     caps->Caps3                             = wined3d_caps->Caps3;
-    caps->PresentationIntervals             = D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE;
+    caps->PresentationIntervals             = wined3d_caps->PresentationIntervals;
     caps->CursorCaps                        = wined3d_caps->CursorCaps;
     caps->DevCaps                           = wined3d_caps->DevCaps;
     caps->PrimitiveMiscCaps                 = wined3d_caps->PrimitiveMiscCaps;
@@ -776,8 +743,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
     struct wined3d_swapchain_desc desc;
     struct d3d9_swapchain *object;
-    unsigned int swap_interval;
-    unsigned int i, count;
+    UINT i, count;
     HRESULT hr;
 
     TRACE("iface %p, present_parameters %p, swapchain %p.\n",
@@ -810,11 +776,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID
     if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters,
             device->d3d_parent->extended))
         return D3DERR_INVALIDCALL;
-    swap_interval = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval);
-    if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, swap_interval, &object)))
+    if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object)))
         *swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface;
-    present_parameters_from_wined3d_swapchain_desc(present_parameters,
-            &desc, present_parameters->PresentationInterval);
+    present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
 
     return hr;
 }
@@ -970,8 +934,6 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
         }
         else
         {
-            device->implicit_swapchains[0]->swap_interval
-                    = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval);
             wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc);
             present_parameters->BackBufferWidth = swapchain_desc.backbuffer_width;
             present_parameters->BackBufferHeight = swapchain_desc.backbuffer_height;
@@ -981,6 +943,10 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
             device->device_state = D3D9_DEVICE_STATE_OK;
         }
 
+        if (!device->d3d_parent->extended)
+            for (i = 0; i < ARRAY_SIZE(device->textures); ++i)
+                device->textures[i] = NULL;
+
         rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0);
         device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
         for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i)
@@ -1010,8 +976,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex *
         const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region)
 {
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
-    struct d3d9_swapchain *swapchain;
-    unsigned int i;
+    UINT i;
     HRESULT hr;
 
     TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n",
@@ -1026,9 +991,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex *
     wined3d_mutex_lock();
     for (i = 0; i < device->implicit_swapchain_count; ++i)
     {
-        swapchain = device->implicit_swapchains[i];
-        if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
-                src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0)))
+        if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
+                src_rect, dst_rect, dst_window_override, 0, 0)))
         {
             wined3d_mutex_unlock();
             return hr;
@@ -1536,7 +1500,7 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface,
     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_box, 0);
+            src->sub_resource_idx, &src_box);
     if (SUCCEEDED(hr) && dst->texture)
         d3d9_texture_flag_auto_gen_mipmap(dst->texture);
 
@@ -2068,7 +2032,7 @@ static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D
     vp.max_z = viewport->MaxZ;
 
     wined3d_mutex_lock();
-    wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
+    wined3d_device_set_viewport(device->wined3d_device, &vp);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -2082,7 +2046,7 @@ static HRESULT WINAPI d3d9_device_GetViewport(IDirect3DDevice9Ex *iface, D3DVIEW
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
     wined3d_mutex_lock();
-    wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport);
+    wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
     wined3d_mutex_unlock();
 
     viewport->X = wined3d_viewport.x;
@@ -2398,6 +2362,13 @@ static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD st
     wined3d_mutex_lock();
     hr = wined3d_device_set_texture(device->wined3d_device, stage,
             texture_impl ? texture_impl->wined3d_texture : NULL);
+    if (SUCCEEDED(hr))
+    {
+        unsigned int i = stage >= D3DVERTEXTEXTURESAMPLER0 ? stage - D3DVERTEXTEXTURESAMPLER0 + 16 : stage;
+
+        if (stage < ARRAY_SIZE(device->textures))
+            device->textures[i] = texture_impl;
+    }
     wined3d_mutex_unlock();
 
     return hr;
@@ -2564,7 +2535,7 @@ static HRESULT WINAPI d3d9_device_SetScissorRect(IDirect3DDevice9Ex *iface, cons
     TRACE("iface %p, rect %p.\n", iface, rect);
 
     wined3d_mutex_lock();
-    wined3d_device_set_scissor_rects(device->wined3d_device, 1, rect);
+    wined3d_device_set_scissor_rect(device->wined3d_device, rect);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -2577,7 +2548,7 @@ static HRESULT WINAPI d3d9_device_GetScissorRect(IDirect3DDevice9Ex *iface, RECT
     TRACE("iface %p, rect %p.\n", iface, rect);
 
     wined3d_mutex_lock();
-    wined3d_device_get_scissor_rects(device->wined3d_device, NULL, rect);
+    wined3d_device_get_scissor_rect(device->wined3d_device, rect);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -2641,15 +2612,11 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface)
 /* wined3d critical section must be taken by the caller. */
 static void d3d9_generate_auto_mipmaps(struct d3d9_device *device)
 {
-    struct wined3d_texture *texture;
-    unsigned int i, stage;
+    unsigned int i;
 
-    for (i = 0; i < D3D9_MAX_TEXTURE_UNITS; ++i)
-    {
-        stage = i >= 16 ? i - 16 + D3DVERTEXTEXTURESAMPLER0 : i;
-        if ((texture = wined3d_device_get_texture(device->wined3d_device, stage)))
-            d3d9_texture_gen_auto_mipmap(wined3d_texture_get_parent(texture));
-    }
+    for (i = 0; i < ARRAY_SIZE(device->textures); ++i)
+        if (device->textures[i])
+            d3d9_texture_gen_auto_mipmap(device->textures[i]);
 }
 
 static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
@@ -3700,8 +3667,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex
         const RGNDATA *dirty_region, DWORD flags)
 {
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
-    struct d3d9_swapchain *swapchain;
-    unsigned int i;
+    UINT i;
     HRESULT hr;
 
     TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
@@ -3717,9 +3683,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex
     wined3d_mutex_lock();
     for (i = 0; i < device->implicit_swapchain_count; ++i)
     {
-        swapchain = device->implicit_swapchains[i];
-        if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
-                src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags)))
+        if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
+                src_rect, dst_rect, dst_window_override, 0, flags)))
         {
             wined3d_mutex_unlock();
             return hr;
@@ -3762,31 +3727,21 @@ static HRESULT WINAPI d3d9_device_CheckResourceResidency(IDirect3DDevice9Ex *ifa
 
 static HRESULT WINAPI d3d9_device_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency)
 {
-    struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
-
     TRACE("iface %p, max_latency %u.\n", iface, max_latency);
 
-    if (max_latency > 30)
-        return D3DERR_INVALIDCALL;
-
-    wined3d_mutex_lock();
-    wined3d_device_set_max_frame_latency(device->wined3d_device, max_latency);
-    wined3d_mutex_unlock();
+    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)
 {
-    struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
-
-    TRACE("iface %p, max_latency %p.\n", iface, max_latency);
+    FIXME("iface %p, max_latency %p stub!\n", iface, max_latency);
 
-    wined3d_mutex_lock();
-    *max_latency = wined3d_device_get_max_frame_latency(device->wined3d_device);
-    wined3d_mutex_unlock();
+    *max_latency = 2;
 
-    return S_OK;
+    return E_NOTIMPL;
 }
 
 static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window)
@@ -4095,40 +4050,40 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa
         InterlockedCompareExchange(&device->device_state, D3D9_DEVICE_STATE_NOT_RESET, D3D9_DEVICE_STATE_LOST);
 }
 
-static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent,
-        enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
         void **parent, const struct wined3d_parent_ops **parent_ops)
 {
-    TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
-            device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops);
+    struct d3d9_surface *d3d_surface;
 
-    if (type == WINED3D_RTYPE_TEXTURE_2D)
-    {
-        struct d3d9_surface *d3d_surface;
+    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
-        if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
-            return E_OUTOFMEMORY;
+    if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
+        return E_OUTOFMEMORY;
 
-        surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
-        *parent = d3d_surface;
-        TRACE("Created surface %p.\n", d3d_surface);
-    }
-    else if (type == WINED3D_RTYPE_TEXTURE_3D)
-    {
-        struct d3d9_volume *d3d_volume;
+    surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
+    *parent = d3d_surface;
+    TRACE("Created surface %p.\n", d3d_surface);
 
-        if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
-            return E_OUTOFMEMORY;
+    return D3D_OK;
+}
 
-        volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
-        *parent = d3d_volume;
-        TRACE("Created volume %p.\n", d3d_volume);
-    }
-    else
-    {
-        ERR("Unhandled resource type %#x.\n", type);
-        return E_FAIL;
-    }
+static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+        void **parent, const struct wined3d_parent_ops **parent_ops)
+{
+    struct d3d9_volume *d3d_volume;
+
+    TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
+
+    if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
+        return E_OUTOFMEMORY;
+
+    volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
+    *parent = d3d_volume;
+    TRACE("Created volume %p.\n", d3d_volume);
 
     return D3D_OK;
 }
@@ -4173,7 +4128,8 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent
 
     TRACE("device_parent %p, desc %p, swapchain %p\n", device_parent, desc, swapchain);
 
-    if (FAILED(hr = d3d9_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT, &d3d_swapchain)))
+    hr = d3d9_swapchain_create(device, desc, &d3d_swapchain);
+    if (FAILED(hr))
     {
         WARN("Failed to create swapchain, hr %#x.\n", hr);
         *swapchain = NULL;
@@ -4192,7 +4148,8 @@ static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops =
     device_parent_wined3d_device_created,
     device_parent_mode_changed,
     device_parent_activate,
-    device_parent_texture_sub_resource_created,
+    device_parent_surface_created,
+    device_parent_volume_created,
     device_parent_create_swapchain_texture,
     device_parent_create_swapchain,
 };
@@ -4315,16 +4272,10 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
         wined3d_mutex_unlock();
         return E_OUTOFMEMORY;
     }
-    for (i = 0; i < device->implicit_swapchain_count; ++i)
-    {
-        device->implicit_swapchains[i]->swap_interval
-                = wined3dswapinterval_from_d3d(parameters[i].PresentationInterval);
-    }
 
     for (i = 0; i < count; ++i)
     {
-        present_parameters_from_wined3d_swapchain_desc(&parameters[i],
-                &swapchain_desc[i], parameters[i].PresentationInterval);
+        present_parameters_from_wined3d_swapchain_desc(&parameters[i], &swapchain_desc[i]);
     }
 
     wined3d_mutex_unlock();
index 98f4a99..644766c 100644 (file)
@@ -254,12 +254,6 @@ static HRESULT WINAPI d3d9_CheckDeviceFormat(IDirect3D9Ex *iface, UINT adapter,
     TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n",
             iface, adapter, device_type, adapter_format, usage, resource_type, format);
 
-    if (!adapter_format)
-    {
-        WARN("Invalid adapter format.\n");
-        return D3DERR_INVALIDCALL;
-    }
-
     usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK);
     switch (resource_type)
     {
@@ -585,7 +579,7 @@ 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_NORMALIZED_DEPTH_BIAS;
+            | WINED3D_NORMALIZED_DEPTH_BIAS | WINED3D_LIMIT_VIEWPORT;
 
     if (!extended)
         flags |= WINED3D_VIDMEM_ACCOUNTING;
index d303f3f..dbb3f45 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
 
-static DWORD d3dpresentationinterval_from_wined3dswapinterval(enum wined3d_swap_interval interval)
-{
-    switch (interval)
-    {
-        case WINED3D_SWAP_INTERVAL_IMMEDIATE:
-            return D3DPRESENT_INTERVAL_IMMEDIATE;
-        case WINED3D_SWAP_INTERVAL_ONE:
-            return D3DPRESENT_INTERVAL_ONE;
-        case WINED3D_SWAP_INTERVAL_TWO:
-            return D3DPRESENT_INTERVAL_TWO;
-        case WINED3D_SWAP_INTERVAL_THREE:
-            return D3DPRESENT_INTERVAL_THREE;
-        case WINED3D_SWAP_INTERVAL_FOUR:
-            return D3DPRESENT_INTERVAL_FOUR;
-        default:
-            ERR("Invalid swap interval %#x.\n", interval);
-        case WINED3D_SWAP_INTERVAL_DEFAULT:
-            return D3DPRESENT_INTERVAL_DEFAULT;
-    }
-}
-
 static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9Ex(IDirect3DSwapChain9Ex *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9Ex_iface);
@@ -158,7 +137,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
-            src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags);
+            src_rect, dst_rect, dst_window_override, 0, flags);
     wined3d_mutex_unlock();
 
     return hr;
@@ -272,15 +251,13 @@ static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9Ex
 {
     struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     struct wined3d_swapchain_desc desc;
-    DWORD presentation_interval;
 
     TRACE("iface %p, parameters %p.\n", iface, parameters);
 
     wined3d_mutex_lock();
     wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &desc);
-    presentation_interval = d3dpresentationinterval_from_wined3dswapinterval(swapchain->swap_interval);
     wined3d_mutex_unlock();
-    present_parameters_from_wined3d_swapchain_desc(parameters, &desc, presentation_interval);
+    present_parameters_from_wined3d_swapchain_desc(parameters, &desc);
 
     return D3D_OK;
 }
@@ -367,13 +344,12 @@ static const struct wined3d_parent_ops d3d9_swapchain_wined3d_parent_ops =
 };
 
 static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_device *device,
-        struct wined3d_swapchain_desc *desc, unsigned int swap_interval)
+        struct wined3d_swapchain_desc *desc)
 {
     HRESULT hr;
 
     swapchain->refcount = 1;
     swapchain->IDirect3DSwapChain9Ex_iface.lpVtbl = &d3d9_swapchain_vtbl;
-    swapchain->swap_interval = swap_interval;
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
@@ -393,7 +369,7 @@ static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_devi
 }
 
 HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc,
-        unsigned int swap_interval, struct d3d9_swapchain **swapchain)
+        struct d3d9_swapchain **swapchain)
 {
     struct d3d9_swapchain *object;
     HRESULT hr;
@@ -401,7 +377,7 @@ HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapcha
     if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    if (FAILED(hr = swapchain_init(object, device, desc, swap_interval)))
+    if (FAILED(hr = swapchain_init(object, device, desc)))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
         heap_free(object);
index 7b74ac5..c97fa6b 100644 (file)
@@ -1339,22 +1339,9 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
             WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
             return D3DERR_INVALIDCALL;
         }
-        wined3d_mutex_lock();
-        hr = wined3d_check_device_format(device->d3d_parent->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM,
-                WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_GENMIPMAP, WINED3D_RTYPE_TEXTURE_2D, wined3dformat_from_d3dformat(format));
-        wined3d_mutex_unlock();
-        if (hr == D3D_OK)
-        {
-            flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
-            levels = 0;
-        }
-        else
-        {
-            WARN("D3DUSAGE_AUTOGENMIPMAP not supported on D3DFORMAT %#x, creating a texture "
-                    "with a single level.\n", format);
-            levels = 1;
-        }
+        flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
         texture->autogen_filter_type = D3DTEXF_LINEAR;
+        levels = 0;
     }
     else
     {
index 88d2383..7c5cb42 100644 (file)
@@ -3,19 +3,18 @@ add_definitions(
     -D__WINESRC__
     -DDIRECT3D_VERSION=0x0900)
 
-if(MSVC)
-    # error C4133: 'function': incompatible types - from 'D3D_CBUFFER_TYPE *' to 'DWORD *'
-    replace_compile_flags("/we4133" " ")
-endif()
-
 include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
 spec2def(d3dcompiler_43.dll d3dcompiler_43.spec ADD_IMPORTLIB)
 
 list(APPEND SOURCE
     asmparser.c
+    asmshader.tab.c
+    asmshader.yy.c
     blob.c
     bytecodewriter.c
     compiler.c
+    hlsl.tab.c
+    hlsl.yy.c
     main.c
     reflection.c
     utils.c
@@ -24,10 +23,6 @@ list(APPEND SOURCE
 
 add_library(d3dcompiler_43 MODULE
     ${SOURCE}
-    asmshader.tab.c
-    asmshader.yy.c
-    hlsl.tab.c
-    hlsl.yy.c
     version.rc
     ${CMAKE_CURRENT_BINARY_DIR}/d3dcompiler_43.def)
 
@@ -43,5 +38,5 @@ set_module_type(d3dcompiler_43 win32dll)
 target_link_libraries(d3dcompiler_43 dx10guid uuid wine wpp)
 add_importlibs(d3dcompiler_43 msvcrt kernel32 ntdll)
 add_dependencies(d3dcompiler_43 d3d_idl_headers)
-add_pch(d3dcompiler_43 precomp.h SOURCE)
+#add_pch(d3dcompiler_43 precomp.h SOURCE)
 add_cd_file(TARGET d3dcompiler_43 DESTINATION reactos/system32 FOR all)
index 03029bd..6141d63 100644 (file)
@@ -29,7 +29,7 @@ if(MSVC)
     set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/FIwine/typeof.h")
 endif()
 
-add_library(ddraw MODULE
+add_library(ddraw SHARED
     ${SOURCE}
     ddraw.rc
     ${CMAKE_CURRENT_BINARY_DIR}/ddraw.def)
index 6b5ccec..e5205c0 100644 (file)
@@ -633,9 +633,8 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win
     swapchain_desc.backbuffer_width = mode.width;
     swapchain_desc.backbuffer_height = mode.height;
     swapchain_desc.backbuffer_format = mode.format_id;
-    swapchain_desc.backbuffer_usage = 0;
-    swapchain_desc.backbuffer_count = 1;
-    swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD;
+    swapchain_desc.backbuffer_usage = WINED3DUSAGE_RENDERTARGET;
+    swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
     swapchain_desc.device_window = window;
     swapchain_desc.windowed = windowed;
     swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
@@ -2100,7 +2099,7 @@ static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface)
     ddraw->flags |= DDRAW_GDI_FLIP;
 
     if (ddraw->primary)
-        ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE, 0);
+        ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE);
 
     return DD_OK;
 }
@@ -4910,19 +4909,18 @@ void ddraw_update_lost_surfaces(struct ddraw *ddraw)
     ddraw->device_state = DDRAW_DEVICE_STATE_OK;
 }
 
-static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent,
-        enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
         void **parent, const struct wined3d_parent_ops **parent_ops)
 {
     struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
     struct ddraw_surface *ddraw_surface;
 
-    TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
-            device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops);
+    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     /* We have a swapchain or wined3d internal texture. */
-    if (type != WINED3D_RTYPE_TEXTURE_2D || !wined3d_texture_get_parent(wined3d_texture)
-            || wined3d_texture_get_parent(wined3d_texture) == ddraw)
+    if (!wined3d_texture_get_parent(wined3d_texture) || wined3d_texture_get_parent(wined3d_texture) == ddraw)
     {
         *parent = NULL;
         *parent_ops = &ddraw_null_wined3d_parent_ops;
@@ -4947,6 +4945,19 @@ static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_d
     return DD_OK;
 }
 
+static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+        void **parent, const struct wined3d_parent_ops **parent_ops)
+{
+    TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
+
+    *parent = NULL;
+    *parent_ops = &ddraw_null_wined3d_parent_ops;
+
+    return DD_OK;
+}
+
 static void STDMETHODCALLTYPE ddraw_frontbuffer_destroyed(void *parent)
 {
     struct ddraw *ddraw = parent;
@@ -4963,26 +4974,25 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic
         struct wined3d_texture **texture)
 {
     struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
-    const struct wined3d_parent_ops *parent_ops;
     HRESULT hr;
 
     TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n",
             device_parent, container_parent, desc, texture_flags, texture);
 
-    if (!ddraw->wined3d_frontbuffer)
-        parent_ops = &ddraw_frontbuffer_parent_ops;
-    else
-        parent_ops = &ddraw_null_wined3d_parent_ops;
+    if (ddraw->wined3d_frontbuffer)
+    {
+        ERR("Frontbuffer already created.\n");
+        return E_FAIL;
+    }
 
     if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, 1,
-            texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, parent_ops, texture)))
+            texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture)))
     {
         WARN("Failed to create texture, hr %#x.\n", hr);
         return hr;
     }
 
-    if (!ddraw->wined3d_frontbuffer)
-        ddraw->wined3d_frontbuffer = *texture;
+    ddraw->wined3d_frontbuffer = *texture;
 
     return hr;
 }
@@ -5013,7 +5023,8 @@ static const struct wined3d_device_parent_ops ddraw_wined3d_device_parent_ops =
     device_parent_wined3d_device_created,
     device_parent_mode_changed,
     device_parent_activate,
-    device_parent_texture_sub_resource_created,
+    device_parent_surface_created,
+    device_parent_volume_created,
     device_parent_create_swapchain_texture,
     device_parent_create_swapchain,
 };
index 1bba80c..cac38c5 100644 (file)
@@ -57,15 +57,14 @@ struct FvfToDecl
 #define DDRAW_NO3D              0x00000008
 #define DDRAW_SCL_DDRAW1        0x00000010
 #define DDRAW_SCL_RECURSIVE     0x00000020
-#define DDRAW_SWAPPED           0x00000040
-#define DDRAW_GDI_FLIP          0x00000080
+#define DDRAW_GDI_FLIP          0x00000040
 
 #define DDRAW_STRIDE_ALIGNMENT  8
 
 #define DDRAW_WINED3D_FLAGS     (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \
         | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \
         | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \
-        | WINED3D_LEGACY_CUBEMAP_FILTERING)
+        | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT)
 
 enum ddraw_device_state
 {
@@ -219,7 +218,7 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw,
         struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
         const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
 HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
-        const RECT *rect, BOOL read, unsigned int swap_interval) DECLSPEC_HIDDEN;
+        const RECT *rect, BOOL read) DECLSPEC_HIDDEN;
 
 static inline struct ddraw_surface *impl_from_IDirect3DTexture(IDirect3DTexture *iface)
 {
index 799b2bc..24dbd3b 100644 (file)
@@ -5296,12 +5296,25 @@ static HRESULT WINAPI d3d_device7_Clear_FPUPreserve(IDirect3DDevice7 *iface, DWO
     return hr;
 }
 
+/*****************************************************************************
+ * IDirect3DDevice7::SetViewport
+ *
+ * Sets the current viewport.
+ *
+ * Version 7 only, but IDirect3DViewport uses this call for older
+ * versions
+ *
+ * Params:
+ *  Data: The new viewport to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
 static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport)
 {
     struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
-    struct wined3d_sub_resource_desc rt_desc;
-    struct wined3d_rendertarget_view *rtv;
-    struct ddraw_surface *surface;
     struct wined3d_viewport vp;
 
     TRACE("iface %p, viewport %p.\n", iface, viewport);
@@ -5309,23 +5322,6 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi
     if (!viewport)
         return DDERR_INVALIDPARAMS;
 
-    wined3d_mutex_lock();
-    if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
-    {
-        wined3d_mutex_unlock();
-        return DDERR_INVALIDCAPS;
-    }
-    surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
-    wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
-
-    if (viewport->dwX > rt_desc.width || viewport->dwWidth > rt_desc.width - viewport->dwX
-            || viewport->dwY > rt_desc.height || viewport->dwHeight > rt_desc.height - viewport->dwY)
-    {
-        WARN("Invalid viewport, returning E_INVALIDARG.\n");
-        wined3d_mutex_unlock();
-        return E_INVALIDARG;
-    }
-
     vp.x = viewport->dwX;
     vp.y = viewport->dwY;
     vp.width = viewport->dwWidth;
@@ -5333,7 +5329,8 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi
     vp.min_z = viewport->dvMinZ;
     vp.max_z = viewport->dvMaxZ;
 
-    wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
+    wined3d_mutex_lock();
+    wined3d_device_set_viewport(device->wined3d_device, &vp);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -5356,6 +5353,21 @@ static HRESULT WINAPI d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7 *ifac
     return hr;
 }
 
+/*****************************************************************************
+ * IDirect3DDevice::GetViewport
+ *
+ * Returns the current viewport
+ *
+ * Version 7
+ *
+ * Params:
+ *  Data: D3D7Viewport structure to write the viewport information to
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
 static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport)
 {
     struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
@@ -5367,7 +5379,7 @@ static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi
         return DDERR_INVALIDPARAMS;
 
     wined3d_mutex_lock();
-    wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport);
+    wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
     wined3d_mutex_unlock();
 
     viewport->dwX = wined3d_viewport.x;
index e2c4fc1..17bea27 100644 (file)
@@ -348,7 +348,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
                             wined3d_device_copy_sub_resource_region(device->wined3d_device,
                                     wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0,
                                     ci->wDest * sizeof(D3DTLVERTEX), 0, 0,
-                                    wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box, 0);
+                                    wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box);
                             break;
 
                         default:
@@ -610,16 +610,9 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
     struct wined3d_map_desc map_desc;
     struct wined3d_box box = {0};
     HRESULT hr;
-    DWORD buf_size = buffer->desc.dwBufferSize, copy_size;
 
     TRACE("iface %p, data %p.\n", iface, data);
 
-    if (data->dwSize != sizeof(*data))
-    {
-        WARN("data->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", data->dwSize);
-        return DDERR_INVALIDPARAMS;
-    }
-
     /* Skip past previous vertex data. */
     buffer->src_vertex_pos += buffer->data.dwVertexCount;
 
@@ -666,7 +659,7 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
         buffer->src_vertex_pos = 0;
     }
 
-    if (data->dwVertexCount && (!buf_size || data->dwVertexOffset < buf_size))
+    if (data->dwVertexCount)
     {
         box.left = buffer->src_vertex_pos * sizeof(D3DVERTEX);
         box.right = box.left + data->dwVertexCount * sizeof(D3DVERTEX);
@@ -674,11 +667,8 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
                 0, &map_desc, &box, WINED3D_MAP_WRITE)))
             return hr;
 
-        copy_size = data->dwVertexCount * sizeof(D3DVERTEX);
-        if (buf_size)
-            copy_size = min(copy_size, buf_size - data->dwVertexOffset);
-
-        memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset, copy_size);
+        memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset,
+                data->dwVertexCount * sizeof(D3DVERTEX));
 
         wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0);
     }
@@ -706,11 +696,12 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
 static HRESULT WINAPI d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer *iface, D3DEXECUTEDATA *data)
 {
     struct d3d_execute_buffer *buffer = impl_from_IDirect3DExecuteBuffer(iface);
+    DWORD dwSize;
 
     TRACE("iface %p, data %p.\n", iface, data);
 
-    /* Tests show that dwSize is ignored. */
-    memcpy(data, &buffer->data, sizeof(*data));
+    dwSize = data->dwSize;
+    memcpy(data, &buffer->data, dwSize);
 
     if (TRACE_ON(ddraw))
     {
index 87aec96..5148832 100644 (file)
@@ -176,7 +176,7 @@ static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette *iface,
     hr = wined3d_palette_set_entries(palette->wined3d_palette, flags, start, count, entries);
 
     if (SUCCEEDED(hr) && palette->flags & DDPCAPS_PRIMARYSURFACE)
-        ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE, 0);
+        ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE);
 
     wined3d_mutex_unlock();
 
index df8d038..11a0e6b 100644 (file)
@@ -40,22 +40,15 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra
  * applications from drawing to the screen while we've locked the frontbuffer.
  * We'd like to do this in wined3d instead, but for that to work wined3d needs
  * to support windowless rendering first. */
-HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
-        const RECT *rect, BOOL read, unsigned int swap_interval)
+HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read)
 {
-    struct wined3d_texture *dst_texture;
+    struct ddraw *ddraw = surface->ddraw;
     HDC surface_dc, screen_dc;
     int x, y, w, h;
     HRESULT hr;
     BOOL ret;
     RECT r;
 
-    if (surface->ddraw->flags & DDRAW_SWAPPED && !read)
-    {
-        surface->ddraw->flags &= ~DDRAW_SWAPPED;
-        rect = NULL;
-    }
-
     if (!rect)
     {
         SetRect(&r, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
@@ -70,25 +63,15 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
     if (w <= 0 || h <= 0)
         return DD_OK;
 
-    if (surface->ddraw->swapchain_window && !(surface->ddraw->flags & DDRAW_GDI_FLIP))
+    if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP))
     {
         /* Nothing to do, we control the frontbuffer, or at least the parts we
          * care about. */
         if (read)
             return DD_OK;
 
-        if (swap_interval)
-            dst_texture = wined3d_swapchain_get_back_buffer(surface->ddraw->wined3d_swapchain, 0);
-        else
-            dst_texture = surface->ddraw->wined3d_frontbuffer;
-
-        if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture,
-                surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval)
-        {
-            hr = wined3d_swapchain_present(surface->ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0);
-            surface->ddraw->flags |= DDRAW_SWAPPED;
-        }
-        return hr;
+        return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect,
+                surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT);
     }
 
     if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc)))
@@ -491,7 +474,7 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD
             palette_impl->flags |= DDPCAPS_PRIMARYSURFACE;
         wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain,
                 palette_impl ? palette_impl->wined3d_palette : NULL);
-        ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
+        ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
     }
     if (palette_impl)
         IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface);
@@ -1007,7 +990,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface,
     }
 
     if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-        hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0);
+        hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE);
     if (SUCCEEDED(hr))
         hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture),
                 surface->sub_resource_idx, &map_desc, rect ? &box : NULL,
@@ -1196,7 +1179,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Unlock(IDirectDrawSurface
     wined3d_mutex_lock();
     hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx);
     if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-        hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE, 0);
+        hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE);
     wined3d_mutex_unlock();
 
     return hr;
@@ -1241,24 +1224,6 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Unlock(IDirectDrawSurface
     return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL);
 }
 
-static unsigned int ddraw_swap_interval_from_flags(DWORD flags)
-{
-    if (flags & DDFLIP_NOVSYNC)
-        return 0;
-
-    switch (flags & (DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4))
-    {
-        case DDFLIP_INTERVAL2:
-            return 2;
-        case DDFLIP_INTERVAL3:
-            return 3;
-        case DDFLIP_INTERVAL4:
-            return 4;
-        default:
-            return 1;
-    }
-}
-
 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 *iface,
         IDirectDrawSurface7 *src, DWORD flags)
 {
@@ -1372,7 +1337,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7
     wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture);
     src_impl->wined3d_texture = texture;
 
-    if (flags & ~(DDFLIP_NOVSYNC | DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4))
+    if (flags)
     {
         static UINT once;
         if (!once++)
@@ -1382,7 +1347,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7
     }
 
     if (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-        hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE, ddraw_swap_interval_from_flags(flags));
+        hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE);
     else
         hr = DD_OK;
 
@@ -1523,11 +1488,11 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
     if (!dst_surface->clipper)
     {
         if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-            hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0);
+            hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE);
         if (SUCCEEDED(hr))
             hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fill_colour, fx, filter);
         if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
-            hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0);
+            hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE);
 
         return hr;
     }
@@ -1570,7 +1535,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
 
             if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
             {
-                if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE, 0)))
+                if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE)))
                     break;
             }
         }
@@ -1581,7 +1546,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
 
         if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
         {
-            if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE, 0)))
+            if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE)))
                 break;
         }
     }
@@ -2254,7 +2219,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc)
     if (surface->dc)
         hr = DDERR_DCALREADYCREATED;
     else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-        hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0);
+        hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE);
     if (SUCCEEDED(hr))
         hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc);
 
@@ -2358,7 +2323,7 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h
     {
         surface->dc = NULL;
         if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-            hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
+            hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
     }
     wined3d_mutex_unlock();
 
@@ -4326,12 +4291,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac
     }
 
     if (src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-        hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0);
+        hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE);
     if (SUCCEEDED(hr))
         hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect,
                 src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT);
     if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
-        hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0);
+        hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE);
     wined3d_mutex_unlock();
 
     switch(hr)
index b0a028d..65f24dc 100644 (file)
@@ -570,7 +570,7 @@ unsigned int wined3dmapflags_from_ddrawmapflags(unsigned int flags)
     unsigned int wined3d_flags;
 
     wined3d_flags = flags & handled;
-    if (!(flags & (DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS | DDLOCK_WRITEONLY)))
+    if (!(flags & (DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS)))
         wined3d_flags |= WINED3D_MAP_READ;
     if (!(flags & DDLOCK_READONLY))
         wined3d_flags |= WINED3D_MAP_WRITE;
@@ -578,7 +578,7 @@ unsigned int wined3dmapflags_from_ddrawmapflags(unsigned int flags)
         wined3d_flags |= WINED3D_MAP_READ | WINED3D_MAP_WRITE;
     if (flags & DDLOCK_NODIRTYUPDATE)
         wined3d_flags |= WINED3D_MAP_NO_DIRTY_UPDATE;
-    flags &= ~(handled | DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_WRITEONLY | DDLOCK_NODIRTYUPDATE);
+    flags &= ~(handled | DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_NODIRTYUPDATE);
 
     if (flags)
         FIXME("Unhandled flags %#x.\n", flags);
index f2caf20..6ef3226 100644 (file)
@@ -249,118 +249,109 @@ static HRESULT WINAPI d3d_viewport_Initialize(IDirect3DViewport3 *iface, IDirect
     return DDERR_ALREADYINITIALIZED;
 }
 
-static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *vp)
+/*****************************************************************************
+ * IDirect3DViewport3::GetViewport
+ *
+ * Returns the viewport data assigned to this viewport interface
+ *
+ * Params:
+ *  Data: Address to store the data
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData)
 {
-    struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
-    DWORD size;
-
-    TRACE("iface %p, vp %p.\n", iface, vp);
+    struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
+    DWORD dwSize;
 
-    if (!vp)
-        return DDERR_INVALIDPARAMS;
+    TRACE("iface %p, data %p.\n", iface, lpData);
 
     wined3d_mutex_lock();
 
-    size = vp->dwSize;
-    if (!viewport->use_vp2)
-    {
-        memcpy(vp, &viewport->viewports.vp1, size);
-    }
-    else
-    {
+    dwSize = lpData->dwSize;
+    if (!This->use_vp2)
+        memcpy(lpData, &(This->viewports.vp1), dwSize);
+    else {
         D3DVIEWPORT vp1;
-
         vp1.dwSize = sizeof(vp1);
-        vp1.dwX = viewport->viewports.vp2.dwX;
-        vp1.dwY = viewport->viewports.vp2.dwY;
-        vp1.dwWidth = viewport->viewports.vp2.dwWidth;
-        vp1.dwHeight = viewport->viewports.vp2.dwHeight;
+        vp1.dwX = This->viewports.vp2.dwX;
+        vp1.dwY = This->viewports.vp2.dwY;
+        vp1.dwWidth = This->viewports.vp2.dwWidth;
+        vp1.dwHeight = This->viewports.vp2.dwHeight;
         vp1.dvMaxX = 0.0;
         vp1.dvMaxY = 0.0;
         vp1.dvScaleX = 0.0;
         vp1.dvScaleY = 0.0;
-        vp1.dvMinZ = viewport->viewports.vp2.dvMinZ;
-        vp1.dvMaxZ = viewport->viewports.vp2.dvMaxZ;
-        memcpy(vp, &vp1, size);
+        vp1.dvMinZ = This->viewports.vp2.dvMinZ;
+        vp1.dvMaxZ = This->viewports.vp2.dvMaxZ;
+        memcpy(lpData, &vp1, dwSize);
     }
 
     if (TRACE_ON(ddraw))
     {
         TRACE("  returning D3DVIEWPORT :\n");
-        _dump_D3DVIEWPORT(vp);
+        _dump_D3DVIEWPORT(lpData);
     }
 
     wined3d_mutex_unlock();
 
-    return D3D_OK;
+    return DD_OK;
 }
 
-static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *vp)
+/*****************************************************************************
+ * IDirect3DViewport3::SetViewport
+ *
+ * Sets the viewport information for this interface
+ *
+ * Params:
+ *  lpData: Viewport to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData)
 {
-    struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
-    struct d3d_device *device = viewport->active_device;
-    struct wined3d_sub_resource_desc rt_desc;
-    struct wined3d_rendertarget_view *rtv;
+    struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
     IDirect3DViewport3 *current_viewport;
-    struct ddraw_surface *surface;
 
-    TRACE("iface %p, vp %p.\n", iface, vp);
-
-    if (!vp)
-        return DDERR_INVALIDPARAMS;
+    TRACE("iface %p, data %p.\n", iface, lpData);
 
     if (TRACE_ON(ddraw))
     {
         TRACE("  getting D3DVIEWPORT :\n");
-        _dump_D3DVIEWPORT(vp);
-    }
-
-    if (!device)
-    {
-        WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n");
-        return D3DERR_VIEWPORTHASNODEVICE;
+        _dump_D3DVIEWPORT(lpData);
     }
 
     wined3d_mutex_lock();
 
-    if (device->version > 1)
-    {
-        if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
-        {
-            wined3d_mutex_unlock();
-            return DDERR_INVALIDCAPS;
-        }
-        surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
-        wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
-
-        if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX
-            || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY)
-        {
-            WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n");
-            wined3d_mutex_unlock();
-            return DDERR_INVALIDPARAMS;
-        }
-    }
-
-    viewport->use_vp2 = 0;
-    memset(&viewport->viewports.vp1, 0, sizeof(viewport->viewports.vp1));
-    memcpy(&viewport->viewports.vp1, vp, vp->dwSize);
+    This->use_vp2 = 0;
+    memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
+    memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
 
-    /* Empirical testing on a couple of d3d1 games showed that these values
-     * should be ignored. */
-    viewport->viewports.vp1.dvMinZ = 0.0;
-    viewport->viewports.vp1.dvMaxZ = 1.0;
+    /* Tests on two games show that these values are never used properly so override
+       them with proper ones :-)
+    */
+    This->viewports.vp1.dvMinZ = 0.0;
+    This->viewports.vp1.dvMaxZ = 1.0;
 
-    if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, &current_viewport)))
+    if (This->active_device)
     {
-        if (current_viewport == iface)
-            viewport_activate(viewport, FALSE);
-        IDirect3DViewport3_Release(current_viewport);
+        IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
+        if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport)))
+        {
+            if (current_viewport == iface) viewport_activate(This, FALSE);
+            IDirect3DViewport3_Release(current_viewport);
+        }
     }
 
     wined3d_mutex_unlock();
 
-    return D3D_OK;
+    return DD_OK;
 }
 
 /*****************************************************************************
@@ -891,44 +882,53 @@ static HRESULT WINAPI d3d_viewport_NextLight(IDirect3DViewport3 *iface,
  * IDirect3DViewport2 Methods.
  *****************************************************************************/
 
-static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *vp)
+/*****************************************************************************
+ * IDirect3DViewport3::GetViewport2
+ *
+ * Returns the currently set viewport in a D3DVIEWPORT2 structure.
+ * Similar to IDirect3DViewport3::GetViewport
+ *
+ * Params:
+ *  lpData: Pointer to the structure to fill
+ *
+ * Returns:
+ *  D3D_OK on success
+ *  DDERR_INVALIDPARAMS if the viewport was set with
+ *                      IDirect3DViewport3::SetViewport
+ *  DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData)
 {
-    struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
-    DWORD size;
-
-    TRACE("iface %p, vp %p.\n", iface, vp);
+    struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
+    DWORD dwSize;
 
-    if (!vp)
-        return DDERR_INVALIDPARAMS;
+    TRACE("iface %p, data %p.\n", iface, lpData);
 
     wined3d_mutex_lock();
-    size = vp->dwSize;
-    if (viewport->use_vp2)
-    {
-        memcpy(vp, &viewport->viewports.vp2, size);
-    }
-    else
-    {
+    dwSize = lpData->dwSize;
+    if (This->use_vp2)
+        memcpy(lpData, &(This->viewports.vp2), dwSize);
+    else {
         D3DVIEWPORT2 vp2;
-
         vp2.dwSize = sizeof(vp2);
-        vp2.dwX = viewport->viewports.vp1.dwX;
-        vp2.dwY = viewport->viewports.vp1.dwY;
-        vp2.dwWidth = viewport->viewports.vp1.dwWidth;
-        vp2.dwHeight = viewport->viewports.vp1.dwHeight;
+        vp2.dwX = This->viewports.vp1.dwX;
+        vp2.dwY = This->viewports.vp1.dwY;
+        vp2.dwWidth = This->viewports.vp1.dwWidth;
+        vp2.dwHeight = This->viewports.vp1.dwHeight;
         vp2.dvClipX = 0.0;
         vp2.dvClipY = 0.0;
         vp2.dvClipWidth = 0.0;
         vp2.dvClipHeight = 0.0;
-        vp2.dvMinZ = viewport->viewports.vp1.dvMinZ;
-        vp2.dvMaxZ = viewport->viewports.vp1.dvMaxZ;
-        memcpy(vp, &vp2, size);
+        vp2.dvMinZ = This->viewports.vp1.dvMinZ;
+        vp2.dvMaxZ = This->viewports.vp1.dvMaxZ;
+        memcpy(lpData, &vp2, dwSize);
     }
 
     if (TRACE_ON(ddraw))
     {
         TRACE("  returning D3DVIEWPORT2 :\n");
-        _dump_D3DVIEWPORT2(vp);
+        _dump_D3DVIEWPORT2(lpData);
     }
 
     wined3d_mutex_unlock();
@@ -936,64 +936,47 @@ static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVI
     return D3D_OK;
 }
 
-static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *vp)
+/*****************************************************************************
+ * IDirect3DViewport3::SetViewport2
+ *
+ * Sets the viewport from a D3DVIEWPORT2 structure
+ *
+ * Params:
+ *  lpData: Viewport to set
+ *
+ * Returns:
+ *  D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData)
 {
-    struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
-    struct d3d_device *device = viewport->active_device;
-    struct wined3d_sub_resource_desc rt_desc;
-    struct wined3d_rendertarget_view *rtv;
+    struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
     IDirect3DViewport3 *current_viewport;
-    struct ddraw_surface *surface;
-
-    TRACE("iface %p, vp %p.\n", iface, vp);
 
-    if (!vp)
-        return DDERR_INVALIDPARAMS;
+    TRACE("iface %p, data %p.\n", iface, lpData);
 
     if (TRACE_ON(ddraw))
     {
         TRACE("  getting D3DVIEWPORT2 :\n");
-        _dump_D3DVIEWPORT2(vp);
-    }
-
-    if (!device)
-    {
-        WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n");
-        return D3DERR_VIEWPORTHASNODEVICE;
+        _dump_D3DVIEWPORT2(lpData);
     }
 
     wined3d_mutex_lock();
 
-    if (device->version > 1)
-    {
-        if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
-        {
-            wined3d_mutex_unlock();
-            return DDERR_INVALIDCAPS;
-        }
-        surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
-        wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
+    This->use_vp2 = 1;
+    memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
+    memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
 
-        if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX
-            || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY)
+    if (This->active_device)
+    {
+        IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
+        if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport)))
         {
-            WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n");
-            wined3d_mutex_unlock();
-            return DDERR_INVALIDPARAMS;
+            if (current_viewport == iface) viewport_activate(This, FALSE);
+            IDirect3DViewport3_Release(current_viewport);
         }
     }
 
-    viewport->use_vp2 = 1;
-    memset(&viewport->viewports.vp2, 0, sizeof(viewport->viewports.vp2));
-    memcpy(&viewport->viewports.vp2, vp, vp->dwSize);
-
-    if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, &current_viewport)))
-    {
-        if (current_viewport == iface)
-            viewport_activate(viewport, FALSE);
-        IDirect3DViewport3_Release(current_viewport);
-    }
-
     wined3d_mutex_unlock();
 
     return D3D_OK;
index 6a6bf74..235adab 100644 (file)
@@ -7,11 +7,6 @@ add_definitions(
 
 include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
 
-if(MSVC)
-    # error C4312: 'type cast': conversion from 'LONG' to 'void *' of greater size
-    replace_compile_flags("/we4312" " ")
-endif()
-
 # We name this d3dwine.dll, because the Virtualbox additions ship with a custom wined3d.dll
 # and it breaks everything if it is installed.
 spec2def(d3dwine.dll wined3d.spec ADD_IMPORTLIB)
@@ -46,7 +41,7 @@ list(APPEND SOURCE
     wined3d_main.c
     precomp.h)
 
-add_library(d3dwine MODULE
+add_library(d3dwine SHARED
     ${SOURCE}
     version.rc
     ${CMAKE_CURRENT_BINARY_DIR}/d3dwine.def)
index 4fbb3a5..f86c167 100644 (file)
@@ -611,7 +611,7 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g
     unsigned char i;
 
     /* Upload the position fixup */
-    shader_get_position_fixup(context, state, 1, position_fixup);
+    shader_get_position_fixup(context, state, position_fixup);
     GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->pos_fixup, position_fixup));
 
     if (!gl_shader->num_int_consts) return;
@@ -1061,7 +1061,7 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
                             /* This is better than nothing for now */
                             sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset);
                         }
-                        else if(ctx->cur_ps_args->super.vp_mode != WINED3D_VP_MODE_SHADER)
+                        else if(ctx->cur_ps_args->super.vp_mode != vertexshader)
                         {
                             /* This is problematic because we'd have to consult the ctx->ps_input strings
                              * for where to find the varying. Some may be "0.0", others can be texcoords or
@@ -1416,6 +1416,9 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
     struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     const char *mod;
     BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
+    const struct wined3d_shader *shader;
+    const struct wined3d_device *device;
+    const struct wined3d_gl_info *gl_info;
     const char *tex_dst = dst_str;
     struct color_fixup_masks masks;
 
@@ -1429,8 +1432,12 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
             break;
 
         case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
+            shader = ins->ctx->shader;
+            device = shader->device;
+            gl_info = &device->adapter->gl_info;
+
             if (pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx)
-                    && ins->ctx->gl_info->supported[ARB_TEXTURE_RECTANGLE])
+                    && gl_info->supported[ARB_TEXTURE_RECTANGLE])
                 tex_type = "RECT";
             else
                 tex_type = "2D";
@@ -3415,68 +3422,73 @@ static void init_ps_input(const struct wined3d_shader *shader,
     const char *semantic_name;
     DWORD semantic_idx;
 
-    if (args->super.vp_mode == WINED3D_VP_MODE_SHADER)
-    {
-        /* That one is easy. The vertex shaders provide v0-v7 in
-         * fragment.texcoord and v8 and v9 in fragment.color. */
-        for (i = 0; i < 8; ++i)
-        {
-            priv->ps_input[i] = texcoords[i];
-        }
-        priv->ps_input[8] = "fragment.color.primary";
-        priv->ps_input[9] = "fragment.color.secondary";
-        return;
-    }
+    switch(args->super.vp_mode)
+    {
+        case pretransformed:
+        case fixedfunction:
+            /* The pixelshader has to collect the varyings on its own. In any case properly load
+             * color0 and color1. In the case of pretransformed vertices also load texcoords. Set
+             * other attribs to 0.0.
+             *
+             * For fixedfunction this behavior is correct, according to the tests. For pretransformed
+             * we'd either need a replacement shader that can load other attribs like BINORMAL, or
+             * load the texcoord attrib pointers to match the pixel shader signature
+             */
+            for (i = 0; i < shader->input_signature.element_count; ++i)
+            {
+                input = &shader->input_signature.elements[i];
+                if (!(semantic_name = input->semantic_name))
+                    continue;
+                semantic_idx = input->semantic_idx;
 
-    /* The fragment shader has to collect the varyings on its own. In any case
-     * properly load color0 and color1. In the case of pre-transformed
-     * vertices also load texture coordinates. Set other attributes to 0.0.
-     *
-     * For fixed-function this behavior is correct, according to the tests.
-     * For pre-transformed we'd either need a replacement shader that can load
-     * other attributes like BINORMAL, or load the texture coordinate
-     * attribute pointers to match the fragment shader signature. */
-    for (i = 0; i < shader->input_signature.element_count; ++i)
-    {
-        input = &shader->input_signature.elements[i];
-        if (!(semantic_name = input->semantic_name))
-            continue;
-        semantic_idx = input->semantic_idx;
+                if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+                {
+                    if (!semantic_idx)
+                        priv->ps_input[input->register_idx] = "fragment.color.primary";
+                    else if (semantic_idx == 1)
+                        priv->ps_input[input->register_idx] = "fragment.color.secondary";
+                    else
+                        priv->ps_input[input->register_idx] = "0.0";
+                }
+                else if (args->super.vp_mode == fixedfunction)
+                {
+                    priv->ps_input[input->register_idx] = "0.0";
+                }
+                else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+                {
+                    if (semantic_idx < 8)
+                        priv->ps_input[input->register_idx] = texcoords[semantic_idx];
+                    else
+                        priv->ps_input[input->register_idx] = "0.0";
+                }
+                else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
+                {
+                    if (!semantic_idx)
+                        priv->ps_input[input->register_idx] = "fragment.fogcoord";
+                    else
+                        priv->ps_input[input->register_idx] = "0.0";
+                }
+                else
+                {
+                    priv->ps_input[input->register_idx] = "0.0";
+                }
 
-        if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
-        {
-            if (!semantic_idx)
-                priv->ps_input[input->register_idx] = "fragment.color.primary";
-            else if (semantic_idx == 1)
-                priv->ps_input[input->register_idx] = "fragment.color.secondary";
-            else
-                priv->ps_input[input->register_idx] = "0.0";
-        }
-        else if (args->super.vp_mode == WINED3D_VP_MODE_FF)
-        {
-            priv->ps_input[input->register_idx] = "0.0";
-        }
-        else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
-        {
-            if (semantic_idx < 8)
-                priv->ps_input[input->register_idx] = texcoords[semantic_idx];
-            else
-                priv->ps_input[input->register_idx] = "0.0";
-        }
-        else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
-        {
-            if (!semantic_idx)
-                priv->ps_input[input->register_idx] = "fragment.fogcoord";
-            else
-                priv->ps_input[input->register_idx] = "0.0";
-        }
-        else
-        {
-            priv->ps_input[input->register_idx] = "0.0";
-        }
+                TRACE("v%u, semantic %s%u is %s\n", input->register_idx,
+                        semantic_name, semantic_idx, priv->ps_input[input->register_idx]);
+            }
+            break;
 
-        TRACE("v%u, semantic %s%u is %s\n", input->register_idx,
-                semantic_name, semantic_idx, priv->ps_input[input->register_idx]);
+        case vertexshader:
+            /* That one is easy. The vertex shaders provide v0-v7 in fragment.texcoord and v8 and v9 in
+             * fragment.color
+             */
+            for(i = 0; i < 8; i++)
+            {
+                priv->ps_input[i] = texcoords[i];
+            }
+            priv->ps_input[8] = "fragment.color.primary";
+            priv->ps_input[9] = "fragment.color.secondary";
+            break;
     }
 }
 
@@ -6072,19 +6084,17 @@ static const char *get_argreg(struct wined3d_string_buffer *buffer, DWORD argnum
 }
 
 static void gen_ffp_instr(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color,
-        BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+        BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
 {
     const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
     unsigned int mul = 1;
 
-    if (color && alpha)
-        dstmask = "";
-    else if (color)
-        dstmask = ".xyz";
-    else
-        dstmask = ".w";
+    if(color && alpha) dstmask = "";
+    else if(color) dstmask = ".xyz";
+    else dstmask = ".w";
 
-    dstreg = tmp_dst ? "tempreg" : "ret";
+    if(dst == tempreg) dstreg = "tempreg";
+    else dstreg = "ret";
 
     arg0 = get_argreg(buffer, 0, stage, dw_arg0);
     arg1 = get_argreg(buffer, 1, stage, dw_arg1);
@@ -6263,7 +6273,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
 
         if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE)
             tex_read |= 1u << stage;
-        if (settings->op[stage].tmp_dst)
+        if (settings->op[stage].dst == tempreg)
             tempreg_used = TRUE;
         if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
             tempreg_used = TRUE;
@@ -6381,17 +6391,12 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
 
         textype = arbfp_texture_target(settings->op[stage].tex_type);
 
-        if (settings->op[stage].projected == WINED3D_PROJECTION_NONE)
-        {
+        if(settings->op[stage].projected == proj_none) {
             instr = "TEX";
-        }
-        else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4
-                || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
-        {
+        } else if(settings->op[stage].projected == proj_count4 ||
+                  settings->op[stage].projected == proj_count3) {
             instr = "TXP";
-        }
-        else
-        {
+        } else {
             FIXME("Unexpected projection mode %d\n", settings->op[stage].projected);
             instr = "TXP";
         }
@@ -6405,27 +6410,18 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
             shader_addline(&buffer, "SWZ arg1, bumpmat%u, y, w, 0, 0;\n", stage - 1);
             shader_addline(&buffer, "DP3 ret.y, arg1, tex%u;\n", stage - 1);
 
-            /* With projective textures, texbem only divides the static
-             * texture coordinate, not the displacement, so multiply the
-             * displacement with the dividing parameter before passing it to
-             * TXP. */
-            if (settings->op[stage].projected != WINED3D_PROJECTION_NONE)
-            {
-                if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4)
-                {
+            /* with projective textures, texbem only divides the static texture coord, not the displacement,
+             * so multiply the displacement with the dividing parameter before passing it to TXP
+             */
+            if (settings->op[stage].projected != proj_none) {
+                if(settings->op[stage].projected == proj_count4) {
                     shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].w;\n", stage);
-                    shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n",
-                            stage, stage);
-                }
-                else
-                {
+                    shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n", stage, stage);
+                } else {
                     shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].z;\n", stage);
-                    shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n",
-                            stage, stage);
+                    shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n", stage, stage);
                 }
-            }
-            else
-            {
+            } else {
                 shader_addline(&buffer, "ADD ret, ret, fragment.texcoord[%u];\n", stage);
             }
 
@@ -6437,16 +6433,12 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
                                stage - 1, stage - 1, stage - 1);
                 shader_addline(&buffer, "MUL tex%u, tex%u, ret.x;\n", stage, stage);
             }
-        }
-        else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
-        {
+        } else if(settings->op[stage].projected == proj_count3) {
             shader_addline(&buffer, "MOV ret, fragment.texcoord[%u];\n", stage);
             shader_addline(&buffer, "MOV ret.w, ret.z;\n");
             shader_addline(&buffer, "%s tex%u, ret, texture[%u], %s;\n",
                             instr, stage, stage, textype);
-        }
-        else
-        {
+        } else {
             shader_addline(&buffer, "%s tex%u, fragment.texcoord[%u], texture[%u], %s;\n",
                             instr, stage, stage, stage, textype);
         }
@@ -6495,23 +6487,23 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
 
         if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
         {
-            gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+            gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst,
                           settings->op[stage].cop, settings->op[stage].carg0,
                           settings->op[stage].carg1, settings->op[stage].carg2);
         }
         else if (op_equal)
         {
-            gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst,
+            gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst,
                           settings->op[stage].cop, settings->op[stage].carg0,
                           settings->op[stage].carg1, settings->op[stage].carg2);
         }
         else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP
                 && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE)
         {
-            gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+            gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst,
                           settings->op[stage].cop, settings->op[stage].carg0,
                           settings->op[stage].carg1, settings->op[stage].carg2);
-            gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst,
+            gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].dst,
                           settings->op[stage].aop, settings->op[stage].aarg0,
                           settings->op[stage].aarg1, settings->op[stage].aarg2);
         }
@@ -6936,8 +6928,8 @@ static void arbfp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3
     heap_free(arbfp_blitter);
 }
 
-static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer,
-        const struct arbfp_blit_type *type, char *luminance)
+static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
+        char *luminance)
 {
     char chroma;
     const char *tex, *texinstr = "TXP";
@@ -6985,12 +6977,13 @@ static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer,
     shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n");
     shader_addline(buffer, "ADD texcrd.x, texcrd.x, coef.y;\n");
 
-    /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25
-     * and 0.75 for the even and odd pixels respectively. */
+    /* Divide the x coordinate by 0.5 and get the fraction. This gives 0.25 and 0.75 for the
+     * even and odd pixels respectively
+     */
     shader_addline(buffer, "MUL texcrd2, texcrd, coef.y;\n");
     shader_addline(buffer, "FRC texcrd2, texcrd2;\n");
 
-    /* Sample Pixel 1. */
+    /* Sample Pixel 1 */
     shader_addline(buffer, "%s luminance, texcrd, texture[0], %s;\n", texinstr, tex);
 
     /* Put the value into either of the chroma values */
@@ -7019,10 +7012,12 @@ static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer,
 
     /* This gives the correctly filtered luminance value */
     shader_addline(buffer, "TEX luminance, fragment.texcoord[0], texture[0], %s;\n", tex);
+
+    return TRUE;
 }
 
-static void gen_yv12_read(struct wined3d_string_buffer *buffer,
-        const struct arbfp_blit_type *type, char *luminance)
+static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
+        char *luminance)
 {
     const char *tex;
     static const float yv12_coef[]
@@ -7084,6 +7079,7 @@ static void gen_yv12_read(struct wined3d_string_buffer *buffer,
      */
     if (type->res_type == WINED3D_GL_RES_TYPE_TEX_2D)
     {
+
         shader_addline(buffer, "RCP chroma.w, size.y;\n");
 
         shader_addline(buffer, "MUL texcrd2.y, texcrd.y, size.y;\n");
@@ -7091,7 +7087,7 @@ static void gen_yv12_read(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "FLR texcrd2.y, texcrd2.y;\n");
         shader_addline(buffer, "MAD texcrd.y, texcrd.y, yv12_coef.y, yv12_coef.x;\n");
 
-        /* Read odd lines from the right side (add size * 0.5 to the x coordinate). */
+        /* Read odd lines from the right side(add size * 0.5 to the x coordinate */
         shader_addline(buffer, "ADD texcrd2.x, texcrd2.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */
         shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n");
         shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n");
@@ -7105,11 +7101,11 @@ static void gen_yv12_read(struct wined3d_string_buffer *buffer,
     }
     else
     {
-        /* The y coordinate for V is in the range [size, size + size / 4). */
+        /* Read from [size - size+size/4] */
         shader_addline(buffer, "FLR texcrd.y, texcrd.y;\n");
         shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.w, size.y;\n");
 
-        /* Read odd lines from the right side (add size * 0.5 to the x coordinate). */
+        /* Read odd lines from the right side(add size * 0.5 to the x coordinate */
         shader_addline(buffer, "ADD texcrd2.x, texcrd.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */
         shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n");
         shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n");
@@ -7165,10 +7161,12 @@ static void gen_yv12_read(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex);
     }
     *luminance = 'a';
+
+    return TRUE;
 }
 
-static void gen_nv12_read(struct wined3d_string_buffer *buffer,
-        const struct arbfp_blit_type *type, char *luminance)
+static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
+        char *luminance)
 {
     const char *tex;
     static const float nv12_coef[]
@@ -7244,7 +7242,7 @@ static void gen_nv12_read(struct wined3d_string_buffer *buffer,
     }
     else
     {
-        /* The y coordinate for chroma is in the range [size, size + size / 2). */
+        /* Read from [size - size+size/2] */
         shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.y, size.y;\n");
 
         shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n");
@@ -7299,6 +7297,8 @@ static void gen_nv12_read(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex);
     }
     *luminance = 'a';
+
+    return TRUE;
 }
 
 /* Context activation is done by the caller. */
@@ -7464,15 +7464,27 @@ static GLuint gen_yuv_shader(const struct wined3d_gl_info *gl_info, const struct
     {
         case COMPLEX_FIXUP_UYVY:
         case COMPLEX_FIXUP_YUY2:
-            gen_packed_yuv_read(&buffer, type, &luminance_component);
+            if (!gen_planar_yuv_read(&buffer, type, &luminance_component))
+            {
+                string_buffer_free(&buffer);
+                return 0;
+            }
             break;
 
         case COMPLEX_FIXUP_YV12:
-            gen_yv12_read(&buffer, type, &luminance_component);
+            if (!gen_yv12_read(&buffer, type, &luminance_component))
+            {
+                string_buffer_free(&buffer);
+                return 0;
+            }
             break;
 
         case COMPLEX_FIXUP_NV12:
-            gen_nv12_read(&buffer, type, &luminance_component);
+            if (!gen_nv12_read(&buffer, type, &luminance_component))
+            {
+                string_buffer_free(&buffer);
+                return 0;
+            }
             break;
 
         default:
@@ -7698,7 +7710,7 @@ static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const struct wine
     enum complex_fixup src_fixup;
     BOOL decompress;
 
-    if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D)
+    if (!context->gl_info->supported[ARB_FRAGMENT_PROGRAM])
         return FALSE;
 
     if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id)
@@ -7783,105 +7795,59 @@ static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const struct wine
 }
 
 static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
-        struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
-        DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
-        unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
+        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)
 {
+    unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+    struct wined3d_texture *src_texture = src_surface->container;
+    struct wined3d_texture *dst_texture = dst_surface->container;
     struct wined3d_device *device = dst_texture->resource.device;
-    struct wined3d_texture *staging_texture = NULL;
     struct wined3d_arbfp_blitter *arbfp_blitter;
     struct wined3d_color_key alpha_test_key;
     struct wined3d_blitter *next;
-    unsigned int src_level;
     RECT s, d;
 
-    TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, "
-            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n",
-            blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location),
-            wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location),
-            wine_dbgstr_rect(dst_rect), color_key, debug_d3dtexturefiltertype(filter));
-
     if (!arbfp_blit_supported(op, context, &src_texture->resource, src_location,
             &dst_texture->resource, dst_location))
     {
-        if (!(next = blitter->next))
-        {
-            ERR("No blitter to handle blit op %#x.\n", op);
-            return dst_location;
-        }
-
-        TRACE("Forwarding to blitter %p.\n", next);
-        return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
-                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter);
+        if ((next = blitter->next))
+            return next->ops->blitter_blit(next, op, context, src_surface, src_location,
+                    src_rect, dst_surface, dst_location, dst_rect, color_key, filter);
     }
 
     arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter);
 
-    if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
-    {
-        struct wined3d_resource_desc desc;
-        struct wined3d_box upload_box;
-        HRESULT hr;
-
-        TRACE("Source texture is not GPU accessible, creating a staging texture.\n");
-
-        src_level = src_sub_resource_idx % src_texture->level_count;
-        desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
-        desc.format = src_texture->resource.format->id;
-        desc.multisample_type = src_texture->resource.multisample_type;
-        desc.multisample_quality = src_texture->resource.multisample_quality;
-        desc.usage = WINED3DUSAGE_PRIVATE;
-        desc.access = WINED3D_RESOURCE_ACCESS_GPU;
-        desc.width = wined3d_texture_get_level_width(src_texture, src_level);
-        desc.height = wined3d_texture_get_level_height(src_texture, src_level);
-        desc.depth = 1;
-        desc.size = 0;
-
-        if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0,
-                NULL, NULL, &wined3d_null_parent_ops, &staging_texture)))
-        {
-            ERR("Failed to create staging texture, hr %#x.\n", hr);
-            return dst_location;
-        }
-
-        wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth);
-        wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0,
-                src_texture, src_sub_resource_idx, &upload_box);
-
-        src_texture = staging_texture;
-        src_sub_resource_idx = 0;
-    }
-    else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
-            && (src_texture->sub_resources[src_sub_resource_idx].locations
-            & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) == WINED3D_LOCATION_DRAWABLE
+    /* Now load the surface */
+    if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+            && (surface_get_sub_resource(src_surface)->locations
+            & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE))
+            == WINED3D_LOCATION_DRAWABLE
             && !wined3d_resource_is_offscreen(&src_texture->resource))
     {
+        unsigned int src_level = src_sub_resource_idx % src_texture->level_count;
 
         /* Without FBO blits transferring from the drawable to the texture is
          * expensive, because we have to flip the data in sysmem. Since we can
          * flip in the blitter, we don't actually need that flip anyway. So we
          * use the surface's texture as scratch texture, and flip the source
          * rectangle instead. */
-        texture2d_load_fb_texture(src_texture, src_sub_resource_idx, FALSE, context);
+        surface_load_fb_texture(src_surface, FALSE, context);
 
         s = *src_rect;
-        src_level = src_sub_resource_idx % src_texture->level_count;
         s.top = wined3d_texture_get_level_height(src_texture, src_level) - s.top;
         s.bottom = wined3d_texture_get_level_height(src_texture, src_level) - s.bottom;
         src_rect = &s;
     }
     else
-    {
         wined3d_texture_load(src_texture, context, FALSE);
-    }
 
-    context_apply_ffp_blit_state(context, device);
+    context_apply_blit_state(context, device);
 
     if (dst_location == WINED3D_LOCATION_DRAWABLE)
     {
         d = *dst_rect;
-        wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &d);
+        surface_translate_drawable_coords(dst_surface, context->win_handle, &d);
         dst_rect = &d;
     }
 
@@ -7891,16 +7857,15 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
 
         if (dst_location == WINED3D_LOCATION_DRAWABLE)
         {
-            TRACE("Destination texture %p is onscreen.\n", dst_texture);
+            TRACE("Destination surface %p is onscreen.\n", dst_surface);
             buffer = wined3d_texture_get_gl_buffer(dst_texture);
         }
         else
         {
-            TRACE("Destination texture %p is offscreen.\n", dst_texture);
+            TRACE("Destination surface %p is offscreen.\n", dst_surface);
             buffer = GL_COLOR_ATTACHMENT0;
         }
-        context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER,
-                &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location);
+        context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location);
         context_set_draw_buffer(context, buffer);
         context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER);
         context_invalidate_state(context, STATE_FRAMEBUFFER);
@@ -7917,16 +7882,14 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
     arbfp_blit_set(arbfp_blitter, context, src_texture, src_sub_resource_idx, color_key);
 
     /* Draw a textured quad */
-    context_draw_textured_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter);
+    draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter);
 
     /* Leave the opengl state valid for blitting */
     arbfp_blit_unset(context->gl_info);
 
-    if (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture))
-        context->gl_info->gl_ops.gl.p_glFlush();
-
-    if (staging_texture)
-        wined3d_texture_decref(staging_texture);
+    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;
 }
index 9a1cae3..9d6837a 100644 (file)
@@ -341,8 +341,9 @@ static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES])
             lowest_read = i;
         }
 
-        if (lowest_write == -1 && op[i].tmp_dst)
+        if(lowest_write == -1 && op[i].dst == tempreg) {
             lowest_write = i;
+        }
 
         if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE ||
            op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) {
@@ -504,13 +505,16 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES],
 
         TRACE("glSampleMapATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, GL_SWIZZLE_STR_ATI)\n",
               stage, stage);
-        GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage, GL_TEXTURE0_ARB + stage, GL_SWIZZLE_STR_ATI));
-        if (op[stage + 1].projected == WINED3D_PROJECTION_NONE)
+        GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage,
+                   GL_TEXTURE0_ARB + stage,
+                   GL_SWIZZLE_STR_ATI));
+        if(op[stage + 1].projected == proj_none) {
             swizzle = GL_SWIZZLE_STR_ATI;
-        else if (op[stage + 1].projected == WINED3D_PROJECTION_COUNT4)
+        } else if(op[stage + 1].projected == proj_count4) {
             swizzle = GL_SWIZZLE_STQ_DQ_ATI;
-        else
+        } else {
             swizzle = GL_SWIZZLE_STR_DR_ATI;
+        }
         TRACE("glPassTexCoordATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, %s)\n",
               stage + 1, stage + 1, debug_swizzle(swizzle));
         GL_EXTCALL(glPassTexCoordATI(GL_REG_0_ATI + stage + 1,
@@ -575,12 +579,13 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES],
         if (op[stage].cop == WINED3D_TOP_DISABLE)
             break;
 
-        if (op[stage].projected == WINED3D_PROJECTION_NONE)
+        if(op[stage].projected == proj_none) {
             swizzle = GL_SWIZZLE_STR_ATI;
-        else if (op[stage].projected == WINED3D_PROJECTION_COUNT3)
+        } else if(op[stage].projected == proj_count3) {
             swizzle = GL_SWIZZLE_STR_DR_ATI;
-        else
+        } else {
             swizzle = GL_SWIZZLE_STQ_DQ_ATI;
+        }
 
         if (op_reads_texture(&op[stage]))
         {
@@ -619,18 +624,14 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES],
             break;
         }
 
-        if (op[stage].tmp_dst)
-        {
-            /* If we're writing to D3DTA_TEMP, but never reading from it we
-             * don't have to write there in the first place. Skip the entire
-             * stage, this saves some GPU time. */
-            if (tmparg == GL_NONE)
-                continue;
+        if(op[stage].dst == tempreg) {
+            /* If we're writing to D3DTA_TEMP, but never reading from it we don't have to write there in the first place.
+             * skip the entire stage, this saves some GPU time
+             */
+            if(tmparg == GL_NONE) continue;
 
             dstreg = tmparg;
-        }
-        else
-        {
+        } else {
             dstreg = GL_REG_0_ATI;
         }
 
index 9baf055..cae7ef8 100644 (file)
@@ -615,7 +615,10 @@ static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
                 return TRUE;
 
             if (!wined3d_resource_allocate_sysmem(&buffer->resource))
+            {
+                ERR("Failed to allocate system memory.\n");
                 return FALSE;
+            }
             return TRUE;
 
         case WINED3D_LOCATION_BUFFER:
@@ -1180,6 +1183,8 @@ static void wined3d_buffer_unmap(struct wined3d_buffer *buffer)
         }
 
         GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint));
+        if (wined3d_settings.strict_draw_ordering)
+            gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
         context_release(context);
 
         buffer_clear_dirty_areas(buffer);
@@ -1375,9 +1380,6 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
     buffer->bind_flags = bind_flags;
     buffer->locations = WINED3D_LOCATION_SYSMEM;
 
-    if (!wined3d_resource_allocate_sysmem(&buffer->resource))
-        return E_OUTOFMEMORY;
-
     TRACE("buffer %p, size %#x, usage %#x, format %s, memory @ %p.\n",
             buffer, buffer->resource.size, buffer->resource.usage,
             debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory);
@@ -1426,7 +1428,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
 
     if (data)
         wined3d_device_update_sub_resource(device, &buffer->resource,
-                0, NULL, data->data, data->row_pitch, data->slice_pitch, 0);
+                0, NULL, data->data, data->row_pitch, data->slice_pitch);
 
     return WINED3D_OK;
 }
index 0ee5b65..8a8d952 100644 (file)
@@ -148,8 +148,8 @@ 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_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY ||
+            resource->target == GL_TEXTURE_3D)
     {
         if (!gl_info->fbo_ops.glFramebufferTextureLayer)
         {
@@ -164,6 +164,7 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
     {
         gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment,
                 resource->target, resource->object, resource->level);
+        checkGLcall("glFramebufferTexture1D()");
     }
     else
     {
@@ -252,8 +253,6 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G
     }
     texture_type[] =
     {
-        {GL_TEXTURE_1D,                   GL_TEXTURE_BINDING_1D,                   "1d",          WINED3D_GL_EXT_NONE},
-        {GL_TEXTURE_1D_ARRAY,             GL_TEXTURE_BINDING_1D_ARRAY,             "1d-array",    EXT_TEXTURE_ARRAY},
         {GL_TEXTURE_2D,                   GL_TEXTURE_BINDING_2D,                   "2d",          WINED3D_GL_EXT_NONE},
         {GL_TEXTURE_RECTANGLE_ARB,        GL_TEXTURE_BINDING_RECTANGLE_ARB,        "rectangle",   ARB_TEXTURE_RECTANGLE},
         {GL_TEXTURE_2D_ARRAY,             GL_TEXTURE_BINDING_2D_ARRAY,             "2d-array" ,   EXT_TEXTURE_ARRAY},
@@ -457,15 +456,19 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co
     }
 
     texture = wined3d_texture_from_resource(resource);
-    if (texture->current_renderbuffer)
+    if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
     {
-        key->objects[idx].object = texture->current_renderbuffer->id;
-        key->objects[idx].target = 0;
-        key->objects[idx].level = key->objects[idx].layer = 0;
-        key->rb_namespace |= 1 << idx;
-        return;
-    }
+        struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
 
+        if (surface->current_renderbuffer)
+        {
+            key->objects[idx].object = surface->current_renderbuffer->id;
+            key->objects[idx].target = 0;
+            key->objects[idx].level = key->objects[idx].layer = 0;
+            key->rb_namespace |= 1 << idx;
+            return;
+        }
+    }
     key->objects[idx].target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
     key->objects[idx].level = sub_resource_idx % texture->level_count;
     key->objects[idx].layer = sub_resource_idx / texture->level_count;
@@ -612,7 +615,10 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
         }
         else if (depth_stencil->resource->type == WINED3D_RTYPE_TEXTURE_2D)
         {
-            wined3d_texture_set_compatible_renderbuffer(ds_texture, ds_level, &render_targets[0]);
+            struct wined3d_surface *surface;
+
+            surface = ds_texture->sub_resources[depth_stencil->sub_resource_idx].u.surface;
+            surface_set_compatible_renderbuffer(surface, &render_targets[0]);
         }
     }
 
@@ -755,8 +761,8 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ
 
 /* Context activation is done by the caller. */
 static void context_apply_fbo_state(struct wined3d_context *context, GLenum target,
-        const struct wined3d_rendertarget_info *render_targets,
-        const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location)
+        struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
+        DWORD color_location, DWORD ds_location)
 {
     struct fbo_entry *entry, *entry2;
 
@@ -778,35 +784,32 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ
     }
     else
     {
+        struct wined3d_rendertarget_info ds = {{0}};
+
+        if (depth_stencil)
+        {
+            ds.resource = &depth_stencil->container->resource;
+            ds.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil);
+            ds.layer_count = 1;
+        }
         context->current_fbo = context_find_fbo_entry(context, target,
-                render_targets, depth_stencil, color_location, ds_location);
+                render_targets, &ds, color_location, ds_location);
         context_apply_fbo_entry(context, target, context->current_fbo);
     }
 }
 
 /* Context activation is done by the caller. */
 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
-        struct wined3d_resource *rt, unsigned int rt_sub_resource_idx,
-        struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, DWORD location)
+        struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location)
 {
-    struct wined3d_rendertarget_info ds_info = {{0}};
-
     memset(context->blit_targets, 0, sizeof(context->blit_targets));
-    if (rt)
+    if (render_target)
     {
-        context->blit_targets[0].resource = rt;
-        context->blit_targets[0].sub_resource_idx = rt_sub_resource_idx;
+        context->blit_targets[0].resource = &render_target->container->resource;
+        context->blit_targets[0].sub_resource_idx = surface_get_sub_resource_idx(render_target);
         context->blit_targets[0].layer_count = 1;
     }
-
-    if (ds)
-    {
-        ds_info.resource = ds;
-        ds_info.sub_resource_idx = ds_sub_resource_idx;
-        ds_info.layer_count = 1;
-    }
-
-    context_apply_fbo_state(context, target, context->blit_targets, &ds_info, location, location);
+    context_apply_fbo_state(context, target, context->blit_targets, depth_stencil, location, location);
 }
 
 /* Context activation is done by the caller. */
@@ -1067,22 +1070,34 @@ static void context_queue_fbo_entry_destruction(struct wined3d_context *context,
     list_add_head(&context->fbo_destroy_list, &entry->entry);
 }
 
-void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource)
+void context_resource_released(const struct wined3d_device *device,
+        struct wined3d_resource *resource, enum wined3d_resource_type type)
 {
-    unsigned int i;
+    struct wined3d_texture *texture;
+    UINT i;
 
     if (!device->d3d_initialized)
         return;
 
-    for (i = 0; i < device->context_count; ++i)
+    switch (type)
     {
-        struct wined3d_context *context = device->contexts[i];
+        case WINED3D_RTYPE_TEXTURE_2D:
+        case WINED3D_RTYPE_TEXTURE_3D:
+            texture = texture_from_resource(resource);
 
-        if (&context->current_rt.texture->resource == resource)
-        {
-            context->current_rt.texture = NULL;
-            context->current_rt.sub_resource_idx = 0;
-        }
+            for (i = 0; i < device->context_count; ++i)
+            {
+                struct wined3d_context *context = device->contexts[i];
+                if (context->current_rt.texture == texture)
+                {
+                    context->current_rt.texture = NULL;
+                    context->current_rt.sub_resource_idx = 0;
+                }
+            }
+            break;
+
+        default:
+            break;
     }
 }
 
@@ -1092,7 +1107,7 @@ void context_gl_resource_released(struct wined3d_device *device,
     context_enum_fbo_entries(device, name, rb_namespace, context_queue_fbo_entry_destruction);
 }
 
-void context_texture_update(struct wined3d_context *context, const struct wined3d_texture *texture)
+void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct fbo_entry *entry = context->current_fbo;
@@ -1102,10 +1117,10 @@ void context_texture_update(struct wined3d_context *context, const struct wined3
 
     for (i = 0; i < gl_info->limits.buffers + 1; ++i)
     {
-        if (texture->texture_rgb.name == entry->key.objects[i].object
-                || texture->texture_srgb.name == entry->key.objects[i].object)
+        if (surface->container->texture_rgb.name == entry->key.objects[i].object
+                || surface->container->texture_srgb.name == entry->key.objects[i].object)
         {
-            TRACE("Updated texture %p is bound as attachment %u to the current FBO.\n", texture, i);
+            TRACE("Updated surface %p is bound as attachment %u to the current FBO.\n", surface, i);
             context->rebind_fbo = TRUE;
             return;
         }
@@ -1451,9 +1466,6 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
             }
         }
 
-        if (context->blit_vbo)
-            GL_EXTCALL(glDeleteBuffers(1, &context->blit_vbo));
-
         checkGLcall("context cleanup");
     }
 
@@ -1591,12 +1603,14 @@ void context_release(struct wined3d_context *context)
 /* This is used when a context for render target A is active, but a separate context is
  * needed to access the WGL framebuffer for render target B. Re-acquire a context for rt
  * A to avoid breaking caller code. */
-void context_restore(struct wined3d_context *context, struct wined3d_texture *texture, unsigned int sub_resource_idx)
+void context_restore(struct wined3d_context *context, struct wined3d_surface *restore)
 {
-    if (context->current_rt.texture != texture || context->current_rt.sub_resource_idx != sub_resource_idx)
+    if (context->current_rt.texture != restore->container
+            || context->current_rt.sub_resource_idx != surface_get_sub_resource_idx(restore))
     {
         context_release(context);
-        context = context_acquire(texture->resource.device, texture, sub_resource_idx);
+        context = context_acquire(restore->container->resource.device,
+                restore->container, surface_get_sub_resource_idx(restore));
     }
 
     context_release(context);
@@ -1777,7 +1791,6 @@ void context_bind_dummy_textures(const struct wined3d_device *device, const stru
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
         }
-
         if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer);
 
@@ -1853,6 +1866,8 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc,
     ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version >> 16;
     ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_MINOR_VERSION_ARB;
     ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version & 0xffff;
+    if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2))
+        ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
     if (ctx_flags)
     {
         ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
@@ -1862,20 +1877,9 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc,
 
     if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
     {
-        if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2))
+        if (ctx_flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
         {
-            if (ctx_flags)
-            {
-                ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
-                ctx_attribs[ctx_attrib_idx - 1] = ctx_flags;
-            }
-            else
-            {
-                ctx_flags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
-                ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
-                ctx_attribs[ctx_attrib_idx++] = ctx_flags;
-                ctx_attribs[ctx_attrib_idx] = 0;
-            }
+            ctx_attribs[ctx_attrib_idx - 1] &= ~WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
             if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
                 WARN("Failed to create a WGL context with wglCreateContextAttribsARB, last error %#x.\n",
                         GetLastError());
@@ -2172,6 +2176,15 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, 1);");
 
+    if (gl_info->supported[ARB_VERTEX_BLEND])
+    {
+        /* Direct3D always uses n-1 weights for n world matrices and uses
+         * 1 - sum for the last one this is equal to GL_WEIGHT_SUM_UNITY_ARB.
+         * Enabling it doesn't do anything unless GL_VERTEX_BLEND_ARB isn't
+         * enabled as well. */
+        gl_info->gl_ops.gl.p_glEnable(GL_WEIGHT_SUM_UNITY_ARB);
+        checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)");
+    }
     if (gl_info->supported[NV_TEXTURE_SHADER2])
     {
         /* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d
@@ -2257,10 +2270,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     if (device->dummy_textures.tex_2d)
         context_bind_dummy_textures(device, ret);
 
-    /* Initialise all rectangles to avoid resetting unused ones later. */
-    gl_info->gl_ops.gl.p_glScissor(0, 0, 0, 0);
-    checkGLcall("glScissor");
-
     TRACE("Created context %p.\n", ret);
 
     return ret;
@@ -2359,6 +2368,28 @@ const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context,
     return context->tex_unit_map;
 }
 
+/* Context activation is done by the caller. */
+static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width, UINT height)
+{
+    const GLdouble projection[] =
+    {
+        2.0 / width,          0.0,  0.0, 0.0,
+                0.0, 2.0 / height,  0.0, 0.0,
+                0.0,          0.0,  2.0, 0.0,
+               -1.0,         -1.0, -1.0, 1.0,
+    };
+
+    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");
+}
+
 static void context_get_rt_size(const struct wined3d_context *context, SIZE *size)
 {
     const struct wined3d_texture *rt = context->current_rt.texture;
@@ -2407,6 +2438,206 @@ void context_enable_clip_distances(struct wined3d_context *context, unsigned int
     checkGLcall("toggle clip distances");
 }
 
+/*****************************************************************************
+ * SetupForBlit
+ *
+ * Sets up a context for DirectDraw blitting.
+ * All texture units are disabled, texture unit 0 is set as current unit
+ * fog, lighting, blending, alpha test, z test, scissor test, culling disabled
+ * color writing enabled for all channels
+ * register combiners disabled, shaders disabled
+ * world matrix is set to identity, texture matrix 0 too
+ * projection matrix is setup for drawing screen coordinates
+ *
+ * Params:
+ *  This: Device to activate the context for
+ *  context: Context to setup
+ *
+ *****************************************************************************/
+/* Context activation is done by the caller. */
+static void SetupForBlit(const struct wined3d_device *device, struct wined3d_context *context)
+{
+    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);
+
+    context_get_rt_size(context, &rt_size);
+
+    if (context->last_was_blit)
+    {
+        if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
+        {
+            set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
+            context->blit_w = rt_size.cx;
+            context->blit_h = rt_size.cy;
+            /* No need to dirtify here, the states are still dirtified because
+             * they weren't applied since the last SetupForBlit() call. */
+        }
+        TRACE("Context is already set up for blitting, nothing to do\n");
+        return;
+    }
+    context->last_was_blit = TRUE;
+
+    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+    {
+        /* 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);
+            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 ...");
+        }
+
+        /* 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 (sampler != WINED3D_UNMAPPED_STAGE)
+    {
+        if (sampler < MAX_TEXTURES)
+        {
+            context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler));
+            context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
+        }
+        context_invalidate_state(context, STATE_SAMPLER(sampler));
+    }
+
+    /* Other misc states */
+    gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
+    checkGLcall("glDisable GL_DEPTH_TEST");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+    checkGLcall("glDisable GL_BLEND");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
+    checkGLcall("glDisable GL_CULL_FACE");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE));
+    gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
+    checkGLcall("glDisable GL_STENCIL_TEST");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+    checkGLcall("glDisable GL_SCISSOR_TEST");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
+    if (gl_info->supported[ARB_POINT_SPRITE])
+    {
+        gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
+        checkGLcall("glDisable GL_POINT_SPRITE_ARB");
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE));
+    }
+    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)));
+    if (gl_info->supported[EXT_SECONDARY_COLOR])
+    {
+        gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
+        checkGLcall("glDisable(GL_COLOR_SUM_EXT)");
+    }
+
+    context->last_was_rhw = TRUE;
+    context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
+
+    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. */
+    if (gl_info->supported[ARB_CLIP_CONTROL])
+        GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE));
+
+    set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
+
+    /* Disable shaders */
+    device->shader_backend->shader_disable(device->shader_priv, context);
+
+    context->blit_w = rt_size.cx;
+    context->blit_h = rt_size.cy;
+    context_invalidate_state(context, STATE_VIEWPORT);
+    context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+}
+
 static inline BOOL is_rt_mask_onscreen(DWORD rt_mask)
 {
     return rt_mask & (1u << 31);
@@ -2525,9 +2756,11 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint
                 break;
             case GL_TEXTURE_1D:
                 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
+                checkGLcall("glBindTexture");
                 break;
             case GL_TEXTURE_1D_ARRAY:
                 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
+                checkGLcall("glBindTexture");
                 break;
             case GL_TEXTURE_2D:
                 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
@@ -2667,7 +2900,7 @@ static void context_set_render_offscreen(struct wined3d_context *context, BOOL o
     context_invalidate_state(context, STATE_SCISSORRECT);
     if (!context->gl_info->supported[ARB_CLIP_CONTROL])
     {
-        context_invalidate_state(context, STATE_RASTERIZER);
+        context_invalidate_state(context, STATE_FRONTFACE);
         context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN);
         context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
     }
@@ -2734,12 +2967,12 @@ GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context)
     }
 }
 
-static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, struct wined3d_resource *rt)
+static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, struct wined3d_texture *rt)
 {
-    if (!rt || rt->format->id == WINED3DFMT_NULL)
+    if (!rt || rt->resource.format->id == WINED3DFMT_NULL)
         return 0;
-    else if (rt->type != WINED3D_RTYPE_BUFFER && texture_from_resource(rt)->swapchain)
-        return context_generate_rt_mask_from_resource(rt);
+    else if (rt->swapchain)
+        return context_generate_rt_mask_from_resource(&rt->resource);
     else
         return context_generate_rt_mask(context_get_offscreen_gl_buffer(context));
 }
@@ -2747,13 +2980,9 @@ static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *conte
 /* Context activation is done by the caller. */
 void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
 {
-    const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_texture *rt = context->current_rt.texture;
+    struct wined3d_surface *surface;
     DWORD rt_mask, *cur_mask;
-    unsigned int i, sampler;
-    SIZE rt_size;
-
-    TRACE("Setting up context %p for blitting.\n", context);
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
@@ -2761,8 +2990,8 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
         {
             wined3d_texture_load(rt, context, FALSE);
 
-            context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, &rt->resource,
-                    context->current_rt.sub_resource_idx, NULL, 0, rt->resource.draw_binding);
+            surface = rt->sub_resources[context->current_rt.sub_resource_idx].u.surface;
+            context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, surface, NULL, rt->resource.draw_binding);
             if (rt->resource.format->id != WINED3DFMT_NULL)
                 rt_mask = 1;
             else
@@ -2777,7 +3006,7 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
     }
     else
     {
-        rt_mask = context_generate_rt_mask_no_fbo(context, &rt->resource);
+        rt_mask = context_generate_rt_mask_no_fbo(context, rt);
     }
 
     cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
@@ -2792,235 +3021,49 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
     {
         context_check_fbo_status(context, GL_FRAMEBUFFER);
     }
+
+    SetupForBlit(device, context);
     context_invalidate_state(context, STATE_FRAMEBUFFER);
+}
 
-    context_get_rt_size(context, &rt_size);
+static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts,
+        const struct wined3d_rendertarget_view *ds)
+{
+    unsigned int i;
 
-    if (context->last_was_blit)
+    if (ds)
+        return TRUE;
+
+    for (i = 0; i < rt_count; ++i)
     {
-        if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
-        {
-            gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy);
-            context->viewport_count = WINED3D_MAX_VIEWPORTS;
-            context->blit_w = rt_size.cx;
-            context->blit_h = rt_size.cy;
-            /* No need to dirtify here, the states are still dirtified because
-             * they weren't applied since the last context_apply_blit_state()
-             * call. */
-        }
-        checkGLcall("blit state application");
-        TRACE("Context is already set up for blitting, nothing to do.\n");
-        return;
+        if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
+            return TRUE;
     }
-    context->last_was_blit = TRUE;
 
-    if (gl_info->supported[ARB_SAMPLER_OBJECTS])
-        GL_EXTCALL(glBindSampler(0, 0));
-    context_active_texture(context, gl_info, 0);
+    return FALSE;
+}
 
-    sampler = context->rev_tex_unit_map[0];
-    if (sampler != WINED3D_UNMAPPED_STAGE)
+/* Context activation is done by the caller. */
+BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
+        UINT rt_count, const struct wined3d_fb_state *fb)
+{
+    struct wined3d_rendertarget_view * const *rts = fb->render_targets;
+    struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    DWORD rt_mask = 0, *cur_mask;
+    unsigned int i;
+
+    if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
+            || rt_count != gl_info->limits.buffers)
     {
-        if (sampler < MAX_TEXTURES)
+        if (!have_framebuffer_attachment(rt_count, rts, dsv))
         {
-            context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler));
-            context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
-        }
-        context_invalidate_state(context, STATE_SAMPLER(sampler));
-    }
-
-    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
-    {
-        gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
-    }
-    gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
-    gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
-    gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE));
-    gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE));
-    gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
-    if (gl_info->supported[ARB_POINT_SPRITE])
-    {
-        gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE));
-    }
-    if (gl_info->supported[ARB_FRAMEBUFFER_SRGB])
-    {
-        gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE));
-    }
-    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->last_was_rhw = TRUE;
-    context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
-
-    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. */
-    if (gl_info->supported[ARB_CLIP_CONTROL])
-        GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE));
-    gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy);
-    context->viewport_count = WINED3D_MAX_VIEWPORTS;
-    context_invalidate_state(context, STATE_VIEWPORT);
-
-    device->shader_backend->shader_disable(device->shader_priv, context);
-
-    context->blit_w = rt_size.cx;
-    context->blit_h = rt_size.cy;
-
-    checkGLcall("blit state application");
-}
-
-static void context_apply_blit_projection(const struct wined3d_context *context, unsigned int w, unsigned int h)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    const GLdouble projection[] =
-    {
-        2.0 / w,     0.0,  0.0, 0.0,
-            0.0, 2.0 / h,  0.0, 0.0,
-            0.0,     0.0,  2.0, 0.0,
-           -1.0,    -1.0, -1.0, 1.0,
-    };
-
-    gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
-    gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
-}
-
-/* Setup OpenGL states for fixed-function blitting. */
-/* Context activation is done by the caller. */
-void context_apply_ffp_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int i, sampler;
-
-    if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
-        ERR("Applying fixed-function state without legacy context support.\n");
-
-    if (context->last_was_ffp_blit)
-    {
-        SIZE rt_size;
-
-        context_get_rt_size(context, &rt_size);
-        if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
-            context_apply_blit_projection(context, rt_size.cx, rt_size.cy);
-        context_apply_blit_state(context, device);
-
-        checkGLcall("ffp blit state application");
-        return;
-    }
-    context->last_was_ffp_blit = TRUE;
-
-    context_apply_blit_state(context, device);
-
-    /* Disable all textures. The caller can then bind a texture it wants to blit
-     * from. */
-    for (i = gl_info->limits.textures - 1; i > 0 ; --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);
-        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
-        if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
-            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
-        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
-
-        gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-        sampler = context->rev_tex_unit_map[i];
-        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);
-    gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
-    if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
-        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
-    gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
-
-    gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-    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);
-
-    gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
-    gl_info->gl_ops.gl.p_glLoadIdentity();
-
-    /* Setup transforms. */
-    gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
-    gl_info->gl_ops.gl.p_glLoadIdentity();
-    context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
-    context_apply_blit_projection(context, context->blit_w, context->blit_h);
-    context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
-
-    /* Other misc states. */
-    gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING));
-    glDisableWINE(GL_FOG);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
-
-    if (gl_info->supported[EXT_SECONDARY_COLOR])
-    {
-        gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
-    }
-    checkGLcall("ffp blit state application");
-}
-
-static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts,
-        const struct wined3d_rendertarget_view *ds)
-{
-    unsigned int i;
-
-    if (ds)
-        return TRUE;
-
-    for (i = 0; i < rt_count; ++i)
-    {
-        if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
-            return TRUE;
-    }
-
-    return FALSE;
-}
-
-/* Context activation is done by the caller. */
-BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
-        UINT rt_count, const struct wined3d_fb_state *fb)
-{
-    struct wined3d_rendertarget_view * const *rts = fb->render_targets;
-    struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    DWORD rt_mask = 0, *cur_mask;
-    unsigned int i;
-
-    if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
-            || rt_count != gl_info->limits.buffers)
-    {
-        if (!have_framebuffer_attachment(rt_count, rts, dsv))
-        {
-            WARN("Invalid render target config, need at least one attachment.\n");
-            return FALSE;
+            WARN("Invalid render target config, need at least one attachment.\n");
+            return FALSE;
         }
 
         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
         {
-            struct wined3d_rendertarget_info ds_info = {{0}};
-
             context_validate_onscreen_formats(context, dsv);
 
             if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))
@@ -3038,22 +3081,14 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
                     if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
                         rt_mask |= (1u << i);
                 }
-
-                if (dsv)
-                {
-                    ds_info.gl_view = dsv->gl_view;
-                    ds_info.resource = dsv->resource;
-                    ds_info.sub_resource_idx = dsv->sub_resource_idx;
-                    ds_info.layer_count = dsv->layer_count;
-                }
-
-                context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, &ds_info,
+                context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
+                        wined3d_rendertarget_view_get_surface(dsv),
                         rt_count ? rts[0]->resource->draw_binding : 0,
                         dsv ? dsv->resource->draw_binding : 0);
             }
             else
             {
-                context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, &ds_info,
+                context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL,
                         WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE);
                 rt_mask = context_generate_rt_mask_from_resource(rts[0]->resource);
             }
@@ -3065,7 +3100,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
         }
         else
         {
-            rt_mask = context_generate_rt_mask_no_fbo(context, rt_count ? rts[0]->resource : NULL);
+            rt_mask = context_generate_rt_mask_no_fbo(context,
+                    rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL);
         }
     }
     else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
@@ -3079,7 +3115,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
     }
     else
     {
-        rt_mask = context_generate_rt_mask_no_fbo(context, rt_count ? rts[0]->resource : NULL);
+        rt_mask = context_generate_rt_mask_no_fbo(context,
+                rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL);
     }
 
     cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
@@ -3097,7 +3134,6 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
     }
 
     context->last_was_blit = FALSE;
-    context->last_was_ffp_blit = FALSE;
 
     /* Blending and clearing should be orthogonal, but tests on the nvidia
      * driver show that disabling blending when clearing improves the clearing
@@ -3129,7 +3165,7 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const
     unsigned int i;
 
     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
-        return context_generate_rt_mask_no_fbo(context, rts[0]->resource);
+        return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])->container);
     else if (!context->render_offscreen)
         return context_generate_rt_mask_from_resource(rts[0]->resource);
 
@@ -3166,11 +3202,9 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
-        struct wined3d_rendertarget_info ds_info = {{0}};
-
         if (!context->render_offscreen)
         {
-            context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, &ds_info,
+            context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL,
                     WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE);
         }
         else
@@ -3191,16 +3225,8 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat
                 if (!color_location)
                     color_location = fb->render_targets[i]->resource->draw_binding;
             }
-
-            if (fb->depth_stencil)
-            {
-                ds_info.gl_view = fb->depth_stencil->gl_view;
-                ds_info.resource = fb->depth_stencil->resource;
-                ds_info.sub_resource_idx = fb->depth_stencil->sub_resource_idx;
-                ds_info.layer_count = fb->depth_stencil->layer_count;
-            }
-
-            context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, &ds_info,
+            context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
+                    wined3d_rendertarget_view_get_surface(fb->depth_stencil),
                     color_location, fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0);
         }
     }
@@ -4027,7 +4053,6 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
 
     context->numDirtyEntries = 0; /* This makes the whole list clean */
     context->last_was_blit = FALSE;
-    context->last_was_ffp_blit = FALSE;
 
     return TRUE;
 }
@@ -4089,7 +4114,6 @@ static void context_apply_compute_state(struct wined3d_context *context,
     context_invalidate_state(context, STATE_FRAMEBUFFER);
 
     context->last_was_blit = FALSE;
-    context->last_was_ffp_blit = FALSE;
 }
 
 static BOOL use_transform_feedback(const struct wined3d_state *state)
@@ -4353,6 +4377,9 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state
     GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
     checkGLcall("glMemoryBarrier");
 
+    if (wined3d_settings.strict_draw_ordering)
+        gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
     context_release(context);
 }
 
@@ -4538,7 +4565,6 @@ static const BYTE *software_vertex_blending(struct wined3d_context *context,
         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;
@@ -5026,12 +5052,13 @@ 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))
+         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)
         {
             si_emulated = context->stream_info;
@@ -5059,9 +5086,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
         }
         else if (!context->transform_feedback_active)
         {
-            enum wined3d_primitive_type primitive_type = shader->u.gs.output_type
-                    ? shader->u.gs.output_type : d3d_primitive_type_from_gl(state->gl_primitive_type);
-            GLenum mode = gl_tfb_primitive_type_from_d3d(primitive_type);
+            GLenum mode = gl_tfb_primitive_type_from_d3d(shader->u.gs.output_type);
             GL_EXTCALL(glBeginTransformFeedback(mode));
             checkGLcall("glBeginTransformFeedback");
             context->transform_feedback_active = 1;
@@ -5116,663 +5141,8 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
     for (i = 0; i < context->buffer_fence_count; ++i)
         wined3d_fence_issue(context->buffer_fences[i], device);
 
-    context_release(context);
-}
-
-void context_unload_tex_coords(const struct wined3d_context *context)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int texture_idx;
-
-    for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
-    {
-        gl_info->gl_ops.ext.p_glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx);
-        gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    }
-}
-
-void context_load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
-        GLuint *current_bo, const struct wined3d_state *state)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int mapped_stage = 0;
-    unsigned int texture_idx;
-
-    for (texture_idx = 0; texture_idx < context->d3d_info->limits.ffp_blend_stages; ++texture_idx)
-    {
-        unsigned int coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
-
-        if ((mapped_stage = context->tex_unit_map[texture_idx]) == WINED3D_UNMAPPED_STAGE)
-            continue;
-
-        if (mapped_stage >= gl_info->limits.texture_coords)
-        {
-            FIXME("Attempted to load unsupported texture coordinate %u.\n", mapped_stage);
-            continue;
-        }
-
-        if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
-        {
-            const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx];
-
-            TRACE("Setting up texture %u, idx %d, coord_idx %u, data {%#x:%p}.\n",
-                    texture_idx, mapped_stage, coord_idx, e->data.buffer_object, e->data.addr);
-
-            if (*current_bo != e->data.buffer_object)
-            {
-                GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
-                checkGLcall("glBindBuffer");
-                *current_bo = e->data.buffer_object;
-            }
-
-            GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
-            checkGLcall("glClientActiveTextureARB");
-
-            /* The coords to supply depend completely on the fvf/vertex shader. */
-            gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
-                    e->data.addr + state->load_base_vertex_index * e->stride);
-            gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-        }
-        else
-        {
-            GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
-        }
-    }
-    if (gl_info->supported[NV_REGISTER_COMBINERS])
-    {
-        /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
-        for (texture_idx = mapped_stage + 1; texture_idx < gl_info->limits.textures; ++texture_idx)
-        {
-            GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
-        }
-    }
-
-    checkGLcall("loadTexCoords");
-}
-
-/* This should match any arrays loaded in context_load_vertex_data(). */
-static void context_unload_vertex_data(struct wined3d_context *context)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-
-    if (!context->namedArraysLoaded)
-        return;
-    gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
-    gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
-    gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
-    if (gl_info->supported[EXT_SECONDARY_COLOR])
-        gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
-    context_unload_tex_coords(context);
-    context->namedArraysLoaded = FALSE;
-}
-
-static void context_load_vertex_data(struct wined3d_context *context,
-        const struct wined3d_stream_info *si, const struct wined3d_state *state)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    const struct wined3d_stream_info_element *e;
-    GLuint current_bo;
-
-    TRACE("context %p, si %p, state %p.\n", context, si, state);
-
-    /* This is used for the fixed-function pipeline only, and the
-     * fixed-function pipeline doesn't do instancing. */
-    context->instance_count = 0;
-    current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0;
-
-    /* Blend data */
-    if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT))
-            || si->use_map & (1u << WINED3D_FFP_BLENDINDICES))
-    {
-        /* TODO: Support vertex blending in immediate mode draws. No need to
-         * write a FIXME here, this is done after the general vertex
-         * declaration decoding. */
-        WARN("Vertex blending not supported.\n");
-    }
-
-    /* Point Size */
-    if (si->use_map & (1u << WINED3D_FFP_PSIZE))
-    {
-        /* No such functionality in the fixed-function GL pipeline. */
-        WARN("Per-vertex point size not supported.\n");
-    }
-
-    /* Position */
-    if (si->use_map & (1u << WINED3D_FFP_POSITION))
-    {
-        e = &si->elements[WINED3D_FFP_POSITION];
-
-        if (current_bo != e->data.buffer_object)
-        {
-            GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
-            checkGLcall("glBindBuffer");
-            current_bo = e->data.buffer_object;
-        }
-
-        TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
-                e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
-                e->data.addr + state->load_base_vertex_index * e->stride);
-        gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
-                e->data.addr + state->load_base_vertex_index * e->stride);
-        checkGLcall("glVertexPointer(...)");
-        gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
-        checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
-    }
-
-    /* Normals */
-    if (si->use_map & (1u << WINED3D_FFP_NORMAL))
-    {
-        e = &si->elements[WINED3D_FFP_NORMAL];
-
-        if (current_bo != e->data.buffer_object)
-        {
-            GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
-            checkGLcall("glBindBuffer");
-            current_bo = e->data.buffer_object;
-        }
-
-        TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
-                e->data.addr + state->load_base_vertex_index * e->stride);
-        gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
-                e->data.addr + state->load_base_vertex_index * e->stride);
-        checkGLcall("glNormalPointer(...)");
-        gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
-        checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
-
-    }
-    else
-    {
-        gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
-        checkGLcall("glNormal3f(0, 0, 0)");
-    }
-
-    /* Diffuse colour */
-    if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
-    {
-        e = &si->elements[WINED3D_FFP_DIFFUSE];
-
-        if (current_bo != e->data.buffer_object)
-        {
-            GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
-            checkGLcall("glBindBuffer");
-            current_bo = e->data.buffer_object;
-        }
-
-        TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
-                e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
-                e->data.addr + state->load_base_vertex_index * e->stride);
-        gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
-                e->data.addr + state->load_base_vertex_index * e->stride);
-        checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
-        gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
-        checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
-
-    }
-    else
-    {
-        gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-        checkGLcall("glColor4f(1, 1, 1, 1)");
-    }
-
-    /* Specular colour */
-    if (si->use_map & (1u << WINED3D_FFP_SPECULAR))
-    {
-        TRACE("Setting specular colour.\n");
-
-        e = &si->elements[WINED3D_FFP_SPECULAR];
-
-        if (gl_info->supported[EXT_SECONDARY_COLOR])
-        {
-            GLenum type = e->format->gl_vtx_type;
-            GLint format = e->format->gl_vtx_format;
-
-            if (current_bo != e->data.buffer_object)
-            {
-                GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
-                checkGLcall("glBindBuffer");
-                current_bo = e->data.buffer_object;
-            }
-
-            if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
-            {
-                /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
-                 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
-                 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
-                 * 4 component secondary colors use it
-                 */
-                TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
-                        e->data.addr + state->load_base_vertex_index * e->stride);
-                GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
-                        e->data.addr + state->load_base_vertex_index * e->stride));
-                checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
-            }
-            else
-            {
-                switch (type)
-                {
-                    case GL_UNSIGNED_BYTE:
-                        TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
-                                e->data.addr + state->load_base_vertex_index * e->stride);
-                        GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
-                                e->data.addr + state->load_base_vertex_index * e->stride));
-                        checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
-                        break;
-
-                    default:
-                        FIXME("Add 4 component specular colour pointers for type %#x.\n", type);
-                        /* Make sure that the right colour component is dropped. */
-                        TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
-                                e->data.addr + state->load_base_vertex_index * e->stride);
-                        GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
-                                e->data.addr + state->load_base_vertex_index * e->stride));
-                        checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
-                }
-            }
-            gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
-            checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
-        }
-        else
-        {
-            WARN("Specular colour is not supported in this GL implementation.\n");
-        }
-    }
-    else
-    {
-        if (gl_info->supported[EXT_SECONDARY_COLOR])
-        {
-            GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
-            checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
-        }
-        else
-        {
-            WARN("Specular colour is not supported in this GL implementation.\n");
-        }
-    }
-
-    /* Texture coordinates */
-    context_load_tex_coords(context, si, &current_bo, state);
-}
-
-static void context_unload_numbered_array(struct wined3d_context *context, unsigned int i)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-
-    GL_EXTCALL(glDisableVertexAttribArray(i));
-    checkGLcall("glDisableVertexAttribArray");
-    if (gl_info->supported[ARB_INSTANCED_ARRAYS])
-        GL_EXTCALL(glVertexAttribDivisor(i, 0));
-
-    context->numbered_array_mask &= ~(1u << i);
-}
-
-static void context_unload_numbered_arrays(struct wined3d_context *context)
-{
-    unsigned int i;
-
-    while (context->numbered_array_mask)
-    {
-        i = wined3d_bit_scan(&context->numbered_array_mask);
-        context_unload_numbered_array(context, i);
-    }
-}
-
-static void context_load_numbered_arrays(struct wined3d_context *context,
-        const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
-{
-    const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    GLuint current_bo;
-    unsigned int i;
-
-    /* Default to no instancing. */
-    context->instance_count = 0;
-    current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0;
-
-    for (i = 0; i < MAX_ATTRIBS; ++i)
-    {
-        const struct wined3d_stream_info_element *element = &stream_info->elements[i];
-        const struct wined3d_stream_state *stream;
-
-        if (!(stream_info->use_map & (1u << i)))
-        {
-            if (context->numbered_array_mask & (1u << i))
-                context_unload_numbered_array(context, i);
-            if (!use_vs(state) && i == WINED3D_FFP_DIFFUSE)
-                GL_EXTCALL(glVertexAttrib4f(i, 1.0f, 1.0f, 1.0f, 1.0f));
-            else
-                GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f));
-            continue;
-        }
-
-        stream = &state->streams[element->stream_idx];
-
-        if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count)
-            context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
-
-        if (gl_info->supported[ARB_INSTANCED_ARRAYS])
-        {
-            GL_EXTCALL(glVertexAttribDivisor(i, element->divisor));
-        }
-        else if (element->divisor)
-        {
-            /* Unload instanced arrays, they will be loaded using immediate
-             * mode instead. */
-            if (context->numbered_array_mask & (1u << i))
-                context_unload_numbered_array(context, i);
-            continue;
-        }
-
-        TRACE("Loading array %u [VBO=%u].\n", i, element->data.buffer_object);
-
-        if (element->stride)
-        {
-            if (current_bo != element->data.buffer_object)
-            {
-                GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object));
-                checkGLcall("glBindBuffer");
-                current_bo = element->data.buffer_object;
-            }
-            /* Use the VBO to find out if a vertex buffer exists, not the vb
-             * pointer. vb can point to a user pointer data blob. In that case
-             * current_bo will be 0. If there is a vertex buffer but no vbo we
-             * won't be load converted attributes anyway. */
-            if (vs && vs->reg_maps.shader_version.major >= 4
-                    && (element->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_INTEGER))
-            {
-                GL_EXTCALL(glVertexAttribIPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type,
-                        element->stride, element->data.addr + state->load_base_vertex_index * element->stride));
-            }
-            else
-            {
-                GL_EXTCALL(glVertexAttribPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type,
-                        element->format->gl_normalized, element->stride,
-                        element->data.addr + state->load_base_vertex_index * element->stride));
-            }
-
-            if (!(context->numbered_array_mask & (1u << i)))
-            {
-                GL_EXTCALL(glEnableVertexAttribArray(i));
-                context->numbered_array_mask |= (1u << i);
-            }
-        }
-        else
-        {
-            /* Stride = 0 means always the same values.
-             * glVertexAttribPointer() doesn't do that. Instead disable the
-             * pointer and set up the attribute statically. But we have to
-             * figure out the system memory address. */
-            const BYTE *ptr = element->data.addr;
-            if (element->data.buffer_object)
-                ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context);
-
-            if (context->numbered_array_mask & (1u << i))
-                context_unload_numbered_array(context, i);
+    if (wined3d_settings.strict_draw_ordering)
+        gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
 
-            switch (element->format->id)
-            {
-                case WINED3DFMT_R32_FLOAT:
-                    GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr));
-                    break;
-                case WINED3DFMT_R32G32_FLOAT:
-                    GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr));
-                    break;
-                case WINED3DFMT_R32G32B32_FLOAT:
-                    GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr));
-                    break;
-                case WINED3DFMT_R32G32B32A32_FLOAT:
-                    GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr));
-                    break;
-                case WINED3DFMT_R8G8B8A8_UINT:
-                    GL_EXTCALL(glVertexAttrib4ubv(i, ptr));
-                    break;
-                case WINED3DFMT_B8G8R8A8_UNORM:
-                    if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
-                    {
-                        const DWORD *src = (const DWORD *)ptr;
-                        DWORD c = *src & 0xff00ff00u;
-                        c |= (*src & 0xff0000u) >> 16;
-                        c |= (*src & 0xffu) << 16;
-                        GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c));
-                        break;
-                    }
-                    /* else fallthrough */
-                case WINED3DFMT_R8G8B8A8_UNORM:
-                    GL_EXTCALL(glVertexAttrib4Nubv(i, ptr));
-                    break;
-                case WINED3DFMT_R16G16_SINT:
-                    GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr));
-                    break;
-                case WINED3DFMT_R16G16B16A16_SINT:
-                    GL_EXTCALL(glVertexAttrib4sv(i, (const GLshort *)ptr));
-                    break;
-                case WINED3DFMT_R16G16_SNORM:
-                {
-                    const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
-                    GL_EXTCALL(glVertexAttrib4Nsv(i, s));
-                    break;
-                }
-                case WINED3DFMT_R16G16_UNORM:
-                {
-                    const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
-                    GL_EXTCALL(glVertexAttrib4Nusv(i, s));
-                    break;
-                }
-                case WINED3DFMT_R16G16B16A16_SNORM:
-                    GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr));
-                    break;
-                case WINED3DFMT_R16G16B16A16_UNORM:
-                    GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr));
-                    break;
-                case WINED3DFMT_R10G10B10X2_UINT:
-                    FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n");
-                    /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
-                    break;
-                case WINED3DFMT_R10G10B10X2_SNORM:
-                    FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n");
-                    /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
-                    break;
-                case WINED3DFMT_R16G16_FLOAT:
-                    if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
-                    {
-                        /* Not supported by GL_ARB_half_float_vertex. */
-                        GL_EXTCALL(glVertexAttrib2hvNV(i, (const GLhalfNV *)ptr));
-                    }
-                    else
-                    {
-                        float x = float_16_to_32(((const unsigned short *)ptr) + 0);
-                        float y = float_16_to_32(((const unsigned short *)ptr) + 1);
-                        GL_EXTCALL(glVertexAttrib2f(i, x, y));
-                    }
-                    break;
-                case WINED3DFMT_R16G16B16A16_FLOAT:
-                    if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
-                    {
-                        /* Not supported by GL_ARB_half_float_vertex. */
-                        GL_EXTCALL(glVertexAttrib4hvNV(i, (const GLhalfNV *)ptr));
-                    }
-                    else
-                    {
-                        float x = float_16_to_32(((const unsigned short *)ptr) + 0);
-                        float y = float_16_to_32(((const unsigned short *)ptr) + 1);
-                        float z = float_16_to_32(((const unsigned short *)ptr) + 2);
-                        float w = float_16_to_32(((const unsigned short *)ptr) + 3);
-                        GL_EXTCALL(glVertexAttrib4f(i, x, y, z, w));
-                    }
-                    break;
-                default:
-                    ERR("Unexpected declaration in stride 0 attributes.\n");
-                    break;
-
-            }
-        }
-    }
-    checkGLcall("Loading numbered arrays");
-}
-
-void context_update_stream_sources(struct wined3d_context *context, const struct wined3d_state *state)
-{
-
-    if (context->use_immediate_mode_draw)
-        return;
-
-    context_unload_vertex_data(context);
-    if (context->d3d_info->ffp_generic_attributes || use_vs(state))
-    {
-        TRACE("Loading numbered arrays.\n");
-        context_load_numbered_arrays(context, &context->stream_info, state);
-        return;
-    }
-
-    TRACE("Loading named arrays.\n");
-    context_unload_numbered_arrays(context);
-    context_load_vertex_data(context, &context->stream_info, state);
-    context->namedArraysLoaded = TRUE;
-}
-
-static void apply_texture_blit_state(const struct wined3d_gl_info *gl_info, struct gl_texture *texture,
-        GLenum target, unsigned int level, enum wined3d_texture_filter_type filter)
-{
-    gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter));
-    gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
-            wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE));
-    gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
-        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
-    gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, level);
-
-    /* We changed the filtering settings on the texture. Make sure they get
-     * reset on subsequent draws. */
-    texture->sampler_desc.mag_filter = WINED3D_TEXF_POINT;
-    texture->sampler_desc.min_filter = WINED3D_TEXF_POINT;
-    texture->sampler_desc.mip_filter = WINED3D_TEXF_NONE;
-    texture->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP;
-    texture->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP;
-    texture->sampler_desc.srgb_decode = FALSE;
-    texture->base_level = level;
-}
-
-/* Context activation is done by the caller. */
-void context_draw_shaded_quad(struct wined3d_context *context, struct wined3d_texture *texture,
-        unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect,
-        enum wined3d_texture_filter_type filter)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_blt_info info;
-    unsigned int level, w, h, i;
-    SIZE dst_size;
-    struct blit_vertex
-    {
-        float x, y;
-        struct wined3d_vec3 texcoord;
-    }
-    quad[4];
-
-    texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info);
-
-    level = sub_resource_idx % texture->level_count;
-    context_bind_texture(context, info.bind_target, texture->texture_rgb.name);
-    apply_texture_blit_state(gl_info, &texture->texture_rgb, info.bind_target, level, filter);
-    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level);
-
-    context_get_rt_size(context, &dst_size);
-    w = dst_size.cx;
-    h = dst_size.cy;
-
-    quad[0].x = dst_rect->left * 2.0f / w - 1.0f;
-    quad[0].y = dst_rect->top * 2.0f / h - 1.0f;
-    quad[0].texcoord = info.texcoords[0];
-
-    quad[1].x = dst_rect->right * 2.0f / w - 1.0f;
-    quad[1].y = dst_rect->top * 2.0f / h - 1.0f;
-    quad[1].texcoord = info.texcoords[1];
-
-    quad[2].x = dst_rect->left * 2.0f / w - 1.0f;
-    quad[2].y = dst_rect->bottom * 2.0f / h - 1.0f;
-    quad[2].texcoord = info.texcoords[2];
-
-    quad[3].x = dst_rect->right * 2.0f / w - 1.0f;
-    quad[3].y = dst_rect->bottom * 2.0f / h - 1.0f;
-    quad[3].texcoord = info.texcoords[3];
-
-    /* Draw a quad. */
-    if (gl_info->supported[ARB_VERTEX_BUFFER_OBJECT])
-    {
-        if (!context->blit_vbo)
-            GL_EXTCALL(glGenBuffers(1, &context->blit_vbo));
-        GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, context->blit_vbo));
-
-        context_unload_vertex_data(context);
-        context_unload_numbered_arrays(context);
-
-        GL_EXTCALL(glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW));
-        GL_EXTCALL(glVertexAttribPointer(0, 2, GL_FLOAT, FALSE, sizeof(*quad), NULL));
-        GL_EXTCALL(glVertexAttribPointer(1, 3, GL_FLOAT, FALSE, sizeof(*quad),
-                (void *)FIELD_OFFSET(struct blit_vertex, texcoord)));
-
-        GL_EXTCALL(glEnableVertexAttribArray(0));
-        GL_EXTCALL(glEnableVertexAttribArray(1));
-
-        gl_info->gl_ops.gl.p_glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-        GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
-        GL_EXTCALL(glDisableVertexAttribArray(1));
-        GL_EXTCALL(glDisableVertexAttribArray(0));
-    }
-    else
-    {
-        gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
-
-        for (i = 0; i < ARRAY_SIZE(quad); ++i)
-        {
-            GL_EXTCALL(glVertexAttrib3fv(1, &quad[i].texcoord.x));
-            GL_EXTCALL(glVertexAttrib2fv(0, &quad[i].x));
-        }
-
-        gl_info->gl_ops.gl.p_glEnd();
-    }
-    checkGLcall("draw");
-
-    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
-    context_bind_texture(context, info.bind_target, 0);
-}
-
-/* Context activation is done by the caller. */
-void context_draw_textured_quad(struct wined3d_context *context, struct wined3d_texture *texture,
-        unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect,
-        enum wined3d_texture_filter_type filter)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_blt_info info;
-    unsigned int level;
-
-    texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info);
-
-    gl_info->gl_ops.gl.p_glEnable(info.bind_target);
-    checkGLcall("glEnable(bind_target)");
-
-    level = sub_resource_idx % texture->level_count;
-    context_bind_texture(context, info.bind_target, texture->texture_rgb.name);
-    apply_texture_blit_state(gl_info, &texture->texture_rgb, info.bind_target, level, filter);
-    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level);
-    gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-    checkGLcall("glTexEnvi");
-
-    /* Draw a quad. */
-    gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
-    gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x);
-    gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top);
-
-    gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x);
-    gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top);
-
-    gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x);
-    gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom);
-
-    gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x);
-    gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom);
-    gl_info->gl_ops.gl.p_glEnd();
-
-    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
-    context_bind_texture(context, info.bind_target, 0);
+    context_release(context);
 }
index eb24d94..460fe12 100644 (file)
@@ -33,8 +33,8 @@ enum wined3d_cs_op
     WINED3D_CS_OP_DRAW,
     WINED3D_CS_OP_FLUSH,
     WINED3D_CS_OP_SET_PREDICATION,
-    WINED3D_CS_OP_SET_VIEWPORTS,
-    WINED3D_CS_OP_SET_SCISSOR_RECTS,
+    WINED3D_CS_OP_SET_VIEWPORT,
+    WINED3D_CS_OP_SET_SCISSOR_RECT,
     WINED3D_CS_OP_SET_RENDERTARGET_VIEW,
     WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW,
     WINED3D_CS_OP_SET_VERTEX_DECLARATION,
@@ -94,7 +94,7 @@ struct wined3d_cs_present
     struct wined3d_swapchain *swapchain;
     RECT src_rect;
     RECT dst_rect;
-    unsigned int swap_interval;
+    DWORD swap_interval;
     DWORD flags;
 };
 
@@ -138,18 +138,16 @@ struct wined3d_cs_set_predication
     BOOL value;
 };
 
-struct wined3d_cs_set_viewports
+struct wined3d_cs_set_viewport
 {
     enum wined3d_cs_op opcode;
-    unsigned int viewport_count;
-    struct wined3d_viewport viewports[1];
+    struct wined3d_viewport viewport;
 };
 
-struct wined3d_cs_set_scissor_rects
+struct wined3d_cs_set_scissor_rect
 {
     enum wined3d_cs_op opcode;
-    unsigned int rect_count;
-    RECT rects[1];
+    RECT rect;
 };
 
 struct wined3d_cs_set_rendertarget_view
@@ -408,7 +406,9 @@ 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
@@ -456,7 +456,12 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
 
     swapchain = op->swapchain;
     wined3d_swapchain_set_window(swapchain, op->dst_window_override);
-    wined3d_swapchain_set_swap_interval(swapchain, op->swap_interval);
+
+    if (op->swap_interval && swapchain->desc.swap_interval != op->swap_interval)
+    {
+        swapchain->desc.swap_interval = op->swap_interval;
+        swapchain_update_swap_interval(swapchain);
+    }
 
     swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags);
 
@@ -471,7 +476,7 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
 
 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
         const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
-        unsigned int swap_interval, DWORD flags)
+        DWORD swap_interval, DWORD flags)
 {
     struct wined3d_cs_present *op;
     unsigned int i;
@@ -497,8 +502,9 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 
     /* Limit input latency by limiting the number of presents that we can get
-     * ahead of the worker thread. */
-    while (pending >= swapchain->max_frame_latency)
+     * ahead of the worker thread. We have a constant limit here, but
+     * IDXGIDevice1 allows tuning this. */
+    while (pending > 1)
     {
         wined3d_pause();
         pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0);
@@ -532,24 +538,19 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *
 {
     unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers;
     const struct wined3d_state *state = &cs->device->state;
-    const struct wined3d_viewport *vp = &state->viewports[0];
-    struct wined3d_rendertarget_view *view;
+    const struct wined3d_viewport *vp = &state->viewport;
     struct wined3d_cs_clear *op;
-    RECT view_rect;
     unsigned int i;
 
     op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]),
             WINED3D_CS_QUEUE_DEFAULT);
     op->opcode = WINED3D_CS_OP_CLEAR;
     op->flags = flags;
-    if (flags & WINED3DCLEAR_TARGET)
-        op->rt_count = rt_count;
-    else
-        op->rt_count = 0;
+    op->rt_count = rt_count;
     op->fb = &cs->fb;
     SetRect(&op->draw_rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
     if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
-        IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rects[0]);
+        IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rect);
     op->color = *color;
     op->depth = depth;
     op->stencil = stencil;
@@ -560,21 +561,12 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *
     {
         for (i = 0; i < rt_count; ++i)
         {
-            if ((view = state->fb->render_targets[i]))
-            {
-                SetRect(&view_rect, 0, 0, view->width, view->height);
-                IntersectRect(&op->draw_rect, &op->draw_rect, &view_rect);
-                wined3d_resource_acquire(view->resource);
-            }
+            if (state->fb->render_targets[i])
+                wined3d_resource_acquire(state->fb->render_targets[i]->resource);
         }
     }
     if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
-    {
-        view = state->fb->depth_stencil;
-        SetRect(&view_rect, 0, 0, view->width, view->height);
-        IntersectRect(&op->draw_rect, &op->draw_rect, &view_rect);
-        wined3d_resource_acquire(view->resource);
-    }
+        wined3d_resource_acquire(state->fb->depth_stencil->resource);
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
@@ -782,7 +774,6 @@ 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;
-    const struct wined3d_shader *geometry_shader;
     struct wined3d_state *state = &cs->state;
     const struct wined3d_cs_draw *op = data;
     int load_base_vertex_idx;
@@ -802,8 +793,6 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
 
     if (state->gl_primitive_type != op->primitive_type)
     {
-        if ((geometry_shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) && !geometry_shader->function)
-            device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY));
         if (state->gl_primitive_type == GL_POINTS || op->primitive_type == GL_POINTS)
             device_invalidate_state(cs->device, STATE_POINT_ENABLE);
         state->gl_primitive_type = op->primitive_type;
@@ -969,53 +958,40 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
-static void wined3d_cs_exec_set_viewports(struct wined3d_cs *cs, const void *data)
+static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data)
 {
-    const struct wined3d_cs_set_viewports *op = data;
+    const struct wined3d_cs_set_viewport *op = data;
 
-    if (op->viewport_count)
-        memcpy(cs->state.viewports, op->viewports, op->viewport_count * sizeof(*op->viewports));
-    else
-        memset(cs->state.viewports, 0, sizeof(*cs->state.viewports));
-    cs->state.viewport_count = op->viewport_count;
+    cs->state.viewport = op->viewport;
     device_invalidate_state(cs->device, STATE_VIEWPORT);
 }
 
-void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count,
-        const struct wined3d_viewport *viewports)
+void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport)
 {
-    struct wined3d_cs_set_viewports *op;
+    struct wined3d_cs_set_viewport *op;
 
-    op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_viewports, viewports[viewport_count]),
-            WINED3D_CS_QUEUE_DEFAULT);
-    op->opcode = WINED3D_CS_OP_SET_VIEWPORTS;
-    memcpy(op->viewports, viewports, viewport_count * sizeof(*viewports));
-    op->viewport_count = viewport_count;
+    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
+    op->viewport = *viewport;
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
-static void wined3d_cs_exec_set_scissor_rects(struct wined3d_cs *cs, const void *data)
+static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data)
 {
-    const struct wined3d_cs_set_scissor_rects *op = data;
+    const struct wined3d_cs_set_scissor_rect *op = data;
 
-    if (op->rect_count)
-        memcpy(cs->state.scissor_rects, op->rects, op->rect_count * sizeof(*op->rects));
-    else
-        SetRectEmpty(cs->state.scissor_rects);
-    cs->state.scissor_rect_count = op->rect_count;
+    cs->state.scissor_rect = op->rect;
     device_invalidate_state(cs->device, STATE_SCISSORRECT);
 }
 
-void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_count, const RECT *rects)
+void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
 {
-    struct wined3d_cs_set_scissor_rects *op;
+    struct wined3d_cs_set_scissor_rect *op;
 
-    op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_scissor_rects, rects[rect_count]),
-            WINED3D_CS_QUEUE_DEFAULT);
-    op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECTS;
-    memcpy(op->rects, rects, rect_count * sizeof(*rects));
-    op->rect_count = rect_count;
+    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT;
+    op->rect = *rect;
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
@@ -1047,14 +1023,16 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const
     struct wined3d_device *device = cs->device;
     struct wined3d_rendertarget_view *prev;
 
-    if ((prev = cs->state.fb->depth_stencil) && prev->resource->type != WINED3D_RTYPE_BUFFER)
+    if ((prev = cs->state.fb->depth_stencil))
     {
-        struct wined3d_texture *prev_texture = texture_from_resource(prev->resource);
+        struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev);
 
-        if (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
-                || prev_texture->flags & WINED3D_TEXTURE_DISCARD)
-            wined3d_texture_validate_location(prev_texture,
+        if (prev_surface && (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
+                || prev_surface->container->flags & WINED3D_TEXTURE_DISCARD))
+        {
+            wined3d_texture_validate_location(prev_surface->container,
                     prev->sub_resource_idx, WINED3D_LOCATION_DISCARDED);
+        }
     }
 
     cs->fb.depth_stencil = op->view;
@@ -1492,7 +1470,7 @@ static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const vo
     const struct wined3d_cs_set_rasterizer_state *op = data;
 
     cs->state.rasterizer_state = op->state;
-    device_invalidate_state(cs->device, STATE_RASTERIZER);
+    device_invalidate_state(cs->device, STATE_FRONTFACE);
 }
 
 void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs,
@@ -2081,6 +2059,23 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
                 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_2D)
+    {
+        struct wined3d_surface *dst_surface, *src_surface;
+        struct wined3d_texture *dst_texture, *src_texture;
+        RECT dst_rect, src_rect;
+
+        dst_texture = texture_from_resource(op->dst_resource);
+        src_texture = texture_from_resource(op->src_resource);
+        dst_surface = dst_texture->sub_resources[op->dst_sub_resource_idx].u.surface;
+        src_surface = src_texture->sub_resources[op->src_sub_resource_idx].u.surface;
+        SetRect(&dst_rect, op->dst_box.left, op->dst_box.top, op->dst_box.right, op->dst_box.bottom);
+        SetRect(&src_rect, op->src_box.left, op->src_box.top, op->src_box.right, op->src_box.bottom);
+
+        if (FAILED(wined3d_surface_blt(dst_surface, &dst_rect, src_surface,
+                &src_rect, op->flags, &op->fx, op->filter)))
+            FIXME("Blit failed.\n");
+    }
     else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_3D)
     {
         struct wined3d_texture *src_texture, *dst_texture;
@@ -2115,6 +2110,13 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
             goto error;
         }
 
+        if (op->src_box.left || op->src_box.top || op->src_box.front)
+        {
+            FIXME("Source box %s not supported for %s resources.\n",
+                    debug_box(&op->src_box), debug_d3dresourcetype(op->dst_resource->type));
+            goto error;
+        }
+
         dst_texture = texture_from_resource(op->dst_resource);
         src_texture = texture_from_resource(op->src_resource);
 
@@ -2149,9 +2151,8 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
                 &row_pitch, &slice_pitch);
 
         wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
-        wined3d_texture_upload_data(dst_texture, op->dst_sub_resource_idx, context,
-                dst_texture->resource.format, &op->src_box, wined3d_const_bo_address(&addr),
-                row_pitch, slice_pitch, op->dst_box.left, op->dst_box.top, op->dst_box.front, FALSE);
+        wined3d_texture_upload_data(dst_texture, op->dst_sub_resource_idx, context, &op->dst_box,
+                wined3d_const_bo_address(&addr), row_pitch, slice_pitch);
         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);
 
@@ -2159,10 +2160,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
     }
     else
     {
-        if (FAILED(texture2d_blt(texture_from_resource(op->dst_resource), op->dst_sub_resource_idx,
-                &op->dst_box, texture_from_resource(op->src_resource), op->src_sub_resource_idx,
-                &op->src_box, op->flags, &op->fx, op->filter)))
-            FIXME("Blit failed.\n");
+        FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(op->dst_resource->type));
     }
 
 error:
@@ -2211,7 +2209,6 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
     struct wined3d_const_bo_address addr;
     struct wined3d_context *context;
     struct wined3d_texture *texture;
-    struct wined3d_box src_box;
 
     context = context_acquire(cs->device, NULL, 0);
 
@@ -2248,9 +2245,8 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
         wined3d_texture_load_location(texture, op->sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_bind_and_dirtify(texture, context, FALSE);
 
-    wined3d_box_set(&src_box, 0, 0, box->right - box->left, box->bottom - box->top, 0, box->back - box->front);
-    wined3d_texture_upload_data(texture, op->sub_resource_idx, context, texture->resource.format, &src_box,
-            &addr, op->data.row_pitch, op->data.slice_pitch, box->left, box->top, box->front, FALSE);
+    wined3d_texture_upload_data(texture, op->sub_resource_idx, context,
+            box, &addr, op->data.row_pitch, op->data.slice_pitch);
 
     wined3d_texture_validate_location(texture, op->sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_invalidate_location(texture, op->sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
@@ -2266,6 +2262,7 @@ 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)
@@ -2311,6 +2308,7 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r
 
 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;
@@ -2324,6 +2322,10 @@ 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);
 }
 
@@ -2464,8 +2466,8 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_DRAW                        */ wined3d_cs_exec_draw,
     /* WINED3D_CS_OP_FLUSH                       */ wined3d_cs_exec_flush,
     /* WINED3D_CS_OP_SET_PREDICATION             */ wined3d_cs_exec_set_predication,
-    /* WINED3D_CS_OP_SET_VIEWPORTS               */ wined3d_cs_exec_set_viewports,
-    /* WINED3D_CS_OP_SET_SCISSOR_RECTS           */ wined3d_cs_exec_set_scissor_rects,
+    /* WINED3D_CS_OP_SET_VIEWPORT                */ wined3d_cs_exec_set_viewport,
+    /* WINED3D_CS_OP_SET_SCISSOR_RECT            */ wined3d_cs_exec_set_scissor_rect,
     /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW       */ wined3d_cs_exec_set_rendertarget_view,
     /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW      */ wined3d_cs_exec_set_depth_stencil_view,
     /* WINED3D_CS_OP_SET_VERTEX_DECLARATION      */ wined3d_cs_exec_set_vertex_declaration,
@@ -2506,11 +2508,13 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* 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))
@@ -2564,7 +2568,9 @@ 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,
@@ -2601,6 +2607,7 @@ 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);
@@ -2614,6 +2621,7 @@ static BOOL wined3d_cs_queue_check_space(struct wined3d_cs_queue *queue, size_t
     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);
@@ -2675,6 +2683,7 @@ 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())
@@ -2683,6 +2692,7 @@ static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum w
     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())
@@ -2705,7 +2715,9 @@ 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,
index 8b4b3f9..e2b27e0 100644 (file)
@@ -99,7 +99,7 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
     }
 }
 
-enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type)
+static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type)
 {
     switch (primitive_type)
     {
@@ -226,11 +226,11 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
         float depth, DWORD stencil)
 {
     struct wined3d_rendertarget_view *rtv = rt_count ? fb->render_targets[0] : NULL;
+    struct wined3d_surface *target = rtv ? wined3d_rendertarget_view_get_surface(rtv) : NULL;
     struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
+    struct wined3d_surface *depth_stencil = dsv ? wined3d_rendertarget_view_get_surface(dsv) : NULL;
     const struct wined3d_state *state = &device->cs->state;
-    struct wined3d_texture *depth_stencil = NULL;
     const struct wined3d_gl_info *gl_info;
-    struct wined3d_texture *target = NULL;
     UINT drawable_width, drawable_height;
     struct wined3d_color corrected_color;
     struct wined3d_context *context;
@@ -238,19 +238,10 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
     BOOL render_offscreen;
     unsigned int i;
 
-    if (rtv && rtv->resource->type != WINED3D_RTYPE_BUFFER)
-    {
-        target = texture_from_resource(rtv->resource);
-        context = context_acquire(device, target, rtv->sub_resource_idx);
-    }
+    if (target)
+        context = context_acquire(device, target->container, rtv->sub_resource_idx);
     else
-    {
         context = context_acquire(device, NULL, 0);
-    }
-
-    if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER)
-        depth_stencil = texture_from_resource(dsv->resource);
-
     if (!context->valid)
     {
         context_release(context);
@@ -290,11 +281,11 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
     }
     else
     {
-        unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->level_count;
+        unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->container->level_count;
 
         render_offscreen = TRUE;
-        drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil, ds_level);
-        drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil, ds_level);
+        drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil->container, ds_level);
+        drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil->container, ds_level);
     }
 
     if (depth_stencil)
@@ -411,7 +402,9 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
             gl_info->gl_ops.gl.p_glScissor(draw_rect->left, drawable_height - draw_rect->bottom,
                         draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
         }
+        checkGLcall("glScissor");
         gl_info->gl_ops.gl.p_glClear(clear_mask);
+        checkGLcall("glClear");
     }
     else
     {
@@ -446,14 +439,16 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
                 gl_info->gl_ops.gl.p_glScissor(current_rect.left, drawable_height - current_rect.bottom,
                           current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
             }
+            checkGLcall("glScissor");
+
             gl_info->gl_ops.gl.p_glClear(clear_mask);
+            checkGLcall("glClear");
         }
     }
-    context->scissor_rect_count = WINED3D_MAX_VIEWPORTS;
-    checkGLcall("clear");
 
-    if (flags & WINED3DCLEAR_TARGET && target->swapchain && target->swapchain->front_buffer == target)
-        gl_info->gl_ops.gl.p_glFlush();
+    if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET
+            && target->container->swapchain && target->container->swapchain->front_buffer == target->container))
+        gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
 }
@@ -682,11 +677,12 @@ 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, &textures->tex_1d_array);
         TRACE("Dummy 1D array texture given name %u.\n", textures->tex_1d_array);
         gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
         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);
+                GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
 
         gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d_array);
         TRACE("Dummy 2D array texture given name %u.\n", textures->tex_2d_array);
@@ -756,8 +752,8 @@ static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d
 
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
     {
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array);
         gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d_array);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array);
     }
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
@@ -1040,8 +1036,7 @@ static void wined3d_device_create_primary_opengl_context_cs(void *object)
         return;
     }
     wined3d_ffp_blitter_create(&device->blitter, &device->adapter->gl_info);
-    if (!wined3d_glsl_blitter_create(&device->blitter, device))
-        wined3d_arbfp_blitter_create(&device->blitter, device);
+    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);
 
@@ -1089,7 +1084,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
         goto err_out;
     }
 
-    if (swapchain_desc->backbuffer_count && swapchain_desc->backbuffer_usage & WINED3DUSAGE_RENDERTARGET)
+    if (swapchain_desc->backbuffer_count)
     {
         struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource;
         struct wined3d_view_desc view_desc;
@@ -1125,7 +1120,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
     TRACE("All defaults now set up.\n");
 
     /* Clear the screen */
-    if (device->back_buffer_view)
+    if (swapchain->back_buffers && swapchain->back_buffers[0])
         clear_flags |= WINED3DCLEAR_TARGET;
     if (swapchain_desc->enable_auto_depth_stencil)
         clear_flags |= WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL;
@@ -1217,7 +1212,9 @@ 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)
@@ -1931,24 +1928,13 @@ INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *devi
     return device->state.base_vertex_index;
 }
 
-void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count,
-        const struct wined3d_viewport *viewports)
+void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport)
 {
-    unsigned int i;
+    TRACE("device %p, viewport %p.\n", device, viewport);
+    TRACE("x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n",
+          viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z);
 
-    TRACE("device %p, viewport_count %u, viewports %p.\n", device, viewport_count, viewports);
-
-    for (i = 0; i < viewport_count; ++i)
-    {
-        TRACE("%u: x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n",  i, viewports[i].x, viewports[i].y,
-                viewports[i].width, viewports[i].height, viewports[i].min_z, viewports[i].max_z);
-    }
-
-    if (viewport_count)
-        memcpy(device->update_state->viewports, viewports, viewport_count * sizeof(*viewports));
-    else
-        memset(device->update_state->viewports, 0, sizeof(device->update_state->viewports));
-    device->update_state->viewport_count = viewport_count;
+    device->update_state->viewport = *viewport;
 
     /* Handle recording of state blocks */
     if (device->recording)
@@ -1958,21 +1944,14 @@ void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned
         return;
     }
 
-    wined3d_cs_emit_set_viewports(device->cs, viewport_count, viewports);
+    wined3d_cs_emit_set_viewport(device->cs, viewport);
 }
 
-void CDECL wined3d_device_get_viewports(const struct wined3d_device *device, unsigned int *viewport_count,
-        struct wined3d_viewport *viewports)
+void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport)
 {
-    unsigned int count;
-
-    TRACE("device %p, viewport_count %p, viewports %p.\n", device, viewport_count, viewports);
+    TRACE("device %p, viewport %p.\n", device, viewport);
 
-    count = viewport_count ? min(*viewport_count, device->state.viewport_count) : 1;
-    if (count && viewports)
-        memcpy(viewports, device->state.viewports, count * sizeof(*viewports));
-    if (viewport_count)
-        *viewport_count = device->state.viewport_count;
+    *viewport = device->state.viewport;
 }
 
 static void resolve_depth_buffer(struct wined3d_device *device)
@@ -2144,33 +2123,19 @@ DWORD CDECL wined3d_device_get_sampler_state(const struct wined3d_device *device
     return device->state.sampler_states[sampler_idx][state];
 }
 
-void CDECL wined3d_device_set_scissor_rects(struct wined3d_device *device, unsigned int rect_count,
-        const RECT *rects)
+void CDECL wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect)
 {
-    unsigned int i;
-
-    TRACE("device %p, rect_count %u, rects %p.\n", device, rect_count, rects);
-
-    for (i = 0; i < rect_count; ++i)
-    {
-        TRACE("%u: %s\n", i, wine_dbgstr_rect(&rects[i]));
-    }
+    TRACE("device %p, rect %s.\n", device, wine_dbgstr_rect(rect));
 
     if (device->recording)
         device->recording->changed.scissorRect = TRUE;
 
-    if (device->update_state->scissor_rect_count == rect_count
-            && !memcmp(device->update_state->scissor_rects, rects, rect_count * sizeof(*rects)))
+    if (EqualRect(&device->update_state->scissor_rect, rect))
     {
-        TRACE("App is setting the old scissor rectangles over, nothing to do.\n");
+        TRACE("App is setting the old scissor rectangle over, nothing to do.\n");
         return;
     }
-
-    if (rect_count)
-        memcpy(device->update_state->scissor_rects, rects, rect_count * sizeof(*rects));
-    else
-        memset(device->update_state->scissor_rects, 0, sizeof(device->update_state->scissor_rects));
-    device->update_state->scissor_rect_count = rect_count;
+    CopyRect(&device->update_state->scissor_rect, rect);
 
     if (device->recording)
     {
@@ -2178,20 +2143,15 @@ void CDECL wined3d_device_set_scissor_rects(struct wined3d_device *device, unsig
         return;
     }
 
-    wined3d_cs_emit_set_scissor_rects(device->cs, rect_count, rects);
+    wined3d_cs_emit_set_scissor_rect(device->cs, rect);
 }
 
-void CDECL wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count, RECT *rects)
+void CDECL wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect)
 {
-    unsigned int count;
-
-    TRACE("device %p, rect_count %p, rects %p.\n", device, rect_count, rects);
+    TRACE("device %p, rect %p.\n", device, rect);
 
-    count = rect_count ? min(*rect_count, device->state.scissor_rect_count) : 1;
-    if (count && rects)
-        memcpy(rects, device->state.scissor_rects, count * sizeof(*rects));
-    if (rect_count)
-        *rect_count = device->state.scissor_rect_count;
+    *rect = device->state.scissor_rect;
+    TRACE("Returning rect %s.\n", wine_dbgstr_rect(rect));
 }
 
 void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device,
@@ -3105,23 +3065,6 @@ struct wined3d_unordered_access_view * CDECL wined3d_device_get_unordered_access
     return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx);
 }
 
-void CDECL wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int latency)
-{
-    unsigned int i;
-
-    if (!latency)
-        latency = 3;
-
-    device->max_frame_latency = latency;
-    for (i = 0; i < device->swapchain_count; ++i)
-        swapchain_set_max_frame_latency(device->swapchains[i], device);
-}
-
-unsigned int CDECL wined3d_device_get_max_frame_latency(const struct wined3d_device *device)
-{
-    return device->max_frame_latency;
-}
-
 /* Context activation is done by the caller. */
 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
 static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount,
@@ -3203,8 +3146,8 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
     TRACE("%.8e %.8e %.8e %.8e\n", world_mat._41, world_mat._42, world_mat._43, world_mat._44);
 
     /* Get the viewport */
-    wined3d_device_get_viewports(device, NULL, &vp);
-    TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n",
+    wined3d_device_get_viewport(device, &vp);
+    TRACE("viewport  x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n",
           vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z);
 
     multiply_matrix(&mat,&view_mat,&world_mat);
@@ -3919,9 +3862,12 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
     level_count = min(src_level_count, dst_level_count);
 
     src_size = max(src_texture->resource.width, src_texture->resource.height);
-    src_size = max(src_size, src_texture->resource.depth);
     dst_size = max(dst_texture->resource.width, dst_texture->resource.height);
-    dst_size = max(dst_size, dst_texture->resource.depth);
+    if (type == WINED3D_RTYPE_TEXTURE_3D)
+    {
+        src_size = max(src_size, src_texture->resource.depth);
+        dst_size = max(dst_size, dst_texture->resource.depth);
+    }
     while (src_size > dst_size)
     {
         src_size >>= 1;
@@ -4175,17 +4121,14 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
 HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *device,
         struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, unsigned int dst_x,
         unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource,
-        unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, unsigned int flags)
+        unsigned int src_sub_resource_idx, const struct wined3d_box *src_box)
 {
     struct wined3d_box dst_box, b;
 
     TRACE("device %p, dst_resource %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, "
-            "src_resource %p, src_sub_resource_idx %u, src_box %s, flags %#x.\n",
+            "src_resource %p, src_sub_resource_idx %u, src_box %s.\n",
             device, dst_resource, dst_sub_resource_idx, dst_x, dst_y, dst_z,
-            src_resource, src_sub_resource_idx, debug_box(src_box), flags);
-
-    if (flags)
-        FIXME("Ignoring flags %#x.\n", flags);
+            src_resource, src_sub_resource_idx, debug_box(src_box));
 
     if (src_resource == dst_resource && src_sub_resource_idx == dst_sub_resource_idx)
     {
@@ -4250,7 +4193,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
 
         wined3d_box_set(&dst_box, dst_x, 0, dst_x + (src_box->right - src_box->left), 1, 0, 1);
     }
-    else
+    else if (dst_resource->type == WINED3D_RTYPE_TEXTURE_2D)
     {
         struct wined3d_texture *dst_texture = texture_from_resource(dst_resource);
         struct wined3d_texture *src_texture = texture_from_resource(src_resource);
@@ -4268,6 +4211,7 @@ 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);
@@ -4278,22 +4222,33 @@ 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)
         {
-            unsigned int src_w, src_h, src_d, dst_w, dst_h, dst_d, dst_level;
+            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);
-            src_d = wined3d_texture_get_level_depth(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;
-            dst_d = wined3d_texture_get_level_depth(dst_texture, dst_level) - dst_z;
 
-            wined3d_box_set(&b, 0, 0, min(src_w, dst_w), min(src_h, dst_h), 0, min(src_d, dst_d));
+            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)))
@@ -4303,7 +4258,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
         }
 
         wined3d_box_set(&dst_box, dst_x, dst_y, dst_x + (src_box->right - src_box->left),
-                dst_y + (src_box->bottom - src_box->top), dst_z, dst_z + (src_box->back - src_box->front));
+                dst_y + (src_box->bottom - src_box->top), 0, 1);
         if (FAILED(wined3d_texture_check_box_dimensions(dst_texture,
                 dst_sub_resource_idx % dst_texture->level_count, &dst_box)))
         {
@@ -4311,6 +4266,11 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
             return WINED3DERR_INVALIDCALL;
         }
     }
+    else
+    {
+        FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type));
+        return WINED3DERR_INVALIDCALL;
+    }
 
     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);
@@ -4320,17 +4280,13 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
 
 void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource,
         unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch,
-        unsigned int depth_pitch, unsigned int flags)
+        unsigned int depth_pitch)
 {
     unsigned int width, height, depth;
     struct wined3d_box b;
 
-    TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u, "
-            "flags %#x.\n",
-            device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch, flags);
-
-    if (flags)
-        FIXME("Ignoring flags %#x.\n", flags);
+    TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u.\n",
+            device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch);
 
     if (resource->type == WINED3D_RTYPE_BUFFER)
     {
@@ -4344,7 +4300,8 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
         height = 1;
         depth = 1;
     }
-    else
+    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;
@@ -4360,6 +4317,11 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
         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;
+    }
 
     if (!box)
     {
@@ -4374,6 +4336,10 @@ 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);
 }
 
@@ -4437,7 +4403,7 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi
         return WINED3D_OK;
 
     resource = view->resource;
-    if (resource->type != WINED3D_RTYPE_TEXTURE_1D && resource->type != WINED3D_RTYPE_TEXTURE_2D)
+    if (resource->type != WINED3D_RTYPE_TEXTURE_2D)
     {
         FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
         return WINED3DERR_INVALIDCALL;
@@ -4526,20 +4492,19 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device
     {
         struct wined3d_state *state = &device->state;
 
-        state->viewports[0].x = 0;
-        state->viewports[0].y = 0;
-        state->viewports[0].width = view->width;
-        state->viewports[0].height = view->height;
-        state->viewports[0].min_z = 0.0f;
-        state->viewports[0].max_z = 1.0f;
-        state->viewport_count = 1;
-        wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports);
+        state->viewport.x = 0;
+        state->viewport.y = 0;
+        state->viewport.width = view->width;
+        state->viewport.height = view->height;
+        state->viewport.min_z = 0.0f;
+        state->viewport.max_z = 1.0f;
+        wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
 
-        SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height);
-        state->scissor_rect_count = 1;
-        wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects);
+        SetRect(&state->scissor_rect, 0, 0, view->width, view->height);
+        wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
     }
 
+
     prev = device->fb.render_targets[view_idx];
     if (view == prev)
         return WINED3D_OK;
@@ -4871,9 +4836,10 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         TRACE("auto_depth_stencil_format %s\n", debug_d3dformat(swapchain_desc->auto_depth_stencil_format));
     TRACE("flags %#x\n", swapchain_desc->flags);
     TRACE("refresh_rate %u\n", swapchain_desc->refresh_rate);
+    TRACE("swap_interval %u\n", swapchain_desc->swap_interval);
     TRACE("auto_restore_display_mode %#x\n", swapchain_desc->auto_restore_display_mode);
 
-    if (swapchain_desc->backbuffer_usage && swapchain_desc->backbuffer_usage != WINED3DUSAGE_RENDERTARGET)
+    if (swapchain_desc->backbuffer_usage != WINED3DUSAGE_RENDERTARGET)
         FIXME("Got unexpected backbuffer usage %#x.\n", swapchain_desc->backbuffer_usage);
 
     if (swapchain_desc->swap_effect != WINED3D_SWAP_EFFECT_DISCARD
@@ -4887,6 +4853,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     swapchain->desc.auto_depth_stencil_format = swapchain_desc->auto_depth_stencil_format;
     swapchain->desc.flags = swapchain_desc->flags;
     swapchain->desc.refresh_rate = swapchain_desc->refresh_rate;
+    swapchain->desc.swap_interval = swapchain_desc->swap_interval;
     swapchain->desc.auto_restore_display_mode = swapchain_desc->auto_restore_display_mode;
 
     if (swapchain_desc->device_window
@@ -4988,7 +4955,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         wined3d_rendertarget_view_decref(device->back_buffer_view);
         device->back_buffer_view = NULL;
     }
-    if (swapchain->desc.backbuffer_count && swapchain->desc.backbuffer_usage & WINED3DUSAGE_RENDERTARGET)
+    if (swapchain->desc.backbuffer_count)
     {
         struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource;
 
@@ -5039,22 +5006,21 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         wined3d_device_set_rendertarget_view(device, 0, view, FALSE);
 
         /* Note the min_z / max_z is not reset. */
-        state->viewports[0].x = 0;
-        state->viewports[0].y = 0;
-        state->viewports[0].width = view->width;
-        state->viewports[0].height = view->height;
-        state->viewport_count = 1;
-        wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports);
+        state->viewport.x = 0;
+        state->viewport.y = 0;
+        state->viewport.width = view->width;
+        state->viewport.height = view->height;
+        wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
 
-        SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height);
-        state->scissor_rect_count = 1;
-        wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects);
+        SetRect(&state->scissor_rect, 0, 0, view->width, view->height);
+        wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
     }
 
     if (device->d3d_initialized)
     {
         if (reset_state)
             hr = wined3d_device_create_primary_opengl_context(device);
+        swapchain_update_swap_interval(swapchain);
     }
 
     /* All done. There is no need to reload resources or shaders, this will happen automatically on the
@@ -5157,49 +5123,55 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso
         case WINED3D_RTYPE_TEXTURE_3D:
             for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
             {
-                if (&device->state.textures[i]->resource == resource)
+                struct wined3d_texture *texture = texture_from_resource(resource);
+
+                if (device->state.textures[i] == texture)
                 {
-                    ERR("Texture resource %p is still in use, stage %u.\n", resource, i);
+                    ERR("Texture %p is still in use, stage %u.\n", texture, i);
                     device->state.textures[i] = NULL;
                 }
 
-                if (device->recording && &device->update_state->textures[i]->resource == resource)
+                if (device->recording && device->update_state->textures[i] == texture)
                 {
-                    ERR("Texture resource %p is still in use by recording stateblock %p, stage %u.\n",
-                            resource, device->recording, i);
+                    ERR("Texture %p is still in use by recording stateblock %p, stage %u.\n",
+                            texture, device->recording, i);
                     device->update_state->textures[i] = NULL;
                 }
             }
             break;
 
         case WINED3D_RTYPE_BUFFER:
-            for (i = 0; i < MAX_STREAMS; ++i)
             {
-                if (&device->state.streams[i].buffer->resource == resource)
+                struct wined3d_buffer *buffer = buffer_from_resource(resource);
+
+                for (i = 0; i < MAX_STREAMS; ++i)
                 {
-                    ERR("Buffer resource %p is still in use, stream %u.\n", resource, i);
-                    device->state.streams[i].buffer = NULL;
+                    if (device->state.streams[i].buffer == buffer)
+                    {
+                        ERR("Buffer %p is still in use, stream %u.\n", buffer, i);
+                        device->state.streams[i].buffer = NULL;
+                    }
+
+                    if (device->recording && device->update_state->streams[i].buffer == buffer)
+                    {
+                        ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
+                                buffer, device->recording, i);
+                        device->update_state->streams[i].buffer = NULL;
+                    }
                 }
 
-                if (device->recording && &device->update_state->streams[i].buffer->resource == resource)
+                if (device->state.index_buffer == buffer)
                 {
-                    ERR("Buffer resource %p is still in use by stateblock %p, stream %u.\n",
-                            resource, device->recording, i);
-                    device->update_state->streams[i].buffer = NULL;
+                    ERR("Buffer %p is still in use as index buffer.\n", buffer);
+                    device->state.index_buffer =  NULL;
                 }
-            }
 
-            if (&device->state.index_buffer->resource == resource)
-            {
-                ERR("Buffer resource %p is still in use as index buffer.\n", resource);
-                device->state.index_buffer =  NULL;
-            }
-
-            if (device->recording && &device->update_state->index_buffer->resource == resource)
-            {
-                ERR("Buffer resource %p is still in use by stateblock %p as index buffer.\n",
-                        resource, device->recording);
-                device->update_state->index_buffer =  NULL;
+                if (device->recording && device->update_state->index_buffer == buffer)
+                {
+                    ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
+                            buffer, device->recording);
+                    device->update_state->index_buffer =  NULL;
+                }
             }
             break;
 
@@ -5268,8 +5240,6 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
             &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
     device->update_state = &device->state;
 
-    device->max_frame_latency = 3;
-
     if (!(device->cs = wined3d_cs_create(device)))
     {
         WARN("Failed to create command stream.\n");
@@ -5369,3 +5339,58 @@ 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 */
index baeb287..d82a671 100644 (file)
@@ -156,7 +156,6 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_point_parameters",             ARB_POINT_PARAMETERS          },
     {"GL_ARB_point_sprite",                 ARB_POINT_SPRITE              },
     {"GL_ARB_provoking_vertex",             ARB_PROVOKING_VERTEX          },
-    {"GL_ARB_sample_shading",               ARB_SAMPLE_SHADING            },
     {"GL_ARB_sampler_objects",              ARB_SAMPLER_OBJECTS           },
     {"GL_ARB_seamless_cube_map",            ARB_SEAMLESS_CUBE_MAP         },
     {"GL_ARB_shader_atomic_counters",       ARB_SHADER_ATOMIC_COUNTERS    },
@@ -164,7 +163,6 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_shader_image_load_store",      ARB_SHADER_IMAGE_LOAD_STORE   },
     {"GL_ARB_shader_image_size",            ARB_SHADER_IMAGE_SIZE         },
     {"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT},
-    {"GL_ARB_shader_texture_image_samples", ARB_SHADER_TEXTURE_IMAGE_SAMPLES},
     {"GL_ARB_shader_texture_lod",           ARB_SHADER_TEXTURE_LOD        },
     {"GL_ARB_shading_language_100",         ARB_SHADING_LANGUAGE_100      },
     {"GL_ARB_shading_language_420pack",     ARB_SHADING_LANGUAGE_420PACK  },
@@ -203,6 +201,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_transform_feedback3",          ARB_TRANSFORM_FEEDBACK3       },
     {"GL_ARB_uniform_buffer_object",        ARB_UNIFORM_BUFFER_OBJECT     },
     {"GL_ARB_vertex_array_bgra",            ARB_VERTEX_ARRAY_BGRA         },
+    {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND              },
     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT      },
     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM            },
     {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER             },
@@ -679,7 +678,7 @@ static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, struc
     GLenum error;
     DWORD data[16];
 
-    if (!gl_info->supported[EXT_SECONDARY_COLOR] || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+    if (!gl_info->supported[EXT_SECONDARY_COLOR])
         return FALSE;
 
     while (gl_info->gl_ops.gl.p_glGetError());
@@ -859,8 +858,6 @@ static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, struct w
         return FALSE;
     if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
         return FALSE;
-    if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
-        return FALSE;
 
     gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
     gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
@@ -1401,13 +1398,11 @@ static const struct gpu_description gpu_description_table[] =
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX980,     "NVIDIA GeForce GTX 980",           DRIVER_NVIDIA_GEFORCE8,  4096},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX980TI,   "NVIDIA GeForce GTX 980 Ti",        DRIVER_NVIDIA_GEFORCE8,  6144},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1050,    "NVIDIA GeForce GTX 1050",          DRIVER_NVIDIA_GEFORCE8,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1050TI,  "NVIDIA GeForce GTX 1050 Ti",       DRIVER_NVIDIA_GEFORCE8,  4096},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1060,    "NVIDIA GeForce GTX 1060",          DRIVER_NVIDIA_GEFORCE8,  6144},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1070,    "NVIDIA GeForce GTX 1070",          DRIVER_NVIDIA_GEFORCE8,  8192},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1080,    "NVIDIA GeForce GTX 1080",          DRIVER_NVIDIA_GEFORCE8,  8192},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1080TI,  "NVIDIA GeForce GTX 1080 Ti",       DRIVER_NVIDIA_GEFORCE8,  11264},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_TITANX_PASCAL,      "NVIDIA TITAN X (Pascal)",          DRIVER_NVIDIA_GEFORCE8,  12288},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_TITANV,             "NVIDIA TITAN V",                   DRIVER_NVIDIA_GEFORCE8,  12288},
 
     /* AMD cards */
     {HW_VENDOR_AMD,        CARD_AMD_RAGE_128PRO,           "ATI Rage Fury",                    DRIVER_AMD_RAGE_128PRO,  16  },
@@ -1708,11 +1703,13 @@ 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:
@@ -1906,13 +1903,11 @@ static const struct wined3d_renderer_table
 cards_nvidia_binary[] =
 {
     /* Direct 3D 11 */
-    {"TITAN V",                     CARD_NVIDIA_TITANV},            /* GeForce 1000 - highend */
     {"TITAN X (Pascal)",            CARD_NVIDIA_TITANX_PASCAL},     /* GeForce 1000 - highend */
     {"GTX 1080 Ti",                 CARD_NVIDIA_GEFORCE_GTX1080TI}, /* GeForce 1000 - highend */
     {"GTX 1080",                    CARD_NVIDIA_GEFORCE_GTX1080},   /* GeForce 1000 - highend */
     {"GTX 1070",                    CARD_NVIDIA_GEFORCE_GTX1070},   /* GeForce 1000 - highend */
     {"GTX 1060",                    CARD_NVIDIA_GEFORCE_GTX1060},   /* GeForce 1000 - midend high */
-    {"GTX 1050 Ti",                 CARD_NVIDIA_GEFORCE_GTX1050TI}, /* GeForce 1000 - midend */
     {"GTX 1050",                    CARD_NVIDIA_GEFORCE_GTX1050},   /* GeForce 1000 - midend */
     {"GTX 980 Ti",                  CARD_NVIDIA_GEFORCE_GTX980TI},  /* GeForce 900 - highend */
     {"GTX 980",                     CARD_NVIDIA_GEFORCE_GTX980},    /* GeForce 900 - highend */
@@ -2230,7 +2225,9 @@ cards_intel[] =
     {"830M",                        CARD_INTEL_830M},
 },
 /* 20101109 - These are never returned by current Gallium radeon
- * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351. */
+ * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351.
+ *
+ * These are returned but not handled: RC410, RV380. */
 cards_amd_mesa[] =
 {
     /* Polaris 10/11 */
@@ -2308,12 +2305,10 @@ cards_amd_mesa[] =
     {"RS482",                       CARD_AMD_RADEON_XPRESS_200M},
     {"RS480",                       CARD_AMD_RADEON_XPRESS_200M},
     {"RS400",                       CARD_AMD_RADEON_XPRESS_200M},
-    {"RC410",                       CARD_AMD_RADEON_XPRESS_200M},
     /* R300 */
     {"R360",                        CARD_AMD_RADEON_9500},
     {"R350",                        CARD_AMD_RADEON_9500},
     {"R300",                        CARD_AMD_RADEON_9500},
-    {"RV380",                       CARD_AMD_RADEON_9500},
     {"RV370",                       CARD_AMD_RADEON_9500},
     {"RV360",                       CARD_AMD_RADEON_9500},
     {"RV351",                       CARD_AMD_RADEON_9500},
@@ -2827,8 +2822,6 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     USE_GL_FUNC(glPointParameterfvARB)
     /* GL_ARB_provoking_vertex */
     USE_GL_FUNC(glProvokingVertex)
-    /* GL_ARB_sample_shading */
-    USE_GL_FUNC(glMinSampleShadingARB)
     /* GL_ARB_sampler_objects */
     USE_GL_FUNC(glGenSamplers)
     USE_GL_FUNC(glDeleteSamplers)
@@ -2955,6 +2948,17 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     USE_GL_FUNC(glGetUniformBlockIndex)
     USE_GL_FUNC(glGetUniformIndices)
     USE_GL_FUNC(glUniformBlockBinding)
+    /* GL_ARB_vertex_blend */
+    USE_GL_FUNC(glVertexBlendARB)
+    USE_GL_FUNC(glWeightPointerARB)
+    USE_GL_FUNC(glWeightbvARB)
+    USE_GL_FUNC(glWeightdvARB)
+    USE_GL_FUNC(glWeightfvARB)
+    USE_GL_FUNC(glWeightivARB)
+    USE_GL_FUNC(glWeightsvARB)
+    USE_GL_FUNC(glWeightubvARB)
+    USE_GL_FUNC(glWeightuivARB)
+    USE_GL_FUNC(glWeightusvARB)
     /* GL_ARB_vertex_buffer_object */
     USE_GL_FUNC(glBindBufferARB)
     USE_GL_FUNC(glBufferDataARB)
@@ -3422,7 +3426,6 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT);
     MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB);
     MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB);
-    MAP_GL_FUNCTION(glMinSampleShading, glMinSampleShadingARB);
     MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB);
     MAP_GL_FUNCTION(glTexBuffer, glTexBufferARB);
     MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT);
@@ -3476,6 +3479,7 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
     GLfloat gl_floatv[2];
     GLint gl_max;
 
+    gl_info->limits.blends = 1;
     gl_info->limits.buffers = 1;
     gl_info->limits.textures = 0;
     gl_info->limits.texture_coords = 0;
@@ -3631,6 +3635,12 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
         gl_info->limits.texture_coords = 1;
     }
 
+    if (gl_info->supported[ARB_VERTEX_BLEND])
+    {
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
+        gl_info->limits.blends = gl_max;
+        TRACE("Max blends: %u.\n", gl_info->limits.blends);
+    }
     if (gl_info->supported[EXT_TEXTURE3D])
     {
         gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
@@ -3900,7 +3910,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
         {EXT_TEXTURE_SNORM,                MAKEDWORD_VERSION(3, 1)},
         /* We don't need or want GL_ARB_texture_rectangle (core in 3.1). */
 
-        {ARB_DEPTH_CLAMP,                  MAKEDWORD_VERSION(3, 2)},
         {ARB_DRAW_ELEMENTS_BASE_VERTEX,    MAKEDWORD_VERSION(3, 2)},
         /* ARB_geometry_shader4 exposes a somewhat different API compared to 3.2
          * core geometry shaders so it's not really correct to expose the
@@ -3924,7 +3933,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
 
         {ARB_DRAW_INDIRECT,                MAKEDWORD_VERSION(4, 0)},
         {ARB_GPU_SHADER5,                  MAKEDWORD_VERSION(4, 0)},
-        {ARB_SAMPLE_SHADING,               MAKEDWORD_VERSION(4, 0)},
         {ARB_TESSELLATION_SHADER,          MAKEDWORD_VERSION(4, 0)},
         {ARB_TEXTURE_CUBE_MAP_ARRAY,       MAKEDWORD_VERSION(4, 0)},
         {ARB_TEXTURE_GATHER,               MAKEDWORD_VERSION(4, 0)},
@@ -3966,7 +3974,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
         {ARB_CLIP_CONTROL,                 MAKEDWORD_VERSION(4, 5)},
         {ARB_CULL_DISTANCE,                MAKEDWORD_VERSION(4, 5)},
         {ARB_DERIVATIVE_CONTROL,           MAKEDWORD_VERSION(4, 5)},
-        {ARB_SHADER_TEXTURE_IMAGE_SAMPLES, MAKEDWORD_VERSION(4, 5)},
 
         {ARB_PIPELINE_STATISTICS_QUERY,    MAKEDWORD_VERSION(4, 6)},
         {ARB_TEXTURE_FILTER_ANISOTROPIC,   MAKEDWORD_VERSION(4, 6)},
@@ -4080,11 +4087,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
         gl_info->supported[WINED3D_GL_BLEND_EQUATION] = TRUE;
 
     if (gl_version >= MAKEDWORD_VERSION(2, 0))
-    {
         gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
-        /* We want to use the core APIs for two-sided stencil in GL 2.0. */
-        gl_info->supported[EXT_STENCIL_TWO_SIDE] = FALSE;
-    }
     if (gl_version >= MAKEDWORD_VERSION(3, 2))
         gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE;
 
@@ -5357,7 +5360,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
         case WINED3D_RTYPE_NONE:
             allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                     | WINED3DUSAGE_RENDERTARGET;
-            gl_type = WINED3D_GL_RES_TYPE_TEX_2D;
+            gl_type = WINED3D_GL_RES_TYPE_TEX_1D;
             gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
             break;
 
@@ -5366,7 +5369,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
                     | WINED3DUSAGE_SOFTWAREPROCESSING
                     | WINED3DUSAGE_TEXTURE
                     | WINED3DUSAGE_QUERY_FILTER
-                    | WINED3DUSAGE_QUERY_GENMIPMAP
                     | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
                     | WINED3DUSAGE_QUERY_SRGBREAD
                     | WINED3DUSAGE_QUERY_SRGBWRITE
@@ -5431,6 +5433,12 @@ 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;
@@ -5679,6 +5687,9 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
                                      WINED3DCAPS3_COPY_TO_VIDMEM                   |
                                      WINED3DCAPS3_COPY_TO_SYSTEMMEM;
 
+    caps->PresentationIntervals    = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
+                                     WINED3DPRESENT_INTERVAL_ONE;
+
     caps->CursorCaps               = WINED3DCURSORCAPS_COLOR            |
                                      WINED3DCURSORCAPS_LOWRES;
 
@@ -6608,16 +6619,28 @@ static DWORD get_max_gl_version(const struct wined3d_gl_info *gl_info, DWORD fla
 {
     const char *gl_vendor, *gl_renderer;
 
-    if (wined3d_settings.explicit_gl_version)
+    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 MAKEDWORD_VERSION(1, 0);
+        return wined3d_settings.max_gl_version;
 
-    return wined3d_settings.max_gl_version;
+    return MAKEDWORD_VERSION(4, 4);
+}
+
+static BOOL has_extension(const char *list, const char *ext)
+{
+    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;
 }
 
 static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags)
@@ -6678,6 +6701,17 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal,
     }
 
     max_gl_version = get_max_gl_version(gl_info, wined3d_creation_flags);
+
+    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);
+        }
+    }
+
     for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
     {
         if (supported_gl_versions[i] <= max_gl_version)
index 41bd1fd..4c879f9 100644 (file)
@@ -91,6 +91,7 @@ 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
@@ -804,12 +805,11 @@ static void append_transform_feedback_skip_components(const char **varyings,
     }
 }
 
-static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc,
+static void shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc,
         struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count,
         char *strings, unsigned int *strings_length, GLenum buffer_mode)
 {
     unsigned int i, buffer_idx, count, length, highest_output_slot, stride;
-    BOOL have_varyings_to_record = FALSE;
 
     count = length = 0;
     highest_output_slot = 0;
@@ -859,8 +859,6 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3
                 string_buffer_sprintf(buffer, "shader_in_out.reg%u", e->register_idx);
                 append_transform_feedback_varying(varyings, &count, &strings, &length, buffer);
             }
-
-            have_varyings_to_record = TRUE;
         }
 
         if (buffer_idx < so_desc->buffer_stride_count
@@ -885,12 +883,10 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3
         *varying_count = count;
     if (strings_length)
         *strings_length = length;
-
-    return have_varyings_to_record;
 }
 
 static void shader_glsl_init_transform_feedback(const struct wined3d_context *context,
-        struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader)
+        struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader)
 {
     const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc;
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -946,13 +942,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co
 
     buffer = string_buffer_get(&priv->string_buffers);
 
-    if (!shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode))
-    {
-        FIXME("No varyings to record, disabling transform feedback.\n");
-        shader->u.gs.so_desc.element_count = 0;
-        string_buffer_release(&priv->string_buffers, buffer);
-        return;
-    }
+    shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode);
 
     if (!(varyings = heap_calloc(count, sizeof(*varyings))))
     {
@@ -1470,7 +1460,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
     const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_priv *priv = shader_priv;
-    float position_fixup[4 * WINED3D_MAX_VIEWPORTS];
+    float position_fixup[4];
     float normal[3 * 3];
     DWORD update_mask;
 
@@ -1508,11 +1498,9 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
 
     if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP)
     {
-        unsigned int fixup_count = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ?
-                max(state->viewport_count, 1) : 1;
-        shader_get_position_fixup(context, state, fixup_count, position_fixup);
+        shader_get_position_fixup(context, state, position_fixup);
         if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY])
-            GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, fixup_count, position_fixup));
+            GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup));
         else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN])
             GL_EXTCALL(glUniform4fv(prog->ds.pos_fixup_location, 1, position_fixup));
         else
@@ -1969,11 +1957,6 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_
     }
 }
 
-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)
 {
     switch (primitive_type)
@@ -2956,10 +2939,6 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
                 sprintf(register_name, "vpc[%u]", reg->idx[0].offset);
             break;
 
-        case WINED3DSPR_SAMPLEMASK:
-            sprintf(register_name, "sample_mask");
-            break;
-
         default:
             FIXME("Unhandled register type %#x.\n", reg->type);
             sprintf(register_name, "unrecognized_register");
@@ -3264,6 +3243,7 @@ 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
@@ -3276,6 +3256,7 @@ 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))
     {
@@ -3287,7 +3268,30 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
         projected = FALSE;
 
-    if (needs_legacy_glsl_syntax(gl_info))
+    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 (shadow)
             base = "shadow";
@@ -3327,7 +3331,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 && !needs_legacy_glsl_syntax(gl_info);
+    sample_function->output_single_component = shadow && !legacy_syntax;
 }
 
 static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx,
@@ -3448,6 +3452,7 @@ 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;
@@ -3516,6 +3521,26 @@ 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)
@@ -3537,7 +3562,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
         shader_glsl_color_correction(ins, fixup);
 }
 
-static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOOL use_viewport_index)
+static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer)
 {
     /* Write the final position.
      *
@@ -3546,16 +3571,8 @@ static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOO
      * pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering
      * upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow
      * a MAD. */
-    if (use_viewport_index)
-    {
-        shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup[gl_ViewportIndex].y;\n");
-        shader_addline(buffer, "gl_Position.xy += pos_fixup[gl_ViewportIndex].zw * gl_Position.ww;\n");
-    }
-    else
-    {
-        shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
-        shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
-    }
+    shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
+    shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
 
     /* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix()
      * in utils.c
@@ -4881,11 +4898,10 @@ static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_emit(const struct wined3d_shader_instruction *ins)
 {
     unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset;
-    const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
 
     shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n");
     if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL])
-        shader_glsl_fixup_position(ins->ctx->buffer, reg_maps->viewport_array);
+        shader_glsl_fixup_position(ins->ctx->buffer);
 
     if (!stream)
         shader_addline(ins->ctx->buffer, "EmitVertex();\n");
@@ -5740,71 +5756,6 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
     shader_addline(buffer, ")%s);\n", dst_swizzle);
 }
 
-static void shader_glsl_sample_info(const struct wined3d_shader_instruction *ins)
-{
-    const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
-    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
-    struct wined3d_string_buffer *buffer = ins->ctx->buffer;
-    const struct wined3d_shader_dst_param *dst = ins->dst;
-    const struct wined3d_shader_src_param *src = ins->src;
-    enum wined3d_shader_resource_type resource_type;
-    enum wined3d_data_type dst_data_type;
-    unsigned int resource_idx, bind_idx;
-    char dst_swizzle[6];
-    DWORD write_mask;
-
-    dst_data_type = dst->reg.data_type;
-    if (ins->flags == WINED3DSI_SAMPLE_INFO_UINT)
-        dst_data_type = WINED3D_DATA_UINT;
-    else if (ins->flags)
-        FIXME("Unhandled flags %#x.\n", ins->flags);
-
-    write_mask = shader_glsl_append_dst_ext(buffer, ins, dst, dst_data_type);
-    shader_glsl_get_swizzle(src, FALSE, write_mask, dst_swizzle);
-
-    if (dst_data_type == WINED3D_DATA_UINT)
-        shader_addline(buffer, "uvec4(");
-    else
-        shader_addline(buffer, "vec4(");
-
-    if (src->reg.type == WINED3DSPR_RASTERIZER)
-    {
-        if (gl_info->supported[ARB_SAMPLE_SHADING])
-        {
-            shader_addline(buffer, "gl_NumSamples");
-        }
-        else
-        {
-            FIXME("OpenGL implementation does not support ARB_sample_shading.\n");
-            shader_addline(buffer, "1");
-        }
-    }
-    else
-    {
-        resource_idx = src->reg.idx[0].offset;
-        resource_type = reg_maps->resource_info[resource_idx].type;
-        if (resource_type >= ARRAY_SIZE(resource_type_info))
-        {
-            ERR("Unexpected resource type %#x.\n", resource_type);
-            return;
-        }
-        bind_idx = shader_glsl_find_sampler(&reg_maps->sampler_map, resource_idx, WINED3D_SAMPLER_DEFAULT);
-
-        if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES])
-        {
-            shader_addline(buffer, "textureSamples(%s_sampler%u)",
-                    shader_glsl_get_prefix(reg_maps->shader_version.type), bind_idx);
-        }
-        else
-        {
-            FIXME("textureSamples() is not supported.\n");
-            shader_addline(buffer, "1");
-        }
-    }
-
-    shader_addline(buffer, ", 0, 0, 0)%s);\n", dst_swizzle);
-}
-
 static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
@@ -6547,7 +6498,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
         semantic_idx = input->semantic_idx;
         shader_glsl_write_mask_to_str(input->mask, reg_mask);
 
-        if (args->vp_mode == WINED3D_VP_MODE_SHADER)
+        if (args->vp_mode == vertexshader)
         {
             if (input->sysval_semantic == WINED3D_SV_POSITION && !semantic_idx)
             {
@@ -6563,14 +6514,6 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
                 shader_addline(buffer, "ps_in[%u]%s = uintBitsToFloat(gl_FrontFacing ? 0xffffffffu : 0u);\n",
                         input->register_idx, reg_mask);
             }
-            else if (input->sysval_semantic == WINED3D_SV_SAMPLE_INDEX)
-            {
-                if (gl_info->supported[ARB_SAMPLE_SHADING])
-                    shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_SampleID);\n",
-                            input->register_idx, reg_mask);
-                else
-                    FIXME("ARB_sample_shading is not supported.\n");
-            }
             else if (input->sysval_semantic == WINED3D_SV_RENDER_TARGET_ARRAY_INDEX && !semantic_idx)
             {
                 if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT])
@@ -6579,14 +6522,6 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
                 else
                     FIXME("ARB_fragment_layer_viewport is not supported.\n");
             }
-            else if (input->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx)
-            {
-                if (gl_info->supported[ARB_VIEWPORT_ARRAY])
-                    shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_ViewportIndex);\n",
-                            input->register_idx, reg_mask);
-                else
-                    FIXME("ARB_viewport_array is not supported.\n");
-            }
             else
             {
                 if (input->sysval_semantic)
@@ -6602,7 +6537,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
             if (args->pointsprite)
                 shader_addline(buffer, "ps_in[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n",
                         shader->u.ps.input_reg_map[input->register_idx]);
-            else if (args->vp_mode == WINED3D_VP_MODE_NONE && args->texcoords_initialized & (1u << semantic_idx))
+            else if (args->vp_mode == pretransformed && args->texcoords_initialized & (1u << semantic_idx))
                 shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n",
                         shader->u.ps.input_reg_map[input->register_idx], reg_mask,
                         needs_legacy_glsl_syntax(gl_info)
@@ -6878,11 +6813,6 @@ 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_VIEWPORT_ARRAY_INDEX && !semantic_idx)
-        {
-            shader_addline(buffer, "gl_ViewportIndex = 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);
@@ -7307,8 +7237,6 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "#extension GL_ARB_shader_image_size : enable\n");
     if (gl_info->supported[ARB_SHADER_STORAGE_BUFFER_OBJECT])
         shader_addline(buffer, "#extension GL_ARB_shader_storage_buffer_object : enable\n");
-    if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES])
-        shader_addline(buffer, "#extension GL_ARB_shader_texture_image_samples : enable\n");
     if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK])
         shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n");
     if (gl_info->supported[ARB_SHADING_LANGUAGE_PACKING])
@@ -7321,8 +7249,6 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n");
     if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
         shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n");
-    if (gl_info->supported[ARB_VIEWPORT_ARRAY])
-        shader_addline(buffer, "#extension GL_ARB_viewport_array : enable\n");
     if (gl_info->supported[EXT_GPU_SHADER4])
         shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
@@ -7348,9 +7274,6 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in
         shader_glsl_generate_fog_code(buffer, gl_info, args->fog);
 
     shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1);
-
-    if (reg_maps->sample_mask)
-        shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n");
 }
 
 /* Context activation is done by the caller. */
@@ -7387,8 +7310,6 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
         shader_addline(buffer, "#extension GL_ARB_fragment_coord_conventions : enable\n");
     if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT])
         shader_addline(buffer, "#extension GL_ARB_fragment_layer_viewport : enable\n");
-    if (gl_info->supported[ARB_SAMPLE_SHADING])
-        shader_addline(buffer, "#extension GL_ARB_sample_shading : enable\n");
     if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
         shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
     /* The spec says that it doesn't have to be explicitly enabled, but the
@@ -7441,7 +7362,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
         shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts);
     }
 
-    if (version->major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER)
+    if (version->major < 3 || args->vp_mode != vertexshader)
     {
         shader_addline(buffer, "uniform struct\n{\n");
         shader_addline(buffer, "    vec4 color;\n");
@@ -7475,7 +7396,7 @@ 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 == WINED3D_VP_MODE_SHADER && reg_maps->input_registers)
+        if (args->vp_mode == vertexshader && reg_maps->input_registers)
             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);
@@ -7561,9 +7482,6 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
 
     shader_addline(buffer, "void main()\n{\n");
 
-    if (reg_maps->sample_mask)
-        shader_addline(buffer, "float sample_mask = uintBitsToFloat(0xffffffffu);\n");
-
     /* Direct3D applications expect integer vPos values, while OpenGL drivers
      * add approximately 0.5. This causes off-by-one problems as spotted by
      * the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly
@@ -7592,7 +7510,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
                     "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n");
     }
 
-    if (reg_maps->shader_version.major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER)
+    if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader)
     {
         unsigned int i;
         WORD map = reg_maps->texcoord;
@@ -7686,7 +7604,7 @@ static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_in
         shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n");
 
     if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
-        shader_glsl_fixup_position(buffer, FALSE);
+        shader_glsl_fixup_position(buffer);
 }
 
 /* Context activation is done by the caller. */
@@ -7924,7 +7842,7 @@ static void shader_glsl_generate_ds_epilogue(const struct wined3d_gl_info *gl_in
     shader_addline(buffer, "setup_ds_output(ds_out);\n");
 
     if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
-        shader_glsl_fixup_position(buffer, FALSE);
+        shader_glsl_fixup_position(buffer);
 }
 
 static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *context,
@@ -8028,11 +7946,7 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
     const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    const struct wined3d_shader_signature_element *output;
-    enum wined3d_primitive_type primitive_type;
     struct shader_glsl_ctx_priv priv_ctx;
-    unsigned int max_vertices;
-    unsigned int i, j;
     GLuint shader_id;
 
     memset(&priv_ctx, 0, sizeof(priv_ctx));
@@ -8044,42 +7958,16 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
 
     shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
 
-    primitive_type = shader->u.gs.input_type ? shader->u.gs.input_type : args->primitive_type;
-    shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(primitive_type));
+    shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(shader->u.gs.input_type));
     if (shader->u.gs.instance_count > 1)
         shader_addline(buffer, ", invocations = %u", shader->u.gs.instance_count);
     shader_addline(buffer, ") in;\n");
-
-    primitive_type = shader->u.gs.output_type ? shader->u.gs.output_type : args->primitive_type;
-    if (!(max_vertices = shader->u.gs.vertices_out))
-    {
-        switch (args->primitive_type)
-        {
-            case WINED3D_PT_POINTLIST:
-                max_vertices = 1;
-                break;
-            case WINED3D_PT_LINELIST:
-                max_vertices = 2;
-                break;
-            case WINED3D_PT_TRIANGLELIST:
-                max_vertices = 3;
-                break;
-            default:
-                FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(args->primitive_type));
-                break;
-        }
-    }
     shader_addline(buffer, "layout(%s, max_vertices = %u) out;\n",
-            glsl_primitive_type_from_d3d(primitive_type), max_vertices);
+            glsl_primitive_type_from_d3d(shader->u.gs.output_type), shader->u.gs.vertices_out);
     shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input);
 
     if (!gl_info->supported[ARB_CLIP_CONTROL])
-    {
-        shader_addline(buffer, "uniform vec4 pos_fixup");
-        if (reg_maps->viewport_array)
-            shader_addline(buffer, "[%u]", WINED3D_MAX_VIEWPORTS);
-        shader_addline(buffer, ";\n");
-    }
+        shader_addline(buffer, "uniform vec4 pos_fixup;\n");
 
     if (is_rasterization_disabled(shader))
     {
@@ -8090,29 +7978,9 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
         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 (shader->function)
-    {
-        if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
-            return 0;
-    }
-    else
-    {
-        for (i = 0; i < max_vertices; ++i)
-        {
-            for (j = 0; j < shader->output_signature.element_count; ++j)
-            {
-                output = &shader->output_signature.elements[j];
-                shader_addline(buffer, "gs_out[%u] = shader_in[%u].reg[%u];\n",
-                        output->register_idx, i, output->register_idx);
-            }
-            shader_addline(buffer, "setup_gs_output(gs_out);\n");
-            if (!gl_info->supported[ARB_CLIP_CONTROL])
-                shader_glsl_fixup_position(buffer, FALSE);
-            shader_addline(buffer, "EmitVertex();\n");
-        }
-    }
+    if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
+        return 0;
     shader_addline(buffer, "}\n");
 
     shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER));
@@ -9042,7 +8910,7 @@ static const char *shader_glsl_get_ffp_fragment_op_arg(struct wined3d_string_buf
 }
 
 static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color,
-        BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+        BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
 {
     const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
 
@@ -9053,7 +8921,10 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un
     else
         dstmask = ".w";
 
-    dstreg = tmp_dst ? "temp_reg" : "ret";
+    if (dst == tempreg)
+        dstreg = "temp_reg";
+    else
+        dstreg = "ret";
 
     arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, dw_arg0);
     arg1 = shader_glsl_get_ffp_fragment_op_arg(buffer, 1, stage, dw_arg1);
@@ -9223,7 +9094,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
             tfactor_used = TRUE;
         if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
             tempreg_used = TRUE;
-        if (settings->op[stage].tmp_dst)
+        if (settings->op[stage].dst == tempreg)
             tempreg_used = TRUE;
         if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT)
             tss_const_map |= 1u << stage;
@@ -9419,12 +9290,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
         if (!(tex_map & (1u << stage)))
             continue;
 
-        if (settings->op[stage].projected == WINED3D_PROJECTION_NONE)
+        if (settings->op[stage].projected == proj_none)
         {
             proj = FALSE;
         }
-        else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4
-                || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
+        else if (settings->op[stage].projected == proj_count4
+                || settings->op[stage].projected == proj_count3)
         {
             proj = TRUE;
         }
@@ -9507,12 +9378,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
             shader_addline(buffer, "ret.xy = bumpenv_mat%u * tex%u.xy;\n", stage - 1, stage - 1);
 
             /* With projective textures, texbem only divides the static
-             * texture coordinate, not the displacement, so multiply the
+             * texture coord, not the displacement, so multiply the
              * displacement with the dividing parameter before passing it to
              * TXP. */
-            if (settings->op[stage].projected != WINED3D_PROJECTION_NONE)
+            if (settings->op[stage].projected != proj_none)
             {
-                if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4)
+                if (settings->op[stage].projected == proj_count4)
                 {
                     shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].w) + ffp_texcoord[%u].xy;\n",
                             stage, stage);
@@ -9537,7 +9408,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
                 shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n",
                         stage, stage - 1, stage - 1, stage - 1);
         }
-        else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
+        else if (settings->op[stage].projected == proj_count3)
         {
             shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].xyz);\n",
                     stage, texture_function, stage, stage);
@@ -9589,23 +9460,23 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
 
         if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
         {
-            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
                     settings->op[stage].cop, settings->op[stage].carg0,
                     settings->op[stage].carg1, settings->op[stage].carg2);
         }
         else if (op_equal)
         {
-            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst,
+            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].dst,
                     settings->op[stage].cop, settings->op[stage].carg0,
                     settings->op[stage].carg1, settings->op[stage].carg2);
         }
         else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP
                 && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE)
         {
-            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
                     settings->op[stage].cop, settings->op[stage].carg0,
                     settings->op[stage].carg1, settings->op[stage].carg2);
-            shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst,
+            shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].dst,
                     settings->op[stage].aop, settings->op[stage].aarg0,
                     settings->op[stage].aarg1, settings->op[stage].aarg2);
         }
@@ -10905,7 +10776,6 @@ static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *g
             && gl_info->supported[ARB_SHADER_IMAGE_SIZE]
             && gl_info->supported[ARB_SHADING_LANGUAGE_PACKING]
             && gl_info->supported[ARB_TESSELLATION_SHADER]
-            && gl_info->supported[ARB_TEXTURE_COMPRESSION_BPTC]
             && gl_info->supported[ARB_TEXTURE_GATHER]
             && gl_info->supported[ARB_TRANSFORM_FEEDBACK3])
         return 5;
@@ -11163,7 +11033,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_SAMPLE_C                         */ shader_glsl_sample_c,
     /* WINED3DSIH_SAMPLE_C_LZ                      */ shader_glsl_sample_c,
     /* WINED3DSIH_SAMPLE_GRAD                      */ shader_glsl_sample,
-    /* WINED3DSIH_SAMPLE_INFO                      */ shader_glsl_sample_info,
+    /* WINED3DSIH_SAMPLE_INFO                      */ NULL,
     /* WINED3DSIH_SAMPLE_LOD                       */ shader_glsl_sample,
     /* WINED3DSIH_SAMPLE_POS                       */ NULL,
     /* WINED3DSIH_SETP                             */ NULL,
@@ -12108,854 +11978,3 @@ const struct fragment_pipeline glsl_fragment_pipe =
     shader_glsl_color_fixup_supported,
     glsl_fragment_pipe_state_template,
 };
-
-struct glsl_blitter_args
-{
-    GLenum texture_type;
-    struct color_fixup_desc fixup;
-    unsigned short padding;
-};
-
-struct glsl_blitter_program
-{
-    struct wine_rb_entry entry;
-    struct glsl_blitter_args args;
-    GLuint id;
-};
-
-struct wined3d_glsl_blitter
-{
-    struct wined3d_blitter blitter;
-    struct wined3d_string_buffer_list string_buffers;
-    struct wine_rb_tree programs;
-    GLuint palette_texture;
-};
-
-static int glsl_blitter_args_compare(const void *key, const struct wine_rb_entry *entry)
-{
-    const struct glsl_blitter_args *a = key;
-    const struct glsl_blitter_args *b = &WINE_RB_ENTRY_VALUE(entry, const struct glsl_blitter_program, entry)->args;
-
-    return memcmp(a, b, sizeof(*a));
-}
-
-/* Context activation is done by the caller. */
-static void glsl_free_blitter_program(struct wine_rb_entry *entry, void *ctx)
-{
-    struct glsl_blitter_program *program = WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry);
-    struct wined3d_context *context = ctx;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-
-    GL_EXTCALL(glDeleteProgram(program->id));
-    checkGLcall("glDeleteProgram()");
-    heap_free(program);
-}
-
-/* Context activation is done by the caller. */
-static void glsl_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_glsl_blitter *glsl_blitter;
-    struct wined3d_blitter *next;
-
-    if ((next = blitter->next))
-        next->ops->blitter_destroy(next, context);
-
-    glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter);
-
-    if (glsl_blitter->palette_texture)
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &glsl_blitter->palette_texture);
-
-    wine_rb_destroy(&glsl_blitter->programs, glsl_free_blitter_program, context);
-    string_buffer_list_cleanup(&glsl_blitter->string_buffers);
-
-    heap_free(glsl_blitter);
-}
-
-static void glsl_blitter_generate_p8_shader(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
-        const char *output, const char *tex_type, const char *swizzle)
-{
-    shader_addline(buffer, "uniform sampler1D sampler_palette;\n");
-    shader_addline(buffer, "\nvoid main()\n{\n");
-    /* The alpha-component contains the palette index. */
-    shader_addline(buffer, "    float index = texture%s(sampler, out_texcoord.%s).%c;\n",
-            needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle,
-            gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x');
-    /* Scale the index by 255/256 and add a bias of 0.5 in order to sample in
-     * the middle. */
-    shader_addline(buffer, "    index = (index * 255.0 + 0.5) / 256.0;\n");
-    shader_addline(buffer, "    %s = texture%s(sampler_palette, index);\n",
-            output, needs_legacy_glsl_syntax(gl_info) ? "1D" : "");
-    shader_addline(buffer, "}\n");
-}
-
-static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
-        const char *tex_type)
-{
-    enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
-    char chroma, luminance;
-    const char *tex;
-
-    /* The YUY2 and UYVY formats contain two pixels packed into a 32 bit
-     * macropixel, giving effectively 16 bits per pixel. The color consists of
-     * a luminance(Y) and two chroma(U and V) values. Each macropixel has two
-     * luminance values, one for each single pixel it contains, and one U and
-     * one V value shared between both pixels.
-     *
-     * The data is loaded into an A8L8 texture. With YUY2, the luminance
-     * component contains the luminance and alpha the chroma. With UYVY it is
-     * vice versa. Thus take the format into account when generating the read
-     * swizzles
-     *
-     * Reading the Y value is straightforward - just sample the texture. The
-     * hardware takes care of filtering in the horizontal and vertical
-     * direction.
-     *
-     * Reading the U and V values is harder. We have to avoid filtering
-     * horizontally, because that would mix the U and V values of one pixel or
-     * two adjacent pixels.  Thus floor the texture coordinate and add 0.5 to
-     * get an unfiltered read, regardless of the filtering setting. Vertical
-     * filtering works automatically though - the U and V values of two rows
-     * are mixed nicely.
-     *
-     * Apart of avoiding filtering issues, the code has to know which value it
-     * just read, and where it can find the other one. To determine this, it
-     * checks if it sampled an even or odd pixel, and shifts the 2nd read
-     * accordingly.
-     *
-     * Handling horizontal filtering of U and V values requires reading a 2nd
-     * pair of pixels, extracting U and V and mixing them. This is not
-     * implemented yet.
-     *
-     * An alternative implementation idea is to load the texture as A8R8G8B8
-     * texture, with width / 2. This way one read gives all 3 values, finding
-     * U and V is easy in an unfiltered situation. Finding the luminance on
-     * the other hand requires finding out if it is an odd or even pixel. The
-     * real drawback of this approach is filtering. This would have to be
-     * emulated completely in the shader, reading up two 2 packed pixels in up
-     * to 2 rows and interpolating both horizontally and vertically. Beyond
-     * that it would require adjustments to the texture handling code to deal
-     * with the width scaling. */
-
-    if (complex_fixup == COMPLEX_FIXUP_UYVY)
-    {
-        chroma = 'x';
-        luminance = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y';
-    }
-    else
-    {
-        chroma = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y';
-        luminance = 'x';
-    }
-
-    tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
-    /* First we have to read the chroma values. This means we need at least
-     * two pixels (no filtering), or 4 pixels (with filtering). To get the
-     * unmodified chroma, we have to rid ourselves of the filtering when we
-     * sample the texture. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* We must not allow filtering between pixel x and x+1, this would mix U
-     * and V. Vertical filtering is ok. However, bear in mind that the pixel
-     * center is at 0.5, so add 0.5. */
-    shader_addline(buffer, "    texcoord.x = (floor(texcoord.x * size.x) + 0.5) / size.x;\n");
-    shader_addline(buffer, "    luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma);
-
-    /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25
-     * and 0.75 for the even and odd pixels respectively. */
-    /* Put the value into either of the chroma values. */
-    shader_addline(buffer, "    bool even = fract(texcoord.x * size.x * 0.5) < 0.5;\n");
-    shader_addline(buffer, "    if (even)\n");
-    shader_addline(buffer, "        chroma.y = luminance;\n");
-    shader_addline(buffer, "    else\n");
-    shader_addline(buffer, "        chroma.x = luminance;\n");
-
-    /* Sample pixel 2. If we read an even pixel, sample the pixel right to the
-     * current one. Otherwise, sample the left pixel. */
-    shader_addline(buffer, "    texcoord.x += even ? 1.0 / size.x : -1.0 / size.x;\n");
-    shader_addline(buffer, "    luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma);
-
-    /* Put the value into the other chroma. */
-    shader_addline(buffer, "    if (even)\n");
-    shader_addline(buffer, "        chroma.x = luminance;\n");
-    shader_addline(buffer, "    else\n");
-    shader_addline(buffer, "        chroma.y = luminance;\n");
-
-    /* TODO: If filtering is enabled, sample a 2nd pair of pixels left or right of
-     * the current one and lerp the two U and V values. */
-
-    /* This gives the correctly filtered luminance value. */
-    shader_addline(buffer, "    luminance = texture%s(sampler, out_texcoord.xy).%c;\n", tex, luminance);
-}
-
-static void gen_yv12_read(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const char *tex_type)
-{
-    char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x';
-    const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
-    /* YV12 surfaces contain a WxH sized luminance plane, followed by a
-     * (W/2)x(H/2) V and a (W/2)x(H/2) U plane, each with 8 bit per pixel. So
-     * the effective bitdepth is 12 bits per pixel. Since the U and V planes
-     * have only half the pitch of the luminance plane, the packing into the
-     * gl texture is a bit unfortunate. If the whole texture is interpreted as
-     * luminance data it looks approximately like this:
-     *
-     *        +----------------------------------+----
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |   2
-     *        |            LUMINANCE             |   -
-     *        |                                  |   3
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        +----------------+-----------------+----
-     *        |                |                 |
-     *        |  V even rows   |  V odd rows     |
-     *        |                |                 |   1
-     *        +----------------+------------------   -
-     *        |                |                 |   3
-     *        |  U even rows   |  U odd rows     |
-     *        |                |                 |
-     *        +----------------+-----------------+----
-     *        |                |                 |
-     *        |     0.5        |       0.5       |
-     *
-     * So it appears as if there are 4 chroma images, but in fact the odd rows
-     * in the chroma images are in the same row as the even ones. So it is
-     * kinda tricky to read. */
-
-    /* First sample the chroma values. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* The chroma planes have only half the width. */
-    shader_addline(buffer, "    texcoord.x *= 0.5;\n");
-
-    /* The first value is between 2/3 and 5/6 of the texture's height, so
-     * scale+bias the coordinate. Also read the right side of the image when
-     * reading odd lines.
-     *
-     * Don't forget to clamp the y values in into the range, otherwise we'll
-     * get filtering bleeding. */
-
-    /* Read odd lines from the right side (add 0.5 to the x coordinate). */
-    shader_addline(buffer, "    if (fract(floor(texcoord.y * size.y) * 0.5 + 1.0 / 6.0) >= 0.5)\n");
-    shader_addline(buffer, "        texcoord.x += 0.5;\n");
-
-    /* Clamp, keep the half pixel origin in mind. */
-    shader_addline(buffer, "    texcoord.y = clamp(2.0 / 3.0 + texcoord.y / 6.0, "
-            "2.0 / 3.0 + 0.5 / size.y, 5.0 / 6.0 - 0.5 / size.y);\n");
-
-    shader_addline(buffer, "    chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
-    /* The other chroma value is 1/6th of the texture lower, from 5/6th to
-     * 6/6th No need to clamp because we're just reusing the already clamped
-     * value from above. */
-    shader_addline(buffer, "    texcoord.y += 1.0 / 6.0;\n");
-    shader_addline(buffer, "    chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
-    /* Sample the luminance value. It is in the top 2/3rd of the texture, so
-     * scale the y coordinate.  Clamp the y coordinate to prevent the chroma
-     * values from bleeding into the sampled luminance values due to
-     * filtering. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* Multiply the y coordinate by 2/3 and clamp it. */
-    shader_addline(buffer, "    texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n");
-    shader_addline(buffer, "    luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-}
-
-static void gen_nv12_read(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const char *tex_type)
-{
-    char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x';
-    const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
-    /* NV12 surfaces contain a WxH sized luminance plane, followed by a
-     * (W/2)x(H/2) sized plane where each component is an UV pair. So the
-     * effective bitdepth is 12 bits per pixel. If the whole texture is
-     * interpreted as luminance data it looks approximately like this:
-     *
-     *        +----------------------------------+----
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |   2
-     *        |            LUMINANCE             |   -
-     *        |                                  |   3
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        +----------------------------------+----
-     *        |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV|
-     *        |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV|
-     *        |                                  |   1
-     *        |                                  |   -
-     *        |                                  |   3
-     *        |                                  |
-     *        |                                  |
-     *        +----------------------------------+---- */
-
-    /* First sample the chroma values. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* We only have half the number of chroma pixels. */
-    shader_addline(buffer, "    texcoord.x *= 0.5;\n");
-    shader_addline(buffer, "    texcoord.y = (texcoord.y + 2.0) / 3.0;\n");
-
-    /* We must not allow filtering horizontally, this would mix U and V.
-     * Vertical filtering is ok. However, bear in mind that the pixel center
-     * is at 0.5, so add 0.5. */
-
-    /* Convert to non-normalised coordinates so we can find the individual
-     * pixel. */
-    shader_addline(buffer, "    texcoord.x = floor(texcoord.x * size.x);\n");
-    /* Multiply by 2 since chroma components are stored in UV pixel pairs, add
-     * 0.5 to hit the center of the pixel. Then convert back to normalised
-     * coordinates. */
-    shader_addline(buffer, "    texcoord.x = (texcoord.x * 2.0 + 0.5) / size.x;\n");
-    /* Clamp, keep the half pixel origin in mind. */
-    shader_addline(buffer, "    texcoord.y = max(texcoord.y, 2.0 / 3.0 + 0.5 / size.y);\n");
-
-    shader_addline(buffer, "    chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-    /* Add 1.0 / size.x to sample the adjacent texel. */
-    shader_addline(buffer, "    texcoord.x += 1.0 / size.x;\n");
-    shader_addline(buffer, "    chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
-    /* Sample the luminance value. It is in the top 2/3rd of the texture, so
-     * scale the y coordinate. Clamp the y coordinate to prevent the chroma
-     * values from bleeding into the sampled luminance values due to
-     * filtering. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* Multiply the y coordinate by 2/3 and clamp it. */
-    shader_addline(buffer, "    texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n");
-    shader_addline(buffer, "    luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-}
-
-static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
-        const char *output, const char *tex_type, const char *swizzle)
-{
-    enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
-
-    shader_addline(buffer, "const vec4 yuv_coef = vec4(1.403, -0.344, -0.714, 1.770);\n");
-    shader_addline(buffer, "float luminance;\n");
-    shader_addline(buffer, "vec2 texcoord;\n");
-    shader_addline(buffer, "vec2 chroma;\n");
-    shader_addline(buffer, "uniform vec2 size;\n");
-
-    shader_addline(buffer, "\nvoid main()\n{\n");
-
-    switch (complex_fixup)
-    {
-        case COMPLEX_FIXUP_UYVY:
-        case COMPLEX_FIXUP_YUY2:
-            gen_packed_yuv_read(buffer, gl_info, args, tex_type);
-            break;
-
-        case COMPLEX_FIXUP_YV12:
-            gen_yv12_read(buffer, gl_info, tex_type);
-            break;
-
-        case COMPLEX_FIXUP_NV12:
-            gen_nv12_read(buffer, gl_info, tex_type);
-            break;
-
-        default:
-            FIXME("Unsupported fixup %#x.\n", complex_fixup);
-            string_buffer_free(buffer);
-            return;
-    }
-
-    /* Calculate the final result. Formula is taken from
-     * http://www.fourcc.org/fccyvrgb.php. Note that the chroma
-     * ranges from -0.5 to 0.5. */
-    shader_addline(buffer, "\n    chroma.xy -= 0.5;\n");
-
-    shader_addline(buffer, "    %s.x = luminance + chroma.x * yuv_coef.x;\n", output);
-    shader_addline(buffer, "    %s.y = luminance + chroma.y * yuv_coef.y + chroma.x * yuv_coef.z;\n", output);
-    shader_addline(buffer, "    %s.z =&nbs