[D3D8][D3D9][DDRAW][WINED3D] Sync with Wine Staging 1.7.37. CORE-9246
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 28 Feb 2015 10:18:41 +0000 (10:18 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 28 Feb 2015 10:18:41 +0000 (10:18 +0000)
svn path=/trunk/; revision=66488

46 files changed:
reactos/dll/directx/wine/d3d8/device.c
reactos/dll/directx/wine/d3d8/directx.c
reactos/dll/directx/wine/d3d8/shader.c
reactos/dll/directx/wine/d3d8/texture.c
reactos/dll/directx/wine/d3d9/device.c
reactos/dll/directx/wine/d3d9/directx.c
reactos/dll/directx/wine/d3d9/shader.c
reactos/dll/directx/wine/d3d9/surface.c
reactos/dll/directx/wine/d3d9/texture.c
reactos/dll/directx/wine/ddraw/ddraw.c
reactos/dll/directx/wine/ddraw/ddraw_private.h
reactos/dll/directx/wine/ddraw/executebuffer.c
reactos/dll/directx/wine/ddraw/main.c
reactos/dll/directx/wine/ddraw/surface.c
reactos/dll/directx/wine/wined3d/CMakeLists.txt
reactos/dll/directx/wine/wined3d/arb_program_shader.c
reactos/dll/directx/wine/wined3d/buffer.c
reactos/dll/directx/wine/wined3d/context.c
reactos/dll/directx/wine/wined3d/cs.c
reactos/dll/directx/wine/wined3d/device.c
reactos/dll/directx/wine/wined3d/directx.c
reactos/dll/directx/wine/wined3d/drawprim.c
reactos/dll/directx/wine/wined3d/dxtn.c [new file with mode: 0644]
reactos/dll/directx/wine/wined3d/gl_compat.c
reactos/dll/directx/wine/wined3d/glsl_shader.c
reactos/dll/directx/wine/wined3d/query.c
reactos/dll/directx/wine/wined3d/resource.c
reactos/dll/directx/wine/wined3d/sampler.c
reactos/dll/directx/wine/wined3d/shader.c
reactos/dll/directx/wine/wined3d/shader_sm1.c
reactos/dll/directx/wine/wined3d/shader_sm4.c
reactos/dll/directx/wine/wined3d/state.c
reactos/dll/directx/wine/wined3d/stateblock.c
reactos/dll/directx/wine/wined3d/surface.c
reactos/dll/directx/wine/wined3d/swapchain.c
reactos/dll/directx/wine/wined3d/texture.c
reactos/dll/directx/wine/wined3d/utils.c
reactos/dll/directx/wine/wined3d/vertexdeclaration.c
reactos/dll/directx/wine/wined3d/view.c
reactos/dll/directx/wine/wined3d/volume.c
reactos/dll/directx/wine/wined3d/wined3d.spec
reactos/dll/directx/wine/wined3d/wined3d_gl.h
reactos/dll/directx/wine/wined3d/wined3d_main.c
reactos/dll/directx/wine/wined3d/wined3d_private.h
reactos/include/reactos/wine/wined3d.h
reactos/media/doc/README.WINE

index 7516764..22c6d1e 100644 (file)
@@ -542,16 +542,42 @@ 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;
+    UINT i, count;
+    HRESULT hr;
 
     TRACE("iface %p, present_parameters %p, swapchain %p.\n",
             iface, present_parameters, swapchain);
 
+    if (!present_parameters->Windowed)
+    {
+        WARN("Trying to create an additional fullscreen swapchain, returning D3DERR_INVALIDCALL.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
+    wined3d_mutex_lock();
+    count = wined3d_device_get_swapchain_count(device->wined3d_device);
+    for (i = 0; i < count; ++i)
+    {
+        struct wined3d_swapchain *wined3d_swapchain;
+
+        wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i);
+        wined3d_swapchain_get_desc(wined3d_swapchain, &desc);
+
+        if (!desc.windowed)
+        {
+            wined3d_mutex_unlock();
+            WARN("Trying to create an additional swapchain in fullscreen mode, returning D3DERR_INVALIDCALL.\n");
+            return D3DERR_INVALIDCALL;
+        }
+    }
+    wined3d_mutex_unlock();
+
     wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
-    if (SUCCEEDED(d3d8_swapchain_create(device, &desc, &object)))
+    if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object)))
         *swapchain = &object->IDirect3DSwapChain8_iface;
     present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
 
-    return D3D_OK;
+    return hr;
 }
 
 static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
@@ -606,6 +632,12 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface,
 
     TRACE("iface %p, present_parameters %p.\n", iface, present_parameters);
 
+    if (device->device_state == D3D8_DEVICE_STATE_LOST)
+    {
+        WARN("App not active, returning D3DERR_DEVICELOST.\n");
+        return D3DERR_DEVICELOST;
+    }
+
     wined3d_mutex_lock();
 
     if (device->vertex_buffer)
@@ -894,7 +926,7 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width
     wined3d_mutex_lock();
 
     if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc,
-            1, flags, NULL, &d3d8_null_wined3d_parent_ops, &texture)))
+            1, flags, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture)))
     {
         wined3d_mutex_unlock();
         WARN("Failed to create texture, hr %#x.\n", hr);
@@ -972,7 +1004,6 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
     struct wined3d_resource_desc wined3d_desc;
     struct wined3d_resource *wined3d_resource;
     UINT src_w, src_h;
-    HRESULT hr;
 
     TRACE("iface %p, src_surface %p, src_rects %p, rect_count %u, dst_surface %p, dst_points %p.\n",
             iface, src_surface, src_rects, rect_count, dst_surface, dst_points);
@@ -1004,24 +1035,13 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
     dst_format = wined3d_desc.format;
 
     /* Check that the source and destination formats match */
-    if (src_format != dst_format && WINED3DFMT_UNKNOWN != dst_format)
+    if (src_format != dst_format)
     {
         WARN("Source %p format must match the destination %p format, returning D3DERR_INVALIDCALL.\n",
                 src_surface, dst_surface);
         wined3d_mutex_unlock();
         return D3DERR_INVALIDCALL;
     }
-    else if (WINED3DFMT_UNKNOWN == dst_format)
-    {
-        TRACE("Converting destination surface from WINED3DFMT_UNKNOWN to the source format.\n");
-        if (FAILED(hr = wined3d_surface_update_desc(dst->wined3d_surface, wined3d_desc.width, wined3d_desc.height,
-                src_format, wined3d_desc.multisample_type, wined3d_desc.multisample_quality, NULL, 0)))
-        {
-            WARN("Failed to update surface desc, hr %#x.\n", hr);
-            wined3d_mutex_unlock();
-            return hr;
-        }
-    }
 
     /* Quick if complete copy ... */
     if (!rect_count && !src_rects && !dst_points)
@@ -2977,7 +2997,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
     texture_desc = *desc;
     texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
     if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1,
-            WINED3D_SURFACE_MAPPABLE, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture)))
+            WINED3D_SURFACE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture)))
     {
         WARN("Failed to create texture, hr %#x.\n", hr);
         return hr;
index 10b4ea0..57e0076 100644 (file)
@@ -389,7 +389,7 @@ static const struct IDirect3D8Vtbl d3d8_vtbl =
 
 BOOL d3d8_init(struct d3d8 *d3d8)
 {
-    DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING;
+    DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING | WINED3D_HANDLE_RESTORE;
 
     d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
     d3d8->refcount = 1;
index 7453e01..1b56899 100644 (file)
@@ -108,11 +108,19 @@ HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_d
 
     if (byte_code)
     {
-        if (usage) FIXME("Usage %#x not implemented.\n", usage);
+        struct wined3d_shader_desc desc;
+
+        if (usage)
+            FIXME("Usage %#x not implemented.\n", usage);
+
+        desc.byte_code = byte_code;
+        desc.input_signature = NULL;
+        desc.output_signature = NULL;
+        desc.max_version = 1;
 
         wined3d_mutex_lock();
-        hr = wined3d_shader_create_vs(device->wined3d_device, byte_code, NULL /* output signature */,
-                shader, &d3d8_vertexshader_wined3d_parent_ops, &shader->wined3d_shader, 1);
+        hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
+                &d3d8_vertexshader_wined3d_parent_ops, &shader->wined3d_shader);
         wined3d_mutex_unlock();
         if (FAILED(hr))
         {
@@ -149,13 +157,19 @@ static const struct wined3d_parent_ops d3d8_pixelshader_wined3d_parent_ops =
 HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_device *device,
         const DWORD *byte_code, DWORD shader_handle)
 {
+    struct wined3d_shader_desc desc;
     HRESULT hr;
 
     shader->handle = shader_handle;
 
+    desc.byte_code = byte_code;
+    desc.input_signature = NULL;
+    desc.output_signature = NULL;
+    desc.max_version = 1;
+
     wined3d_mutex_lock();
-    hr = wined3d_shader_create_ps(device->wined3d_device, byte_code, NULL, shader,
-            &d3d8_pixelshader_wined3d_parent_ops, &shader->wined3d_shader, 1);
+    hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
+            &d3d8_pixelshader_wined3d_parent_ops, &shader->wined3d_shader);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
index 76c18cf..da7d494 100644 (file)
@@ -1169,9 +1169,12 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
         surface_flags |= WINED3D_SURFACE_MAPPABLE;
 
+    if (!levels)
+        levels = wined3d_log2i(max(width, height)) + 1;
+
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
-            texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
+            NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -1211,9 +1214,12 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic
     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
         surface_flags |= WINED3D_SURFACE_MAPPABLE;
 
+    if (!levels)
+        levels = wined3d_log2i(edge_length) + 1;
+
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
-            texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
+            NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -1249,9 +1255,12 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev
     desc.depth = depth;
     desc.size = 0;
 
+    if (!levels)
+        levels = wined3d_log2i(max(max(width, height), depth)) + 1;
+
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0,
-            texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
+            NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
index ff430d5..4a82ca4 100644 (file)
@@ -500,11 +500,36 @@ 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;
+    UINT i, count;
     HRESULT hr;
 
     TRACE("iface %p, present_parameters %p, swapchain %p.\n",
             iface, present_parameters, swapchain);
 
+    if (!present_parameters->Windowed)
+    {
+        WARN("Trying to create an additional fullscreen swapchain, returning D3DERR_INVALIDCALL.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
+    wined3d_mutex_lock();
+    count = wined3d_device_get_swapchain_count(device->wined3d_device);
+    for (i = 0; i < count; ++i)
+    {
+        struct wined3d_swapchain *wined3d_swapchain;
+
+        wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i);
+        wined3d_swapchain_get_desc(wined3d_swapchain, &desc);
+
+        if (!desc.windowed)
+        {
+            wined3d_mutex_unlock();
+            WARN("Trying to create an additional swapchain in fullscreen mode, returning D3DERR_INVALIDCALL.\n");
+            return D3DERR_INVALIDCALL;
+        }
+    }
+    wined3d_mutex_unlock();
+
     wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
     if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object)))
         *swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface;
@@ -607,6 +632,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Reset(IDirect3DDevice9Ex *if
 
     TRACE("iface %p, present_parameters %p.\n", iface, present_parameters);
 
+    if (!device->d3d_parent->extended && device->device_state == D3D9_DEVICE_STATE_LOST)
+    {
+        WARN("App not active, returning D3DERR_DEVICELOST.\n");
+        return D3DERR_DEVICELOST;
+    }
+
     wined3d_mutex_lock();
 
     if (device->vertex_buffer)
@@ -784,16 +815,9 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface,
     }
 
     if (set_mem)
-    {
-        struct wined3d_resource *resource;
-        struct d3d9_surface *surface;
-
-        resource = wined3d_texture_get_sub_resource(object->wined3d_texture, 0);
-        surface = wined3d_resource_get_parent(resource);
-        wined3d_surface_update_desc(surface->wined3d_surface, width, height,
+        wined3d_texture_update_desc(object->wined3d_texture, width, height,
                 wined3dformat_from_d3dformat(format), WINED3D_MULTISAMPLE_NONE, 0,
                 *shared_handle, 0);
-    }
 
     TRACE("Created texture %p.\n", object);
     *texture = (IDirect3DTexture9 *)&object->IDirect3DBaseTexture9_iface;
@@ -1014,7 +1038,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
     wined3d_mutex_lock();
 
     if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc,
-            1, flags, NULL, &d3d9_null_wined3d_parent_ops, &texture)))
+            1, flags, NULL, NULL, &d3d9_null_wined3d_parent_ops, &texture)))
     {
         wined3d_mutex_unlock();
         WARN("Failed to create texture, hr %#x.\n", hr);
@@ -1026,12 +1050,13 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
     surface_impl->parent_device = &device->IDirect3DDevice9Ex_iface;
     *surface = &surface_impl->IDirect3DSurface9_iface;
     IDirect3DSurface9_AddRef(*surface);
-    wined3d_texture_decref(texture);
 
     if (user_mem)
-        wined3d_surface_update_desc(surface_impl->wined3d_surface, width, height,
+        wined3d_texture_update_desc(texture, width, height,
                 desc.format, multisample_type, multisample_quality, user_mem, 0);
 
+    wined3d_texture_decref(texture);
+
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -3519,7 +3544,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
     texture_desc = *desc;
     texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
     if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1,
-            WINED3D_SURFACE_MAPPABLE, container_parent, &d3d9_null_wined3d_parent_ops, &texture)))
+            WINED3D_SURFACE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, &texture)))
     {
         WARN("Failed to create texture, hr %#x.\n", hr);
         return hr;
index 6b68838..957b520 100644 (file)
@@ -633,10 +633,13 @@ static const struct IDirect3D9ExVtbl d3d9_vtbl =
 
 BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
 {
-    DWORD flags = WINED3D_PRESENT_CONVERSION;
+    DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE;
 
     if (!extended)
         flags |= WINED3D_VIDMEM_ACCOUNTING;
+    else
+        flags |= WINED3D_RESTORE_MODE_ON_ACTIVATE;
+
     d3d9->IDirect3D9Ex_iface.lpVtbl = &d3d9_vtbl;
     d3d9->refcount = 1;
 
index 94ec829..59ccd2d 100644 (file)
@@ -133,14 +133,20 @@ static const struct wined3d_parent_ops d3d9_vertexshader_wined3d_parent_ops =
 
 HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device *device, const DWORD *byte_code)
 {
+    struct wined3d_shader_desc desc;
     HRESULT hr;
 
     shader->refcount = 1;
     shader->IDirect3DVertexShader9_iface.lpVtbl = &d3d9_vertexshader_vtbl;
 
+    desc.byte_code = byte_code;
+    desc.input_signature = NULL;
+    desc.output_signature = NULL;
+    desc.max_version = 3;
+
     wined3d_mutex_lock();
-    hr = wined3d_shader_create_vs(device->wined3d_device, byte_code, NULL,
-            shader, &d3d9_vertexshader_wined3d_parent_ops, &shader->wined3d_shader, 3);
+    hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
+            &d3d9_vertexshader_wined3d_parent_ops, &shader->wined3d_shader);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -158,7 +164,8 @@ struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVerte
 {
     if (!iface)
         return NULL;
-    assert(iface->lpVtbl == &d3d9_vertexshader_vtbl);
+    if (iface->lpVtbl != &d3d9_vertexshader_vtbl)
+        WARN("Vertex shader %p with the wrong vtbl %p\n", iface, iface->lpVtbl);
 
     return impl_from_IDirect3DVertexShader9(iface);
 }
@@ -277,14 +284,20 @@ static const struct wined3d_parent_ops d3d9_pixelshader_wined3d_parent_ops =
 
 HRESULT pixelshader_init(struct d3d9_pixelshader *shader, struct d3d9_device *device, const DWORD *byte_code)
 {
+    struct wined3d_shader_desc desc;
     HRESULT hr;
 
     shader->refcount = 1;
     shader->IDirect3DPixelShader9_iface.lpVtbl = &d3d9_pixelshader_vtbl;
 
+    desc.byte_code = byte_code;
+    desc.input_signature = NULL;
+    desc.output_signature = NULL;
+    desc.max_version = 3;
+
     wined3d_mutex_lock();
-    hr = wined3d_shader_create_ps(device->wined3d_device, byte_code, NULL, shader,
-            &d3d9_pixelshader_wined3d_parent_ops, &shader->wined3d_shader, 3);
+    hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
+            &d3d9_pixelshader_wined3d_parent_ops, &shader->wined3d_shader);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -302,7 +315,8 @@ struct d3d9_pixelshader *unsafe_impl_from_IDirect3DPixelShader9(IDirect3DPixelSh
 {
     if (!iface)
         return NULL;
-    assert(iface->lpVtbl == &d3d9_pixelshader_vtbl);
+    if (iface->lpVtbl != &d3d9_pixelshader_vtbl)
+        WARN("Pixel shader %p with the wrong vtbl %p\n", iface, iface->lpVtbl);
 
     return impl_from_IDirect3DPixelShader9(iface);
 }
index 4a563d3..df11181 100644 (file)
@@ -88,6 +88,12 @@ static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface)
         return IDirect3DBaseTexture9_Release(&surface->texture->IDirect3DBaseTexture9_iface);
     }
 
+    if (!surface->resource.refcount)
+    {
+        ERR("Surface doesn't have any references.\n");
+        return 0;
+    }
+
     refcount = InterlockedDecrement(&surface->resource.refcount);
     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
 
index 182f53c..4072748 100644 (file)
@@ -1293,9 +1293,17 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
         surface_flags |= WINED3D_SURFACE_MAPPABLE;
 
+    if (!levels)
+    {
+        if (usage & D3DUSAGE_AUTOGENMIPMAP)
+            levels = 1;
+        else
+            levels = wined3d_log2i(max(width, height)) + 1;
+    }
+
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
-            texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
+            NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -1335,9 +1343,17 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
         surface_flags |= WINED3D_SURFACE_MAPPABLE;
 
+    if (!levels)
+    {
+        if (usage & D3DUSAGE_AUTOGENMIPMAP)
+            levels = 1;
+        else
+            levels = wined3d_log2i(edge_length) + 1;
+    }
+
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
-            texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
+            NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -1373,9 +1389,17 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
     desc.depth = depth;
     desc.size = 0;
 
+    if (!levels)
+    {
+        if (usage & D3DUSAGE_AUTOGENMIPMAP)
+            levels = 1;
+        else
+            levels = wined3d_log2i(max(max(width, height), depth)) + 1;
+    }
+
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0,
-            texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
+            NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
index 44e535d..8824c56 100644 (file)
@@ -23,9 +23,7 @@
 
 #include "ddraw_private.h"
 
-static struct wined3d_display_mode original_mode;
 static const struct ddraw *exclusive_ddraw;
-static BOOL restore_mode;
 
 /* Device identifier. Don't relay it to WineD3D */
 static const DDDEVICEIDENTIFIER2 deviceidentifier =
@@ -679,11 +677,8 @@ static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface)
         return DDERR_NOEXCLUSIVEMODE;
     }
 
-    if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &original_mode)))
-    {
+    if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, NULL)))
         ddraw->flags &= ~DDRAW_RESTORE_MODE;
-        restore_mode = FALSE;
-    }
 
     wined3d_mutex_unlock();
 
@@ -1092,10 +1087,6 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW
         return DD_OK;
     }
 
-    if (!restore_mode && FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d,
-            WINED3DADAPTER_DEFAULT, &original_mode, NULL)))
-        ERR("Failed to get current display mode, hr %#x.\n", hr);
-
     switch (bpp)
     {
         case 8:  format = WINED3DFMT_P8_UINT;        break;
@@ -1116,10 +1107,7 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW
      * can't be changed if a surface is locked or some drawing is in progress. */
     /* TODO: Lose the primary surface. */
     if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
-    {
         ddraw->flags |= DDRAW_RESTORE_MODE;
-        restore_mode = TRUE;
-    }
 
     wined3d_mutex_unlock();
 
@@ -4721,7 +4709,6 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
 {
     struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
     struct ddraw_surface *ddraw_surface;
-    HRESULT hr;
 
     TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
             device_parent, container_parent, surface, parent, parent_ops);
@@ -4741,13 +4728,7 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
         return DDERR_OUTOFVIDEOMEMORY;
     }
 
-    if (FAILED(hr = ddraw_surface_init(ddraw_surface, ddraw, container_parent, surface, parent_ops)))
-    {
-        WARN("Failed to initialize surface, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, ddraw_surface);
-        return hr;
-    }
-
+    ddraw_surface_init(ddraw_surface, ddraw, container_parent, surface, parent_ops);
     *parent = ddraw_surface;
     list_add_head(&ddraw->surface_list, &ddraw_surface->surface_list_entry);
 
@@ -4800,7 +4781,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
     texture_desc = *desc;
     texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
     if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &texture_desc, 1,
-            WINED3D_SURFACE_MAPPABLE, ddraw, &ddraw_frontbuffer_parent_ops, &texture)))
+            WINED3D_SURFACE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, &texture)))
     {
         WARN("Failed to create texture, hr %#x.\n", hr);
         return hr;
@@ -4864,7 +4845,8 @@ HRESULT ddraw_init(struct ddraw *ddraw, enum wined3d_device_type device_type)
     ddraw->numIfaces = 1;
     ddraw->ref7 = 1;
 
-    flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING;
+    flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
+            | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES;
     if (!(ddraw->wined3d = wined3d_create(flags)))
     {
         if (!(ddraw->wined3d = wined3d_create(flags | WINED3D_NO3D)))
index 1ad8c2c..9b73e65 100644 (file)
@@ -213,7 +213,7 @@ struct ddraw_texture
 HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc,
         struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) DECLSPEC_HIDDEN;
 struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface) DECLSPEC_HIDDEN;
-HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
+void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
         struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
 ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN;
 HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
index c645aed..028b4bd 100644 (file)
@@ -144,9 +144,10 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
                     buffer->indices[(i * 3) + 2] = ci->u3.v3;
                     instr += size;
                 }
-                IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface,
-                        D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, tl_vx, buffer->nb_vertices,
-                        buffer->indices, count * 3, 0);
+                if (count)
+                    IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface,
+                            D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, tl_vx, buffer->nb_vertices,
+                            buffer->indices, count * 3, 0);
            } break;
 
            case D3DOP_MATRIXLOAD:
index bac39e8..55b9282 100644 (file)
@@ -424,7 +424,7 @@ HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA callback, void *contex
         cont_enum = callback(NULL, driver_desc, driver_name, context, 0);
 
         /* The Battle.net System Checker expects both a NULL device and a GUID-based device */
-        if (cont_enum && (flags & ~DDENUM_ATTACHEDSECONDARYDEVICES))
+        if (cont_enum && (flags & DDENUM_ATTACHEDSECONDARYDEVICES))
             ddraw_enumerate_secondary_devices(wined3d, callback, context);
     }
     __EXCEPT_PAGE_FAULT
index 49db2aa..60639d2 100644 (file)
@@ -4461,7 +4461,7 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface,
         format_id = wined3dformat_from_ddrawformat(&This->surface_desc.u4.ddpfPixelFormat);
     }
 
-    if (FAILED(hr = wined3d_surface_update_desc(This->wined3d_surface, width, height,
+    if (FAILED(hr = wined3d_texture_update_desc(This->wined3d_texture, width, height,
             format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch)))
     {
         WARN("Failed to update surface desc, hr %#x.\n", hr);
@@ -5600,6 +5600,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
     DDSURFACEDESC2 *desc, *mip_desc;
     struct ddraw_texture *texture;
     UINT layers, levels, i, j;
+    unsigned int pitch = 0;
     HRESULT hr;
 
     TRACE("ddraw %p, surface_desc %p, surface %p, outer_unknown %p, version %u.\n",
@@ -5811,14 +5812,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             {
                 /* Undocumented feature: Create sublevels until either the
                  * width or the height is 1. */
-                DWORD min = desc->dwWidth < desc->dwHeight ? desc->dwWidth : desc->dwHeight;
-
-                desc->u2.dwMipMapCount = 0;
-                while (min)
-                {
-                    ++desc->u2.dwMipMapCount;
-                    min >>= 1;
-                }
+                desc->u2.dwMipMapCount = wined3d_log2i(min(desc->dwWidth, desc->dwHeight)) + 1;
             }
         }
         else
@@ -5938,6 +5932,15 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
                 HeapFree(GetProcessHeap(), 0, texture);
                 return DDERR_INVALIDPARAMS;
             }
+
+            if ((desc->dwFlags & DDSD_LINEARSIZE)
+                    && desc->u1.dwLinearSize < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
+                            wined3d_desc.format, wined3d_desc.width) * ((desc->dwHeight + 3) / 4))
+            {
+                WARN("Invalid linear size %u specified.\n", desc->u1.dwLinearSize);
+                HeapFree(GetProcessHeap(), 0, texture);
+                return DDERR_INVALIDPARAMS;
+            }
         }
         else
         {
@@ -5947,6 +5950,16 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
                 HeapFree(GetProcessHeap(), 0, texture);
                 return DDERR_INVALIDPARAMS;
             }
+
+            if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
+                    wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
+            {
+                WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
+                HeapFree(GetProcessHeap(), 0, texture);
+                return DDERR_INVALIDPARAMS;
+            }
+
+            pitch = desc->u1.lPitch;
         }
     }
 
@@ -5974,7 +5987,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
      * Commandos: Behind Enemy Lines is another. We set
      * WINED3D_SURFACE_PIN_SYSMEM because of this. */
     if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, levels,
-            WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
+            WINED3D_SURFACE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
     {
         WARN("Failed to create wined3d texture, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, texture);
@@ -6051,6 +6064,14 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
         }
     }
 
+    if ((desc->dwFlags & DDSD_LPSURFACE) && FAILED(hr = wined3d_texture_update_desc(wined3d_texture,
+            wined3d_desc.width, wined3d_desc.height, wined3d_desc.format,
+            WINED3D_MULTISAMPLE_NONE, 0, desc->lpSurface, pitch)))
+    {
+        ERR("Failed to set surface memory, hr %#x.\n", hr);
+        goto fail;
+    }
+
     if (desc->dwFlags & DDSD_BACKBUFFERCOUNT)
     {
         unsigned int count = desc->u5.dwBackBufferCount;
@@ -6078,7 +6099,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             desc->u5.dwBackBufferCount = 0;
 
             if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1,
-                    WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
+                    WINED3D_SURFACE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
             {
                 HeapFree(GetProcessHeap(), 0, texture);
                 hr = hr_ddraw_from_wined3d(hr);
@@ -6126,13 +6147,12 @@ fail:
     return hr;
 }
 
-HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
+void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
         struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
 {
     DDSURFACEDESC2 *desc = &surface->surface_desc;
     struct wined3d_resource_desc wined3d_desc;
     unsigned int version = texture->version;
-    HRESULT hr;
 
     surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl;
     surface->IDirectDrawSurface4_iface.lpVtbl = &ddraw_surface4_vtbl;
@@ -6171,60 +6191,18 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, s
     if (format_is_compressed(&desc->u4.ddpfPixelFormat))
     {
         if (desc->dwFlags & DDSD_LPSURFACE)
-        {
-            if ((desc->dwFlags & DDSD_LINEARSIZE)
-                    && desc->u1.dwLinearSize < wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4))
-            {
-                WARN("Invalid linear size %u specified.\n", desc->u1.dwLinearSize);
-                return DDERR_INVALIDPARAMS;
-            }
-
-            if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
-                    wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
-                    desc->lpSurface, 0)))
-            {
-                ERR("Failed to set surface memory, hr %#x.\n", hr);
-                return hr;
-            }
-
-            desc->dwFlags |= DDSD_LINEARSIZE;
-            desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_PITCH);
             desc->u1.dwLinearSize = ~0u;
-        }
         else
-        {
-            desc->dwFlags |= DDSD_LINEARSIZE;
-            desc->dwFlags &= ~DDSD_PITCH;
             desc->u1.dwLinearSize = wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4);
-        }
+        desc->dwFlags |= DDSD_LINEARSIZE;
+        desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_PITCH);
     }
     else
     {
-        if (desc->dwFlags & DDSD_LPSURFACE)
-        {
-            if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
-                    wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
-            {
-                WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
-                return DDERR_INVALIDPARAMS;
-            }
-
-            if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
-                    wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
-                    desc->lpSurface, desc->u1.lPitch)))
-            {
-                ERR("Failed to set surface memory, hr %#x.\n", hr);
-                return hr;
-            }
-
-            desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE);
-        }
-        else
-        {
-            desc->dwFlags |= DDSD_PITCH;
-            desc->dwFlags &= ~DDSD_LINEARSIZE;
+        if (!(desc->dwFlags & DDSD_LPSURFACE))
             desc->u1.lPitch = wined3d_surface_get_pitch(wined3d_surface);
-        }
+        desc->dwFlags |= DDSD_PITCH;
+        desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE);
     }
     desc->lpSurface = NULL;
 
@@ -6233,8 +6211,6 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, s
     *parent_ops = &ddraw_surface_wined3d_parent_ops;
 
     wined3d_private_store_init(&surface->private_store);
-
-    return DD_OK;
 }
 
 static void STDMETHODCALLTYPE view_wined3d_object_destroyed(void *parent)
index a35703f..d1192c7 100644 (file)
@@ -19,6 +19,7 @@ list(APPEND SOURCE
     device.c
     directx.c
     drawprim.c
+    dxtn.c
     gl_compat.c
     glsl_shader.c
     nvidia_texture_shader.c
index d1e2a3c..5620af1 100644 (file)
@@ -817,7 +817,7 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader
             max_constantsF -= count_bits(reg_maps->integer_constants);
             max_constantsF -= gl_info->reserved_arb_constants;
 
-            for (i = 0; i < shader->limits.constant_float; ++i)
+            for (i = 0; i < shader->limits->constant_float; ++i)
             {
                 DWORD idx = i >> 5;
                 DWORD shift = i & 0x1f;
@@ -893,7 +893,7 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader
     }
 
     /* Avoid declaring more constants than needed */
-    max_constantsF = min(max_constantsF, shader->limits.constant_float);
+    max_constantsF = min(max_constantsF, shader->limits->constant_float);
 
     /* we use the array-based constants array if the local constants are marked for loading,
      * because then we use indirect addressing, or when the local constant list is empty,
@@ -1384,8 +1384,8 @@ static const char *shader_arb_get_modifier(const struct wined3d_shader_instructi
 static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
         const char *dst_str, const char *coord_reg, WORD flags, const char *dsx, const char *dsy)
 {
+    enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[sampler_idx].type;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     const char *tex_type;
     BOOL np2_fixup = FALSE;
     struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
@@ -1398,12 +1398,13 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
     /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */
     if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS;
 
-    switch(sampler_type) {
-        case WINED3DSTT_1D:
+    switch (resource_type)
+    {
+        case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
             tex_type = "1D";
             break;
 
-        case WINED3DSTT_2D:
+        case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
             shader = ins->ctx->shader;
             device = shader->device;
             gl_info = &device->adapter->gl_info;
@@ -1423,16 +1424,16 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
             }
             break;
 
-        case WINED3DSTT_VOLUME:
+        case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
             tex_type = "3D";
             break;
 
-        case WINED3DSTT_CUBE:
+        case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
             tex_type = "CUBE";
             break;
 
         default:
-            ERR("Unexpected texture type %d\n", sampler_type);
+            ERR("Unexpected resource type %#x.\n", resource_type);
             tex_type = "";
     }
 
@@ -4251,7 +4252,7 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader,
         {
             int i;
             const char *one = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ONE);
-            for(i = 0; i < min(8, MAX_REG_TEXCRD); i++)
+            for(i = 0; i < MAX_REG_TEXCRD; i++)
             {
                 if (reg_maps->texcoord_mask[i] && reg_maps->texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL)
                     shader_addline(buffer, "MOV result.texcoord[%u].w, %s\n", i, one);
@@ -4370,7 +4371,7 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh
 
     shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
 
-    pixelshader_update_samplers(shader, args->super.tex_types);
+    pixelshader_update_resource_types(shader, args->super.tex_types);
 
     if (!shader_buffer_init(&buffer))
     {
@@ -5231,8 +5232,10 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_MOVA                  */ shader_hw_mov,
     /* WINED3DSIH_MOVC                  */ NULL,
     /* WINED3DSIH_MUL                   */ shader_hw_map2gl,
+    /* WINED3DSIH_NE                    */ NULL,
     /* WINED3DSIH_NOP                   */ shader_hw_nop,
     /* WINED3DSIH_NRM                   */ shader_hw_nrm,
+    /* WINED3DSIH_OR                    */ NULL,
     /* WINED3DSIH_PHASE                 */ shader_hw_nop,
     /* WINED3DSIH_POW                   */ shader_hw_pow,
     /* WINED3DSIH_RCP                   */ shader_hw_scalar_op,
@@ -5273,6 +5276,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_TEXREG2GB             */ pshader_hw_texreg2gb,
     /* WINED3DSIH_TEXREG2RGB            */ pshader_hw_texreg2rgb,
     /* WINED3DSIH_UDIV                  */ NULL,
+    /* WINED3DSIH_UGE                   */ NULL,
     /* WINED3DSIH_USHR                  */ NULL,
     /* WINED3DSIH_UTOF                  */ NULL,
     /* WINED3DSIH_XOR                   */ NULL,
@@ -6529,7 +6533,11 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
             state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
         }
         context->last_was_pshader = FALSE;
-    } else {
+    }
+    else if (!context->last_was_pshader)
+    {
+        if (device->shader_backend == &arb_program_shader_backend)
+            context->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
         context->last_was_pshader = TRUE;
     }
 
@@ -7243,7 +7251,7 @@ static GLuint gen_p8_shader(struct arbfp_blit_priv *priv,
 
     /* The alpha-component contains the palette index */
     if(textype == GL_TEXTURE_RECTANGLE_ARB)
-        shader_addline(&buffer, "TXP index, fragment.texcoord[0], texture[0], RECT;\n");
+        shader_addline(&buffer, "TEX index, fragment.texcoord[0], texture[0], RECT;\n");
     else
         shader_addline(&buffer, "TEX index, fragment.texcoord[0], texture[0], 2D;\n");
 
@@ -7282,7 +7290,7 @@ static void upload_palette(const struct wined3d_texture *texture, struct wined3d
     if (!priv->palette_texture)
         gl_info->gl_ops.gl.p_glGenTextures(1, &priv->palette_texture);
 
-    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1));
+    GL_EXTCALL(glActiveTexture(GL_TEXTURE1));
     gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, priv->palette_texture);
 
     gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@@ -7463,7 +7471,7 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context,
     struct arbfp_blit_type type;
     struct arbfp_blit_desc *desc;
 
-    if (surface->flags & SFLAG_CONVERTED)
+    if (surface->container->flags & WINED3D_TEXTURE_CONVERTED)
     {
         gl_info->gl_ops.gl.p_glEnable(textype);
         checkGLcall("glEnable(textype)");
index 810771a..16e28ae 100644 (file)
@@ -102,8 +102,8 @@ static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_g
 {
     if(!This->buffer_object) return;
 
-    GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
-    checkGLcall("glDeleteBuffersARB");
+    GL_EXTCALL(glDeleteBuffers(1, &This->buffer_object));
+    checkGLcall("glDeleteBuffers");
     This->buffer_object = 0;
 
     if(This->query)
@@ -137,7 +137,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine
      * to be verified to check if the rhw and color values are in the correct
      * format. */
 
-    GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object));
+    GL_EXTCALL(glGenBuffers(1, &This->buffer_object));
     error = gl_info->gl_ops.gl.p_glGetError();
     if (!This->buffer_object || error != GL_NO_ERROR)
     {
@@ -147,7 +147,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine
 
     if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
         context_invalidate_state(context, STATE_INDEXBUFFER);
-    GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+    GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object));
     error = gl_info->gl_ops.gl.p_glGetError();
     if (error != GL_NO_ERROR)
     {
@@ -178,11 +178,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine
      * calling glBufferSubData on updates. Upload the actual data in case
      * we're not double buffering, so we can release the heap mem afterwards
      */
-    GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, This->resource.heap_memory, gl_usage));
+    GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, This->resource.heap_memory, gl_usage));
     error = gl_info->gl_ops.gl.p_glGetError();
     if (error != GL_NO_ERROR)
     {
-        ERR("glBufferDataARB failed with error %s (%#x)\n", debug_glerror(error), error);
+        ERR("glBufferData failed with error %s (%#x)\n", debug_glerror(error), error);
         goto fail;
     }
 
@@ -263,7 +263,7 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This,
 #define WINED3D_BUFFER_FIXUP_XYZRHW     0x02
 
 static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
-        UINT attrib_idx, DWORD fixup_flags, DWORD *stride_this_run)
+        const struct wined3d_state *state, UINT attrib_idx, DWORD fixup_flags, DWORD *stride_this_run)
 {
     const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
     enum wined3d_format_id format;
@@ -273,7 +273,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
      * there, on nonexistent attribs the vbo is 0.
      */
     if (!(si->use_map & (1 << attrib_idx))
-            || attrib->data.buffer_object != This->buffer_object)
+            || state->streams[attrib->stream_idx].buffer != This)
         return FALSE;
 
     format = attrib->format->id;
@@ -301,7 +301,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
 }
 
 static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
-        DWORD fixup_flags)
+        const struct wined3d_state *state, DWORD fixup_flags)
 {
     UINT stride_this_run = 0;
     BOOL ret = FALSE;
@@ -375,31 +375,31 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_s
      * texcoord needs no conversion while a FLOAT4 positiont needs one
      */
 
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_POSITION,
             fixup_flags, &stride_this_run) || ret;
     fixup_flags &= ~WINED3D_BUFFER_FIXUP_XYZRHW;
 
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_NORMAL,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_DIFFUSE,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_SPECULAR,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_SPECULAR,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD0,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD0,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD1,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD1,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD2,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD2,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD3,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD3,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD4,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD4,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD5,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD5,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD6,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD6,
             fixup_flags, &stride_this_run) || ret;
-    ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD7,
+    ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD7,
             fixup_flags, &stride_this_run) || ret;
 
     if (!stride_this_run && This->conversion_map)
@@ -497,8 +497,8 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *con
     if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
         context_invalidate_state(context, STATE_INDEXBUFFER);
 
-    GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
-    GL_EXTCALL(glGetBufferSubDataARB(This->buffer_type_hint, 0, This->resource.size, This->resource.heap_memory));
+    GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object));
+    GL_EXTCALL(glGetBufferSubData(This->buffer_type_hint, 0, This->resource.size, This->resource.heap_memory));
     This->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
 
     return This->resource.heap_memory;
@@ -586,8 +586,8 @@ static void buffer_sync_apple(struct wined3d_buffer *This, DWORD flags, const st
 
     if (flags & WINED3D_MAP_DISCARD)
     {
-        GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage));
-        checkGLcall("glBufferDataARB\n");
+        GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage));
+        checkGLcall("glBufferData");
         return;
     }
 
@@ -651,8 +651,8 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined
 
     /* This potentially invalidates the element array buffer binding, but the
      * caller always takes care of this. */
-    GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
-    checkGLcall("glBindBufferARB");
+    GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object));
+    checkGLcall("glBindBuffer");
     if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
     {
         GLbitfield mapflags;
@@ -676,8 +676,8 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined
                 syncflags |= WINED3D_MAP_NOOVERWRITE;
             buffer_sync_apple(This, syncflags, gl_info);
         }
-        map = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_WRITE_ONLY_ARB));
-        checkGLcall("glMapBufferARB");
+        map = GL_EXTCALL(glMapBuffer(This->buffer_type_hint, GL_WRITE_ONLY));
+        checkGLcall("glMapBuffer");
     }
     if (!map)
     {
@@ -704,8 +704,8 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined
             checkGLcall("glFlushMappedBufferRangeAPPLE");
         }
     }
-    GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
-    checkGLcall("glUnmapBufferARB");
+    GL_EXTCALL(glUnmapBuffer(This->buffer_type_hint));
+    checkGLcall("glUnmapBuffer");
 }
 
 void buffer_mark_used(struct wined3d_buffer *buffer)
@@ -764,7 +764,7 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte
                 fixup_flags |= WINED3D_BUFFER_FIXUP_XYZRHW;
         }
 
-        decl_changed = buffer_find_decl(buffer, &context->stream_info, fixup_flags);
+        decl_changed = buffer_find_decl(buffer, &context->stream_info, state, fixup_flags);
         buffer->flags |= WINED3D_BUFFER_HASDESC;
     }
 
@@ -910,10 +910,10 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte
             }
         }
 
-        GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
-        checkGLcall("glBindBufferARB");
-        GL_EXTCALL(glBufferSubDataARB(buffer->buffer_type_hint, start, len, data + start));
-        checkGLcall("glBufferSubDataARB");
+        GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object));
+        checkGLcall("glBindBuffer");
+        GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, start, len, data + start));
+        checkGLcall("glBufferSubData");
     }
 
     HeapFree(GetProcessHeap(), 0, data);
@@ -976,7 +976,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN
 
                 if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
                     context_invalidate_state(context, STATE_INDEXBUFFER);
-                GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
+                GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object));
 
                 if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
                 {
@@ -989,17 +989,17 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN
                 {
                     if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
                         buffer_sync_apple(buffer, flags, gl_info);
-                    buffer->map_ptr = GL_EXTCALL(glMapBufferARB(buffer->buffer_type_hint,
-                            GL_READ_WRITE_ARB));
-                    checkGLcall("glMapBufferARB");
+                    buffer->map_ptr = GL_EXTCALL(glMapBuffer(buffer->buffer_type_hint,
+                            GL_READ_WRITE));
+                    checkGLcall("glMapBuffer");
                 }
 
                 if (((DWORD_PTR)buffer->map_ptr) & (RESOURCE_ALIGNMENT - 1))
                 {
                     WARN("Pointer %p is not %u byte aligned.\n", buffer->map_ptr, RESOURCE_ALIGNMENT);
 
-                    GL_EXTCALL(glUnmapBufferARB(buffer->buffer_type_hint));
-                    checkGLcall("glUnmapBufferARB");
+                    GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint));
+                    checkGLcall("glUnmapBuffer");
                     buffer->map_ptr = NULL;
 
                     if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)
@@ -1075,7 +1075,7 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer)
 
         if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
             context_invalidate_state(context, STATE_INDEXBUFFER);
-        GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
+        GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object));
 
         if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
         {
@@ -1096,7 +1096,7 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer)
             }
         }
 
-        GL_EXTCALL(glUnmapBufferARB(buffer->buffer_type_hint));
+        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);
index cbb5815..c319207 100644 (file)
@@ -133,7 +133,7 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
             {
                 case WINED3D_LOCATION_TEXTURE_RGB:
                 case WINED3D_LOCATION_TEXTURE_SRGB:
-                    surface_prepare_texture(depth_stencil, context, FALSE);
+                    wined3d_texture_prepare_texture(depth_stencil->container, context, FALSE);
 
                     if (format_flags & WINED3DFMT_FLAG_DEPTH)
                     {
@@ -209,7 +209,7 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
             case WINED3D_LOCATION_TEXTURE_RGB:
             case WINED3D_LOCATION_TEXTURE_SRGB:
                 srgb = location == WINED3D_LOCATION_TEXTURE_SRGB;
-                surface_prepare_texture(surface, context, srgb);
+                wined3d_texture_prepare_texture(surface->container, context, srgb);
                 gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
                         surface->texture_target, surface_get_texture_name(surface, gl_info, srgb),
                         surface->texture_level);
@@ -429,7 +429,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ
 
     /* Set valid read and draw buffer bindings to satisfy pedantic pre-ES2_compatibility
      * GL contexts requirements. */
-    glReadBuffer(GL_NONE);
+    gl_info->gl_ops.gl.p_glReadBuffer(GL_NONE);
     context_set_draw_buffer(context, GL_NONE);
     if (target != GL_FRAMEBUFFER)
     {
@@ -496,8 +496,8 @@ void context_alloc_occlusion_query(struct wined3d_context *context, struct wined
     {
         if (gl_info->supported[ARB_OCCLUSION_QUERY])
         {
-            GL_EXTCALL(glGenQueriesARB(1, &query->id));
-            checkGLcall("glGenQueriesARB");
+            GL_EXTCALL(glGenQueries(1, &query->id));
+            checkGLcall("glGenQueries");
 
             TRACE("Allocated occlusion query %u in context %p.\n", query->id, context);
         }
@@ -617,8 +617,8 @@ void context_alloc_timestamp_query(struct wined3d_context *context, struct wined
     }
     else
     {
-        GL_EXTCALL(glGenQueriesARB(1, &query->id));
-        checkGLcall("glGenQueriesARB");
+        GL_EXTCALL(glGenQueries(1, &query->id));
+        checkGLcall("glGenQueries");
 
         TRACE("Allocated timestamp query %u in context %p.\n", query->id, context);
     }
@@ -758,47 +758,11 @@ void context_surface_update(struct wined3d_context *context, const struct wined3
     }
 }
 
-static BOOL context_restore_pixel_format(struct wined3d_context *ctx)
+static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC dc, int format)
 {
-    const struct wined3d_gl_info *gl_info = ctx->gl_info;
-    BOOL ret = FALSE;
+    int current = GetPixelFormat(dc);
 
-    if (ctx->restore_pf && IsWindow(ctx->restore_pf_win))
-    {
-        if (ctx->gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH])
-        {
-            HDC dc = GetDC(ctx->restore_pf_win);
-            if (dc)
-            {
-                if (!(ret = GL_EXTCALL(wglSetPixelFormatWINE(dc, ctx->restore_pf))))
-                {
-                    ERR("wglSetPixelFormatWINE failed to restore pixel format %d on window %p.\n",
-                            ctx->restore_pf, ctx->restore_pf_win);
-                }
-                ReleaseDC(ctx->restore_pf_win, dc);
-            }
-        }
-        else
-        {
-            ERR("can't restore pixel format %d on window %p\n", ctx->restore_pf, ctx->restore_pf_win);
-        }
-    }
-
-    ctx->restore_pf = 0;
-    ctx->restore_pf_win = NULL;
-    return ret;
-}
-
-static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BOOL private, int format)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    int current;
-
-    if (dc == context->hdc && context->hdc_is_private && context->hdc_has_format)
-        return TRUE;
-
-    current = GetPixelFormat(dc);
-    if (current == format) goto success;
+    if (current == format) return TRUE;
 
     if (!current)
     {
@@ -809,10 +773,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO
                     format, dc, GetLastError());
             return FALSE;
         }
-
-        context->restore_pf = 0;
-        context->restore_pf_win = private ? NULL : WindowFromDC(dc);
-        goto success;
+        return TRUE;
     }
 
     /* By default WGL doesn't allow pixel format adjustments but we need it
@@ -821,25 +782,13 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO
      * when really needed. */
     if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH])
     {
-        HWND win;
-
         if (!GL_EXTCALL(wglSetPixelFormatWINE(dc, format)))
         {
             ERR("wglSetPixelFormatWINE failed to set pixel format %d on device context %p.\n",
                     format, dc);
             return FALSE;
         }
-
-        win = private ? NULL : WindowFromDC(dc);
-        if (win != context->restore_pf_win)
-        {
-            context_restore_pixel_format(context);
-
-            context->restore_pf = private ? 0 : current;
-            context->restore_pf_win = win;
-        }
-
-        goto success;
+        return TRUE;
     }
 
     /* OpenGL doesn't allow pixel format adjustments. Print an error and
@@ -849,11 +798,6 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO
     ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n",
             format, dc, current);
     return TRUE;
-
-success:
-    if (dc == context->hdc && context->hdc_is_private)
-        context->hdc_has_format = TRUE;
-    return TRUE;
 }
 
 static BOOL context_set_gl_context(struct wined3d_context *ctx)
@@ -861,7 +805,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
     struct wined3d_swapchain *swapchain = ctx->swapchain;
     BOOL backup = FALSE;
 
-    if (!context_set_pixel_format(ctx, ctx->hdc, ctx->hdc_is_private, ctx->pixel_format))
+    if (!context_set_pixel_format(ctx->gl_info, ctx->hdc, ctx->pixel_format))
     {
         WARN("Failed to set pixel format %d on device context %p.\n",
                 ctx->pixel_format, ctx->hdc);
@@ -894,7 +838,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
             return FALSE;
         }
 
-        if (!context_set_pixel_format(ctx, dc, TRUE, ctx->pixel_format))
+        if (!context_set_pixel_format(ctx->gl_info, dc, ctx->pixel_format))
         {
             ERR("Failed to set pixel format %d on device context %p.\n",
                     ctx->pixel_format, dc);
@@ -916,8 +860,15 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
     return TRUE;
 }
 
-static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HDC dc, HGLRC gl_ctx)
+static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HDC dc, HGLRC gl_ctx, int pf)
 {
+    if (!context_set_pixel_format(gl_info, dc, pf))
+    {
+        ERR("Failed to restore pixel format %d on device context %p.\n", pf, dc);
+        context_set_current(NULL);
+        return;
+    }
+
     if (!wglMakeCurrent(dc, gl_ctx))
     {
         ERR("Failed to restore GL context %p on device context %p, last error %#x.\n",
@@ -938,8 +889,6 @@ static void context_update_window(struct wined3d_context *context)
         wined3d_release_dc(context->win_handle, context->hdc);
 
     context->win_handle = context->swapchain->win_handle;
-    context->hdc_is_private = FALSE;
-    context->hdc_has_format = FALSE;
     context->needs_set = 1;
     context->valid = 1;
 
@@ -960,9 +909,11 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
     HGLRC restore_ctx;
     HDC restore_dc;
     unsigned int i;
+    int restore_pf;
 
     restore_ctx = wglGetCurrentContext();
     restore_dc = wglGetCurrentDC();
+    restore_pf = GetPixelFormat(restore_dc);
 
     if (restore_ctx == context->glCtx)
         restore_ctx = NULL;
@@ -972,14 +923,14 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
     LIST_FOR_EACH_ENTRY(timestamp_query, &context->timestamp_queries, struct wined3d_timestamp_query, entry)
     {
         if (context->valid)
-            GL_EXTCALL(glDeleteQueriesARB(1, &timestamp_query->id));
+            GL_EXTCALL(glDeleteQueries(1, &timestamp_query->id));
         timestamp_query->context = NULL;
     }
 
     LIST_FOR_EACH_ENTRY(occlusion_query, &context->occlusion_queries, struct wined3d_occlusion_query, entry)
     {
         if (context->valid && gl_info->supported[ARB_OCCLUSION_QUERY])
-            GL_EXTCALL(glDeleteQueriesARB(1, &occlusion_query->id));
+            GL_EXTCALL(glDeleteQueries(1, &occlusion_query->id));
         occlusion_query->context = NULL;
     }
 
@@ -1017,10 +968,10 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
         }
 
         if (gl_info->supported[ARB_TIMER_QUERY])
-            GL_EXTCALL(glDeleteQueriesARB(context->free_timestamp_query_count, context->free_timestamp_queries));
+            GL_EXTCALL(glDeleteQueries(context->free_timestamp_query_count, context->free_timestamp_queries));
 
         if (gl_info->supported[ARB_OCCLUSION_QUERY])
-            GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, context->free_occlusion_queries));
+            GL_EXTCALL(glDeleteQueries(context->free_occlusion_query_count, context->free_occlusion_queries));
 
         if (gl_info->supported[ARB_SYNC])
         {
@@ -1051,10 +1002,9 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
     HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
     HeapFree(GetProcessHeap(), 0, context->free_event_queries);
 
-    context_restore_pixel_format(context);
     if (restore_ctx)
     {
-        context_restore_gl_context(gl_info, restore_dc, restore_ctx);
+        context_restore_gl_context(gl_info, restore_dc, restore_ctx, restore_pf);
     }
     else if (wglGetCurrentContext() && !wglMakeCurrent(NULL, NULL))
     {
@@ -1150,17 +1100,12 @@ void context_release(struct wined3d_context *context)
             WARN("Context %p is not the current context.\n", context);
     }
 
-    if (!--context->level)
+    if (!--context->level && context->restore_ctx)
     {
-        if (context_restore_pixel_format(context))
-            context->needs_set = 1;
-        if (context->restore_ctx)
-        {
-            TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc);
-            context_restore_gl_context(context->gl_info, context->restore_dc, context->restore_ctx);
-            context->restore_ctx = NULL;
-            context->restore_dc = NULL;
-        }
+        TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc);
+        context_restore_gl_context(context->gl_info, context->restore_dc, context->restore_ctx, context->restore_pf);
+        context->restore_ctx = NULL;
+        context->restore_dc = NULL;
     }
 }
 
@@ -1179,11 +1124,9 @@ static void context_enter(struct wined3d_context *context)
                     current_gl, wglGetCurrentDC());
             context->restore_ctx = current_gl;
             context->restore_dc = wglGetCurrentDC();
+            context->restore_pf = GetPixelFormat(context->restore_dc);
             context->needs_set = 1;
         }
-        else if (!context->needs_set && !(context->hdc_is_private && context->hdc_has_format)
-                    && context->pixel_format != GetPixelFormat(context->hdc))
-            context->needs_set = 1;
     }
 }
 
@@ -1320,8 +1263,8 @@ static void bind_dummy_textures(const struct wined3d_device *device, const struc
 
     for (i = 0; i < count; ++i)
     {
-        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
-        checkGLcall("glActiveTextureARB");
+        GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i));
+        checkGLcall("glActiveTexture");
 
         gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[i]);
         checkGLcall("glBindTexture");
@@ -1391,7 +1334,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     int swap_interval;
     DWORD state;
     HDC hdc;
-    BOOL hdc_is_private = FALSE;
 
     TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle);
 
@@ -1459,9 +1401,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     {
         WARN("Failed to retireve device context, trying swapchain backup.\n");
 
-        if ((hdc = swapchain_get_backup_dc(swapchain)))
-            hdc_is_private = TRUE;
-        else
+        if (!(hdc = swapchain_get_backup_dc(swapchain)))
         {
             ERR("Failed to retrieve a device context.\n");
             goto out;
@@ -1510,9 +1450,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
 
     context_enter(ret);
 
-    ret->gl_info = gl_info;
-
-    if (!context_set_pixel_format(ret, hdc, hdc_is_private, pixel_format))
+    if (!context_set_pixel_format(gl_info, hdc, pixel_format))
     {
         ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc);
         context_release(ret);
@@ -1567,6 +1505,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
         goto out;
     }
 
+    ret->gl_info = gl_info;
     ret->d3d_info = &device->adapter->d3d_info;
     ret->state_table = device->StateTable;
 
@@ -1589,8 +1528,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     ret->glCtx = ctx;
     ret->win_handle = swapchain->win_handle;
     ret->hdc = hdc;
-    ret->hdc_is_private = hdc_is_private;
-    ret->hdc_has_format = TRUE;
     ret->pixel_format = pixel_format;
     ret->needs_set = 1;
 
@@ -1677,7 +1614,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
 
     gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);
     checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);");
-    gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);
+    gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);");
 
     if (gl_info->supported[ARB_VERTEX_BLEND])
@@ -1912,6 +1849,8 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
             context_invalidate_state(context, STATE_SAMPLER(sampler));
         }
     }
+    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];
@@ -2072,7 +2011,7 @@ static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt
 
             if (gl_info->supported[ARB_DRAW_BUFFERS])
             {
-                GL_EXTCALL(glDrawBuffersARB(i, context->draw_buffers));
+                GL_EXTCALL(glDrawBuffers(i, context->draw_buffers));
                 checkGLcall("glDrawBuffers()");
             }
             else
@@ -2107,8 +2046,8 @@ void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer)
 /* Context activation is done by the caller. */
 void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit)
 {
-    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0 + unit));
-    checkGLcall("glActiveTextureARB");
+    GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + unit));
+    checkGLcall("glActiveTexture");
     context->active_texture = unit;
 }
 
@@ -2577,14 +2516,14 @@ static void context_map_fixed_function_samplers(struct wined3d_context *context,
 
 static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state)
 {
-    const enum wined3d_sampler_texture_type *sampler_type =
-            state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type;
+    const struct wined3d_shader_resource_info *resource_info =
+            state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
     unsigned int i;
     const struct wined3d_d3d_info *d3d_info = context->d3d_info;
 
     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
     {
-        if (sampler_type[i] && context->tex_unit_map[i] != i)
+        if (resource_info[i].type && context->tex_unit_map[i] != i)
         {
             context_map_stage(context, i, i);
             context_invalidate_state(context, STATE_SAMPLER(i));
@@ -2595,8 +2534,8 @@ static void context_map_psamplers(struct wined3d_context *context, const struct
 }
 
 static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
-        const enum wined3d_sampler_texture_type *pshader_sampler_tokens,
-        const enum wined3d_sampler_texture_type *vshader_sampler_tokens, DWORD unit)
+        const struct wined3d_shader_resource_info *ps_resource_info,
+        const struct wined3d_shader_resource_info *vs_resource_info, DWORD unit)
 {
     DWORD current_mapping = context->rev_tex_unit_map[unit];
 
@@ -2608,39 +2547,39 @@ static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
     {
         /* Used by a fragment sampler */
 
-        if (!pshader_sampler_tokens)
+        if (!ps_resource_info)
         {
             /* No pixel shader, check fixed function */
             return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1 << current_mapping));
         }
 
         /* Pixel shader, check the shader's sampler map */
-        return !pshader_sampler_tokens[current_mapping];
+        return !ps_resource_info[current_mapping].type;
     }
 
     /* Used by a vertex sampler */
-    return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS];
+    return !vs_resource_info[current_mapping - MAX_FRAGMENT_SAMPLERS].type;
 }
 
 static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state)
 {
-    const enum wined3d_sampler_texture_type *vshader_sampler_type =
-            state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.sampler_type;
-    const enum wined3d_sampler_texture_type *pshader_sampler_type = NULL;
+    const struct wined3d_shader_resource_info *vs_resource_info =
+            state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info;
+    const struct wined3d_shader_resource_info *ps_resource_info = NULL;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
     int i;
 
+    /* Note that we only care if a resource is used or not, not the
+     * resource's specific type. Otherwise we'd need to call
+     * shader_update_samplers() here for 1.x pixelshaders. */
     if (ps)
-    {
-        /* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
-         * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
-        pshader_sampler_type = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type;
-    }
+        ps_resource_info = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
 
-    for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
+    for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
+    {
         DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
-        if (vshader_sampler_type[i])
+        if (vs_resource_info[i].type)
         {
             if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
             {
@@ -2650,7 +2589,7 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
 
             while (start >= 0)
             {
-                if (context_unit_free_for_vs(context, pshader_sampler_type, vshader_sampler_type, start))
+                if (context_unit_free_for_vs(context, ps_resource_info, vs_resource_info, start))
                 {
                     context_map_stage(context, vsampler_idx, start);
                     context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
@@ -2922,7 +2861,7 @@ static void context_preload_textures(struct wined3d_context *context, const stru
     {
         for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
         {
-            if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.sampler_type[i])
+            if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info[i].type)
                 context_preload_texture(context, state, MAX_FRAGMENT_SAMPLERS + i);
         }
     }
@@ -2931,7 +2870,7 @@ static void context_preload_textures(struct wined3d_context *context, const stru
     {
         for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
         {
-            if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type[i])
+            if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info[i].type)
                 context_preload_texture(context, state, i);
         }
     }
@@ -2947,6 +2886,74 @@ static void context_preload_textures(struct wined3d_context *context, const stru
     }
 }
 
+static void context_bind_shader_resources(struct wined3d_context *context, const struct wined3d_state *state)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct wined3d_shader_sampler_map_entry *entry;
+    struct wined3d_shader_resource_view *view;
+    struct wined3d_sampler *sampler;
+    struct wined3d_texture *texture;
+    struct wined3d_shader *shader;
+    unsigned int i, j, count;
+
+    static const struct
+    {
+        enum wined3d_shader_type type;
+        unsigned int base_idx;
+        unsigned int count;
+    }
+    shader_types[] =
+    {
+        {WINED3D_SHADER_TYPE_PIXEL,     0,                      MAX_FRAGMENT_SAMPLERS},
+        {WINED3D_SHADER_TYPE_VERTEX,    MAX_FRAGMENT_SAMPLERS,  MAX_VERTEX_SAMPLERS},
+    };
+
+    for (i = 0; i < ARRAY_SIZE(shader_types); ++i)
+    {
+        if (!(shader = state->shader[shader_types[i].type]))
+            continue;
+
+        count = shader->reg_maps.sampler_map.count;
+        if (count > shader_types[i].count)
+        {
+            FIXME("Shader %p needs %u samplers, but only %u are supported.\n",
+                    shader, count, shader_types[i].count);
+            count = shader_types[i].count;
+        }
+
+        for (j = 0; j < count; ++j)
+        {
+            entry = &shader->reg_maps.sampler_map.entries[j];
+
+            if (!(view = state->shader_resource_view[shader_types[i].type][entry->resource_idx]))
+            {
+                WARN("No resource view bound at index %u, %u.\n", shader_types[i].type, entry->resource_idx);
+                continue;
+            }
+
+            if (view->resource->type == WINED3D_RTYPE_BUFFER)
+            {
+                FIXME("Buffer shader resources not supported.\n");
+                continue;
+            }
+
+            if (!(sampler = state->sampler[shader_types[i].type][entry->sampler_idx]))
+            {
+                WARN("No sampler object bound at index %u, %u.\n", shader_types[i].type, entry->sampler_idx);
+                continue;
+            }
+
+            texture = wined3d_texture_from_resource(view->resource);
+            wined3d_texture_load(texture, context, FALSE);
+            context_active_texture(context, gl_info, shader_types[i].base_idx + entry->bind_idx);
+            wined3d_texture_bind(texture, context, FALSE);
+
+            GL_EXTCALL(glBindSampler(shader_types[i].base_idx + entry->bind_idx, sampler->name));
+            checkGLcall("glBindSampler");
+        }
+    }
+}
+
 /* Context activation is done by the caller. */
 BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device)
 {
@@ -3020,6 +3027,12 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
         context->constant_update_mask = 0;
     }
 
+    if (context->update_shader_resource_bindings)
+    {
+        context_bind_shader_resources(context, state);
+        context->update_shader_resource_bindings = 0;
+    }
+
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
         context_check_fbo_status(context, GL_FRAMEBUFFER);
index 08dbbed..7209998 100644 (file)
@@ -634,10 +634,15 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
 
     if (op->texture)
     {
+        const struct wined3d_format *new_format = op->texture->resource.format;
+        const struct wined3d_format *old_format = prev ? prev->resource.format : NULL;
+
         if (InterlockedIncrement(&op->texture->resource.bind_count) == 1)
             op->texture->sampler = op->stage;
 
-        if (!prev || op->texture->target != prev->target)
+        if (!prev || op->texture->target != prev->target
+                || !is_same_fixup(new_format->color_fixup, old_format->color_fixup)
+                || (new_format->flags & WINED3DFMT_FLAG_SHADOW) != (old_format->flags & WINED3DFMT_FLAG_SHADOW))
             device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
 
         if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
@@ -697,6 +702,7 @@ static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, cons
     const struct wined3d_cs_set_shader_resource_view *op = data;
 
     cs->state.shader_resource_view[op->type][op->view_idx] = op->view;
+    device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
 }
 
 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type,
@@ -718,6 +724,7 @@ static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data)
     const struct wined3d_cs_set_sampler *op = data;
 
     cs->state.sampler[op->type][op->sampler_idx] = op->sampler;
+    device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
 }
 
 void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type,
@@ -740,6 +747,7 @@ static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
 
     cs->state.shader[op->type] = op->shader;
     device_invalidate_state(cs->device, STATE_SHADER(op->type));
+    device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
 }
 
 void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader)
index 5513a0d..6fac754 100644 (file)
@@ -471,6 +471,13 @@ ULONG CDECL wined3d_device_incref(struct wined3d_device *device)
     return refcount;
 }
 
+static void device_leftover_sampler(struct wine_rb_entry *entry, void *context)
+{
+    struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
+
+    ERR("Leftover sampler %p.\n", sampler);
+}
+
 ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
 {
     ULONG refcount = InterlockedDecrement(&device->ref);
@@ -514,6 +521,8 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
             DestroyCursor(device->hardwareCursor);
         device->hardwareCursor = 0;
 
+        wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL);
+
         wined3d_decref(device->wined3d);
         device->wined3d = NULL;
         HeapFree(GetProcessHeap(), 0, device);
@@ -583,7 +592,7 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
     desc.depth = 1;
     desc.size = 0;
     if (FAILED(hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE,
-            NULL, &wined3d_null_parent_ops, &device->logo_texture)))
+            NULL, NULL, &wined3d_null_parent_ops, &device->logo_texture)))
     {
         ERR("Wine logo requested, but failed to create texture, hr %#x.\n", hr);
         goto out;
@@ -599,7 +608,7 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
 
         color_key.color_space_low_value = 0;
         color_key.color_space_high_value = 0;
-        wined3d_texture_set_color_key(device->logo_texture, WINEDDCKEY_SRCBLT, &color_key);
+        wined3d_texture_set_color_key(device->logo_texture, WINED3D_CKEY_SRC_BLT, &color_key);
     }
     else
     {
@@ -667,7 +676,7 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]);
             checkGLcall("glBindTexture");
 
-            GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
+            GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
             checkGLcall("glTexImage3D");
         }
 
@@ -1012,6 +1021,13 @@ err_out:
     return hr;
 }
 
+static void device_free_sampler(struct wine_rb_entry *entry, void *context)
+{
+    struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
+
+    wined3d_sampler_decref(sampler);
+}
+
 HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
 {
     struct wined3d_resource *resource, *cursor;
@@ -1046,6 +1062,8 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
         resource->resource_ops->resource_unload(resource);
     }
 
+    wine_rb_clear(&device->samplers, device_free_sampler, NULL);
+
     /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader
      * private data, it might contain opengl pointers
      */
@@ -3011,7 +3029,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device,
         e->data.addr += (ULONG_PTR)buffer_get_sysmem(buffer, context);
         if (buffer->buffer_object)
         {
-            GL_EXTCALL(glDeleteBuffersARB(1, &buffer->buffer_object));
+            GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object));
             buffer->buffer_object = 0;
         }
         if (e->data.addr)
@@ -3447,9 +3465,9 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device
 static HRESULT device_update_volume(struct wined3d_device *device,
         struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume)
 {
+    struct wined3d_const_bo_address data;
     struct wined3d_map_desc src;
     HRESULT hr;
-    struct wined3d_bo_address data;
     struct wined3d_context *context;
 
     TRACE("device %p, src_volume %p, dst_volume %p.\n",
@@ -3473,7 +3491,9 @@ static HRESULT device_update_volume(struct wined3d_device *device,
 
     context = context_acquire(device, NULL);
 
-    wined3d_volume_load(dst_volume, context, FALSE);
+    /* Only a prepare, since we're uploading the entire volume. */
+    wined3d_texture_prepare_texture(dst_volume->container, context, FALSE);
+    wined3d_texture_bind(dst_volume->container, context, FALSE);
 
     data.buffer_object = 0;
     data.addr = src.data;
@@ -3978,13 +3998,11 @@ void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device,
 static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device,
         struct wined3d_surface *cursor_image)
 {
+    struct wined3d_sub_resource_data data;
     struct wined3d_resource_desc desc;
     struct wined3d_map_desc map_desc;
     struct wined3d_texture *texture;
-    struct wined3d_surface *surface;
-    BYTE *src_data, *dst_data;
-    unsigned int src_pitch;
-    unsigned int i;
+    HRESULT hr;
 
     if (FAILED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY)))
     {
@@ -3992,8 +4010,9 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined
         return NULL;
     }
 
-    src_pitch = map_desc.row_pitch;
-    src_data = map_desc.data;
+    data.data = map_desc.data;
+    data.row_pitch = map_desc.row_pitch;
+    data.slice_pitch = map_desc.slice_pitch;
 
     desc.resource_type = WINED3D_RTYPE_TEXTURE;
     desc.format = WINED3DFMT_B8G8R8A8_UNORM;
@@ -4006,31 +4025,15 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined
     desc.depth = 1;
     desc.size = 0;
 
-    if (FAILED(wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE,
-            NULL, &wined3d_null_parent_ops, &texture)))
+    hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE,
+            &data, NULL, &wined3d_null_parent_ops, &texture);
+    wined3d_surface_unmap(cursor_image);
+    if (FAILED(hr))
     {
         ERR("Failed to create cursor texture.\n");
-        wined3d_surface_unmap(cursor_image);
         return NULL;
     }
 
-    surface = surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
-    if (FAILED(wined3d_surface_map(surface, &map_desc, NULL, WINED3D_MAP_DISCARD)))
-    {
-        ERR("Failed to map destination surface.\n");
-        wined3d_texture_decref(texture);
-        wined3d_surface_unmap(cursor_image);
-        return NULL;
-    }
-
-    dst_data = map_desc.data;
-
-    for (i = 0; i < desc.height; ++i)
-        memcpy(&dst_data[map_desc.row_pitch * i], &src_data[src_pitch * i], desc.width * 4);
-
-    wined3d_surface_unmap(surface);
-    wined3d_surface_unmap(cursor_image);
-
     return texture;
 }
 
@@ -4313,7 +4316,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     struct wined3d_resource *resource, *cursor;
     struct wined3d_swapchain *swapchain;
     struct wined3d_display_mode m;
-    BOOL DisplayModeChanged = FALSE;
+    BOOL DisplayModeChanged;
     BOOL update_desc = FALSE;
     UINT backbuffer_width = swapchain_desc->backbuffer_width;
     UINT backbuffer_height = swapchain_desc->backbuffer_height;
@@ -4327,6 +4330,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         ERR("Failed to get the first implicit swapchain.\n");
         return WINED3DERR_INVALIDCALL;
     }
+    DisplayModeChanged = swapchain->reapply_mode;
 
     if (reset_state)
     {
@@ -4489,16 +4493,14 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     {
         UINT i;
 
-        if (FAILED(hr = wined3d_surface_update_desc(surface_from_resource(
-                wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)), swapchain->desc.backbuffer_width,
+        if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width,
                 swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
                 swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
             return hr;
 
         for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
         {
-            if (FAILED(hr = wined3d_surface_update_desc(surface_from_resource(
-                    wined3d_texture_get_sub_resource(swapchain->back_buffers[i], 0)), swapchain->desc.backbuffer_width,
+            if (FAILED(hr = wined3d_texture_update_desc(swapchain->back_buffers[i], swapchain->desc.backbuffer_width,
                     swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
                     swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
                 return hr;
@@ -4595,6 +4597,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
                         swapchain_desc->backbuffer_height,
                         TRUE);
             }
+            swapchain->d3d_mode = m;
         }
         else if (!swapchain->desc.windowed)
         {
@@ -4621,6 +4624,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         device->exStyle = exStyle;
     }
 
+    wine_rb_clear(&device->samplers, device_free_sampler, NULL);
+
     if (reset_state)
     {
         TRACE("Resetting stateblock.\n");
@@ -4858,6 +4863,21 @@ struct wined3d_surface * CDECL wined3d_device_get_surface_from_dc(const struct w
     return NULL;
 }
 
+static int wined3d_sampler_compare(const void *key, const struct wine_rb_entry *entry)
+{
+    const struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
+
+    return memcmp(&sampler->desc, key, sizeof(sampler->desc));
+}
+
+static const struct wine_rb_functions wined3d_sampler_rb_functions =
+{
+    wined3d_rb_alloc,
+    wined3d_rb_realloc,
+    wined3d_rb_free,
+    wined3d_sampler_compare,
+};
+
 HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
         UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
         BYTE surface_alignment, struct wined3d_device_parent *device_parent)
@@ -4889,12 +4909,19 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
 
     fragment_pipeline = adapter->fragment_pipe;
 
+    if (wine_rb_init(&device->samplers, &wined3d_sampler_rb_functions) == -1)
+    {
+        ERR("Failed to initialize sampler rbtree.\n");
+        return E_OUTOFMEMORY;
+    }
+
     if (vertex_pipeline->vp_states && fragment_pipeline->states
             && FAILED(hr = compile_state_table(device->StateTable, device->multistate_funcs,
             &adapter->gl_info, &adapter->d3d_info, vertex_pipeline,
             fragment_pipeline, misc_state_template)))
     {
         ERR("Failed to compile state table, hr %#x.\n", hr);
+        wine_rb_destroy(&device->samplers, NULL, NULL);
         wined3d_decref(device->wined3d);
         return hr;
     }
@@ -4924,6 +4951,7 @@ err:
     {
         HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
     }
+    wine_rb_destroy(&device->samplers, NULL, NULL);
     wined3d_decref(device->wined3d);
     return hr;
 }
@@ -4952,7 +4980,7 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state)
 LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
         UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc)
 {
-    if (device->filter_messages)
+    if (device->filter_messages && message != WM_DISPLAYCHANGE)
     {
         TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n",
                 window, message, wparam, lparam);
@@ -4976,8 +5004,23 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
     }
     else if (message == WM_ACTIVATEAPP)
     {
+        UINT i;
+
+        for (i = 0; i < device->swapchain_count; i++)
+            wined3d_swapchain_activate(device->swapchains[i], wparam);
+
         device->device_parent->ops->activate(device->device_parent, wparam);
     }
+    else if (message == WM_SYSCOMMAND)
+    {
+        if (wparam == SC_RESTORE && device->wined3d->flags & WINED3D_HANDLE_RESTORE)
+        {
+            if (unicode)
+                DefWindowProcW(window, message, wparam, lparam);
+            else
+                DefWindowProcA(window, message, wparam, lparam);
+        }
+    }
 
     if (unicode)
         return CallWindowProcW(proc, window, message, wparam, lparam);
index 267ed0b..2090993 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "wined3d_private.h"
 #include <winternl.h>
-#include <winnls.h>
 
 #include <wine/unicode.h>
 
@@ -34,10 +33,6 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
 #define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
 #define DEFAULT_REFRESH_RATE 0
 
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
-#endif
-
 /* The driver names reflect the lowest GPU supported
  * by a certain driver, so DRIVER_AMD_R300 supports
  * R3xx, R4xx and R5xx GPUs. */
@@ -55,6 +50,7 @@ enum wined3d_display_driver
     DRIVER_NVIDIA_GEFORCE2MX,
     DRIVER_NVIDIA_GEFORCEFX,
     DRIVER_NVIDIA_GEFORCE6,
+    DRIVER_NVIDIA_GEFORCE8,
     DRIVER_VMWARE,
     DRIVER_UNKNOWN
 };
@@ -113,7 +109,6 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_color_buffer_float",           ARB_COLOR_BUFFER_FLOAT        },
     {"GL_ARB_debug_output",                 ARB_DEBUG_OUTPUT              },
     {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT        },
-    {"GL_ARB_depth_clamp",                  ARB_DEPTH_CLAMP               },
     {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE             },
     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS              },
     {"GL_ARB_draw_elements_base_vertex",    ARB_DRAW_ELEMENTS_BASE_VERTEX },
@@ -136,6 +131,7 @@ 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_sampler_objects",              ARB_SAMPLER_OBJECTS           },
     {"GL_ARB_shader_bit_encoding",          ARB_SHADER_BIT_ENCODING       },
     {"GL_ARB_shader_objects",               ARB_SHADER_OBJECTS            },
     {"GL_ARB_shader_texture_lod",           ARB_SHADER_TEXTURE_LOD        },
@@ -204,7 +200,6 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_EXT_vertex_array_bgra",            EXT_VERTEX_ARRAY_BGRA         },
 
     /* NV */
-    {"GL_NV_depth_clamp",                   NV_DEPTH_CLAMP                },
     {"GL_NV_fence",                         NV_FENCE                      },
     {"GL_NV_fog_distance",                  NV_FOG_DISTANCE               },
     {"GL_NV_fragment_program",              NV_FRAGMENT_PROGRAM           },
@@ -248,34 +243,12 @@ const struct min_lookup minMipLookup[] =
     {{GL_LINEAR,    GL_LINEAR_MIPMAP_NEAREST,   GL_LINEAR_MIPMAP_LINEAR}},  /* LINEAR */
 };
 
-const struct min_lookup minMipLookup_noFilter[] =
-{
-    /* NONE         POINT                       LINEAR */
-    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
-    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* POINT */
-    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* LINEAR */
-};
-
-const struct min_lookup minMipLookup_noMip[] =
-{
-    /* NONE         POINT                       LINEAR */
-    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
-    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* POINT */
-    {{GL_LINEAR,    GL_LINEAR,                  GL_LINEAR }},               /* LINEAR */
-};
-
 const GLenum magLookup[] =
 {
     /* NONE     POINT       LINEAR */
     GL_NEAREST, GL_NEAREST, GL_LINEAR,
 };
 
-const GLenum magLookup_noFilter[] =
-{
-    /* NONE     POINT       LINEAR */
-    GL_NEAREST, GL_NEAREST, GL_NEAREST,
-};
-
 struct wined3d_caps_gl_ctx
 {
     HDC dc;
@@ -571,15 +544,15 @@ static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
     gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
     checkGLcall("Specifying the PBO test texture");
 
-    GL_EXTCALL(glGenBuffersARB(1, &pbo));
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
-    GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
+    GL_EXTCALL(glGenBuffers(1, &pbo));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo));
+    GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(pattern), pattern, GL_STREAM_DRAW));
     checkGLcall("Specifying the PBO test pbo");
 
     gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
     checkGLcall("Loading the PBO test texture");
 
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
 
     gl_info->gl_ops.gl.p_glFinish(); /* just to be sure */
 
@@ -588,7 +561,7 @@ static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
     checkGLcall("Reading back the PBO test texture");
 
     gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture);
-    GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
+    GL_EXTCALL(glDeleteBuffers(1, &pbo));
     checkGLcall("PBO test cleanup");
 
     if (memcmp(check, pattern, sizeof(check)))
@@ -1163,9 +1136,9 @@ static const struct driver_version_information driver_version_table[] =
     {DRIVER_AMD_RAGE_128PRO,    DRIVER_MODEL_NT5X,  "ati2dvaa.dll", 13, 3279,  0},
     {DRIVER_AMD_R100,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 14, 10, 6614},
     {DRIVER_AMD_R300,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 14, 10, 6764},
-    {DRIVER_AMD_R600,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 14, 10, 8681},
+    {DRIVER_AMD_R600,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 17, 10, 1280},
     {DRIVER_AMD_R300,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 14, 10, 741 },
-    {DRIVER_AMD_R600,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 14, 10, 741 },
+    {DRIVER_AMD_R600,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 17, 10, 1280 },
 
     /* Intel
      * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp
@@ -1179,7 +1152,8 @@ static const struct driver_version_information driver_version_table[] =
     {DRIVER_INTEL_GMA3000,      DRIVER_MODEL_NT6X,  "igdumd32.dll", 15, 10, 1666},
 
     /* Nvidia
-     * - Geforce6 and newer cards are supported by the current driver (197.x) on XP-Win7
+     * - Geforce8 and newer is supported by the current 340.52 driver on XP-Win8
+     * - Geforce6 and 7 support is up to 307.83 on XP-Win8
      * - GeforceFX support is up to 173.x on <= XP
      * - Geforce2MX/3/4 up to 96.x on <= XP
      * - TNT/Geforce1/2 up to 71.x on <= XP
@@ -1187,8 +1161,10 @@ static const struct driver_version_information driver_version_table[] =
     {DRIVER_NVIDIA_TNT,         DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 10, 7186},
     {DRIVER_NVIDIA_GEFORCE2MX,  DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 10, 9371},
     {DRIVER_NVIDIA_GEFORCEFX,   DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 11, 7516},
-    {DRIVER_NVIDIA_GEFORCE6,    DRIVER_MODEL_NT5X,  "nv4_disp.dll", 15, 12, 6658},
-    {DRIVER_NVIDIA_GEFORCE6,    DRIVER_MODEL_NT6X,  "nvd3dum.dll",  15, 12, 6658},
+    {DRIVER_NVIDIA_GEFORCE6,    DRIVER_MODEL_NT5X,  "nv4_disp.dll", 18, 13,  783},
+    {DRIVER_NVIDIA_GEFORCE8,    DRIVER_MODEL_NT5X,  "nv4_disp.dll", 18, 13, 4052},
+    {DRIVER_NVIDIA_GEFORCE6,    DRIVER_MODEL_NT6X,  "nvd3dum.dll",  18, 13,  783},
+    {DRIVER_NVIDIA_GEFORCE8,    DRIVER_MODEL_NT6X,  "nvd3dum.dll",  18, 13, 4052},
 
     /* VMware */
     {DRIVER_VMWARE,             DRIVER_MODEL_NT5X,  "vm3dum.dll",   14, 1,  1134},
@@ -1226,70 +1202,72 @@ static const struct gpu_description gpu_description_table[] =
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       "NVIDIA GeForce Go 7400",           DRIVER_NVIDIA_GEFORCE6,  256 },
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       "NVIDIA GeForce 7600 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     "NVIDIA GeForce 7800 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     "NVIDIA GeForce 8300 GS",           DRIVER_NVIDIA_GEFORCE6,  128 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8400GS,     "NVIDIA GeForce 8400 GS",           DRIVER_NVIDIA_GEFORCE6,  128 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     "NVIDIA GeForce 8600 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    "NVIDIA GeForce 8600M GT",          DRIVER_NVIDIA_GEFORCE6,  512 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    "NVIDIA GeForce 8800 GTS",          DRIVER_NVIDIA_GEFORCE6,  320 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTX,    "NVIDIA GeForce 8800 GTX",          DRIVER_NVIDIA_GEFORCE6,  768 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9200,       "NVIDIA GeForce 9200",              DRIVER_NVIDIA_GEFORCE6,  256 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9300,       "NVIDIA GeForce 9300",              DRIVER_NVIDIA_GEFORCE6,  256 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400M,      "NVIDIA GeForce 9400M",             DRIVER_NVIDIA_GEFORCE6,  256 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400GT,     "NVIDIA GeForce 9400 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9500GT,     "NVIDIA GeForce 9500 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           DRIVER_NVIDIA_GEFORCE6,  384 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     "NVIDIA GeForce 9800 GT",           DRIVER_NVIDIA_GEFORCE6,  512 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_210,        "NVIDIA GeForce 210",               DRIVER_NVIDIA_GEFORCE6,  512 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT220,      "NVIDIA GeForce GT 220",            DRIVER_NVIDIA_GEFORCE6,  512 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT240,      "NVIDIA GeForce GT 240",            DRIVER_NVIDIA_GEFORCE6,  512 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX260,     "NVIDIA GeForce GTX 260",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX275,     "NVIDIA GeForce GTX 275",           DRIVER_NVIDIA_GEFORCE6,  896 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     "NVIDIA GeForce GTX 280",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_315M,       "NVIDIA GeForce 315M",              DRIVER_NVIDIA_GEFORCE6,  512 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_320M,       "NVIDIA GeForce 320M",              DRIVER_NVIDIA_GEFORCE6,  256},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_410M,       "NVIDIA GeForce 410M",              DRIVER_NVIDIA_GEFORCE6,  512},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT320M,     "NVIDIA GeForce GT 320M",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT325M,     "NVIDIA GeForce GT 325M",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT330,      "NVIDIA GeForce GT 330",            DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS350M,    "NVIDIA GeForce GTS 350M",          DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT420,      "NVIDIA GeForce GT 420",            DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT430,      "NVIDIA GeForce GT 430",            DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT440,      "NVIDIA GeForce GT 440",            DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS450,     "NVIDIA GeForce GTS 450",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX460,     "NVIDIA GeForce GTX 460",           DRIVER_NVIDIA_GEFORCE6,  768 },
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX460M,    "NVIDIA GeForce GTX 460M",          DRIVER_NVIDIA_GEFORCE6,  1536},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX465,     "NVIDIA GeForce GTX 465",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX470,     "NVIDIA GeForce GTX 470",           DRIVER_NVIDIA_GEFORCE6,  1280},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX480,     "NVIDIA GeForce GTX 480",           DRIVER_NVIDIA_GEFORCE6,  1536},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT520,      "NVIDIA GeForce GT 520",            DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT540M,     "NVIDIA GeForce GT 540M",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX550,     "NVIDIA GeForce GTX 550 Ti",        DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT555M,     "NVIDIA GeForce GT 555M",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560TI,   "NVIDIA GeForce GTX 560 Ti",        DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560,     "NVIDIA GeForce GTX 560",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX570,     "NVIDIA GeForce GTX 570",           DRIVER_NVIDIA_GEFORCE6,  1280},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX580,     "NVIDIA GeForce GTX 580",           DRIVER_NVIDIA_GEFORCE6,  1536},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT610,      "NVIDIA GeForce GT 610",            DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT630,      "NVIDIA GeForce GT 630",            DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT630M,     "NVIDIA GeForce GT 630M",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT640M,     "NVIDIA GeForce GT 640M",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT650M,     "NVIDIA GeForce GT 650M",           DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX650,     "NVIDIA GeForce GTX 650",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX650TI,   "NVIDIA GeForce GTX 650 Ti",        DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660,     "NVIDIA GeForce GTX 660",           DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660M,    "NVIDIA GeForce GTX 660M",          DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660TI,   "NVIDIA GeForce GTX 660 Ti",        DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX670,     "NVIDIA GeForce GTX 670",           DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX670MX,   "NVIDIA GeForce GTX 670MX",         DRIVER_NVIDIA_GEFORCE6,  3072},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX680,     "NVIDIA GeForce GTX 680",           DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX750,     "NVIDIA GeForce GTX 750",           DRIVER_NVIDIA_GEFORCE6,  1024},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX750TI,   "NVIDIA GeForce GTX 750 Ti",        DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX760,     "NVIDIA Geforce GTX 760",           DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX765M,    "NVIDIA GeForce GTX 765M",          DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX770M,    "NVIDIA GeForce GTX 770M",          DRIVER_NVIDIA_GEFORCE6,  3072},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX770,     "NVIDIA GeForce GTX 770",           DRIVER_NVIDIA_GEFORCE6,  2048},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX780,     "NVIDIA GeForce GTX 780",           DRIVER_NVIDIA_GEFORCE6,  3072},
-    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX780TI,   "NVIDIA GeForce GTX 780 Ti",        DRIVER_NVIDIA_GEFORCE6,  3072},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     "NVIDIA GeForce 8300 GS",           DRIVER_NVIDIA_GEFORCE8,  128 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8400GS,     "NVIDIA GeForce 8400 GS",           DRIVER_NVIDIA_GEFORCE8,  128 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     "NVIDIA GeForce 8600 GT",           DRIVER_NVIDIA_GEFORCE8,  256 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    "NVIDIA GeForce 8600M GT",          DRIVER_NVIDIA_GEFORCE8,  512 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    "NVIDIA GeForce 8800 GTS",          DRIVER_NVIDIA_GEFORCE8,  320 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTX,    "NVIDIA GeForce 8800 GTX",          DRIVER_NVIDIA_GEFORCE8,  768 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9200,       "NVIDIA GeForce 9200",              DRIVER_NVIDIA_GEFORCE8,  256 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9300,       "NVIDIA GeForce 9300",              DRIVER_NVIDIA_GEFORCE8,  256 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400M,      "NVIDIA GeForce 9400M",             DRIVER_NVIDIA_GEFORCE8,  256 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400GT,     "NVIDIA GeForce 9400 GT",           DRIVER_NVIDIA_GEFORCE8,  256 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9500GT,     "NVIDIA GeForce 9500 GT",           DRIVER_NVIDIA_GEFORCE8,  256 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           DRIVER_NVIDIA_GEFORCE8,  384 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     "NVIDIA GeForce 9800 GT",           DRIVER_NVIDIA_GEFORCE8,  512 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_210,        "NVIDIA GeForce 210",               DRIVER_NVIDIA_GEFORCE8,  512 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT220,      "NVIDIA GeForce GT 220",            DRIVER_NVIDIA_GEFORCE8,  512 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT240,      "NVIDIA GeForce GT 240",            DRIVER_NVIDIA_GEFORCE8,  512 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX260,     "NVIDIA GeForce GTX 260",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX275,     "NVIDIA GeForce GTX 275",           DRIVER_NVIDIA_GEFORCE8,  896 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     "NVIDIA GeForce GTX 280",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_315M,       "NVIDIA GeForce 315M",              DRIVER_NVIDIA_GEFORCE8,  512 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_320M,       "NVIDIA GeForce 320M",              DRIVER_NVIDIA_GEFORCE8,  256},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_410M,       "NVIDIA GeForce 410M",              DRIVER_NVIDIA_GEFORCE8,  512},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT320M,     "NVIDIA GeForce GT 320M",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT325M,     "NVIDIA GeForce GT 325M",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT330,      "NVIDIA GeForce GT 330",            DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS350M,    "NVIDIA GeForce GTS 350M",          DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT420,      "NVIDIA GeForce GT 420",            DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT430,      "NVIDIA GeForce GT 430",            DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT440,      "NVIDIA GeForce GT 440",            DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS450,     "NVIDIA GeForce GTS 450",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX460,     "NVIDIA GeForce GTX 460",           DRIVER_NVIDIA_GEFORCE8,  768 },
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX460M,    "NVIDIA GeForce GTX 460M",          DRIVER_NVIDIA_GEFORCE8,  1536},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX465,     "NVIDIA GeForce GTX 465",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX470,     "NVIDIA GeForce GTX 470",           DRIVER_NVIDIA_GEFORCE8,  1280},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX480,     "NVIDIA GeForce GTX 480",           DRIVER_NVIDIA_GEFORCE8,  1536},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT520,      "NVIDIA GeForce GT 520",            DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT540M,     "NVIDIA GeForce GT 540M",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX550,     "NVIDIA GeForce GTX 550 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT555M,     "NVIDIA GeForce GT 555M",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560TI,   "NVIDIA GeForce GTX 560 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560,     "NVIDIA GeForce GTX 560",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX570,     "NVIDIA GeForce GTX 570",           DRIVER_NVIDIA_GEFORCE8,  1280},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX580,     "NVIDIA GeForce GTX 580",           DRIVER_NVIDIA_GEFORCE8,  1536},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT610,      "NVIDIA GeForce GT 610",            DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT630,      "NVIDIA GeForce GT 630",            DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT630M,     "NVIDIA GeForce GT 630M",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT640M,     "NVIDIA GeForce GT 640M",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT650M,     "NVIDIA GeForce GT 650M",           DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX650,     "NVIDIA GeForce GTX 650",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX650TI,   "NVIDIA GeForce GTX 650 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660,     "NVIDIA GeForce GTX 660",           DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660M,    "NVIDIA GeForce GTX 660M",          DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660TI,   "NVIDIA GeForce GTX 660 Ti",        DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX670,     "NVIDIA GeForce GTX 670",           DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX670MX,   "NVIDIA GeForce GTX 670MX",         DRIVER_NVIDIA_GEFORCE8,  3072},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX680,     "NVIDIA GeForce GTX 680",           DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT750M,     "NVIDIA GeForce GT 750M",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX750,     "NVIDIA GeForce GTX 750",           DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX750TI,   "NVIDIA GeForce GTX 750 Ti",        DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX760,     "NVIDIA Geforce GTX 760",           DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX765M,    "NVIDIA GeForce GTX 765M",          DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX770M,    "NVIDIA GeForce GTX 770M",          DRIVER_NVIDIA_GEFORCE8,  3072},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX770,     "NVIDIA GeForce GTX 770",           DRIVER_NVIDIA_GEFORCE8,  2048},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX780,     "NVIDIA GeForce GTX 780",           DRIVER_NVIDIA_GEFORCE8,  3072},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX780TI,   "NVIDIA GeForce GTX 780 Ti",        DRIVER_NVIDIA_GEFORCE8,  3072},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX970,     "NVIDIA GeForce GTX 970",           DRIVER_NVIDIA_GEFORCE8,  4096},
 
     /* AMD cards */
     {HW_VENDOR_AMD,        CARD_AMD_RAGE_128PRO,           "ATI Rage Fury",                    DRIVER_AMD_RAGE_128PRO,  16  },
@@ -1677,47 +1655,33 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s
     return HW_VENDOR_NVIDIA;
 }
 
-static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info);
-static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info, const struct wined3d_shader_backend_ops *shader_backend_ops);
-
-static enum wined3d_d3d_level d3d_level_from_gl_info(const struct wined3d_gl_info *gl_info)
+static enum wined3d_d3d_level d3d_level_from_caps(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps, DWORD glsl_version)
 {
-    struct shader_caps shader_caps;
-    struct fragment_caps fragment_caps;
-    const struct wined3d_shader_backend_ops *shader_backend;
-    const struct fragment_pipeline *fragment_pipeline;
-
-    shader_backend = select_shader_backend(gl_info);
-    shader_backend->shader_get_caps(gl_info, &shader_caps);
-
-    if (shader_caps.vs_version >= 5)
+    if (shader_caps->vs_version >= 5)
         return WINED3D_D3D_LEVEL_11;
-    if (shader_caps.vs_version == 4)
+    if (shader_caps->vs_version == 4)
     {
         /* No backed supports SM 5 at the moment */
-        if (gl_info->glsl_version >= MAKEDWORD_VERSION(4, 00))
+        if (glsl_version >= MAKEDWORD_VERSION(4, 00))
             return WINED3D_D3D_LEVEL_11;
         return WINED3D_D3D_LEVEL_10;
     }
-    if (shader_caps.vs_version == 3)
+    if (shader_caps->vs_version == 3)
     {
-        /* Wine can not use SM 4 on mesa drivers as the necessary functionality is not exposed
-         * on compatibility contexts */
-        if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30))
+        /* Wine cannot use SM 4 on mesa drivers as the necessary functionality
+         * is not exposed on compatibility contexts */
+        if (glsl_version >= MAKEDWORD_VERSION(1, 30))
             return WINED3D_D3D_LEVEL_10;
         return WINED3D_D3D_LEVEL_9_SM3;
     }
-    if (shader_caps.vs_version == 2)
+    if (shader_caps->vs_version == 2)
         return WINED3D_D3D_LEVEL_9_SM2;
-    if (shader_caps.vs_version == 1)
+    if (shader_caps->vs_version == 1)
         return WINED3D_D3D_LEVEL_8;
 
-    fragment_pipeline = select_fragment_implementation(gl_info, shader_backend);
-    fragment_pipeline->get_caps(gl_info, &fragment_caps);
-
-    if (fragment_caps.TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3)
+    if (fragment_caps->TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3)
         return WINED3D_D3D_LEVEL_7;
-    if (fragment_caps.MaxSimultaneousTextures > 1)
+    if (fragment_caps->MaxSimultaneousTextures > 1)
         return WINED3D_D3D_LEVEL_6;
 
     return WINED3D_D3D_LEVEL_5;
@@ -1731,6 +1695,7 @@ static const struct wined3d_renderer_table
 cards_nvidia_binary[] =
 {
     /* Direct 3D 11 */
+    {"GTX 970",                     CARD_NVIDIA_GEFORCE_GTX970},    /* GeForce 900 - highend */
     {"GTX 780 Ti",                  CARD_NVIDIA_GEFORCE_GTX780TI},  /* Geforce 700 - highend */
     {"GTX 780",                     CARD_NVIDIA_GEFORCE_GTX780},    /* Geforce 700 - highend */
     {"GTX 770M",                    CARD_NVIDIA_GEFORCE_GTX770M},   /* Geforce 700 - midend high mobile */
@@ -1739,6 +1704,7 @@ cards_nvidia_binary[] =
     {"GTX 760",                     CARD_NVIDIA_GEFORCE_GTX760},    /* Geforce 700 - midend high  */
     {"GTX 750 Ti",                  CARD_NVIDIA_GEFORCE_GTX750TI},  /* Geforce 700 - midend */
     {"GTX 750",                     CARD_NVIDIA_GEFORCE_GTX750},    /* Geforce 700 - midend */
+    {"GT 750M",                     CARD_NVIDIA_GEFORCE_GT750M},    /* Geforce 700 - midend mobile */
     {"GTX 680",                     CARD_NVIDIA_GEFORCE_GTX680},    /* Geforce 600 - highend */
     {"GTX 670MX",                   CARD_NVIDIA_GEFORCE_GTX670MX},  /* Geforce 600 - highend */
     {"GTX 670",                     CARD_NVIDIA_GEFORCE_GTX670},    /* Geforce 600 - midend high */
@@ -2084,6 +2050,7 @@ cards_amd_mesa[] =
 cards_nvidia_mesa[] =
 {
     /* Maxwell */
+    {"NV124",                       CARD_NVIDIA_GEFORCE_GTX970},
     {"NV117",                       CARD_NVIDIA_GEFORCE_GTX750},
     /* Kepler */
     {"NVF1",                        CARD_NVIDIA_GEFORCE_GTX780TI},
@@ -2215,12 +2182,12 @@ card_fallback_amd[] =
 },
 card_fallback_intel[] =
 {
-    CARD_INTEL_915G,                /* D3D5 */
-    CARD_INTEL_915G,                /* D3D6 */
-    CARD_INTEL_915G,                /* D3D7 */
+    CARD_INTEL_845G,                /* D3D5 */
+    CARD_INTEL_845G,                /* D3D6 */
+    CARD_INTEL_845G,                /* D3D7 */
     CARD_INTEL_915G,                /* D3D8 */
     CARD_INTEL_915G,                /* D3D9_SM2 */
-    CARD_INTEL_915G,                /* D3D9_SM3 */
+    CARD_INTEL_945G,                /* D3D9_SM3 */
     CARD_INTEL_G45,                 /* D3D10 */
     CARD_INTEL_IVBD,                /* D3D11 */
 };
@@ -2278,8 +2245,8 @@ card_vendor_table[] =
 };
 
 
-static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
-        enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor)
+static enum wined3d_pci_device wined3d_guess_card(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps,
+        DWORD glsl_version, const char *gl_renderer, enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor)
 {
     /* A Direct3D device object contains the PCI id (vendor + device) of the
      * videocard which is used for rendering. Various applications use this
@@ -2332,7 +2299,7 @@ static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *
      * memory can be overruled using a registry setting. */
 
     unsigned int i;
-    enum wined3d_d3d_level d3d_level = d3d_level_from_gl_info(gl_info);
+    enum wined3d_d3d_level d3d_level = d3d_level_from_caps(shader_caps, fragment_caps, glsl_version);
     enum wined3d_pci_device device;
 
     for (i = 0; i < (sizeof(card_vendor_table) / sizeof(*card_vendor_table)); ++i)
@@ -2450,7 +2417,543 @@ static void parse_extension_string(struct wined3d_gl_info *gl_info, const char *
 static void load_gl_funcs(struct wined3d_gl_info *gl_info)
 {
 #define USE_GL_FUNC(pfn) gl_info->gl_ops.ext.p_##pfn = (void *)wglGetProcAddress(#pfn);
-    GL_EXT_FUNCS_GEN;
+    /* GL_APPLE_fence */
+    USE_GL_FUNC(glDeleteFencesAPPLE)
+    USE_GL_FUNC(glFinishFenceAPPLE)
+    USE_GL_FUNC(glFinishObjectAPPLE)
+    USE_GL_FUNC(glGenFencesAPPLE)
+    USE_GL_FUNC(glIsFenceAPPLE)
+    USE_GL_FUNC(glSetFenceAPPLE)
+    USE_GL_FUNC(glTestFenceAPPLE)
+    USE_GL_FUNC(glTestObjectAPPLE)
+    /* GL_APPLE_flush_buffer_range */
+    USE_GL_FUNC(glBufferParameteriAPPLE)
+    USE_GL_FUNC(glFlushMappedBufferRangeAPPLE)
+    /* GL_ARB_blend_func_extended */
+    USE_GL_FUNC(glBindFragDataLocationIndexed)
+    USE_GL_FUNC(glGetFragDataIndex)
+    /* GL_ARB_color_buffer_float */
+    USE_GL_FUNC(glClampColorARB)
+    /* GL_ARB_debug_output */
+    USE_GL_FUNC(glDebugMessageCallbackARB)
+    USE_GL_FUNC(glDebugMessageControlARB)
+    USE_GL_FUNC(glDebugMessageInsertARB)
+    USE_GL_FUNC(glGetDebugMessageLogARB)
+    /* GL_ARB_draw_buffers */
+    USE_GL_FUNC(glDrawBuffersARB)
+    /* GL_ARB_draw_elements_base_vertex */
+    USE_GL_FUNC(glDrawElementsBaseVertex)
+    USE_GL_FUNC(glDrawElementsInstancedBaseVertex)
+    USE_GL_FUNC(glDrawRangeElementsBaseVertex)
+    USE_GL_FUNC(glMultiDrawElementsBaseVertex)
+    /* GL_ARB_draw_instanced */
+    USE_GL_FUNC(glDrawArraysInstancedARB)
+    USE_GL_FUNC(glDrawElementsInstancedARB)
+    /* GL_ARB_framebuffer_object */
+    USE_GL_FUNC(glBindFramebuffer)
+    USE_GL_FUNC(glBindRenderbuffer)
+    USE_GL_FUNC(glBlitFramebuffer)
+    USE_GL_FUNC(glCheckFramebufferStatus)
+    USE_GL_FUNC(glDeleteFramebuffers)
+    USE_GL_FUNC(glDeleteRenderbuffers)
+    USE_GL_FUNC(glFramebufferRenderbuffer)
+    USE_GL_FUNC(glFramebufferTexture1D)
+    USE_GL_FUNC(glFramebufferTexture2D)
+    USE_GL_FUNC(glFramebufferTexture3D)
+    USE_GL_FUNC(glFramebufferTextureLayer)
+    USE_GL_FUNC(glGenFramebuffers)
+    USE_GL_FUNC(glGenRenderbuffers)
+    USE_GL_FUNC(glGenerateMipmap)
+    USE_GL_FUNC(glGetFramebufferAttachmentParameteriv)
+    USE_GL_FUNC(glGetRenderbufferParameteriv)
+    USE_GL_FUNC(glIsFramebuffer)
+    USE_GL_FUNC(glIsRenderbuffer)
+    USE_GL_FUNC(glRenderbufferStorage)
+    USE_GL_FUNC(glRenderbufferStorageMultisample)
+    /* GL_ARB_geometry_shader4 */
+    USE_GL_FUNC(glFramebufferTextureARB)
+    USE_GL_FUNC(glFramebufferTextureFaceARB)
+    USE_GL_FUNC(glFramebufferTextureLayerARB)
+    USE_GL_FUNC(glProgramParameteriARB)
+    /* GL_ARB_instanced_arrays */
+    USE_GL_FUNC(glVertexAttribDivisorARB)
+    /* GL_ARB_internalformat_query */
+    USE_GL_FUNC(glGetInternalformativ)
+    /* GL_ARB_internalformat_query2 */
+    USE_GL_FUNC(glGetInternalformati64v)
+    /* GL_ARB_map_buffer_range */
+    USE_GL_FUNC(glFlushMappedBufferRange)
+    USE_GL_FUNC(glMapBufferRange)
+    /* GL_ARB_multisample */
+    USE_GL_FUNC(glSampleCoverageARB)
+    /* GL_ARB_multitexture */
+    USE_GL_FUNC(glActiveTextureARB)
+    USE_GL_FUNC(glClientActiveTextureARB)
+    USE_GL_FUNC(glMultiTexCoord1fARB)
+    USE_GL_FUNC(glMultiTexCoord1fvARB)
+    USE_GL_FUNC(glMultiTexCoord2fARB)
+    USE_GL_FUNC(glMultiTexCoord2fvARB)
+    USE_GL_FUNC(glMultiTexCoord2svARB)
+    USE_GL_FUNC(glMultiTexCoord3fARB)
+    USE_GL_FUNC(glMultiTexCoord3fvARB)
+    USE_GL_FUNC(glMultiTexCoord4fARB)
+    USE_GL_FUNC(glMultiTexCoord4fvARB)
+    USE_GL_FUNC(glMultiTexCoord4svARB)
+    /* GL_ARB_occlusion_query */
+    USE_GL_FUNC(glBeginQueryARB)
+    USE_GL_FUNC(glDeleteQueriesARB)
+    USE_GL_FUNC(glEndQueryARB)
+    USE_GL_FUNC(glGenQueriesARB)
+    USE_GL_FUNC(glGetQueryivARB)
+    USE_GL_FUNC(glGetQueryObjectivARB)
+    USE_GL_FUNC(glGetQueryObjectuivARB)
+    USE_GL_FUNC(glIsQueryARB)
+    /* GL_ARB_point_parameters */
+    USE_GL_FUNC(glPointParameterfARB)
+    USE_GL_FUNC(glPointParameterfvARB)
+    /* GL_ARB_provoking_vertex */
+    USE_GL_FUNC(glProvokingVertex)
+    /* GL_ARB_sampler_objects */
+    USE_GL_FUNC(glGenSamplers)
+    USE_GL_FUNC(glDeleteSamplers)
+    USE_GL_FUNC(glIsSampler)
+    USE_GL_FUNC(glBindSampler)
+    USE_GL_FUNC(glSamplerParameteri)
+    USE_GL_FUNC(glSamplerParameterf)
+    USE_GL_FUNC(glSamplerParameteriv)
+    USE_GL_FUNC(glSamplerParameterfv)
+    USE_GL_FUNC(glSamplerParameterIiv)
+    USE_GL_FUNC(glSamplerParameterIuiv)
+    USE_GL_FUNC(glGetSamplerParameteriv)
+    USE_GL_FUNC(glGetSamplerParameterfv)
+    USE_GL_FUNC(glGetSamplerParameterIiv)
+    USE_GL_FUNC(glGetSamplerParameterIuiv)
+    /* GL_ARB_shader_objects */
+    USE_GL_FUNC(glAttachObjectARB)
+    USE_GL_FUNC(glBindAttribLocationARB)
+    USE_GL_FUNC(glCompileShaderARB)
+    USE_GL_FUNC(glCreateProgramObjectARB)
+    USE_GL_FUNC(glCreateShaderObjectARB)
+    USE_GL_FUNC(glDeleteObjectARB)
+    USE_GL_FUNC(glDetachObjectARB)
+    USE_GL_FUNC(glGetActiveUniformARB)
+    USE_GL_FUNC(glGetAttachedObjectsARB)
+    USE_GL_FUNC(glGetAttribLocationARB)
+    USE_GL_FUNC(glGetHandleARB)
+    USE_GL_FUNC(glGetInfoLogARB)
+    USE_GL_FUNC(glGetObjectParameterfvARB)
+    USE_GL_FUNC(glGetObjectParameterivARB)
+    USE_GL_FUNC(glGetShaderSourceARB)
+    USE_GL_FUNC(glGetUniformLocationARB)
+    USE_GL_FUNC(glGetUniformfvARB)
+    USE_GL_FUNC(glGetUniformivARB)
+    USE_GL_FUNC(glLinkProgramARB)
+    USE_GL_FUNC(glShaderSourceARB)
+    USE_GL_FUNC(glUniform1fARB)
+    USE_GL_FUNC(glUniform1fvARB)
+    USE_GL_FUNC(glUniform1iARB)
+    USE_GL_FUNC(glUniform1ivARB)
+    USE_GL_FUNC(glUniform2fARB)
+    USE_GL_FUNC(glUniform2fvARB)
+    USE_GL_FUNC(glUniform2iARB)
+    USE_GL_FUNC(glUniform2ivARB)
+    USE_GL_FUNC(glUniform3fARB)
+    USE_GL_FUNC(glUniform3fvARB)
+    USE_GL_FUNC(glUniform3iARB)
+    USE_GL_FUNC(glUniform3ivARB)
+    USE_GL_FUNC(glUniform4fARB)
+    USE_GL_FUNC(glUniform4fvARB)
+    USE_GL_FUNC(glUniform4iARB)
+    USE_GL_FUNC(glUniform4ivARB)
+    USE_GL_FUNC(glUniformMatrix2fvARB)
+    USE_GL_FUNC(glUniformMatrix3fvARB)
+    USE_GL_FUNC(glUniformMatrix4fvARB)
+    USE_GL_FUNC(glUseProgramObjectARB)
+    USE_GL_FUNC(glValidateProgramARB)
+    /* GL_ARB_sync */
+    USE_GL_FUNC(glClientWaitSync)
+    USE_GL_FUNC(glDeleteSync)
+    USE_GL_FUNC(glFenceSync)
+    USE_GL_FUNC(glGetInteger64v)
+    USE_GL_FUNC(glGetSynciv)
+    USE_GL_FUNC(glIsSync)
+    USE_GL_FUNC(glWaitSync)
+    /* GL_ARB_texture_compression */
+    USE_GL_FUNC(glCompressedTexImage2DARB)
+    USE_GL_FUNC(glCompressedTexImage3DARB)
+    USE_GL_FUNC(glCompressedTexSubImage2DARB)
+    USE_GL_FUNC(glCompressedTexSubImage3DARB)
+    USE_GL_FUNC(glGetCompressedTexImageARB)
+    /* GL_ARB_timer_query */
+    USE_GL_FUNC(glQueryCounter)
+    USE_GL_FUNC(glGetQueryObjectui64v)
+    /* GL_ARB_uniform_buffer_object */
+    USE_GL_FUNC(glBindBufferBase)
+    USE_GL_FUNC(glBindBufferRange)
+    USE_GL_FUNC(glGetActiveUniformBlockName)
+    USE_GL_FUNC(glGetActiveUniformBlockiv)
+    USE_GL_FUNC(glGetActiveUniformName)
+    USE_GL_FUNC(glGetActiveUniformsiv)
+    USE_GL_FUNC(glGetIntegeri_v)
+    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)
+    USE_GL_FUNC(glBufferSubDataARB)
+    USE_GL_FUNC(glDeleteBuffersARB)
+    USE_GL_FUNC(glGenBuffersARB)
+    USE_GL_FUNC(glGetBufferParameterivARB)
+    USE_GL_FUNC(glGetBufferPointervARB)
+    USE_GL_FUNC(glGetBufferSubDataARB)
+    USE_GL_FUNC(glIsBufferARB)
+    USE_GL_FUNC(glMapBufferARB)
+    USE_GL_FUNC(glUnmapBufferARB)
+    /* GL_ARB_vertex_program */
+    USE_GL_FUNC(glBindProgramARB)
+    USE_GL_FUNC(glDeleteProgramsARB)
+    USE_GL_FUNC(glDisableVertexAttribArrayARB)
+    USE_GL_FUNC(glEnableVertexAttribArrayARB)
+    USE_GL_FUNC(glGenProgramsARB)
+    USE_GL_FUNC(glGetProgramivARB)
+    USE_GL_FUNC(glProgramEnvParameter4fvARB)
+    USE_GL_FUNC(glProgramLocalParameter4fvARB)
+    USE_GL_FUNC(glProgramStringARB)
+    USE_GL_FUNC(glVertexAttrib1dARB)
+    USE_GL_FUNC(glVertexAttrib1dvARB)
+    USE_GL_FUNC(glVertexAttrib1fARB)
+    USE_GL_FUNC(glVertexAttrib1fvARB)
+    USE_GL_FUNC(glVertexAttrib1sARB)
+    USE_GL_FUNC(glVertexAttrib1svARB)
+    USE_GL_FUNC(glVertexAttrib2dARB)
+    USE_GL_FUNC(glVertexAttrib2dvARB)
+    USE_GL_FUNC(glVertexAttrib2fARB)
+    USE_GL_FUNC(glVertexAttrib2fvARB)
+    USE_GL_FUNC(glVertexAttrib2sARB)
+    USE_GL_FUNC(glVertexAttrib2svARB)
+    USE_GL_FUNC(glVertexAttrib3dARB)
+    USE_GL_FUNC(glVertexAttrib3dvARB)
+    USE_GL_FUNC(glVertexAttrib3fARB)
+    USE_GL_FUNC(glVertexAttrib3fvARB)
+    USE_GL_FUNC(glVertexAttrib3sARB)
+    USE_GL_FUNC(glVertexAttrib3svARB)
+    USE_GL_FUNC(glVertexAttrib4NbvARB)
+    USE_GL_FUNC(glVertexAttrib4NivARB)
+    USE_GL_FUNC(glVertexAttrib4NsvARB)
+    USE_GL_FUNC(glVertexAttrib4NubARB)
+    USE_GL_FUNC(glVertexAttrib4NubvARB)
+    USE_GL_FUNC(glVertexAttrib4NuivARB)
+    USE_GL_FUNC(glVertexAttrib4NusvARB)
+    USE_GL_FUNC(glVertexAttrib4bvARB)
+    USE_GL_FUNC(glVertexAttrib4dARB)
+    USE_GL_FUNC(glVertexAttrib4dvARB)
+    USE_GL_FUNC(glVertexAttrib4fARB)
+    USE_GL_FUNC(glVertexAttrib4fvARB)
+    USE_GL_FUNC(glVertexAttrib4ivARB)
+    USE_GL_FUNC(glVertexAttrib4sARB)
+    USE_GL_FUNC(glVertexAttrib4svARB)
+    USE_GL_FUNC(glVertexAttrib4ubvARB)
+    USE_GL_FUNC(glVertexAttrib4uivARB)
+    USE_GL_FUNC(glVertexAttrib4usvARB)
+    USE_GL_FUNC(glVertexAttribPointerARB)
+    /* GL_ATI_fragment_shader */
+    USE_GL_FUNC(glAlphaFragmentOp1ATI)
+    USE_GL_FUNC(glAlphaFragmentOp2ATI)
+    USE_GL_FUNC(glAlphaFragmentOp3ATI)
+    USE_GL_FUNC(glBeginFragmentShaderATI)
+    USE_GL_FUNC(glBindFragmentShaderATI)
+    USE_GL_FUNC(glColorFragmentOp1ATI)
+    USE_GL_FUNC(glColorFragmentOp2ATI)
+    USE_GL_FUNC(glColorFragmentOp3ATI)
+    USE_GL_FUNC(glDeleteFragmentShaderATI)
+    USE_GL_FUNC(glEndFragmentShaderATI)
+    USE_GL_FUNC(glGenFragmentShadersATI)
+    USE_GL_FUNC(glPassTexCoordATI)
+    USE_GL_FUNC(glSampleMapATI)
+    USE_GL_FUNC(glSetFragmentShaderConstantATI)
+    /* GL_ATI_separate_stencil */
+    USE_GL_FUNC(glStencilOpSeparateATI)
+    USE_GL_FUNC(glStencilFuncSeparateATI)
+    /* GL_EXT_blend_color */
+    USE_GL_FUNC(glBlendColorEXT)
+    /* GL_EXT_blend_equation_separate */
+    USE_GL_FUNC(glBlendFuncSeparateEXT)
+    /* GL_EXT_blend_func_separate */
+    USE_GL_FUNC(glBlendEquationSeparateEXT)
+    /* GL_EXT_blend_minmax */
+    USE_GL_FUNC(glBlendEquationEXT)
+    /* GL_EXT_depth_bounds_test */
+    USE_GL_FUNC(glDepthBoundsEXT)
+    /* GL_EXT_draw_buffers2 */
+    USE_GL_FUNC(glColorMaskIndexedEXT)
+    USE_GL_FUNC(glDisableIndexedEXT)
+    USE_GL_FUNC(glEnableIndexedEXT)
+    USE_GL_FUNC(glGetBooleanIndexedvEXT)
+    USE_GL_FUNC(glGetIntegerIndexedvEXT)
+    USE_GL_FUNC(glIsEnabledIndexedEXT)
+    /* GL_EXT_fog_coord */
+    USE_GL_FUNC(glFogCoordPointerEXT)
+    USE_GL_FUNC(glFogCoorddEXT)
+    USE_GL_FUNC(glFogCoorddvEXT)
+    USE_GL_FUNC(glFogCoordfEXT)
+    USE_GL_FUNC(glFogCoordfvEXT)
+    /* GL_EXT_framebuffer_blit */
+    USE_GL_FUNC(glBlitFramebufferEXT)
+    /* GL_EXT_framebuffer_multisample */
+    USE_GL_FUNC(glRenderbufferStorageMultisampleEXT)
+    /* GL_EXT_framebuffer_object */
+    USE_GL_FUNC(glBindFramebufferEXT)
+    USE_GL_FUNC(glBindRenderbufferEXT)
+    USE_GL_FUNC(glCheckFramebufferStatusEXT)
+    USE_GL_FUNC(glDeleteFramebuffersEXT)
+    USE_GL_FUNC(glDeleteRenderbuffersEXT)
+    USE_GL_FUNC(glFramebufferRenderbufferEXT)
+    USE_GL_FUNC(glFramebufferTexture1DEXT)
+    USE_GL_FUNC(glFramebufferTexture2DEXT)
+    USE_GL_FUNC(glFramebufferTexture3DEXT)
+    USE_GL_FUNC(glGenFramebuffersEXT)
+    USE_GL_FUNC(glGenRenderbuffersEXT)
+    USE_GL_FUNC(glGenerateMipmapEXT)
+    USE_GL_FUNC(glGetFramebufferAttachmentParameterivEXT)
+    USE_GL_FUNC(glGetRenderbufferParameterivEXT)
+    USE_GL_FUNC(glIsFramebufferEXT)
+    USE_GL_FUNC(glIsRenderbufferEXT)
+    USE_GL_FUNC(glRenderbufferStorageEXT)
+    /* GL_EXT_gpu_program_parameters */
+    USE_GL_FUNC(glProgramEnvParameters4fvEXT)
+    USE_GL_FUNC(glProgramLocalParameters4fvEXT)
+    /* GL_EXT_gpu_shader4 */
+    USE_GL_FUNC(glBindFragDataLocationEXT)
+    USE_GL_FUNC(glGetFragDataLocationEXT)
+    USE_GL_FUNC(glGetUniformuivEXT)
+    USE_GL_FUNC(glGetVertexAttribIivEXT)
+    USE_GL_FUNC(glGetVertexAttribIuivEXT)
+    USE_GL_FUNC(glUniform1uiEXT)
+    USE_GL_FUNC(glUniform1uivEXT)
+    USE_GL_FUNC(glUniform2uiEXT)
+    USE_GL_FUNC(glUniform2uivEXT)
+    USE_GL_FUNC(glUniform3uiEXT)
+    USE_GL_FUNC(glUniform3uivEXT)
+    USE_GL_FUNC(glUniform4uiEXT)
+    USE_GL_FUNC(glUniform4uivEXT)
+    USE_GL_FUNC(glVertexAttribI1iEXT)
+    USE_GL_FUNC(glVertexAttribI1ivEXT)
+    USE_GL_FUNC(glVertexAttribI1uiEXT)
+    USE_GL_FUNC(glVertexAttribI1uivEXT)
+    USE_GL_FUNC(glVertexAttribI2iEXT)
+    USE_GL_FUNC(glVertexAttribI2ivEXT)
+    USE_GL_FUNC(glVertexAttribI2uiEXT)
+    USE_GL_FUNC(glVertexAttribI2uivEXT)
+    USE_GL_FUNC(glVertexAttribI3iEXT)
+    USE_GL_FUNC(glVertexAttribI3ivEXT)
+    USE_GL_FUNC(glVertexAttribI3uiEXT)
+    USE_GL_FUNC(glVertexAttribI3uivEXT)
+    USE_GL_FUNC(glVertexAttribI4bvEXT)
+    USE_GL_FUNC(glVertexAttribI4iEXT)
+    USE_GL_FUNC(glVertexAttribI4ivEXT)
+    USE_GL_FUNC(glVertexAttribI4svEXT)
+    USE_GL_FUNC(glVertexAttribI4ubvEXT)
+    USE_GL_FUNC(glVertexAttribI4uiEXT)
+    USE_GL_FUNC(glVertexAttribI4uivEXT)
+    USE_GL_FUNC(glVertexAttribI4usvEXT)
+    USE_GL_FUNC(glVertexAttribIPointerEXT)
+    /* GL_EXT_point_parameters */
+    USE_GL_FUNC(glPointParameterfEXT)
+    USE_GL_FUNC(glPointParameterfvEXT)
+    /* GL_EXT_provoking_vertex */
+    USE_GL_FUNC(glProvokingVertexEXT)
+    /* GL_EXT_secondary_color */
+    USE_GL_FUNC(glSecondaryColor3fEXT)
+    USE_GL_FUNC(glSecondaryColor3fvEXT)
+    USE_GL_FUNC(glSecondaryColor3ubEXT)
+    USE_GL_FUNC(glSecondaryColor3ubvEXT)
+    USE_GL_FUNC(glSecondaryColorPointerEXT)
+    /* GL_EXT_stencil_two_side */
+    USE_GL_FUNC(glActiveStencilFaceEXT)
+    /* GL_EXT_texture3D */
+    USE_GL_FUNC(glTexImage3D)
+    USE_GL_FUNC(glTexImage3DEXT)
+    USE_GL_FUNC(glTexSubImage3D)
+    USE_GL_FUNC(glTexSubImage3DEXT)
+    /* GL_NV_fence */
+    USE_GL_FUNC(glDeleteFencesNV)
+    USE_GL_FUNC(glFinishFenceNV)
+    USE_GL_FUNC(glGenFencesNV)
+    USE_GL_FUNC(glGetFenceivNV)
+    USE_GL_FUNC(glIsFenceNV)
+    USE_GL_FUNC(glSetFenceNV)
+    USE_GL_FUNC(glTestFenceNV)
+    /* GL_NV_half_float */
+    USE_GL_FUNC(glColor3hNV)
+    USE_GL_FUNC(glColor3hvNV)
+    USE_GL_FUNC(glColor4hNV)
+    USE_GL_FUNC(glColor4hvNV)
+    USE_GL_FUNC(glFogCoordhNV)
+    USE_GL_FUNC(glFogCoordhvNV)
+    USE_GL_FUNC(glMultiTexCoord1hNV)
+    USE_GL_FUNC(glMultiTexCoord1hvNV)
+    USE_GL_FUNC(glMultiTexCoord2hNV)
+    USE_GL_FUNC(glMultiTexCoord2hvNV)
+    USE_GL_FUNC(glMultiTexCoord3hNV)
+    USE_GL_FUNC(glMultiTexCoord3hvNV)
+    USE_GL_FUNC(glMultiTexCoord4hNV)
+    USE_GL_FUNC(glMultiTexCoord4hvNV)
+    USE_GL_FUNC(glNormal3hNV)
+    USE_GL_FUNC(glNormal3hvNV)
+    USE_GL_FUNC(glSecondaryColor3hNV)
+    USE_GL_FUNC(glSecondaryColor3hvNV)
+    USE_GL_FUNC(glTexCoord1hNV)
+    USE_GL_FUNC(glTexCoord1hvNV)
+    USE_GL_FUNC(glTexCoord2hNV)
+    USE_GL_FUNC(glTexCoord2hvNV)
+    USE_GL_FUNC(glTexCoord3hNV)
+    USE_GL_FUNC(glTexCoord3hvNV)
+    USE_GL_FUNC(glTexCoord4hNV)
+    USE_GL_FUNC(glTexCoord4hvNV)
+    USE_GL_FUNC(glVertex2hNV)
+    USE_GL_FUNC(glVertex2hvNV)
+    USE_GL_FUNC(glVertex3hNV)
+    USE_GL_FUNC(glVertex3hvNV)
+    USE_GL_FUNC(glVertex4hNV)
+    USE_GL_FUNC(glVertex4hvNV)
+    USE_GL_FUNC(glVertexAttrib1hNV)
+    USE_GL_FUNC(glVertexAttrib1hvNV)
+    USE_GL_FUNC(glVertexAttrib2hNV)
+    USE_GL_FUNC(glVertexAttrib2hvNV)
+    USE_GL_FUNC(glVertexAttrib3hNV)
+    USE_GL_FUNC(glVertexAttrib3hvNV)
+    USE_GL_FUNC(glVertexAttrib4hNV)
+    USE_GL_FUNC(glVertexAttrib4hvNV)
+    USE_GL_FUNC(glVertexAttribs1hvNV)
+    USE_GL_FUNC(glVertexAttribs2hvNV)
+    USE_GL_FUNC(glVertexAttribs3hvNV)
+    USE_GL_FUNC(glVertexAttribs4hvNV)
+    USE_GL_FUNC(glVertexWeighthNV)
+    USE_GL_FUNC(glVertexWeighthvNV)
+    /* GL_NV_point_sprite */
+    USE_GL_FUNC(glPointParameteriNV)
+    USE_GL_FUNC(glPointParameterivNV)
+    /* GL_NV_register_combiners */
+    USE_GL_FUNC(glCombinerInputNV)
+    USE_GL_FUNC(glCombinerOutputNV)
+    USE_GL_FUNC(glCombinerParameterfNV)
+    USE_GL_FUNC(glCombinerParameterfvNV)
+    USE_GL_FUNC(glCombinerParameteriNV)
+    USE_GL_FUNC(glCombinerParameterivNV)
+    USE_GL_FUNC(glFinalCombinerInputNV)
+    /* WGL extensions */
+    USE_GL_FUNC(wglChoosePixelFormatARB)
+    USE_GL_FUNC(wglGetExtensionsStringARB)
+    USE_GL_FUNC(wglGetPixelFormatAttribfvARB)
+    USE_GL_FUNC(wglGetPixelFormatAttribivARB)
+    USE_GL_FUNC(wglSetPixelFormatWINE)
+    USE_GL_FUNC(wglSwapIntervalEXT)
+
+    /* Newer core functions */
+    USE_GL_FUNC(glActiveTexture)            /* OpenGL 1.3 */
+    USE_GL_FUNC(glAttachShader)             /* OpenGL 2.0 */
+    USE_GL_FUNC(glBeginQuery)               /* OpenGL 1.5 */
+    USE_GL_FUNC(glBindAttribLocation)       /* OpenGL 2.0 */
+    USE_GL_FUNC(glBindBuffer)               /* OpenGL 1.5 */
+    USE_GL_FUNC(glBlendColor)               /* OpenGL 1.4 */
+    USE_GL_FUNC(glBlendEquation)            /* OpenGL 1.4 */
+    USE_GL_FUNC(glBlendEquationSeparate)    /* OpenGL 2.0 */
+    USE_GL_FUNC(glBlendFuncSeparate)        /* OpenGL 1.4 */
+    USE_GL_FUNC(glBufferData)               /* OpenGL 1.5 */
+    USE_GL_FUNC(glBufferSubData)            /* OpenGL 1.5 */
+    USE_GL_FUNC(glColorMaski)               /* OpenGL 3.0 */
+    USE_GL_FUNC(glCompileShader)            /* OpenGL 2.0 */
+    USE_GL_FUNC(glCompressedTexImage2D)     /* OpenGL 1.3 */
+    USE_GL_FUNC(glCompressedTexImage3D)     /* OpenGL 1.3 */
+    USE_GL_FUNC(glCompressedTexSubImage2D)  /* OpenGL 1.3 */
+    USE_GL_FUNC(glCompressedTexSubImage3D)  /* OpenGL 1.3 */
+    USE_GL_FUNC(glCreateProgram)            /* OpenGL 2.0 */
+    USE_GL_FUNC(glCreateShader)             /* OpenGL 2.0 */
+    USE_GL_FUNC(glDeleteBuffers)            /* OpenGL 1.5 */
+    USE_GL_FUNC(glDeleteProgram)            /* OpenGL 2.0 */
+    USE_GL_FUNC(glDeleteQueries)            /* OpenGL 1.5 */
+    USE_GL_FUNC(glDeleteShader)             /* OpenGL 2.0 */
+    USE_GL_FUNC(glDetachShader)             /* OpenGL 2.0 */
+    USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */
+    USE_GL_FUNC(glDrawBuffers)              /* OpenGL 2.0 */
+    USE_GL_FUNC(glDrawElementsInstanced)    /* OpenGL 3.1 */
+    USE_GL_FUNC(glEnableVertexAttribArray)  /* OpenGL 2.0 */
+    USE_GL_FUNC(glEndQuery)                 /* OpenGL 1.5 */
+    USE_GL_FUNC(glGenBuffers)               /* OpenGL 1.5 */
+    USE_GL_FUNC(glGenQueries)               /* OpenGL 1.5 */
+    USE_GL_FUNC(glGetActiveUniform)         /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetAttachedShaders)       /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetAttribLocation)        /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetBufferSubData)         /* OpenGL 1.5 */
+    USE_GL_FUNC(glGetCompressedTexImage)    /* OpenGL 1.3 */
+    USE_GL_FUNC(glGetProgramInfoLog)        /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetProgramiv)             /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetQueryiv)               /* OpenGL 1.5 */
+    USE_GL_FUNC(glGetQueryObjectuiv)        /* OpenGL 1.5 */
+    USE_GL_FUNC(glGetShaderInfoLog)         /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetShaderiv)              /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetShaderSource)          /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetUniformfv)             /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetUniformiv)             /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetUniformLocation)       /* OpenGL 2.0 */
+    USE_GL_FUNC(glLinkProgram)              /* OpenGL 2.0 */
+    USE_GL_FUNC(glMapBuffer)                /* OpenGL 1.5 */
+    USE_GL_FUNC(glPointParameteri)          /* OpenGL 1.4 */
+    USE_GL_FUNC(glPointParameteriv)         /* OpenGL 1.4 */
+    USE_GL_FUNC(glShaderSource)             /* OpenGL 2.0 */
+    USE_GL_FUNC(glStencilFuncSeparate)      /* OpenGL 2.0 */
+    USE_GL_FUNC(glStencilOpSeparate)        /* OpenGL 2.0 */
+    USE_GL_FUNC(glTexImage3D)               /* OpenGL 1.2 */
+    USE_GL_FUNC(glTexSubImage3D)            /* OpenGL 1.2 */
+    USE_GL_FUNC(glUniform1f)                /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform1fv)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform1i)                /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform1iv)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform2f)                /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform2fv)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform2i)                /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform2iv)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform3f)                /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform3fv)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform3i)                /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform3iv)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform4f)                /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform4fv)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform4i)                /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniform4iv)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniformMatrix2fv)         /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniformMatrix3fv)         /* OpenGL 2.0 */
+    USE_GL_FUNC(glUniformMatrix4fv)         /* OpenGL 2.0 */
+    USE_GL_FUNC(glUnmapBuffer)              /* OpenGL 1.5 */
+    USE_GL_FUNC(glUseProgram)               /* OpenGL 2.0 */
+    USE_GL_FUNC(glValidateProgram)          /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib1f)           /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib1fv)          /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib2f)           /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib2fv)          /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib3f)           /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib3fv)          /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib4f)           /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib4fv)          /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib4Nsv)         /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib4Nubv)        /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib4Nusv)        /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib4sv)          /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttrib4ubv)         /* OpenGL 2.0 */
+    USE_GL_FUNC(glVertexAttribDivisor)      /* OpenGL 3.3 */
+    USE_GL_FUNC(glVertexAttribPointer)      /* OpenGL 2.0 */
 #undef USE_GL_FUNC
 
 #ifndef USE_WIN32_OPENGL
@@ -2458,6 +2961,110 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     /* note that we still need the above wglGetProcAddress calls to initialize the table */
     gl_info->gl_ops.ext = ((struct opengl_funcs *)NtCurrentTeb()->glTable)->ext;
 #endif
+
+#define MAP_GL_FUNCTION(core_func, ext_func)                                          \
+        do                                                                            \
+        {                                                                             \
+            if (!gl_info->gl_ops.ext.p_##core_func)                                   \
+                gl_info->gl_ops.ext.p_##core_func = gl_info->gl_ops.ext.p_##ext_func; \
+        } while (0)
+#define MAP_GL_FUNCTION_CAST(core_func, ext_func)                                             \
+        do                                                                                    \
+        {                                                                                     \
+            if (!gl_info->gl_ops.ext.p_##core_func)                                           \
+                gl_info->gl_ops.ext.p_##core_func = (void *)gl_info->gl_ops.ext.p_##ext_func; \
+        } while (0)
+
+    MAP_GL_FUNCTION(glActiveTexture, glActiveTextureARB);
+    MAP_GL_FUNCTION(glAttachShader, glAttachObjectARB);
+    MAP_GL_FUNCTION(glBeginQuery, glBeginQueryARB);
+    MAP_GL_FUNCTION(glBindAttribLocation, glBindAttribLocationARB);
+    MAP_GL_FUNCTION(glBindBuffer, glBindBufferARB);
+    MAP_GL_FUNCTION(glBlendColor, glBlendColorEXT);
+    MAP_GL_FUNCTION(glBlendEquation, glBlendEquationEXT);
+    MAP_GL_FUNCTION(glBlendEquationSeparate, glBlendEquationSeparateEXT);
+    MAP_GL_FUNCTION(glBlendFuncSeparate, glBlendFuncSeparateEXT);
+    MAP_GL_FUNCTION(glBufferData, glBufferDataARB);
+    MAP_GL_FUNCTION(glBufferSubData, glBufferSubDataARB);
+    MAP_GL_FUNCTION(glColorMaski, glColorMaskIndexedEXT);
+    MAP_GL_FUNCTION(glCompileShader, glCompileShaderARB);
+    MAP_GL_FUNCTION(glCompressedTexImage2D, glCompressedTexImage2DARB);
+    MAP_GL_FUNCTION(glCompressedTexImage3D, glCompressedTexImage3DARB);
+    MAP_GL_FUNCTION(glCompressedTexSubImage2D, glCompressedTexSubImage2DARB);
+    MAP_GL_FUNCTION(glCompressedTexSubImage3D, glCompressedTexSubImage3DARB);
+    MAP_GL_FUNCTION(glCreateProgram, glCreateProgramObjectARB);
+    MAP_GL_FUNCTION(glCreateShader, glCreateShaderObjectARB);
+    MAP_GL_FUNCTION(glDeleteBuffers, glDeleteBuffersARB);
+    MAP_GL_FUNCTION(glDeleteProgram, glDeleteObjectARB);
+    MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB);
+    MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB);
+    MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB);
+    MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB);
+    MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB);
+    MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB);
+    MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB);
+    MAP_GL_FUNCTION(glEndQuery, glEndQueryARB);
+    MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB);
+    MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB);
+    MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB);
+    MAP_GL_FUNCTION(glGetAttachedShaders, glGetAttachedObjectsARB);
+    MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB);
+    MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB);
+    MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB);
+    MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB);
+    MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB);
+    MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB);
+    MAP_GL_FUNCTION(glGetQueryObjectuiv, glGetQueryObjectuivARB);
+    MAP_GL_FUNCTION(glGetShaderInfoLog, glGetInfoLogARB);
+    MAP_GL_FUNCTION(glGetShaderiv, glGetObjectParameterivARB);
+    MAP_GL_FUNCTION(glGetShaderSource, glGetShaderSourceARB);
+    MAP_GL_FUNCTION(glGetUniformfv, glGetUniformfvARB);
+    MAP_GL_FUNCTION(glGetUniformiv, glGetUniformivARB);
+    MAP_GL_FUNCTION(glGetUniformLocation, glGetUniformLocationARB);
+    MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB);
+    MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB);
+    MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB);
+    MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT);
+    MAP_GL_FUNCTION(glTexSubImage3D, glTexSubImage3DEXT);
+    MAP_GL_FUNCTION(glUniform1f, glUniform1fARB);
+    MAP_GL_FUNCTION(glUniform1fv, glUniform1fvARB);
+    MAP_GL_FUNCTION(glUniform1i, glUniform1iARB);
+    MAP_GL_FUNCTION(glUniform1iv, glUniform1ivARB);
+    MAP_GL_FUNCTION(glUniform2f, glUniform2fARB);
+    MAP_GL_FUNCTION(glUniform2fv, glUniform2fvARB);
+    MAP_GL_FUNCTION(glUniform2i, glUniform2iARB);
+    MAP_GL_FUNCTION(glUniform2iv, glUniform2ivARB);
+    MAP_GL_FUNCTION(glUniform3f, glUniform3fARB);
+    MAP_GL_FUNCTION(glUniform3fv, glUniform3fvARB);
+    MAP_GL_FUNCTION(glUniform3i, glUniform3iARB);
+    MAP_GL_FUNCTION(glUniform3iv, glUniform3ivARB);
+    MAP_GL_FUNCTION(glUniform4f, glUniform4fARB);
+    MAP_GL_FUNCTION(glUniform4fv, glUniform4fvARB);
+    MAP_GL_FUNCTION(glUniform4i, glUniform4iARB);
+    MAP_GL_FUNCTION(glUniform4iv, glUniform4ivARB);
+    MAP_GL_FUNCTION(glUniformMatrix2fv, glUniformMatrix2fvARB);
+    MAP_GL_FUNCTION(glUniformMatrix3fv, glUniformMatrix3fvARB);
+    MAP_GL_FUNCTION(glUniformMatrix4fv, glUniformMatrix4fvARB);
+    MAP_GL_FUNCTION(glUnmapBuffer, glUnmapBufferARB);
+    MAP_GL_FUNCTION(glUseProgram, glUseProgramObjectARB);
+    MAP_GL_FUNCTION(glValidateProgram, glValidateProgramARB);
+    MAP_GL_FUNCTION(glVertexAttrib1f, glVertexAttrib1fARB);
+    MAP_GL_FUNCTION(glVertexAttrib1fv, glVertexAttrib1fvARB);
+    MAP_GL_FUNCTION(glVertexAttrib2f, glVertexAttrib2fARB);
+    MAP_GL_FUNCTION(glVertexAttrib2fv, glVertexAttrib2fvARB);
+    MAP_GL_FUNCTION(glVertexAttrib3f, glVertexAttrib3fARB);
+    MAP_GL_FUNCTION(glVertexAttrib3fv, glVertexAttrib3fvARB);
+    MAP_GL_FUNCTION(glVertexAttrib4f, glVertexAttrib4fARB);
+    MAP_GL_FUNCTION(glVertexAttrib4fv, glVertexAttrib4fvARB);
+    MAP_GL_FUNCTION(glVertexAttrib4Nsv, glVertexAttrib4NsvARB);
+    MAP_GL_FUNCTION(glVertexAttrib4Nubv, glVertexAttrib4NubvARB);
+    MAP_GL_FUNCTION(glVertexAttrib4Nusv, glVertexAttrib4NusvARB);
+    MAP_GL_FUNCTION(glVertexAttrib4sv, glVertexAttrib4svARB);
+    MAP_GL_FUNCTION(glVertexAttrib4ubv, glVertexAttrib4ubvARB);
+    MAP_GL_FUNCTION(glVertexAttribDivisor, glVertexAttribDivisorARB);
+    MAP_GL_FUNCTION(glVertexAttribPointer, glVertexAttribPointerARB);
+#undef MAP_GL_FUNCTION
+#undef MAP_GL_FUNCTION_CAST
 }
 
 static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
@@ -2776,16 +3383,12 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     if (!gl_info->supported[EXT_TEXTURE3D] && gl_version >= MAKEDWORD_VERSION(1, 2))
     {
         TRACE("GL CORE: GL_EXT_texture3D support.\n");
-        gl_info->gl_ops.ext.p_glTexImage3DEXT = (void *)gl_info->gl_ops.ext.p_glTexImage3D;
-        gl_info->gl_ops.ext.p_glTexSubImage3DEXT = gl_info->gl_ops.ext.p_glTexSubImage3D;
         gl_info->supported[EXT_TEXTURE3D] = TRUE;
     }
 
     if (!gl_info->supported[NV_POINT_SPRITE] && gl_version >= MAKEDWORD_VERSION(1, 4))
     {
         TRACE("GL CORE: GL_NV_point_sprite support.\n");
-        gl_info->gl_ops.ext.p_glPointParameterivNV = gl_info->gl_ops.ext.p_glPointParameteriv;
-        gl_info->gl_ops.ext.p_glPointParameteriNV = gl_info->gl_ops.ext.p_glPointParameteri;
         gl_info->supported[NV_POINT_SPRITE] = TRUE;
     }
 
@@ -2838,11 +3441,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
         TRACE(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
         gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
     }
-    if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP])
-    {
-        TRACE(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
-        gl_info->supported[ARB_DEPTH_CLAMP] = TRUE;
-    }
     if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
     {
         TRACE(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
@@ -2898,7 +3496,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     {
         GLint counter_bits;
 
-        GL_EXTCALL(glGetQueryivARB(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB, &counter_bits));
+        GL_EXTCALL(glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &counter_bits));
         TRACE("Occlusion query counter has %d bits.\n", counter_bits);
         if (!counter_bits)
             gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE;
@@ -2907,7 +3505,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     {
         GLint counter_bits;
 
-        GL_EXTCALL(glGetQueryivARB(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS_ARB, &counter_bits));
+        GL_EXTCALL(glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &counter_bits));
         TRACE("Timestamp query counter has %d bits.\n", counter_bits);
         if (!counter_bits)
             gl_info->supported[ARB_TIMER_QUERY] = FALSE;
@@ -3029,7 +3627,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str);
     TRACE("Found GL_VENDOR (%s)->(0x%04x/0x%04x).\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor);
 
-    device = wined3d_guess_card(gl_info, gl_renderer_str, &gl_vendor, &card_vendor);
+    device = wined3d_guess_card(&shader_caps, &fragment_caps, gl_info->glsl_version, gl_renderer_str, &gl_vendor, &card_vendor);
     TRACE("Found (fake) card: 0x%x (vendor id), 0x%x (device id).\n", card_vendor, device);
 
     gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT;
@@ -3288,78 +3886,94 @@ HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UI
 HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d,
         UINT adapter_idx, const struct wined3d_display_mode *mode)
 {
-    struct wined3d_display_mode current_mode;
-    const struct wined3d_format *format;
     struct wined3d_adapter *adapter;
-    DEVMODEW devmode;
+    DEVMODEW new_mode, current_mode;
     RECT clip_rc;
-    HRESULT hr;
     LONG ret;
+    enum wined3d_format_id new_format_id;
 
-    TRACE("wined3d %p, adapter_idx %u, mode %p (%ux%u@%u %s %#x).\n", wined3d, adapter_idx, mode,
-            mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id),
-            mode->scanline_ordering);
+    TRACE("wined3d %p, adapter_idx %u, mode %p.\n", wined3d, adapter_idx, mode);
 
     if (adapter_idx >= wined3d->adapter_count)
         return WINED3DERR_INVALIDCALL;
-
     adapter = &wined3d->adapters[adapter_idx];
-    format = wined3d_get_format(&adapter->gl_info, mode->format_id);
 
-    memset(&devmode, 0, sizeof(devmode));
-    devmode.dmSize = sizeof(devmode);
-    devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-    devmode.dmBitsPerPel = format->byte_count * CHAR_BIT;
-    devmode.dmPelsWidth = mode->width;
-    devmode.dmPelsHeight = mode->height;
+    memset(&new_mode, 0, sizeof(new_mode));
+    new_mode.dmSize = sizeof(new_mode);
+    memset(&current_mode, 0, sizeof(current_mode));
+    current_mode.dmSize = sizeof(current_mode);
+    if (mode)
+    {
+        const struct wined3d_format *format;
+
+        TRACE("mode %ux%u@%u %s %#x.\n", mode->width, mode->height, mode->refresh_rate,
+                debug_d3dformat(mode->format_id), mode->scanline_ordering);
+
+        format = wined3d_get_format(&adapter->gl_info, mode->format_id);
+
+        new_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+        new_mode.dmBitsPerPel = format->byte_count * CHAR_BIT;
+        new_mode.dmPelsWidth = mode->width;
+        new_mode.dmPelsHeight = mode->height;
 
-    devmode.dmDisplayFrequency = mode->refresh_rate;
-    if (mode->refresh_rate)
-        devmode.dmFields |= DM_DISPLAYFREQUENCY;
+        new_mode.dmDisplayFrequency = mode->refresh_rate;
+        if (mode->refresh_rate)
+            new_mode.dmFields |= DM_DISPLAYFREQUENCY;
 
-    if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN)
+        if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN)
+        {
+            new_mode.dmFields |= DM_DISPLAYFLAGS;
+            if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED)
+                new_mode.u2.dmDisplayFlags |= DM_INTERLACED;
+        }
+        new_format_id = mode->format_id;
+    }
+    else
     {
-        devmode.dmFields |= DM_DISPLAYFLAGS;
-        if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED)
-            devmode.u2.dmDisplayFlags |= DM_INTERLACED;
+        if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_REGISTRY_SETTINGS, &new_mode))
+        {
+            ERR("Failed to read mode from registry.\n");
+            return WINED3DERR_NOTAVAILABLE;
+        }
+        new_format_id = pixelformat_for_depth(new_mode.dmBitsPerPel);
     }
 
     /* Only change the mode if necessary. */
-    if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &current_mode, NULL)))
+    if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &current_mode))
     {
-        ERR("Failed to get current display mode, hr %#x.\n", hr);
+        ERR("Failed to get current display mode.\n");
     }
-    else if (current_mode.width == mode->width
-            && current_mode.height == mode->height
-            && current_mode.format_id == mode->format_id
-            && (current_mode.refresh_rate == mode->refresh_rate
-            || !mode->refresh_rate)
-            && (current_mode.scanline_ordering == mode->scanline_ordering
-            || mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_UNKNOWN))
+    else if (current_mode.dmPelsWidth == new_mode.dmPelsWidth
+            && current_mode.dmPelsHeight == new_mode.dmPelsHeight
+            && current_mode.dmBitsPerPel == new_mode.dmBitsPerPel
+            && (current_mode.dmDisplayFrequency == new_mode.dmDisplayFrequency
+            || !(new_mode.dmFields & DM_DISPLAYFREQUENCY))
+            && (current_mode.u2.dmDisplayFlags == new_mode.u2.dmDisplayFlags
+            || !(new_mode.dmFields & DM_DISPLAYFLAGS)))
     {
         TRACE("Skipping redundant mode setting call.\n");
         return WINED3D_OK;
     }
 
-    ret = ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
+    ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL);
     if (ret != DISP_CHANGE_SUCCESSFUL)
     {
-        if (devmode.dmDisplayFrequency)
+        if (new_mode.dmFields & DM_DISPLAYFREQUENCY)
         {
             WARN("ChangeDisplaySettingsExW failed, trying without the refresh rate.\n");
-            devmode.dmFields &= ~DM_DISPLAYFREQUENCY;
-            devmode.dmDisplayFrequency = 0;
-            ret = ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
+            new_mode.dmFields &= ~DM_DISPLAYFREQUENCY;
+            new_mode.dmDisplayFrequency = 0;
+            ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL);
         }
         if (ret != DISP_CHANGE_SUCCESSFUL)
             return WINED3DERR_NOTAVAILABLE;
     }
 
     /* Store the new values. */
-    adapter->screen_format = mode->format_id;
+    adapter->screen_format = new_format_id;
 
     /* And finally clip mouse to our screen. */
-    SetRect(&clip_rc, 0, 0, mode->width, mode->height);
+    SetRect(&clip_rc, 0, 0, new_mode.dmPelsWidth, new_mode.dmPelsHeight);
     ClipCursor(&clip_rc);
 
     return WINED3D_OK;
@@ -4432,7 +5046,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
         caps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
                               WINED3DSTENCILCAPS_INCR;
     }
-    if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL])
+    if (gl_info->supported[WINED3D_GL_VERSION_2_0] || gl_info->supported[EXT_STENCIL_TWO_SIDE]
+            || gl_info->supported[ATI_SEPARATE_STENCIL])
     {
         caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
     }
index 5c04119..3261620 100644 (file)
@@ -54,9 +54,9 @@ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primit
                 }
                 else
                 {
-                    GL_EXTCALL(glDrawElementsInstancedARB(primitive_type, count, idxtype,
+                    GL_EXTCALL(glDrawElementsInstanced(primitive_type, count, idxtype,
                             (const char *)idx_data + (idx_size * start_idx), instance_count));
-                    checkGLcall("glDrawElementsInstancedARB");
+                    checkGLcall("glDrawElementsInstanced");
                 }
             }
         }
@@ -340,20 +340,20 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info,
     switch(format)
     {
         case WINED3DFMT_R32_FLOAT:
-            GL_EXTCALL(glVertexAttrib1fvARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib1fv(index, ptr));
             break;
         case WINED3DFMT_R32G32_FLOAT:
-            GL_EXTCALL(glVertexAttrib2fvARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib2fv(index, ptr));
             break;
         case WINED3DFMT_R32G32B32_FLOAT:
-            GL_EXTCALL(glVertexAttrib3fvARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib3fv(index, ptr));
             break;
         case WINED3DFMT_R32G32B32A32_FLOAT:
-            GL_EXTCALL(glVertexAttrib4fvARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib4fv(index, ptr));
             break;
 
         case WINED3DFMT_R8G8B8A8_UINT:
-            GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib4ubv(index, ptr));
             break;
         case WINED3DFMT_B8G8R8A8_UNORM:
             if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
@@ -362,38 +362,38 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info,
                 DWORD c = *src & 0xff00ff00;
                 c |= (*src & 0xff0000) >> 16;
                 c |= (*src & 0xff) << 16;
-                GL_EXTCALL(glVertexAttrib4NubvARB(index, (GLubyte *)&c));
+                GL_EXTCALL(glVertexAttrib4Nubv(index, (GLubyte *)&c));
                 break;
             }
             /* else fallthrough */
         case WINED3DFMT_R8G8B8A8_UNORM:
-            GL_EXTCALL(glVertexAttrib4NubvARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib4Nubv(index, ptr));
             break;
 
         case WINED3DFMT_R16G16_SINT:
-            GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib2sv(index, ptr));
             break;
         case WINED3DFMT_R16G16B16A16_SINT:
-            GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib4sv(index, ptr));
             break;
 
         case WINED3DFMT_R16G16_SNORM:
         {
             GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
-            GL_EXTCALL(glVertexAttrib4NsvARB(index, s));
+            GL_EXTCALL(glVertexAttrib4Nsv(index, s));
             break;
         }
         case WINED3DFMT_R16G16_UNORM:
         {
             GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
-            GL_EXTCALL(glVertexAttrib4NusvARB(index, s));
+            GL_EXTCALL(glVertexAttrib4Nusv(index, s));
             break;
         }
         case WINED3DFMT_R16G16B16A16_SNORM:
-            GL_EXTCALL(glVertexAttrib4NsvARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib4Nsv(index, ptr));
             break;
         case WINED3DFMT_R16G16B16A16_UNORM:
-            GL_EXTCALL(glVertexAttrib4NusvARB(index, ptr));
+            GL_EXTCALL(glVertexAttrib4Nusv(index, ptr));
             break;
 
         case WINED3DFMT_R10G10B10A2_UINT:
@@ -418,7 +418,7 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info,
             {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
                 float y = float_16_to_32(((const unsigned short *)ptr) + 1);
-                GL_EXTCALL(glVertexAttrib2fARB(index, x, y));
+                GL_EXTCALL(glVertexAttrib2f(index, x, y));
             }
             break;
         case WINED3DFMT_R16G16B16A16_FLOAT:
@@ -433,7 +433,7 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info,
                 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(glVertexAttrib4fARB(index, x, y, z, w));
+                GL_EXTCALL(glVertexAttrib4f(index, x, y, z, w));
             }
             break;
 
diff --git a/reactos/dll/directx/wine/wined3d/dxtn.c b/reactos/dll/directx/wine/wined3d/dxtn.c
new file mode 100644 (file)
index 0000000..3dd2147
--- /dev/null
@@ -0,0 +1,514 @@
+/*
+ * Copyright 2014 Michael Müller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wined3d_private.h"
+
+#include <wine/library.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+static void* txc_dxtn_handle;
+static void (*pfetch_2d_texel_rgba_dxt1)(int srcRowStride, const BYTE *pixData, int i, int j, DWORD *texel);
+static void (*pfetch_2d_texel_rgba_dxt3)(int srcRowStride, const BYTE *pixData, int i, int j, DWORD *texel);
+static void (*pfetch_2d_texel_rgba_dxt5)(int srcRowStride, const BYTE *pixData, int i, int j, DWORD *texel);
+static void (*ptx_compress_dxtn)(int comps, int width, int height, const BYTE *srcPixData,
+                                 GLenum destformat, BYTE *dest, int dstRowStride);
+
+static inline BOOL dxt1_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
+        DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+    unsigned int x, y;
+    DWORD color;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    for (y = 0; y < h; ++y)
+    {
+        DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+        for (x = 0; x < w; ++x)
+        {
+            /* pfetch_2d_texel_rgba_dxt1 doesn't correctly handle pitch */
+            pfetch_2d_texel_rgba_dxt1(0, src + (y / 4) * pitch_in + (x / 4) * 8,
+                                      x & 3, y & 3, &color);
+            if (alpha)
+            {
+                dst_line[x] = (color & 0xff00ff00) | ((color & 0xff) << 16) |
+                              ((color & 0xff0000) >> 16);
+            }
+            else
+            {
+                dst_line[x] = 0xff000000 | ((color & 0xff) << 16) |
+                              (color & 0xff00) | ((color & 0xff0000) >> 16);
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static inline BOOL dxt1_to_x4r4g4b4(const BYTE *src, BYTE *dst, DWORD pitch_in,
+        DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+    unsigned int x, y;
+    DWORD color;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    for (y = 0; y < h; ++y)
+    {
+        WORD *dst_line = (WORD *)(dst + y * pitch_out);
+        for (x = 0; x < w; ++x)
+        {
+            /* pfetch_2d_texel_rgba_dxt1 doesn't correctly handle pitch */
+            pfetch_2d_texel_rgba_dxt1(0, src + (y / 4) * pitch_in + (x / 4) * 16,
+                                      x & 3, y & 3, &color);
+            if (alpha)
+            {
+                dst_line[x] = ((color & 0xf0000000) >> 16) | ((color & 0xf00000) >> 20) |
+                              ((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
+            }
+            else
+            {
+                dst_line[x] = 0xf000  | ((color & 0xf00000) >> 20) |
+                              ((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static inline BOOL dxt1_to_x1r5g5b5(const BYTE *src, BYTE *dst, DWORD pitch_in,
+        DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+    unsigned int x, y;
+    DWORD color;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    for (y = 0; y < h; ++y)
+    {
+        WORD *dst_line = (WORD *)(dst + y * pitch_out);
+        for (x = 0; x < w; ++x)
+        {
+            /* pfetch_2d_texel_rgba_dxt1 doesn't correctly handle pitch */
+            pfetch_2d_texel_rgba_dxt1(0, src + (y / 4) * pitch_in + (x / 4) * 16,
+                                      x & 3, y & 3, &color);
+            if (alpha)
+            {
+                dst_line[x] = ((color & 0x80000000) >> 16) | ((color & 0xf80000) >> 19) |
+                              ((color & 0xf800) >> 6) | ((color & 0xf8) << 7);
+            }
+            else
+            {
+                dst_line[x] = 0x8000 | ((color & 0xf80000) >> 19) |
+                              ((color & 0xf800) >> 6) | ((color & 0xf8) << 7);
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static inline BOOL dxt3_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
+        DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+    unsigned int x, y;
+    DWORD color;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    for (y = 0; y < h; ++y)
+    {
+        DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+        for (x = 0; x < w; ++x)
+        {
+            /* pfetch_2d_texel_rgba_dxt3 doesn't correctly handle pitch */
+            pfetch_2d_texel_rgba_dxt3(0, src + (y / 4) * pitch_in + (x / 4) * 16,
+                                      x & 3, y & 3, &color);
+            if (alpha)
+            {
+                dst_line[x] = (color & 0xff00ff00) | ((color & 0xff) << 16) |
+                              ((color & 0xff0000) >> 16);
+            }
+            else
+            {
+                dst_line[x] = 0xff000000 | ((color & 0xff) << 16) |
+                              (color & 0xff00) | ((color & 0xff0000) >> 16);
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static inline BOOL dxt3_to_x4r4g4b4(const BYTE *src, BYTE *dst, DWORD pitch_in,
+        DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+    unsigned int x, y;
+    DWORD color;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    for (y = 0; y < h; ++y)
+    {
+        WORD *dst_line = (WORD *)(dst + y * pitch_out);
+        for (x = 0; x < w; ++x)
+        {
+            /* pfetch_2d_texel_rgba_dxt3 doesn't correctly handle pitch */
+            pfetch_2d_texel_rgba_dxt3(0, src + (y / 4) * pitch_in + (x / 4) * 16,
+                                      x & 3, y & 3, &color);
+            if (alpha)
+            {
+                dst_line[x] = ((color & 0xf0000000) >> 16) | ((color & 0xf00000) >> 20) |
+                              ((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
+            }
+            else
+            {
+                dst_line[x] = 0xf000  | ((color & 0xf00000) >> 20) |
+                              ((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static inline BOOL dxt5_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
+        DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+    unsigned int x, y;
+    DWORD color;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    for (y = 0; y < h; ++y)
+    {
+        DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+        for (x = 0; x < w; ++x)
+        {
+            /* pfetch_2d_texel_rgba_dxt5 doesn't correctly handle pitch */
+            pfetch_2d_texel_rgba_dxt5(0, src + (y / 4) * pitch_in + (x / 4) * 16,
+                                      x & 3, y & 3, &color);
+            if (alpha)
+            {
+                dst_line[x] = (color & 0xff00ff00) | ((color & 0xff) << 16) |
+                              ((color & 0xff0000) >> 16);
+            }
+            else
+            {
+                dst_line[x] = 0xff000000 | ((color & 0xff) << 16) |
+                              (color & 0xff00) | ((color & 0xff0000) >> 16);
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static inline BOOL x8r8g8b8_to_dxtn(const BYTE *src, BYTE *dst, DWORD pitch_in,
+        DWORD pitch_out, unsigned int w, unsigned int h, GLenum destformat, BOOL alpha)
+{
+    unsigned int x, y;
+    DWORD color, *tmp;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    tmp = HeapAlloc(GetProcessHeap(), 0, h * w * sizeof(DWORD));
+    if (!tmp)
+    {
+        ERR("Failed to allocate memory for conversion\n");
+        return FALSE;
+    }
+
+    for (y = 0; y < h; ++y)
+    {
+        const DWORD *src_line = (const DWORD *)(src + y * pitch_in);
+        DWORD *dst_line = tmp + y * w;
+        for (x = 0; x < w; ++x)
+        {
+            color = src_line[x];
+            if (alpha)
+            {
+                dst_line[x] = (color & 0xff00ff00) | ((color & 0xff) << 16) |
+                              ((color & 0xff0000) >> 16);
+            }
+            else
+            {
+                dst_line[x] = 0xff000000 | ((color & 0xff) << 16) |
+                              (color & 0xff00) | ((color & 0xff0000) >> 16);
+            }
+        }
+    }
+
+    ptx_compress_dxtn(4, w, h, (BYTE *)tmp, destformat, dst, pitch_out);
+    HeapFree(GetProcessHeap(), 0, tmp);
+    return TRUE;
+}
+
+static inline BOOL x1r5g5b5_to_dxtn(const BYTE *src, BYTE *dst, DWORD pitch_in,
+        DWORD pitch_out, unsigned int w, unsigned int h, GLenum destformat, BOOL alpha)
+{
+    static const unsigned char convert_5to8[] =
+    {
+        0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a,
+        0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b,
+        0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd,
+        0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff,
+    };
+    unsigned int x, y;
+    DWORD *tmp;
+    WORD color;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out);
+
+    tmp = HeapAlloc(GetProcessHeap(), 0, h * w * sizeof(DWORD));
+    if (!tmp)
+    {
+        ERR("Failed to allocate memory for conversion\n");
+        return FALSE;
+    }
+
+    for (y = 0; y < h; ++y)
+    {
+        const WORD *src_line = (const WORD *)(src + y * pitch_in);
+        DWORD *dst_line = tmp + y * w;
+        for (x = 0; x < w; ++x)
+        {
+            color = src_line[x];
+            if (alpha)
+            {
+                dst_line[x] = ((color & 0x8000) ? 0xff000000 : 0) |
+                              convert_5to8[(color & 0x001f)] << 16 |
+                              convert_5to8[(color & 0x03e0) >> 5] << 8 |
+                              convert_5to8[(color & 0x7c00) >> 10];
+            }
+            else
+            {
+                dst_line[x] = 0xff000000 |
+                              convert_5to8[(color & 0x001f)] << 16 |
+                              convert_5to8[(color & 0x03e0) >> 5] << 8 |
+                              convert_5to8[(color & 0x7c00) >> 10];
+            }
+        }
+    }
+
+    ptx_compress_dxtn(4, w, h, (BYTE *)tmp, destformat, dst, pitch_out);
+    HeapFree(GetProcessHeap(), 0, tmp);
+    return TRUE;
+}
+
+BOOL wined3d_dxt1_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+        enum wined3d_format_id format, unsigned int w, unsigned int h)
+{
+    if (!txc_dxtn_handle)
+        return FALSE;
+
+    switch (format)
+    {
+        case WINED3DFMT_B8G8R8A8_UNORM:
+            return dxt1_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, TRUE);
+        case WINED3DFMT_B8G8R8X8_UNORM:
+            return dxt1_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, FALSE);
+        case WINED3DFMT_B4G4R4A4_UNORM:
+            return dxt1_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, TRUE);
+        case WINED3DFMT_B4G4R4X4_UNORM:
+            return dxt1_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, FALSE);
+        case WINED3DFMT_B5G5R5A1_UNORM:
+            return dxt1_to_x1r5g5b5(src, dst, pitch_in, pitch_out, w, h, TRUE);
+        case WINED3DFMT_B5G5R5X1_UNORM:
+            return dxt1_to_x1r5g5b5(src, dst, pitch_in, pitch_out, w, h, FALSE);
+        default:
+            break;
+    }
+
+    FIXME("Cannot find a conversion function from format DXT1 to %s.\n", debug_d3dformat(format));
+    return FALSE;
+}
+
+BOOL wined3d_dxt3_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+        enum wined3d_format_id format, unsigned int w, unsigned int h)
+{
+    if (!txc_dxtn_handle)
+        return FALSE;
+
+    switch (format)
+    {
+        case WINED3DFMT_B8G8R8A8_UNORM:
+            return dxt3_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, TRUE);
+        case WINED3DFMT_B8G8R8X8_UNORM:
+            return dxt3_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, FALSE);
+        case WINED3DFMT_B4G4R4A4_UNORM:
+            return dxt3_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, TRUE);
+        case WINED3DFMT_B4G4R4X4_UNORM:
+            return dxt3_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, FALSE);
+        default:
+            break;
+    }
+
+    FIXME("Cannot find a conversion function from format DXT3 to %s.\n", debug_d3dformat(format));
+    return FALSE;
+}
+
+BOOL wined3d_dxt5_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+        enum wined3d_format_id format, unsigned int w, unsigned int h)
+{
+    if (!txc_dxtn_handle)
+        return FALSE;
+
+    switch (format)
+    {
+        case WINED3DFMT_B8G8R8A8_UNORM:
+            return dxt5_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, TRUE);
+        case WINED3DFMT_B8G8R8X8_UNORM:
+            return dxt5_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, FALSE);
+        default:
+            break;
+    }
+
+    FIXME("Cannot find a conversion function from format DXT5 to %s.\n", debug_d3dformat(format));
+    return FALSE;
+}
+
+BOOL wined3d_dxt1_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+        enum wined3d_format_id format, unsigned int w, unsigned int h)
+{
+    if (!txc_dxtn_handle)
+        return FALSE;
+
+    switch (format)
+    {
+        case WINED3DFMT_B8G8R8A8_UNORM:
+            return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
+                                    GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, TRUE);
+        case WINED3DFMT_B8G8R8X8_UNORM:
+            return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
+                                    GL_COMPRESSED_RGB_S3TC_DXT1_EXT, FALSE);
+        case WINED3DFMT_B5G5R5A1_UNORM:
+            return x1r5g5b5_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
+                                    GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, TRUE);
+        case WINED3DFMT_B5G5R5X1_UNORM:
+            return x1r5g5b5_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
+                                    GL_COMPRESSED_RGB_S3TC_DXT1_EXT, FALSE);
+        default:
+            break;
+    }
+
+    FIXME("Cannot find a conversion function from format %s to DXT1.\n", debug_d3dformat(format));
+    return FALSE;
+}
+
+BOOL wined3d_dxt3_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+        enum wined3d_format_id format, unsigned int w, unsigned int h)
+{
+    if (!txc_dxtn_handle)
+        return FALSE;
+
+    switch (format)
+    {
+        case WINED3DFMT_B8G8R8A8_UNORM:
+            return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
+                                    GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, TRUE);
+        case WINED3DFMT_B8G8R8X8_UNORM:
+            return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
+                                    GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, FALSE);
+        default:
+            break;
+    }
+
+    FIXME("Cannot find a conversion function from format %s to DXT3.\n", debug_d3dformat(format));
+    return FALSE;
+}
+
+BOOL wined3d_dxt5_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+        enum wined3d_format_id format, unsigned int w, unsigned int h)
+{
+    if (!txc_dxtn_handle)
+        return FALSE;
+
+    switch (format)
+    {
+        case WINED3DFMT_B8G8R8A8_UNORM:
+            return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
+                                    GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, TRUE);
+        case WINED3DFMT_B8G8R8X8_UNORM:
+            return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
+                                    GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, FALSE);
+        default:
+            break;
+    }
+
+    FIXME("Cannot find a conversion function from format %s to DXT5.\n", debug_d3dformat(format));
+    return FALSE;
+}
+
+BOOL wined3d_dxtn_init(void)
+{
+    static const char *soname[] =
+    {
+#ifdef SONAME_LIBTXC_DXTN
+        SONAME_LIBTXC_DXTN,
+#endif
+        "libtxc_dxtn.so",
+        "libtxc_dxtn_s2tc.so.0"
+    };
+    int i;
+
+    for (i = 0; i < sizeof(soname)/sizeof(soname[0]); i++)
+    {
+        txc_dxtn_handle = wine_dlopen(soname[i], RTLD_NOW, NULL, 0);
+        if (txc_dxtn_handle) break;
+    }
+
+    if (!txc_dxtn_handle)
+    {
+        FIXME("Wine cannot find the txc_dxtn library, DXTn software support unavailable.\n");
+        return FALSE;
+    }
+
+    #define LOAD_FUNCPTR(f) \
+        if (!(p##f = wine_dlsym(txc_dxtn_handle, #f, NULL, 0))) \
+        { \
+            ERR("Can't find symbol %s , DXTn software support unavailable.\n", #f); \
+            goto error; \
+        }
+
+    LOAD_FUNCPTR(fetch_2d_texel_rgba_dxt1);
+    LOAD_FUNCPTR(fetch_2d_texel_rgba_dxt3);
+    LOAD_FUNCPTR(fetch_2d_texel_rgba_dxt5);
+    LOAD_FUNCPTR(tx_compress_dxtn);
+
+    #undef LOAD_FUNCPTR
+    return TRUE;
+
+error:
+    wine_dlclose(txc_dxtn_handle, NULL, 0);
+    txc_dxtn_handle = NULL;
+    return FALSE;
+}
+
+BOOL wined3d_dxtn_supported(void)
+{
+    return (txc_dxtn_handle != NULL);
+}
+
+void wined3d_dxtn_free(void)
+{
+    if (txc_dxtn_handle)
+        wine_dlclose(txc_dxtn_handle, NULL, 0);
+}
index 74ad048..70131e0 100644 (file)
@@ -104,7 +104,8 @@ static void WINE_GLAPI wine_glMultiTexCoord4svARB(GLenum target, const GLshort *
     context_get_current()->gl_info->gl_ops.gl.p_glTexCoord4sv(v);
 }
 
-static void WINE_GLAPI wine_glActiveTextureARB(GLenum texture) {
+static void WINE_GLAPI wine_glActiveTexture(GLenum texture)
+{
     if(texture != GL_TEXTURE0) {
         ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
         return;
@@ -343,7 +344,7 @@ void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info)
     if (!gl_info->supported[ARB_MULTITEXTURE])
     {
         TRACE("Applying GL_ARB_multitexture emulation hooks\n");
-        gl_info->gl_ops.ext.p_glActiveTextureARB        = wine_glActiveTextureARB;
+        gl_info->gl_ops.ext.p_glActiveTexture           = wine_glActiveTexture;
         gl_info->gl_ops.ext.p_glClientActiveTextureARB  = wine_glClientActiveTextureARB;
         gl_info->gl_ops.ext.p_glMultiTexCoord1fARB      = wine_glMultiTexCoord1fARB;
         gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB     = wine_glMultiTexCoord1fvARB;
index 85d82f2..e44da89 100644 (file)
@@ -56,6 +56,7 @@ struct glsl_sample_function
 {
     const char *name;
     DWORD coord_mask;
+    enum wined3d_data_type data_type;
 };
 
 enum heap_node_op
@@ -86,8 +87,8 @@ struct shader_glsl_priv {
     struct constant_heap vconst_heap;
     struct constant_heap pconst_heap;
     unsigned char *stack;
-    GLhandleARB depth_blt_program_full[tex_type_count];
-    GLhandleARB depth_blt_program_masked[tex_type_count];
+    GLuint depth_blt_program_full[tex_type_count];
+    GLuint depth_blt_program_masked[tex_type_count];
     UINT next_constant_version;
 
     const struct wined3d_vertex_pipe_ops *vertex_pipe;
@@ -100,7 +101,7 @@ struct shader_glsl_priv {
 struct glsl_vs_program
 {
     struct list shader_entry;
-    GLhandleARB id;
+    GLuint id;
     GLenum vertex_color_clamp;
     GLint *uniform_f_locations;
     GLint uniform_i_locations[MAX_CONST_I];
@@ -111,13 +112,13 @@ struct glsl_vs_program
 struct glsl_gs_program
 {
     struct list shader_entry;
-    GLhandleARB id;
+    GLuint id;
 };
 
 struct glsl_ps_program
 {
     struct list shader_entry;
-    GLhandleARB id;
+    GLuint id;
     GLint *uniform_f_locations;
     GLint uniform_i_locations[MAX_CONST_I];
     GLint uniform_b_locations[MAX_CONST_B];
@@ -139,16 +140,16 @@ struct glsl_shader_prog_link
     struct glsl_vs_program vs;
     struct glsl_gs_program gs;
     struct glsl_ps_program ps;
-    GLhandleARB programId;
+    GLuint id;
     DWORD constant_update_mask;
     UINT constant_version;
 };
 
 struct glsl_program_key
 {
-    GLhandleARB vs_id;
-    GLhandleARB gs_id;
-    GLhandleARB ps_id;
+    GLuint vs_id;
+    GLuint gs_id;
+    GLuint ps_id;
 };
 
 struct shader_glsl_ctx_priv {
@@ -166,18 +167,18 @@ struct glsl_ps_compiled_shader
 {
     struct ps_compile_args          args;
     struct ps_np2fixup_info         np2fixup;
-    GLhandleARB                     prgId;
+    GLuint                          id;
 };
 
 struct glsl_vs_compiled_shader
 {
     struct vs_compile_args          args;
-    GLhandleARB                     prgId;
+    GLuint                          id;
 };
 
 struct glsl_gs_compiled_shader
 {
-    GLhandleARB id;
+    GLuint id;
 };
 
 struct glsl_shader_private
@@ -194,14 +195,14 @@ struct glsl_shader_private
 struct glsl_ffp_vertex_shader
 {
     struct wined3d_ffp_vs_desc desc;
-    GLhandleARB id;
+    GLuint id;
     struct list linked_programs;
 };
 
 struct glsl_ffp_fragment_shader
 {
     struct ffp_frag_desc entry;
-    GLhandleARB id;
+    GLuint id;
     struct list linked_programs;
 };
 
@@ -216,9 +217,9 @@ static const char *debug_gl_shader_type(GLenum type)
     switch (type)
     {
 #define WINED3D_TO_STR(u) case u: return #u
-        WINED3D_TO_STR(GL_VERTEX_SHADER_ARB);
-        WINED3D_TO_STR(GL_GEOMETRY_SHADER_ARB);
-        WINED3D_TO_STR(GL_FRAGMENT_SHADER_ARB);
+        WINED3D_TO_STR(GL_VERTEX_SHADER);
+        WINED3D_TO_STR(GL_GEOMETRY_SHADER);
+        WINED3D_TO_STR(GL_FRAGMENT_SHADER);
 #undef WINED3D_TO_STR
         default:
             return wine_dbg_sprintf("UNKNOWN(%#x)", type);
@@ -275,80 +276,84 @@ static char *get_info_log_line(char **ptr)
 }
 
 /* Context activation is done by the caller. */
-static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleARB obj)
+static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program)
 {
-    int infologLength = 0;
-    char *infoLog;
+    int length = 0;
+    char *log;
 
     if (!WARN_ON(d3d_shader) && !FIXME_ON(d3d_shader))
         return;
 
-    GL_EXTCALL(glGetObjectParameterivARB(obj,
-               GL_OBJECT_INFO_LOG_LENGTH_ARB,
-               &infologLength));
+    if (program)
+        GL_EXTCALL(glGetProgramiv(id, GL_INFO_LOG_LENGTH, &length));
+    else
+        GL_EXTCALL(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length));
 
     /* A size of 1 is just a null-terminated string, so the log should be bigger than
      * that if there are errors. */
-    if (infologLength > 1)
+    if (length > 1)
     {
         char *ptr, *line;
 
-        infoLog = HeapAlloc(GetProcessHeap(), 0, infologLength);
+        log = HeapAlloc(GetProcessHeap(), 0, length);
         /* The info log is supposed to be zero-terminated, but at least some
          * versions of fglrx don't terminate the string properly. The reported
          * length does include the terminator, so explicitly set it to zero
          * here. */
-        infoLog[infologLength - 1] = 0;
-        GL_EXTCALL(glGetInfoLogARB(obj, infologLength, NULL, infoLog));
+        log[length - 1] = 0;
+        if (program)
+            GL_EXTCALL(glGetProgramInfoLog(id, length, NULL, log));
+        else
+            GL_EXTCALL(glGetShaderInfoLog(id, length, NULL, log));
 
-        ptr = infoLog;
+        ptr = log;
         if (gl_info->quirks & WINED3D_QUIRK_INFO_LOG_SPAM)
         {
-            WARN("Info log received from GLSL shader #%u:\n", obj);
+            WARN("Info log received from GLSL shader #%u:\n", id);
             while ((line = get_info_log_line(&ptr))) WARN("    %s\n", line);
         }
         else
         {
-            FIXME("Info log received from GLSL shader #%u:\n", obj);
+            FIXME("Info log received from GLSL shader #%u:\n", id);
             while ((line = get_info_log_line(&ptr))) FIXME("    %s\n", line);
         }
-        HeapFree(GetProcessHeap(), 0, infoLog);
+        HeapFree(GetProcessHeap(), 0, log);
     }
 }
 
 /* Context activation is done by the caller. */
-static void shader_glsl_compile(const struct wined3d_gl_info *gl_info, GLhandleARB shader, const char *src)
+static void shader_glsl_compile(const struct wined3d_gl_info *gl_info, GLuint shader, const char *src)
 {
     TRACE("Compiling shader object %u.\n", shader);
-    GL_EXTCALL(glShaderSourceARB(shader, 1, &src, NULL));
-    checkGLcall("glShaderSourceARB");
-    GL_EXTCALL(glCompileShaderARB(shader));
-    checkGLcall("glCompileShaderARB");
-    print_glsl_info_log(gl_info, shader);
+    GL_EXTCALL(glShaderSource(shader, 1, &src, NULL));
+    checkGLcall("glShaderSource");
+    GL_EXTCALL(glCompileShader(shader));
+    checkGLcall("glCompileShader");
+    print_glsl_info_log(gl_info, shader, FALSE);
 }
 
 /* Context activation is done by the caller. */
-static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLhandleARB program)
+static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLuint program)
 {
-    GLint i, object_count, source_size = -1;
-    GLhandleARB *objects;
+    GLint i, shader_count, source_size = -1;
+    GLuint *shaders;
     char *source = NULL;
 
-    GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_ATTACHED_OBJECTS_ARB, &object_count));
-    objects = HeapAlloc(GetProcessHeap(), 0, object_count * sizeof(*objects));
-    if (!objects)
+    GL_EXTCALL(glGetProgramiv(program, GL_ATTACHED_SHADERS, &shader_count));
+    shaders = HeapAlloc(GetProcessHeap(), 0, shader_count * sizeof(*shaders));
+    if (!shaders)
     {
-        ERR("Failed to allocate object array memory.\n");
+        ERR("Failed to allocate shader array memory.\n");
         return;
     }
 
-    GL_EXTCALL(glGetAttachedObjectsARB(program, object_count, NULL, objects));
-    for (i = 0; i < object_count; ++i)
+    GL_EXTCALL(glGetAttachedShaders(program, shader_count, NULL, shaders));
+    for (i = 0; i < shader_count; ++i)
     {
         char *ptr, *line;
         GLint tmp;
 
-        GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &tmp));
+        GL_EXTCALL(glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &tmp));
 
         if (source_size < tmp)
         {
@@ -358,100 +363,92 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf
             if (!source)
             {
                 ERR("Failed to allocate %d bytes for shader source.\n", tmp);
-                HeapFree(GetProcessHeap(), 0, objects);
+                HeapFree(GetProcessHeap(), 0, shaders);
                 return;
             }
             source_size = tmp;
         }
 
-        FIXME("Object %u:\n", objects[i]);
-        GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SUBTYPE_ARB, &tmp));
-        FIXME("    GL_OBJECT_SUBTYPE_ARB: %s.\n", debug_gl_shader_type(tmp));
-        GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_COMPILE_STATUS_ARB, &tmp));
-        FIXME("    GL_OBJECT_COMPILE_STATUS_ARB: %d.\n", tmp);
+        FIXME("Shader %u:\n", shaders[i]);
+        GL_EXTCALL(glGetShaderiv(shaders[i], GL_SHADER_TYPE, &tmp));
+        FIXME("    GL_SHADER_TYPE: %s.\n", debug_gl_shader_type(tmp));
+        GL_EXTCALL(glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &tmp));
+        FIXME("    GL_COMPILE_STATUS: %d.\n", tmp);
         FIXME("\n");
 
         ptr = source;
-        GL_EXTCALL(glGetShaderSourceARB(objects[i], source_size, NULL, source));
+        GL_EXTCALL(glGetShaderSource(shaders[i], source_size, NULL, source));
         while ((line = get_info_log_line(&ptr))) FIXME("    %s\n", line);
         FIXME("\n");
     }
 
     HeapFree(GetProcessHeap(), 0, source);
-    HeapFree(GetProcessHeap(), 0, objects);
+    HeapFree(GetProcessHeap(), 0, shaders);
 }
 
 /* Context activation is done by the caller. */
-static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLhandleARB program)
+static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program)
 {
     GLint tmp;
 
-    if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader)) return;
+    if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader))
+        return;
 
-    GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_TYPE_ARB, &tmp));
-    if (tmp == GL_PROGRAM_OBJECT_ARB)
+    GL_EXTCALL(glGetProgramiv(program, GL_LINK_STATUS, &tmp));
+    if (!tmp)
     {
-        GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &tmp));
-        if (!tmp)
-        {
-            FIXME("Program %u link status invalid.\n", program);
-            shader_glsl_dump_program_source(gl_info, program);
-        }
+        FIXME("Program %u link status invalid.\n", program);
+        shader_glsl_dump_program_source(gl_info, program);
     }
 
-    print_glsl_info_log(gl_info, program);
+    print_glsl_info_log(gl_info, program, TRUE);
 }
 
 /* Context activation is done by the caller. */
-static void shader_glsl_load_psamplers(const struct wined3d_gl_info *gl_info,
-        const DWORD *tex_unit_map, GLhandleARB programId)
+static void shader_glsl_load_samplers(const struct wined3d_gl_info *gl_info,
+        const DWORD *tex_unit_map, GLuint program_id)
 {
-    GLint name_loc;
+    unsigned int mapped_unit;
     char sampler_name[20];
-    unsigned int i;
+    const char *prefix;
+    unsigned int i, j;
+    GLint name_loc;
 
-    for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+    static const struct
     {
-        snprintf(sampler_name, sizeof(sampler_name), "ps_sampler%u", i);
-        name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
-        if (name_loc != -1) {
-            DWORD mapped_unit = tex_unit_map[i];
-            if (mapped_unit != WINED3D_UNMAPPED_STAGE && mapped_unit < gl_info->limits.fragment_samplers)
-            {
-                TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit);
-                GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit));
-                checkGLcall("glUniform1iARB");
-            } else {
-                ERR("Trying to load sampler %s on unsupported unit %d\n", sampler_name, mapped_unit);
-            }
-        }
+        enum wined3d_shader_type type;
+        unsigned int base_idx;
+        unsigned int count;
     }
-}
-
-/* Context activation is done by the caller. */
-static void shader_glsl_load_vsamplers(const struct wined3d_gl_info *gl_info,
-        const DWORD *tex_unit_map, GLhandleARB programId)
-{
-    GLint name_loc;
-    char sampler_name[20];
-    unsigned int i;
+    sampler_info[] =
+    {
+        {WINED3D_SHADER_TYPE_PIXEL,     0,                      MAX_FRAGMENT_SAMPLERS},
+        {WINED3D_SHADER_TYPE_VERTEX,    MAX_FRAGMENT_SAMPLERS,  MAX_VERTEX_SAMPLERS},
+    };
 
-    for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
+    for (i = 0; i < ARRAY_SIZE(sampler_info); ++i)
     {
-        snprintf(sampler_name, sizeof(sampler_name), "vs_sampler%u", i);
-        name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
-        if (name_loc != -1) {
-            DWORD mapped_unit = tex_unit_map[MAX_FRAGMENT_SAMPLERS + i];
-            if (mapped_unit != WINED3D_UNMAPPED_STAGE && mapped_unit < gl_info->limits.combined_samplers)
+        prefix = shader_glsl_get_prefix(sampler_info[i].type);
+
+        for (j = 0; j < sampler_info[i].count; ++j)
+        {
+            snprintf(sampler_name, sizeof(sampler_name), "%s_sampler%u", prefix, j);
+            name_loc = GL_EXTCALL(glGetUniformLocation(program_id, sampler_name));
+            if (name_loc == -1)
+                continue;
+
+            mapped_unit = tex_unit_map[sampler_info[i].base_idx + j];
+            if (mapped_unit == WINED3D_UNMAPPED_STAGE || mapped_unit >= gl_info->limits.combined_samplers)
             {
-                TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit);
-                GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit));
-                checkGLcall("glUniform1iARB");
-            } else {
-                ERR("Trying to load sampler %s on unsupported unit %d\n", sampler_name, mapped_unit);
+                ERR("Trying to load sampler %s on unsupported unit %u.\n", sampler_name, mapped_unit);
+                continue;
             }
+
+            TRACE("Loading sampler %s on unit %u.\n", sampler_name, mapped_unit);
+            GL_EXTCALL(glUniform1i(name_loc, mapped_unit));
         }
     }
+    checkGLcall("glUniform1i");
 }
 
 /* Context activation is done by the caller. */
@@ -524,7 +521,7 @@ static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, con
         }
     }
     if (start <= end)
-        GL_EXTCALL(glUniform4fvARB(constant_locations[start], end - start + 1, &constants[start * 4]));
+        GL_EXTCALL(glUniform4fv(constant_locations[start], end - start + 1, &constants[start * 4]));
     checkGLcall("walk_constant_heap()");
 }
 
@@ -540,7 +537,7 @@ static inline void apply_clamped_constant(const struct wined3d_gl_info *gl_info,
     clamped_constant[2] = data[2] < -1.0f ? -1.0f : data[2] > 1.0f ? 1.0f : data[2];
     clamped_constant[3] = data[3] < -1.0f ? -1.0f : data[3] > 1.0f ? 1.0f : data[3];
 
-    GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant));
+    GL_EXTCALL(glUniform4fv(location, 1, clamped_constant));
 }
 
 /* Context activation is done by the caller. */
@@ -624,9 +621,9 @@ static void shader_glsl_load_constantsF(const struct wined3d_shader *shader, con
     /* Immediate constants are clamped to [-1;1] at shader creation time if needed */
     LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
     {
-        GL_EXTCALL(glUniform4fvARB(constant_locations[lconst->idx], 1, (const GLfloat *)lconst->value));
+        GL_EXTCALL(glUniform4fv(constant_locations[lconst->idx], 1, (const GLfloat *)lconst->value));
     }
-    checkGLcall("glUniform4fvARB()");
+    checkGLcall("glUniform4fv()");
 }
 
 /* Context activation is done by the caller. */
@@ -641,7 +638,7 @@ static void shader_glsl_load_constantsI(const struct wined3d_shader *shader, con
         if (!(constants_set & 1)) continue;
 
         /* We found this uniform name in the program - go ahead and send the data */
-        GL_EXTCALL(glUniform4ivARB(locations[i], 1, &constants[i*4]));
+        GL_EXTCALL(glUniform4iv(locations[i], 1, &constants[i * 4]));
     }
 
     /* Load immediate constants */
@@ -653,10 +650,10 @@ static void shader_glsl_load_constantsI(const struct wined3d_shader *shader, con
         const GLint *values = (const GLint *)lconst->value;
 
         /* We found this uniform name in the program - go ahead and send the data */
-        GL_EXTCALL(glUniform4ivARB(locations[idx], 1, values));
+        GL_EXTCALL(glUniform4iv(locations[idx], 1, values));
         ptr = list_next(&shader->constantsI, ptr);
     }
-    checkGLcall("glUniform4ivARB()");
+    checkGLcall("glUniform4iv()");
 }
 
 /* Context activation is done by the caller. */
@@ -670,7 +667,7 @@ static void shader_glsl_load_constantsB(const struct wined3d_shader *shader, con
     {
         if (!(constants_set & 1)) continue;
 
-        GL_EXTCALL(glUniform1ivARB(locations[i], 1, &constants[i]));
+        GL_EXTCALL(glUniform1iv(locations[i], 1, &constants[i]));
     }
 
     /* Load immediate constants */
@@ -681,10 +678,10 @@ static void shader_glsl_load_constantsB(const struct wined3d_shader *shader, con
         unsigned int idx = lconst->idx;
         const GLint *values = (const GLint *)lconst->value;
 
-        GL_EXTCALL(glUniform1ivARB(locations[idx], 1, values));
+        GL_EXTCALL(glUniform1iv(locations[idx], 1, values));
         ptr = list_next(&shader->constantsB, ptr);
     }
-    checkGLcall("glUniform1ivARB()");
+    checkGLcall("glUniform1iv()");
 }
 
 static void reset_program_constant_version(struct wine_rb_entry *entry, void *context)
@@ -724,7 +721,7 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps
         }
     }
 
-    GL_EXTCALL(glUniform4fvARB(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, np2fixup_constants));
+    GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, np2fixup_constants));
 }
 
 /* Context activation is done by the caller (state handler). */
@@ -765,8 +762,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
     if (update_mask & WINED3D_SHADER_CONST_VS_POS_FIXUP)
     {
         shader_get_position_fixup(context, state, position_fixup);
-        GL_EXTCALL(glUniform4fvARB(prog->vs.pos_fixup_location, 1, position_fixup));
-        checkGLcall("glUniform4fvARB");
+        GL_EXTCALL(glUniform4fv(prog->vs.pos_fixup_location, 1, position_fixup));
+        checkGLcall("glUniform4fv");
     }
 
     if (update_mask & WINED3D_SHADER_CONST_PS_F)
@@ -788,14 +785,14 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
             if (prog->ps.bumpenv_mat_location[i] == -1)
                 continue;
 
-            GL_EXTCALL(glUniformMatrix2fvARB(prog->ps.bumpenv_mat_location[i], 1, 0,
+            GL_EXTCALL(glUniformMatrix2fv(prog->ps.bumpenv_mat_location[i], 1, 0,
                     (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00]));
 
             if (prog->ps.bumpenv_lum_scale_location[i] != -1)
             {
-                GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_scale_location[i], 1,
+                GL_EXTCALL(glUniform1fv(prog->ps.bumpenv_lum_scale_location[i], 1,
                         (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE]));
-                GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_offset_location[i], 1,
+                GL_EXTCALL(glUniform1fv(prog->ps.bumpenv_lum_offset_location[i], 1,
                         (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET]));
             }
         }
@@ -816,7 +813,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
             correction_params[0] = (float) context->current_rt->resource.height;
             correction_params[1] = -1.0f;
         }
-        GL_EXTCALL(glUniform4fvARB(prog->ps.ycorrection_location, 1, correction_params));
+        GL_EXTCALL(glUniform4fv(prog->ps.ycorrection_location, 1, correction_params));
     }
 
     if (update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP)
@@ -829,13 +826,13 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
         if (prog->ps.tex_factor_location != -1)
         {
             D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
-            GL_EXTCALL(glUniform4fvARB(prog->ps.tex_factor_location, 1, col));
+            GL_EXTCALL(glUniform4fv(prog->ps.tex_factor_location, 1, col));
         }
 
         if (state->render_states[WINED3D_RS_SPECULARENABLE])
-            GL_EXTCALL(glUniform4fARB(prog->ps.specular_enable_location, 1.0f, 1.0f, 1.0f, 0.0f));
+            GL_EXTCALL(glUniform4f(prog->ps.specular_enable_location, 1.0f, 1.0f, 1.0f, 0.0f));
         else
-            GL_EXTCALL(glUniform4fARB(prog->ps.specular_enable_location, 0.0f, 0.0f, 0.0f, 0.0f));
+            GL_EXTCALL(glUniform4f(prog->ps.specular_enable_location, 0.0f, 0.0f, 0.0f, 0.0f));
 
         for (i = 0; i < MAX_TEXTURES; ++i)
         {
@@ -843,7 +840,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
                 continue;
 
             D3DCOLORTOGLFLOAT4(state->texture_states[i][WINED3D_TSS_CONSTANT], col);
-            GL_EXTCALL(glUniform4fvARB(prog->ps.tss_constant_location[i], 1, col));
+            GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, col));
         }
 
         checkGLcall("fixed function uniforms");
@@ -962,7 +959,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     }
 
     /* Declare the constants (aka uniforms) */
-    if (shader->limits.constant_float > 0)
+    if (shader->limits->constant_float > 0)
     {
         unsigned max_constantsF;
 
@@ -1016,7 +1013,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
                 /* Set by driver quirks in directx.c */
                 max_constantsF -= gl_info->reserved_glsl_constants;
 
-                if (max_constantsF < shader->limits.constant_float)
+                if (max_constantsF < shader->limits->constant_float)
                 {
                     static unsigned int once;
 
@@ -1032,18 +1029,18 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
                 max_constantsF = gl_info->limits.glsl_vs_float_constants;
             }
         }
-        max_constantsF = min(shader->limits.constant_float, max_constantsF);
+        max_constantsF = min(shader->limits->constant_float, max_constantsF);
         shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF);
     }
 
     /* Always declare the full set of constants, the compiler can remove the
      * unused ones because d3d doesn't (yet) support indirect int and bool
      * constant addressing. This avoids problems if the app uses e.g. i0 and i9. */
-    if (shader->limits.constant_int > 0 && reg_maps->integer_constants)
-        shader_addline(buffer, "uniform ivec4 %s_i[%u];\n", prefix, shader->limits.constant_int);
+    if (shader->limits->constant_int > 0 && reg_maps->integer_constants)
+        shader_addline(buffer, "uniform ivec4 %s_i[%u];\n", prefix, shader->limits->constant_int);
 
-    if (shader->limits.constant_bool > 0 && reg_maps->boolean_constants)
-        shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits.constant_bool);
+    if (shader->limits->constant_bool > 0 && reg_maps->boolean_constants)
+        shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits->constant_bool);
 
     for (i = 0; i < WINED3D_MAX_CBS; ++i)
     {
@@ -1053,55 +1050,68 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     }
 
     /* Declare texture samplers */
-    for (i = 0; i < shader->limits.sampler; ++i)
+    for (i = 0; i < reg_maps->sampler_map.count; ++i)
     {
-        if (reg_maps->sampler_type[i])
+        struct wined3d_shader_sampler_map_entry *entry;
+        BOOL shadow_sampler, tex_rect;
+        const char *sampler_type;
+
+        entry = &reg_maps->sampler_map.entries[i];
+
+        if (entry->resource_idx >= ARRAY_SIZE(reg_maps->resource_info))
         {
-            BOOL shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << i));
-            BOOL tex_rect;
+            ERR("Invalid resource index %u.\n", entry->resource_idx);
+            continue;
+        }
 
-            switch (reg_maps->sampler_type[i])
-            {
-                case WINED3DSTT_1D:
-                    if (shadow_sampler)
-                        shader_addline(buffer, "uniform sampler1DShadow %s_sampler%u;\n", prefix, i);
+        shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << entry->sampler_idx));
+        switch (reg_maps->resource_info[entry->resource_idx].type)
+        {
+            case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
+                if (shadow_sampler)
+                    sampler_type = "sampler1DShadow";
+                else
+                    sampler_type = "sampler1D";
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
+                tex_rect = version->type == WINED3D_SHADER_TYPE_PIXEL
+                        && (ps_args->np2_fixup & (1 << entry->resource_idx))
+                        && gl_info->supported[ARB_TEXTURE_RECTANGLE];
+                if (shadow_sampler)
+                {
+                    if (tex_rect)
+                        sampler_type = "sampler2DRectShadow";
                     else
-                        shader_addline(buffer, "uniform sampler1D %s_sampler%u;\n", prefix, i);
-                    break;
-                case WINED3DSTT_2D:
-                    tex_rect = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->np2_fixup & (1 << i));
-                    tex_rect = tex_rect && gl_info->supported[ARB_TEXTURE_RECTANGLE];
-                    if (shadow_sampler)
-                    {
-                        if (tex_rect)
-                            shader_addline(buffer, "uniform sampler2DRectShadow %s_sampler%u;\n", prefix, i);
-                        else
-                            shader_addline(buffer, "uniform sampler2DShadow %s_sampler%u;\n", prefix, i);
-                    }
+                        sampler_type = "sampler2DShadow";
+                }
+                else
+                {
+                    if (tex_rect)
+                        sampler_type = "sampler2DRect";
                     else
-                    {
-                        if (tex_rect)
-                            shader_addline(buffer, "uniform sampler2DRect %s_sampler%u;\n", prefix, i);
-                        else
-                            shader_addline(buffer, "uniform sampler2D %s_sampler%u;\n", prefix, i);
-                    }
-                    break;
-                case WINED3DSTT_CUBE:
-                    if (shadow_sampler)
-                        FIXME("Unsupported Cube shadow sampler.\n");
-                    shader_addline(buffer, "uniform samplerCube %s_sampler%u;\n", prefix, i);
-                    break;
-                case WINED3DSTT_VOLUME:
-                    if (shadow_sampler)
-                        FIXME("Unsupported 3D shadow sampler.\n");
-                    shader_addline(buffer, "uniform sampler3D %s_sampler%u;\n", prefix, i);
-                    break;
-                default:
-                    shader_addline(buffer, "uniform unsupported_sampler %s_sampler%u;\n", prefix, i);
-                    FIXME("Unrecognized sampler type: %#x\n", reg_maps->sampler_type[i]);
-                    break;
-            }
+                        sampler_type = "sampler2D";
+                }
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
+                if (shadow_sampler)
+                    FIXME("Unsupported 3D shadow sampler.\n");
+                sampler_type = "sampler3D";
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+                if (shadow_sampler)
+                    FIXME("Unsupported Cube shadow sampler.\n");
+                sampler_type = "samplerCube";
+                break;
+
+            default:
+                sampler_type = "unsupported_sampler";
+                FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[i].type);
+                break;
         }
+        shader_addline(buffer, "uniform %s %s_sampler%u;\n", sampler_type, prefix, entry->bind_idx);
     }
 
     /* Declare uniforms for NP2 texcoord fixup:
@@ -1119,19 +1129,18 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
          * samplerNP2Fixup stores texture dimensions and is updated through
          * shader_glsl_load_np2fixup_constants when the sampler changes. */
 
-        for (i = 0; i < shader->limits.sampler; ++i)
+        for (i = 0; i < shader->limits->sampler; ++i)
         {
-            if (reg_maps->sampler_type[i])
-            {
-                if (!(ps_args->np2_fixup & (1 << i))) continue;
-
-                if (WINED3DSTT_2D != reg_maps->sampler_type[i]) {
-                    FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n");
-                    continue;
-                }
+            if (!reg_maps->resource_info[i].type || !(ps_args->np2_fixup & (1 << i)))
+                continue;
 
-                fixup->idx[i] = cur++;
+            if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D)
+            {
+                FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n");
+                continue;
             }
+
+            fixup->idx[i] = cur++;
         }
 
         fixup->num_consts = (cur + 1) >> 1;
@@ -1161,27 +1170,21 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
         }
 
         shader_addline(buffer, "uniform vec4 posFixup;\n");
-        shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits.packed_output);
+        shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits->packed_output);
     }
     else if (version->type == WINED3D_SHADER_TYPE_GEOMETRY)
     {
-        shader_addline(buffer, "varying in vec4 gs_in[][%u];\n", shader->limits.packed_input);
+        shader_addline(buffer, "varying in vec4 gs_in[][%u];\n", shader->limits->packed_input);
     }
     else if (version->type == WINED3D_SHADER_TYPE_PIXEL)
     {
         if (version->major >= 3)
         {
-            UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits.packed_input);
+            UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input);
 
             if (use_vs(state))
-                shader_addline(buffer, "varying vec4 %s_in[%u];\n", prefix, in_count);
-            else
-                /* TODO: Write a replacement shader for the fixed function
-                 * vertex pipeline, so this isn't needed. For fixed function
-                 * vertex processing + 3.0 pixel shader we need a separate
-                 * function in the pixel shader that reads the fixed function
-                 * color into the packed input registers. */
-                shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
+                shader_addline(buffer, "varying vec4 %s_link[%u];\n", prefix, in_count);
+            shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
         }
 
         for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
@@ -1212,7 +1215,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
         }
         if (reg_maps->vpos || reg_maps->usesdsy)
         {
-            if (shader->limits.constant_float + extra_constants_needed
+            if (shader->limits->constant_float + extra_constants_needed
                     + 1 < gl_info->limits.glsl_ps_float_constants)
             {
                 shader_addline(buffer, "uniform vec4 ycorrection;\n");
@@ -1241,8 +1244,8 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     }
 
     /* Declare output register temporaries */
-    if (shader->limits.packed_output)
-        shader_addline(buffer, "vec4 %s_out[%u];\n", prefix, shader->limits.packed_output);
+    if (shader->limits->packed_output)
+        shader_addline(buffer, "vec4 %s_out[%u];\n", prefix, shader->limits->packed_output);
 
     /* Declare temporary variables */
     for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
@@ -1746,28 +1749,28 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i
     }
     else
     {
-        char param_str[200];
-
-        shader_glsl_gen_modifier(wined3d_src->modifiers, glsl_src->reg_name, swizzle_str, param_str);
+        char reg_name[200];
 
         switch (wined3d_src->reg.data_type)
         {
             case WINED3D_DATA_FLOAT:
-                sprintf(glsl_src->param_str, "%s", param_str);
+                sprintf(reg_name, "%s", glsl_src->reg_name);
                 break;
             case WINED3D_DATA_INT:
-                sprintf(glsl_src->param_str, "floatBitsToInt(%s)", param_str);
+                sprintf(reg_name, "floatBitsToInt(%s)", glsl_src->reg_name);
                 break;
             case WINED3D_DATA_RESOURCE:
             case WINED3D_DATA_SAMPLER:
             case WINED3D_DATA_UINT:
-                sprintf(glsl_src->param_str, "floatBitsToUint(%s)", param_str);
+                sprintf(reg_name, "floatBitsToUint(%s)", glsl_src->reg_name);
                 break;
             default:
                 FIXME("Unhandled data type %#x.\n", wined3d_src->reg.data_type);
-                sprintf(glsl_src->param_str, "%s", param_str);
+                sprintf(reg_name, "%s", glsl_src->reg_name);
                 break;
         }
+
+        shader_glsl_gen_modifier(wined3d_src->modifiers, reg_name, swizzle_str, glsl_src->param_str);
     }
 }
 
@@ -1788,14 +1791,15 @@ static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *
 
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
 static DWORD shader_glsl_append_dst_ext(struct wined3d_shader_buffer *buffer,
-        const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst)
+        const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst,
+        enum wined3d_data_type data_type)
 {
     struct glsl_dst_param glsl_dst;
     DWORD mask;
 
     if ((mask = shader_glsl_add_dst_param(ins, dst, &glsl_dst)))
     {
-        switch (dst->reg.data_type)
+        switch (data_type)
         {
             case WINED3D_DATA_FLOAT:
                 shader_addline(buffer, "%s%s = %s(",
@@ -1812,7 +1816,7 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_shader_buffer *buffer,
                         glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
                 break;
             default:
-                FIXME("Unhandled data type %#x.\n", dst->reg.data_type);
+                FIXME("Unhandled data type %#x.\n", data_type);
                 shader_addline(buffer, "%s%s = %s(",
                         glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
                 break;
@@ -1825,7 +1829,7 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_shader_buffer *buffer,
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
 static DWORD shader_glsl_append_dst(struct wined3d_shader_buffer *buffer, const struct wined3d_shader_instruction *ins)
 {
-    return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+    return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
 }
 
 /** Process GLSL instruction modifiers */
@@ -1876,20 +1880,23 @@ static const char *shader_glsl_get_rel_op(enum wined3d_shader_rel_op op)
 }
 
 static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx,
-        DWORD sampler_idx, DWORD flags, struct glsl_sample_function *sample_function)
+        DWORD resource_idx, DWORD flags, struct glsl_sample_function *sample_function)
 {
-    enum wined3d_sampler_texture_type sampler_type = ctx->reg_maps->sampler_type[sampler_idx];
+    enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
     const struct wined3d_gl_info *gl_info = ctx->gl_info;
     BOOL shadow = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
-            && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << sampler_idx));
+            && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << resource_idx));
     BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
     BOOL texrect = flags & WINED3D_GLSL_SAMPLE_NPOT && gl_info->supported[ARB_TEXTURE_RECTANGLE];
     BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
     BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD;
 
+    sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type;
+
     /* Note that there's no such thing as a projected cube texture. */
-    switch(sampler_type) {
-        case WINED3DSTT_1D:
+    switch (resource_type)
+    {
+        case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
             if (shadow)
             {
                 if (lod)
@@ -1940,7 +1947,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
             }
             break;
 
-        case WINED3DSTT_2D:
+        case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
             if (shadow)
             {
                 if (texrect)
@@ -2043,67 +2050,67 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
             }
             break;
 
-        case WINED3DSTT_CUBE:
+        case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
             if (shadow)
             {
-                FIXME("Unsupported Cube shadow function.\n");
-                sample_function->name = "unsupportedCubeShadow";
+                FIXME("Unsupported 3D shadow function.\n");
+                sample_function->name = "unsupported3DShadow";
                 sample_function->coord_mask = 0;
             }
             else
             {
                 if (lod)
                 {
-                    sample_function->name = "textureCubeLod";
+                    sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
                 }
-                else if (grad)
+                else  if (grad)
                 {
                     if (gl_info->supported[EXT_GPU_SHADER4])
-                        sample_function->name = "textureCubeGrad";
+                        sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad";
                     else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
-                        sample_function->name = "textureCubeGradARB";
+                        sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
                     else
                     {
-                        FIXME("Unsupported Cube grad function.\n");
-                        sample_function->name = "unsupportedCubeGrad";
+                        FIXME("Unsupported 3D grad function.\n");
+                        sample_function->name = "unsupported3DGrad";
                     }
                 }
                 else
                 {
-                    sample_function->name = "textureCube";
+                    sample_function->name = projected ? "texture3DProj" : "texture3D";
                 }
                 sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
             }
             break;
 
-        case WINED3DSTT_VOLUME:
+        case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
             if (shadow)
             {
-                FIXME("Unsupported 3D shadow function.\n");
-                sample_function->name = "unsupported3DShadow";
+                FIXME("Unsupported Cube shadow function.\n");
+                sample_function->name = "unsupportedCubeShadow";
                 sample_function->coord_mask = 0;
             }
             else
             {
                 if (lod)
                 {
-                    sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
+                    sample_function->name = "textureCubeLod";
                 }
-                else  if (grad)
+                else if (grad)
                 {
                     if (gl_info->supported[EXT_GPU_SHADER4])
-                        sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad";
+                        sample_function->name = "textureCubeGrad";
                     else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
-                        sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
+                        sample_function->name = "textureCubeGradARB";
                     else
                     {
-                        FIXME("Unsupported 3D grad function.\n");
-                        sample_function->name = "unsupported3DGrad";
+                        FIXME("Unsupported Cube grad function.\n");
+                        sample_function->name = "unsupportedCubeGrad";
                     }
                 }
                 else
                 {
-                    sample_function->name = projected ? "texture3DProj" : "texture3D";
+                    sample_function->name = "textureCube";
                 }
                 sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
             }
@@ -2112,7 +2119,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
         default:
             sample_function->name = "";
             sample_function->coord_mask = 0;
-            FIXME("Unrecognized sampler type: %#x;\n", sampler_type);
+            FIXME("Unhandled resource type %#x.\n", resource_type);
             break;
     }
 }
@@ -2252,7 +2259,7 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s
         fixup = COLOR_FIXUP_IDENTITY; /* FIXME: Vshader color fixup */
     }
 
-    shader_glsl_append_dst(ins->ctx->buffer, ins);
+    shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], sample_function->data_type);
 
     shader_addline(ins->ctx->buffer, "%s(%s_sampler%u, ",
             sample_function->name, shader_glsl_get_prefix(version->type), sampler);
@@ -2303,6 +2310,7 @@ static void shader_glsl_binop(const struct wined3d_shader_instruction *ins)
         case WINED3DSIH_IADD: op = "+";  break;
         case WINED3DSIH_ISHL: op = "<<"; break;
         case WINED3DSIH_MUL:  op = "*";  break;
+        case WINED3DSIH_OR:   op = "|";  break;
         case WINED3DSIH_SUB:  op = "-";  break;
         case WINED3DSIH_USHR: op = ">>"; break;
         case WINED3DSIH_XOR:  op = "^";  break;
@@ -2339,7 +2347,9 @@ static void shader_glsl_relop(const struct wined3d_shader_instruction *ins)
             case WINED3DSIH_EQ:  op = "equal"; break;
             case WINED3DSIH_GE:  op = "greaterThanEqual"; break;
             case WINED3DSIH_IGE: op = "greaterThanEqual"; break;
+            case WINED3DSIH_UGE: op = "greaterThanEqual"; break;
             case WINED3DSIH_LT:  op = "lessThan"; break;
+            case WINED3DSIH_NE:  op = "notEqual"; break;
             default:
                 op = "<unhandled operator>";
                 ERR("Unhandled opcode %#x.\n", ins->handler_idx);
@@ -2356,7 +2366,9 @@ static void shader_glsl_relop(const struct wined3d_shader_instruction *ins)
             case WINED3DSIH_EQ:  op = "=="; break;
             case WINED3DSIH_GE:  op = ">="; break;
             case WINED3DSIH_IGE: op = ">="; break;
+            case WINED3DSIH_UGE: op = ">="; break;
             case WINED3DSIH_LT:  op = "<"; break;
+            case WINED3DSIH_NE:  op = "!="; break;
             default:
                 op = "<unhandled operator>";
                 ERR("Unhandled opcode %#x.\n", ins->handler_idx);
@@ -2382,7 +2394,7 @@ static void shader_glsl_imul(const struct wined3d_shader_instruction *ins)
 
     if (ins->dst[1].reg.type != WINED3DSPR_NULL)
     {
-        write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+        write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
         shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
         shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
 
@@ -2410,17 +2422,17 @@ static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins)
             shader_addline(buffer, "tmp0%s = %s / %s;\n",
                     dst_mask, src0_param.param_str, src1_param.param_str);
 
-            write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+            write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
             shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
             shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
             shader_addline(buffer, "%s %% %s));\n", src0_param.param_str, src1_param.param_str);
 
-            shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+            shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
             shader_addline(buffer, "tmp0%s);\n", dst_mask);
         }
         else
         {
-            write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+            write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
             shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
             shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
             shader_addline(buffer, "%s / %s);\n", src0_param.param_str, src1_param.param_str);
@@ -2428,7 +2440,7 @@ static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins)
     }
     else if (ins->dst[1].reg.type != WINED3DSPR_NULL)
     {
-        write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+        write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
         shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
         shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
         shader_addline(buffer, "%s %% %s);\n", src0_param.param_str, src1_param.param_str);
@@ -2588,6 +2600,7 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
         case WINED3DSIH_DSX: instruction = "dFdx"; break;
         case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break;
         case WINED3DSIH_ROUND_NI: instruction = "floor"; break;
+        case WINED3DSIH_SQRT: instruction = "sqrt"; break;
         default: instruction = "";
             FIXME("Opcode %#x not yet handled in GLSL\n", ins->handler_idx);
             break;
@@ -2892,7 +2905,7 @@ static void shader_glsl_conditional_move(const struct wined3d_shader_instruction
                 continue;
             shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char);
         }
-        else if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst)))
+        else if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst, dst.reg.data_type)))
             continue;
 
         shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
@@ -3170,23 +3183,23 @@ static void shader_glsl_sincos(const struct wined3d_shader_instruction *ins)
             shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
             shader_addline(buffer, "tmp0%s = sin(%s);\n", dst_mask, src0_param.param_str);
 
-            write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+            write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
             shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
             shader_addline(buffer, "cos(%s));\n", src0_param.param_str);
 
-            shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+            shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
             shader_addline(buffer, "tmp0%s);\n", dst_mask);
         }
         else
         {
-            write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+            write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
             shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
             shader_addline(buffer, "sin(%s));\n", src0_param.param_str);
         }
     }
     else if (ins->dst[1].reg.type != WINED3DSPR_NULL)
     {
-        write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+        write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
         shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
         shader_addline(buffer, "cos(%s));\n", src0_param.param_str);
     }
@@ -3351,7 +3364,7 @@ static void shader_glsl_if(const struct wined3d_shader_instruction *ins)
     struct glsl_src_param src0_param;
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
-    shader_addline(ins->ctx->buffer, "if (%s) {\n", src0_param.param_str);
+    shader_addline(ins->ctx->buffer, "if (bool(%s)) {\n", src0_param.param_str);
 }
 
 static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins)
@@ -3438,25 +3451,25 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
             ins->ctx->reg_maps->shader_version.minor);
     struct glsl_sample_function sample_function;
     DWORD sample_flags = 0;
-    DWORD sampler_idx;
+    DWORD resource_idx;
     DWORD mask = 0, swizzle;
     const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
 
     /* 1.0-1.4: Use destination register as sampler source.
      * 2.0+: Use provided sampler source. */
     if (shader_version < WINED3D_SHADER_VERSION(2,0))
-        sampler_idx = ins->dst[0].reg.idx[0].offset;
+        resource_idx = ins->dst[0].reg.idx[0].offset;
     else
-        sampler_idx = ins->src[1].reg.idx[0].offset;
+        resource_idx = ins->src[1].reg.idx[0].offset;
 
     if (shader_version < WINED3D_SHADER_VERSION(1,4))
     {
-        DWORD flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
+        DWORD flags = (priv->cur_ps_args->tex_transform >> resource_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
                 & WINED3D_PSARGS_TEXTRANSFORM_MASK;
-        enum wined3d_sampler_texture_type sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
+        enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type;
 
         /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
-        if (flags & WINED3D_PSARGS_PROJECTED && sampler_type != WINED3DSTT_CUBE)
+        if (flags & WINED3D_PSARGS_PROJECTED && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
         {
             sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
             switch (flags & ~WINED3D_PSARGS_PROJECTED)
@@ -3492,7 +3505,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
     else
     {
         if ((ins->flags & WINED3DSI_TEXLD_PROJECT)
-                && ins->ctx->reg_maps->sampler_type[sampler_idx] != WINED3DSTT_CUBE)
+                && ins->ctx->reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
         {
             /* ps 2.0 texldp instruction always divides by the fourth component. */
             sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
@@ -3500,10 +3513,10 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
         }
     }
 
-    if (priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+    if (priv->cur_ps_args->np2_fixup & (1 << resource_idx))
         sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
 
-    shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
+    shader_glsl_get_sample_function(ins->ctx, resource_idx, sample_flags, &sample_function);
     mask |= sample_function.coord_mask;
 
     if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
@@ -3515,8 +3528,8 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
     {
         char coord_mask[6];
         shader_glsl_write_mask_to_str(mask, coord_mask);
-        shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
-                "T%u%s", sampler_idx, coord_mask);
+        shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL,
+                "T%u%s", resource_idx, coord_mask);
     }
     else
     {
@@ -3526,10 +3539,10 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
         {
             struct glsl_src_param bias;
             shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias);
-            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
+            shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
                     "%s", coord_param.param_str);
         } else {
-            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
+            shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL,
                     "%s", coord_param.param_str);
         }
     }
@@ -3597,6 +3610,37 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
             "%s", coord_param.param_str);
 }
 
+static unsigned int shader_glsl_find_sampler(const struct wined3d_shader_sampler_map *sampler_map,
+        unsigned int resource_idx, unsigned int sampler_idx)
+{
+    struct wined3d_shader_sampler_map_entry *entries = sampler_map->entries;
+    unsigned int i;
+
+    for (i = 0; i < sampler_map->count; ++i)
+    {
+        if (entries[i].resource_idx == resource_idx && entries[i].sampler_idx == sampler_idx)
+            return entries[i].bind_idx;
+    }
+
+    ERR("No GLSL sampler found for resource %u / sampler %u.\n", resource_idx, sampler_idx);
+
+    return ~0u;
+}
+
+static void shader_glsl_sample(const struct wined3d_shader_instruction *ins)
+{
+    struct glsl_sample_function sample_function;
+    struct glsl_src_param coord_param;
+    unsigned int sampler_idx;
+
+    shader_glsl_get_sample_function(ins->ctx, ins->src[1].reg.idx[0].offset, 0, &sample_function);
+    shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
+    sampler_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map,
+            ins->src[1].reg.idx[0].offset, ins->src[2].reg.idx[0].offset);
+    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE,
+            NULL, NULL, NULL, "%s", coord_param.param_str);
+}
+
 static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
 {
     /* FIXME: Make this work for more than just 2D textures */
@@ -4100,7 +4144,16 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
         semantic_idx = input_signature[i].semantic_idx;
         shader_glsl_write_mask_to_str(input_signature[i].mask, reg_mask);
 
-        if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+        if (vertexprocessing == vertexshader)
+        {
+            if (!strcmp(semantic_name, "SV_POSITION") && !semantic_idx)
+                shader_addline(buffer, "ps_in[%u]%s = vpos%s;\n",
+                        shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+            else
+                shader_addline(buffer, "ps_in[%u]%s = ps_link[%u]%s;\n",
+                        shader->u.ps.input_reg_map[i], reg_mask, shader->u.ps.input_reg_map[i], reg_mask);
+        }
+        else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
         {
             if (semantic_idx < 8 && vertexprocessing == pretransformed)
                 shader_addline(buffer, "ps_in[%u]%s = gl_TexCoord[%u]%s;\n",
@@ -4148,7 +4201,7 @@ static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_sh
 }
 
 static struct glsl_shader_prog_link *get_glsl_program_entry(const struct shader_glsl_priv *priv,
-        GLhandleARB vs_id, GLhandleARB gs_id, GLhandleARB ps_id)
+        GLuint vs_id, GLuint gs_id, GLuint ps_id)
 {
     struct wine_rb_entry *entry;
     struct glsl_program_key key;
@@ -4172,7 +4225,7 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struc
     key.ps_id = entry->ps.id;
     wine_rb_remove(&priv->program_lookup, &key);
 
-    GL_EXTCALL(glDeleteObjectARB(entry->programId));
+    GL_EXTCALL(glDeleteProgram(entry->id));
     if (entry->vs.id)
         list_remove(&entry->vs.shader_entry);
     if (entry->gs.id)
@@ -4222,7 +4275,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
         else if (in_idx == in_count + 1)
             sprintf(destination, "gl_FrontSecondaryColor");
         else
-            sprintf(destination, "ps_in[%u]", in_idx);
+            sprintf(destination, "ps_link[%u]", in_idx);
 
         semantic_name_in = input_signature[i].semantic_name;
         semantic_idx_in = input_signature[i].semantic_idx;
@@ -4268,7 +4321,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
         else if (i == in_count + 1)
             sprintf(destination, "gl_FrontSecondaryColor");
         else
-            sprintf(destination, "ps_in[%u]", i);
+            sprintf(destination, "ps_link[%u]", i);
 
         if (size == 1) shader_addline(buffer, "%s.%s = 0.0;\n", destination, reg_mask);
         else shader_addline(buffer, "%s.%s = vec%u(0.0);\n", destination, reg_mask, size);
@@ -4278,11 +4331,11 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
 }
 
 /* Context activation is done by the caller. */
-static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer *buffer,
+static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buffer,
         const struct wined3d_shader *vs, const struct wined3d_shader *ps,
         const struct wined3d_gl_info *gl_info)
 {
-    GLhandleARB ret = 0;
+    GLuint ret = 0;
     DWORD ps_major = ps ? ps->reg_maps.shader_version.major : 0;
     unsigned int i;
     const char *semantic_name;
@@ -4297,7 +4350,7 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
 
     if (ps_major < 3)
     {
-        shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits.packed_output);
+        shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output);
 
         for (i = 0; map; map >>= 1, ++i)
         {
@@ -4319,7 +4372,7 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
                     shader_addline(buffer, "gl_FrontSecondaryColor%s = vs_out[%u]%s;\n",
                             reg_mask, i, reg_mask);
             }
-            else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION))
+            else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx)
             {
                 shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n",
                         reg_mask, i, reg_mask);
@@ -4350,10 +4403,10 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
     }
     else
     {
-        UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits.packed_input);
+        UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits->packed_input);
         /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */
-        shader_addline(buffer, "varying vec4 ps_in[%u];\n", in_count);
-        shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits.packed_output);
+        shader_addline(buffer, "varying vec4 ps_link[%u];\n", in_count);
+        shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output);
 
         /* First, sort out position and point size. Those are not passed to the pixel shader */
         for (i = 0; map; map >>= 1, ++i)
@@ -4361,9 +4414,10 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
             if (!(map & 1)) continue;
 
             semantic_name = output_signature[i].semantic_name;
+            semantic_idx = output_signature[i].semantic_idx;
             shader_glsl_write_mask_to_str(output_signature[i].mask, reg_mask);
 
-            if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION))
+            if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx)
             {
                 shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n",
                         reg_mask, i, reg_mask);
@@ -4381,8 +4435,8 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
         shader_addline(buffer, "}\n");
     }
 
-    ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
-    checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)");
+    ret = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
+    checkGLcall("glCreateShader(GL_VERTEX_SHADER)");
     shader_glsl_compile(gl_info, ret, buffer->buffer);
 
     return ret;
@@ -4438,7 +4492,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
     struct shader_glsl_ctx_priv priv_ctx;
 
     /* Create the hw GLSL shader object and assign it as the shader->prgId */
-    GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
+    GLuint shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
 
     memset(&priv_ctx, 0, sizeof(priv_ctx));
     priv_ctx.cur_ps_args = args;
@@ -4463,7 +4517,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
     shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
 
     /* Pack 3.0 inputs */
-    if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader)
+    if (reg_maps->shader_version.major >= 3)
         shader_glsl_input_pack(shader, buffer, shader->input_signature, reg_maps, args->vp_mode);
 
     /* Base Shader Body */
@@ -4485,11 +4539,10 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
 
     shader_addline(buffer, "}\n");
 
-    TRACE("Compiling shader object %u\n", shader_obj);
-    shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
+    TRACE("Compiling shader object %u.\n", shader_id);
+    shader_glsl_compile(gl_info, shader_id, buffer->buffer);
 
-    /* Store the shader object */
-    return shader_obj;
+    return shader_id;
 }
 
 /* Context activation is done by the caller. */
@@ -4503,7 +4556,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
     struct shader_glsl_ctx_priv priv_ctx;
 
     /* Create the hw GLSL shader program and assign it as the shader->prgId */
-    GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+    GLuint shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
 
     shader_addline(buffer, "#version 120\n");
 
@@ -4560,23 +4613,23 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
 
     shader_addline(buffer, "}\n");
 
-    TRACE("Compiling shader object %u\n", shader_obj);
-    shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
+    TRACE("Compiling shader object %u.\n", shader_id);
+    shader_glsl_compile(gl_info, shader_id, buffer->buffer);
 
-    return shader_obj;
+    return shader_id;
 }
 
 /* Context activation is done by the caller. */
-static GLhandleARB shader_glsl_generate_geometry_shader(const struct wined3d_context *context,
+static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context *context,
         struct wined3d_shader_buffer *buffer, const struct wined3d_shader *shader)
 {
     const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const DWORD *function = shader->function;
     struct shader_glsl_ctx_priv priv_ctx;
-    GLhandleARB shader_id;
+    GLuint shader_id;
 
-    shader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_GEOMETRY_SHADER_ARB));
+    shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER));
 
     shader_addline(buffer, "#version 120\n");
 
@@ -4600,7 +4653,7 @@ static GLhandleARB shader_glsl_generate_geometry_shader(const struct wined3d_con
     return shader_id;
 }
 
-static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
+static GLuint find_glsl_pshader(const struct wined3d_context *context,
         struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader,
         const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
 {
@@ -4609,7 +4662,7 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
     struct ps_np2fixup_info *np2fixup;
     UINT i;
     DWORD new_size;
-    GLhandleARB ret;
+    GLuint ret;
 
     if (!shader->backend_data)
     {
@@ -4633,7 +4686,7 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
         {
             if (args->np2_fixup)
                 *np2fixup_info = &gl_shaders[i].np2fixup;
-            return gl_shaders[i].prgId;
+            return gl_shaders[i].id;
         }
     }
 
@@ -4666,11 +4719,11 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
     memset(np2fixup, 0, sizeof(*np2fixup));
     *np2fixup_info = args->np2_fixup ? np2fixup : NULL;
 
-    pixelshader_update_samplers(shader, args->tex_types);
+    pixelshader_update_resource_types(shader, args->tex_types);
 
     shader_buffer_clear(buffer);
     ret = shader_glsl_generate_pshader(context, buffer, shader, args, np2fixup);
-    gl_shaders[shader_data->num_gl_shaders++].prgId = ret;
+    gl_shaders[shader_data->num_gl_shaders++].id = ret;
 
     return ret;
 }
@@ -4682,7 +4735,7 @@ static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const str
     return stored->fog_src == new->fog_src;
 }
 
-static GLhandleARB find_glsl_vshader(const struct wined3d_context *context,
+static GLuint find_glsl_vshader(const struct wined3d_context *context,
         struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader,
         const struct vs_compile_args *args)
 {
@@ -4691,7 +4744,7 @@ static GLhandleARB find_glsl_vshader(const struct wined3d_context *context,
     DWORD use_map = context->stream_info.use_map;
     struct glsl_vs_compiled_shader *gl_shaders, *new_array;
     struct glsl_shader_private *shader_data;
-    GLhandleARB ret;
+    GLuint ret;
 
     if (!shader->backend_data)
     {
@@ -4712,7 +4765,7 @@ static GLhandleARB find_glsl_vshader(const struct wined3d_context *context,
     for (i = 0; i < shader_data->num_gl_shaders; ++i)
     {
         if (vs_args_equal(&gl_shaders[i].args, args, use_map))
-            return gl_shaders[i].prgId;
+            return gl_shaders[i].id;
     }
 
     TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
@@ -4743,17 +4796,17 @@ static GLhandleARB find_glsl_vshader(const struct wined3d_context *context,
 
     shader_buffer_clear(buffer);
     ret = shader_glsl_generate_vshader(context, buffer, shader, args);
-    gl_shaders[shader_data->num_gl_shaders++].prgId = ret;
+    gl_shaders[shader_data->num_gl_shaders++].id = ret;
 
     return ret;
 }
 
-static GLhandleARB find_glsl_geometry_shader(const struct wined3d_context *context,
+static GLuint find_glsl_geometry_shader(const struct wined3d_context *context,
         struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader)
 {
     struct glsl_gs_compiled_shader *gl_shaders;
     struct glsl_shader_private *shader_data;
-    GLhandleARB ret;
+    GLuint ret;
 
     if (!shader->backend_data)
     {
@@ -4904,10 +4957,10 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_shader_buffer *buffer
 }
 
 /* Context activation is done by the caller. */
-static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffer *buffer,
+static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffer *buffer,
         const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
 {
-    GLhandleARB shader_obj;
+    GLuint shader_obj;
     unsigned int i;
 
     shader_buffer_clear(buffer);
@@ -4995,8 +5048,10 @@ static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_
             if (settings->ortho_fog)
                 /* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */
                 shader_addline(buffer, "gl_FogFragCoord = gl_Position.z * 0.5 + 0.5;\n");
-            else
+            else if (settings->transformed)
                 shader_addline(buffer, "gl_FogFragCoord = ec_pos.z;\n");
+            else
+                shader_addline(buffer, "gl_FogFragCoord = abs(ec_pos.z);\n");
             break;
 
         default:
@@ -5014,7 +5069,7 @@ static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_
 
     shader_addline(buffer, "}\n");
 
-    shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+    shader_obj = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
     shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
 
     return shader_obj;
@@ -5275,7 +5330,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
     BOOL tempreg_used = FALSE, tfactor_used = FALSE;
     const char *final_combiner_src = "ret";
     UINT lowest_disabled_stage;
-    GLhandleARB shader_obj;
+    GLuint shader_id;
     DWORD arg0, arg1, arg2;
     unsigned int stage;
 
@@ -5615,9 +5670,9 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
 
     shader_addline(buffer, "}\n");
 
-    shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
-    shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
-    return shader_obj;
+    shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
+    shader_glsl_compile(gl_info, shader_id, buffer->buffer);
+    return shader_id;
 }
 
 static struct glsl_ffp_vertex_shader *shader_glsl_find_ffp_vertex_shader(struct shader_glsl_priv *priv,
@@ -5663,83 +5718,83 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str
 
 
 static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info,
-        GLhandleARB program_id, struct glsl_vs_program *vs, unsigned int vs_c_count)
+        GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count)
 {
     unsigned int i;
     char name[32];
 
     vs->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0,
-            sizeof(GLhandleARB) * gl_info->limits.glsl_vs_float_constants);
+            sizeof(GLuint) * gl_info->limits.glsl_vs_float_constants);
     for (i = 0; i < vs_c_count; ++i)
     {
         snprintf(name, sizeof(name), "vs_c[%u]", i);
-        vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
     }
     memset(&vs->uniform_f_locations[vs_c_count], 0xff,
-            (gl_info->limits.glsl_vs_float_constants - vs_c_count) * sizeof(GLhandleARB));
+            (gl_info->limits.glsl_vs_float_constants - vs_c_count) * sizeof(GLuint));
 
     for (i = 0; i < MAX_CONST_I; ++i)
     {
         snprintf(name, sizeof(name), "vs_i[%u]", i);
-        vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
     }
 
     for (i = 0; i < MAX_CONST_B; ++i)
     {
         snprintf(name, sizeof(name), "vs_b[%u]", i);
-        vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
     }
 
-    vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "posFixup"));
+    vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "posFixup"));
 }
 
 static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info,
-        GLhandleARB program_id, struct glsl_ps_program *ps, unsigned int ps_c_count)
+        GLuint program_id, struct glsl_ps_program *ps, unsigned int ps_c_count)
 {
     unsigned int i;
     char name[32];
 
     ps->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0,
-            sizeof(GLhandleARB) * gl_info->limits.glsl_ps_float_constants);
+            sizeof(GLuint) * gl_info->limits.glsl_ps_float_constants);
     for (i = 0; i < ps_c_count; ++i)
     {
         snprintf(name, sizeof(name), "ps_c[%u]", i);
-        ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
     }
     memset(&ps->uniform_f_locations[ps_c_count], 0xff,
-            (gl_info->limits.glsl_ps_float_constants - ps_c_count) * sizeof(GLhandleARB));
+            (gl_info->limits.glsl_ps_float_constants - ps_c_count) * sizeof(GLuint));
 
     for (i = 0; i < MAX_CONST_I; ++i)
     {
         snprintf(name, sizeof(name), "ps_i[%u]", i);
-        ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
     }
 
     for (i = 0; i < MAX_CONST_B; ++i)
     {
         snprintf(name, sizeof(name), "ps_b[%u]", i);
-        ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
     }
 
     for (i = 0; i < MAX_TEXTURES; ++i)
     {
         snprintf(name, sizeof(name), "bumpenv_mat%u", i);
-        ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
         snprintf(name, sizeof(name), "bumpenv_lum_scale%u", i);
-        ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
         snprintf(name, sizeof(name), "bumpenv_lum_offset%u", i);
-        ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
         snprintf(name, sizeof(name), "tss_const%u", i);
-        ps->tss_constant_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+        ps->tss_constant_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
     }
 
-    ps->tex_factor_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "tex_factor"));
-    ps->specular_enable_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "specular_enable"));
-    ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "ps_samplerNP2Fixup"));
-    ps->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "ycorrection"));
+    ps->tex_factor_location = GL_EXTCALL(glGetUniformLocation(program_id, "tex_factor"));
+    ps->specular_enable_location = GL_EXTCALL(glGetUniformLocation(program_id, "specular_enable"));
+    ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "ps_samplerNP2Fixup"));
+    ps->ycorrection_location = GL_EXTCALL(glGetUniformLocation(program_id, "ycorrection"));
 }
 
-static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, GLhandleARB program_id,
+static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, GLuint program_id,
         const struct wined3d_shader_reg_maps *reg_maps, unsigned int base, unsigned int count)
 {
     const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type);
@@ -5769,13 +5824,13 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     struct wined3d_shader *vshader = NULL;
     struct wined3d_shader *gshader = NULL;
     struct wined3d_shader *pshader = NULL;
-    GLhandleARB programId                  = 0;
-    GLhandleARB reorder_shader_id          = 0;
+    GLuint program_id = 0;
+    GLuint reorder_shader_id = 0;
     unsigned int i;
-    GLhandleARB vs_id = 0;
-    GLhandleARB gs_id = 0;
-    GLhandleARB ps_id = 0;
-    struct list *ps_list, *vs_list;
+    GLuint vs_id = 0;
+    GLuint gs_id = 0;
+    GLuint ps_id = 0;
+    struct list *ps_list = NULL, *vs_list = NULL;
 
     if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_VERTEX)))
     {
@@ -5852,12 +5907,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     }
 
     /* If we get to this point, then no matching program exists, so we create one */
-    programId = GL_EXTCALL(glCreateProgramObjectARB());
-    TRACE("Created new GLSL shader program %u\n", programId);
+    program_id = GL_EXTCALL(glCreateProgram());
+    TRACE("Created new GLSL shader program %u.\n", program_id);
 
     /* Create the entry */
     entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
-    entry->programId = programId;
+    entry->id = program_id;
     entry->vs.id = vs_id;
     entry->gs.id = gs_id;
     entry->ps.id = ps_id;
@@ -5872,9 +5927,9 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     /* Attach GLSL vshader */
     if (vs_id)
     {
-        TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, programId);
-        GL_EXTCALL(glAttachObjectARB(programId, vs_id));
-        checkGLcall("glAttachObjectARB");
+        TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, program_id);
+        GL_EXTCALL(glAttachShader(program_id, vs_id));
+        checkGLcall("glAttachShader");
 
         list_add_head(vs_list, &entry->vs.shader_entry);
     }
@@ -5885,13 +5940,13 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
         char tmp_name[10];
 
         reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info);
-        TRACE("Attaching GLSL shader object %u to program %u\n", reorder_shader_id, programId);
-        GL_EXTCALL(glAttachObjectARB(programId, reorder_shader_id));
-        checkGLcall("glAttachObjectARB");
+        TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id);
+        GL_EXTCALL(glAttachShader(program_id, reorder_shader_id));
+        checkGLcall("glAttachShader");
         /* Flag the reorder function for deletion, then it will be freed automatically when the program
          * is destroyed
          */
-        GL_EXTCALL(glDeleteObjectARB(reorder_shader_id));
+        GL_EXTCALL(glDeleteShader(reorder_shader_id));
 
         /* Bind vertex attributes to a corresponding index number to match
          * the same index numbers as ARB_vertex_programs (makes loading
@@ -5907,26 +5962,26 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
             if (!(map & 1)) continue;
 
             snprintf(tmp_name, sizeof(tmp_name), "vs_in%u", i);
-            GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
+            GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name));
         }
-        checkGLcall("glBindAttribLocationARB");
+        checkGLcall("glBindAttribLocation");
     }
 
     if (gshader)
     {
-        TRACE("Attaching GLSL geometry shader object %u to program %u.\n", gs_id, programId);
-        GL_EXTCALL(glAttachObjectARB(programId, gs_id));
-        checkGLcall("glAttachObjectARB");
+        TRACE("Attaching GLSL geometry shader object %u to program %u.\n", gs_id, program_id);
+        GL_EXTCALL(glAttachShader(program_id, gs_id));
+        checkGLcall("glAttachShader");
 
         TRACE("input type %s, output type %s, vertices out %u.\n",
                 debug_d3dprimitivetype(gshader->u.gs.input_type),
                 debug_d3dprimitivetype(gshader->u.gs.output_type),
                 gshader->u.gs.vertices_out);
-        GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_INPUT_TYPE_ARB,
+        GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_INPUT_TYPE_ARB,
                 gl_primitive_type_from_d3d(gshader->u.gs.input_type)));
-        GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_OUTPUT_TYPE_ARB,
+        GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_OUTPUT_TYPE_ARB,
                 gl_primitive_type_from_d3d(gshader->u.gs.output_type)));
-        GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_VERTICES_OUT_ARB,
+        GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_VERTICES_OUT_ARB,
                 gshader->u.gs.vertices_out));
         checkGLcall("glProgramParameteriARB");
 
@@ -5936,28 +5991,28 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     /* Attach GLSL pshader */
     if (ps_id)
     {
-        TRACE("Attaching GLSL shader object %u to program %u.\n", ps_id, programId);
-        GL_EXTCALL(glAttachObjectARB(programId, ps_id));
-        checkGLcall("glAttachObjectARB");
+        TRACE("Attaching GLSL shader object %u to program %u.\n", ps_id, program_id);
+        GL_EXTCALL(glAttachShader(program_id, ps_id));
+        checkGLcall("glAttachShader");
 
         list_add_head(ps_list, &entry->ps.shader_entry);
     }
 
     /* Link the program */
-    TRACE("Linking GLSL shader program %u\n", programId);
-    GL_EXTCALL(glLinkProgramARB(programId));
-    shader_glsl_validate_link(gl_info, programId);
-
-    shader_glsl_init_vs_uniform_locations(gl_info, programId, &entry->vs,
-            vshader ? vshader->limits.constant_float : 0);
-    shader_glsl_init_ps_uniform_locations(gl_info, programId, &entry->ps,
-            pshader ? pshader->limits.constant_float : 0);
+    TRACE("Linking GLSL shader program %u.\n", program_id);
+    GL_EXTCALL(glLinkProgram(program_id));
+    shader_glsl_validate_link(gl_info, program_id);
+
+    shader_glsl_init_vs_uniform_locations(gl_info, program_id, &entry->vs,
+            vshader ? min(vshader->limits->constant_float, gl_info->limits.glsl_vs_float_constants) : 0);
+    shader_glsl_init_ps_uniform_locations(gl_info, program_id, &entry->ps,
+            pshader ? min(pshader->limits->constant_float, gl_info->limits.glsl_ps_float_constants) : 0);
     checkGLcall("Find glsl program uniform locations");
 
     if (pshader && pshader->reg_maps.shader_version.major >= 3
             && pshader->u.ps.declared_in_count > vec4_varyings(3, gl_info))
     {
-        TRACE("Shader %d needs vertex color clamping disabled\n", programId);
+        TRACE("Shader %d needs vertex color clamping disabled.\n", program_id);
         entry->vs.vertex_color_clamp = GL_FALSE;
     }
     else
@@ -5966,8 +6021,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     }
 
     /* Set the shader to allow uniform loading on it */
-    GL_EXTCALL(glUseProgramObjectARB(programId));
-    checkGLcall("glUseProgramObjectARB(programId)");
+    GL_EXTCALL(glUseProgram(program_id));
+    checkGLcall("glUseProgram");
 
     /* Load the vertex and pixel samplers now. The function that finds the mappings makes sure
      * that it stays the same for each vertexshader-pixelshader pair(=linked glsl program). If
@@ -5975,10 +6030,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
      * vertex shader with fixed function pixel processing is used we make sure that the card
      * supports enough samplers to allow the max number of vertex samplers with all possible
      * fixed function fragment processing setups. So once the program is linked these samplers
-     * won't change.
-     */
-    shader_glsl_load_vsamplers(gl_info, context->tex_unit_map, programId);
-    shader_glsl_load_psamplers(gl_info, context->tex_unit_map, programId);
+     * won't change. */
+    shader_glsl_load_samplers(gl_info, context->tex_unit_map, program_id);
 
     entry->constant_update_mask = 0;
     if (vshader)
@@ -5990,12 +6043,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
             entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B;
         entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP;
 
-        shader_glsl_init_uniform_block_bindings(gl_info, programId, &vshader->reg_maps,
+        shader_glsl_init_uniform_block_bindings(gl_info, program_id, &vshader->reg_maps,
                 0, gl_info->limits.vertex_uniform_blocks);
     }
 
     if (gshader)
-        shader_glsl_init_uniform_block_bindings(gl_info, programId, &gshader->reg_maps,
+        shader_glsl_init_uniform_block_bindings(gl_info, program_id, &gshader->reg_maps,
                 gl_info->limits.vertex_uniform_blocks, gl_info->limits.geometry_uniform_blocks);
 
     if (ps_id)
@@ -6010,7 +6063,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
             if (entry->ps.ycorrection_location != -1)
                 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR;
 
-            shader_glsl_init_uniform_block_bindings(gl_info, programId, &pshader->reg_maps,
+            shader_glsl_init_uniform_block_bindings(gl_info, program_id, &pshader->reg_maps,
                     gl_info->limits.vertex_uniform_blocks + gl_info->limits.geometry_uniform_blocks,
                     gl_info->limits.fragment_uniform_blocks);
         }
@@ -6034,10 +6087,10 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
 }
 
 /* Context activation is done by the caller. */
-static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked)
+static GLuint create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked)
 {
-    GLhandleARB program_id;
-    GLhandleARB vshader_id, pshader_id;
+    GLuint program_id;
+    GLuint vshader_id, pshader_id;
     const char *blt_pshader;
 
     static const char blt_vshader[] =
@@ -6122,24 +6175,24 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info,
         return 0;
     }
 
-    vshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+    vshader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
     shader_glsl_compile(gl_info, vshader_id, blt_vshader);
 
-    pshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
+    pshader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
     shader_glsl_compile(gl_info, pshader_id, blt_pshader);
 
-    program_id = GL_EXTCALL(glCreateProgramObjectARB());
-    GL_EXTCALL(glAttachObjectARB(program_id, vshader_id));
-    GL_EXTCALL(glAttachObjectARB(program_id, pshader_id));
-    GL_EXTCALL(glLinkProgramARB(program_id));
+    program_id = GL_EXTCALL(glCreateProgram());
+    GL_EXTCALL(glAttachShader(program_id, vshader_id));
+    GL_EXTCALL(glAttachShader(program_id, pshader_id));
+    GL_EXTCALL(glLinkProgram(program_id));
 
     shader_glsl_validate_link(gl_info, program_id);
 
     /* Once linked we can mark the shaders for deletion. They will be deleted once the program
      * is destroyed
      */
-    GL_EXTCALL(glDeleteObjectARB(vshader_id));
-    GL_EXTCALL(glDeleteObjectARB(pshader_id));
+    GL_EXTCALL(glDeleteShader(vshader_id));
+    GL_EXTCALL(glDeleteShader(pshader_id));
     return program_id;
 }
 
@@ -6150,7 +6203,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex
     struct glsl_context_data *ctx_data = context->shader_backend_data;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_priv *priv = shader_priv;
-    GLhandleARB program_id = 0, prev_id = 0;
+    GLuint program_id = 0, prev_id = 0;
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;
 
     priv->vertex_pipe->vp_enable(gl_info, !use_vs(state));
@@ -6158,7 +6211,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex
 
     if (ctx_data->glsl_program)
     {
-        prev_id = ctx_data->glsl_program->programId;
+        prev_id = ctx_data->glsl_program->id;
         old_vertex_color_clamp = ctx_data->glsl_program->vs.vertex_color_clamp;
     }
     else
@@ -6171,7 +6224,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex
 
     if (ctx_data->glsl_program)
     {
-        program_id = ctx_data->glsl_program->programId;
+        program_id = ctx_data->glsl_program->id;
         current_vertex_color_clamp = ctx_data->glsl_program->vs.vertex_color_clamp;
     }
     else
@@ -6197,8 +6250,8 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex
 
     if (prev_id != program_id)
     {
-        GL_EXTCALL(glUseProgramObjectARB(program_id));
-        checkGLcall("glUseProgramObjectARB");
+        GL_EXTCALL(glUseProgram(program_id));
+        checkGLcall("glUseProgram");
 
         if (program_id)
             context->constant_update_mask |= ctx_data->glsl_program->constant_update_mask;
@@ -6223,8 +6276,8 @@ static void shader_glsl_disable(void *shader_priv, struct wined3d_context *conte
     struct shader_glsl_priv *priv = shader_priv;
 
     shader_glsl_invalidate_current_program(context);
-    GL_EXTCALL(glUseProgramObjectARB(0));
-    checkGLcall("glUseProgramObjectARB");
+    GL_EXTCALL(glUseProgram(0));
+    checkGLcall("glUseProgram");
 
     priv->vertex_pipe->vp_enable(gl_info, FALSE);
     priv->fragment_pipe->enable_extension(gl_info, FALSE);
@@ -6242,26 +6295,26 @@ static void shader_glsl_select_depth_blt(void *shader_priv, const struct wined3d
 {
     BOOL masked = ds_mask_size->cx && ds_mask_size->cy;
     struct shader_glsl_priv *priv = shader_priv;
-    GLhandleARB *blt_program;
+    GLuint *blt_program;
     GLint loc;
 
     blt_program = masked ? &priv->depth_blt_program_masked[tex_type] : &priv->depth_blt_program_full[tex_type];
     if (!*blt_program)
     {
         *blt_program = create_glsl_blt_shader(gl_info, tex_type, masked);
-        loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "sampler"));
-        GL_EXTCALL(glUseProgramObjectARB(*blt_program));
-        GL_EXTCALL(glUniform1iARB(loc, 0));
+        loc = GL_EXTCALL(glGetUniformLocation(*blt_program, "sampler"));
+        GL_EXTCALL(glUseProgram(*blt_program));
+        GL_EXTCALL(glUniform1i(loc, 0));
     }
     else
     {
-        GL_EXTCALL(glUseProgramObjectARB(*blt_program));
+        GL_EXTCALL(glUseProgram(*blt_program));
     }
 
     if (masked)
     {
-        loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "mask"));
-        GL_EXTCALL(glUniform4fARB(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy));
+        loc = GL_EXTCALL(glGetUniformLocation(*blt_program, "mask"));
+        GL_EXTCALL(glUniform4f(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy));
     }
 }
 
@@ -6269,13 +6322,13 @@ static void shader_glsl_select_depth_blt(void *shader_priv, const struct wined3d
 static void shader_glsl_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info)
 {
     const struct glsl_context_data *ctx_data = context_get_current()->shader_backend_data;
-    GLhandleARB program_id;
+    GLuint program_id;
 
-    program_id = ctx_data->glsl_program ? ctx_data->glsl_program->programId : 0;
+    program_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0;
     if (program_id) TRACE("Using GLSL program %u\n", program_id);
 
-    GL_EXTCALL(glUseProgramObjectARB(program_id));
-    checkGLcall("glUseProgramObjectARB");
+    GL_EXTCALL(glUseProgram(program_id));
+    checkGLcall("glUseProgram");
 }
 
 static void shader_glsl_invalidate_contexts_program(struct wined3d_device *device,
@@ -6329,9 +6382,9 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
 
                 for (i = 0; i < shader_data->num_gl_shaders; ++i)
                 {
-                    TRACE("Deleting pixel shader %u.\n", gl_shaders[i].prgId);
-                    GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
-                    checkGLcall("glDeleteObjectARB");
+                    TRACE("Deleting pixel shader %u.\n", gl_shaders[i].id);
+                    GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
+                    checkGLcall("glDeleteShader");
                 }
                 HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ps);
 
@@ -6351,9 +6404,9 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
 
                 for (i = 0; i < shader_data->num_gl_shaders; ++i)
                 {
-                    TRACE("Deleting vertex shader %u.\n", gl_shaders[i].prgId);
-                    GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
-                    checkGLcall("glDeleteObjectARB");
+                    TRACE("Deleting vertex shader %u.\n", gl_shaders[i].id);
+                    GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
+                    checkGLcall("glDeleteShader");
                 }
                 HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.vs);
 
@@ -6374,8 +6427,8 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
                 for (i = 0; i < shader_data->num_gl_shaders; ++i)
                 {
                     TRACE("Deleting geometry shader %u.\n", gl_shaders[i].id);
-                    GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].id));
-                    checkGLcall("glDeleteObjectARB");
+                    GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
+                    checkGLcall("glDeleteShader");
                 }
                 HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.gs);
 
@@ -6545,11 +6598,11 @@ static void shader_glsl_free(struct wined3d_device *device)
     {
         if (priv->depth_blt_program_full[i])
         {
-            GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_full[i]));
+            GL_EXTCALL(glDeleteProgram(priv->depth_blt_program_full[i]));
         }
         if (priv->depth_blt_program_masked[i])
         {
-            GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_masked[i]));
+            GL_EXTCALL(glDeleteProgram(priv->depth_blt_program_masked[i]));
         }
     }
 
@@ -6583,7 +6636,7 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s
     if (gl_info->supported[EXT_GPU_SHADER4] && gl_info->supported[ARB_SHADER_BIT_ENCODING]
             && gl_info->supported[ARB_GEOMETRY_SHADER4] && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50)
             && gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && gl_info->supported[ARB_DRAW_INSTANCED]
-            && gl_info->supported[ARB_TEXTURE_RG])
+            && gl_info->supported[ARB_TEXTURE_RG] && gl_info->supported[ARB_SAMPLER_OBJECTS])
         shader_model = 4;
     /* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3
      * texldd and texldl instructions. */
@@ -6713,8 +6766,10 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_MOVA                  */ shader_glsl_mov,
     /* WINED3DSIH_MOVC                  */ shader_glsl_conditional_move,
     /* WINED3DSIH_MUL                   */ shader_glsl_binop,
+    /* WINED3DSIH_NE                    */ shader_glsl_relop,
     /* WINED3DSIH_NOP                   */ shader_glsl_nop,
     /* WINED3DSIH_NRM                   */ shader_glsl_nrm,
+    /* WINED3DSIH_OR                    */ shader_glsl_binop,
     /* WINED3DSIH_PHASE                 */ shader_glsl_nop,
     /* WINED3DSIH_POW                   */ shader_glsl_pow,
     /* WINED3DSIH_RCP                   */ shader_glsl_scalar_op,
@@ -6722,7 +6777,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_RET                   */ shader_glsl_ret,
     /* WINED3DSIH_ROUND_NI              */ shader_glsl_map2gl,
     /* WINED3DSIH_RSQ                   */ shader_glsl_scalar_op,
-    /* WINED3DSIH_SAMPLE                */ NULL,
+    /* WINED3DSIH_SAMPLE                */ shader_glsl_sample,
     /* WINED3DSIH_SAMPLE_GRAD           */ NULL,
     /* WINED3DSIH_SAMPLE_LOD            */ NULL,
     /* WINED3DSIH_SETP                  */ NULL,
@@ -6730,7 +6785,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_SGN                   */ shader_glsl_sgn,
     /* WINED3DSIH_SINCOS                */ shader_glsl_sincos,
     /* WINED3DSIH_SLT                   */ shader_glsl_compare,
-    /* WINED3DSIH_SQRT                  */ NULL,
+    /* WINED3DSIH_SQRT                  */ shader_glsl_map2gl,
     /* WINED3DSIH_SUB                   */ shader_glsl_binop,
     /* WINED3DSIH_TEX                   */ shader_glsl_tex,
     /* WINED3DSIH_TEXBEM                */ shader_glsl_texbem,
@@ -6755,6 +6810,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_TEXREG2GB             */ shader_glsl_texreg2gb,
     /* WINED3DSIH_TEXREG2RGB            */ shader_glsl_texreg2rgb,
     /* WINED3DSIH_UDIV                  */ shader_glsl_udiv,
+    /* WINED3DSIH_UGE                   */ shader_glsl_relop,
     /* WINED3DSIH_USHR                  */ shader_glsl_binop,
     /* WINED3DSIH_UTOF                  */ shader_glsl_to_float,
     /* WINED3DSIH_XOR                   */ shader_glsl_binop,
@@ -6865,7 +6921,7 @@ static void shader_glsl_free_ffp_vertex_shader(struct wine_rb_entry *entry, void
     {
         delete_glsl_program_entry(ctx->priv, ctx->gl_info, program);
     }
-    ctx->gl_info->gl_ops.ext.p_glDeleteObjectARB(shader->id);
+    ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id);
     HeapFree(GetProcessHeap(), 0, shader);
 }
 
@@ -7137,7 +7193,7 @@ static void shader_glsl_free_ffp_fragment_shader(struct wine_rb_entry *entry, vo
     {
         delete_glsl_program_entry(ctx->priv, ctx->gl_info, program);
     }
-    ctx->gl_info->gl_ops.ext.p_glDeleteObjectARB(shader->id);
+    ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id);
     HeapFree(GetProcessHeap(), 0, shader);
 }
 
index 443626b..1ce9ba1 100644 (file)
@@ -348,16 +348,16 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
 
     context = context_acquire(query->device, oq->context->current_rt);
 
-    GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
-    checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
+    GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
+    checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
     TRACE("available %#x.\n", available);
 
     if (available)
     {
         if (size)
         {
-            GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_ARB, &samples));
-            checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
+            GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples));
+            checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)");
             TRACE("Returning %d samples.\n", samples);
             fill_query_data(data, size, &samples, sizeof(samples));
         }
@@ -490,7 +490,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
                 {
                     context = context_acquire(query->device, oq->context->current_rt);
 
-                    GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
+                    GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
                     checkGLcall("glEndQuery()");
                 }
             }
@@ -501,7 +501,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
                 context_alloc_occlusion_query(context, oq);
             }
 
-            GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, oq->id));
+            GL_EXTCALL(glBeginQuery(GL_SAMPLES_PASSED, oq->id));
             checkGLcall("glBeginQuery()");
 
             context_release(context);
@@ -522,7 +522,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
                 {
                     context = context_acquire(query->device, oq->context->current_rt);
 
-                    GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
+                    GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
                     checkGLcall("glEndQuery()");
 
                     context_release(context);
@@ -578,16 +578,16 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
 
     context = context_acquire(query->device, tq->context->current_rt);
 
-    GL_EXTCALL(glGetQueryObjectuivARB(tq->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
-    checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
+    GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available));
+    checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
     TRACE("available %#x.\n", available);
 
     if (available)
     {
         if (size)
         {
-            GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT_ARB, &timestamp));
-            checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
+            GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, &timestamp));
+            checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)");
             TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp));
             fill_query_data(data, size, &timestamp, sizeof(timestamp));
         }
index 9b73bfc..d94fb76 100644 (file)
@@ -48,7 +48,7 @@ static DWORD resource_access_from_pool(enum wined3d_pool pool)
 
 static void resource_check_usage(DWORD usage)
 {
-    static const DWORD handled = WINED3DUSAGE_RENDERTARGET
+    static DWORD handled = WINED3DUSAGE_RENDERTARGET
             | WINED3DUSAGE_DEPTHSTENCIL
             | WINED3DUSAGE_WRITEONLY
             | WINED3DUSAGE_DYNAMIC
@@ -64,7 +64,10 @@ static void resource_check_usage(DWORD usage)
      * driver. */
 
     if (usage & ~handled)
+    {
         FIXME("Unhandled usage flags %#x.\n", usage & ~handled);
+        handled |= usage;
+    }
     if ((usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY)) == WINED3DUSAGE_DYNAMIC)
         WARN_(d3d_perf)("WINED3DUSAGE_DYNAMIC used without WINED3DUSAGE_WRITEONLY.\n");
 }
@@ -79,14 +82,23 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
     const struct wined3d *d3d = device->wined3d;
 
     resource_check_usage(usage);
-    if (pool != WINED3D_POOL_SCRATCH)
+    if (pool != WINED3D_POOL_SCRATCH && type != WINED3D_RTYPE_BUFFER)
     {
         if ((usage & WINED3DUSAGE_RENDERTARGET) && !(format->flags & WINED3DFMT_FLAG_RENDERTARGET))
+        {
+            WARN("Format %s cannot be used for render targets.\n", debug_d3dformat(format->id));
             return WINED3DERR_INVALIDCALL;
+        }
         if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && !(format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
+        {
+            WARN("Format %s cannot be used for depth/stencil buffers.\n", debug_d3dformat(format->id));
             return WINED3DERR_INVALIDCALL;
+        }
         if ((usage & WINED3DUSAGE_TEXTURE) && !(format->flags & WINED3DFMT_FLAG_TEXTURE))
+        {
+            WARN("Format %s cannot be used for texturing.\n", debug_d3dformat(format->id));
             return WINED3DERR_INVALIDCALL;
+        }
     }
 
     resource->ref = 1;
@@ -149,7 +161,7 @@ void resource_cleanup(struct wined3d_resource *resource)
     if (resource->pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
     {
         TRACE("Decrementing device memory pool by %u.\n", resource->size);
-        adapter_adjust_memory(resource->device->adapter, 0 - resource->size);
+        adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size);
     }
 
     wined3d_resource_free_sysmem(resource);
index d82c4c9..84ba74a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Henri Verbeet for CodeWeavers
+ * Copyright 2012, 2015 Henri Verbeet for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -33,11 +33,20 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler)
 ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
 {
     ULONG refcount = InterlockedDecrement(&sampler->refcount);
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
 
     TRACE("%p decreasing refcount to %u.\n", sampler, refcount);
 
     if (!refcount)
+    {
+        context = context_acquire(sampler->device, NULL);
+        gl_info = context->gl_info;
+        GL_EXTCALL(glDeleteSamplers(1, &sampler->name));
+        context_release(context);
+
         HeapFree(GetProcessHeap(), 0, sampler);
+    }
 
     return refcount;
 }
@@ -49,22 +58,74 @@ void * CDECL wined3d_sampler_get_parent(const struct wined3d_sampler *sampler)
     return sampler->parent;
 }
 
-static void wined3d_sampler_init(struct wined3d_sampler *sampler, void *parent)
+static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d_device *device,
+        const struct wined3d_sampler_desc *desc, void *parent)
 {
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
+
     sampler->refcount = 1;
+    sampler->device = device;
     sampler->parent = parent;
+    sampler->desc = *desc;
+
+    context = context_acquire(device, NULL);
+    gl_info = context->gl_info;
+
+    GL_EXTCALL(glGenSamplers(1, &sampler->name));
+    GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_S,
+            gl_info->wrap_lookup[desc->address_u - WINED3D_TADDRESS_WRAP]));
+    GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_T,
+            gl_info->wrap_lookup[desc->address_v - WINED3D_TADDRESS_WRAP]));
+    GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_R,
+            gl_info->wrap_lookup[desc->address_w - WINED3D_TADDRESS_WRAP]));
+    GL_EXTCALL(glSamplerParameterfv(sampler->name, GL_TEXTURE_BORDER_COLOR, &desc->border_color[0]));
+    GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAG_FILTER,
+            wined3d_gl_mag_filter(desc->mag_filter)));
+    GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MIN_FILTER,
+            wined3d_gl_min_mip_filter(desc->min_filter, desc->mip_filter)));
+    GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_LOD_BIAS, desc->lod_bias));
+    GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MIN_LOD, desc->min_lod));
+    GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MAX_LOD, desc->max_lod));
+    if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+        GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAX_ANISOTROPY_EXT, desc->max_anisotropy));
+    if (desc->compare)
+        GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE));
+    GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_FUNC,
+            wined3d_gl_compare_func(desc->comparison_func)));
+    if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && !desc->srgb_decode)
+        GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT));
+    checkGLcall("sampler creation");
+
+    TRACE("Created sampler %u.\n", sampler->name);
+
+    context_release(context);
 }
 
-HRESULT CDECL wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler)
+HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
+        void *parent, struct wined3d_sampler **sampler)
 {
     struct wined3d_sampler *object;
 
-    TRACE("parent %p, sampler %p.\n", parent, sampler);
+    TRACE("device %p, desc %p, parent %p, sampler %p.\n", device, desc, parent, sampler);
+
+    if (!device->adapter->gl_info.supported[ARB_SAMPLER_OBJECTS])
+        return WINED3DERR_INVALIDCALL;
+
+    if (desc->address_u < WINED3D_TADDRESS_WRAP || desc->address_u > WINED3D_TADDRESS_MIRROR_ONCE
+            || desc->address_v < WINED3D_TADDRESS_WRAP || desc->address_v > WINED3D_TADDRESS_MIRROR_ONCE
+            || desc->address_w < WINED3D_TADDRESS_WRAP || desc->address_w > WINED3D_TADDRESS_MIRROR_ONCE)
+        return WINED3DERR_INVALIDCALL;
+
+    if (desc->mag_filter < WINED3D_TEXF_POINT || desc->mag_filter > WINED3D_TEXF_LINEAR
+            || desc->min_filter < WINED3D_TEXF_POINT || desc->min_filter > WINED3D_TEXF_LINEAR
+            || desc->mip_filter > WINED3D_TEXF_LINEAR)
+        return WINED3DERR_INVALIDCALL;
 
     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    wined3d_sampler_init(object, parent);
+    wined3d_sampler_init(object, device, desc, parent);
 
     TRACE("Created sampler %p.\n", object);
     *sampler = object;
index 2bb945d..9c0732e 100644 (file)
@@ -101,8 +101,10 @@ static const char * const shader_opcode_names[] =
     /* WINED3DSIH_MOVA                  */ "mova",
     /* WINED3DSIH_MOVC                  */ "movc",
     /* WINED3DSIH_MUL                   */ "mul",
+    /* WINED3DSIH_NE                    */ "ne",
     /* WINED3DSIH_NOP                   */ "nop",
     /* WINED3DSIH_NRM                   */ "nrm",
+    /* WINED3DSIH_OR                    */ "or",
     /* WINED3DSIH_PHASE                 */ "phase",
     /* WINED3DSIH_POW                   */ "pow",
     /* WINED3DSIH_RCP                   */ "rcp",
@@ -143,6 +145,7 @@ static const char * const shader_opcode_names[] =
     /* WINED3DSIH_TEXREG2GB             */ "texreg2gb",
     /* WINED3DSIH_TEXREG2RGB            */ "texreg2rgb",
     /* WINED3DSIH_UDIV                  */ "udiv",
+    /* WINED3DSIH_UGE                   */ "uge",
     /* WINED3DSIH_USHR                  */ "ushr",
     /* WINED3DSIH_UTOF                  */ "utof",
     /* WINED3DSIH_XOR                   */ "xor",
@@ -363,6 +366,84 @@ static void shader_delete_constant_list(struct list *clist)
     list_init(clist);
 }
 
+static void shader_set_limits(struct wined3d_shader *shader)
+{
+    static const struct limits_entry
+    {
+        unsigned int min_version;
+        unsigned int max_version;
+        struct wined3d_shader_limits limits;
+    }
+    vs_limits[] =
+    {
+        /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */
+        {WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 1), { 0,  0, 256,  0, 12,  0}},
+        {WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 1), { 0, 16, 256, 16, 12,  0}},
+        /* DX10 cards on Windows advertise a D3D9 constant limit of 256
+         * even though they are capable of supporting much more (GL
+         * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
+         * wined3d-advertised maximum. Clamp the constant limit for <= 3.0
+         * shaders to 256. */
+        {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 0), { 4, 16, 256, 16, 12,  0}},
+        {WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(4, 0), {16,  0,   0,  0, 16,  0}},
+        {0}
+    },
+    gs_limits[] =
+    {
+        /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */
+        {WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(4, 0), {16,  0,   0,  0, 32, 16}},
+        {0}
+    },
+    ps_limits[] =
+    {
+        /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */
+        {WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 3), { 4,  0,   8,  0,  0,  0}},
+        {WINED3D_SHADER_VERSION(1, 4), WINED3D_SHADER_VERSION(1, 4), { 6,  0,   8,  0,  0,  0}},
+        {WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 0), {16,  0,  32,  0,  0,  0}},
+        {WINED3D_SHADER_VERSION(2, 1), WINED3D_SHADER_VERSION(2, 1), {16, 16,  32, 16,  0,  0}},
+        {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 0), {16, 16, 224, 16,  0, 12}},
+        {WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(4, 0), {16,  0,   0,  0,  0, 32}},
+        {0}
+    };
+    const struct limits_entry *limits_array;
+    DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
+            shader->reg_maps.shader_version.minor);
+    int i = 0;
+
+    switch (shader->reg_maps.shader_version.type)
+    {
+        default:
+            FIXME("Unexpected shader type %u found.\n", shader->reg_maps.shader_version.type);
+            /* Fall-through. */
+        case WINED3D_SHADER_TYPE_VERTEX:
+            limits_array = vs_limits;
+            break;
+        case WINED3D_SHADER_TYPE_GEOMETRY:
+            limits_array = gs_limits;
+            break;
+        case WINED3D_SHADER_TYPE_PIXEL:
+            limits_array = ps_limits;
+            break;
+    }
+
+    while (limits_array[i].min_version && limits_array[i].min_version <= shader_version)
+    {
+        if (shader_version <= limits_array[i].max_version)
+        {
+            shader->limits = &limits_array[i].limits;
+            break;
+        }
+        ++i;
+    }
+    if (!shader->limits)
+    {
+        FIXME("Unexpected shader version \"%u.%u\".\n",
+                shader->reg_maps.shader_version.major,
+                shader->reg_maps.shader_version.minor);
+        shader->limits = &limits_array[max(0, i - 1)].limits;
+    }
+}
+
 static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
 {
     DWORD idx, shift;
@@ -371,8 +452,8 @@ static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
     bitmap[idx] |= (1 << shift);
 }
 
-static void shader_record_register_usage(struct wined3d_shader *shader, struct wined3d_shader_reg_maps *reg_maps,
-        const struct wined3d_shader_register *reg, enum wined3d_shader_type shader_type)
+static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct wined3d_shader_reg_maps *reg_maps,
+        const struct wined3d_shader_register *reg, enum wined3d_shader_type shader_type, unsigned int constf_size)
 {
     switch (reg->type)
     {
@@ -436,16 +517,40 @@ static void shader_record_register_usage(struct wined3d_shader *shader, struct w
             }
             else
             {
-                set_bitmap_bit(reg_maps->constf, reg->idx[0].offset);
+                if (reg->idx[0].offset >= min(shader->limits->constant_float, constf_size))
+                {
+                    WARN("Shader using float constant %u which is not supported.\n", reg->idx[0].offset);
+                    return FALSE;
+                }
+                else
+                {
+                    set_bitmap_bit(reg_maps->constf, reg->idx[0].offset);
+                }
             }
             break;
 
         case WINED3DSPR_CONSTINT:
-            reg_maps->integer_constants |= (1 << reg->idx[0].offset);
+            if (reg->idx[0].offset >= shader->limits->constant_int)
+            {
+                WARN("Shader using integer constant %u which is not supported.\n", reg->idx[0].offset);
+                return FALSE;
+            }
+            else
+            {
+                reg_maps->integer_constants |= (1 << reg->idx[0].offset);
+            }
             break;
 
         case WINED3DSPR_CONSTBOOL:
-            reg_maps->boolean_constants |= (1 << reg->idx[0].offset);
+            if (reg->idx[0].offset >= shader->limits->constant_bool)
+            {
+                WARN("Shader using bool constant %u which is not supported.\n", reg->idx[0].offset);
+                return FALSE;
+            }
+            else
+            {
+                reg_maps->boolean_constants |= (1 << reg->idx[0].offset);
+            }
             break;
 
         case WINED3DSPR_COLOROUT:
@@ -457,6 +562,52 @@ static void shader_record_register_usage(struct wined3d_shader *shader, struct w
                     reg->type, reg->idx[0].offset, reg->idx[1].offset);
             break;
     }
+    return TRUE;
+}
+
+static void shader_record_sample(struct wined3d_shader_reg_maps *reg_maps,
+        unsigned int resource_idx, unsigned int sampler_idx, unsigned int bind_idx)
+{
+    struct wined3d_shader_sampler_map_entry *entries, *entry;
+    struct wined3d_shader_sampler_map *map;
+    unsigned int i;
+
+    map = &reg_maps->sampler_map;
+    entries = map->entries;
+    for (i = 0; i < map->count; ++i)
+    {
+        if (entries[i].resource_idx == resource_idx && entries[i].sampler_idx == sampler_idx)
+            return;
+    }
+
+    if (!map->size)
+    {
+        if (!(entries = HeapAlloc(GetProcessHeap(), 0, sizeof(*entries) * 4)))
+        {
+            ERR("Failed to allocate sampler map entries.\n");
+            return;
+        }
+        map->size = 4;
+        map->entries = entries;
+    }
+    else if (map->count == map->size)
+    {
+        size_t new_size = map->size * 2;
+
+        if (sizeof(*entries) * new_size <= sizeof(*entries) * map->size
+                || !(entries = HeapReAlloc(GetProcessHeap(), 0, entries, sizeof(*entries) * new_size)))
+        {
+            ERR("Failed to resize sampler map entries.\n");
+            return;
+        }
+        map->size = new_size;
+        map->entries = entries;
+    }
+
+    entry = &entries[map->count++];
+    entry->resource_idx = resource_idx;
+    entry->sampler_idx = sampler_idx;
+    entry->bind_idx = bind_idx;
 }
 
 static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, unsigned int param)
@@ -495,8 +646,10 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
     fe->shader_read_header(fe_data, &ptr, &shader_version);
     reg_maps->shader_version = shader_version;
 
+    shader_set_limits(shader);
+
     reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-            sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
+            sizeof(*reg_maps->constf) * ((min(shader->limits->constant_float, constf_size) + 31) / 32));
     if (!reg_maps->constf)
     {
         ERR("Failed to allocate constant map memory.\n");
@@ -521,26 +674,47 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         if (ins.handler_idx == WINED3DSIH_DCL)
         {
             struct wined3d_shader_semantic *semantic = &ins.declaration.semantic;
+            unsigned int reg_idx = semantic->reg.reg.idx[0].offset;
 
             switch (semantic->reg.reg.type)
             {
                 /* Mark input registers used. */
                 case WINED3DSPR_INPUT:
-                    reg_maps->input_registers |= 1 << semantic->reg.reg.idx[0].offset;
-                    shader_signature_from_semantic(&input_signature[semantic->reg.reg.idx[0].offset], semantic);
+                    if (reg_idx >= MAX_REG_INPUT)
+                    {
+                        ERR("Invalid input register index %u.\n", reg_idx);
+                        break;
+                    }
+                    if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL && shader_version.major == 3
+                            && semantic->usage == WINED3D_DECL_USAGE_POSITION && !semantic->usage_idx)
+                        return WINED3DERR_INVALIDCALL;
+                    reg_maps->input_registers |= 1 << reg_idx;
+                    shader_signature_from_semantic(&input_signature[reg_idx], semantic);
                     break;
 
                 /* Vertex shader: mark 3.0 output registers used, save token. */
                 case WINED3DSPR_OUTPUT:
-                    reg_maps->output_registers |= 1 << semantic->reg.reg.idx[0].offset;
-                    shader_signature_from_semantic(&output_signature[semantic->reg.reg.idx[0].offset], semantic);
+                    if (reg_idx >= MAX_REG_OUTPUT)
+                    {
+                        ERR("Invalid output register index %u.\n", reg_idx);
+                        break;
+                    }
+                    reg_maps->output_registers |= 1 << reg_idx;
+                    shader_signature_from_semantic(&output_signature[reg_idx], semantic);
                     if (semantic->usage == WINED3D_DECL_USAGE_FOG)
                         reg_maps->fog = 1;
                     break;
 
-                /* Save sampler usage token. */
                 case WINED3DSPR_SAMPLER:
-                    reg_maps->sampler_type[semantic->reg.reg.idx[0].offset] = semantic->sampler_type;
+                    shader_record_sample(reg_maps, reg_idx, reg_idx, reg_idx);
+                case WINED3DSPR_RESOURCE:
+                    if (reg_idx >= ARRAY_SIZE(reg_maps->resource_info))
+                    {
+                        ERR("Invalid resource index %u.\n", reg_idx);
+                        break;
+                    }
+                    reg_maps->resource_info[reg_idx].type = semantic->resource_type;
+                    reg_maps->resource_info[reg_idx].data_type = semantic->resource_data_type;
                     break;
 
                 default:
@@ -652,7 +826,9 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
              * they are initialized (required by spec). */
             for (i = 0; i < ins.dst_count; ++i)
             {
-                shader_record_register_usage(shader, reg_maps, &ins.dst[i].reg, shader_version.type);
+                if (!shader_record_register_usage(shader, reg_maps, &ins.dst[i].reg,
+                        shader_version.type, constf_size))
+                    return WINED3DERR_INVALIDCALL;
 
                 /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
                  * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
@@ -766,20 +942,21 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                             || ins.handler_idx == WINED3DSIH_TEXREG2GB
                             || ins.handler_idx == WINED3DSIH_TEXREG2RGB))
                 {
-                    /* Fake sampler usage, only set reserved bit and type. */
-                    DWORD sampler_code = ins.dst[i].reg.idx[0].offset;
+                    unsigned int reg_idx = ins.dst[i].reg.idx[0].offset;
 
-                    TRACE("Setting fake 2D sampler for 1.x pixelshader.\n");
-                    reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D;
+                    TRACE("Setting fake 2D resource for 1.x pixelshader.\n");
+                    reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
+                    reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_FLOAT;
+                    shader_record_sample(reg_maps, reg_idx, reg_idx, reg_idx);
 
                     /* texbem is only valid with < 1.4 pixel shaders */
                     if (ins.handler_idx == WINED3DSIH_TEXBEM
                             || ins.handler_idx == WINED3DSIH_TEXBEML)
                     {
-                        reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
+                        reg_maps->bumpmat |= 1 << reg_idx;
                         if (ins.handler_idx == WINED3DSIH_TEXBEML)
                         {
-                            reg_maps->luminanceparams |= 1 << ins.dst[i].reg.idx[0].offset;
+                            reg_maps->luminanceparams |= 1 << reg_idx;
                         }
                     }
                 }
@@ -807,21 +984,36 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             }
             else if (ins.handler_idx == WINED3DSIH_ENDLOOP
                     || ins.handler_idx == WINED3DSIH_ENDREP)
+            {
                 --cur_loop_depth;
+            }
+            else if (ins.handler_idx == WINED3DSIH_SAMPLE
+                    || ins.handler_idx == WINED3DSIH_SAMPLE_GRAD
+                    || ins.handler_idx == WINED3DSIH_SAMPLE_LOD)
+            {
+                shader_record_sample(reg_maps, ins.src[1].reg.idx[0].offset,
+                        ins.src[2].reg.idx[0].offset, reg_maps->sampler_map.count);
+            }
 
             if (ins.predicate)
-                shader_record_register_usage(shader, reg_maps, &ins.predicate->reg, shader_version.type);
+                if (!shader_record_register_usage(shader, reg_maps, &ins.predicate->reg,
+                        shader_version.type, constf_size))
+                    return WINED3DERR_INVALIDCALL;
 
             for (i = 0; i < ins.src_count; ++i)
             {
                 unsigned int count = get_instr_extra_regcount(ins.handler_idx, i);
                 struct wined3d_shader_register reg = ins.src[i].reg;
 
-                shader_record_register_usage(shader, reg_maps, &ins.src[i].reg, shader_version.type);
+                if (!shader_record_register_usage(shader, reg_maps, &ins.src[i].reg,
+                        shader_version.type, constf_size))
+                    return WINED3DERR_INVALIDCALL;
                 while (count)
                 {
                     ++reg.idx[0].offset;
-                    shader_record_register_usage(shader, reg_maps, &reg, shader_version.type);
+                    if (!shader_record_register_usage(shader, reg_maps, &reg,
+                            shader_version.type, constf_size))
+                        return WINED3DERR_INVALIDCALL;
                     --count;
                 }
 
@@ -865,12 +1057,95 @@ static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semanti
 
     if (semantic->reg.reg.type == WINED3DSPR_SAMPLER)
     {
-        switch (semantic->sampler_type)
+        switch (semantic->resource_type)
         {
-            case WINED3DSTT_2D: TRACE("_2d"); break;
-            case WINED3DSTT_CUBE: TRACE("_cube"); break;
-            case WINED3DSTT_VOLUME: TRACE("_volume"); break;
-            default: TRACE("_unknown_ttype(0x%08x)", semantic->sampler_type);
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
+                TRACE("_2d");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
+                TRACE("_volume");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+                TRACE("_cube");
+                break;
+
+            default:
+                TRACE("_unknown_ttype(0x%08x)", semantic->resource_type);
+                break;
+        }
+    }
+    else if (semantic->reg.reg.type == WINED3DSPR_RESOURCE)
+    {
+        TRACE("_resource_");
+        switch (semantic->resource_type)
+        {
+            case WINED3D_SHADER_RESOURCE_BUFFER:
+                TRACE("buffer");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
+                TRACE("texture1d");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
+                TRACE("texture2d");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DMS:
+                TRACE("texture2dms");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
+                TRACE("texture3d");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+                TRACE("texturecube");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY:
+                TRACE("texture1darray");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
+                TRACE("texture2darray");
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY:
+                TRACE("texture2dmsarray");
+                break;
+
+            default:
+                TRACE("unknown");
+                break;
+        }
+        switch (semantic->resource_data_type)
+        {
+            case WINED3D_DATA_FLOAT:
+                TRACE(" (float)");
+                break;
+
+            case WINED3D_DATA_INT:
+                TRACE(" (int)");
+                break;
+
+            case WINED3D_DATA_UINT:
+                TRACE(" (uint)");
+                break;
+
+            case WINED3D_DATA_UNORM:
+                TRACE(" (unorm)");
+                break;
+
+            case WINED3D_DATA_SNORM:
+                TRACE(" (snorm)");
+                break;
+
+            default:
+                TRACE(" (unknown)");
+                break;
         }
     }
     else
@@ -1483,6 +1758,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
 
 static void shader_cleanup(struct wined3d_shader *shader)
 {
+    HeapFree(GetProcessHeap(), 0, shader->signature_strings);
     shader->device->shader_backend->shader_destroy(shader);
     HeapFree(GetProcessHeap(), 0, shader->reg_maps.constf);
     HeapFree(GetProcessHeap(), 0, shader->function);
@@ -1783,11 +2059,11 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh
 
     TRACE("shader %p, start_idx %u, src_data %p, count %u.\n", shader, start_idx, src_data, count);
 
-    if (end_idx > shader->limits.constant_float)
+    if (end_idx > shader->limits->constant_float)
     {
         WARN("end_idx %u > float constants limit %u.\n",
-                end_idx, shader->limits.constant_float);
-        end_idx = shader->limits.constant_float;
+                end_idx, shader->limits->constant_float);
+        end_idx = shader->limits->constant_float;
     }
 
     for (i = start_idx; i < end_idx; ++i)
@@ -1856,75 +2132,8 @@ BOOL vshader_get_input(const struct wined3d_shader *shader,
     return FALSE;
 }
 
-static void vertexshader_set_limits(struct wined3d_shader *shader)
-{
-    DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
-            shader->reg_maps.shader_version.minor);
-    struct wined3d_device *device = shader->device;
-    const DWORD vs_uniform_count = device->adapter->d3d_info.limits.vs_uniform_count;
-
-    shader->limits.packed_input = 0;
-
-    switch (shader_version)
-    {
-        case WINED3D_SHADER_VERSION(1, 0):
-        case WINED3D_SHADER_VERSION(1, 1):
-            shader->limits.constant_bool = 0;
-            shader->limits.constant_int = 0;
-            shader->limits.packed_output = 12;
-            shader->limits.sampler = 0;
-            /* TODO: vs_1_1 has a minimum of 96 constants. What happens when
-             * a vs_1_1 shader is used on a vs_3_0 capable card that has 256
-             * constants? */
-            shader->limits.constant_float = min(256, vs_uniform_count);
-            break;
-
-        case WINED3D_SHADER_VERSION(2, 0):
-        case WINED3D_SHADER_VERSION(2, 1):
-            shader->limits.constant_bool = 16;
-            shader->limits.constant_int = 16;
-            shader->limits.packed_output = 12;
-            shader->limits.sampler = 0;
-            shader->limits.constant_float = min(256, vs_uniform_count);
-            break;
-
-        case WINED3D_SHADER_VERSION(3, 0):
-            shader->limits.constant_bool = 16;
-            shader->limits.constant_int = 16;
-            shader->limits.packed_output = 12;
-            shader->limits.sampler = 4;
-            /* DX10 cards on Windows advertise a d3d9 constant limit of 256
-             * even though they are capable of supporting much more (GL
-             * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
-             * wined3d-advertised maximum. Clamp the constant limit for <= 3.0
-             * shaders to 256. */
-            shader->limits.constant_float = min(256, vs_uniform_count);
-            break;
-
-        case WINED3D_SHADER_VERSION(4, 0):
-            shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
-            shader->limits.constant_int = 0;
-            shader->limits.constant_float = 0;
-            shader->limits.constant_bool = 0;
-            shader->limits.packed_output = 16;
-            shader->limits.packed_input = 0;
-            break;
-
-        default:
-            shader->limits.constant_bool = 16;
-            shader->limits.constant_int = 16;
-            shader->limits.packed_output = 12;
-            shader->limits.sampler = 0;
-            shader->limits.constant_float = min(256, vs_uniform_count);
-            FIXME("Unrecognized vertex shader version \"%u.%u\".\n",
-                    shader->reg_maps.shader_version.major,
-                    shader->reg_maps.shader_version.minor);
-    }
-}
-
 static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
-        const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
-        void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
+        const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
 {
     struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
     unsigned int i;
@@ -1932,12 +2141,12 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
     WORD map;
     const DWORD vs_uniform_count = device->adapter->d3d_info.limits.vs_uniform_count;
 
-    if (!byte_code) return WINED3DERR_INVALIDCALL;
+    if (!desc->byte_code)
+        return WINED3DERR_INVALIDCALL;
 
     shader_init(shader, device, parent, parent_ops);
-    hr = shader_set_function(shader, byte_code, output_signature, vs_uniform_count,
-            WINED3D_SHADER_TYPE_VERTEX, max_version);
-    if (FAILED(hr))
+    if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
+            vs_uniform_count, WINED3D_SHADER_TYPE_VERTEX, desc->max_version)))
     {
         WARN("Failed to set function, hr %#x.\n", hr);
         shader_cleanup(shader);
@@ -1955,66 +2164,66 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
         shader->u.vs.attributes[i].usage_idx = shader->input_signature[i].semantic_idx;
     }
 
-    if (output_signature)
+    if (desc->output_signature)
     {
-        for (i = 0; i < output_signature->element_count; ++i)
+        struct wined3d_shader_signature_element *e;
+        SIZE_T total, len;
+        char *ptr;
+
+        total = 0;
+        for (i = 0; i < desc->output_signature->element_count; ++i)
+        {
+            e = &desc->output_signature->elements[i];
+            len = strlen(e->semantic_name);
+            if (len >= ~(SIZE_T)0 - total)
+            {
+                shader_cleanup(shader);
+                return E_OUTOFMEMORY;
+            }
+
+            total += len + 1;
+        }
+
+        if (!(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total)))
         {
-            struct wined3d_shader_signature_element *e = &output_signature->elements[i];
+            shader_cleanup(shader);
+            return E_OUTOFMEMORY;
+        }
+        ptr = shader->signature_strings;
+
+        for (i = 0; i < desc->output_signature->element_count; ++i)
+        {
+            e = &desc->output_signature->elements[i];
             reg_maps->output_registers |= 1 << e->register_idx;
             shader->output_signature[e->register_idx] = *e;
+
+            len = strlen(e->semantic_name);
+            memcpy(ptr, e->semantic_name, len + 1);
+            shader->output_signature[e->register_idx].semantic_name = ptr;
+            ptr += len + 1;
         }
     }
 
-    vertexshader_set_limits(shader);
-
     shader->load_local_constsF = (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) ||
             shader->lconst_inf_or_nan;
 
     return WINED3D_OK;
 }
 
-static void geometryshader_set_limits(struct wined3d_shader *shader)
-{
-    DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
-            shader->reg_maps.shader_version.minor);
-
-    switch (shader_version)
-    {
-        case WINED3D_SHADER_VERSION(4, 0):
-            shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
-            shader->limits.constant_int = 0;
-            shader->limits.constant_float = 0;
-            shader->limits.constant_bool = 0;
-            shader->limits.packed_output = 32;
-            shader->limits.packed_input = 16;
-            break;
-
-        default:
-            memset(&shader->limits, 0, sizeof(shader->limits));
-            FIXME("Unhandled geometry shader version \"%u.%u\".\n",
-                    shader->reg_maps.shader_version.major,
-                    shader->reg_maps.shader_version.minor);
-    }
-}
-
 static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
-        const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
-        void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
+        const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
 {
     HRESULT hr;
 
     shader_init(shader, device, parent, parent_ops);
-    hr = shader_set_function(shader, byte_code, output_signature, 0,
-            WINED3D_SHADER_TYPE_GEOMETRY, max_version);
-    if (FAILED(hr))
+    if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
+            0, WINED3D_SHADER_TYPE_GEOMETRY, desc->max_version)))
     {
         WARN("Failed to set function, hr %#x.\n", hr);
         shader_cleanup(shader);
         return hr;
     }
 
-    geometryshader_set_limits(shader);
-
     shader->load_local_constsF = shader->lconst_inf_or_nan;
 
     return WINED3D_OK;
@@ -2044,7 +2253,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
     if (shader->reg_maps.shader_version.major == 1
             && shader->reg_maps.shader_version.minor <= 3)
     {
-        for (i = 0; i < shader->limits.sampler; ++i)
+        for (i = 0; i < shader->limits->sampler; ++i)
         {
             DWORD flags = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
 
@@ -2054,10 +2263,10 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
 
                 if (!state->shader[WINED3D_SHADER_TYPE_VERTEX])
                 {
+                    enum wined3d_shader_resource_type resource_type = shader->reg_maps.resource_info[i].type;
                     unsigned int j;
                     unsigned int index = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
                     DWORD max_valid = WINED3D_TTFF_COUNT4;
-                    enum wined3d_sampler_texture_type sampler_type = shader->reg_maps.sampler_type[i];
 
                     for (j = 0; j < state->vertex_declaration->element_count; ++j)
                     {
@@ -2077,15 +2286,17 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
                                 tex_transform, max_valid);
                         tex_transform = max_valid;
                     }
-                    if ((sampler_type == WINED3DSTT_1D && tex_transform > WINED3D_TTFF_COUNT1)
-                            || (sampler_type == WINED3DSTT_2D && tex_transform > WINED3D_TTFF_COUNT2)
-                            || (sampler_type == WINED3DSTT_VOLUME && tex_transform > WINED3D_TTFF_COUNT3))
+                    if ((resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_1D && tex_transform > WINED3D_TTFF_COUNT1)
+                            || (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2D
+                            && tex_transform > WINED3D_TTFF_COUNT2)
+                            || (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_3D
+                            && tex_transform > WINED3D_TTFF_COUNT3))
                         tex_transform |= WINED3D_PSARGS_PROJECTED;
                     else
                     {
                         WARN("Application requested projected texture with unsuitable texture coordinates.\n");
                         WARN("(texture unit %u, transform flags %#x, sampler type %u).\n",
-                                i, tex_transform, sampler_type);
+                                i, tex_transform, resource_type);
                     }
                 }
                 else
@@ -2098,11 +2309,11 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
     if (shader->reg_maps.shader_version.major == 1
             && shader->reg_maps.shader_version.minor <= 4)
     {
-        for (i = 0; i < shader->limits.sampler; ++i)
+        for (i = 0; i < shader->limits->sampler; ++i)
         {
             const struct wined3d_texture *texture = state->textures[i];
 
-            if (!shader->reg_maps.sampler_type[i])
+            if (!shader->reg_maps.resource_info[i].type)
                 continue;
 
             /* Treat unbound textures as 2D. The dummy texture will provide
@@ -2131,7 +2342,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
 
     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
     {
-        if (!shader->reg_maps.sampler_type[i])
+        if (!shader->reg_maps.resource_info[i].type)
             continue;
 
         texture = state->textures[i];
@@ -2194,102 +2405,26 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
     }
 }
 
-static void pixelshader_set_limits(struct wined3d_shader *shader)
-{
-    DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
-            shader->reg_maps.shader_version.minor);
-
-    shader->limits.packed_output = 0;
-
-    switch (shader_version)
-    {
-        case WINED3D_SHADER_VERSION(1, 0):
-        case WINED3D_SHADER_VERSION(1, 1):
-        case WINED3D_SHADER_VERSION(1, 2):
-        case WINED3D_SHADER_VERSION(1, 3):
-            shader->limits.constant_float = 8;
-            shader->limits.constant_int = 0;
-            shader->limits.constant_bool = 0;
-            shader->limits.sampler = 4;
-            shader->limits.packed_input = 0;
-            break;
-
-        case WINED3D_SHADER_VERSION(1, 4):
-            shader->limits.constant_float = 8;
-            shader->limits.constant_int = 0;
-            shader->limits.constant_bool = 0;
-            shader->limits.sampler = 6;
-            shader->limits.packed_input = 0;
-            break;
-
-        /* FIXME: Temporaries must match D3DPSHADERCAPS2_0.NumTemps. */
-        case WINED3D_SHADER_VERSION(2, 0):
-            shader->limits.constant_float = 32;
-            shader->limits.constant_int = 16;
-            shader->limits.constant_bool = 16;
-            shader->limits.sampler = 16;
-            shader->limits.packed_input = 0;
-            break;
-
-        case WINED3D_SHADER_VERSION(2, 1):
-            shader->limits.constant_float = 32;
-            shader->limits.constant_int = 16;
-            shader->limits.constant_bool = 16;
-            shader->limits.sampler = 16;
-            shader->limits.packed_input = 0;
-            break;
-
-        case WINED3D_SHADER_VERSION(3, 0):
-            shader->limits.constant_float = 224;
-            shader->limits.constant_int = 16;
-            shader->limits.constant_bool = 16;
-            shader->limits.sampler = 16;
-            shader->limits.packed_input = 12;
-            break;
-
-        case WINED3D_SHADER_VERSION(4, 0):
-            shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
-            shader->limits.constant_int = 0;
-            shader->limits.constant_float = 0;
-            shader->limits.constant_bool = 0;
-            shader->limits.packed_input = 32;
-            break;
-
-        default:
-            shader->limits.constant_float = 32;
-            shader->limits.constant_int = 16;
-            shader->limits.constant_bool = 16;
-            shader->limits.sampler = 16;
-            shader->limits.packed_input = 0;
-            FIXME("Unrecognized pixel shader version %u.%u\n",
-                    shader->reg_maps.shader_version.major,
-                    shader->reg_maps.shader_version.minor);
-    }
-}
-
 static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
-        const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
-        void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
+        const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
 {
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     unsigned int i, highest_reg_used = 0, num_regs_used = 0;
     HRESULT hr;
     const DWORD ps_uniform_count = device->adapter->d3d_info.limits.ps_uniform_count;
 
-    if (!byte_code) return WINED3DERR_INVALIDCALL;
+    if (!desc->byte_code)
+        return WINED3DERR_INVALIDCALL;
 
     shader_init(shader, device, parent, parent_ops);
-    hr = shader_set_function(shader, byte_code, output_signature, ps_uniform_count,
-            WINED3D_SHADER_TYPE_PIXEL, max_version);
-    if (FAILED(hr))
+    if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
+            ps_uniform_count, WINED3D_SHADER_TYPE_PIXEL, desc->max_version)))
     {
         WARN("Failed to set function, hr %#x.\n", hr);
         shader_cleanup(shader);
         return hr;
     }
 
-    pixelshader_set_limits(shader);
-
     for (i = 0; i < MAX_REG_INPUT; ++i)
     {
         if (shader->u.ps.input_reg_used[i])
@@ -2332,55 +2467,97 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de
 
     shader->load_local_constsF = shader->lconst_inf_or_nan;
 
+    if (desc->input_signature)
+    {
+        struct wined3d_shader_signature_element *e;
+        SIZE_T total, len;
+        char *ptr;
+
+        total = 0;
+        for (i = 0; i < desc->input_signature->element_count; ++i)
+        {
+            e = &desc->input_signature->elements[i];
+            len = strlen(e->semantic_name);
+            if (len >= ~(SIZE_T)0 - total)
+            {
+                shader_cleanup(shader);
+                return E_OUTOFMEMORY;
+            }
+
+            total += len + 1;
+        }
+
+        if (!(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total)))
+        {
+            shader_cleanup(shader);
+            return E_OUTOFMEMORY;
+        }
+        ptr = shader->signature_strings;
+
+        for (i = 0; i < desc->input_signature->element_count; ++i)
+        {
+            e = &desc->input_signature->elements[i];
+            shader->reg_maps.input_registers |= 1 << e->register_idx;
+            shader->input_signature[e->register_idx] = *e;
+
+            len = strlen(e->semantic_name);
+            memcpy(ptr, e->semantic_name, len + 1);
+            shader->input_signature[e->register_idx].semantic_name = ptr;
+            ptr += len + 1;
+
+            if (!strcmp(e->semantic_name, "SV_POSITION"))
+                shader->reg_maps.vpos = 1;
+        }
+    }
+
     return WINED3D_OK;
 }
 
-void pixelshader_update_samplers(struct wined3d_shader *shader, WORD tex_types)
+void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types)
 {
     struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
-    enum wined3d_sampler_texture_type *sampler_type = reg_maps->sampler_type;
+    struct wined3d_shader_resource_info *resource_info = reg_maps->resource_info;
     unsigned int i;
 
     if (reg_maps->shader_version.major != 1) return;
 
-    for (i = 0; i < shader->limits.sampler; ++i)
+    for (i = 0; i < shader->limits->sampler; ++i)
     {
         /* We don't sample from this sampler. */
-        if (!sampler_type[i]) continue;
+        if (!resource_info[i].type)
+            continue;
 
         switch ((tex_types >> i * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK)
         {
             case WINED3D_SHADER_TEX_2D:
-                sampler_type[i] = WINED3DSTT_2D;
+                resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
                 break;
 
             case WINED3D_SHADER_TEX_3D:
-                sampler_type[i] = WINED3DSTT_VOLUME;
+                resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_3D;
                 break;
 
             case WINED3D_SHADER_TEX_CUBE:
-                sampler_type[i] = WINED3DSTT_CUBE;
+                resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_CUBE;
                 break;
         }
     }
 }
 
-HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const DWORD *byte_code,
-        const struct wined3d_shader_signature *output_signature, void *parent,
-        const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
+HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
+        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader)
 {
     struct wined3d_shader *object;
     HRESULT hr;
 
-    TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
-            device, byte_code, output_signature, parent, parent_ops, shader);
+    TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
+            device, desc, parent, parent_ops, shader);
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
         return E_OUTOFMEMORY;
 
-    hr = geometryshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
-    if (FAILED(hr))
+    if (FAILED(hr = geometryshader_init(object, device, desc, parent, parent_ops)))
     {
         WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
@@ -2393,22 +2570,20 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const DWOR
     return WINED3D_OK;
 }
 
-HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const DWORD *byte_code,
-        const struct wined3d_shader_signature *output_signature, void *parent,
-        const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
+HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
+        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader)
 {
     struct wined3d_shader *object;
     HRESULT hr;
 
-    TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
-            device, byte_code, output_signature, parent, parent_ops, shader);
+    TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
+            device, desc, parent, parent_ops, shader);
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
         return E_OUTOFMEMORY;
 
-    hr = pixelshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
-    if (FAILED(hr))
+    if (FAILED(hr = pixelshader_init(object, device, desc, parent, parent_ops)))
     {
         WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
@@ -2421,22 +2596,20 @@ HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const DWOR
     return WINED3D_OK;
 }
 
-HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const DWORD *byte_code,
-        const struct wined3d_shader_signature *output_signature, void *parent,
-        const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
+HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
+        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader)
 {
     struct wined3d_shader *object;
     HRESULT hr;
 
-    TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
-            device, byte_code, output_signature, parent, parent_ops, shader);
+    TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
+            device, desc, parent, parent_ops, shader);
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
         return E_OUTOFMEMORY;
 
-    hr = vertexshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
-    if (FAILED(hr))
+    if (FAILED(hr = vertexshader_init(object, device, desc, parent, parent_ops)))
     {
         WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
index da6641d..f5f0b66 100644 (file)
@@ -33,8 +33,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 #define WINED3DSP_DCL_USAGEINDEX_MASK           (0xf << WINED3DSP_DCL_USAGEINDEX_SHIFT)
 
 /* DCL sampler type */
-#define WINED3DSP_TEXTURETYPE_SHIFT             27
-#define WINED3DSP_TEXTURETYPE_MASK              (0xf << WINED3DSP_TEXTURETYPE_SHIFT)
+#define WINED3D_SM1_RESOURCE_TYPE_SHIFT         27
+#define WINED3D_SM1_RESOURCE_TYPE_MASK          (0xf << WINED3D_SM1_RESOURCE_TYPE_SHIFT)
 
 /* Opcode-related masks */
 #define WINED3DSI_OPCODE_MASK                   0x0000ffff
@@ -96,6 +96,15 @@ enum WINED3DSHADER_ADDRESSMODE_TYPE
     WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
 };
 
+enum wined3d_sm1_resource_type
+{
+    WINED3D_SM1_RESOURCE_UNKNOWN        = 0x0,
+    WINED3D_SM1_RESOURCE_TEXTURE_1D     = 0x1,
+    WINED3D_SM1_RESOURCE_TEXTURE_2D     = 0x2,
+    WINED3D_SM1_RESOURCE_TEXTURE_CUBE   = 0x3,
+    WINED3D_SM1_RESOURCE_TEXTURE_3D     = 0x4,
+};
+
 enum wined3d_sm1_opcode
 {
     WINED3D_SM1_OP_NOP          = 0x00,
@@ -374,6 +383,15 @@ static const struct wined3d_sm1_opcode_info ps_opcode_table[] =
     {0,                       0, 0, WINED3DSIH_TABLE_SIZE,   0,                           0                          },
 };
 
+static const enum wined3d_shader_resource_type resource_type_table[] =
+{
+    /* WINED3D_SM1_RESOURCE_UNKNOWN */      WINED3D_SHADER_RESOURCE_NONE,
+    /* WINED3D_SM1_RESOURCE_TEXTURE_1D */   WINED3D_SHADER_RESOURCE_TEXTURE_1D,
+    /* WINED3D_SM1_RESOURCE_TEXTURE_2D */   WINED3D_SHADER_RESOURCE_TEXTURE_2D,
+    /* WINED3D_SM1_RESOURCE_TEXTURE_CUBE */ WINED3D_SHADER_RESOURCE_TEXTURE_CUBE,
+    /* WINED3D_SM1_RESOURCE_TEXTURE_3D */   WINED3D_SHADER_RESOURCE_TEXTURE_3D,
+};
+
 /* Read a parameter opcode from the input stream,
  * and possibly a relative addressing token.
  * Return the number of tokens read */
@@ -609,12 +627,23 @@ static void shader_sm1_read_dst_param(struct wined3d_sm1_data *priv, const DWORD
 
 static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
 {
+    enum wined3d_sm1_resource_type resource_type;
     DWORD usage_token = *(*ptr)++;
     DWORD dst_token = *(*ptr)++;
 
     semantic->usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
     semantic->usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-    semantic->sampler_type = (usage_token & WINED3DSP_TEXTURETYPE_MASK) >> WINED3DSP_TEXTURETYPE_SHIFT;
+    resource_type = (usage_token & WINED3D_SM1_RESOURCE_TYPE_MASK) >> WINED3D_SM1_RESOURCE_TYPE_SHIFT;
+    if (resource_type >= ARRAY_SIZE(resource_type_table))
+    {
+        FIXME("Unhandled resource type %#x.\n", resource_type);
+        semantic->resource_type = WINED3D_SHADER_RESOURCE_NONE;
+    }
+    else
+    {
+        semantic->resource_type = resource_type_table[resource_type];
+    }
+    semantic->resource_data_type = WINED3D_DATA_FLOAT;
     shader_parse_dst_param(dst_token, NULL, &semantic->reg);
 }
 
index 7a25e02..4881cfa 100644 (file)
@@ -26,6 +26,9 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode);
 #define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT    24
 #define WINED3D_SM4_INSTRUCTION_LENGTH_MASK     (0x1f << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
 
+#define WINED3D_SM4_RESOURCE_TYPE_SHIFT         11
+#define WINED3D_SM4_RESOURCE_TYPE_MASK          (0xf << WINED3D_SM4_RESOURCE_TYPE_SHIFT)
+
 #define WINED3D_SM4_PRIMITIVE_TYPE_SHIFT        11
 #define WINED3D_SM4_PRIMITIVE_TYPE_MASK         (0x7 << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT)
 
@@ -105,6 +108,8 @@ enum wined3d_sm4_opcode
     WINED3D_SM4_OP_MOV                  = 0x36,
     WINED3D_SM4_OP_MOVC                 = 0x37,
     WINED3D_SM4_OP_MUL                  = 0x38,
+    WINED3D_SM4_OP_NE                   = 0x39,
+    WINED3D_SM4_OP_OR                   = 0x3c,
     WINED3D_SM4_OP_RET                  = 0x3e,
     WINED3D_SM4_OP_ROUND_NI             = 0x41,
     WINED3D_SM4_OP_RSQ                  = 0x44,
@@ -114,9 +119,11 @@ enum wined3d_sm4_opcode
     WINED3D_SM4_OP_SQRT                 = 0x4b,
     WINED3D_SM4_OP_SINCOS               = 0x4d,
     WINED3D_SM4_OP_UDIV                 = 0x4e,
+    WINED3D_SM4_OP_UGE                  = 0x50,
     WINED3D_SM4_OP_USHR                 = 0x55,
     WINED3D_SM4_OP_UTOF                 = 0x56,
     WINED3D_SM4_OP_XOR                  = 0x57,
+    WINED3D_SM4_OP_DCL_RESOURCE         = 0x58,
     WINED3D_SM4_OP_DCL_CONSTANT_BUFFER  = 0x59,
     WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY  = 0x5c,
     WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE  = 0x5d,
@@ -130,6 +137,7 @@ enum wined3d_sm4_register_type
     WINED3D_SM4_RT_OUTPUT       = 0x2,
     WINED3D_SM4_RT_IMMCONST     = 0x4,
     WINED3D_SM4_RT_SAMPLER      = 0x6,
+    WINED3D_SM4_RT_RESOURCE     = 0x7,
     WINED3D_SM4_RT_CONSTBUFFER  = 0x8,
     WINED3D_SM4_RT_PRIMID       = 0xb,
     WINED3D_SM4_RT_NULL         = 0xd,
@@ -163,6 +171,28 @@ enum wined3d_sm4_immconst_type
     WINED3D_SM4_IMMCONST_VEC4   = 0x2,
 };
 
+enum wined3d_sm4_resource_type
+{
+    WINED3D_SM4_RESOURCE_BUFFER             = 0x1,
+    WINED3D_SM4_RESOURCE_TEXTURE_1D         = 0x2,
+    WINED3D_SM4_RESOURCE_TEXTURE_2D         = 0x3,
+    WINED3D_SM4_RESOURCE_TEXTURE_2DMS       = 0x4,
+    WINED3D_SM4_RESOURCE_TEXTURE_3D         = 0x5,
+    WINED3D_SM4_RESOURCE_TEXTURE_CUBE       = 0x6,
+    WINED3D_SM4_RESOURCE_TEXTURE_1DARRAY    = 0x7,
+    WINED3D_SM4_RESOURCE_TEXTURE_2DARRAY    = 0x8,
+    WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY  = 0x9,
+};
+
+enum wined3d_sm4_data_type
+{
+    WINED3D_SM4_DATA_UNORM  = 0x1,
+    WINED3D_SM4_DATA_SNORM  = 0x2,
+    WINED3D_SM4_DATA_INT    = 0x3,
+    WINED3D_SM4_DATA_UINT   = 0x4,
+    WINED3D_SM4_DATA_FLOAT  = 0x5,
+};
+
 struct wined3d_shader_src_param_entry
 {
     struct list entry;
@@ -173,7 +203,12 @@ struct wined3d_sm4_data
 {
     struct wined3d_shader_version shader_version;
     const DWORD *end;
-    const struct wined3d_shader_signature *output_signature;
+
+    struct
+    {
+        enum wined3d_shader_register_type register_type;
+        UINT register_idx;
+    } output_map[MAX_REG_OUTPUT];
 
     struct wined3d_shader_src_param src_param[5];
     struct wined3d_shader_dst_param dst_param[2];
@@ -242,6 +277,8 @@ static const struct wined3d_sm4_opcode_info opcode_table[] =
     {WINED3D_SM4_OP_MOV,                    WINED3DSIH_MOV,                 "F",    "F"},
     {WINED3D_SM4_OP_MOVC,                   WINED3DSIH_MOVC,                "F",    "UFF"},
     {WINED3D_SM4_OP_MUL,                    WINED3DSIH_MUL,                 "F",    "FF"},
+    {WINED3D_SM4_OP_NE,                     WINED3DSIH_NE,                  "U",    "FF"},
+    {WINED3D_SM4_OP_OR,                     WINED3DSIH_OR,                  "U",    "UU"},
     {WINED3D_SM4_OP_RET,                    WINED3DSIH_RET,                 "",     ""},
     {WINED3D_SM4_OP_ROUND_NI,               WINED3DSIH_ROUND_NI,            "F",    "F"},
     {WINED3D_SM4_OP_RSQ,                    WINED3DSIH_RSQ,                 "F",    "F"},
@@ -251,9 +288,11 @@ static const struct wined3d_sm4_opcode_info opcode_table[] =
     {WINED3D_SM4_OP_SQRT,                   WINED3DSIH_SQRT,                "F",    "F"},
     {WINED3D_SM4_OP_SINCOS,                 WINED3DSIH_SINCOS,              "FF",   "F"},
     {WINED3D_SM4_OP_UDIV,                   WINED3DSIH_UDIV,                "UU",   "UU"},
+    {WINED3D_SM4_OP_UGE,                    WINED3DSIH_UGE,                 "U",    "UU"},
     {WINED3D_SM4_OP_USHR,                   WINED3DSIH_USHR,                "U",    "UU"},
     {WINED3D_SM4_OP_UTOF,                   WINED3DSIH_UTOF,                "F",    "U"},
     {WINED3D_SM4_OP_XOR,                    WINED3DSIH_XOR,                 "U",    "UU"},
+    {WINED3D_SM4_OP_DCL_RESOURCE,           WINED3DSIH_DCL,                 "R",    ""},
     {WINED3D_SM4_OP_DCL_CONSTANT_BUFFER,    WINED3DSIH_DCL_CONSTANT_BUFFER, "",     ""},
     {WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY,    WINED3DSIH_DCL_OUTPUT_TOPOLOGY, "",     ""},
     {WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE,    WINED3DSIH_DCL_INPUT_PRIMITIVE, "",     ""},
@@ -313,6 +352,30 @@ static const struct sysval_map sysval_map[] =
     {WINED3D_SV_TARGET7,    WINED3DSPR_COLOROUT,    7},
 };
 
+static const enum wined3d_shader_resource_type resource_type_table[] =
+{
+    /* 0 */                                         WINED3D_SHADER_RESOURCE_NONE,
+    /* WINED3D_SM4_RESOURCE_BUFFER */               WINED3D_SHADER_RESOURCE_BUFFER,
+    /* WINED3D_SM4_RESOURCE_TEXTURE_1D */           WINED3D_SHADER_RESOURCE_TEXTURE_1D,
+    /* WINED3D_SM4_RESOURCE_TEXTURE_2D */           WINED3D_SHADER_RESOURCE_TEXTURE_2D,
+    /* WINED3D_SM4_RESOURCE_TEXTURE_2DMS */         WINED3D_SHADER_RESOURCE_TEXTURE_2DMS,
+    /* WINED3D_SM4_RESOURCE_TEXTURE_3D */           WINED3D_SHADER_RESOURCE_TEXTURE_3D,
+    /* WINED3D_SM4_RESOURCE_TEXTURE_CUBE */         WINED3D_SHADER_RESOURCE_TEXTURE_CUBE,
+    /* WINED3D_SM4_RESOURCE_TEXTURE_1DARRAY */      WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY,
+    /* WINED3D_SM4_RESOURCE_TEXTURE_2DARRAY */      WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY,
+    /* WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY */    WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY,
+};
+
+static const enum wined3d_data_type data_type_table[] =
+{
+    /* 0 */                         WINED3D_DATA_FLOAT,
+    /* WINED3D_SM4_DATA_UNORM */    WINED3D_DATA_UNORM,
+    /* WINED3D_SM4_DATA_SNORM */    WINED3D_DATA_SNORM,
+    /* WINED3D_SM4_DATA_INT */      WINED3D_DATA_INT,
+    /* WINED3D_SM4_DATA_UINT */     WINED3D_DATA_UINT,
+    /* WINED3D_SM4_DATA_FLOAT */    WINED3D_DATA_FLOAT,
+};
+
 static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
         enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param);
 
@@ -328,20 +391,6 @@ static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_op
     return NULL;
 }
 
-static void map_sysval(enum wined3d_sysval_semantic sysval, struct wined3d_shader_register *reg)
-{
-    unsigned int i;
-
-    for (i = 0; i < sizeof(sysval_map) / sizeof(*sysval_map); ++i)
-    {
-        if (sysval == sysval_map[i].sysval)
-        {
-            reg->type = sysval_map[i].register_type;
-            reg->idx[0].offset = sysval_map[i].register_idx;
-        }
-    }
-}
-
 static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_shader_register *reg)
 {
     switch (priv->shader_version.type)
@@ -349,23 +398,16 @@ static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_sha
         case WINED3D_SHADER_TYPE_PIXEL:
             if (reg->type == WINED3DSPR_OUTPUT)
             {
-                unsigned int i;
-                const struct wined3d_shader_signature *s = priv->output_signature;
+                unsigned int reg_idx = reg->idx[0].offset;
 
-                if (!s)
+                if (reg_idx >= ARRAY_SIZE(priv->output_map))
                 {
-                    ERR("Shader has no output signature, unable to map register.\n");
+                    ERR("Invalid output index %u.\n", reg_idx);
                     break;
                 }
 
-                for (i = 0; i < s->element_count; ++i)
-                {
-                    if (s->elements[i].register_idx == reg->idx[0].offset)
-                    {
-                        map_sysval(s->elements[i].sysval_semantic, reg);
-                        break;
-                    }
-                }
+                reg->type = priv->output_map[reg_idx].register_type;
+                reg->idx[0].offset = priv->output_map[reg_idx].register_idx;
             }
             break;
 
@@ -396,14 +438,37 @@ static enum wined3d_data_type map_data_type(char t)
 
 static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature)
 {
-    struct wined3d_sm4_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
-    if (!priv)
+    struct wined3d_sm4_data *priv;
+    unsigned int i, j;
+
+    if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
     {
         ERR("Failed to allocate private data\n");
         return NULL;
     }
 
-    priv->output_signature = output_signature;
+    memset(priv->output_map, 0xff, sizeof(priv->output_map));
+    for (i = 0; i < output_signature->element_count; ++i)
+    {
+        struct wined3d_shader_signature_element *e = &output_signature->elements[i];
+
+        if (e->register_idx >= ARRAY_SIZE(priv->output_map))
+        {
+            WARN("Invalid output index %u.\n", e->register_idx);
+            continue;
+        }
+
+        for (j = 0; j < ARRAY_SIZE(sysval_map); ++j)
+        {
+            if (e->sysval_semantic == sysval_map[j].sysval)
+            {
+                priv->output_map[e->register_idx].register_type = sysval_map[j].register_type;
+                priv->output_map[e->register_idx].register_idx = sysval_map[j].register_idx;
+                break;
+            }
+        }
+    }
+
     list_init(&priv->src_free);
     list_init(&priv->src);
 
@@ -731,7 +796,40 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi
         FIXME("Skipping modifier 0x%08x.\n", modifier);
     }
 
-    if (opcode == WINED3D_SM4_OP_DCL_CONSTANT_BUFFER)
+    if (opcode == WINED3D_SM4_OP_DCL_RESOURCE)
+    {
+        enum wined3d_sm4_resource_type resource_type;
+        enum wined3d_sm4_data_type data_type;
+        DWORD components;
+
+        resource_type = (opcode_token & WINED3D_SM4_RESOURCE_TYPE_MASK) >> WINED3D_SM4_RESOURCE_TYPE_SHIFT;
+        if (!resource_type || (resource_type >= ARRAY_SIZE(resource_type_table)))
+        {
+            FIXME("Unhandled resource type %#x.\n", resource_type);
+            ins->declaration.semantic.resource_type = WINED3D_SHADER_RESOURCE_NONE;
+        }
+        else
+        {
+            ins->declaration.semantic.resource_type = resource_type_table[resource_type];
+        }
+        shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_RESOURCE, &ins->declaration.semantic.reg);
+
+        components = *p++;
+        if ((components & 0xfff0) != (components & 0xf) * 0x1110)
+            FIXME("Components (%#x) have different data types.\n", components);
+        data_type = components & 0xf;
+
+        if (!data_type || (data_type >= ARRAY_SIZE(data_type_table)))
+        {
+            FIXME("Unhandled data type %#x.\n", data_type);
+            ins->declaration.semantic.resource_data_type = WINED3D_DATA_FLOAT;
+        }
+        else
+        {
+            ins->declaration.semantic.resource_data_type = data_type_table[data_type];
+        }
+    }
+    else if (opcode == WINED3D_SM4_OP_DCL_CONSTANT_BUFFER)
     {
         shader_sm4_read_src_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.src);
         if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK)
index 17162ac..8f06177 100644 (file)
@@ -95,7 +95,6 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_
 {
     enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE];
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    static UINT once;
 
     /* No z test without depth stencil buffers */
     if (!state->fb->depth_stencil)
@@ -124,21 +123,8 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_
             break;
     }
 
-    if (context->gl_info->supported[ARB_DEPTH_CLAMP])
-    {
-        if (!zenable && context->stream_info.position_transformed)
-        {
-            gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
-            checkGLcall("glEnable(GL_DEPTH_CLAMP)");
-        }
-        else
-        {
-            gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
-            checkGLcall("glDisable(GL_DEPTH_CLAMP)");
-        }
-    }
-    else if (!zenable && !once++)
-        FIXME("Z buffer disabled, but ARB_depth_clamp isn't supported.\n");
+    if (context->last_was_rhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
+        transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
 }
 
 static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -226,7 +212,7 @@ static void state_zwritenable(struct wined3d_context *context, const struct wine
     }
 }
 
-static GLenum gl_compare_func(enum wined3d_cmp_func f)
+GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f)
 {
     switch (f)
     {
@@ -254,7 +240,7 @@ static GLenum gl_compare_func(enum wined3d_cmp_func f)
 
 static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
-    GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
+    GLenum depth_func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
     if (!depth_func) return;
@@ -309,7 +295,7 @@ static void state_blendop(struct wined3d_context *context, const struct wined3d_
     if (state->render_states[WINED3D_RS_BLENDOPALPHA]
             && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
     {
-        WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
+        WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparate.\n");
         return;
     }
 
@@ -319,12 +305,12 @@ static void state_blendop(struct wined3d_context *context, const struct wined3d_
 
     if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
     {
-        GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
-        checkGLcall("glBlendEquationSeparateEXT");
+        GL_EXTCALL(glBlendEquationSeparate(blend_equation, blend_equation_alpha));
+        checkGLcall("glBlendEquationSeparate");
     }
     else
     {
-        GL_EXTCALL(glBlendEquationEXT(blend_equation));
+        GL_EXTCALL(glBlendEquation(blend_equation));
         checkGLcall("glBlendEquation");
     }
 }
@@ -454,7 +440,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
         /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
         if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
         {
-            WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
+            WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparate.\n");
             return;
         }
 
@@ -478,8 +464,8 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
             dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA], rt_format);
         }
 
-        GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
-        checkGLcall("glBlendFuncSeparateEXT");
+        GL_EXTCALL(glBlendFuncSeparate(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
+        checkGLcall("glBlendFuncSeparate");
     }
     else
     {
@@ -496,7 +482,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
 
 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
-    WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
+    WARN("Unsupported in local OpenGL implementation: glBlendColor.\n");
 }
 
 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -507,7 +493,7 @@ static void state_blendfactor(struct wined3d_context *context, const struct wine
     TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
 
     D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
-    GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
+    GL_EXTCALL(glBlendColor(col[0], col[1], col[2], col[3]));
     checkGLcall("glBlendColor");
 }
 
@@ -527,7 +513,7 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st
      * WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture
      * function will call alpha in case it finds some texture + colorkeyenable
      * combination which needs extra care. */
-    if (state->textures[0] && (state->textures[0]->color_key_flags & WINEDDSD_CKSRCBLT))
+    if (state->textures[0] && (state->textures[0]->color_key_flags & WINED3D_CKEY_SRC_BLT))
         enable_ckey = TRUE;
 
     if (enable_ckey || context->last_was_ckey)
@@ -558,7 +544,7 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st
     else
     {
         ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
-        glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
+        glParm = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
     }
     if (glParm)
     {
@@ -827,9 +813,9 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_
 
     onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
     twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
-    if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
+    if (!(func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
         func = GL_ALWAYS;
-    if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
+    if (!(func_ccw = wined3d_gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
         func_ccw = GL_ALWAYS;
     ref = state->render_states[WINED3D_RS_STENCILREF];
     mask = state->render_states[WINED3D_RS_STENCILMASK];
@@ -852,7 +838,15 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_
         gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
         checkGLcall("glEnable GL_STENCIL_TEST");
 
-        if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
+        if (gl_info->supported[WINED3D_GL_VERSION_2_0])
+        {
+            GL_EXTCALL(glStencilFuncSeparate(GL_FRONT, func, ref, mask));
+            GL_EXTCALL(glStencilOpSeparate(GL_FRONT, stencilFail, depthFail, stencilPass));
+            GL_EXTCALL(glStencilFuncSeparate(GL_BACK, func_ccw, ref, mask));
+            GL_EXTCALL(glStencilOpSeparate(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
+            checkGLcall("setting two sided stencil state");
+        }
+        else if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
         {
             /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
              * which has an effect on the code below too. If we apply the front face
@@ -873,7 +867,9 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_
             checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
             GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
             checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
-        } else {
+        }
+        else
+        {
             ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
         }
     }
@@ -1592,11 +1588,12 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined
 
 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
 {
-    GL_EXTCALL(glColorMaskIndexedEXT(index,
+    GL_EXTCALL(glColorMaski(index,
             mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
             mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
             mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
             mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
+    checkGLcall("glColorMaski");
 }
 
 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -3205,7 +3202,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st
 
         if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
         {
-            if (texture->color_key_flags & WINEDDSD_CKSRCBLT && !texture->resource.format->alpha_size)
+            if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size)
             {
                 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
                  * properly. On the other hand applications can still use texture combiners apparently. This code
@@ -3358,8 +3355,8 @@ static void load_tex_coords(const struct wined3d_context *context, const struct
 
             if (*curVBO != e->data.buffer_object)
             {
-                GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
-                checkGLcall("glBindBufferARB");
+                GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+                checkGLcall("glBindBuffer");
                 *curVBO = e->data.buffer_object;
             }
 
@@ -3595,24 +3592,92 @@ void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_sta
     }
 }
 
-static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static enum wined3d_texture_address wined3d_texture_address_mode(const struct wined3d_texture *texture,
+        enum wined3d_texture_address t)
 {
-    DWORD sampler = state_id - STATE_SAMPLER(0);
-    DWORD mapped_stage = context->tex_unit_map[sampler];
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    union {
+    if (t < WINED3D_TADDRESS_WRAP || t > WINED3D_TADDRESS_MIRROR_ONCE)
+    {
+        FIXME("Unrecognized or unsupported texture address mode %#x.\n", t);
+        return WINED3D_TADDRESS_WRAP;
+    }
+
+    /* Cubemaps are always set to clamp, regardless of the sampler state. */
+    if (texture->target == GL_TEXTURE_CUBE_MAP_ARB || ((texture->flags & WINED3D_TEXTURE_COND_NP2)
+            && t == WINED3D_TADDRESS_WRAP))
+        return WINED3D_TADDRESS_CLAMP;
+
+    return t;
+}
+
+static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc *desc,
+        const struct wined3d_gl_info *gl_info, const DWORD *sampler_states, const struct wined3d_texture *texture)
+{
+    union
+    {
         float f;
         DWORD d;
-    } tmpvalue;
+    } lod_bias;
+
+    desc->address_u = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_U]);
+    desc->address_v = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_V]);
+    desc->address_w = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_W]);
+    D3DCOLORTOGLFLOAT4(sampler_states[WINED3D_SAMP_BORDER_COLOR], desc->border_color);
+    if (sampler_states[WINED3D_SAMP_MAG_FILTER] > WINED3D_TEXF_ANISOTROPIC)
+        FIXME("Unrecognized or unsupported WINED3D_SAMP_MAG_FILTER %#x.\n",
+                sampler_states[WINED3D_SAMP_MAG_FILTER]);
+    desc->mag_filter = min(max(sampler_states[WINED3D_SAMP_MAG_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR);
+    if (sampler_states[WINED3D_SAMP_MIN_FILTER] > WINED3D_TEXF_ANISOTROPIC)
+        FIXME("Unrecognized or unsupported WINED3D_SAMP_MIN_FILTER %#x.\n",
+                sampler_states[WINED3D_SAMP_MIN_FILTER]);
+    desc->min_filter = min(max(sampler_states[WINED3D_SAMP_MIN_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR);
+    if (sampler_states[WINED3D_SAMP_MIP_FILTER] > WINED3D_TEXF_ANISOTROPIC)
+        FIXME("Unrecognized or unsupported WINED3D_SAMP_MIP_FILTER %#x.\n",
+                sampler_states[WINED3D_SAMP_MIP_FILTER]);
+    desc->mip_filter = min(max(sampler_states[WINED3D_SAMP_MIP_FILTER], WINED3D_TEXF_NONE), WINED3D_TEXF_LINEAR);
+    lod_bias.d = sampler_states[WINED3D_SAMP_MIPMAP_LOD_BIAS];
+    desc->lod_bias = lod_bias.f;
+    desc->min_lod = -1000.0f;
+    desc->max_lod = 1000.0f;
+    desc->max_anisotropy = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY];
+    if ((sampler_states[WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_ANISOTROPIC
+                && sampler_states[WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_ANISOTROPIC
+                && sampler_states[WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_ANISOTROPIC)
+            || (texture->flags & WINED3D_TEXTURE_COND_NP2))
+        desc->max_anisotropy = 1;
+    desc->compare = texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW;
+    desc->comparison_func = WINED3D_CMP_LESSEQUAL;
+    desc->srgb_decode = sampler_states[WINED3D_SAMP_SRGB_TEXTURE];
+
+    if (!(texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING))
+    {
+        desc->mag_filter = WINED3D_TEXF_POINT;
+        desc->min_filter = WINED3D_TEXF_POINT;
+        desc->mip_filter = WINED3D_TEXF_NONE;
+    }
+
+    if (texture->flags & WINED3D_TEXTURE_COND_NP2)
+    {
+        desc->mip_filter = WINED3D_TEXF_NONE;
+        if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
+            desc->min_filter = WINED3D_TEXF_POINT;
+    }
+}
+
+/* Enabling and disabling texture dimensions is done by texture stage state /
+ * pixel shader setup, this function only has to bind textures and set the per
+ * texture states. */
+static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+    DWORD sampler_idx = state_id - STATE_SAMPLER(0);
+    DWORD mapped_stage = context->tex_unit_map[sampler_idx];
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    TRACE("Sampler %u.\n", sampler_idx);
 
-    TRACE("Sampler: %d\n", sampler);
-    /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
-     * only has to bind textures and set the per texture states
-     */
 
     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
     {
-        TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
+        TRACE("No sampler mapped to stage %u. Returning.\n", sampler_idx);
         return;
     }
 
@@ -3622,25 +3687,75 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
     }
     context_active_texture(context, gl_info, mapped_stage);
 
-    if (state->textures[sampler])
+    if (state->textures[sampler_idx])
     {
-        struct wined3d_texture *texture = state->textures[sampler];
-        BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
+        struct wined3d_texture *texture = state->textures[sampler_idx];
+        BOOL srgb = state->sampler_states[sampler_idx][WINED3D_SAMP_SRGB_TEXTURE];
+        const DWORD *sampler_states = state->sampler_states[sampler_idx];
+        struct wined3d_sampler_desc desc;
+        struct gl_texture *gl_tex;
+        unsigned int base_level;
+
+        wined3d_sampler_desc_from_sampler_states(&desc, gl_info, sampler_states, texture);
 
         wined3d_texture_bind(texture, context, srgb);
-        wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
+        if (!gl_info->supported[ARB_SAMPLER_OBJECTS])
+        {
+            wined3d_texture_apply_sampler_desc(texture, &desc, gl_info);
+        }
+        else
+        {
+            struct wined3d_device *device = context->swapchain->device;
+            struct wined3d_sampler *sampler;
+            struct wine_rb_entry *entry;
 
-        if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
+            if ((entry = wine_rb_get(&device->samplers, &desc)))
+            {
+                sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
+            }
+            else
+            {
+                if (FAILED(wined3d_sampler_create(device, &desc, NULL, &sampler)))
+                {
+                    ERR("Failed to create sampler.\n");
+                    sampler = NULL;
+                }
+                else
+                {
+                    if (wine_rb_put(&device->samplers, &desc, &sampler->entry) == -1)
+                        ERR("Failed to insert sampler.\n");
+                }
+            }
+
+            if (sampler)
+            {
+                GL_EXTCALL(glBindSampler(sampler_idx, sampler->name));
+                checkGLcall("glBindSampler");
+            }
+        }
+
+        if (texture->flags & WINED3D_TEXTURE_COND_NP2)
+            base_level = 0;
+        else if (desc.mip_filter == WINED3D_TEXF_NONE)
+            base_level = texture->lod;
+        else
+            base_level = min(max(sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL],
+                    texture->lod), texture->level_count - 1);
+
+        gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB);
+        if (base_level != gl_tex->base_level)
         {
-            tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
-            gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
-                      GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
-            checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
+            /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap
+             * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest
+             * mimap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL
+             * corresponds to GL_TEXTURE_BASE_LEVEL. */
+            gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, base_level);
+            gl_tex->base_level = base_level;
         }
 
-        if (!use_ps(state) && sampler < context->lowest_disabled_stage)
+        if (!use_ps(state) && sampler_idx < context->lowest_disabled_stage)
         {
-            if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
+            if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler_idx)
             {
                 /* If color keying is enabled update the alpha test, it
                  * depends on the existence of a color key in stage 0. */
@@ -3654,10 +3769,10 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
     }
     else
     {
-        if (sampler < context->lowest_disabled_stage)
+        if (sampler_idx < context->lowest_disabled_stage)
         {
             /* TODO: What should I do with pixel shaders here ??? */
-            if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
+            if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler_idx)
             {
                 /* If color keying is enabled update the alpha test, it
                  * depends on the existence of a color key in stage 0. */
@@ -3968,12 +4083,16 @@ void transform_projection(struct wined3d_context *context, const struct wined3d_
         double y_offset = context->render_offscreen
                 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
                 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
+        enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ?
+                state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE;
+        double z_scale = zenable ? 2.0f : 0.0f;
+        double z_offset = zenable ? -1.0f : 0.0f;
         const GLdouble projection[] =
         {
-             x_scale,      0.0,  0.0, 0.0,
-                 0.0,  y_scale,  0.0, 0.0,
-                 0.0,      0.0,  2.0, 0.0,
-            x_offset, y_offset, -1.0, 1.0,
+             x_scale,      0.0,  0.0,      0.0,
+                 0.0,  y_scale,  0.0,      0.0,
+                 0.0,      0.0,  z_scale,  0.0,
+            x_offset, y_offset,  z_offset, 1.0,
         };
 
         gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
@@ -4020,10 +4139,10 @@ static inline void unload_numbered_array(struct wined3d_context *context, int i)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
-    GL_EXTCALL(glDisableVertexAttribArrayARB(i));
-    checkGLcall("glDisableVertexAttribArrayARB(reg)");
+    GL_EXTCALL(glDisableVertexAttribArray(i));
+    checkGLcall("glDisableVertexAttribArray");
     if (gl_info->supported[ARB_INSTANCED_ARRAYS])
-        GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
+        GL_EXTCALL(glVertexAttribDivisor(i, 0));
 
     context->numbered_array_mask &= ~(1 << i);
 }
@@ -4059,7 +4178,7 @@ static void load_numbered_arrays(struct wined3d_context *context,
             if (context->numbered_array_mask & (1 << i))
                 unload_numbered_array(context, i);
             if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.input_registers & (1 << i))
-                GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
+                GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f));
             continue;
         }
 
@@ -4079,11 +4198,11 @@ static void load_numbered_arrays(struct wined3d_context *context,
                 continue;
             }
 
-            GL_EXTCALL(glVertexAttribDivisorARB(i, 1));
+            GL_EXTCALL(glVertexAttribDivisor(i, 1));
         }
         else if (gl_info->supported[ARB_INSTANCED_ARRAYS])
         {
-            GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
+            GL_EXTCALL(glVertexAttribDivisor(i, 0));
         }
 
         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
@@ -4092,15 +4211,15 @@ static void load_numbered_arrays(struct wined3d_context *context,
         {
             if (curVBO != stream_info->elements[i].data.buffer_object)
             {
-                GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
-                checkGLcall("glBindBufferARB");
+                GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, stream_info->elements[i].data.buffer_object));
+                checkGLcall("glBindBuffer");
                 curVBO = stream_info->elements[i].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
              * curVBO will be 0. If there is a vertex buffer but no vbo we
              * won't be load converted attributes anyway. */
-            GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
+            GL_EXTCALL(glVertexAttribPointer(i, stream_info->elements[i].format->gl_vtx_format,
                     stream_info->elements[i].format->gl_vtx_type,
                     stream_info->elements[i].format->gl_normalized,
                     stream_info->elements[i].stride, stream_info->elements[i].data.addr
@@ -4108,14 +4227,14 @@ static void load_numbered_arrays(struct wined3d_context *context,
 
             if (!(context->numbered_array_mask & (1 << i)))
             {
-                GL_EXTCALL(glEnableVertexAttribArrayARB(i));
+                GL_EXTCALL(glEnableVertexAttribArray(i));
                 context->numbered_array_mask |= (1 << i);
             }
         }
         else
         {
             /* Stride = 0 means always the same values.
-             * glVertexAttribPointerARB doesn't do that. Instead disable the
+             * 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 = stream_info->elements[i].data.addr;
@@ -4129,20 +4248,20 @@ static void load_numbered_arrays(struct wined3d_context *context,
             switch (stream_info->elements[i].format->id)
             {
                 case WINED3DFMT_R32_FLOAT:
-                    GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
+                    GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr));
                     break;
                 case WINED3DFMT_R32G32_FLOAT:
-                    GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
+                    GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr));
                     break;
                 case WINED3DFMT_R32G32B32_FLOAT:
-                    GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
+                    GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr));
                     break;
                 case WINED3DFMT_R32G32B32A32_FLOAT:
-                    GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
+                    GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr));
                     break;
 
                 case WINED3DFMT_R8G8B8A8_UINT:
-                    GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
+                    GL_EXTCALL(glVertexAttrib4ubv(i, ptr));
                     break;
                 case WINED3DFMT_B8G8R8A8_UNORM:
                     if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
@@ -4151,38 +4270,38 @@ static void load_numbered_arrays(struct wined3d_context *context,
                         DWORD c = *src & 0xff00ff00;
                         c |= (*src & 0xff0000) >> 16;
                         c |= (*src & 0xff) << 16;
-                        GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
+                        GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c));
                         break;
                     }
                     /* else fallthrough */
                 case WINED3DFMT_R8G8B8A8_UNORM:
-                    GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
+                    GL_EXTCALL(glVertexAttrib4Nubv(i, ptr));
                     break;
 
                 case WINED3DFMT_R16G16_SINT:
-                    GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
+                    GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr));
                     break;
                 case WINED3DFMT_R16G16B16A16_SINT:
-                    GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
+                    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(glVertexAttrib4NsvARB(i, s));
+                    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(glVertexAttrib4NusvARB(i, s));
+                    GL_EXTCALL(glVertexAttrib4Nusv(i, s));
                     break;
                 }
                 case WINED3DFMT_R16G16B16A16_SNORM:
-                    GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
+                    GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr));
                     break;
                 case WINED3DFMT_R16G16B16A16_UNORM:
-                    GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
+                    GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr));
                     break;
 
                 case WINED3DFMT_R10G10B10A2_UINT:
@@ -4204,7 +4323,7 @@ static void load_numbered_arrays(struct wined3d_context *context,
                     {
                         float x = float_16_to_32(((const unsigned short *)ptr) + 0);
                         float y = float_16_to_32(((const unsigned short *)ptr) + 1);
-                        GL_EXTCALL(glVertexAttrib2fARB(i, x, y));
+                        GL_EXTCALL(glVertexAttrib2f(i, x, y));
                     }
                     break;
                 case WINED3DFMT_R16G16B16A16_FLOAT:
@@ -4219,7 +4338,7 @@ static void load_numbered_arrays(struct wined3d_context *context,
                         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(glVertexAttrib4fARB(i, x, y, z, w));
+                        GL_EXTCALL(glVertexAttrib4f(i, x, y, z, w));
                     }
                     break;
 
@@ -4263,8 +4382,8 @@ static void load_vertex_data(struct wined3d_context *context,
 
             if (curVBO != e->data.buffer_object)
             {
-                GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
-                checkGLcall("glBindBufferARB");
+                GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+                checkGLcall("glBindBuffer");
                 curVBO = e->data.buffer_object;
             }
 
@@ -4319,8 +4438,8 @@ static void load_vertex_data(struct wined3d_context *context,
 
         if (curVBO != e->data.buffer_object)
         {
-            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
-            checkGLcall("glBindBufferARB");
+            GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+            checkGLcall("glBindBuffer");
             curVBO = e->data.buffer_object;
         }
 
@@ -4341,8 +4460,8 @@ static void load_vertex_data(struct wined3d_context *context,
 
         if (curVBO != e->data.buffer_object)
         {
-            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
-            checkGLcall("glBindBufferARB");
+            GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+            checkGLcall("glBindBuffer");
             curVBO = e->data.buffer_object;
         }
 
@@ -4368,8 +4487,8 @@ static void load_vertex_data(struct wined3d_context *context,
 
         if (curVBO != e->data.buffer_object)
         {
-            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
-            checkGLcall("glBindBufferARB");
+            GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+            checkGLcall("glBindBuffer");
             curVBO = e->data.buffer_object;
         }
 
@@ -4403,8 +4522,8 @@ static void load_vertex_data(struct wined3d_context *context,
 
             if (curVBO != e->data.buffer_object)
             {
-                GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
-                checkGLcall("glBindBufferARB");
+                GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+                checkGLcall("glBindBuffer");
                 curVBO = e->data.buffer_object;
             }
 
@@ -4638,9 +4757,6 @@ void vertexdeclaration(struct wined3d_context *context, const struct wined3d_sta
                 && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.minor <= 3)
             context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
     }
-
-    if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
-        state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
 }
 
 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -4842,12 +4958,12 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st
 
     if (!state->index_buffer || !stream_info->all_vbo)
     {
-        GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
+        GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
     }
     else
     {
         struct wined3d_buffer *ib = state->index_buffer;
-        GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
+        GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer_object));
     }
 }
 
@@ -4883,11 +4999,8 @@ static void psorigin(struct wined3d_context *context, const struct wined3d_state
     const struct wined3d_gl_info *gl_info = context->gl_info;
     GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
 
-    if (gl_info->supported[NV_POINT_SPRITE])
-    {
-        GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
-        checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
-    }
+    GL_EXTCALL(glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin));
+    checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
 }
 
 void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -4954,6 +5067,14 @@ static void state_cb_warn(struct wined3d_context *context, const struct wined3d_
     WARN("Constant buffers (%s) no supported.\n", debug_d3dstate(state_id));
 }
 
+static void state_shader_resource_binding(struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD state_id)
+{
+    TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+    context->update_shader_resource_bindings = 1;
+}
+
 const struct StateEntryTemplate misc_state_template[] =
 {
     { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX),  { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX),  state_cb_vs,        }, ARB_UNIFORM_BUFFER_OBJECT       },
@@ -4962,6 +5083,7 @@ const struct StateEntryTemplate misc_state_template[] =
     { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),state_cb_warn,      }, WINED3D_GL_EXT_NONE             },
     { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL),   { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL),   state_cb_ps,        }, ARB_UNIFORM_BUFFER_OBJECT       },
     { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL),   { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL),   state_cb_warn,      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SHADER_RESOURCE_BINDING,                      { STATE_SHADER_RESOURCE_BINDING,                      state_shader_resource_binding}, WINED3D_GL_EXT_NONE    },
     { STATE_RENDER(WINED3D_RS_SRCBLEND),                  { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DESTBLEND),                 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          state_blend         }, WINED3D_GL_EXT_NONE             },
@@ -5893,6 +6015,7 @@ static void validate_state_table(struct StateEntry *state_table)
         STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX),
         STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),
         STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL),
+        STATE_SHADER_RESOURCE_BINDING,
         STATE_VIEWPORT,
         STATE_LIGHT_TYPE,
         STATE_SCISSORRECT,
index 3228c0f..5315a46 100644 (file)
@@ -456,6 +456,7 @@ ULONG CDECL wined3d_stateblock_incref(struct wined3d_stateblock *stateblock)
 
 void state_unbind_resources(struct wined3d_state *state)
 {
+    struct wined3d_shader_resource_view *srv;
     struct wined3d_vertex_declaration *decl;
     struct wined3d_sampler *sampler;
     struct wined3d_texture *texture;
@@ -527,6 +528,15 @@ void state_unbind_resources(struct wined3d_state *state)
                 wined3d_sampler_decref(sampler);
             }
         }
+
+        for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j)
+        {
+            if ((srv = state->shader_resource_view[i][j]))
+            {
+                state->shader_resource_view[i][j] = NULL;
+                wined3d_shader_resource_view_decref(srv);
+            }
+        }
     }
 }
 
index 5f1bc10..07122b3 100644 (file)
@@ -57,7 +57,7 @@ static void surface_cleanup(struct wined3d_surface *surface)
         if (surface->pbo)
         {
             TRACE("Deleting PBO %u.\n", surface->pbo);
-            GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo));
+            GL_EXTCALL(glDeleteBuffers(1, &surface->pbo));
         }
 
         if (surface->rb_multisample)
@@ -308,14 +308,13 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3
     context_bind_texture(context, info.bind_target, texture->texture_rgb.name);
 
     /* Filtering for StretchRect */
-    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER,
-            wined3d_gl_mag_filter(magLookup, filter));
+    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter));
     checkGLcall("glTexParameteri");
     gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER,
-            wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE));
+            wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE));
     checkGLcall("glTexParameteri");
-    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
-    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
         gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
     gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@@ -341,10 +340,10 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3
 
     /* We changed the filtering settings on the texture. Inform the
      * container about this to get the filters reset properly next draw. */
-    texture->texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT;
-    texture->texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT;
-    texture->texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE;
-    texture->texture_rgb.states[WINED3DTEXSTA_SRGBTEXTURE] = FALSE;
+    texture->texture_rgb.sampler_desc.mag_filter = WINED3D_TEXF_POINT;
+    texture->texture_rgb.sampler_desc.min_filter = WINED3D_TEXF_POINT;
+    texture->texture_rgb.sampler_desc.mip_filter = WINED3D_TEXF_NONE;
+    texture->texture_rgb.sampler_desc.srgb_decode = FALSE;
 }
 
 /* Works correctly only for <= 4 bpp formats. */
@@ -520,22 +519,22 @@ static void surface_prepare_buffer(struct wined3d_surface *surface)
     context = context_acquire(surface->resource.device, NULL);
     gl_info = context->gl_info;
 
-    GL_EXTCALL(glGenBuffersARB(1, &surface->pbo));
+    GL_EXTCALL(glGenBuffers(1, &surface->pbo));
     error = gl_info->gl_ops.gl.p_glGetError();
     if (!surface->pbo || error != GL_NO_ERROR)
         ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error);
 
     TRACE("Binding PBO %u.\n", surface->pbo);
 
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
-    checkGLcall("glBindBufferARB");
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo));
+    checkGLcall("glBindBuffer");
 
-    GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->resource.size + 4,
-            NULL, GL_STREAM_DRAW_ARB));
-    checkGLcall("glBufferDataARB");
+    GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4,
+            NULL, GL_STREAM_DRAW));
+    checkGLcall("glBufferData");
 
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-    checkGLcall("glBindBufferARB");
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+    checkGLcall("glBindBuffer");
 
     context_release(context);
 }
@@ -585,18 +584,19 @@ void surface_prepare_map_memory(struct wined3d_surface *surface)
 
 static void surface_evict_sysmem(struct wined3d_surface *surface)
 {
-    if (surface->resource.map_count || surface->flags & SFLAG_DONOTFREE)
+    /* In some conditions the surface memory must not be freed:
+     * WINED3D_TEXTURE_CONVERTED: Converting the data back would take too long
+     * WINED3D_TEXTURE_DYNAMIC_MAP: Avoid freeing the data for performance
+     * SFLAG_CLIENT: OpenGL uses our memory as backup */
+    if (surface->resource.map_count || surface->flags & SFLAG_CLIENT
+            || surface->container->flags & (WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_PIN_SYSMEM
+            | WINED3D_TEXTURE_DYNAMIC_MAP))
         return;
 
     wined3d_resource_free_sysmem(&surface->resource);
     surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM);
 }
 
-static void surface_force_reload(struct wined3d_surface *surface)
-{
-    surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
-}
-
 static void surface_release_client_storage(struct wined3d_surface *surface)
 {
     struct wined3d_context *context = context_acquire(surface->resource.device, NULL);
@@ -614,22 +614,22 @@ static void surface_release_client_storage(struct wined3d_surface *surface)
         gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
                 GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
     }
+    wined3d_texture_force_reload(surface->container);
 
     context_release(context);
-
-    surface_invalidate_location(surface, WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB);
-    surface_force_reload(surface);
 }
 
 static BOOL surface_use_pbo(const struct wined3d_surface *surface)
 {
     const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
+    struct wined3d_texture *texture = surface->container;
 
-    return surface->resource.pool == WINED3D_POOL_DEFAULT
+    return texture->resource.pool == WINED3D_POOL_DEFAULT
                 && surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU
                 && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]
-                && !surface->resource.format->convert
-                && !(surface->flags & (SFLAG_NONPOW2 | SFLAG_PIN_SYSMEM));
+                && !texture->resource.format->convert
+                && !(texture->flags & WINED3D_TEXTURE_PIN_SYSMEM)
+                && !(surface->flags & SFLAG_NONPOW2);
 }
 
 static HRESULT surface_private_setup(struct wined3d_surface *surface)
@@ -730,10 +730,10 @@ static void surface_unmap(struct wined3d_surface *surface)
             context = context_acquire(device, NULL);
             gl_info = context->gl_info;
 
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
-            GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-            checkGLcall("glUnmapBufferARB");
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo));
+            GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+            checkGLcall("glUnmapBuffer");
             context_release(context);
             break;
 
@@ -1149,8 +1149,8 @@ HRESULT CDECL wined3d_surface_get_render_target_data(struct wined3d_surface *sur
 /* Context activation is done by the caller. */
 static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
 {
-    GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo));
-    checkGLcall("glDeleteBuffersARB(1, &surface->pbo)");
+    GL_EXTCALL(glDeleteBuffers(1, &surface->pbo));
+    checkGLcall("glDeleteBuffers(1, &surface->pbo)");
 
     surface->pbo = 0;
     surface_invalidate_location(surface, WINED3D_LOCATION_BUFFER);
@@ -1204,7 +1204,6 @@ static void surface_unload(struct wined3d_resource *resource)
         surface_load_location(surface, surface->resource.map_binding);
         surface_invalidate_location(surface, ~surface->resource.map_binding);
     }
-    surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
 
     context = context_acquire(device, NULL);
     gl_info = context->gl_info;
@@ -1323,7 +1322,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
     struct wined3d_bo_address data;
 
     /* Only support read back of converted P8 surfaces. */
-    if (surface->flags & SFLAG_CONVERTED && format->id != WINED3DFMT_P8_UINT)
+    if (surface->container->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT)
     {
         ERR("Trying to read back converted surface %p with format %s.\n", surface, debug_d3dformat(format->id));
         return;
@@ -1333,23 +1332,23 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
 
     if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
     {
-        TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p.\n",
+        TRACE("(%p) : Calling glGetCompressedTexImage level %d, format %#x, type %#x, data %p.\n",
                 surface, surface->texture_level, format->glFormat, format->glType, data.addr);
 
         if (data.buffer_object)
         {
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data.buffer_object));
-            checkGLcall("glBindBufferARB");
-            GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target, surface->texture_level, NULL));
-            checkGLcall("glGetCompressedTexImageARB");
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
-            checkGLcall("glBindBufferARB");
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object));
+            checkGLcall("glBindBuffer");
+            GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, surface->texture_level, NULL));
+            checkGLcall("glGetCompressedTexImage");
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+            checkGLcall("glBindBuffer");
         }
         else
         {
-            GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target,
+            GL_EXTCALL(glGetCompressedTexImage(surface->texture_target,
                     surface->texture_level, data.addr));
-            checkGLcall("glGetCompressedTexImageARB");
+            checkGLcall("glGetCompressedTexImage");
         }
     }
     else
@@ -1378,15 +1377,15 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
 
         if (data.buffer_object)
         {
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data.buffer_object));
-            checkGLcall("glBindBufferARB");
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object));
+            checkGLcall("glBindBuffer");
 
             gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
                     gl_format, gl_type, NULL);
             checkGLcall("glGetTexImage");
 
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
-            checkGLcall("glBindBufferARB");
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+            checkGLcall("glBindBuffer");
         }
         else
         {
@@ -1447,8 +1446,8 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
              * get a boxed texture with width pow2width and not a texture of width resource.width.
              *
              * Performance should not be an issue, because applications normally do not lock the surfaces when
-             * rendering. If an app does, the SFLAG_DYNLOCK flag will kick in and the memory copy won't be released,
-             * and doesn't have to be re-read. */
+             * rendering. If an app does, the WINED3D_TEXTURE_DYNAMIC_MAP flag will kick in and the memory copy
+             * won't be released, and doesn't have to be re-read. */
             src_data = mem;
             dst_data = data.addr;
             TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch);
@@ -1467,9 +1466,9 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
 /* This call just uploads data, the caller is responsible for binding the
  * correct texture. */
 /* Context activation is done by the caller. */
-static void surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
+void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
         const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point,
-        BOOL srgb, const struct wined3d_bo_address *data)
+        BOOL srgb, const struct wined3d_const_bo_address *data)
 {
     UINT update_w = src_rect->right - src_rect->left;
     UINT update_h = src_rect->bottom - src_rect->top;
@@ -1480,8 +1479,8 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi
 
     if (surface->resource.map_count)
     {
-        WARN("Uploading a surface that is currently mapped, setting SFLAG_PIN_SYSMEM.\n");
-        surface->flags |= SFLAG_PIN_SYSMEM;
+        WARN("Uploading a surface that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n");
+        surface->container->flags |= WINED3D_TEXTURE_PIN_SYSMEM;
     }
 
     if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
@@ -1492,8 +1491,8 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi
 
     if (data->buffer_object)
     {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, data->buffer_object));
-        checkGLcall("glBindBufferARB");
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
+        checkGLcall("glBindBuffer");
     }
 
     if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
@@ -1514,30 +1513,30 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi
         else
             internal = format->glInternal;
 
-        TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, "
+        TRACE("glCompressedTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, "
                 "format %#x, image_size %#x, addr %p.\n", surface->texture_target, surface->texture_level,
                 dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr);
 
         if (row_length == src_pitch)
         {
-            GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level,
+            GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level,
                     dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr));
         }
         else
         {
             UINT row, y;
 
-            /* glCompressedTexSubImage2DARB() ignores pixel store state, so we
-             * can't use the unpack row length like below. */
+            /* glCompressedTexSubImage2D() ignores pixel store state, so we
+             * can't use the unpack row length like for glTexSubImage2D. */
             for (row = 0, y = dst_point->y; row < row_count; ++row)
             {
-                GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level,
+                GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level,
                         dst_point->x, y, update_w, format->block_height, internal, row_length, addr));
                 y += format->block_height;
                 addr += src_pitch;
             }
         }
-        checkGLcall("glCompressedTexSubImage2DARB");
+        checkGLcall("glCompressedTexSubImage2D");
     }
     else
     {
@@ -1559,8 +1558,8 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi
 
     if (data->buffer_object)
     {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-        checkGLcall("glBindBufferARB");
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+        checkGLcall("glBindBuffer");
     }
 
     if (wined3d_settings.strict_draw_ordering)
@@ -1578,132 +1577,6 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi
     }
 }
 
-static HRESULT d3dfmt_get_conv(const struct wined3d_surface *surface, BOOL need_alpha_ck, BOOL use_texturing,
-        struct wined3d_format *format, enum wined3d_conversion_type *conversion_type)
-{
-    BOOL colorkey_active = need_alpha_ck && (surface->container->color_key_flags & WINEDDSD_CKSRCBLT);
-    const struct wined3d_device *device = surface->resource.device;
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
-    BOOL blit_supported = FALSE;
-
-    /* Copy the default values from the surface. Below we might perform fixups */
-    /* TODO: get rid of color keying desc fixups by using e.g. a table. */
-    *format = *surface->resource.format;
-    *conversion_type = WINED3D_CT_NONE;
-
-    /* Ok, now look if we have to do any conversion */
-    switch (surface->resource.format->id)
-    {
-        case WINED3DFMT_P8_UINT:
-            /* Below the call to blit_supported is disabled for Wine 1.2
-             * because the function isn't operating correctly yet. At the
-             * moment 8-bit blits are handled in software and if certain GL
-             * extensions are around, surface conversion is performed at
-             * upload time. The blit_supported call recognizes it as a
-             * destination fixup. This type of upload 'fixup' and 8-bit to
-             * 8-bit blits need to be handled by the blit_shader.
-             * TODO: get rid of this #if 0. */
-#if 0
-            blit_supported = device->blitter->blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
-                    &rect, surface->resource.usage, surface->resource.pool, surface->resource.format,
-                    &rect, surface->resource.usage, surface->resource.pool, surface->resource.format);
-#endif
-            blit_supported = gl_info->supported[ARB_FRAGMENT_PROGRAM];
-
-            /* Use conversion when the blit_shader backend supports it. It only supports this in case of
-             * texturing. Further also use conversion in case of color keying.
-             * Paletted textures can be emulated using shaders but only do that for 2D purposes e.g. situations
-             * in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which
-             * conflicts with this.
-             */
-            if (!((blit_supported && surface->container->swapchain
-                    && surface->container == surface->container->swapchain->front_buffer))
-                    || colorkey_active || !use_texturing)
-            {
-                format->glFormat = GL_RGBA;
-                format->glInternal = GL_RGBA;
-                format->glType = GL_UNSIGNED_BYTE;
-                format->conv_byte_count = 4;
-                *conversion_type = WINED3D_CT_PALETTED;
-            }
-            break;
-
-        case WINED3DFMT_B2G3R3_UNORM:
-            /* **********************
-                GL_UNSIGNED_BYTE_3_3_2
-                ********************** */
-            if (colorkey_active) {
-                /* This texture format will never be used.. So do not care about color keying
-                    up until the point in time it will be needed :-) */
-                FIXME(" ColorKeying not supported in the RGB 332 format !\n");
-            }
-            break;
-
-        case WINED3DFMT_B5G6R5_UNORM:
-            if (colorkey_active)
-            {
-                *conversion_type = WINED3D_CT_CK_565;
-                format->glFormat = GL_RGBA;
-                format->glInternal = GL_RGB5_A1;
-                format->glType = GL_UNSIGNED_SHORT_5_5_5_1;
-                format->conv_byte_count = 2;
-            }
-            break;
-
-        case WINED3DFMT_B5G5R5X1_UNORM:
-            if (colorkey_active)
-            {
-                *conversion_type = WINED3D_CT_CK_5551;
-                format->glFormat = GL_BGRA;
-                format->glInternal = GL_RGB5_A1;
-                format->glType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-                format->conv_byte_count = 2;
-            }
-            break;
-
-        case WINED3DFMT_B8G8R8_UNORM:
-            if (colorkey_active)
-            {
-                *conversion_type = WINED3D_CT_CK_RGB24;
-                format->glFormat = GL_RGBA;
-                format->glInternal = GL_RGBA8;
-                format->glType = GL_UNSIGNED_INT_8_8_8_8;
-                format->conv_byte_count = 4;
-            }
-            break;
-
-        case WINED3DFMT_B8G8R8X8_UNORM:
-            if (colorkey_active)
-            {
-                *conversion_type = WINED3D_CT_RGB32_888;
-                format->glFormat = GL_RGBA;
-                format->glInternal = GL_RGBA8;
-                format->glType = GL_UNSIGNED_INT_8_8_8_8;
-                format->conv_byte_count = 4;
-            }
-            break;
-
-        case WINED3DFMT_B8G8R8A8_UNORM:
-            if (colorkey_active)
-            {
-                *conversion_type = WINED3D_CT_CK_ARGB32;
-                format->conv_byte_count = 4;
-            }
-            break;
-
-        default:
-            break;
-    }
-
-    if (*conversion_type != WINED3D_CT_NONE)
-    {
-        format->rtInternal = format->glInternal;
-        format->glGammaInternal = format->glInternal;
-    }
-
-    return WINED3D_OK;
-}
-
 static BOOL surface_check_block_align(struct wined3d_surface *surface, const RECT *rect)
 {
     UINT width_mask, height_mask;
@@ -1731,10 +1604,8 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
     const struct wined3d_format *src_format;
     const struct wined3d_format *dst_format;
     const struct wined3d_gl_info *gl_info;
-    enum wined3d_conversion_type convert;
     struct wined3d_context *context;
     struct wined3d_bo_address data;
-    struct wined3d_format format;
     UINT update_w, update_h;
     UINT dst_w, dst_h;
     RECT r, dst_rect;
@@ -1808,8 +1679,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
     }
 
     /* Use wined3d_surface_blt() instead of uploading directly if we need conversion. */
-    d3dfmt_get_conv(dst_surface, FALSE, TRUE, &format, &convert);
-    if (convert != WINED3D_CT_NONE || format.convert)
+    if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE))
         return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT);
 
     context = context_acquire(dst_surface->resource.device, NULL);
@@ -1819,7 +1689,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
      * the texture wouldn't be the current location, and we'd upload zeroes
      * just to overwrite them again. */
     if (update_w == dst_w && update_h == dst_h)
-        surface_prepare_texture(dst_surface, context, FALSE);
+        wined3d_texture_prepare_texture(dst_surface->container, context, FALSE);
     else
         surface_load_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_bind(dst_surface->container, context, FALSE);
@@ -1827,7 +1697,8 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
     surface_get_memory(src_surface, &data, src_surface->locations);
     src_pitch = wined3d_surface_get_pitch(src_surface);
 
-    surface_upload_data(dst_surface, gl_info, src_format, src_rect, src_pitch, dst_point, FALSE, &data);
+    wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect,
+            src_pitch, dst_point, FALSE, wined3d_const_bo_address(&data));
 
     context_invalidate_active_texture(context);
 
@@ -1839,83 +1710,6 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
     return WINED3D_OK;
 }
 
-/* This call just allocates the texture, the caller is responsible for binding
- * the correct texture. */
-/* Context activation is done by the caller. */
-static void surface_allocate_surface(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
-        const struct wined3d_format *format, BOOL srgb)
-{
-    BOOL disable_client_storage = FALSE;
-    GLsizei width = surface->pow2Width;
-    GLsizei height = surface->pow2Height;
-    const BYTE *mem = NULL;
-    GLenum internal;
-
-    if (srgb)
-        internal = format->glGammaInternal;
-    else if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET
-            && wined3d_resource_is_offscreen(&surface->container->resource))
-        internal = format->rtInternal;
-    else
-        internal = format->glInternal;
-
-    if (!internal)
-        FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
-
-    if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
-    {
-        height *= format->height_scale.numerator;
-        height /= format->height_scale.denominator;
-    }
-
-    TRACE("(%p) : Creating surface (target %#x)  level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n",
-            surface, surface->texture_target, surface->texture_level, debug_d3dformat(format->id),
-            internal, width, height, format->glFormat, format->glType);
-
-    if (gl_info->supported[APPLE_CLIENT_STORAGE])
-    {
-        if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_CONVERTED)
-                || !surface->resource.heap_memory)
-        {
-            /* In some cases we want to disable client storage.
-             * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches
-             * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues...
-             * SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface
-             * heap_memory == NULL: Not defined in the extension. Seems to disable client storage effectively
-             */
-            surface->flags &= ~SFLAG_CLIENT;
-        }
-        else
-        {
-            surface->flags |= SFLAG_CLIENT;
-            mem = surface->resource.heap_memory;
-
-            gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
-            checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
-            disable_client_storage = TRUE;
-        }
-    }
-
-    if (format->flags & WINED3DFMT_FLAG_COMPRESSED && mem)
-    {
-        GL_EXTCALL(glCompressedTexImage2DARB(surface->texture_target, surface->texture_level,
-                internal, width, height, 0, surface->resource.size, mem));
-        checkGLcall("glCompressedTexImage2DARB");
-    }
-    else
-    {
-        gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
-                internal, width, height, 0, format->glFormat, format->glType, mem);
-        checkGLcall("glTexImage2D");
-    }
-
-    if (disable_client_storage)
-    {
-        gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
-        checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
-    }
-}
-
 /* In D3D the depth stencil dimensions have to be greater than or equal to the
  * render target dimensions. With FBOs, the dimensions have to be an exact match. */
 /* TODO: We should synchronize the renderbuffer's content with the texture's content. */
@@ -2018,43 +1812,18 @@ GLenum surface_get_gl_buffer(const struct wined3d_surface *surface)
 void surface_load(struct wined3d_surface *surface, BOOL srgb)
 {
     DWORD location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
-    BOOL ck_changed;
 
     TRACE("surface %p, srgb %#x.\n", surface, srgb);
 
     if (surface->resource.pool == WINED3D_POOL_SCRATCH)
         ERR("Not supported on scratch surfaces.\n");
 
-    ck_changed = !(surface->flags & SFLAG_GLCKEY) != !(surface->container->color_key_flags & WINEDDSD_CKSRCBLT);
-
-    /* Reload if either the texture and sysmem have different ideas about the
-     * color key, or the actual key values changed. */
-    if (ck_changed || ((surface->container->color_key_flags & WINEDDSD_CKSRCBLT)
-            && (surface->gl_color_key.color_space_low_value
-            != surface->container->src_blt_color_key.color_space_low_value
-            || surface->gl_color_key.color_space_high_value
-            != surface->container->src_blt_color_key.color_space_high_value)))
-    {
-        TRACE("Reloading because of color keying\n");
-        /* To perform the color key conversion we need a sysmem copy of
-         * the surface. Make sure we have it. */
-
-        surface_prepare_map_memory(surface);
-        surface_load_location(surface, surface->resource.map_binding);
-        surface_invalidate_location(surface, ~surface->resource.map_binding);
-        /* Switching color keying on / off may change the internal format. */
-        if (ck_changed)
-            surface_force_reload(surface);
-    }
-    else if (!(surface->locations & location))
-    {
-        TRACE("Reloading because surface is dirty.\n");
-    }
-    else
+    if (surface->locations & location)
     {
         TRACE("surface is already in texture\n");
         return;
     }
+    TRACE("Reloading because surface is dirty.\n");
 
     surface_load_location(surface, location);
     surface_evict_sysmem(surface);
@@ -2361,35 +2130,14 @@ HRESULT CDECL wined3d_surface_update_overlay(struct wined3d_surface *surface, co
     return WINED3D_OK;
 }
 
-HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
-        UINT width, UINT height, enum wined3d_format_id format_id,
-        enum wined3d_multisample_type multisample_type, UINT multisample_quality,
-        void *mem, UINT pitch)
+HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface,
+        const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch)
 {
-    struct wined3d_device *device = surface->resource.device;
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
-    const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
-    UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
-    struct wined3d_texture *texture;
+    struct wined3d_resource *texture_resource = &surface->container->resource;
+    unsigned int width, height;
     BOOL create_dib = FALSE;
-    HRESULT hr;
     DWORD valid_location = 0;
-
-    TRACE("surface %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, "
-            "mem %p, pitch %u.\n",
-            surface, width, height, debug_d3dformat(format_id), multisample_type, multisample_type, mem, pitch);
-
-    if (!resource_size)
-        return WINED3DERR_INVALIDCALL;
-
-    if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE))
-    {
-        WARN("Surface is mapped or the DC is in use.\n");
-        return WINED3DERR_INVALIDCALL;
-    }
-
-    if (device->d3d_initialized)
-        surface->resource.resource_ops->resource_unload(&surface->resource);
+    HRESULT hr;
 
     if (surface->flags & SFLAG_DIBSECTION)
     {
@@ -2403,6 +2151,8 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
     surface->locations = 0;
     wined3d_resource_free_sysmem(&surface->resource);
 
+    width = texture_resource->width;
+    height = texture_resource->height;
     surface->resource.width = width;
     surface->resource.height = height;
     if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[ARB_TEXTURE_RECTANGLE]
@@ -2425,20 +2175,26 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
     else
         surface->flags &= ~SFLAG_NONPOW2;
 
-    surface->user_memory = mem;
-    if (surface->user_memory)
+    if ((surface->user_memory = mem))
     {
         surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
         valid_location = WINED3D_LOCATION_USER_MEMORY;
     }
     surface->pitch = pitch;
-    surface->resource.format = format;
-    surface->resource.multisample_type = multisample_type;
-    surface->resource.multisample_quality = multisample_quality;
+    surface->resource.format = texture_resource->format;
+    surface->resource.multisample_type = texture_resource->multisample_type;
+    surface->resource.multisample_quality = texture_resource->multisample_quality;
     if (surface->pitch)
+    {
         surface->resource.size = height * surface->pitch;
+    }
     else
-        surface->resource.size = resource_size;
+    {
+        /* User memory surfaces don't have the regular surface alignment. */
+        surface->resource.size = wined3d_format_calculate_size(texture_resource->format,
+                1, width, height, 1);
+        surface->pitch = wined3d_format_calculate_pitch(texture_resource->format, width);
+    }
 
     /* The format might be changed to a format that needs conversion.
      * If the surface didn't use PBOs previously but could now, don't
@@ -2447,13 +2203,6 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
     if (surface->resource.map_binding == WINED3D_LOCATION_BUFFER && !surface_use_pbo(surface))
         surface->resource.map_binding = create_dib ? WINED3D_LOCATION_DIB : WINED3D_LOCATION_SYSMEM;
 
-    texture = surface->container;
-    texture->resource.format = format;
-    texture->resource.multisample_type = multisample_type;
-    texture->resource.multisample_quality = multisample_quality;
-    texture->resource.width = width;
-    texture->resource.height = height;
-
     if (create_dib)
     {
         if (FAILED(hr = surface_create_dib_section(surface)))
@@ -2645,6 +2394,126 @@ static void convert_yuy2_r5g6b5(const BYTE *src, BYTE *dst,
     }
 }
 
+static void convert_dxt1_a8r8g8b8(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h);
+}
+
+static void convert_dxt1_x8r8g8b8(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h);
+}
+
+static void convert_dxt1_a4r4g4b4(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h);
+}
+
+static void convert_dxt1_x4r4g4b4(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h);
+}
+
+static void convert_dxt1_a1r5g5b5(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h);
+}
+
+static void convert_dxt1_x1r5g5b5(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h);
+}
+
+static void convert_dxt3_a8r8g8b8(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h);
+}
+
+static void convert_dxt3_x8r8g8b8(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h);
+}
+
+static void convert_dxt3_a4r4g4b4(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h);
+}
+
+static void convert_dxt3_x4r4g4b4(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h);
+}
+
+static void convert_dxt5_a8r8g8b8(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt5_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h);
+}
+
+static void convert_dxt5_x8r8g8b8(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt5_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h);
+}
+
+static void convert_a8r8g8b8_dxt1(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h);
+}
+
+static void convert_x8r8g8b8_dxt1(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h);
+}
+
+static void convert_a1r5g5b5_dxt1(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h);
+}
+
+static void convert_x1r5g5b5_dxt1(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h);
+}
+
+static void convert_a8r8g8b8_dxt3(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt3_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h);
+}
+
+static void convert_x8r8g8b8_dxt3(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt3_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h);
+}
+
+static void convert_a8r8g8b8_dxt5(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h);
+}
+
+static void convert_x8r8g8b8_dxt5(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h);
+}
+
 struct d3dfmt_converter_desc
 {
     enum wined3d_format_id from, to;
@@ -2661,6 +2530,33 @@ static const struct d3dfmt_converter_desc converters[] =
     {WINED3DFMT_YUY2,           WINED3DFMT_B5G6R5_UNORM,    convert_yuy2_r5g6b5},
 };
 
+static const struct d3dfmt_converter_desc dxtn_converters[] =
+{
+    /* decode DXT */
+    {WINED3DFMT_DXT1,           WINED3DFMT_B8G8R8A8_UNORM,  convert_dxt1_a8r8g8b8},
+    {WINED3DFMT_DXT1,           WINED3DFMT_B8G8R8X8_UNORM,  convert_dxt1_x8r8g8b8},
+    {WINED3DFMT_DXT1,           WINED3DFMT_B4G4R4A4_UNORM,  convert_dxt1_a4r4g4b4},
+    {WINED3DFMT_DXT1,           WINED3DFMT_B4G4R4X4_UNORM,  convert_dxt1_x4r4g4b4},
+    {WINED3DFMT_DXT1,           WINED3DFMT_B5G5R5A1_UNORM,  convert_dxt1_a1r5g5b5},
+    {WINED3DFMT_DXT1,           WINED3DFMT_B5G5R5X1_UNORM,  convert_dxt1_x1r5g5b5},
+    {WINED3DFMT_DXT3,           WINED3DFMT_B8G8R8A8_UNORM,  convert_dxt3_a8r8g8b8},
+    {WINED3DFMT_DXT3,           WINED3DFMT_B8G8R8X8_UNORM,  convert_dxt3_x8r8g8b8},
+    {WINED3DFMT_DXT3,           WINED3DFMT_B4G4R4A4_UNORM,  convert_dxt3_a4r4g4b4},
+    {WINED3DFMT_DXT3,           WINED3DFMT_B4G4R4X4_UNORM,  convert_dxt3_x4r4g4b4},
+    {WINED3DFMT_DXT5,           WINED3DFMT_B8G8R8A8_UNORM,  convert_dxt5_a8r8g8b8},
+    {WINED3DFMT_DXT5,           WINED3DFMT_B8G8R8X8_UNORM,  convert_dxt5_x8r8g8b8},
+
+    /* encode DXT */
+    {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT1,            convert_a8r8g8b8_dxt1},
+    {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT1,            convert_x8r8g8b8_dxt1},
+    {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_DXT1,            convert_a1r5g5b5_dxt1},
+    {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_DXT1,            convert_x1r5g5b5_dxt1},
+    {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT3,            convert_a8r8g8b8_dxt3},
+    {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT3,            convert_x8r8g8b8_dxt3},
+    {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT5,            convert_a8r8g8b8_dxt5},
+    {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT5,            convert_x8r8g8b8_dxt5}
+};
+
 static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from,
         enum wined3d_format_id to)
 {
@@ -2672,6 +2568,12 @@ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_fo
             return &converters[i];
     }
 
+    for (i = 0; i < (sizeof(dxtn_converters) / sizeof(*dxtn_converters)); ++i)
+    {
+        if (dxtn_converters[i].from == from && dxtn_converters[i].to == to)
+            return wined3d_dxtn_supported() ? &dxtn_converters[i] : NULL;
+    }
+
     return NULL;
 }
 
@@ -2698,7 +2600,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_surface *so
     desc.usage = 0;
     desc.pool = WINED3D_POOL_SCRATCH;
     if (FAILED(wined3d_texture_create(source->resource.device, &desc, 1,
-            WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, &wined3d_null_parent_ops, &ret)))
+            WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, NULL, &wined3d_null_parent_ops, &ret)))
     {
         ERR("Failed to create a destination surface for conversion.\n");
         return NULL;
@@ -2846,13 +2748,15 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface,
     /* Performance optimization: Count how often a surface is mapped, if it is
      * mapped regularly do not throw away the system memory copy. This avoids
      * the need to download the surface from OpenGL all the time. The surface
-     * is still downloaded if the OpenGL texture is changed. */
-    if (!(surface->flags & SFLAG_DYNLOCK) && surface->resource.map_binding == WINED3D_LOCATION_SYSMEM)
+     * is still downloaded if the OpenGL texture is changed. Note that this
+     * only really makes sense for managed textures.*/
+    if (!(surface->container->flags & WINED3D_TEXTURE_DYNAMIC_MAP)
+            && surface->resource.map_binding == WINED3D_LOCATION_SYSMEM)
     {
         if (++surface->lockCount > MAXLOCKCOUNT)
         {
             TRACE("Surface is mapped regularly, not freeing the system memory copy any more.\n");
-            surface->flags |= SFLAG_DYNLOCK;
+            surface->container->flags |= WINED3D_TEXTURE_DYNAMIC_MAP;
         }
     }
 
@@ -2892,9 +2796,9 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface,
             context = context_acquire(device, NULL);
             gl_info = context->gl_info;
 
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
-            base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo));
+            base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE));
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
             checkGLcall("map PBO");
 
             context_release(context);
@@ -2973,7 +2877,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
         if (FAILED(hr))
             return WINED3DERR_INVALIDCALL;
         if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
-                || surface->flags & SFLAG_PIN_SYSMEM
+                || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
                 || surface->pbo))
             surface->resource.map_binding = WINED3D_LOCATION_DIB;
     }
@@ -3007,7 +2911,8 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
     surface->resource.map_count--;
     surface->flags &= ~SFLAG_DCINUSE;
 
-    if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY || (surface->flags & SFLAG_PIN_SYSMEM
+    if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
+            || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
             && surface->resource.map_binding != WINED3D_LOCATION_DIB))
     {
         /* The game Salammbo modifies the surface contents without mapping the surface between
@@ -3065,12 +2970,13 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
 
     if (data.buffer_object)
     {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data.buffer_object));
-        checkGLcall("glBindBufferARB");
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object));
+        checkGLcall("glBindBuffer");
     }
 
     /* Setup pixel store pack state -- to glReadPixels into the correct place */
-    gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, surface->resource.width);
+    gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH,
+            wined3d_surface_get_pitch(surface) / surface->resource.format->byte_count);
     checkGLcall("glPixelStorei");
 
     gl_info->gl_ops.gl.p_glReadPixels(0, 0,
@@ -3094,8 +3000,8 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
 
         if (data.buffer_object)
         {
-            mem = GL_EXTCALL(glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_WRITE_ARB));
-            checkGLcall("glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_WRITE_ARB)");
+            mem = GL_EXTCALL(glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE));
+            checkGLcall("glMapBuffer");
         }
         else
             mem = data.addr;
@@ -3113,14 +3019,14 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
         HeapFree(GetProcessHeap(), 0, row);
 
         if (data.buffer_object)
-            GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB));
+            GL_EXTCALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
     }
 
 error:
     if (data.buffer_object)
     {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
-        checkGLcall("glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)");
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+        checkGLcall("glBindBuffer");
     }
 
     context_release(context);
@@ -3139,7 +3045,7 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb)
     gl_info = context->gl_info;
     device_invalidate_state(device, STATE_FRAMEBUFFER);
 
-    surface_prepare_texture(surface, context, srgb);
+    wined3d_texture_prepare_texture(surface->container, context, srgb);
     wined3d_texture_bind_and_dirtify(surface->container, context, srgb);
 
     TRACE("Reading back offscreen render target %p.\n", surface);
@@ -3157,44 +3063,6 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb)
     context_release(context);
 }
 
-/* Context activation is done by the caller. */
-static void surface_prepare_texture_internal(struct wined3d_surface *surface,
-        struct wined3d_context *context, BOOL srgb)
-{
-    DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
-    enum wined3d_conversion_type convert;
-    struct wined3d_format format;
-
-    if (surface->flags & alloc_flag) return;
-
-    d3dfmt_get_conv(surface, TRUE, TRUE, &format, &convert);
-    if (convert != WINED3D_CT_NONE || format.convert)
-        surface->flags |= SFLAG_CONVERTED;
-    else surface->flags &= ~SFLAG_CONVERTED;
-
-    wined3d_texture_bind_and_dirtify(surface->container, context, srgb);
-    surface_allocate_surface(surface, context->gl_info, &format, srgb);
-    surface->flags |= alloc_flag;
-}
-
-/* Context activation is done by the caller. */
-void surface_prepare_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb)
-{
-    struct wined3d_texture *texture = surface->container;
-    UINT sub_count = texture->level_count * texture->layer_count;
-    UINT i;
-
-    TRACE("surface %p is a subresource of texture %p.\n", surface, texture);
-
-    for (i = 0; i < sub_count; ++i)
-    {
-        struct wined3d_surface *s = surface_from_resource(texture->sub_resources[i]);
-        surface_prepare_texture_internal(s, context, srgb);
-    }
-
-    return;
-}
-
 void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample)
 {
     if (multisample)
@@ -3221,190 +3089,6 @@ void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl
     }
 }
 
-static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD color)
-{
-    /* FIXME: Is this really how color keys are supposed to work? I think it
-     * makes more sense to compare the individual channels. */
-    return color >= color_key->color_space_low_value
-            && color <= color_key->color_space_high_value;
-}
-
-static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height,
-        UINT outpitch, enum wined3d_conversion_type conversion_type, struct wined3d_surface *surface)
-{
-    const BYTE *source;
-    BYTE *dest;
-
-    TRACE("src %p, dst %p, pitch %u, width %u, height %u, outpitch %u, conversion_type %#x, surface %p.\n",
-            src, dst, pitch, width, height, outpitch, conversion_type, surface);
-
-    switch (conversion_type)
-    {
-        case WINED3D_CT_NONE:
-        {
-            memcpy(dst, src, pitch * height);
-            break;
-        }
-
-        case WINED3D_CT_PALETTED:
-            if (surface->container->swapchain && surface->container->swapchain->palette)
-            {
-                unsigned int x, y;
-                const struct wined3d_palette *palette = surface->container->swapchain->palette;
-                for (y = 0; y < height; y++)
-                {
-                    source = src + pitch * y;
-                    dest = dst + outpitch * y;
-                    for (x = 0; x < width; x++)
-                    {
-                        BYTE color = *source++;
-                        *dest++ = palette->colors[color].rgbRed;
-                        *dest++ = palette->colors[color].rgbGreen;
-                        *dest++ = palette->colors[color].rgbBlue;
-                        *dest++ = 0;
-                    }
-                }
-            }
-            else
-            {
-                /* This should probably use the system palette, but unless
-                 * the X server is running in P8 mode there is no such thing.
-                 * The probably best solution is to set the fixed 20 colors
-                 * from the default windows palette and set the rest to black,
-                 * white, or some ugly pink. For now use black for the entire
-                 * palette. Don't use pink everywhere. Age of Empires 2 draws
-                 * a front buffer filled with zeroes without a palette when
-                 * starting and we don't want the screen to flash in an ugly
-                 * color. */
-                FIXME("P8 surface loaded without a palette.\n");
-                memset(dst, 0, height * outpitch);
-            }
-
-            break;
-
-        case WINED3D_CT_CK_565:
-        {
-            /* Converting the 565 format in 5551 packed to emulate color-keying.
-
-              Note : in all these conversion, it would be best to average the averaging
-                      pixels to get the color of the pixel that will be color-keyed to
-                      prevent 'color bleeding'. This will be done later on if ever it is
-                      too visible.
-
-              Note2: Nvidia documents say that their driver does not support alpha + color keying
-                     on the same surface and disables color keying in such a case
-            */
-            unsigned int x, y;
-            const WORD *Source;
-            WORD *Dest;
-
-            TRACE("Color keyed 565\n");
-
-            for (y = 0; y < height; y++) {
-                Source = (const WORD *)(src + y * pitch);
-                Dest = (WORD *) (dst + y * outpitch);
-                for (x = 0; x < width; x++ ) {
-                    WORD color = *Source++;
-                    *Dest = ((color & 0xffc0) | ((color & 0x1f) << 1));
-                    if (!color_in_range(&surface->container->src_blt_color_key, color))
-                        *Dest |= 0x0001;
-                    Dest++;
-                }
-            }
-        }
-        break;
-
-        case WINED3D_CT_CK_5551:
-        {
-            /* Converting X1R5G5B5 format to R5G5B5A1 to emulate color-keying. */
-            unsigned int x, y;
-            const WORD *Source;
-            WORD *Dest;
-            TRACE("Color keyed 5551\n");
-            for (y = 0; y < height; y++) {
-                Source = (const WORD *)(src + y * pitch);
-                Dest = (WORD *) (dst + y * outpitch);
-                for (x = 0; x < width; x++ ) {
-                    WORD color = *Source++;
-                    *Dest = color;
-                    if (!color_in_range(&surface->container->src_blt_color_key, color))
-                        *Dest |= (1 << 15);
-                    else
-                        *Dest &= ~(1 << 15);
-                    Dest++;
-                }
-            }
-        }
-        break;
-
-        case WINED3D_CT_CK_RGB24:
-        {
-            /* Converting R8G8B8 format to R8G8B8A8 with color-keying. */
-            unsigned int x, y;
-            for (y = 0; y < height; y++)
-            {
-                source = src + pitch * y;
-                dest = dst + outpitch * y;
-                for (x = 0; x < width; x++) {
-                    DWORD color = ((DWORD)source[0] << 16) + ((DWORD)source[1] << 8) + (DWORD)source[2] ;
-                    DWORD dstcolor = color << 8;
-                    if (!color_in_range(&surface->container->src_blt_color_key, color))
-                        dstcolor |= 0xff;
-                    *(DWORD*)dest = dstcolor;
-                    source += 3;
-                    dest += 4;
-                }
-            }
-        }
-        break;
-
-        case WINED3D_CT_RGB32_888:
-        {
-            /* Converting X8R8G8B8 format to R8G8B8A8 with color-keying. */
-            unsigned int x, y;
-            for (y = 0; y < height; y++)
-            {
-                source = src + pitch * y;
-                dest = dst + outpitch * y;
-                for (x = 0; x < width; x++) {
-                    DWORD color = 0xffffff & *(const DWORD*)source;
-                    DWORD dstcolor = color << 8;
-                    if (!color_in_range(&surface->container->src_blt_color_key, color))
-                        dstcolor |= 0xff;
-                    *(DWORD*)dest = dstcolor;
-                    source += 4;
-                    dest += 4;
-                }
-            }
-        }
-        break;
-
-        case WINED3D_CT_CK_ARGB32:
-        {
-            unsigned int x, y;
-            for (y = 0; y < height; ++y)
-            {
-                source = src + pitch * y;
-                dest = dst + outpitch * y;
-                for (x = 0; x < width; ++x)
-                {
-                    DWORD color = *(const DWORD *)source;
-                    if (color_in_range(&surface->container->src_blt_color_key, color))
-                        color &= ~0xff000000;
-                    *(DWORD*)dest = color;
-                    source += 4;
-                    dest += 4;
-                }
-            }
-        }
-        break;
-
-        default:
-            ERR("Unsupported conversion type %#x.\n", conversion_type);
-    }
-    return WINED3D_OK;
-}
-
 void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back)
 {
     if (front->container->level_count != 1 || front->container->layer_count != 1
@@ -3687,11 +3371,10 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
     checkGLcall("glCopyTexSubImage2D");
 
     /* No issue with overriding these - the sampler is dirty due to blit usage */
-    gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER,
-            wined3d_gl_mag_filter(magLookup, filter));
+    gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter));
     checkGLcall("glTexParameteri");
     gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER,
-            wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE));
+            wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE));
     checkGLcall("glTexParameteri");
 
     if (!src_surface->container->swapchain
@@ -3747,7 +3430,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
         bottom = src_surface->resource.height - src_rect->top;
     }
 
-    if (src_surface->flags & SFLAG_NORMCOORD)
+    if (src_surface->container->flags & WINED3D_TEXTURE_NORMALIZED_COORDS)
     {
         left /= src_surface->pow2Width;
         right /= src_surface->pow2Width;
@@ -3756,8 +3439,8 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
     }
 
     /* draw the source texture stretched and upside down. The correct surface is bound already */
-    gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
-    gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+    gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
     context_set_draw_buffer(context, drawBuffer);
     gl_info->gl_ops.gl.p_glReadBuffer(drawBuffer);
@@ -3932,7 +3615,7 @@ static void surface_blt_to_drawable(const struct wined3d_device *device,
          * other cases pixels that should be masked away have alpha set to 0. */
         if (src_surface->resource.format->id == WINED3DFMT_P8_UINT)
             gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL,
-                    (float)src_surface->container->src_blt_color_key.color_space_low_value / 256.0f);
+                    (float)src_surface->container->src_blt_color_key.color_space_low_value / 255.0f);
         else
             gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f);
         checkGLcall("glAlphaFunc");
@@ -4135,13 +3818,12 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
         else if (flags & WINEDDBLT_KEYSRCOVERRIDE)
         {
             /* Use color key from DDBltFx */
-            src_surface->container->color_key_flags |= WINEDDSD_CKSRCBLT;
-            src_surface->container->src_blt_color_key = DDBltFx->ddckSrcColorkey;
+            wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, &DDBltFx->ddckSrcColorkey);
         }
         else
         {
             /* Do not use color key */
-            src_surface->container->color_key_flags &= ~WINEDDSD_CKSRCBLT;
+            wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, NULL);
         }
 
         surface_blt_to_drawable(device, filter,
@@ -4149,8 +3831,8 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
                 src_surface, src_rect, dst_surface, dst_rect);
 
         /* Restore the color key parameters */
-        src_surface->container->color_key_flags = old_color_key_flags;
-        src_surface->container->src_blt_color_key = old_blt_key;
+        wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT,
+                (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL);
 
         surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding);
         surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding);
@@ -4281,7 +3963,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co
         switch (location)
         {
             case WINED3D_LOCATION_TEXTURE_RGB:
-                surface_prepare_texture(surface, context, FALSE);
+                wined3d_texture_prepare_texture(surface->container, context, FALSE);
                 break;
             case WINED3D_LOCATION_RB_MULTISAMPLE:
                 surface_prepare_rb(surface, gl_info, TRUE);
@@ -4453,9 +4135,9 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD
     {
         context = context_acquire(device, NULL);
         gl_info = context->gl_info;
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, dst.buffer_object));
-        GL_EXTCALL(glBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, size, src.addr));
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object));
+        GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
         checkGLcall("Upload PBO");
         context_release(context);
         return;
@@ -4464,9 +4146,9 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD
     {
         context = context_acquire(device, NULL);
         gl_info = context->gl_info;
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, src.buffer_object));
-        GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_PACK_BUFFER_ARB, 0, size, dst.addr));
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object));
+        GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
         checkGLcall("Download PBO");
         context_release(context);
         return;
@@ -4539,7 +4221,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
 {
     RECT src_rect = {0, 0, surface->resource.width, surface->resource.height};
     struct wined3d_device *device = surface->resource.device;
-    enum wined3d_conversion_type convert;
+    const struct wined3d_color_key_conversion *conversion;
+    struct wined3d_texture *texture = surface->container;
     struct wined3d_context *context;
     UINT width, src_pitch, dst_pitch;
     struct wined3d_bo_address data;
@@ -4548,7 +4231,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
     BYTE *mem = NULL;
 
     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
-            && wined3d_resource_is_offscreen(&surface->container->resource)
+            && wined3d_resource_is_offscreen(&texture->resource)
             && (surface->locations & WINED3D_LOCATION_DRAWABLE))
     {
         surface_load_fb_texture(surface, srgb);
@@ -4591,9 +4274,6 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
 
     /* Upload from system memory */
 
-    d3dfmt_get_conv(surface, TRUE /* We need color keying */,
-            TRUE /* We will use textures */, &format, &convert);
-
     if (srgb)
     {
         if ((surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding))
@@ -4628,23 +4308,20 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
     /* TODO: Use already acquired context when possible. */
     context = context_acquire(device, NULL);
 
-    surface_prepare_texture(surface, context, srgb);
-    wined3d_texture_bind_and_dirtify(surface->container, context, srgb);
-
-    if (surface->container->color_key_flags & WINEDDSD_CKSRCBLT)
-    {
-        surface->flags |= SFLAG_GLCKEY;
-        surface->gl_color_key = surface->container->src_blt_color_key;
-    }
-    else surface->flags &= ~SFLAG_GLCKEY;
+    wined3d_texture_prepare_texture(texture, context, srgb);
+    wined3d_texture_bind_and_dirtify(texture, context, srgb);
 
     width = surface->resource.width;
     src_pitch = wined3d_surface_get_pitch(surface);
 
+    format = *texture->resource.format;
+    if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
+        format = *wined3d_get_format(gl_info, conversion->dst_format);
+
     /* Don't use PBOs for converted surfaces. During PBO conversion we look at
-     * SFLAG_CONVERTED but it isn't set (yet) in all cases it is getting
-     * called. */
-    if ((convert != WINED3D_CT_NONE || format.convert) && surface->pbo)
+     * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is
+     * getting called. */
+    if ((format.convert || conversion) && surface->pbo)
     {
         TRACE("Removing the pbo attached to surface %p.\n", surface);
 
@@ -4664,9 +4341,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
         /* This code is entered for texture formats which need a fixup. */
         UINT height = surface->resource.height;
 
-        /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
-        dst_pitch = width * format.conv_byte_count;
-        dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
+        format.byte_count = format.conv_byte_count;
+        dst_pitch = wined3d_format_calculate_pitch(&format, width);
 
         if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
         {
@@ -4676,17 +4352,16 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
         }
         format.convert(data.addr, mem, src_pitch, src_pitch * height,
                 dst_pitch, dst_pitch * height, width, height, 1);
-        format.byte_count = format.conv_byte_count;
         src_pitch = dst_pitch;
         data.addr = mem;
     }
-    else if (convert != WINED3D_CT_NONE)
+    else if (conversion)
     {
         /* This code is only entered for color keying fixups */
+        struct wined3d_palette *palette = NULL;
         UINT height = surface->resource.height;
 
-        /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
-        dst_pitch = width * format.conv_byte_count;
+        dst_pitch = wined3d_format_calculate_pitch(&format, width);
         dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
 
         if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
@@ -4695,14 +4370,16 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
             context_release(context);
             return E_OUTOFMEMORY;
         }
-        d3dfmt_convert_surface(data.addr, mem, src_pitch,
-                width, height, dst_pitch, convert, surface);
-        format.byte_count = format.conv_byte_count;
+        if (texture->swapchain && texture->swapchain->palette)
+            palette = texture->swapchain->palette;
+        conversion->convert(data.addr, src_pitch, mem, dst_pitch,
+                width, height, palette, &texture->gl_color_key);
         src_pitch = dst_pitch;
         data.addr = mem;
     }
 
-    surface_upload_data(surface, gl_info, &format, &src_rect, src_pitch, &dst_point, srgb, &data);
+    wined3d_surface_upload_data(surface, gl_info, &format, &src_rect,
+            src_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
 
     context_release(context);
 
@@ -5624,8 +5301,6 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
     DWORD src_ds_flags, dst_ds_flags;
     RECT src_rect, dst_rect;
     BOOL scale, convert;
-    enum wined3d_conversion_type dst_convert_type;
-    struct wined3d_format dst_conv_fmt;
 
     static const DWORD simple_blit = WINEDDBLT_ASYNC
             | WINEDDBLT_COLORFILL
@@ -5740,8 +5415,9 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
     /* We want to avoid invalidating the sysmem location for converted
      * surfaces, since otherwise we'd have to convert the data back when
      * locking them. */
-    d3dfmt_get_conv(dst_surface, TRUE, TRUE, &dst_conv_fmt, &dst_convert_type);
-    if (dst_convert_type != WINED3D_CT_NONE || dst_conv_fmt.convert || dst_surface->flags & SFLAG_CONVERTED)
+    if (dst_surface->container->flags & WINED3D_TEXTURE_CONVERTED
+            || dst_surface->container->resource.format->convert
+            || wined3d_format_get_color_key_conversion(dst_surface->container, TRUE))
     {
         WARN_(d3d_perf)("Converted surface, using CPU blit.\n");
         goto cpu;
@@ -5995,12 +5671,8 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text
     list_init(&surface->overlays);
 
     /* Flags */
-    if (target != GL_TEXTURE_RECTANGLE_ARB)
-        surface->flags |= SFLAG_NORMCOORD;
     if (flags & WINED3D_SURFACE_DISCARD)
         surface->flags |= SFLAG_DISCARD;
-    if (flags & WINED3D_SURFACE_PIN_SYSMEM)
-        surface->flags |= SFLAG_PIN_SYSMEM;
     if (lockable || desc->format == WINED3DFMT_D16_LOCKABLE)
         surface->resource.access_flags |= WINED3D_RESOURCE_ACCESS_CPU;
 
index 276fa36..d919572 100644 (file)
@@ -134,12 +134,17 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
         const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
         const RGNDATA *dirty_region, DWORD flags)
 {
+    static DWORD notified_flags = 0;
+
     TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
             swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
             dst_window_override, dirty_region, flags);
 
-    if (flags)
-        FIXME("Ignoring flags %#x.\n", flags);
+    if (flags & ~notified_flags)
+    {
+        FIXME("Ignoring flags %#x.\n", flags & ~notified_flags);
+        notified_flags |= flags;
+    }
 
     if (!swapchain->back_buffers)
     {
@@ -347,7 +352,7 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
         context2 = context_acquire(device, backbuffer);
         context_apply_blit_state(context2, device);
 
-        if (backbuffer->flags & SFLAG_NORMCOORD)
+        if (backbuffer->container->flags & WINED3D_TEXTURE_NORMALIZED_COORDS)
         {
             tex_left /= src_w;
             tex_right /= src_w;
@@ -873,16 +878,14 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
 
     if (!desc->windowed)
     {
-        struct wined3d_display_mode mode;
-
         /* Change the display settings */
-        mode.width = desc->backbuffer_width;
-        mode.height = desc->backbuffer_height;
-        mode.format_id = desc->backbuffer_format;
-        mode.refresh_rate = desc->refresh_rate;
-        mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+        swapchain->d3d_mode.width = desc->backbuffer_width;
+        swapchain->d3d_mode.height = desc->backbuffer_height;
+        swapchain->d3d_mode.format_id = desc->backbuffer_format;
+        swapchain->d3d_mode.refresh_rate = desc->refresh_rate;
+        swapchain->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
 
-        if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &mode)))
+        if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &swapchain->d3d_mode)))
         {
             WARN("Failed to set display mode, hr %#x.\n", hr);
             goto err;
@@ -1173,3 +1176,54 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain)
         wined3d_resource_update_draw_binding(&swapchain->back_buffers[i]->resource);
     }
 }
+
+void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate)
+{
+    struct wined3d_device *device = swapchain->device;
+    BOOL filter_messages = device->filter_messages;
+
+    /* This code is not protected by the wined3d mutex, so it may run while
+     * wined3d_device_reset is active. Testing on Windows shows that changing
+     * focus during resets and resetting during focus change events causes
+     * the application to crash with an invalid memory access. */
+
+    device->filter_messages = !(device->wined3d->flags & WINED3D_FOCUS_MESSAGES);
+
+    if (activate)
+    {
+        if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES))
+        {
+            /* The d3d versions do not agree on the exact messages here. D3d8 restores
+             * the window but leaves the size untouched, d3d9 sets the size on an
+             * invisible window, generates messages but doesn't change the window
+             * properties. The implementation follows d3d9.
+             *
+             * Guild Wars 1 wants a WINDOWPOSCHANGED message on the device window to
+             * resume drawing after a focus loss. */
+            SetWindowPos(swapchain->device_window, NULL, 0, 0,
+                    swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height,
+                    SWP_NOACTIVATE | SWP_NOZORDER);
+        }
+
+        if (device->wined3d->flags & WINED3D_RESTORE_MODE_ON_ACTIVATE)
+        {
+            if (FAILED(wined3d_set_adapter_display_mode(device->wined3d,
+                    device->adapter->ordinal, &swapchain->d3d_mode)))
+                ERR("Failed to set display mode.\n");
+        }
+    }
+    else
+    {
+        if (FAILED(wined3d_set_adapter_display_mode(device->wined3d,
+                device->adapter->ordinal, NULL)))
+            ERR("Failed to set display mode.\n");
+
+        swapchain->reapply_mode = TRUE;
+
+        if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES)
+                && IsWindowVisible(swapchain->device_window))
+            ShowWindow(swapchain->device_window, SW_MINIMIZE);
+    }
+
+    device->filter_messages = filter_messages;
+}
index fb8425c..54ad91b 100644 (file)
@@ -26,19 +26,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
 static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops,
-        UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, struct wined3d_device *device,
-        void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops)
+        UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD surface_flags,
+        struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops,
+        const struct wined3d_resource_ops *resource_ops)
 {
     const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format);
     HRESULT hr;
 
     TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
             "multisample_type %#x, multisample_quality %#x, usage %s, pool %s, width %u, height %u, depth %u, "
-            "device %p, parent %p, parent_ops %p, resource_ops %p.\n",
+            "surface_flags %#x, device %p, parent %p, parent_ops %p, resource_ops %p.\n",
             texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type),
             debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality,
             debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth,
-            device, parent, parent_ops, resource_ops);
+            surface_flags, device, parent, parent_ops, resource_ops);
 
     if ((format->flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BLOCKS_NO_VERIFY)) == WINED3DFMT_FLAG_BLOCKS)
     {
@@ -78,18 +79,9 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
     texture->level_count = level_count;
     texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE;
     texture->lod = 0;
-    texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT;
-
-    if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING)
-    {
-        texture->min_mip_lookup = minMipLookup;
-        texture->mag_lookup = magLookup;
-    }
-    else
-    {
-        texture->min_mip_lookup = minMipLookup_noFilter;
-        texture->mag_lookup = magLookup_noFilter;
-    }
+    texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS;
+    if (surface_flags & WINED3D_SURFACE_PIN_SYSMEM)
+        texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM;
 
     return WINED3D_OK;
 }
@@ -202,20 +194,24 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
 
     /* Initialise the state of the texture object to the OpenGL defaults, not
      * the wined3d defaults. */
-    gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_WRAP;
-    gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_WRAP;
-    gl_tex->states[WINED3DTEXSTA_ADDRESSW] = WINED3D_TADDRESS_WRAP;
-    gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = 0;
-    gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_LINEAR;
-    gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
-    gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
-    gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
-    gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
+    gl_tex->sampler_desc.address_u = WINED3D_TADDRESS_WRAP;
+    gl_tex->sampler_desc.address_v = WINED3D_TADDRESS_WRAP;
+    gl_tex->sampler_desc.address_w = WINED3D_TADDRESS_WRAP;
+    memset(gl_tex->sampler_desc.border_color, 0, sizeof(gl_tex->sampler_desc.border_color));
+    gl_tex->sampler_desc.mag_filter = WINED3D_TEXF_LINEAR;
+    gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
+    gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
+    gl_tex->sampler_desc.lod_bias = 0.0f;
+    gl_tex->sampler_desc.min_lod = -1000.0f;
+    gl_tex->sampler_desc.max_lod = 1000.0f;
+    gl_tex->sampler_desc.max_anisotropy = 1;
+    gl_tex->sampler_desc.compare = FALSE;
+    gl_tex->sampler_desc.comparison_func = WINED3D_CMP_LESSEQUAL;
     if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
-        gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = TRUE;
+        gl_tex->sampler_desc.srgb_decode = TRUE;
     else
-        gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = srgb;
-    gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
+        gl_tex->sampler_desc.srgb_decode = srgb;
+    gl_tex->base_level = 0;
     wined3d_texture_set_dirty(texture);
 
     context_bind_texture(context, target, gl_tex->name);
@@ -262,11 +258,11 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
         gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         checkGLcall("glTexParameteri");
-        gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_CLAMP;
-        gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_CLAMP;
-        gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT;
-        gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT;
-        gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE;
+        gl_tex->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP;
+        gl_tex->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP;
+        gl_tex->sampler_desc.mag_filter = WINED3D_TEXF_POINT;
+        gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT;
+        gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_NONE;
     }
 }
 
@@ -292,190 +288,106 @@ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture,
     wined3d_texture_bind(texture, context, srgb);
 }
 
-/* Context activation is done by the caller. */
-static void apply_wrap(const struct wined3d_gl_info *gl_info, GLenum target,
-        enum wined3d_texture_address d3d_wrap, GLenum param, BOOL cond_np2)
-{
-    GLint gl_wrap;
-
-    if (d3d_wrap < WINED3D_TADDRESS_WRAP || d3d_wrap > WINED3D_TADDRESS_MIRROR_ONCE)
-    {
-        FIXME("Unrecognized or unsupported texture address mode %#x.\n", d3d_wrap);
-        return;
-    }
-
-    /* Cubemaps are always set to clamp, regardless of the sampler state. */
-    if (target == GL_TEXTURE_CUBE_MAP_ARB
-            || (cond_np2 && d3d_wrap == WINED3D_TADDRESS_WRAP))
-        gl_wrap = GL_CLAMP_TO_EDGE;
-    else
-        gl_wrap = gl_info->wrap_lookup[d3d_wrap - WINED3D_TADDRESS_WRAP];
-
-    TRACE("Setting param %#x to %#x for target %#x.\n", param, gl_wrap, target);
-    gl_info->gl_ops.gl.p_glTexParameteri(target, param, gl_wrap);
-    checkGLcall("glTexParameteri(target, param, gl_wrap)");
-}
-
 /* Context activation is done by the caller (state handler). */
-void wined3d_texture_apply_state_changes(struct wined3d_texture *texture,
-        const DWORD sampler_states[WINED3D_HIGHEST_SAMPLER_STATE + 1],
-        const struct wined3d_gl_info *gl_info)
+/* This function relies on the correct texture being bound and loaded. */
+void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture,
+        const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info)
 {
-    BOOL cond_np2 = texture->flags & WINED3D_TEXTURE_COND_NP2;
     GLenum target = texture->target;
     struct gl_texture *gl_tex;
     DWORD state;
-    DWORD aniso;
 
-    TRACE("texture %p, sampler_states %p.\n", texture, sampler_states);
+    TRACE("texture %p, sampler_desc %p, gl_info %p.\n", texture, sampler_desc, gl_info);
 
     gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB);
 
-    /* This function relies on the correct texture being bound and loaded. */
-
-    if (sampler_states[WINED3D_SAMP_ADDRESS_U] != gl_tex->states[WINED3DTEXSTA_ADDRESSU])
+    state = sampler_desc->address_u;
+    if (state != gl_tex->sampler_desc.address_u)
     {
-        state = sampler_states[WINED3D_SAMP_ADDRESS_U];
-        apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_S, cond_np2);
-        gl_tex->states[WINED3DTEXSTA_ADDRESSU] = state;
+        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S,
+                gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
+        gl_tex->sampler_desc.address_u = state;
     }
 
-    if (sampler_states[WINED3D_SAMP_ADDRESS_V] != gl_tex->states[WINED3DTEXSTA_ADDRESSV])
+    state = sampler_desc->address_v;
+    if (state != gl_tex->sampler_desc.address_v)
     {
-        state = sampler_states[WINED3D_SAMP_ADDRESS_V];
-        apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_T, cond_np2);
-        gl_tex->states[WINED3DTEXSTA_ADDRESSV] = state;
+        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T,
+                gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
+        gl_tex->sampler_desc.address_v = state;
     }
 
-    if (sampler_states[WINED3D_SAMP_ADDRESS_W] != gl_tex->states[WINED3DTEXSTA_ADDRESSW])
+    state = sampler_desc->address_w;
+    if (state != gl_tex->sampler_desc.address_w)
     {
-        state = sampler_states[WINED3D_SAMP_ADDRESS_W];
-        apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_R, cond_np2);
-        gl_tex->states[WINED3DTEXSTA_ADDRESSW] = state;
+        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R,
+                gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
+        gl_tex->sampler_desc.address_w = state;
     }
 
-    if (sampler_states[WINED3D_SAMP_BORDER_COLOR] != gl_tex->states[WINED3DTEXSTA_BORDERCOLOR])
+    if (memcmp(gl_tex->sampler_desc.border_color, sampler_desc->border_color,
+            sizeof(gl_tex->sampler_desc.border_color)))
     {
-        float col[4];
-
-        state = sampler_states[WINED3D_SAMP_BORDER_COLOR];
-        D3DCOLORTOGLFLOAT4(state, col);
-        TRACE("Setting border color for %#x to %#x.\n", target, state);
-        gl_info->gl_ops.gl.p_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, &col[0]);
-        checkGLcall("glTexParameterfv(..., GL_TEXTURE_BORDER_COLOR, ...)");
-        gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = state;
+        gl_info->gl_ops.gl.p_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, &sampler_desc->border_color[0]);
+        memcpy(gl_tex->sampler_desc.border_color, sampler_desc->border_color,
+                sizeof(gl_tex->sampler_desc.border_color));
     }
 
-    if (sampler_states[WINED3D_SAMP_MAG_FILTER] != gl_tex->states[WINED3DTEXSTA_MAGFILTER])
+    state = sampler_desc->mag_filter;
+    if (state != gl_tex->sampler_desc.mag_filter)
     {
-        GLint gl_value;
-
-        state = sampler_states[WINED3D_SAMP_MAG_FILTER];
-        if (state > WINED3D_TEXF_ANISOTROPIC)
-            FIXME("Unrecognized or unsupported MAGFILTER* value %d.\n", state);
-
-        gl_value = wined3d_gl_mag_filter(texture->mag_lookup,
-                min(max(state, WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR));
-        TRACE("ValueMAG=%#x setting MAGFILTER to %#x.\n", state, gl_value);
-        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, gl_value);
-
-        gl_tex->states[WINED3DTEXSTA_MAGFILTER] = state;
+        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(state));
+        gl_tex->sampler_desc.mag_filter = state;
     }
 
-    if ((sampler_states[WINED3D_SAMP_MIN_FILTER] != gl_tex->states[WINED3DTEXSTA_MINFILTER]
-            || sampler_states[WINED3D_SAMP_MIP_FILTER] != gl_tex->states[WINED3DTEXSTA_MIPFILTER]
-            || sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL] != gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL]))
+    if (sampler_desc->min_filter != gl_tex->sampler_desc.min_filter
+            || sampler_desc->mip_filter != gl_tex->sampler_desc.mip_filter)
     {
-        GLint gl_value;
-
-        gl_tex->states[WINED3DTEXSTA_MIPFILTER] = sampler_states[WINED3D_SAMP_MIP_FILTER];
-        gl_tex->states[WINED3DTEXSTA_MINFILTER] = sampler_states[WINED3D_SAMP_MIN_FILTER];
-        gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL];
-
-        if (gl_tex->states[WINED3DTEXSTA_MINFILTER] > WINED3D_TEXF_ANISOTROPIC
-            || gl_tex->states[WINED3DTEXSTA_MIPFILTER] > WINED3D_TEXF_ANISOTROPIC)
-        {
-            FIXME("Unrecognized or unsupported MIN_FILTER value %#x MIP_FILTER value %#x.\n",
-                  gl_tex->states[WINED3DTEXSTA_MINFILTER],
-                  gl_tex->states[WINED3DTEXSTA_MIPFILTER]);
-        }
-        gl_value = wined3d_gl_min_mip_filter(texture->min_mip_lookup,
-                min(max(sampler_states[WINED3D_SAMP_MIN_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR),
-                min(max(sampler_states[WINED3D_SAMP_MIP_FILTER], WINED3D_TEXF_NONE), WINED3D_TEXF_LINEAR));
-
-        TRACE("ValueMIN=%#x, ValueMIP=%#x, setting MINFILTER to %#x.\n",
-              sampler_states[WINED3D_SAMP_MIN_FILTER],
-              sampler_states[WINED3D_SAMP_MIP_FILTER], gl_value);
-        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, gl_value);
-        checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
-
-        if (!cond_np2)
-        {
-            if (gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3D_TEXF_NONE)
-                gl_value = texture->lod;
-            else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= texture->level_count)
-                gl_value = texture->level_count - 1;
-            else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < texture->lod)
-                /* texture->lod is already clamped in the setter. */
-                gl_value = texture->lod;
-            else
-                gl_value = gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL];
-
-            /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap
-             * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest
-             * mimap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL
-             * corresponds to GL_TEXTURE_BASE_LEVEL. */
-            gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, gl_value);
-        }
+        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
+                wined3d_gl_min_mip_filter(sampler_desc->min_filter, sampler_desc->mip_filter));
+        gl_tex->sampler_desc.min_filter = sampler_desc->min_filter;
+        gl_tex->sampler_desc.mip_filter = sampler_desc->mip_filter;
     }
 
-    if ((gl_tex->states[WINED3DTEXSTA_MAGFILTER] != WINED3D_TEXF_ANISOTROPIC
-            && gl_tex->states[WINED3DTEXSTA_MINFILTER] != WINED3D_TEXF_ANISOTROPIC
-            && gl_tex->states[WINED3DTEXSTA_MIPFILTER] != WINED3D_TEXF_ANISOTROPIC)
-            || cond_np2)
-        aniso = 1;
-    else
-        aniso = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY];
-
-    if (gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] != aniso)
+    state = sampler_desc->max_anisotropy;
+    if (state != gl_tex->sampler_desc.max_anisotropy)
     {
         if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
-        {
-            gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
-            checkGLcall("glTexParameteri(GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso)");
-        }
+            gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, state);
         else
-        {
             WARN("Anisotropic filtering not supported.\n");
-        }
-        gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = aniso;
+        gl_tex->sampler_desc.max_anisotropy = state;
     }
 
     /* These should always be the same unless EXT_texture_sRGB_decode is supported. */
-    if (sampler_states[WINED3D_SAMP_SRGB_TEXTURE] != gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE])
+    if (!sampler_desc->srgb_decode != !gl_tex->sampler_desc.srgb_decode)
     {
         gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
-                sampler_states[WINED3D_SAMP_SRGB_TEXTURE] ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT);
-        checkGLcall("glTexParameteri(GL_TEXTURE_SRGB_DECODE_EXT)");
-        gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = sampler_states[WINED3D_SAMP_SRGB_TEXTURE];
+                sampler_desc->srgb_decode ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT);
+        gl_tex->sampler_desc.srgb_decode = sampler_desc->srgb_decode;
     }
 
-    if (!(texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
-            != !gl_tex->states[WINED3DTEXSTA_SHADOW])
+    if (!sampler_desc->compare != !gl_tex->sampler_desc.compare)
     {
-        if (texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
+        if (sampler_desc->compare)
         {
             gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
             gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
-            checkGLcall("glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB)");
-            gl_tex->states[WINED3DTEXSTA_SHADOW] = TRUE;
         }
         else
         {
             gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
-            checkGLcall("glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE)");
-            gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
         }
+        gl_tex->sampler_desc.compare = sampler_desc->compare;
+    }
+
+    checkGLcall("Texture parameter application");
+
+    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, sampler_desc->lod_bias);
+        checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
     }
 }
 
@@ -542,6 +454,22 @@ void wined3d_texture_load(struct wined3d_texture *texture,
     else
         flag = WINED3D_TEXTURE_RGB_VALID;
 
+    if (!(texture->flags & WINED3D_TEXTURE_COLOR_KEY) != !(texture->color_key_flags & WINED3D_CKEY_SRC_BLT)
+            || (texture->flags & WINED3D_TEXTURE_COLOR_KEY
+            && (texture->gl_color_key.color_space_low_value != texture->src_blt_color_key.color_space_low_value
+            || texture->gl_color_key.color_space_high_value != texture->src_blt_color_key.color_space_high_value)))
+    {
+        unsigned int sub_count = texture->level_count * texture->layer_count;
+        unsigned int i;
+
+        TRACE("Reloading because of color key value change.\n");
+        for (i = 0; i < sub_count; i++)
+            texture->texture_ops->texture_sub_resource_add_dirty_region(texture->sub_resources[i], NULL);
+        wined3d_texture_set_dirty(texture);
+
+        texture->gl_color_key = texture->src_blt_color_key;
+    }
+
     if (texture->flags & flag)
     {
         TRACE("Texture %p not dirty, nothing to do.\n", texture);
@@ -592,8 +520,8 @@ DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod)
     {
         texture->lod = lod;
 
-        texture->texture_rgb.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
-        texture->texture_srgb.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
+        texture->texture_rgb.base_level = ~0u;
+        texture->texture_srgb.base_level = ~0u;
         if (texture->resource.bind_count)
             device_invalidate_state(texture->resource.device, STATE_SAMPLER(texture->sampler));
     }
@@ -643,7 +571,7 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
 {
     TRACE("texture %p, flags %#x, color_key %p.\n", texture, flags, color_key);
 
-    if (flags & WINEDDCKEY_COLORSPACE)
+    if (flags & WINED3D_CKEY_COLORSPACE)
     {
         FIXME("Unhandled flags %#x.\n", flags);
         return WINED3DERR_INVALIDCALL;
@@ -651,47 +579,47 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
 
     if (color_key)
     {
-        switch (flags & ~WINEDDCKEY_COLORSPACE)
+        switch (flags & ~WINED3D_CKEY_COLORSPACE)
         {
-            case WINEDDCKEY_DESTBLT:
+            case WINED3D_CKEY_DST_BLT:
                 texture->dst_blt_color_key = *color_key;
-                texture->color_key_flags |= WINEDDSD_CKDESTBLT;
+                texture->color_key_flags |= WINED3D_CKEY_DST_BLT;
                 break;
 
-            case WINEDDCKEY_DESTOVERLAY:
+            case WINED3D_CKEY_DST_OVERLAY:
                 texture->dst_overlay_color_key = *color_key;
-                texture->color_key_flags |= WINEDDSD_CKDESTOVERLAY;
+                texture->color_key_flags |= WINED3D_CKEY_DST_OVERLAY;
                 break;
 
-            case WINEDDCKEY_SRCOVERLAY:
-                texture->src_overlay_color_key = *color_key;
-                texture->color_key_flags |= WINEDDSD_CKSRCOVERLAY;
+            case WINED3D_CKEY_SRC_BLT:
+                texture->src_blt_color_key = *color_key;
+                texture->color_key_flags |= WINED3D_CKEY_SRC_BLT;
                 break;
 
-            case WINEDDCKEY_SRCBLT:
-                texture->src_blt_color_key = *color_key;
-                texture->color_key_flags |= WINEDDSD_CKSRCBLT;
+            case WINED3D_CKEY_SRC_OVERLAY:
+                texture->src_overlay_color_key = *color_key;
+                texture->color_key_flags |= WINED3D_CKEY_SRC_OVERLAY;
                 break;
         }
     }
     else
     {
-        switch (flags & ~WINEDDCKEY_COLORSPACE)
+        switch (flags & ~WINED3D_CKEY_COLORSPACE)
         {
-            case WINEDDCKEY_DESTBLT:
-                texture->color_key_flags &= ~WINEDDSD_CKDESTBLT;
+            case WINED3D_CKEY_DST_BLT:
+                texture->color_key_flags &= ~WINED3D_CKEY_DST_BLT;
                 break;
 
-            case WINEDDCKEY_DESTOVERLAY:
-                texture->color_key_flags &= ~WINEDDSD_CKDESTOVERLAY;
+            case WINED3D_CKEY_DST_OVERLAY:
+                texture->color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY;
                 break;
 
-            case WINEDDCKEY_SRCOVERLAY:
-                texture->color_key_flags &= ~WINEDDSD_CKSRCOVERLAY;
+            case WINED3D_CKEY_SRC_BLT:
+                texture->color_key_flags &= ~WINED3D_CKEY_SRC_BLT;
                 break;
 
-            case WINEDDCKEY_SRCBLT:
-                texture->color_key_flags &= ~WINEDDSD_CKSRCBLT;
+            case WINED3D_CKEY_SRC_OVERLAY:
+                texture->color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY;
                 break;
         }
     }
@@ -699,6 +627,98 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
     return WINED3D_OK;
 }
 
+HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height,
+        enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type,
+        UINT multisample_quality, void *mem, UINT pitch)
+{
+    struct wined3d_device *device = texture->resource.device;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
+    UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
+    struct wined3d_surface *surface;
+
+    TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, "
+            "mem %p, pitch %u.\n",
+            texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_type, mem, pitch);
+
+    if (!resource_size)
+        return WINED3DERR_INVALIDCALL;
+
+    if (texture->level_count * texture->layer_count > 1)
+    {
+        WARN("Texture has multiple sub-resources, not supported.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if (texture->resource.type == WINED3D_RTYPE_VOLUME_TEXTURE)
+    {
+        WARN("Not supported on volume textures.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    /* We have no way of supporting a pitch that is not a multiple of the pixel
+     * byte width short of uploading the texture row-by-row.
+     * Fortunately that's not an issue since D3D9Ex doesn't allow a custom pitch
+     * for user-memory textures (it always expects packed data) while DirectDraw
+     * requires a 4-byte aligned pitch and doesn't support texture formats
+     * larger than 4 bytes per pixel nor any format using 3 bytes per pixel.
+     * This check is here to verify that the assumption holds. */
+    if (pitch % texture->resource.format->byte_count)
+    {
+        WARN("Pitch unsupported, not a multiple of the texture format byte width.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    surface = surface_from_resource(texture->sub_resources[0]);
+    if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE))
+    {
+        WARN("Surface is mapped or the DC is in use.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if (device->d3d_initialized)
+        texture->resource.resource_ops->resource_unload(&texture->resource);
+
+    texture->resource.format = format;
+    texture->resource.multisample_type = multisample_type;
+    texture->resource.multisample_quality = multisample_quality;
+    texture->resource.width = width;
+    texture->resource.height = height;
+
+    return wined3d_surface_update_desc(surface, gl_info, mem, pitch);
+}
+
+void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
+{
+    DWORD alloc_flag = srgb ? WINED3D_TEXTURE_SRGB_ALLOCATED : WINED3D_TEXTURE_RGB_ALLOCATED;
+
+    if (!(texture->flags & WINED3D_TEXTURE_COLOR_KEY) != !(texture->color_key_flags & WINED3D_CKEY_SRC_BLT))
+        wined3d_texture_force_reload(texture);
+
+    if (texture->flags & alloc_flag)
+        return;
+
+    if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT)
+        texture->flags |= WINED3D_TEXTURE_COLOR_KEY;
+
+    texture->texture_ops->texture_prepare_texture(texture, context, srgb);
+    texture->flags |= alloc_flag;
+}
+
+void wined3d_texture_force_reload(struct wined3d_texture *texture)
+{
+    unsigned int sub_count = texture->level_count * texture->layer_count;
+    unsigned int i;
+
+    texture->flags &= ~(WINED3D_TEXTURE_RGB_ALLOCATED | WINED3D_TEXTURE_SRGB_ALLOCATED
+            | WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_COLOR_KEY);
+    for (i = 0; i < sub_count; ++i)
+    {
+        texture->texture_ops->texture_sub_resource_invalidate_location(texture->sub_resources[i],
+                WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB);
+    }
+}
+
 void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture)
 {
     /* TODO: Implement filters using GL_SGI_generate_mipmaps. */
@@ -739,6 +759,29 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
     return WINED3D_OK;
 }
 
+static void wined3d_texture_upload_data(struct wined3d_texture *texture, const struct wined3d_sub_resource_data *data)
+{
+    unsigned int sub_count = texture->level_count * texture->layer_count;
+    struct wined3d_context *context;
+    unsigned int i;
+
+    context = context_acquire(texture->resource.device, NULL);
+
+    wined3d_texture_prepare_texture(texture, context, FALSE);
+    wined3d_texture_bind(texture, context, FALSE);
+
+    for (i = 0; i < sub_count; ++i)
+    {
+        struct wined3d_resource *sub_resource = texture->sub_resources[i];
+
+        texture->texture_ops->texture_sub_resource_upload_data(sub_resource, context, &data[i]);
+        texture->texture_ops->texture_sub_resource_validate_location(sub_resource, WINED3D_LOCATION_TEXTURE_RGB);
+        texture->texture_ops->texture_sub_resource_invalidate_location(sub_resource, ~WINED3D_LOCATION_TEXTURE_RGB);
+    }
+
+    context_release(context);
+}
+
 static void texture2d_sub_resource_load(struct wined3d_resource *sub_resource,
         struct wined3d_context *context, BOOL srgb)
 {
@@ -762,11 +805,148 @@ static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource
     wined3d_surface_destroy(surface);
 }
 
+static void texture2d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location)
+{
+    struct wined3d_surface *surface = surface_from_resource(sub_resource);
+
+    surface_invalidate_location(surface, location);
+}
+
+static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location)
+{
+    struct wined3d_surface *surface = surface_from_resource(sub_resource);
+
+    surface_validate_location(surface, location);
+}
+
+static void texture2d_sub_resource_upload_data(struct wined3d_resource *sub_resource,
+        const struct wined3d_context *context, const struct wined3d_sub_resource_data *data)
+{
+    struct wined3d_surface *surface = surface_from_resource(sub_resource);
+    static const POINT dst_point = {0, 0};
+    struct wined3d_const_bo_address addr;
+    RECT src_rect;
+
+    src_rect.left = 0;
+    src_rect.top = 0;
+    src_rect.right = surface->resource.width;
+    src_rect.bottom = surface->resource.height;
+
+    addr.buffer_object = 0;
+    addr.addr = data->data;
+
+    wined3d_surface_upload_data(surface, context->gl_info, surface->container->resource.format,
+            &src_rect, data->row_pitch, &dst_point, FALSE, &addr);
+}
+
+/* Context activation is done by the caller. */
+static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
+{
+    UINT sub_count = texture->level_count * texture->layer_count;
+    const struct wined3d_format *format = texture->resource.format;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    const struct wined3d_color_key_conversion *conversion;
+    GLenum internal;
+    UINT i;
+
+    TRACE("texture %p, format %s.\n", texture, debug_d3dformat(format->id));
+
+    if (format->convert)
+    {
+        texture->flags |= WINED3D_TEXTURE_CONVERTED;
+    }
+    else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
+    {
+        texture->flags |= WINED3D_TEXTURE_CONVERTED;
+        format = wined3d_get_format(gl_info, conversion->dst_format);
+        TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id));
+    }
+
+    wined3d_texture_bind_and_dirtify(texture, context, srgb);
+
+    if (srgb)
+        internal = format->glGammaInternal;
+    else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
+            && wined3d_resource_is_offscreen(&texture->resource))
+        internal = format->rtInternal;
+    else
+        internal = format->glInternal;
+
+    if (!internal)
+        FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
+
+    TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType);
+
+    for (i = 0; i < sub_count; ++i)
+    {
+        struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]);
+        GLsizei height = surface->pow2Height;
+        GLsizei width = surface->pow2Width;
+        const BYTE *mem = NULL;
+
+        if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
+        {
+            height *= format->height_scale.numerator;
+            height /= format->height_scale.denominator;
+        }
+
+        TRACE("surface %p, target %#x, level %d, width %d, height %d.\n",
+                surface, surface->texture_target, surface->texture_level, width, height);
+
+        if (gl_info->supported[APPLE_CLIENT_STORAGE])
+        {
+            if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION)
+                    || texture->flags & WINED3D_TEXTURE_CONVERTED
+                    || !surface->resource.heap_memory)
+            {
+                /* In some cases we want to disable client storage.
+                 * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches
+                 * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues...
+                 * WINED3D_TEXTURE_CONVERTED: The conversion destination memory is freed after loading the surface
+                 * heap_memory == NULL: Not defined in the extension. Seems to disable client storage effectively
+                 */
+                surface->flags &= ~SFLAG_CLIENT;
+            }
+            else
+            {
+                surface->flags |= SFLAG_CLIENT;
+                mem = surface->resource.heap_memory;
+
+                gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+                checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+            }
+        }
+
+        if (format->flags & WINED3DFMT_FLAG_COMPRESSED && mem)
+        {
+            GL_EXTCALL(glCompressedTexImage2D(surface->texture_target, surface->texture_level,
+                    internal, width, height, 0, surface->resource.size, mem));
+            checkGLcall("glCompressedTexImage2D");
+        }
+        else
+        {
+            gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
+                    internal, width, height, 0, format->glFormat, format->glType, mem);
+            checkGLcall("glTexImage2D");
+        }
+
+        if (mem)
+        {
+            gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+            checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
+        }
+    }
+}
+
 static const struct wined3d_texture_ops texture2d_ops =
 {
     texture2d_sub_resource_load,
     texture2d_sub_resource_add_dirty_region,
     texture2d_sub_resource_cleanup,
+    texture2d_sub_resource_invalidate_location,
+    texture2d_sub_resource_validate_location,
+    texture2d_sub_resource_upload_data,
+    texture2d_prepare_texture,
 };
 
 static ULONG texture_resource_incref(struct wined3d_resource *resource)
@@ -794,6 +974,7 @@ static void wined3d_texture_unload(struct wined3d_resource *resource)
         sub_resource->resource_ops->resource_unload(sub_resource);
     }
 
+    wined3d_texture_force_reload(texture);
     wined3d_texture_unload_gl_texture(texture);
 }
 
@@ -836,18 +1017,11 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi
             return WINED3DERR_INVALIDCALL;
         }
 
-        if (levels > 1)
+        if (levels != 1)
         {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n");
+            WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n");
             return WINED3DERR_INVALIDCALL;
         }
-
-        levels = 1;
-    }
-    else if (!levels)
-    {
-        levels = wined3d_log2i(desc->width) + 1;
-        TRACE("Calculated levels = %u.\n", levels);
     }
 
     if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
@@ -871,8 +1045,8 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi
         }
     }
 
-    if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels,
-            desc, device, parent, parent_ops, &texture_resource_ops)))
+    if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels, desc,
+            surface_flags, device, parent, parent_ops, &texture_resource_ops)))
     {
         WARN("Failed to initialize texture, returning %#x\n", hr);
         return hr;
@@ -982,22 +1156,15 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
             return WINED3DERR_INVALIDCALL;
         }
 
-        if (levels > 1)
+        if (levels != 1)
         {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning WINED3DERR_INVALIDCALL.\n");
+            WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n");
             return WINED3DERR_INVALIDCALL;
         }
-
-        levels = 1;
-    }
-    else if (!levels)
-    {
-        levels = wined3d_log2i(max(desc->width, desc->height)) + 1;
-        TRACE("Calculated levels = %u.\n", levels);
     }
 
-    if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels,
-            desc, device, parent, parent_ops, &texture_resource_ops)))
+    if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels, desc,
+            surface_flags, device, parent, parent_ops, &texture_resource_ops)))
     {
         WARN("Failed to initialize texture, returning %#x.\n", hr);
         return hr;
@@ -1013,7 +1180,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
         texture->pow2_matrix[15] = 1.0f;
         texture->target = GL_TEXTURE_2D;
         texture->flags |= WINED3D_TEXTURE_COND_NP2;
-        texture->min_mip_lookup = minMipLookup_noFilter;
     }
     else if (gl_info->supported[ARB_TEXTURE_RECTANGLE]
             && (desc->width != pow2_width || desc->height != pow2_height))
@@ -1024,12 +1190,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
         texture->pow2_matrix[15] = 1.0f;
         texture->target = GL_TEXTURE_RECTANGLE_ARB;
         texture->flags |= WINED3D_TEXTURE_COND_NP2;
-        texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
-
-        if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING)
-            texture->min_mip_lookup = minMipLookup_noMip;
-        else
-            texture->min_mip_lookup = minMipLookup_noFilter;
+        texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS);
     }
     else
     {
@@ -1095,11 +1256,84 @@ static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource
     wined3d_volume_destroy(volume);
 }
 
+static void texture3d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location)
+{
+    struct wined3d_volume *volume = volume_from_resource(sub_resource);
+
+    wined3d_volume_invalidate_location(volume, location);
+}
+
+static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location)
+{
+    struct wined3d_volume *volume = volume_from_resource(sub_resource);
+
+    wined3d_volume_validate_location(volume, location);
+}
+
+static void texture3d_sub_resource_upload_data(struct wined3d_resource *sub_resource,
+        const struct wined3d_context *context, const struct wined3d_sub_resource_data *data)
+{
+    struct wined3d_volume *volume = volume_from_resource(sub_resource);
+    struct wined3d_const_bo_address addr;
+    unsigned int row_pitch, slice_pitch;
+
+    wined3d_volume_get_pitch(volume, &row_pitch, &slice_pitch);
+    if (row_pitch != data->row_pitch || slice_pitch != data->slice_pitch)
+        FIXME("Ignoring row/slice pitch (%u/%u).\n", data->row_pitch, data->slice_pitch);
+
+    addr.buffer_object = 0;
+    addr.addr = data->data;
+
+    wined3d_volume_upload_data(volume, context, &addr);
+}
+
+static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
+{
+    unsigned int sub_count = texture->level_count * texture->layer_count;
+    const struct wined3d_format *format = texture->resource.format;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned int i;
+
+    wined3d_texture_bind_and_dirtify(texture, context, srgb);
+
+    for (i = 0; i < sub_count; ++i)
+    {
+        struct wined3d_volume *volume = volume_from_resource(texture->sub_resources[i]);
+        void *mem = NULL;
+
+        if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert
+                && volume_prepare_system_memory(volume))
+        {
+            TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume);
+            gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+            checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+            mem = volume->resource.heap_memory;
+            volume->flags |= WINED3D_VFLAG_CLIENT_STORAGE;
+        }
+
+        GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, volume->texture_level,
+                srgb ? format->glGammaInternal : format->glInternal,
+                volume->resource.width, volume->resource.height, volume->resource.depth,
+                0, format->glFormat, format->glType, mem));
+        checkGLcall("glTexImage3D");
+
+        if (mem)
+        {
+            gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+            checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
+        }
+    }
+}
+
 static const struct wined3d_texture_ops texture3d_ops =
 {
     texture3d_sub_resource_load,
     texture3d_sub_resource_add_dirty_region,
     texture3d_sub_resource_cleanup,
+    texture3d_sub_resource_invalidate_location,
+    texture3d_sub_resource_validate_location,
+    texture3d_sub_resource_upload_data,
+    texture3d_prepare_texture,
 };
 
 static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
@@ -1133,18 +1367,11 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
             return WINED3DERR_INVALIDCALL;
         }
 
-        if (levels > 1)
+        if (levels != 1)
         {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n");
+            WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n");
             return WINED3DERR_INVALIDCALL;
         }
-
-        levels = 1;
-    }
-    else if (!levels)
-    {
-        levels = wined3d_log2i(max(max(desc->width, desc->height), desc->depth)) + 1;
-        TRACE("Calculated levels = %u.\n", levels);
     }
 
     if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
@@ -1175,8 +1402,8 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
         }
     }
 
-    if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels,
-            desc, device, parent, parent_ops, &texture_resource_ops)))
+    if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels, desc,
+            0, device, parent, parent_ops, &texture_resource_ops)))
     {
         WARN("Failed to initialize texture, returning %#x.\n", hr);
         return hr;
@@ -1214,14 +1441,20 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
 }
 
 HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
-        UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops,
-        struct wined3d_texture **texture)
+        UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent,
+        const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
 {
     struct wined3d_texture *object;
     HRESULT hr;
 
-    TRACE("device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.\n",
-            device, desc, level_count, surface_flags, parent, parent_ops, texture);
+    TRACE("device %p, desc %p, level_count %u, surface_flags %#x, data %p, parent %p, parent_ops %p, texture %p.\n",
+            device, desc, level_count, surface_flags, data, parent, parent_ops, texture);
+
+    if (!level_count)
+    {
+        WARN("Invalid level count.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
 
     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
         return E_OUTOFMEMORY;
@@ -1253,6 +1486,11 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
         return hr;
     }
 
+    /* FIXME: We'd like to avoid ever allocating system memory for the texture
+     * in this case. */
+    if (data)
+        wined3d_texture_upload_data(object, data);
+
     TRACE("Created texture %p.\n", object);
     *texture = object;
 
index 18e5b21..2591e11 100644 (file)
@@ -128,6 +128,7 @@ static const struct wined3d_format_channels formats[] =
     {WINED3DFMT_R32G32B32A32_UINT,         32, 32, 32, 32,   0, 32, 64, 96,   16,   0,     0},
     {WINED3DFMT_R16G16B16A16_SNORM,        16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
     /* Vendor-specific formats */
+    {WINED3DFMT_ATI1N,                      0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_ATI2N,                      0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_NVDB,                       0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
     {WINED3DFMT_INST,                       0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
@@ -174,6 +175,7 @@ static const struct wined3d_format_base_flags format_base_flags[] =
     {WINED3DFMT_B4G4R4X4_UNORM,     WINED3DFMT_FLAG_GETDC},
     {WINED3DFMT_R8G8B8A8_UNORM,     WINED3DFMT_FLAG_GETDC},
     {WINED3DFMT_R8G8B8X8_UNORM,     WINED3DFMT_FLAG_GETDC},
+    {WINED3DFMT_ATI1N,              WINED3DFMT_FLAG_BROKEN_PITCH},
     {WINED3DFMT_ATI2N,              WINED3DFMT_FLAG_BROKEN_PITCH},
     {WINED3DFMT_R32_FLOAT,          WINED3DFMT_FLAG_FLOAT},
     {WINED3DFMT_R32G32_FLOAT,       WINED3DFMT_FLAG_FLOAT},
@@ -202,6 +204,7 @@ static const struct wined3d_format_block_info format_block_info[] =
     {WINED3DFMT_DXT3,   4,  4,  16, TRUE},
     {WINED3DFMT_DXT4,   4,  4,  16, TRUE},
     {WINED3DFMT_DXT5,   4,  4,  16, TRUE},
+    {WINED3DFMT_ATI1N,  4,  4,  8,  FALSE},
     {WINED3DFMT_ATI2N,  4,  4,  16, FALSE},
     {WINED3DFMT_YUY2,   2,  1,  4,  FALSE},
     {WINED3DFMT_UYVY,   2,  1,  4,  FALSE},
@@ -611,6 +614,207 @@ static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_p
     }
 }
 
+static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD color)
+{
+    /* FIXME: Is this really how color keys are supposed to work? I think it
+     * makes more sense to compare the individual channels. */
+    return color >= color_key->color_space_low_value
+            && color <= color_key->color_space_high_value;
+}
+
+static void convert_p8_uint_b8g8r8a8_unorm(const BYTE *src, unsigned int src_pitch,
+        BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
+        const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
+{
+    const BYTE *src_row;
+    unsigned int x, y;
+    DWORD *dst_row;
+
+    if (!palette)
+    {
+        /* FIXME: This should probably use the system palette. */
+        FIXME("P8 surface loaded without a palette.\n");
+
+        for (y = 0; y < height; ++y)
+        {
+            memset(&dst[dst_pitch * y], 0, width * 4);
+        }
+
+        return;
+    }
+
+    for (y = 0; y < height; ++y)
+    {
+        src_row = &src[src_pitch * y];
+        dst_row = (DWORD *)&dst[dst_pitch * y];
+        for (x = 0; x < width; ++x)
+        {
+            BYTE src_color = src_row[x];
+            dst_row[x] = 0xff000000
+                    | (palette->colors[src_color].rgbRed << 16)
+                    | (palette->colors[src_color].rgbGreen << 8)
+                    | palette->colors[src_color].rgbBlue;
+        }
+    }
+}
+
+static void convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch,
+        BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
+        const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
+{
+    const WORD *src_row;
+    unsigned int x, y;
+    WORD *dst_row;
+
+    for (y = 0; y < height; ++y)
+    {
+        src_row = (WORD *)&src[src_pitch * y];
+        dst_row = (WORD *)&dst[dst_pitch * y];
+        for (x = 0; x < width; ++x)
+        {
+            WORD src_color = src_row[x];
+            if (!color_in_range(color_key, src_color))
+                dst_row[x] = 0x8000 | ((src_color & 0xffc0) >> 1) | (src_color & 0x1f);
+            else
+                dst_row[x] = ((src_color & 0xffc0) >> 1) | (src_color & 0x1f);
+        }
+    }
+}
+
+static void convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch,
+        BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
+        const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
+{
+    const WORD *src_row;
+    unsigned int x, y;
+    WORD *dst_row;
+
+    for (y = 0; y < height; ++y)
+    {
+        src_row = (WORD *)&src[src_pitch * y];
+        dst_row = (WORD *)&dst[dst_pitch * y];
+        for (x = 0; x < width; ++x)
+        {
+            WORD src_color = src_row[x];
+            if (color_in_range(color_key, src_color))
+                dst_row[x] = src_color & ~0x8000;
+            else
+                dst_row[x] = src_color | 0x8000;
+        }
+    }
+}
+
+static void convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
+        BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
+        const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
+{
+    const BYTE *src_row;
+    unsigned int x, y;
+    DWORD *dst_row;
+
+    for (y = 0; y < height; ++y)
+    {
+        src_row = &src[src_pitch * y];
+        dst_row = (DWORD *)&dst[dst_pitch * y];
+        for (x = 0; x < width; ++x)
+        {
+            DWORD src_color = (src_row[x * 3 + 2] << 16) | (src_row[x * 3 + 1] << 8) | src_row[x * 3];
+            if (!color_in_range(color_key, src_color))
+                dst_row[x] = src_color | 0xff000000;
+        }
+    }
+}
+
+static void convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
+        BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
+        const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
+{
+    const DWORD *src_row;
+    unsigned int x, y;
+    DWORD *dst_row;
+
+    for (y = 0; y < height; ++y)
+    {
+        src_row = (DWORD *)&src[src_pitch * y];
+        dst_row = (DWORD *)&dst[dst_pitch * y];
+        for (x = 0; x < width; ++x)
+        {
+            DWORD src_color = src_row[x];
+            if (color_in_range(color_key, src_color))
+                dst_row[x] = src_color & ~0xff000000;
+            else
+                dst_row[x] = src_color | 0xff000000;
+        }
+    }
+}
+
+static void convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
+        BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
+        const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
+{
+    const DWORD *src_row;
+    unsigned int x, y;
+    DWORD *dst_row;
+
+    for (y = 0; y < height; ++y)
+    {
+        src_row = (DWORD *)&src[src_pitch * y];
+        dst_row = (DWORD *)&dst[dst_pitch * y];
+        for (x = 0; x < width; ++x)
+        {
+            DWORD src_color = src_row[x];
+            if (color_in_range(color_key, src_color))
+                src_color &= ~0xff000000;
+            dst_row[x] = src_color;
+        }
+    }
+}
+
+const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(
+        const struct wined3d_texture *texture, BOOL need_alpha_ck)
+{
+    const struct wined3d_format *format = texture->resource.format;
+    unsigned int i;
+
+    static const struct
+    {
+        enum wined3d_format_id src_format;
+        struct wined3d_color_key_conversion conversion;
+    }
+    color_key_info[] =
+    {
+        {WINED3DFMT_B5G6R5_UNORM,   {WINED3DFMT_B5G5R5A1_UNORM, convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key   }},
+        {WINED3DFMT_B5G5R5X1_UNORM, {WINED3DFMT_B5G5R5A1_UNORM, convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key }},
+        {WINED3DFMT_B8G8R8_UNORM,   {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key   }},
+        {WINED3DFMT_B8G8R8X8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key }},
+        {WINED3DFMT_B8G8R8A8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key }},
+    };
+    static const struct wined3d_color_key_conversion convert_p8 =
+    {
+        WINED3DFMT_B8G8R8A8_UNORM,  convert_p8_uint_b8g8r8a8_unorm
+    };
+
+    if (need_alpha_ck && (texture->flags & WINED3D_TEXTURE_COLOR_KEY))
+    {
+        for (i = 0; i < sizeof(color_key_info) / sizeof(*color_key_info); ++i)
+        {
+            if (color_key_info[i].src_format == format->id)
+                return &color_key_info[i].conversion;
+        }
+
+        FIXME("Color-keying not supported with format %s.\n", debug_d3dformat(format->id));
+    }
+
+    /* FIXME: This should check if the blitter backend can do P8 conversion,
+     * instead of checking for ARB_fragment_program. */
+    if (format->id == WINED3DFMT_P8_UINT
+            && !(texture->resource.device->adapter->gl_info.supported[ARB_FRAGMENT_PROGRAM]
+            && texture->swapchain && texture == texture->swapchain->front_buffer))
+        return &convert_p8;
+
+    return NULL;
+}
+
 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
  *
  * These are never supported on native.
@@ -982,6 +1186,11 @@ static const struct wined3d_format_texture_info format_texture_info[] =
             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
             ARB_DEPTH_BUFFER_FLOAT,     convert_s8_uint_d24_float},
     /* Vendor-specific formats */
+    {WINED3DFMT_ATI1N,                  GL_COMPRESSED_RED_RGTC1,          GL_COMPRESSED_RED_RGTC1,                0,
+            GL_RED,                     GL_UNSIGNED_BYTE,                 0,
+            WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+            | WINED3DFMT_FLAG_COMPRESSED,
+            ARB_TEXTURE_COMPRESSION_RGTC, NULL},
     {WINED3DFMT_ATI2N,                  GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
@@ -1816,8 +2025,12 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
          */
     }
 
-    if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
+    if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC])
     {
+        idx = getFmtIdx(WINED3DFMT_ATI1N);
+        gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+                0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X);
+
         idx = getFmtIdx(WINED3DFMT_ATI2N);
         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
@@ -2114,6 +2327,7 @@ const char *debug_d3dformat(enum wined3d_format_id format_id)
         FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
         FMT_TO_STR(WINED3DFMT_VERTEXDATA);
         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
+        FMT_TO_STR(WINED3DFMT_ATI1N);
         FMT_TO_STR(WINED3DFMT_ATI2N);
         FMT_TO_STR(WINED3DFMT_NVDB);
         FMT_TO_STR(WINED3DFMT_NVHU);
@@ -2686,6 +2900,8 @@ const char *debug_d3dstate(DWORD state)
         return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(state - STATE_SHADER(0)));
     if (STATE_IS_CONSTANT_BUFFER(state))
         return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(state - STATE_CONSTANT_BUFFER(0)));
+    if (STATE_IS_SHADER_RESOURCE_BINDING(state))
+        return "STATE_SHADER_RESOURCE_BINDING";
     if (STATE_IS_TRANSFORM(state))
         return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
     if (STATE_IS_STREAMSRC(state))
@@ -3310,7 +3526,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
 
             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
             {
-                if (texture->color_key_flags & WINEDDSD_CKSRCBLT && !texture->resource.format->alpha_size)
+                if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size)
                 {
                     if (aop == WINED3D_TOP_DISABLE)
                     {
@@ -3714,32 +3930,6 @@ const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions =
     wined3d_ffp_vertex_program_key_compare,
 };
 
-UINT wined3d_log2i(UINT32 x)
-{
-    static const UINT l[] =
-    {
-        ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
-          4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    };
-    UINT32 i;
-
-    return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
-}
-
 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
         const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
         const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
index 1ffd3b9..b53b36b 100644 (file)
@@ -214,6 +214,19 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara
             return E_FAIL;
         }
 
+        if (e->offset == WINED3D_APPEND_ALIGNED_ELEMENT)
+        {
+            if (!i)
+            {
+                e->offset = 0;
+            }
+            else
+            {
+                struct wined3d_vertex_declaration_element *prev = &declaration->elements[i - 1];
+                e->offset = (prev->offset + prev->format->byte_count + 3) & ~3;
+            }
+        }
+
         if (e->offset & 0x3)
         {
             WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);
index 2f79a60..7aa27d4 100644 (file)
@@ -173,7 +173,10 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v
 
     if (!refcount)
     {
+        /* Call wined3d_object_destroyed() before releasing the resource,
+         * since releasing the resource may end up destroying the parent. */
         view->parent_ops->wined3d_object_destroyed(view->parent);
+        wined3d_resource_decref(view->resource);
         HeapFree(GetProcessHeap(), 0, view);
     }
 
@@ -187,8 +190,8 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader
     return view->parent;
 }
 
-HRESULT CDECL wined3d_shader_resource_view_create(void *parent, const struct wined3d_parent_ops *parent_ops,
-        struct wined3d_shader_resource_view **view)
+HRESULT CDECL wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent,
+        const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view)
 {
     struct wined3d_shader_resource_view *object;
 
@@ -198,6 +201,8 @@ HRESULT CDECL wined3d_shader_resource_view_create(void *parent, const struct win
         return E_OUTOFMEMORY;
 
     object->refcount = 1;
+    object->resource = resource;
+    wined3d_resource_incref(resource);
     object->parent = parent;
     object->parent_ops = parent_ops;
 
index f61825a..944996f 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
 
-#define WINED3D_VFLAG_ALLOCATED         0x00000001
-#define WINED3D_VFLAG_SRGB_ALLOCATED    0x00000002
-#define WINED3D_VFLAG_CLIENT_STORAGE    0x00000004
-
-static BOOL volume_prepare_system_memory(struct wined3d_volume *volume)
+BOOL volume_prepare_system_memory(struct wined3d_volume *volume)
 {
     if (volume->resource.heap_memory)
         return TRUE;
@@ -42,39 +38,7 @@ static BOOL volume_prepare_system_memory(struct wined3d_volume *volume)
     return TRUE;
 }
 
-/* Context activation is done by the caller. */
-static void wined3d_volume_allocate_texture(struct wined3d_volume *volume,
-        const struct wined3d_context *context, BOOL srgb)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    const struct wined3d_format *format = volume->resource.format;
-    void *mem = NULL;
-
-    if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert
-            && volume_prepare_system_memory(volume))
-    {
-        TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume);
-        gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
-        checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
-        mem = volume->resource.heap_memory;
-        volume->flags |= WINED3D_VFLAG_CLIENT_STORAGE;
-    }
-
-    GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, volume->texture_level,
-            srgb ? format->glGammaInternal : format->glInternal,
-            volume->resource.width, volume->resource.height, volume->resource.depth,
-            0, format->glFormat, format->glType, mem));
-    checkGLcall("glTexImage3D");
-
-    if (mem)
-    {
-        gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
-        checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
-    }
-}
-
-static void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch,
-        UINT *slice_pitch)
+void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch)
 {
     const struct wined3d_format *format = volume->resource.format;
 
@@ -100,14 +64,15 @@ static void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *
 
 /* Context activation is done by the caller. */
 void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
-        const struct wined3d_bo_address *data)
+        const struct wined3d_const_bo_address *data)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_format *format = volume->resource.format;
     UINT width = volume->resource.width;
     UINT height = volume->resource.height;
     UINT depth = volume->resource.depth;
-    BYTE *mem = data->addr;
+    const void *mem = data->addr;
+    void *converted_mem = NULL;
 
     TRACE("volume %p, context %p, level %u, format %s (%#x).\n",
             volume, context, volume->texture_level, debug_d3dformat(format->id),
@@ -117,7 +82,6 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
     {
         UINT dst_row_pitch, dst_slice_pitch;
         UINT src_row_pitch, src_slice_pitch;
-        UINT alignment = volume->resource.device->surface_alignment;
 
         if (data->buffer_object)
             ERR("Loading a converted volume from a PBO.\n");
@@ -125,38 +89,37 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
             ERR("Converting a block-based format.\n");
 
         dst_row_pitch = width * format->conv_byte_count;
-        dst_row_pitch = (dst_row_pitch + alignment - 1) & ~(alignment - 1);
         dst_slice_pitch = dst_row_pitch * height;
 
         wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch);
 
-        mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth);
-        format->convert(data->addr, mem, src_row_pitch, src_slice_pitch,
+        converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth);
+        format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch,
                 dst_row_pitch, dst_slice_pitch, width, height, depth);
+        mem = converted_mem;
     }
 
     if (data->buffer_object)
     {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, data->buffer_object));
-        checkGLcall("glBindBufferARB");
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
+        checkGLcall("glBindBuffer");
     }
 
-    GL_EXTCALL(glTexSubImage3DEXT(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0,
+    GL_EXTCALL(glTexSubImage3D(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0,
             width, height, depth,
             format->glFormat, format->glType, mem));
     checkGLcall("glTexSubImage3D");
 
     if (data->buffer_object)
     {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-        checkGLcall("glBindBufferARB");
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+        checkGLcall("glBindBuffer");
     }
 
-    if (mem != data->addr)
-        HeapFree(GetProcessHeap(), 0, mem);
+    HeapFree(GetProcessHeap(), 0, converted_mem);
 }
 
-static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location)
+void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location)
 {
     TRACE("Volume %p, setting %s.\n", volume, wined3d_debug_location(location));
     volume->locations |= location;
@@ -186,8 +149,8 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume,
 
     if (data->buffer_object)
     {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data->buffer_object));
-        checkGLcall("glBindBufferARB");
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
+        checkGLcall("glBindBuffer");
     }
 
     gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, volume->texture_level,
@@ -196,8 +159,8 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume,
 
     if (data->buffer_object)
     {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
-        checkGLcall("glBindBufferARB");
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+        checkGLcall("glBindBuffer");
     }
 
 }
@@ -250,7 +213,7 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
     wined3d_texture_bind_and_dirtify(volume->container, context, !dest_is_srgb);
     wined3d_volume_download_data(volume, context, &data);
     wined3d_texture_bind_and_dirtify(volume->container, context, dest_is_srgb);
-    wined3d_volume_upload_data(volume, context, &data);
+    wined3d_volume_upload_data(volume, context, wined3d_const_bo_address(&data));
 
     HeapFree(GetProcessHeap(), 0, data.addr);
 }
@@ -295,9 +258,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
         case WINED3D_LOCATION_TEXTURE_RGB:
         case WINED3D_LOCATION_TEXTURE_SRGB:
             if ((location == WINED3D_LOCATION_TEXTURE_RGB
-                    && !(volume->flags & WINED3D_VFLAG_ALLOCATED))
+                    && !(volume->container->flags & WINED3D_TEXTURE_RGB_ALLOCATED))
                     || (location == WINED3D_LOCATION_TEXTURE_SRGB
-                    && !(volume->flags & WINED3D_VFLAG_SRGB_ALLOCATED)))
+                    && !(volume->container->flags & WINED3D_TEXTURE_SRGB_ALLOCATED)))
                 ERR("Trying to load (s)RGB texture without prior allocation.\n");
 
             if (volume->locations & WINED3D_LOCATION_DISCARDED)
@@ -307,12 +270,12 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
             }
             else if (volume->locations & WINED3D_LOCATION_SYSMEM)
             {
-                struct wined3d_bo_address data = {0, volume->resource.heap_memory};
+                struct wined3d_const_bo_address data = {0, volume->resource.heap_memory};
                 wined3d_volume_upload_data(volume, context, &data);
             }
             else if (volume->locations & WINED3D_LOCATION_BUFFER)
             {
-                struct wined3d_bo_address data = {volume->pbo, NULL};
+                struct wined3d_const_bo_address data = {volume->pbo, NULL};
                 wined3d_volume_upload_data(volume, context, &data);
             }
             else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
@@ -403,28 +366,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
 /* Context activation is done by the caller. */
 void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode)
 {
-    wined3d_texture_bind_and_dirtify(volume->container, context, srgb_mode);
-
-    if (srgb_mode)
-    {
-        if (!(volume->flags & WINED3D_VFLAG_SRGB_ALLOCATED))
-        {
-            wined3d_volume_allocate_texture(volume, context, TRUE);
-            volume->flags |= WINED3D_VFLAG_SRGB_ALLOCATED;
-        }
-
-        wined3d_volume_load_location(volume, context, WINED3D_LOCATION_TEXTURE_SRGB);
-    }
-    else
-    {
-        if (!(volume->flags & WINED3D_VFLAG_ALLOCATED))
-        {
-            wined3d_volume_allocate_texture(volume, context, FALSE);
-            volume->flags |= WINED3D_VFLAG_ALLOCATED;
-        }
-
-        wined3d_volume_load_location(volume, context, WINED3D_LOCATION_TEXTURE_RGB);
-    }
+    wined3d_texture_prepare_texture(volume->container, context, srgb_mode);
+    wined3d_volume_load_location(volume, context,
+            srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB);
 }
 
 /* Context activation is done by the caller. */
@@ -435,10 +379,10 @@ static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct win
     if (volume->pbo)
         return;
 
-    GL_EXTCALL(glGenBuffersARB(1, &volume->pbo));
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
-    GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->resource.size, NULL, GL_STREAM_DRAW_ARB));
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+    GL_EXTCALL(glGenBuffers(1, &volume->pbo));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
+    GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, volume->resource.size, NULL, GL_STREAM_DRAW));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
     checkGLcall("Create PBO");
 
     TRACE("Created PBO %u for volume %p.\n", volume->pbo, volume);
@@ -450,8 +394,8 @@ static void wined3d_volume_free_pbo(struct wined3d_volume *volume)
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
     TRACE("Deleting PBO %u belonging to volume %p.\n", volume->pbo, volume);
-    GL_EXTCALL(glDeleteBuffersARB(1, &volume->pbo));
-    checkGLcall("glDeleteBuffersARB");
+    GL_EXTCALL(glDeleteBuffers(1, &volume->pbo));
+    checkGLcall("glDeleteBuffers");
     volume->pbo = 0;
     context_release(context);
 }
@@ -503,8 +447,7 @@ static void volume_unload(struct wined3d_resource *resource)
     }
 
     /* The texture name is managed by the container. */
-    volume->flags &= ~(WINED3D_VFLAG_ALLOCATED | WINED3D_VFLAG_SRGB_ALLOCATED
-            | WINED3D_VFLAG_CLIENT_STORAGE);
+    volume->flags &= ~WINED3D_VFLAG_CLIENT_STORAGE;
 
     resource_unload(resource);
 }
@@ -640,22 +583,22 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
         else
             wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
 
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
 
         if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
         {
             GLbitfield mapflags = wined3d_resource_gl_map_flags(flags);
             mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT;
-            base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER_ARB,
+            base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,
                     0, volume->resource.size, mapflags));
         }
         else
         {
             GLenum access = wined3d_resource_gl_legacy_map_flags(flags);
-            base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, access));
+            base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access));
         }
 
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
         checkGLcall("Map PBO");
 
         context_release(context);
@@ -757,9 +700,9 @@ HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume)
         struct wined3d_context *context = context_acquire(device, NULL);
         const struct wined3d_gl_info *gl_info = context->gl_info;
 
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
-        GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
+        GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
         checkGLcall("Unmap PBO");
 
         context_release(context);
index 615a85d..4e6ebb7 100644 (file)
 @ cdecl wined3d_rendertarget_view_incref(ptr)
 @ cdecl wined3d_rendertarget_view_set_parent(ptr ptr)
 
-@ cdecl wined3d_sampler_create(ptr ptr)
+@ cdecl wined3d_sampler_create(ptr ptr ptr ptr)
 @ cdecl wined3d_sampler_decref(ptr)
 @ cdecl wined3d_sampler_get_parent(ptr)
 @ cdecl wined3d_sampler_incref(ptr)
 
-@ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr ptr long)
-@ cdecl wined3d_shader_create_ps(ptr ptr ptr ptr ptr ptr long)
-@ cdecl wined3d_shader_create_vs(ptr ptr ptr ptr ptr ptr long)
+@ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr)
+@ cdecl wined3d_shader_create_ps(ptr ptr ptr ptr ptr)
+@ cdecl wined3d_shader_create_vs(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_shader_decref(ptr)
 @ cdecl wined3d_shader_get_byte_code(ptr ptr ptr)
 @ cdecl wined3d_shader_get_parent(ptr)
 @ cdecl wined3d_shader_incref(ptr)
 @ cdecl wined3d_shader_set_local_constants_float(ptr long ptr long)
 
-@ cdecl wined3d_shader_resource_view_create(ptr ptr ptr)
+@ cdecl wined3d_shader_resource_view_create(ptr ptr ptr ptr)
 @ cdecl wined3d_shader_resource_view_decref(ptr)
 @ cdecl wined3d_shader_resource_view_get_parent(ptr)
 @ cdecl wined3d_shader_resource_view_incref(ptr)
 @ cdecl wined3d_stateblock_decref(ptr)
 @ cdecl wined3d_stateblock_incref(ptr)
 
+@ cdecl wined3d_strictdrawing_set(long)
+
 @ cdecl wined3d_surface_blt(ptr ptr ptr ptr long ptr long)
 @ cdecl wined3d_surface_decref(ptr)
 @ cdecl wined3d_surface_from_resource(ptr)
 @ cdecl wined3d_surface_restore(ptr)
 @ cdecl wined3d_surface_set_overlay_position(ptr long long)
 @ cdecl wined3d_surface_unmap(ptr)
-@ cdecl wined3d_surface_update_desc(ptr long long long long long ptr long)
 @ cdecl wined3d_surface_update_overlay(ptr ptr ptr ptr long ptr)
 @ cdecl wined3d_surface_update_overlay_z_order(ptr long ptr)
 
 @ cdecl wined3d_swapchain_set_window(ptr ptr)
 
 @ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
-@ cdecl wined3d_texture_create(ptr ptr long long ptr ptr ptr)
+@ cdecl wined3d_texture_create(ptr ptr long long ptr ptr ptr ptr)
 @ cdecl wined3d_texture_decref(ptr)
 @ cdecl wined3d_texture_generate_mipmaps(ptr)
 @ cdecl wined3d_texture_get_autogen_filter_type(ptr)
 @ cdecl wined3d_texture_set_autogen_filter_type(ptr long)
 @ cdecl wined3d_texture_set_color_key(ptr long ptr)
 @ cdecl wined3d_texture_set_lod(ptr long)
+@ cdecl wined3d_texture_update_desc(ptr long long long long long ptr long)
 
 @ cdecl wined3d_vertex_declaration_create(ptr ptr long ptr ptr ptr)
 @ cdecl wined3d_vertex_declaration_create_from_fvf(ptr long ptr ptr ptr)
 @ cdecl wined3d_volume_map(ptr ptr ptr long)
 @ cdecl wined3d_volume_preload(ptr)
 @ cdecl wined3d_volume_unmap(ptr)
+
+@ cdecl wined3d_dxtn_supported()
+@ cdecl wined3d_dxt1_decode(ptr ptr long long long long long)
+@ cdecl wined3d_dxt1_encode(ptr ptr long long long long long)
+@ cdecl wined3d_dxt3_decode(ptr ptr long long long long long)
+@ cdecl wined3d_dxt3_encode(ptr ptr long long long long long)
+@ cdecl wined3d_dxt5_decode(ptr ptr long long long long long)
+@ cdecl wined3d_dxt5_encode(ptr ptr long long long long long)
index b02905e..3f06601 100644 (file)
@@ -25,6 +25,7 @@
 #define __WINE_WINED3D_GL_H
 
 #include "wine/wgl.h"
+#include "wine/wglext.h"
 
 #define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837  /* not in the gl spec */
 
@@ -47,7 +48,6 @@ enum wined3d_gl_extension
     ARB_COLOR_BUFFER_FLOAT,
     ARB_DEBUG_OUTPUT,
     ARB_DEPTH_BUFFER_FLOAT,
-    ARB_DEPTH_CLAMP,
     ARB_DEPTH_TEXTURE,
     ARB_DRAW_BUFFERS,
     ARB_DRAW_ELEMENTS_BASE_VERTEX,
@@ -70,6 +70,7 @@ enum wined3d_gl_extension
     ARB_POINT_PARAMETERS,
     ARB_POINT_SPRITE,
     ARB_PROVOKING_VERTEX,
+    ARB_SAMPLER_OBJECTS,
     ARB_SHADER_BIT_ENCODING,
     ARB_SHADER_OBJECTS,
     ARB_SHADER_TEXTURE_LOD,
@@ -135,7 +136,6 @@ enum wined3d_gl_extension
     EXT_TEXTURE_SRGB_DECODE,
     EXT_VERTEX_ARRAY_BGRA,
     /* NVIDIA */
-    NV_DEPTH_CLAMP,
     NV_FENCE,
     NV_FOG_DISTANCE,
     NV_FRAGMENT_PROGRAM,
@@ -167,439 +167,4 @@ enum wined3d_gl_extension
 
     WINED3D_GL_EXT_COUNT,
 };
-
-#include "wine/wglext.h"
-
-#define GL_EXT_FUNCS_GEN \
-    /* GL_APPLE_fence */ \
-    USE_GL_FUNC(glDeleteFencesAPPLE) \
-    USE_GL_FUNC(glFinishFenceAPPLE) \
-    USE_GL_FUNC(glFinishObjectAPPLE) \
-    USE_GL_FUNC(glGenFencesAPPLE) \
-    USE_GL_FUNC(glIsFenceAPPLE) \
-    USE_GL_FUNC(glSetFenceAPPLE) \
-    USE_GL_FUNC(glTestFenceAPPLE) \
-    USE_GL_FUNC(glTestObjectAPPLE) \
-    /* GL_APPLE_flush_buffer_range */ \
-    USE_GL_FUNC(glBufferParameteriAPPLE) \
-    USE_GL_FUNC(glFlushMappedBufferRangeAPPLE) \
-    /* GL_ARB_blend_func_extended */ \
-    USE_GL_FUNC(glBindFragDataLocationIndexed) \
-    USE_GL_FUNC(glGetFragDataIndex) \
-    /* GL_ARB_color_buffer_float */ \
-    USE_GL_FUNC(glClampColorARB) \
-    /* GL_ARB_debug_output */ \
-    USE_GL_FUNC(glDebugMessageCallbackARB) \
-    USE_GL_FUNC(glDebugMessageControlARB) \
-    USE_GL_FUNC(glDebugMessageInsertARB) \
-    USE_GL_FUNC(glGetDebugMessageLogARB) \
-    /* GL_ARB_draw_buffers */ \
-    USE_GL_FUNC(glDrawBuffersARB) \
-    /* GL_ARB_draw_elements_base_vertex */ \
-    USE_GL_FUNC(glDrawElementsBaseVertex) \
-    USE_GL_FUNC(glDrawElementsInstancedBaseVertex) \
-    USE_GL_FUNC(glDrawRangeElementsBaseVertex) \
-    USE_GL_FUNC(glMultiDrawElementsBaseVertex) \
-    /* GL_ARB_draw_instanced */ \
-    USE_GL_FUNC(glDrawArraysInstancedARB) \
-    USE_GL_FUNC(glDrawElementsInstancedARB) \
-    /* GL_ARB_framebuffer_object */ \
-    USE_GL_FUNC(glBindFramebuffer) \
-    USE_GL_FUNC(glBindRenderbuffer) \
-    USE_GL_FUNC(glBlitFramebuffer) \
-    USE_GL_FUNC(glCheckFramebufferStatus) \
-    USE_GL_FUNC(glDeleteFramebuffers) \
-    USE_GL_FUNC(glDeleteRenderbuffers) \
-    USE_GL_FUNC(glFramebufferRenderbuffer) \
-    USE_GL_FUNC(glFramebufferTexture1D) \
-    USE_GL_FUNC(glFramebufferTexture2D) \
-    USE_GL_FUNC(glFramebufferTexture3D) \
-    USE_GL_FUNC(glFramebufferTextureLayer) \
-    USE_GL_FUNC(glGenFramebuffers) \
-    USE_GL_FUNC(glGenRenderbuffers) \
-    USE_GL_FUNC(glGenerateMipmap) \
-    USE_GL_FUNC(glGetFramebufferAttachmentParameteriv) \
-    USE_GL_FUNC(glGetRenderbufferParameteriv) \
-    USE_GL_FUNC(glIsFramebuffer) \
-    USE_GL_FUNC(glIsRenderbuffer) \
-    USE_GL_FUNC(glRenderbufferStorage) \
-    USE_GL_FUNC(glRenderbufferStorageMultisample) \
-    /* GL_ARB_geometry_shader4 */ \
-    USE_GL_FUNC(glFramebufferTextureARB) \
-    USE_GL_FUNC(glFramebufferTextureFaceARB) \
-    USE_GL_FUNC(glFramebufferTextureLayerARB) \
-    USE_GL_FUNC(glProgramParameteriARB) \
-    /* GL_ARB_instanced_arrays */ \
-    USE_GL_FUNC(glVertexAttribDivisorARB) \
-    /* GL_ARB_internalformat_query */ \
-    USE_GL_FUNC(glGetInternalformativ) \
-    /* GL_ARB_internalformat_query2 */ \
-    USE_GL_FUNC(glGetInternalformati64v) \
-    /* GL_ARB_map_buffer_range */ \
-    USE_GL_FUNC(glFlushMappedBufferRange) \
-    USE_GL_FUNC(glMapBufferRange) \
-    /* GL_ARB_multisample */ \
-    USE_GL_FUNC(glSampleCoverageARB) \
-    /* GL_ARB_multitexture */ \
-    USE_GL_FUNC(glActiveTextureARB) \
-    USE_GL_FUNC(glClientActiveTextureARB) \
-    USE_GL_FUNC(glMultiTexCoord1fARB) \
-    USE_GL_FUNC(glMultiTexCoord1fvARB) \
-    USE_GL_FUNC(glMultiTexCoord2fARB) \
-    USE_GL_FUNC(glMultiTexCoord2fvARB) \
-    USE_GL_FUNC(glMultiTexCoord2svARB) \
-    USE_GL_FUNC(glMultiTexCoord3fARB) \
-    USE_GL_FUNC(glMultiTexCoord3fvARB) \
-    USE_GL_FUNC(glMultiTexCoord4fARB) \
-    USE_GL_FUNC(glMultiTexCoord4fvARB) \
-    USE_GL_FUNC(glMultiTexCoord4svARB) \
-    /* GL_ARB_occlusion_query */ \
-    USE_GL_FUNC(glBeginQueryARB) \
-    USE_GL_FUNC(glDeleteQueriesARB) \
-    USE_GL_FUNC(glEndQueryARB) \
-    USE_GL_FUNC(glGenQueriesARB) \
-    USE_GL_FUNC(glGetQueryivARB) \
-    USE_GL_FUNC(glGetQueryObjectivARB) \
-    USE_GL_FUNC(glGetQueryObjectuivARB) \
-    USE_GL_FUNC(glIsQueryARB) \
-    /* GL_ARB_point_parameters */ \
-    USE_GL_FUNC(glPointParameterfARB) \
-    USE_GL_FUNC(glPointParameterfvARB) \
-    /* GL_ARB_provoking_vertex */ \
-    USE_GL_FUNC(glProvokingVertex) \
-    /* GL_ARB_shader_objects */ \
-    USE_GL_FUNC(glAttachObjectARB) \
-    USE_GL_FUNC(glBindAttribLocationARB) \
-    USE_GL_FUNC(glCompileShaderARB) \
-    USE_GL_FUNC(glCreateProgramObjectARB) \
-    USE_GL_FUNC(glCreateShaderObjectARB) \
-    USE_GL_FUNC(glDeleteObjectARB) \
-    USE_GL_FUNC(glDetachObjectARB) \
-    USE_GL_FUNC(glGetActiveUniformARB) \
-    USE_GL_FUNC(glGetAttachedObjectsARB) \
-    USE_GL_FUNC(glGetAttribLocationARB) \
-    USE_GL_FUNC(glGetHandleARB) \
-    USE_GL_FUNC(glGetInfoLogARB) \
-    USE_GL_FUNC(glGetObjectParameterfvARB) \
-    USE_GL_FUNC(glGetObjectParameterivARB) \
-    USE_GL_FUNC(glGetShaderSourceARB) \
-    USE_GL_FUNC(glGetUniformLocationARB) \
-    USE_GL_FUNC(glGetUniformfvARB) \
-    USE_GL_FUNC(glGetUniformivARB) \
-    USE_GL_FUNC(glLinkProgramARB) \
-    USE_GL_FUNC(glShaderSourceARB) \
-    USE_GL_FUNC(glUniform1fARB) \
-    USE_GL_FUNC(glUniform1fvARB) \
-    USE_GL_FUNC(glUniform1iARB) \
-    USE_GL_FUNC(glUniform1ivARB) \
-    USE_GL_FUNC(glUniform2fARB) \
-    USE_GL_FUNC(glUniform2fvARB) \
-    USE_GL_FUNC(glUniform2iARB) \
-    USE_GL_FUNC(glUniform2ivARB) \
-    USE_GL_FUNC(glUniform3fARB) \
-    USE_GL_FUNC(glUniform3fvARB) \
-    USE_GL_FUNC(glUniform3iARB) \
-    USE_GL_FUNC(glUniform3ivARB) \
-    USE_GL_FUNC(glUniform4fARB) \
-    USE_GL_FUNC(glUniform4fvARB) \
-    USE_GL_FUNC(glUniform4iARB) \
-    USE_GL_FUNC(glUniform4ivARB) \
-    USE_GL_FUNC(glUniformMatrix2fvARB) \
-    USE_GL_FUNC(glUniformMatrix3fvARB) \
-    USE_GL_FUNC(glUniformMatrix4fvARB) \
-    USE_GL_FUNC(glUseProgramObjectARB) \
-    USE_GL_FUNC(glValidateProgramARB) \
-    /* GL_ARB_sync */ \
-    USE_GL_FUNC(glClientWaitSync) \
-    USE_GL_FUNC(glDeleteSync) \
-    USE_GL_FUNC(glFenceSync) \
-    USE_GL_FUNC(glGetInteger64v) \
-    USE_GL_FUNC(glGetSynciv) \
-    USE_GL_FUNC(glIsSync) \
-    USE_GL_FUNC(glWaitSync) \
-    /* GL_ARB_texture_compression */ \
-    USE_GL_FUNC(glCompressedTexImage2DARB) \
-    USE_GL_FUNC(glCompressedTexImage3DARB) \
-    USE_GL_FUNC(glCompressedTexSubImage2DARB) \
-    USE_GL_FUNC(glCompressedTexSubImage3DARB) \
-    USE_GL_FUNC(glGetCompressedTexImageARB) \
-    /* GL_ARB_timer_query */ \
-    USE_GL_FUNC(glQueryCounter) \
-    USE_GL_FUNC(glGetQueryObjectui64v) \
-    /* GL_ARB_uniform_buffer_object */ \
-    USE_GL_FUNC(glBindBufferBase) \
-    USE_GL_FUNC(glBindBufferRange) \
-    USE_GL_FUNC(glGetActiveUniformBlockName) \
-    USE_GL_FUNC(glGetActiveUniformBlockiv) \
-    USE_GL_FUNC(glGetActiveUniformName) \
-    USE_GL_FUNC(glGetActiveUniformsiv) \
-    USE_GL_FUNC(glGetIntegeri_v) \
-    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) \
-    USE_GL_FUNC(glBufferSubDataARB) \
-    USE_GL_FUNC(glDeleteBuffersARB) \
-    USE_GL_FUNC(glGenBuffersARB) \
-    USE_GL_FUNC(glGetBufferParameterivARB) \
-    USE_GL_FUNC(glGetBufferPointervARB) \
-    USE_GL_FUNC(glGetBufferSubDataARB) \
-    USE_GL_FUNC(glIsBufferARB) \
-    USE_GL_FUNC(glMapBufferARB) \
-    USE_GL_FUNC(glUnmapBufferARB) \
-    /* GL_ARB_vertex_program */ \
-    USE_GL_FUNC(glBindProgramARB) \
-    USE_GL_FUNC(glDeleteProgramsARB) \
-    USE_GL_FUNC(glDisableVertexAttribArrayARB) \
-    USE_GL_FUNC(glEnableVertexAttribArrayARB) \
-    USE_GL_FUNC(glGenProgramsARB) \
-    USE_GL_FUNC(glGetProgramivARB) \
-    USE_GL_FUNC(glProgramEnvParameter4fvARB) \
-    USE_GL_FUNC(glProgramLocalParameter4fvARB) \
-    USE_GL_FUNC(glProgramStringARB) \
-    USE_GL_FUNC(glVertexAttrib1dARB) \
-    USE_GL_FUNC(glVertexAttrib1dvARB) \
-    USE_GL_FUNC(glVertexAttrib1fARB) \
-    USE_GL_FUNC(glVertexAttrib1fvARB) \
-    USE_GL_FUNC(glVertexAttrib1sARB) \
-    USE_GL_FUNC(glVertexAttrib1svARB) \
-    USE_GL_FUNC(glVertexAttrib2dARB) \
-    USE_GL_FUNC(glVertexAttrib2dvARB) \
-    USE_GL_FUNC(glVertexAttrib2fARB) \
-    USE_GL_FUNC(glVertexAttrib2fvARB) \
-    USE_GL_FUNC(glVertexAttrib2sARB) \
-    USE_GL_FUNC(glVertexAttrib2svARB) \
-    USE_GL_FUNC(glVertexAttrib3dARB) \
-    USE_GL_FUNC(glVertexAttrib3dvARB) \
-    USE_GL_FUNC(glVertexAttrib3fARB) \
-    USE_GL_FUNC(glVertexAttrib3fvARB) \
-    USE_GL_FUNC(glVertexAttrib3sARB) \
-    USE_GL_FUNC(glVertexAttrib3svARB) \
-    USE_GL_FUNC(glVertexAttrib4NbvARB) \
-    USE_GL_FUNC(glVertexAttrib4NivARB) \
-    USE_GL_FUNC(glVertexAttrib4NsvARB) \
-    USE_GL_FUNC(glVertexAttrib4NubARB) \
-    USE_GL_FUNC(glVertexAttrib4NubvARB) \
-    USE_GL_FUNC(glVertexAttrib4NuivARB) \
-    USE_GL_FUNC(glVertexAttrib4NusvARB) \
-    USE_GL_FUNC(glVertexAttrib4bvARB) \
-    USE_GL_FUNC(glVertexAttrib4dARB) \
-    USE_GL_FUNC(glVertexAttrib4dvARB) \
-    USE_GL_FUNC(glVertexAttrib4fARB) \
-    USE_GL_FUNC(glVertexAttrib4fvARB) \
-    USE_GL_FUNC(glVertexAttrib4ivARB) \
-    USE_GL_FUNC(glVertexAttrib4sARB) \
-    USE_GL_FUNC(glVertexAttrib4svARB) \
-    USE_GL_FUNC(glVertexAttrib4ubvARB) \
-    USE_GL_FUNC(glVertexAttrib4uivARB) \
-    USE_GL_FUNC(glVertexAttrib4usvARB) \
-    USE_GL_FUNC(glVertexAttribPointerARB) \
-    /* GL_ATI_fragment_shader */ \
-    USE_GL_FUNC(glAlphaFragmentOp1ATI) \
-    USE_GL_FUNC(glAlphaFragmentOp2ATI) \
-    USE_GL_FUNC(glAlphaFragmentOp3ATI) \
-    USE_GL_FUNC(glBeginFragmentShaderATI) \
-    USE_GL_FUNC(glBindFragmentShaderATI) \
-    USE_GL_FUNC(glColorFragmentOp1ATI) \
-    USE_GL_FUNC(glColorFragmentOp2ATI) \
-    USE_GL_FUNC(glColorFragmentOp3ATI) \
-    USE_GL_FUNC(glDeleteFragmentShaderATI) \
-    USE_GL_FUNC(glEndFragmentShaderATI) \
-    USE_GL_FUNC(glGenFragmentShadersATI) \
-    USE_GL_FUNC(glPassTexCoordATI) \
-    USE_GL_FUNC(glSampleMapATI) \
-    USE_GL_FUNC(glSetFragmentShaderConstantATI) \
-    /* GL_ATI_separate_stencil */ \
-    USE_GL_FUNC(glStencilOpSeparateATI) \
-    USE_GL_FUNC(glStencilFuncSeparateATI) \
-    /* GL_EXT_blend_color */ \
-    USE_GL_FUNC(glBlendColorEXT) \
-    /* GL_EXT_blend_equation_separate */ \
-    USE_GL_FUNC(glBlendFuncSeparateEXT) \
-    /* GL_EXT_blend_func_separate */ \
-    USE_GL_FUNC(glBlendEquationSeparateEXT) \
-    /* GL_EXT_blend_minmax */ \
-    USE_GL_FUNC(glBlendEquationEXT) \
-    /* GL_EXT_depth_bounds_test */ \
-    USE_GL_FUNC(glDepthBoundsEXT) \
-    /* GL_EXT_draw_buffers2 */ \
-    USE_GL_FUNC(glColorMaskIndexedEXT) \
-    USE_GL_FUNC(glDisableIndexedEXT) \
-    USE_GL_FUNC(glEnableIndexedEXT) \
-    USE_GL_FUNC(glGetBooleanIndexedvEXT) \
-    USE_GL_FUNC(glGetIntegerIndexedvEXT) \
-    USE_GL_FUNC(glIsEnabledIndexedEXT) \
-    /* GL_EXT_fog_coord */ \
-    USE_GL_FUNC(glFogCoordPointerEXT) \
-    USE_GL_FUNC(glFogCoorddEXT) \
-    USE_GL_FUNC(glFogCoorddvEXT) \
-    USE_GL_FUNC(glFogCoordfEXT) \
-    USE_GL_FUNC(glFogCoordfvEXT) \
-    /* GL_EXT_framebuffer_blit */ \
-    USE_GL_FUNC(glBlitFramebufferEXT) \
-    /* GL_EXT_framebuffer_multisample */ \
-    USE_GL_FUNC(glRenderbufferStorageMultisampleEXT) \
-    /* GL_EXT_framebuffer_object */ \
-    USE_GL_FUNC(glBindFramebufferEXT) \
-    USE_GL_FUNC(glBindRenderbufferEXT) \
-    USE_GL_FUNC(glCheckFramebufferStatusEXT) \
-    USE_GL_FUNC(glDeleteFramebuffersEXT) \
-    USE_GL_FUNC(glDeleteRenderbuffersEXT) \
-    USE_GL_FUNC(glFramebufferRenderbufferEXT) \
-    USE_GL_FUNC(glFramebufferTexture1DEXT) \
-    USE_GL_FUNC(glFramebufferTexture2DEXT) \
-    USE_GL_FUNC(glFramebufferTexture3DEXT) \
-    USE_GL_FUNC(glGenFramebuffersEXT) \
-    USE_GL_FUNC(glGenRenderbuffersEXT) \
-    USE_GL_FUNC(glGenerateMipmapEXT) \
-    USE_GL_FUNC(glGetFramebufferAttachmentParameterivEXT) \
-    USE_GL_FUNC(glGetRenderbufferParameterivEXT) \
-    USE_GL_FUNC(glIsFramebufferEXT) \
-    USE_GL_FUNC(glIsRenderbufferEXT) \
-    USE_GL_FUNC(glRenderbufferStorageEXT) \
-    /* GL_EXT_gpu_program_parameters */ \
-    USE_GL_FUNC(glProgramEnvParameters4fvEXT) \
-    USE_GL_FUNC(glProgramLocalParameters4fvEXT) \
-    /* GL_EXT_gpu_shader4 */\
-    USE_GL_FUNC(glBindFragDataLocationEXT) \
-    USE_GL_FUNC(glGetFragDataLocationEXT) \
-    USE_GL_FUNC(glGetUniformuivEXT) \
-    USE_GL_FUNC(glGetVertexAttribIivEXT) \
-    USE_GL_FUNC(glGetVertexAttribIuivEXT) \
-    USE_GL_FUNC(glUniform1uiEXT) \
-    USE_GL_FUNC(glUniform1uivEXT) \
-    USE_GL_FUNC(glUniform2uiEXT) \
-    USE_GL_FUNC(glUniform2uivEXT) \
-    USE_GL_FUNC(glUniform3uiEXT) \
-    USE_GL_FUNC(glUniform3uivEXT) \
-    USE_GL_FUNC(glUniform4uiEXT) \
-    USE_GL_FUNC(glUniform4uivEXT) \
-    USE_GL_FUNC(glVertexAttribI1iEXT) \
-    USE_GL_FUNC(glVertexAttribI1ivEXT) \
-    USE_GL_FUNC(glVertexAttribI1uiEXT) \
-    USE_GL_FUNC(glVertexAttribI1uivEXT) \
-    USE_GL_FUNC(glVertexAttribI2iEXT) \
-    USE_GL_FUNC(glVertexAttribI2ivEXT) \
-    USE_GL_FUNC(glVertexAttribI2uiEXT) \
-    USE_GL_FUNC(glVertexAttribI2uivEXT) \
-    USE_GL_FUNC(glVertexAttribI3iEXT) \
-    USE_GL_FUNC(glVertexAttribI3ivEXT) \
-    USE_GL_FUNC(glVertexAttribI3uiEXT) \
-    USE_GL_FUNC(glVertexAttribI3uivEXT) \
-    USE_GL_FUNC(glVertexAttribI4bvEXT) \
-    USE_GL_FUNC(glVertexAttribI4iEXT) \
-    USE_GL_FUNC(glVertexAttribI4ivEXT) \
-    USE_GL_FUNC(glVertexAttribI4svEXT) \
-    USE_GL_FUNC(glVertexAttribI4ubvEXT) \
-    USE_GL_FUNC(glVertexAttribI4uiEXT) \
-    USE_GL_FUNC(glVertexAttribI4uivEXT) \
-    USE_GL_FUNC(glVertexAttribI4usvEXT) \
-    USE_GL_FUNC(glVertexAttribIPointerEXT) \
-    /* GL_EXT_point_parameters */ \
-    USE_GL_FUNC(glPointParameterfEXT) \
-    USE_GL_FUNC(glPointParameterfvEXT) \
-    /* GL_EXT_provoking_vertex */ \
-    USE_GL_FUNC(glProvokingVertexEXT) \
-    /* GL_EXT_secondary_color */ \
-    USE_GL_FUNC(glSecondaryColor3fEXT) \
-    USE_GL_FUNC(glSecondaryColor3fvEXT) \
-    USE_GL_FUNC(glSecondaryColor3ubEXT) \
-    USE_GL_FUNC(glSecondaryColor3ubvEXT) \
-    USE_GL_FUNC(glSecondaryColorPointerEXT) \
-    /* GL_EXT_stencil_two_side */ \
-    USE_GL_FUNC(glActiveStencilFaceEXT) \
-    /* GL_EXT_texture3D */ \
-    USE_GL_FUNC(glTexImage3D) \
-    USE_GL_FUNC(glTexImage3DEXT) \
-    USE_GL_FUNC(glTexSubImage3D) \
-    USE_GL_FUNC(glTexSubImage3DEXT) \
-    /* GL_NV_fence */ \
-    USE_GL_FUNC(glDeleteFencesNV) \
-    USE_GL_FUNC(glFinishFenceNV) \
-    USE_GL_FUNC(glGenFencesNV) \
-    USE_GL_FUNC(glGetFenceivNV) \
-    USE_GL_FUNC(glIsFenceNV) \
-    USE_GL_FUNC(glSetFenceNV) \
-    USE_GL_FUNC(glTestFenceNV) \
-    /* GL_NV_half_float */ \
-    USE_GL_FUNC(glColor3hNV) \
-    USE_GL_FUNC(glColor3hvNV) \
-    USE_GL_FUNC(glColor4hNV) \
-    USE_GL_FUNC(glColor4hvNV) \
-    USE_GL_FUNC(glFogCoordhNV) \
-    USE_GL_FUNC(glFogCoordhvNV) \
-    USE_GL_FUNC(glMultiTexCoord1hNV) \
-    USE_GL_FUNC(glMultiTexCoord1hvNV) \
-    USE_GL_FUNC(glMultiTexCoord2hNV) \
-    USE_GL_FUNC(glMultiTexCoord2hvNV) \
-    USE_GL_FUNC(glMultiTexCoord3hNV) \
-    USE_GL_FUNC(glMultiTexCoord3hvNV) \
-    USE_GL_FUNC(glMultiTexCoord4hNV) \
-    USE_GL_FUNC(glMultiTexCoord4hvNV) \
-    USE_GL_FUNC(glNormal3hNV) \
-    USE_GL_FUNC(glNormal3hvNV) \
-    USE_GL_FUNC(glSecondaryColor3hNV) \
-    USE_GL_FUNC(glSecondaryColor3hvNV) \
-    USE_GL_FUNC(glTexCoord1hNV) \
-    USE_GL_FUNC(glTexCoord1hvNV) \
-    USE_GL_FUNC(glTexCoord2hNV) \
-    USE_GL_FUNC(glTexCoord2hvNV) \
-    USE_GL_FUNC(glTexCoord3hNV) \
-    USE_GL_FUNC(glTexCoord3hvNV) \
-    USE_GL_FUNC(glTexCoord4hNV) \
-    USE_GL_FUNC(glTexCoord4hvNV) \
-    USE_GL_FUNC(glVertex2hNV) \
-    USE_GL_FUNC(glVertex2hvNV) \
-    USE_GL_FUNC(glVertex3hNV) \
-    USE_GL_FUNC(glVertex3hvNV) \
-    USE_GL_FUNC(glVertex4hNV) \
-    USE_GL_FUNC(glVertex4hvNV) \
-    USE_GL_FUNC(glVertexAttrib1hNV) \
-    USE_GL_FUNC(glVertexAttrib1hvNV) \
-    USE_GL_FUNC(glVertexAttrib2hNV) \
-    USE_GL_FUNC(glVertexAttrib2hvNV) \
-    USE_GL_FUNC(glVertexAttrib3hNV) \
-    USE_GL_FUNC(glVertexAttrib3hvNV) \
-    USE_GL_FUNC(glVertexAttrib4hNV) \
-    USE_GL_FUNC(glVertexAttrib4hvNV) \
-    USE_GL_FUNC(glVertexAttribs1hvNV) \
-    USE_GL_FUNC(glVertexAttribs2hvNV) \
-    USE_GL_FUNC(glVertexAttribs3hvNV) \
-    USE_GL_FUNC(glVertexAttribs4hvNV) \
-    USE_GL_FUNC(glVertexWeighthNV) \
-    USE_GL_FUNC(glVertexWeighthvNV) \
-    /* GL_NV_point_sprite */ \
-    USE_GL_FUNC(glPointParameteri) \
-    USE_GL_FUNC(glPointParameteriNV) \
-    USE_GL_FUNC(glPointParameteriv) \
-    USE_GL_FUNC(glPointParameterivNV) \
-    /* GL_NV_register_combiners */ \
-    USE_GL_FUNC(glCombinerInputNV) \
-    USE_GL_FUNC(glCombinerOutputNV) \
-    USE_GL_FUNC(glCombinerParameterfNV) \
-    USE_GL_FUNC(glCombinerParameterfvNV) \
-    USE_GL_FUNC(glCombinerParameteriNV) \
-    USE_GL_FUNC(glCombinerParameterivNV) \
-    USE_GL_FUNC(glFinalCombinerInputNV) \
-    /* WGL extensions */ \
-    USE_GL_FUNC(wglChoosePixelFormatARB) \
-    USE_GL_FUNC(wglGetExtensionsStringARB) \
-    USE_GL_FUNC(wglGetPixelFormatAttribfvARB) \
-    USE_GL_FUNC(wglGetPixelFormatAttribivARB) \
-    USE_GL_FUNC(wglSetPixelFormatWINE) \
-    USE_GL_FUNC(wglSwapIntervalEXT)
-
 #endif /* __WINE_WINED3D_GL */
index 530287f..16a851e 100644 (file)
@@ -307,6 +307,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
     if (appkey) RegCloseKey( appkey );
     if (hkey) RegCloseKey( hkey );
 
+    wined3d_dxtn_init();
+
     return TRUE;
 }
 
@@ -338,6 +340,9 @@ static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
 
     DeleteCriticalSection(&wined3d_wndproc_cs);
     DeleteCriticalSection(&wined3d_cs);
+
+    wined3d_dxtn_free();
+
     return TRUE;
 }
 
@@ -503,6 +508,11 @@ void wined3d_unregister_window(HWND window)
     wined3d_wndproc_mutex_unlock();
 }
 
+void wined3d_strictdrawing_set(int value)
+{
+    wined3d_settings.strict_draw_ordering = value;
+}
+
 /* At process attach */
 BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
 {
index 8119717..6e256e0 100644 (file)
 #include "wined3d_gl.h"
 #include <wine/wgl_driver.h>
 
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+#endif
+
 /* Driver quirks */
 #define WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT       0x00000001
 #define WINED3D_QUIRK_SET_TEXCOORD_W            0x00000002
@@ -100,14 +104,14 @@ enum complex_fixup
 #include <pshpack2.h>
 struct color_fixup_desc
 {
-    unsigned x_sign_fixup : 1;
-    unsigned x_source : 3;
-    unsigned y_sign_fixup : 1;
-    unsigned y_source : 3;
-    unsigned z_sign_fixup : 1;
-    unsigned z_source : 3;
-    unsigned w_sign_fixup : 1;
-    unsigned w_source : 3;
+    unsigned short x_sign_fixup : 1;
+    unsigned short x_source : 3;
+    unsigned short y_sign_fixup : 1;
+    unsigned short y_source : 3;
+    unsigned short z_sign_fixup : 1;
+    unsigned short z_source : 3;
+    unsigned short w_sign_fixup : 1;
+    unsigned short w_source : 3;
 };
 #include <poppack.h>
 
@@ -150,6 +154,14 @@ static inline BOOL is_complex_fixup(struct color_fixup_desc fixup)
     return fixup.x_source == CHANNEL_SOURCE_COMPLEX0 || fixup.x_source == CHANNEL_SOURCE_COMPLEX1;
 }
 
+static inline BOOL is_same_fixup(struct color_fixup_desc f1, struct color_fixup_desc f2)
+{
+    return f1.x_sign_fixup == f2.x_sign_fixup && f1.x_source == f2.x_source
+            && f1.y_sign_fixup == f2.y_sign_fixup && f1.y_source == f2.y_source
+            && f1.z_sign_fixup == f2.z_sign_fixup && f1.z_source == f2.z_source
+            && f1.w_sign_fixup == f2.w_sign_fixup && f1.w_source == f2.w_source;
+}
+
 static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup)
 {
     enum complex_fixup complex_fixup = 0;
@@ -183,20 +195,19 @@ struct min_lookup
 };
 
 extern const struct min_lookup minMipLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
-extern const struct min_lookup minMipLookup_noFilter[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
-extern const struct min_lookup minMipLookup_noMip[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
 extern const GLenum magLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
-extern const GLenum magLookup_noFilter[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
 
-static inline GLenum wined3d_gl_mag_filter(const GLenum mag_lookup[], enum wined3d_texture_filter_type mag_filter)
+GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f) DECLSPEC_HIDDEN;
+
+static inline GLenum wined3d_gl_mag_filter(enum wined3d_texture_filter_type mag_filter)
 {
-    return mag_lookup[mag_filter];
+    return magLookup[mag_filter];
 }
 
-static inline GLenum wined3d_gl_min_mip_filter(const struct min_lookup min_mip_lookup[],
-        enum wined3d_texture_filter_type min_filter, enum wined3d_texture_filter_type mip_filter)
+static inline GLenum wined3d_gl_min_mip_filter(enum wined3d_texture_filter_type min_filter,
+        enum wined3d_texture_filter_type mip_filter)
 {
-    return min_mip_lookup[min_filter].mip[mip_filter];
+    return minMipLookup[min_filter].mip[mip_filter];
 }
 
 /* float_16_to_32() and float_32_to_16() (see implementation in
@@ -280,13 +291,18 @@ struct wined3d_settings
 
 extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN;
 
-enum wined3d_sampler_texture_type
+enum wined3d_shader_resource_type
 {
-    WINED3DSTT_UNKNOWN = 0,
-    WINED3DSTT_1D = 1,
-    WINED3DSTT_2D = 2,
-    WINED3DSTT_CUBE = 3,
-    WINED3DSTT_VOLUME = 4,
+    WINED3D_SHADER_RESOURCE_NONE,
+    WINED3D_SHADER_RESOURCE_BUFFER,
+    WINED3D_SHADER_RESOURCE_TEXTURE_1D,
+    WINED3D_SHADER_RESOURCE_TEXTURE_2D,
+    WINED3D_SHADER_RESOURCE_TEXTURE_2DMS,
+    WINED3D_SHADER_RESOURCE_TEXTURE_3D,
+    WINED3D_SHADER_RESOURCE_TEXTURE_CUBE,
+    WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY,
+    WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY,
+    WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY,
 };
 
 #define WINED3D_SHADER_CONST_VS_F           0x00000001
@@ -339,6 +355,8 @@ enum wined3d_data_type
     WINED3D_DATA_RESOURCE,
     WINED3D_DATA_SAMPLER,
     WINED3D_DATA_UINT,
+    WINED3D_DATA_UNORM,
+    WINED3D_DATA_SNORM,
 };
 
 enum wined3d_immconst_type
@@ -502,8 +520,10 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
     WINED3DSIH_MOVA,
     WINED3DSIH_MOVC,
     WINED3DSIH_MUL,
+    WINED3DSIH_NE,
     WINED3DSIH_NOP,
     WINED3DSIH_NRM,
+    WINED3DSIH_OR,
     WINED3DSIH_PHASE,
     WINED3DSIH_POW,
     WINED3DSIH_RCP,
@@ -544,6 +564,7 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
     WINED3DSIH_TEXREG2GB,
     WINED3DSIH_TEXREG2RGB,
     WINED3DSIH_UDIV,
+    WINED3DSIH_UGE,
     WINED3DSIH_USHR,
     WINED3DSIH_UTOF,
     WINED3DSIH_XOR,
@@ -565,6 +586,26 @@ struct wined3d_shader_version
     BYTE minor;
 };
 
+struct wined3d_shader_resource_info
+{
+    enum wined3d_shader_resource_type type;
+    enum wined3d_data_type data_type;
+};
+
+struct wined3d_shader_sampler_map_entry
+{
+    unsigned int resource_idx;
+    unsigned int sampler_idx;
+    unsigned int bind_idx;
+};
+
+struct wined3d_shader_sampler_map
+{
+    struct wined3d_shader_sampler_map_entry *entries;
+    size_t size;
+    size_t count;
+};
+
 #define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor))
 
 struct wined3d_shader_reg_maps
@@ -584,7 +625,8 @@ struct wined3d_shader_reg_maps
     WORD local_bool_consts;                 /* MAX_CONST_B, 16 */
     UINT cb_sizes[WINED3D_MAX_CBS];
 
-    enum wined3d_sampler_texture_type sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
+    struct wined3d_shader_resource_info resource_info[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
+    struct wined3d_shader_sampler_map sampler_map;
     BYTE bumpmat;                           /* MAX_TEXTURES, 8 */
     BYTE luminanceparams;                   /* MAX_TEXTURES, 8 */
 
@@ -669,7 +711,8 @@ struct wined3d_shader_semantic
 {
     enum wined3d_decl_usage usage;
     UINT usage_idx;
-    enum wined3d_sampler_texture_type sampler_type;
+    enum wined3d_shader_resource_type resource_type;
+    enum wined3d_data_type resource_data_type;
     struct wined3d_shader_dst_param reg;
 };
 
@@ -930,6 +973,17 @@ struct wined3d_bo_address
     BYTE *addr;
 };
 
+struct wined3d_const_bo_address
+{
+    GLuint buffer_object;
+    const BYTE *addr;
+};
+
+static inline struct wined3d_const_bo_address *wined3d_const_bo_address(struct wined3d_bo_address *data)
+{
+    return (struct wined3d_const_bo_address *)data;
+}
+
 struct wined3d_stream_info_element
 {
     const struct wined3d_format *format;
@@ -974,7 +1028,10 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
 #define STATE_CONSTANT_BUFFER(a) (STATE_SHADER(WINED3D_SHADER_TYPE_COUNT) + (a))
 #define STATE_IS_CONSTANT_BUFFER(a) ((a) >= STATE_CONSTANT_BUFFER(0) && (a) < STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COUNT))
 
-#define STATE_TRANSFORM(a) (STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COUNT) + (a) - 1)
+#define STATE_SHADER_RESOURCE_BINDING (STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COUNT))
+#define STATE_IS_SHADER_RESOURCE_BINDING(a) ((a) == STATE_SHADER_RESOURCE_BINDING)
+
+#define STATE_TRANSFORM(a) (STATE_SHADER_RESOURCE_BINDING + (a))
 #define STATE_IS_TRANSFORM(a) ((a) >= STATE_TRANSFORM(1) && (a) <= STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)))
 
 #define STATE_STREAMSRC (STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)) + 1)
@@ -1111,9 +1168,8 @@ struct wined3d_context
     DWORD lowest_disabled_stage : 4;    /* Max MAX_TEXTURES, 8 */
     DWORD rebind_fbo : 1;
     DWORD needs_set : 1;
-    DWORD hdc_is_private : 1;
-    DWORD hdc_has_format : 1;           /* only meaningful if hdc_is_private */
-    DWORD padding : 16;
+    DWORD update_shader_resource_bindings : 1;
+    DWORD padding : 17;
     DWORD shader_update_mask;
     DWORD constant_update_mask;
     DWORD                   numbered_array_mask;
@@ -1131,7 +1187,6 @@ struct wined3d_context
     HGLRC restore_ctx;
     HDC restore_dc;
     int restore_pf;
-    HWND restore_pf_win;
     HGLRC                   glCtx;
     HWND                    win_handle;
     HDC                     hdc;
@@ -1511,6 +1566,7 @@ enum wined3d_pci_device
     CARD_NVIDIA_GEFORCE_GTX670      = 0x1189,
     CARD_NVIDIA_GEFORCE_GTX670MX    = 0x11a1,
     CARD_NVIDIA_GEFORCE_GTX680      = 0x1180,
+    CARD_NVIDIA_GEFORCE_GT750M      = 0x0fe9,
     CARD_NVIDIA_GEFORCE_GTX750      = 0x1381,
     CARD_NVIDIA_GEFORCE_GTX750TI    = 0x1380,
     CARD_NVIDIA_GEFORCE_GTX760      = 0x1187,
@@ -1519,6 +1575,7 @@ enum wined3d_pci_device
     CARD_NVIDIA_GEFORCE_GTX770      = 0x1184,
     CARD_NVIDIA_GEFORCE_GTX780      = 0x1004,
     CARD_NVIDIA_GEFORCE_GTX780TI    = 0x100a,
+    CARD_NVIDIA_GEFORCE_GTX970      = 0x13c2,
 
     CARD_VMWARE_SVGA3D              = 0x0405,
 
@@ -1964,6 +2021,7 @@ struct wined3d_device
 
     struct list             resources; /* a linked list to track resources created by the device */
     struct list             shaders;   /* a linked list to track shaders (pixel and vertex)      */
+    struct wine_rb_tree samplers;
 
     /* Render Target Support */
     struct wined3d_fb_state fb;
@@ -2096,26 +2154,11 @@ void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DEC
 /* Tests show that the start address of resources is 32 byte aligned */
 #define RESOURCE_ALIGNMENT 16
 
-enum wined3d_texture_state
-{
-    WINED3DTEXSTA_ADDRESSU       = 0,
-    WINED3DTEXSTA_ADDRESSV       = 1,
-    WINED3DTEXSTA_ADDRESSW       = 2,
-    WINED3DTEXSTA_BORDERCOLOR    = 3,
-    WINED3DTEXSTA_MAGFILTER      = 4,
-    WINED3DTEXSTA_MINFILTER      = 5,
-    WINED3DTEXSTA_MIPFILTER      = 6,
-    WINED3DTEXSTA_MAXMIPLEVEL    = 7,
-    WINED3DTEXSTA_MAXANISOTROPY  = 8,
-    WINED3DTEXSTA_SRGBTEXTURE    = 9,
-    WINED3DTEXSTA_SHADOW         = 10,
-    MAX_WINETEXTURESTATES        = 11,
-};
-
 struct gl_texture
 {
-    DWORD                   states[MAX_WINETEXTURESTATES];
-    GLuint                  name;
+    struct wined3d_sampler_desc sampler_desc;
+    unsigned int base_level;
+    GLuint name;
 };
 
 struct wined3d_texture_ops
@@ -2125,13 +2168,26 @@ struct wined3d_texture_ops
     void (*texture_sub_resource_add_dirty_region)(struct wined3d_resource *sub_resource,
             const struct wined3d_box *dirty_region);
     void (*texture_sub_resource_cleanup)(struct wined3d_resource *sub_resource);
+    void (*texture_sub_resource_invalidate_location)(struct wined3d_resource *sub_resource, DWORD location);
+    void (*texture_sub_resource_validate_location)(struct wined3d_resource *sub_resource, DWORD location);
+    void (*texture_sub_resource_upload_data)(struct wined3d_resource *sub_resource,
+            const struct wined3d_context *context, const struct wined3d_sub_resource_data *data);
+    void (*texture_prepare_texture)(struct wined3d_texture *texture,
+            struct wined3d_context *context, BOOL srgb);
 };
 
 #define WINED3D_TEXTURE_COND_NP2            0x00000001
 #define WINED3D_TEXTURE_POW2_MAT_IDENT      0x00000002
 #define WINED3D_TEXTURE_IS_SRGB             0x00000004
-#define WINED3D_TEXTURE_RGB_VALID           0x00000008
-#define WINED3D_TEXTURE_SRGB_VALID          0x00000010
+#define WINED3D_TEXTURE_RGB_ALLOCATED       0x00000008
+#define WINED3D_TEXTURE_RGB_VALID           0x00000010
+#define WINED3D_TEXTURE_SRGB_ALLOCATED      0x00000020
+#define WINED3D_TEXTURE_SRGB_VALID          0x00000040
+#define WINED3D_TEXTURE_CONVERTED           0x00000080
+#define WINED3D_TEXTURE_PIN_SYSMEM          0x00000100
+#define WINED3D_TEXTURE_DYNAMIC_MAP         0x00000200
+#define WINED3D_TEXTURE_NORMALIZED_COORDS   0x00000400
+#define WINED3D_TEXTURE_COLOR_KEY           0x00000800
 
 struct wined3d_texture
 {
@@ -2147,8 +2203,6 @@ struct wined3d_texture
     enum wined3d_texture_filter_type filter_type;
     DWORD sampler;
     DWORD flags;
-    const struct min_lookup *min_mip_lookup;
-    const GLenum *mag_lookup;
     GLenum target;
 
     /* Color keys for DDraw */
@@ -2156,6 +2210,7 @@ struct wined3d_texture
     struct wined3d_color_key src_blt_color_key;
     struct wined3d_color_key dst_overlay_color_key;
     struct wined3d_color_key src_overlay_color_key;
+    struct wined3d_color_key gl_color_key;
     DWORD color_key_flags;
 };
 
@@ -2170,15 +2225,17 @@ static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_t
     return srgb ? &texture->texture_srgb : &texture->texture_rgb;
 }
 
-void wined3d_texture_apply_state_changes(struct wined3d_texture *texture,
-        const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1],
-        const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture,
+        const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
 void wined3d_texture_bind(struct wined3d_texture *texture,
         struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
 void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture,
         struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
+void wined3d_texture_force_reload(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
 void wined3d_texture_load(struct wined3d_texture *texture,
         struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
+void wined3d_texture_prepare_texture(struct wined3d_texture *texture,
+        struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
 void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
 void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
         struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
@@ -2196,6 +2253,8 @@ void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
 
 const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN;
 
+#define WINED3D_VFLAG_CLIENT_STORAGE    0x00000001
+
 struct wined3d_volume
 {
     struct wined3d_resource resource;
@@ -2212,14 +2271,17 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc
     return CONTAINING_RECORD(resource, struct wined3d_volume, resource);
 }
 
+BOOL volume_prepare_system_memory(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
 HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc,
         unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN;
 void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
+void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) DECLSPEC_HIDDEN;
 void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context,
         BOOL srgb_mode) DECLSPEC_HIDDEN;
 void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN;
+void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN;
 void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
-        const struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
+        const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
 
 struct wined3d_surface_dib
 {
@@ -2282,8 +2344,6 @@ struct wined3d_surface
     struct wined3d_surface_dib dib;
     HDC                       hDC;
 
-    struct wined3d_color_key gl_color_key;
-
     struct list               renderbuffers;
     const struct wined3d_renderbuffer_entry *current_renderbuffer;
     SIZE ds_current_size;
@@ -2323,12 +2383,12 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location) D
 void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN;
 void surface_prepare_rb(struct wined3d_surface *surface,
         const struct wined3d_gl_info *gl_info, BOOL multisample) DECLSPEC_HIDDEN;
-void surface_prepare_texture(struct wined3d_surface *surface,
-        struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
 void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
         const struct wined3d_surface *rt) DECLSPEC_HIDDEN;
 void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) DECLSPEC_HIDDEN;
 void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
+HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface,
+        const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) DECLSPEC_HIDDEN;
 HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point,
         struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN;
 void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN;
@@ -2337,59 +2397,38 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w
         struct wined3d_surface **surface) DECLSPEC_HIDDEN;
 void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
 void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
+void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
+        const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point,
+        BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
 
 void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context,
         const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
 void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) DECLSPEC_HIDDEN;
 
 /* Surface flags: */
-#define SFLAG_CONVERTED         0x00000001 /* Converted for color keying or palettized. */
+#define SFLAG_DIBSECTION        0x00000001 /* Has a DIB section attached for GetDC. */
 #define SFLAG_DISCARD           0x00000002 /* ??? */
 #define SFLAG_NONPOW2           0x00000004 /* Surface sizes are not a power of 2 */
-#define SFLAG_NORMCOORD         0x00000008 /* Set if GL texture coordinates are normalized (non-texture rectangle). */
-#define SFLAG_DYNLOCK           0x00000010 /* Surface is often locked by the application. */
-#define SFLAG_PIN_SYSMEM        0x00000020 /* Keep the surface in sysmem, at the same address. */
-#define SFLAG_DCINUSE           0x00000040 /* Set between GetDC and ReleaseDC calls. */
-#define SFLAG_LOST              0x00000080 /* Surface lost flag for ddraw. */
-#define SFLAG_GLCKEY            0x00000100 /* The GL texture was created with a color key. */
-#define SFLAG_CLIENT            0x00000200 /* GL_APPLE_client_storage is used with this surface. */
-#define SFLAG_DIBSECTION        0x00000400 /* Has a DIB section attached for GetDC. */
-#define SFLAG_ALLOCATED         0x00000800 /* A GL texture is allocated for this surface. */
-#define SFLAG_SRGBALLOCATED     0x00001000 /* A sRGB GL texture is allocated for this surface. */
-
-/* In some conditions the surface memory must not be freed:
- * SFLAG_CONVERTED: Converting the data back would take too long
- * SFLAG_DYNLOCK: Avoid freeing the data for performance
- * SFLAG_CLIENT: OpenGL uses our memory as backup
- */
-#define SFLAG_DONOTFREE     (SFLAG_CONVERTED        | \
-                             SFLAG_DYNLOCK          | \
-                             SFLAG_CLIENT           | \
-                             SFLAG_PIN_SYSMEM)
-
-enum wined3d_conversion_type
-{
-    WINED3D_CT_NONE,
-    WINED3D_CT_PALETTED,
-    WINED3D_CT_CK_565,
-    WINED3D_CT_CK_5551,
-    WINED3D_CT_CK_RGB24,
-    WINED3D_CT_RGB32_888,
-    WINED3D_CT_CK_ARGB32,
-};
+#define SFLAG_LOST              0x00000008 /* Surface lost flag for ddraw. */
+#define SFLAG_CLIENT            0x00000010 /* GL_APPLE_client_storage is used with this surface. */
+#define SFLAG_DCINUSE           0x00000020 /* Set between GetDC and ReleaseDC calls. */
 
 struct wined3d_sampler
 {
+    struct wine_rb_entry entry;
     LONG refcount;
+    struct wined3d_device *device;
     void *parent;
+    struct wined3d_sampler_desc desc;
+    GLuint name;
 };
 
 struct wined3d_vertex_declaration_element
 {
     const struct wined3d_format *format;
     BOOL ffp_valid;
-    WORD input_slot;
-    WORD offset;
+    unsigned int input_slot;
+    unsigned int offset;
     UINT output_slot;
     BYTE method;
     BYTE usage;
@@ -2669,6 +2708,7 @@ struct wined3d_shader_resource_view
 {
     LONG refcount;
 
+    struct wined3d_resource *resource;
     void *parent;
     const struct wined3d_parent_ops *parent_ops;
 };
@@ -2690,9 +2730,9 @@ struct wined3d_swapchain
     struct wined3d_texture **back_buffers;
     struct wined3d_texture *front_buffer;
     struct wined3d_swapchain_desc desc;
-    struct wined3d_display_mode original_mode;
+    struct wined3d_display_mode original_mode, d3d_mode;
     struct wined3d_gamma_ramp orig_gamma;
-    BOOL render_to_fbo;
+    BOOL render_to_fbo, reapply_mode;
     const struct wined3d_format *ds_format;
     struct wined3d_palette *palette;
 
@@ -2710,6 +2750,7 @@ struct wined3d_swapchain
 
 void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) DECLSPEC_HIDDEN;
 
+void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN;
 struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
@@ -2814,7 +2855,6 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DE
 /* Math utils */
 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
         const struct wined3d_matrix *src2) DECLSPEC_HIDDEN;
-UINT wined3d_log2i(UINT32 x) DECLSPEC_HIDDEN;
 unsigned int count_bits(unsigned int mask) DECLSPEC_HIDDEN;
 
 void wined3d_release_dc(HWND window, HDC dc) DECLSPEC_HIDDEN;
@@ -2877,7 +2917,7 @@ struct wined3d_pixel_shader
 struct wined3d_shader
 {
     LONG ref;
-    struct wined3d_shader_limits limits;
+    const struct wined3d_shader_limits *limits;
     DWORD *function;
     UINT functionLength;
     BOOL load_local_constsF;
@@ -2900,6 +2940,7 @@ struct wined3d_shader
 
     struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
     struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
+    char *signature_strings;
 
     /* Pointer to the parent device */
     struct wined3d_device *device;
@@ -2913,7 +2954,7 @@ struct wined3d_shader
     } u;
 };
 
-void pixelshader_update_samplers(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN;
+void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN;
 void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
         BOOL position_transformed, struct ps_compile_args *args,
         const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
@@ -3064,6 +3105,13 @@ struct wined3d_rational
     UINT denominator;
 };
 
+struct wined3d_color_key_conversion
+{
+    enum wined3d_format_id dst_format;
+    void (*convert)(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width,
+            unsigned int height, const struct wined3d_palette *palette, const struct wined3d_color_key *color_key);
+};
+
 struct wined3d_format
 {
     enum wined3d_format_id id;
@@ -3111,6 +3159,8 @@ UINT wined3d_format_calculate_size(const struct wined3d_format *format,
         UINT alignment, UINT width, UINT height, UINT depth) DECLSPEC_HIDDEN;
 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface,
         const struct wined3d_color *color) DECLSPEC_HIDDEN;
+const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(
+        const struct wined3d_texture *texture, BOOL need_alpha_ck) DECLSPEC_HIDDEN;
 
 static inline BOOL use_vs(const struct wined3d_state *state)
 {
@@ -3132,6 +3182,9 @@ static inline void context_apply_state(struct wined3d_context *context,
     state_table[rep].apply(context, state, rep);
 }
 
+BOOL wined3d_dxtn_init(void) DECLSPEC_HIDDEN;
+void wined3d_dxtn_free(void) DECLSPEC_HIDDEN;
+
 /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
 #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
 
index fe90469..c0c4389 100644 (file)
 #ifndef __WINE_WINED3D_H
 #define __WINE_WINED3D_H
 
+#ifndef __WINE_CONFIG_H
+# error You must include config.h to use this header
+#endif
+
 #include <wine/list.h>
 
 #define WINED3D_OK                                              S_OK
@@ -241,6 +245,7 @@ enum wined3d_format_id
     WINED3DFMT_MULTI2_ARGB8                 = WINEMAKEFOURCC('M','E','T','1'),
     WINED3DFMT_G8R8_G8B8                    = WINEMAKEFOURCC('G','R','G','B'),
     WINED3DFMT_R8G8_B8G8                    = WINEMAKEFOURCC('R','G','B','G'),
+    WINED3DFMT_ATI1N                        = WINEMAKEFOURCC('A','T','I','1'),
     WINED3DFMT_ATI2N                        = WINEMAKEFOURCC('A','T','I','2'),
     WINED3DFMT_INST                         = WINEMAKEFOURCC('I','N','S','T'),
     WINED3DFMT_NVDB                         = WINEMAKEFOURCC('N','V','D','B'),
@@ -933,6 +938,12 @@ enum wined3d_display_rotation
 #define WINED3DCREATE_MIXED_VERTEXPROCESSING                    0x00000080
 #define WINED3DCREATE_DISABLE_DRIVER_MANAGEMENT                 0x00000100
 #define WINED3DCREATE_ADAPTERGROUP_DEVICE                       0x00000200
+#define WINED3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX              0x00000400
+#define WINED3DCREATE_NOWINDOWCHANGES                           0x00000800
+#define WINED3DCREATE_DISABLE_PSGP_THREADING                    0x00002000
+#define WINED3DCREATE_ENABLE_PRESENTSTATS                       0x00004000
+#define WINED3DCREATE_DISABLE_PRINTSCREEN                       0x00008000
+#define WINED3DCREATE_SCREENSAVER                               0x10000000
 
 /* VTF defines */
 #define WINED3DDMAPSAMPLER                                      0x100
@@ -1230,9 +1241,18 @@ enum wined3d_display_rotation
 #define WINED3D_NO3D                                            0x00000002
 #define WINED3D_VIDMEM_ACCOUNTING                               0x00000004
 #define WINED3D_PRESENT_CONVERSION                              0x00000008
+#define WINED3D_RESTORE_MODE_ON_ACTIVATE                        0x00000010
+#define WINED3D_FOCUS_MESSAGES                                  0x00000020
+#define WINED3D_HANDLE_RESTORE                                  0x00000040
 
 #define WINED3D_RESZ_CODE                                       0x7fa05000
 
+#define WINED3D_CKEY_COLORSPACE                                 0x00000001
+#define WINED3D_CKEY_DST_BLT                                    0x00000002
+#define WINED3D_CKEY_DST_OVERLAY                                0x00000004
+#define WINED3D_CKEY_SRC_BLT                                    0x00000008
+#define WINED3D_CKEY_SRC_OVERLAY                                0x00000010
+
 /* dwDDFX */
 /* arithmetic stretching along y axis */
 #define WINEDDBLTFX_ARITHSTRETCHY                               0x00000001
@@ -1283,35 +1303,6 @@ enum wined3d_display_rotation
 #define WINEDDBLT_DONOTWAIT                                     0x08000000
 #define WINEDDBLT_ALPHATEST                                     0x80000000
 
-/* DDSURFACEDESC.dwFlags */
-#define WINEDDSD_CAPS                                           0x00000001
-#define WINEDDSD_HEIGHT                                         0x00000002
-#define WINEDDSD_WIDTH                                          0x00000004
-#define WINEDDSD_PITCH                                          0x00000008
-#define WINEDDSD_BACKBUFFERCOUNT                                0x00000020
-#define WINEDDSD_ZBUFFERBITDEPTH                                0x00000040
-#define WINEDDSD_ALPHABITDEPTH                                  0x00000080
-#define WINEDDSD_LPSURFACE                                      0x00000800
-#define WINEDDSD_PIXELFORMAT                                    0x00001000
-#define WINEDDSD_CKDESTOVERLAY                                  0x00002000
-#define WINEDDSD_CKDESTBLT                                      0x00004000
-#define WINEDDSD_CKSRCOVERLAY                                   0x00008000
-#define WINEDDSD_CKSRCBLT                                       0x00010000
-#define WINEDDSD_MIPMAPCOUNT                                    0x00020000
-#define WINEDDSD_REFRESHRATE                                    0x00040000
-#define WINEDDSD_LINEARSIZE                                     0x00080000
-#define WINEDDSD_TEXTURESTAGE                                   0x00100000
-#define WINEDDSD_FVF                                            0x00200000
-#define WINEDDSD_SRCVBHANDLE                                    0x00400000
-#define WINEDDSD_ALL                                            0x007ff9ee
-
-/* Set/Get Colour Key Flags */
-#define WINEDDCKEY_COLORSPACE                                   0x00000001 /* Struct is single colour space */
-#define WINEDDCKEY_DESTBLT                                      0x00000002 /* To be used as dest for blt */
-#define WINEDDCKEY_DESTOVERLAY                                  0x00000004 /* To be used as dest for CK overlays */
-#define WINEDDCKEY_SRCBLT                                       0x00000008 /* To be used as src for blt */
-#define WINEDDCKEY_SRCOVERLAY                                   0x00000010 /* To be used as src for CK overlays */
-
 /* dwFlags for GetBltStatus */
 #define WINEDDGBS_CANBLT                                        0x00000001
 #define WINEDDGBS_ISBLTDONE                                     0x00000002
@@ -1503,6 +1494,8 @@ enum wined3d_display_rotation
 #define WINED3D_SURFACE_DISCARD                                 0x00000002
 #define WINED3D_SURFACE_PIN_SYSMEM                              0x00000004
 
+#define WINED3D_APPEND_ALIGNED_ELEMENT                          0xffffffff
+
 struct wined3d_display_mode
 {
     UINT width;
@@ -1679,8 +1672,8 @@ struct wined3d_clip_status
 struct wined3d_vertex_element
 {
     enum wined3d_format_id format;
-    WORD input_slot;
-    WORD offset;
+    unsigned int input_slot;
+    unsigned int offset;
     UINT output_slot; /* D3D 8 & 10 */
     BYTE method;
     BYTE usage;
@@ -1708,6 +1701,13 @@ struct wined3d_map_desc
     void *data;
 };
 
+struct wined3d_sub_resource_data
+{
+    const void *data;
+    unsigned int row_pitch;
+    unsigned int slice_pitch;
+};
+
 struct wined3d_box
 {
     UINT left;
@@ -1956,6 +1956,24 @@ struct wined3d_rendertarget_view_desc
     } u;
 };
 
+struct wined3d_sampler_desc
+{
+    enum wined3d_texture_address address_u;
+    enum wined3d_texture_address address_v;
+    enum wined3d_texture_address address_w;
+    float border_color[4];
+    enum wined3d_texture_filter_type mag_filter;
+    enum wined3d_texture_filter_type min_filter;
+    enum wined3d_texture_filter_type mip_filter;
+    float lod_bias;
+    float min_lod;
+    float max_lod;
+    unsigned int max_anisotropy;
+    BOOL compare;
+    enum wined3d_cmp_func comparison_func;
+    BOOL srgb_decode;
+};
+
 struct wined3d_shader_signature_element
 {
     const char *semantic_name;
@@ -1970,7 +1988,14 @@ struct wined3d_shader_signature
 {
     UINT element_count;
     struct wined3d_shader_signature_element *elements;
-    char *string_data;
+};
+
+struct wined3d_shader_desc
+{
+    const DWORD *byte_code;
+    const struct wined3d_shader_signature *input_signature;
+    const struct wined3d_shader_signature *output_signature;
+    unsigned int max_version;
 };
 
 struct wined3d_parent_ops
@@ -2407,20 +2432,18 @@ void * __cdecl wined3d_rendertarget_view_get_sub_resource_parent(const struct wi
 ULONG __cdecl wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view);
 void __cdecl wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent);
 
-HRESULT __cdecl wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler);
+HRESULT __cdecl wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
+        void *parent, struct wined3d_sampler **sampler);
 ULONG __cdecl wined3d_sampler_decref(struct wined3d_sampler *sampler);
 void * __cdecl wined3d_sampler_get_parent(const struct wined3d_sampler *sampler);
 ULONG __cdecl wined3d_sampler_incref(struct wined3d_sampler *sampler);
 
-HRESULT __cdecl wined3d_shader_create_gs(struct wined3d_device *device, const DWORD *byte_code,
-        const struct wined3d_shader_signature *output_signature, void *parent,
-        const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
-HRESULT __cdecl wined3d_shader_create_ps(struct wined3d_device *device, const DWORD *byte_code,
-        const struct wined3d_shader_signature *output_signature, void *parent,
-        const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
-HRESULT __cdecl wined3d_shader_create_vs(struct wined3d_device *device, const DWORD *byte_code,
-        const struct wined3d_shader_signature *output_signature, void *parent,
-        const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
+HRESULT __cdecl wined3d_shader_create_gs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
+        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
+HRESULT __cdecl wined3d_shader_create_ps(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
+        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
+HRESULT __cdecl wined3d_shader_create_vs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
+        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
 ULONG __cdecl wined3d_shader_decref(struct wined3d_shader *shader);
 HRESULT __cdecl wined3d_shader_get_byte_code(const struct wined3d_shader *shader,
         void *byte_code, UINT *byte_code_size);
@@ -2429,8 +2452,8 @@ ULONG __cdecl wined3d_shader_incref(struct wined3d_shader *shader);
 HRESULT __cdecl wined3d_shader_set_local_constants_float(struct wined3d_shader *shader,
         UINT start_idx, const float *src_data, UINT vector4f_count);
 
-HRESULT __cdecl wined3d_shader_resource_view_create(void *parent, const struct wined3d_parent_ops *parent_ops,
-        struct wined3d_shader_resource_view **view);
+HRESULT __cdecl wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent,
+        const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view);
 ULONG __cdecl wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view);
 void * __cdecl wined3d_shader_resource_view_get_parent(const struct wined3d_shader_resource_view *view);
 ULONG __cdecl wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view);
@@ -2465,10 +2488,6 @@ HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC d
 HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y);
 HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface);
-HRESULT __cdecl wined3d_surface_update_desc(struct wined3d_surface *surface,
-        UINT width, UINT height, enum wined3d_format_id format_id,
-        enum wined3d_multisample_type multisample_type, UINT multisample_quality,
-        void *mem, UINT pitch);
 HRESULT __cdecl wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect,
         struct wined3d_surface *dst_surface, const RECT *dst_rect, DWORD flags, const WINEDDOVERLAYFX *fx);
 HRESULT __cdecl wined3d_surface_update_overlay_z_order(struct wined3d_surface *surface,
@@ -2503,8 +2522,8 @@ void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, H
 HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
         UINT layer, const struct wined3d_box *dirty_region);
 HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
-        UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops,
-        struct wined3d_texture **texture);
+        UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent,
+        const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
 ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture);
 void __cdecl wined3d_texture_generate_mipmaps(struct wined3d_texture *texture);
 enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture);
@@ -2521,6 +2540,10 @@ HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *
 HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture,
         DWORD flags, const struct wined3d_color_key *color_key);
 DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod);
+HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture,
+        UINT width, UINT height, enum wined3d_format_id format_id,
+        enum wined3d_multisample_type multisample_type, UINT multisample_quality,
+        void *mem, UINT pitch);
 
 HRESULT __cdecl wined3d_vertex_declaration_create(struct wined3d_device *device,
         const struct wined3d_vertex_element *elements, UINT element_count, void *parent,
@@ -2542,4 +2565,49 @@ HRESULT __cdecl wined3d_volume_map(struct wined3d_volume *volume,
 void __cdecl wined3d_volume_preload(struct wined3d_volume *volume);
 HRESULT __cdecl wined3d_volume_unmap(struct wined3d_volume *volume);
 
+/* Return the integer base-2 logarithm of x. Undefined for x == 0. */
+static inline unsigned int wined3d_log2i(unsigned int x)
+{
+#ifdef HAVE___BUILTIN_CLZ
+    return __builtin_clz(x) ^ 0x1f;
+#else
+    static const unsigned int l[] =
+    {
+        ~0u, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+          4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    };
+    unsigned int i;
+
+    return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
+#endif
+}
+
+BOOL wined3d_dxt1_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+                         enum wined3d_format_id format, unsigned int w, unsigned int h);
+BOOL wined3d_dxt1_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+                         enum wined3d_format_id format, unsigned int w, unsigned int h);
+BOOL wined3d_dxt3_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+                         enum wined3d_format_id format, unsigned int w, unsigned int h);
+BOOL wined3d_dxt3_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+                         enum wined3d_format_id format, unsigned int w, unsigned int h);
+BOOL wined3d_dxt5_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+                         enum wined3d_format_id format, unsigned int w, unsigned int h);
+BOOL wined3d_dxt5_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
+                         enum wined3d_format_id format, unsigned int w, unsigned int h);
+BOOL wined3d_dxtn_supported(void);
+
 #endif /* __WINE_WINED3D_H */
index b72d377..f94215d 100644 (file)
@@ -28,13 +28,13 @@ reactos/tools/wpp                 # Synced to Wine-1.7.27
 The following libraries are shared with Wine.
 
 reactos/dll/directx/wine/amstream       # Synced to Wine-1.7.27
-reactos/dll/directx/wine/d3d8           # Synced to Wine-1.7.27
-reactos/dll/directx/wine/d3d9           # Synced to Wine-1.7.27
+reactos/dll/directx/wine/d3d8           # Synced to WineStaging-1.7.37
+reactos/dll/directx/wine/d3d9           # Synced to WineStaging-1.7.37
 reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-1.7.37
 reactos/dll/directx/wine/d3drm          # Synced to WineStaging-1.7.37
 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-1.7.27
 reactos/dll/directx/wine/d3dxof         # Synced to WineStaging-1.7.37
-reactos/dll/directx/wine/ddraw          # Synced to Wine-1.7.27
+reactos/dll/directx/wine/ddraw          # Synced to WineStaging-1.7.37
 reactos/dll/directx/wine/devenum        # Synced to Wine-1.7.27
 reactos/dll/directx/wine/dinput         # Synced to WineStaging-1.7.37
 reactos/dll/directx/wine/dinput8        # Synced to Wine-1.7.27
@@ -47,7 +47,7 @@ reactos/dll/directx/wine/dxgi           # Synced to Wine-1.7.27
 reactos/dll/directx/wine/msdmo          # Synced to Wine-1.7.27
 reactos/dll/directx/wine/qedit          # Synced to Wine-1.7.27
 reactos/dll/directx/wine/quartz         # Synced to Wine-1.7.27
-reactos/dll/directx/wine/wined3d        # Synced to Wine-1.7.27
+reactos/dll/directx/wine/wined3d        # Synced to WineStaging-1.7.37
 
 reactos/dll/win32/activeds            # Synced to Wine-1.7.27
 reactos/dll/win32/actxprxy            # Synced to Wine-1.7.27