[D3D8][D3D9][DDRAW][WINED3D] Sync with Wine Staging 3.3. CORE-14434
authorAmine Khaldi <amine.khaldi@reactos.org>
Thu, 8 Mar 2018 12:15:18 +0000 (13:15 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Thu, 8 Mar 2018 12:15:18 +0000 (13:15 +0100)
78 files changed:
dll/directx/wine/d3d8/CMakeLists.txt
dll/directx/wine/d3d8/buffer.c
dll/directx/wine/d3d8/d3d8_main.c
dll/directx/wine/d3d8/d3d8_private.h
dll/directx/wine/d3d8/device.c
dll/directx/wine/d3d8/directx.c
dll/directx/wine/d3d8/precomp.h [new file with mode: 0644]
dll/directx/wine/d3d8/shader.c
dll/directx/wine/d3d8/surface.c
dll/directx/wine/d3d8/swapchain.c
dll/directx/wine/d3d8/texture.c
dll/directx/wine/d3d8/vertexdeclaration.c
dll/directx/wine/d3d8/volume.c
dll/directx/wine/d3d9/CMakeLists.txt
dll/directx/wine/d3d9/buffer.c
dll/directx/wine/d3d9/d3d9_main.c
dll/directx/wine/d3d9/d3d9_private.h
dll/directx/wine/d3d9/device.c
dll/directx/wine/d3d9/directx.c
dll/directx/wine/d3d9/precomp.h [new file with mode: 0644]
dll/directx/wine/d3d9/query.c
dll/directx/wine/d3d9/shader.c
dll/directx/wine/d3d9/stateblock.c
dll/directx/wine/d3d9/surface.c
dll/directx/wine/d3d9/swapchain.c
dll/directx/wine/d3d9/texture.c
dll/directx/wine/d3d9/vertexdeclaration.c
dll/directx/wine/d3d9/volume.c
dll/directx/wine/ddraw/CMakeLists.txt
dll/directx/wine/ddraw/clipper.c
dll/directx/wine/ddraw/ddraw.c
dll/directx/wine/ddraw/ddraw_private.h
dll/directx/wine/ddraw/device.c
dll/directx/wine/ddraw/executebuffer.c
dll/directx/wine/ddraw/light.c
dll/directx/wine/ddraw/main.c
dll/directx/wine/ddraw/material.c
dll/directx/wine/ddraw/palette.c
dll/directx/wine/ddraw/precomp.h [new file with mode: 0644]
dll/directx/wine/ddraw/surface.c
dll/directx/wine/ddraw/utils.c
dll/directx/wine/ddraw/vertexbuffer.c
dll/directx/wine/ddraw/viewport.c
dll/directx/wine/wined3d/CMakeLists.txt
dll/directx/wine/wined3d/arb_program_shader.c
dll/directx/wine/wined3d/ati_fragment_shader.c
dll/directx/wine/wined3d/buffer.c
dll/directx/wine/wined3d/context.c
dll/directx/wine/wined3d/cs.c
dll/directx/wine/wined3d/device.c
dll/directx/wine/wined3d/directx.c
dll/directx/wine/wined3d/drawprim.c [deleted file]
dll/directx/wine/wined3d/dxtn.c
dll/directx/wine/wined3d/gl_compat.c
dll/directx/wine/wined3d/glsl_shader.c
dll/directx/wine/wined3d/nvidia_texture_shader.c
dll/directx/wine/wined3d/palette.c
dll/directx/wine/wined3d/precomp.h [new file with mode: 0644]
dll/directx/wine/wined3d/query.c
dll/directx/wine/wined3d/resource.c
dll/directx/wine/wined3d/sampler.c
dll/directx/wine/wined3d/shader.c
dll/directx/wine/wined3d/shader_sm1.c
dll/directx/wine/wined3d/shader_sm4.c
dll/directx/wine/wined3d/state.c
dll/directx/wine/wined3d/stateblock.c
dll/directx/wine/wined3d/surface.c
dll/directx/wine/wined3d/swapchain.c
dll/directx/wine/wined3d/texture.c
dll/directx/wine/wined3d/utils.c
dll/directx/wine/wined3d/vertexdeclaration.c
dll/directx/wine/wined3d/view.c
dll/directx/wine/wined3d/wined3d.spec
dll/directx/wine/wined3d/wined3d_gl.h
dll/directx/wine/wined3d/wined3d_main.c
dll/directx/wine/wined3d/wined3d_private.h
media/doc/README.WINE
sdk/include/reactos/wine/wined3d.h

index bad1641..09d7a6c 100644 (file)
@@ -17,7 +17,7 @@ list(APPEND SOURCE
     texture.c
     vertexdeclaration.c
     volume.c
     texture.c
     vertexdeclaration.c
     volume.c
-    d3d8_private.h)
+    precomp.h)
 
 add_library(d3d8 SHARED
     ${SOURCE}
 
 add_library(d3d8 SHARED
     ${SOURCE}
@@ -28,5 +28,5 @@ add_library(d3d8 SHARED
 set_module_type(d3d8 win32dll UNICODE)
 target_link_libraries(d3d8 uuid wine)
 add_importlibs(d3d8 d3dwine msvcrt kernel32 ntdll)
 set_module_type(d3d8 win32dll UNICODE)
 target_link_libraries(d3d8 uuid wine)
 add_importlibs(d3d8 d3dwine msvcrt kernel32 ntdll)
-add_pch(d3d8 d3d8_private.h SOURCE)
+add_pch(d3d8 precomp.h SOURCE)
 add_cd_file(TARGET d3d8 DESTINATION reactos/system32 FOR all)
 add_cd_file(TARGET d3d8 DESTINATION reactos/system32 FOR all)
index d778e58..fb6b7bc 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static inline struct d3d8_vertexbuffer *impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8_vertexbuffer, IDirect3DVertexBuffer8_iface);
 static inline struct d3d8_vertexbuffer *impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8_vertexbuffer, IDirect3DVertexBuffer8_iface);
@@ -190,7 +193,7 @@ static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT
     wined3d_box.right = offset + size;
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
     wined3d_box.right = offset + size;
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
-            0, &wined3d_map_desc, &wined3d_box, flags);
+            0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags));
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
@@ -224,12 +227,12 @@ static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface,
     wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
     wined3d_mutex_unlock();
 
     wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
     wined3d_mutex_unlock();
 
+    desc->Format = D3DFMT_VERTEXDATA;
     desc->Type = D3DRTYPE_VERTEXBUFFER;
     desc->Type = D3DRTYPE_VERTEXBUFFER;
-    desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-    desc->Pool = wined3d_desc.pool;
+    desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+    desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
     desc->Size = wined3d_desc.size;
     desc->FVF = buffer->fvf;
     desc->Size = wined3d_desc.size;
     desc->FVF = buffer->fvf;
-    desc->Format = D3DFMT_VERTEXDATA;
 
     return D3D_OK;
 }
 
     return D3D_OK;
 }
@@ -259,7 +262,7 @@ static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *p
 {
     struct d3d8_vertexbuffer *buffer = parent;
     d3d8_resource_cleanup(&buffer->resource);
 {
     struct d3d8_vertexbuffer *buffer = parent;
     d3d8_resource_cleanup(&buffer->resource);
-    HeapFree(GetProcessHeap(), 0, buffer);
+    heap_free(buffer);
 }
 
 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
@@ -270,15 +273,30 @@ static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
 HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device,
         UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
 {
 HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device,
         UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
 {
+    struct wined3d_buffer_desc desc;
     HRESULT hr;
 
     HRESULT hr;
 
+    if (pool == D3DPOOL_SCRATCH)
+    {
+        WARN("Vertex buffer with D3DPOOL_SCRATCH requested.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl;
     d3d8_resource_init(&buffer->resource);
     buffer->fvf = fvf;
 
     buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl;
     d3d8_resource_init(&buffer->resource);
     buffer->fvf = fvf;
 
+    desc.byte_width = size;
+    desc.usage = usage & WINED3DUSAGE_MASK;
+    desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+    desc.misc_flags = 0;
+    desc.structure_byte_stride = 0;
+
     wined3d_mutex_lock();
     wined3d_mutex_lock();
-    hr = wined3d_buffer_create_vb(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
-            (enum wined3d_pool)pool, buffer, &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
+    hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
+            &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -473,7 +491,7 @@ static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT o
     wined3d_box.right = offset + size;
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
     wined3d_box.right = offset + size;
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
-            0, &wined3d_map_desc, &wined3d_box, flags);
+            0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags));
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
@@ -509,8 +527,8 @@ static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface,
 
     desc->Format = d3dformat_from_wined3dformat(buffer->format);
     desc->Type = D3DRTYPE_INDEXBUFFER;
 
     desc->Format = d3dformat_from_wined3dformat(buffer->format);
     desc->Type = D3DRTYPE_INDEXBUFFER;
-    desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-    desc->Pool = wined3d_desc.pool;
+    desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+    desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
     desc->Size = wined3d_desc.size;
 
     return D3D_OK;
     desc->Size = wined3d_desc.size;
 
     return D3D_OK;
@@ -541,7 +559,7 @@ static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *pa
 {
     struct d3d8_indexbuffer *buffer = parent;
     d3d8_resource_cleanup(&buffer->resource);
 {
     struct d3d8_indexbuffer *buffer = parent;
     d3d8_resource_cleanup(&buffer->resource);
-    HeapFree(GetProcessHeap(), 0, buffer);
+    heap_free(buffer);
 }
 
 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
@@ -552,15 +570,26 @@ static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
 HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device,
         UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
 {
 HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device,
         UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
 {
+    struct wined3d_buffer_desc desc;
     HRESULT hr;
 
     HRESULT hr;
 
+    desc.byte_width = size;
+    desc.usage = (usage & WINED3DUSAGE_MASK) | WINED3DUSAGE_STATICDECL;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+    desc.misc_flags = 0;
+    desc.structure_byte_stride = 0;
+
     buffer->IDirect3DIndexBuffer8_iface.lpVtbl = &d3d8_indexbuffer_vtbl;
     d3d8_resource_init(&buffer->resource);
     buffer->format = wined3dformat_from_d3dformat(format);
 
     wined3d_mutex_lock();
     buffer->IDirect3DIndexBuffer8_iface.lpVtbl = &d3d8_indexbuffer_vtbl;
     d3d8_resource_init(&buffer->resource);
     buffer->format = wined3dformat_from_d3dformat(format);
 
     wined3d_mutex_lock();
-    hr = wined3d_buffer_create_ib(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
-            (enum wined3d_pool)pool, buffer, &d3d8_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
+    hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
+            &d3d8_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
index 144817a..0e68630 100644 (file)
  *
  */
 
  *
  */
 
+#include "config.h"
+#include "initguid.h"
 #include "d3d8_private.h"
 #include "d3d8_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
 
 HRESULT WINAPI D3D8GetSWInfo(void) {
     FIXME("(void): stub\n");
 
 HRESULT WINAPI D3D8GetSWInfo(void) {
     FIXME("(void): stub\n");
@@ -36,13 +41,13 @@ IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version)
 
     TRACE("sdk_version %#x.\n", sdk_version);
 
 
     TRACE("sdk_version %#x.\n", sdk_version);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return NULL;
 
     if (!d3d8_init(object))
     {
         WARN("Failed to initialize d3d8.\n");
         return NULL;
 
     if (!d3d8_init(object))
     {
         WARN("Failed to initialize d3d8.\n");
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return NULL;
     }
 
         return NULL;
     }
 
@@ -53,75 +58,73 @@ IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version)
 
 /***********************************************************************
  *              ValidateVertexShader (D3D8.@)
 
 /***********************************************************************
  *              ValidateVertexShader (D3D8.@)
- *
- * I've seen reserved1 and reserved2 always passed as 0's
- * bool seems always passed as 0 or 1, but other values work as well...
- * toto       result?
  */
  */
-HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto)
+HRESULT WINAPI ValidateVertexShader(DWORD *vertexshader, DWORD *reserved1, DWORD *reserved2,
+                                    BOOL return_error, char **errors)
 {
 {
-  HRESULT ret;
-  static BOOL warned;
-
-  if (TRACE_ON(d3d8) || !warned) {
-      FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto);
-      warned = TRUE;
-  }
+    const char *message = "";
+    HRESULT hr = E_FAIL;
 
 
-  if (!vertexshader)
-      return E_FAIL;
+    TRACE("(%p %p %p %d %p): semi-stub\n", vertexshader, reserved1, reserved2, return_error, errors);
 
 
-  if (reserved1 || reserved2)
-      return E_FAIL;
+    if (!vertexshader)
+    {
+        message = "(Global Validation Error) Version Token: Code pointer cannot be NULL.\n";
+        goto done;
+    }
 
 
-  switch(*vertexshader) {
+    switch (*vertexshader)
+    {
         case 0xFFFE0101:
         case 0xFFFE0100:
         case 0xFFFE0101:
         case 0xFFFE0100:
-            ret=S_OK;
+            hr = S_OK;
             break;
             break;
+
         default:
             WARN("Invalid shader version token %#x.\n", *vertexshader);
         default:
             WARN("Invalid shader version token %#x.\n", *vertexshader);
-            ret=E_FAIL;
-        }
+            message = "(Global Validation Error) Version Token: Unsupported vertex shader version.\n";
+    }
 
 
-  return ret;
+done:
+    if (!return_error) message = "";
+    if (errors && (*errors = HeapAlloc(GetProcessHeap(), 0, strlen(message) + 1)))
+        strcpy(*errors, message);
+
+    return hr;
 }
 
 /***********************************************************************
  *              ValidatePixelShader (D3D8.@)
 }
 
 /***********************************************************************
  *              ValidatePixelShader (D3D8.@)
- *
- * PARAMS
- * toto       result?
  */
  */
-HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto)
+HRESULT WINAPI ValidatePixelShader(DWORD *pixelshader, DWORD *reserved1, BOOL return_error, char **errors)
 {
 {
-  HRESULT ret;
-  static BOOL warned;
-
-  if (TRACE_ON(d3d8) || !warned) {
-      FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto);
-      warned = TRUE;
-  }
+    const char *message = "";
+    HRESULT hr = E_FAIL;
 
 
-  if (!pixelshader)
-      return E_FAIL;
+    TRACE("(%p %p %d %p): semi-stub\n", pixelshader, reserved1, return_error, errors);
 
 
-  if (reserved1)
-      return E_FAIL;
+    if (!pixelshader)
+        return E_FAIL;
 
 
-  switch(*pixelshader) {
+   switch (*pixelshader)
+   {
         case 0xFFFF0100:
         case 0xFFFF0101:
         case 0xFFFF0102:
         case 0xFFFF0103:
         case 0xFFFF0104:
         case 0xFFFF0100:
         case 0xFFFF0101:
         case 0xFFFF0102:
         case 0xFFFF0103:
         case 0xFFFF0104:
-            ret=S_OK;
+            hr = S_OK;
             break;
         default:
             WARN("Invalid shader version token %#x.\n", *pixelshader);
             break;
         default:
             WARN("Invalid shader version token %#x.\n", *pixelshader);
-            ret=E_FAIL;
-        }
-  return ret;
+            message = "(Global Validation Error) Version Token: Unsupported pixel shader version.\n";
+    }
+
+    if (!return_error) message = "";
+    if (errors && (*errors = HeapAlloc(GetProcessHeap(), 0, strlen(message) + 1)))
+        strcpy(*errors, message);
+
+    return hr;
 }
 
 void d3d8_resource_cleanup(struct d3d8_resource *resource)
 }
 
 void d3d8_resource_cleanup(struct d3d8_resource *resource)
index a85e299..cba5dd6 100644 (file)
 #ifndef __WINE_D3D8_PRIVATE_H
 #define __WINE_D3D8_PRIVATE_H
 
 #ifndef __WINE_D3D8_PRIVATE_H
 #define __WINE_D3D8_PRIVATE_H
 
-#include <config.h>
-
 #include <assert.h>
 #include <stdarg.h>
 
 #include <assert.h>
 #include <stdarg.h>
 
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #define COBJMACROS
-#include <windef.h>
-#include <winbase.h>
-#include <wingdi.h>
-
-#include <wine/debug.h>
-WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
-
-#include <d3d8.h>
-#include <wine/wined3d.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+#include "wine/heap.h"
+#include "d3d8.h"
+#include "wine/wined3d.h"
 
 #define D3DPRESENTFLAGS_MASK 0x00000fffu
 
 
 #define D3DPRESENTFLAGS_MASK 0x00000fffu
 
@@ -281,7 +273,48 @@ HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_dev
 
 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
 
 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
+unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) DECLSPEC_HIDDEN;
 void load_local_constants(const DWORD *d3d8_elements, struct wined3d_shader *wined3d_vertex_shader) DECLSPEC_HIDDEN;
 size_t parse_token(const DWORD *pToken) DECLSPEC_HIDDEN;
 
 void load_local_constants(const DWORD *d3d8_elements, struct wined3d_shader *wined3d_vertex_shader) DECLSPEC_HIDDEN;
 size_t parse_token(const DWORD *pToken) DECLSPEC_HIDDEN;
 
+static inline DWORD d3dusage_from_wined3dusage(unsigned int usage)
+{
+    return usage & WINED3DUSAGE_MASK;
+}
+
+static inline D3DPOOL d3dpool_from_wined3daccess(unsigned int access, unsigned int usage)
+{
+    switch (access & (WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU))
+    {
+        default:
+        case WINED3D_RESOURCE_ACCESS_GPU:
+            return D3DPOOL_DEFAULT;
+        case WINED3D_RESOURCE_ACCESS_CPU:
+            if (usage & WINED3DUSAGE_SCRATCH)
+                return D3DPOOL_SCRATCH;
+            return D3DPOOL_SYSTEMMEM;
+        case WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU:
+            return D3DPOOL_MANAGED;
+    }
+}
+
+static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool, unsigned int usage)
+{
+    switch (pool)
+    {
+        case D3DPOOL_DEFAULT:
+            if (usage & D3DUSAGE_DYNAMIC)
+                return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+            return WINED3D_RESOURCE_ACCESS_GPU;
+        case D3DPOOL_MANAGED:
+            return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU
+                    | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        case D3DPOOL_SYSTEMMEM:
+        case D3DPOOL_SCRATCH:
+            return WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        default:
+            return 0;
+    }
+}
+
 #endif /* __WINE_D3DX8_PRIVATE_H */
 #endif /* __WINE_D3DX8_PRIVATE_H */
index 6573baa..5daf6f4 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+
+#include <math.h>
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static void STDMETHODCALLTYPE d3d8_null_wined3d_object_destroyed(void *parent) {}
 
 static const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops =
 static void STDMETHODCALLTYPE d3d8_null_wined3d_object_destroyed(void *parent) {}
 
 static const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops =
@@ -128,6 +141,29 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
     }
 }
 
     }
 }
 
+unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags)
+{
+    static const unsigned int handled = D3DLOCK_NOSYSLOCK
+            | D3DLOCK_NOOVERWRITE
+            | D3DLOCK_DISCARD
+            | D3DLOCK_NO_DIRTY_UPDATE;
+    unsigned int wined3d_flags;
+
+    wined3d_flags = flags & handled;
+    if (!(flags & (D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD)))
+        wined3d_flags |= WINED3D_MAP_READ;
+    if (!(flags & D3DLOCK_READONLY))
+        wined3d_flags |= WINED3D_MAP_WRITE;
+    if (!(wined3d_flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE)))
+        wined3d_flags |= WINED3D_MAP_READ | WINED3D_MAP_WRITE;
+    flags &= ~(handled | D3DLOCK_READONLY);
+
+    if (flags)
+        FIXME("Unhandled flags %#x.\n", flags);
+
+    return wined3d_flags;
+}
+
 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
 {
     switch (primitive_type)
 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
 {
     switch (primitive_type)
@@ -154,6 +190,24 @@ static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, U
     }
 }
 
     }
 }
 
+static D3DSWAPEFFECT d3dswapeffect_from_wined3dswapeffect(enum wined3d_swap_effect effect)
+{
+    switch (effect)
+    {
+        case WINED3D_SWAP_EFFECT_DISCARD:
+            return D3DSWAPEFFECT_DISCARD;
+        case WINED3D_SWAP_EFFECT_SEQUENTIAL:
+            return D3DSWAPEFFECT_FLIP;
+        case WINED3D_SWAP_EFFECT_COPY:
+            return D3DSWAPEFFECT_COPY;
+        case WINED3D_SWAP_EFFECT_COPY_VSYNC:
+            return D3DSWAPEFFECT_COPY_VSYNC;
+        default:
+            FIXME("Unhandled swap effect %#x.\n", effect);
+            return D3DSWAPEFFECT_FLIP;
+    }
+}
+
 static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
         const struct wined3d_swapchain_desc *swapchain_desc)
 {
 static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
         const struct wined3d_swapchain_desc *swapchain_desc)
 {
@@ -162,7 +216,7 @@ static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS
     present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc->backbuffer_format);
     present_parameters->BackBufferCount = swapchain_desc->backbuffer_count;
     present_parameters->MultiSampleType = swapchain_desc->multisample_type;
     present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc->backbuffer_format);
     present_parameters->BackBufferCount = swapchain_desc->backbuffer_count;
     present_parameters->MultiSampleType = swapchain_desc->multisample_type;
-    present_parameters->SwapEffect = swapchain_desc->swap_effect;
+    present_parameters->SwapEffect = d3dswapeffect_from_wined3dswapeffect(swapchain_desc->swap_effect);
     present_parameters->hDeviceWindow = swapchain_desc->device_window;
     present_parameters->Windowed = swapchain_desc->windowed;
     present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
     present_parameters->hDeviceWindow = swapchain_desc->device_window;
     present_parameters->Windowed = swapchain_desc->windowed;
     present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
@@ -173,6 +227,24 @@ static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS
     present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval;
 }
 
     present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval;
 }
 
+static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect)
+{
+    switch (effect)
+    {
+        case D3DSWAPEFFECT_DISCARD:
+            return WINED3D_SWAP_EFFECT_DISCARD;
+        case D3DSWAPEFFECT_FLIP:
+            return WINED3D_SWAP_EFFECT_SEQUENTIAL;
+        case D3DSWAPEFFECT_COPY:
+            return WINED3D_SWAP_EFFECT_COPY;
+        case D3DSWAPEFFECT_COPY_VSYNC:
+            return WINED3D_SWAP_EFFECT_COPY_VSYNC;
+        default:
+            FIXME("Unhandled swap effect %#x.\n", effect);
+            return WINED3D_SWAP_EFFECT_SEQUENTIAL;
+    }
+}
+
 static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
         const D3DPRESENT_PARAMETERS *present_parameters)
 {
 static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
         const D3DPRESENT_PARAMETERS *present_parameters)
 {
@@ -194,9 +266,10 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
     swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
     swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
     swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount);
     swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
     swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
     swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount);
+    swapchain_desc->backbuffer_usage = WINED3DUSAGE_RENDERTARGET;
     swapchain_desc->multisample_type = present_parameters->MultiSampleType;
     swapchain_desc->multisample_quality = 0; /* d3d9 only */
     swapchain_desc->multisample_type = present_parameters->MultiSampleType;
     swapchain_desc->multisample_quality = 0; /* d3d9 only */
-    swapchain_desc->swap_effect = present_parameters->SwapEffect;
+    swapchain_desc->swap_effect = wined3dswapeffect_from_d3dswapeffect(present_parameters->SwapEffect);
     swapchain_desc->device_window = present_parameters->hDeviceWindow;
     swapchain_desc->windowed = present_parameters->Windowed;
     swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
     swapchain_desc->device_window = present_parameters->hDeviceWindow;
     swapchain_desc->windowed = present_parameters->Windowed;
     swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
@@ -310,9 +383,9 @@ static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enu
     {
         /* Grow the table */
         UINT new_size = t->table_size + (t->table_size >> 1);
     {
         /* Grow the table */
         UINT new_size = t->table_size + (t->table_size >> 1);
-        struct d3d8_handle_entry *new_entries = HeapReAlloc(GetProcessHeap(),
-                0, t->entries, new_size * sizeof(*t->entries));
-        if (!new_entries)
+        struct d3d8_handle_entry *new_entries;
+
+        if (!(new_entries = heap_realloc(t->entries, new_size * sizeof(*t->entries))))
         {
             ERR("Failed to grow the handle table.\n");
             return D3D8_INVALID_HANDLE;
         {
             ERR("Failed to grow the handle table.\n");
             return D3D8_INVALID_HANDLE;
@@ -430,7 +503,7 @@ static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface)
         {
             d3d8_vertex_declaration_destroy(device->decls[i].declaration);
         }
         {
             d3d8_vertex_declaration_destroy(device->decls[i].declaration);
         }
-        HeapFree(GetProcessHeap(), 0, device->decls);
+        heap_free(device->decls);
 
         if (device->vertex_buffer)
             wined3d_buffer_decref(device->vertex_buffer);
 
         if (device->vertex_buffer)
             wined3d_buffer_decref(device->vertex_buffer);
@@ -440,8 +513,8 @@ static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface)
         wined3d_device_uninit_3d(device->wined3d_device);
         wined3d_device_release_focus_window(device->wined3d_device);
         wined3d_device_decref(device->wined3d_device);
         wined3d_device_uninit_3d(device->wined3d_device);
         wined3d_device_release_focus_window(device->wined3d_device);
         wined3d_device_decref(device->wined3d_device);
-        HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
-        HeapFree(GetProcessHeap(), 0, device);
+        heap_free(device->handle_table.entries);
+        heap_free(device);
 
         wined3d_mutex_unlock();
 
 
         wined3d_mutex_unlock();
 
@@ -672,7 +745,7 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
     IUnknown *parent;
 
     wined3d_resource_get_desc(resource, &desc);
     IUnknown *parent;
 
     wined3d_resource_get_desc(resource, &desc);
-    if (desc.pool != WINED3D_POOL_DEFAULT)
+    if (desc.access & WINED3D_RESOURCE_ACCESS_CPU)
         return D3D_OK;
 
     if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D)
         return D3D_OK;
 
     if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D)
@@ -849,15 +922,14 @@ static HRESULT WINAPI d3d8_device_CreateTexture(IDirect3DDevice8 *iface,
         return D3DERR_INVALIDCALL;
 
     *texture = NULL;
         return D3DERR_INVALIDCALL;
 
     *texture = NULL;
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = texture_init(object, device, width, height, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize texture, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = texture_init(object, device, width, height, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize texture, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -882,15 +954,14 @@ static HRESULT WINAPI d3d8_device_CreateVolumeTexture(IDirect3DDevice8 *iface,
         return D3DERR_INVALIDCALL;
 
     *texture = NULL;
         return D3DERR_INVALIDCALL;
 
     *texture = NULL;
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize volume texture, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize volume texture, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -914,15 +985,14 @@ static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UIN
         return D3DERR_INVALIDCALL;
 
     *texture = NULL;
         return D3DERR_INVALIDCALL;
 
     *texture = NULL;
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize cube texture, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize cube texture, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -942,15 +1012,14 @@ static HRESULT WINAPI d3d8_device_CreateVertexBuffer(IDirect3DDevice8 *iface, UI
     TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p.\n",
             iface, size, usage, fvf, pool, buffer);
 
     TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p.\n",
             iface, size, usage, fvf, pool, buffer);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = vertexbuffer_init(object, device, size, usage, fvf, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = vertexbuffer_init(object, device, size, usage, fvf, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -970,15 +1039,14 @@ static HRESULT WINAPI d3d8_device_CreateIndexBuffer(IDirect3DDevice8 *iface, UIN
     TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p.\n",
             iface, size, usage, format, pool, buffer);
 
     TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p.\n",
             iface, size, usage, format, pool, buffer);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = indexbuffer_init(object, device, size, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize index buffer, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = indexbuffer_init(object, device, size, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize index buffer, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -1007,7 +1075,10 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width
     desc.multisample_type = multisample_type;
     desc.multisample_quality = multisample_quality;
     desc.usage = usage & WINED3DUSAGE_MASK;
     desc.multisample_type = multisample_type;
     desc.multisample_quality = multisample_quality;
     desc.usage = usage & WINED3DUSAGE_MASK;
-    desc.pool = pool;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     desc.width = width;
     desc.height = height;
     desc.depth = 1;
     desc.width = width;
     desc.height = height;
     desc.depth = 1;
@@ -2092,15 +2163,22 @@ static HRESULT d3d8_device_prepare_vertex_buffer(struct d3d8_device *device, UIN
     if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
     {
         UINT size = max(device->vertex_buffer_size * 2, min_size);
     if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
     {
         UINT size = max(device->vertex_buffer_size * 2, min_size);
+        struct wined3d_buffer_desc desc;
         struct wined3d_buffer *buffer;
 
         TRACE("Growing vertex buffer to %u bytes\n", size);
 
         struct wined3d_buffer *buffer;
 
         TRACE("Growing vertex buffer to %u bytes\n", size);
 
-        hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
-                WINED3D_POOL_DEFAULT, NULL, &d3d8_null_wined3d_parent_ops, &buffer);
-        if (FAILED(hr))
+        desc.byte_width = size;
+        desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY;
+        desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        desc.misc_flags = 0;
+        desc.structure_byte_stride = 0;
+
+        if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc,
+                NULL, NULL, &d3d8_null_wined3d_parent_ops, &buffer)))
         {
         {
-            ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device, hr);
+            ERR("Failed to create vertex buffer, hr %#x.\n", hr);
             return hr;
         }
 
             return hr;
         }
 
@@ -2153,7 +2231,7 @@ static HRESULT WINAPI d3d8_device_DrawPrimitiveUP(IDirect3DDevice8 *iface,
     wined3d_box.right = vb_pos + size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = vb_pos + size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
-            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, data, size);
     wined3d_resource_unmap(vb, 0);
         goto done;
     memcpy(wined3d_map_desc.data, data, size);
     wined3d_resource_unmap(vb, 0);
@@ -2180,15 +2258,22 @@ static HRESULT d3d8_device_prepare_index_buffer(struct d3d8_device *device, UINT
     if (device->index_buffer_size < min_size || !device->index_buffer)
     {
         UINT size = max(device->index_buffer_size * 2, min_size);
     if (device->index_buffer_size < min_size || !device->index_buffer)
     {
         UINT size = max(device->index_buffer_size * 2, min_size);
+        struct wined3d_buffer_desc desc;
         struct wined3d_buffer *buffer;
 
         TRACE("Growing index buffer to %u bytes\n", size);
 
         struct wined3d_buffer *buffer;
 
         TRACE("Growing index buffer to %u bytes\n", size);
 
-        hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
-                WINED3D_POOL_DEFAULT, NULL, &d3d8_null_wined3d_parent_ops, &buffer);
-        if (FAILED(hr))
+        desc.byte_width = size;
+        desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_STATICDECL;
+        desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        desc.misc_flags = 0;
+        desc.structure_byte_stride = 0;
+
+        if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc,
+                NULL, NULL, &d3d8_null_wined3d_parent_ops, &buffer)))
         {
         {
-            ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device, hr);
+            ERR("Failed to create index buffer, hr %#x.\n", hr);
             return hr;
         }
 
             return hr;
         }
 
@@ -2247,7 +2332,7 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface
     wined3d_box.right = vb_pos + vtx_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = vb_pos + vtx_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
-            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, (char *)vertex_data + min_vertex_idx * vertex_stride, vtx_size);
     wined3d_resource_unmap(vb, 0);
         goto done;
     memcpy(wined3d_map_desc.data, (char *)vertex_data + min_vertex_idx * vertex_stride, vtx_size);
     wined3d_resource_unmap(vb, 0);
@@ -2269,7 +2354,7 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface
     wined3d_box.right = ib_pos + idx_size;
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = ib_pos + idx_size;
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
-            ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, index_data, idx_size);
     wined3d_resource_unmap(ib, 0);
         goto done;
     memcpy(wined3d_map_desc.data, index_data, idx_size);
     wined3d_resource_unmap(ib, 0);
@@ -2325,8 +2410,7 @@ static HRESULT WINAPI d3d8_device_CreateVertexShader(IDirect3DDevice8 *iface,
     TRACE("iface %p, declaration %p, byte_code %p, shader %p, usage %#x.\n",
             iface, declaration, byte_code, shader, usage);
 
     TRACE("iface %p, declaration %p, byte_code %p, shader %p, usage %#x.\n",
             iface, declaration, byte_code, shader, usage);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         *shader = 0;
         return E_OUTOFMEMORY;
     {
         *shader = 0;
         return E_OUTOFMEMORY;
@@ -2338,7 +2422,7 @@ static HRESULT WINAPI d3d8_device_CreateVertexShader(IDirect3DDevice8 *iface,
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate vertex shader handle.\n");
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate vertex shader handle.\n");
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         *shader = 0;
         return E_OUTOFMEMORY;
     }
         *shader = 0;
         return E_OUTOFMEMORY;
     }
@@ -2352,7 +2436,7 @@ static HRESULT WINAPI d3d8_device_CreateVertexShader(IDirect3DDevice8 *iface,
         wined3d_mutex_lock();
         d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_VS);
         wined3d_mutex_unlock();
         wined3d_mutex_lock();
         d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_VS);
         wined3d_mutex_unlock();
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         *shader = 0;
         return hr;
     }
         *shader = 0;
         return hr;
     }
@@ -2392,13 +2476,13 @@ static struct d3d8_vertex_declaration *d3d8_device_get_fvf_declaration(struct d3
     }
     TRACE("not found. Creating and inserting at position %d.\n", low);
 
     }
     TRACE("not found. Creating and inserting at position %d.\n", low);
 
-    if (!(d3d8_declaration = HeapAlloc(GetProcessHeap(), 0, sizeof(*d3d8_declaration))))
+    if (!(d3d8_declaration = heap_alloc(sizeof(*d3d8_declaration))))
         return NULL;
 
     if (FAILED(hr = d3d8_vertex_declaration_init_fvf(d3d8_declaration, device, fvf)))
     {
         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
         return NULL;
 
     if (FAILED(hr = d3d8_vertex_declaration_init_fvf(d3d8_declaration, device, fvf)))
     {
         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, d3d8_declaration);
+        heap_free(d3d8_declaration);
         return NULL;
     }
 
         return NULL;
     }
 
@@ -2406,9 +2490,8 @@ static struct d3d8_vertex_declaration *d3d8_device_get_fvf_declaration(struct d3
     {
         UINT grow = device->declArraySize / 2;
 
     {
         UINT grow = device->declArraySize / 2;
 
-        convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
-                sizeof(*convertedDecls) * (device->numConvertedDecls + grow));
-        if (!convertedDecls)
+        if (!(convertedDecls = heap_realloc(convertedDecls,
+                sizeof(*convertedDecls) * (device->numConvertedDecls + grow))))
         {
             d3d8_vertex_declaration_destroy(d3d8_declaration);
             return NULL;
         {
             d3d8_vertex_declaration_destroy(d3d8_declaration);
             return NULL;
@@ -2703,8 +2786,7 @@ static HRESULT WINAPI d3d8_device_CreatePixelShader(IDirect3DDevice8 *iface,
     if (!shader)
         return D3DERR_INVALIDCALL;
 
     if (!shader)
         return D3DERR_INVALIDCALL;
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     wined3d_mutex_lock();
         return E_OUTOFMEMORY;
 
     wined3d_mutex_lock();
@@ -2713,7 +2795,7 @@ static HRESULT WINAPI d3d8_device_CreatePixelShader(IDirect3DDevice8 *iface,
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate pixel shader handle.\n");
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate pixel shader handle.\n");
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return E_OUTOFMEMORY;
     }
 
         return E_OUTOFMEMORY;
     }
 
@@ -2726,7 +2808,7 @@ static HRESULT WINAPI d3d8_device_CreatePixelShader(IDirect3DDevice8 *iface,
         wined3d_mutex_lock();
         d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_PS);
         wined3d_mutex_unlock();
         wined3d_mutex_lock();
         d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_PS);
         wined3d_mutex_unlock();
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         *shader = 0;
         return hr;
     }
         *shader = 0;
         return hr;
     }
@@ -3089,7 +3171,7 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
     TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
-    if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
+    if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
         return E_OUTOFMEMORY;
 
     surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
         return E_OUTOFMEMORY;
 
     surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
@@ -3108,7 +3190,7 @@ static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *
     TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
-    if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume))))
+    if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
         return E_OUTOFMEMORY;
 
     volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
         return E_OUTOFMEMORY;
 
     volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
@@ -3204,9 +3286,8 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
     device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl;
     device->device_parent.ops = &d3d8_wined3d_device_parent_ops;
     device->ref = 1;
     device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl;
     device->device_parent.ops = &d3d8_wined3d_device_parent_ops;
     device->ref = 1;
-    device->handle_table.entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-            D3D8_INITIAL_HANDLE_TABLE_SIZE * sizeof(*device->handle_table.entries));
-    if (!device->handle_table.entries)
+    if (!(device->handle_table.entries = heap_alloc_zero(D3D8_INITIAL_HANDLE_TABLE_SIZE
+            * sizeof(*device->handle_table.entries))))
     {
         ERR("Failed to allocate handle table memory.\n");
         return E_OUTOFMEMORY;
     {
         ERR("Failed to allocate handle table memory.\n");
         return E_OUTOFMEMORY;
@@ -3222,7 +3303,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
     {
         WARN("Failed to create wined3d device, hr %#x.\n", hr);
         wined3d_mutex_unlock();
     {
         WARN("Failed to create wined3d device, hr %#x.\n", hr);
         wined3d_mutex_unlock();
-        HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+        heap_free(device->handle_table.entries);
         return hr;
     }
 
         return hr;
     }
 
@@ -3237,7 +3318,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
             ERR("Failed to acquire focus window, hr %#x.\n", hr);
             wined3d_device_decref(device->wined3d_device);
             wined3d_mutex_unlock();
             ERR("Failed to acquire focus window, hr %#x.\n", hr);
             wined3d_device_decref(device->wined3d_device);
             wined3d_mutex_unlock();
-            HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+            heap_free(device->handle_table.entries);
             return hr;
         }
 
             return hr;
         }
 
@@ -3256,7 +3337,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
         wined3d_device_release_focus_window(device->wined3d_device);
         wined3d_device_decref(device->wined3d_device);
         wined3d_mutex_unlock();
         wined3d_device_release_focus_window(device->wined3d_device);
         wined3d_device_decref(device->wined3d_device);
         wined3d_mutex_unlock();
-        HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+        heap_free(device->handle_table.entries);
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
@@ -3266,7 +3347,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
         wined3d_device_release_focus_window(device->wined3d_device);
         wined3d_device_decref(device->wined3d_device);
         wined3d_mutex_unlock();
         wined3d_device_release_focus_window(device->wined3d_device);
         wined3d_device_decref(device->wined3d_device);
         wined3d_mutex_unlock();
-        HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+        heap_free(device->handle_table.entries);
         return hr;
     }
 
         return hr;
     }
 
@@ -3278,8 +3359,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
     present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc);
 
     device->declArraySize = 16;
     present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc);
 
     device->declArraySize = 16;
-    device->decls = HeapAlloc(GetProcessHeap(), 0, device->declArraySize * sizeof(*device->decls));
-    if (!device->decls)
+    if (!(device->decls = heap_alloc(device->declArraySize * sizeof(*device->decls))))
     {
         ERR("Failed to allocate FVF vertex declaration map memory.\n");
         hr = E_OUTOFMEMORY;
     {
         ERR("Failed to allocate FVF vertex declaration map memory.\n");
         hr = E_OUTOFMEMORY;
@@ -3300,6 +3380,6 @@ err:
     wined3d_device_release_focus_window(device->wined3d_device);
     wined3d_device_decref(device->wined3d_device);
     wined3d_mutex_unlock();
     wined3d_device_release_focus_window(device->wined3d_device);
     wined3d_device_decref(device->wined3d_device);
     wined3d_mutex_unlock();
-    HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+    heap_free(device->handle_table.entries);
     return hr;
 }
     return hr;
 }
index ffb8dde..6e8f93a 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static inline struct d3d8 *impl_from_IDirect3D8(IDirect3D8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8, IDirect3D8_iface);
 static inline struct d3d8 *impl_from_IDirect3D8(IDirect3D8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8, IDirect3D8_iface);
@@ -68,7 +81,7 @@ static ULONG WINAPI d3d8_Release(IDirect3D8 *iface)
         wined3d_decref(d3d8->wined3d);
         wined3d_mutex_unlock();
 
         wined3d_decref(d3d8->wined3d);
         wined3d_mutex_unlock();
 
-        HeapFree(GetProcessHeap(), 0, d3d8);
+        heap_free(d3d8);
     }
 
     return refcount;
     }
 
     return refcount;
@@ -360,15 +373,14 @@ static HRESULT WINAPI d3d8_CreateDevice(IDirect3D8 *iface, UINT adapter,
     TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, device %p.\n",
             iface, adapter, device_type, focus_window, flags, parameters, device);
 
     TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, device %p.\n",
             iface, adapter, device_type, focus_window, flags, parameters, device);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = device_init(object, d3d8, d3d8->wined3d, adapter, device_type, focus_window, flags, parameters);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = device_init(object, d3d8, d3d8->wined3d, adapter, device_type, focus_window, flags, parameters);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -405,7 +417,7 @@ BOOL d3d8_init(struct d3d8 *d3d8)
     DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
             | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
             | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART
     DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
             | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
             | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART
-            | WINED3D_LEGACY_CUBEMAP_FILTERING;
+            | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT;
 
     d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
     d3d8->refcount = 1;
 
     d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
     d3d8->refcount = 1;
diff --git a/dll/directx/wine/d3d8/precomp.h b/dll/directx/wine/d3d8/precomp.h
new file mode 100644 (file)
index 0000000..17c27cb
--- /dev/null
@@ -0,0 +1,13 @@
+
+#ifndef __WINE_D3D8_PRECOMP_H
+#define __WINE_D3D8_PRECOMP_H
+
+#include <wine/config.h>
+
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#include "d3d8_private.h"
+
+#endif /* __WINE_D3D8_PRECOMP_H */
index d0361a9..8192b23 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static void STDMETHODCALLTYPE d3d8_vertexshader_wined3d_object_destroyed(void *parent)
 {
     struct d3d8_vertex_shader *shader = parent;
     d3d8_vertex_declaration_destroy(shader->vertex_declaration);
 static void STDMETHODCALLTYPE d3d8_vertexshader_wined3d_object_destroyed(void *parent)
 {
     struct d3d8_vertex_shader *shader = parent;
     d3d8_vertex_declaration_destroy(shader->vertex_declaration);
-    HeapFree(GetProcessHeap(), 0, shader);
+    heap_free(shader);
 }
 
 void d3d8_vertex_shader_destroy(struct d3d8_vertex_shader *shader)
 }
 
 void d3d8_vertex_shader_destroy(struct d3d8_vertex_shader *shader)
@@ -56,15 +59,14 @@ static HRESULT d3d8_vertexshader_create_vertexdeclaration(struct d3d8_device *de
     TRACE("device %p, declaration %p, shader_handle %#x, decl_ptr %p.\n",
             device, declaration, shader_handle, decl_ptr);
 
     TRACE("device %p, declaration %p, shader_handle %#x, decl_ptr %p.\n",
             device, declaration, shader_handle, decl_ptr);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = d3d8_vertex_declaration_init(object, device, declaration, shader_handle);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = d3d8_vertex_declaration_init(object, device, declaration, shader_handle);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -140,7 +142,7 @@ HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_d
 
 static void STDMETHODCALLTYPE d3d8_pixelshader_wined3d_object_destroyed(void *parent)
 {
 
 static void STDMETHODCALLTYPE d3d8_pixelshader_wined3d_object_destroyed(void *parent)
 {
-    HeapFree(GetProcessHeap(), 0, parent);
+    heap_free(parent);
 }
 
 void d3d8_pixel_shader_destroy(struct d3d8_pixel_shader *shader)
 }
 
 void d3d8_pixel_shader_destroy(struct d3d8_pixel_shader *shader)
index 5453616..fff47f5 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static inline struct d3d8_surface *impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8_surface, IDirect3DSurface8_iface);
 static inline struct d3d8_surface *impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8_surface, IDirect3DSurface8_iface);
@@ -188,8 +191,8 @@ static HRESULT WINAPI d3d8_surface_GetDesc(IDirect3DSurface8 *iface, D3DSURFACE_
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
     desc->Type = D3DRTYPE_SURFACE;
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
     desc->Type = D3DRTYPE_SURFACE;
-    desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-    desc->Pool = wined3d_desc.pool;
+    desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+    desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
     desc->Size = wined3d_desc.size;
     desc->MultiSampleType = wined3d_desc.multisample_type;
     desc->Width = wined3d_desc.width;
     desc->Size = wined3d_desc.size;
     desc->MultiSampleType = wined3d_desc.multisample_type;
     desc->Width = wined3d_desc.width;
@@ -241,7 +244,7 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface,
     }
 
     hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx,
     }
 
     hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx,
-            &map_desc, rect ? &box : NULL, flags);
+            &map_desc, rect ? &box : NULL, wined3dmapflags_from_d3dmapflags(flags));
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
@@ -303,7 +306,7 @@ static void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
 {
     struct d3d8_surface *surface = parent;
     d3d8_resource_cleanup(&surface->resource);
 {
     struct d3d8_surface *surface = parent;
     d3d8_resource_cleanup(&surface->resource);
-    HeapFree(GetProcessHeap(), 0, surface);
+    heap_free(surface);
 }
 
 static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
index d82a8ed..3a588b5 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static inline struct d3d8_swapchain *impl_from_IDirect3DSwapChain8(IDirect3DSwapChain8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8_swapchain, IDirect3DSwapChain8_iface);
 static inline struct d3d8_swapchain *impl_from_IDirect3DSwapChain8(IDirect3DSwapChain8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8_swapchain, IDirect3DSwapChain8_iface);
@@ -102,7 +105,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
-            src_rect, dst_rect, dst_window_override, 0);
+            src_rect, dst_rect, dst_window_override, 0, 0);
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -155,7 +158,7 @@ static const IDirect3DSwapChain8Vtbl d3d8_swapchain_vtbl =
 
 static void STDMETHODCALLTYPE d3d8_swapchain_wined3d_object_released(void *parent)
 {
 
 static void STDMETHODCALLTYPE d3d8_swapchain_wined3d_object_released(void *parent)
 {
-    HeapFree(GetProcessHeap(), 0, parent);
+    heap_free(parent);
 }
 
 static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops =
@@ -194,13 +197,13 @@ HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapcha
     struct d3d8_swapchain *object;
     HRESULT hr;
 
     struct d3d8_swapchain *object;
     HRESULT hr;
 
-    if (!(object = HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = swapchain_init(object, device, desc)))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = swapchain_init(object, device, desc)))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
index b860859..87a2575 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static inline struct d3d8_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface)
 {
 static inline struct d3d8_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
 }
 
 static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface)
 {
 }
 
 static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
 }
 
 static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface)
 {
 }
 
 static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
 }
 
 static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out)
 }
 
 static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out)
@@ -250,8 +253,8 @@ static HRESULT WINAPI d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8 *iface, UIN
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_SURFACE;
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_SURFACE;
-        desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-        desc->Pool = wined3d_desc.pool;
+        desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+        desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
         desc->Size = wined3d_desc.size;
         desc->MultiSampleType = wined3d_desc.multisample_type;
         desc->Width = wined3d_desc.width;
         desc->Size = wined3d_desc.size;
         desc->MultiSampleType = wined3d_desc.multisample_type;
         desc->Width = wined3d_desc.width;
@@ -597,8 +600,8 @@ static HRESULT WINAPI d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8 *ifac
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_SURFACE;
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_SURFACE;
-        desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-        desc->Pool = wined3d_desc.pool;
+        desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+        desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
         desc->Size = wined3d_desc.size;
         desc->MultiSampleType = wined3d_desc.multisample_type;
         desc->Width = wined3d_desc.width;
         desc->Size = wined3d_desc.size;
         desc->MultiSampleType = wined3d_desc.multisample_type;
         desc->Width = wined3d_desc.width;
@@ -942,8 +945,8 @@ static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *ifac
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_VOLUME;
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_VOLUME;
-        desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-        desc->Pool = wined3d_desc.pool;
+        desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+        desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
         desc->Size = wined3d_desc.size;
         desc->Width = wined3d_desc.width;
         desc->Height = wined3d_desc.height;
         desc->Size = wined3d_desc.size;
         desc->Width = wined3d_desc.width;
         desc->Height = wined3d_desc.height;
@@ -1080,7 +1083,7 @@ static void STDMETHODCALLTYPE d3d8_texture_wined3d_object_destroyed(void *parent
 {
     struct d3d8_texture *texture = parent;
     d3d8_resource_cleanup(&texture->resource);
 {
     struct d3d8_texture *texture = parent;
     d3d8_resource_cleanup(&texture->resource);
-    HeapFree(GetProcessHeap(), 0, texture);
+    heap_free(texture);
 }
 
 static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops =
@@ -1105,7 +1108,10 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
     desc.multisample_quality = 0;
     desc.usage = usage & WINED3DUSAGE_MASK;
     desc.usage |= WINED3DUSAGE_TEXTURE;
     desc.multisample_quality = 0;
     desc.usage = usage & WINED3DUSAGE_MASK;
     desc.usage |= WINED3DUSAGE_TEXTURE;
-    desc.pool = pool;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     desc.width = width;
     desc.height = height;
     desc.depth = 1;
     desc.width = width;
     desc.height = height;
     desc.depth = 1;
@@ -1150,7 +1156,10 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic
     desc.multisample_quality = 0;
     desc.usage = usage & WINED3DUSAGE_MASK;
     desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
     desc.multisample_quality = 0;
     desc.usage = usage & WINED3DUSAGE_MASK;
     desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
-    desc.pool = pool;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     desc.width = edge_length;
     desc.height = edge_length;
     desc.depth = 1;
     desc.width = edge_length;
     desc.height = edge_length;
     desc.depth = 1;
@@ -1194,7 +1203,9 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev
     desc.multisample_quality = 0;
     desc.usage = usage & WINED3DUSAGE_MASK;
     desc.usage |= WINED3DUSAGE_TEXTURE;
     desc.multisample_quality = 0;
     desc.usage = usage & WINED3DUSAGE_MASK;
     desc.usage |= WINED3DUSAGE_TEXTURE;
-    desc.pool = pool;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.access = wined3daccess_from_d3dpool(pool, usage);
     desc.width = width;
     desc.height = height;
     desc.depth = depth;
     desc.width = width;
     desc.height = height;
     desc.depth = depth;
index e01230e..0cae3cd 100644 (file)
 /* IDirect3DVertexDeclaration8 is internal to our implementation.
  * It's not visible in the API. */
 
 /* IDirect3DVertexDeclaration8 is internal to our implementation.
  * It's not visible in the API. */
 
+#include "config.h"
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static const char *debug_d3dvsdt_type(D3DVSDT_TYPE d3dvsdt_type)
 {
     switch (d3dvsdt_type)
 static const char *debug_d3dvsdt_type(D3DVSDT_TYPE d3dvsdt_type)
 {
     switch (d3dvsdt_type)
@@ -263,7 +266,7 @@ static UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3
     TRACE("d3d8_elements %p, d3d8_elements_size %p, wined3d_elements %p\n", d3d8_elements, d3d8_elements_size, wined3d_elements);
 
     /* 128 should be enough for anyone... */
     TRACE("d3d8_elements %p, d3d8_elements_size %p, wined3d_elements %p\n", d3d8_elements, d3d8_elements_size, wined3d_elements);
 
     /* 128 should be enough for anyone... */
-    *wined3d_elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 128 * sizeof(**wined3d_elements));
+    *wined3d_elements = heap_alloc_zero(128 * sizeof(**wined3d_elements));
     while (D3DVSD_END() != *token)
     {
         token_type = ((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
     while (D3DVSD_END() != *token)
     {
         token_type = ((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
@@ -311,8 +314,8 @@ static UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3
 static void STDMETHODCALLTYPE d3d8_vertexdeclaration_wined3d_object_destroyed(void *parent)
 {
     struct d3d8_vertex_declaration *declaration = parent;
 static void STDMETHODCALLTYPE d3d8_vertexdeclaration_wined3d_object_destroyed(void *parent)
 {
     struct d3d8_vertex_declaration *declaration = parent;
-    HeapFree(GetProcessHeap(), 0, declaration->elements);
-    HeapFree(GetProcessHeap(), 0, declaration);
+    heap_free(declaration->elements);
+    heap_free(declaration);
 }
 
 void d3d8_vertex_declaration_destroy(struct d3d8_vertex_declaration *declaration)
 }
 
 void d3d8_vertex_declaration_destroy(struct d3d8_vertex_declaration *declaration)
@@ -339,11 +342,10 @@ HRESULT d3d8_vertex_declaration_init(struct d3d8_vertex_declaration *declaration
     declaration->shader_handle = shader_handle;
 
     wined3d_element_count = convert_to_wined3d_declaration(elements, &declaration->elements_size, &wined3d_elements);
     declaration->shader_handle = shader_handle;
 
     wined3d_element_count = convert_to_wined3d_declaration(elements, &declaration->elements_size, &wined3d_elements);
-    declaration->elements = HeapAlloc(GetProcessHeap(), 0, declaration->elements_size);
-    if (!declaration->elements)
+    if (!(declaration->elements = heap_alloc(declaration->elements_size)))
     {
         ERR("Failed to allocate vertex declaration elements memory.\n");
     {
         ERR("Failed to allocate vertex declaration elements memory.\n");
-        HeapFree(GetProcessHeap(), 0, wined3d_elements);
+        heap_free(wined3d_elements);
         return E_OUTOFMEMORY;
     }
 
         return E_OUTOFMEMORY;
     }
 
@@ -353,11 +355,11 @@ HRESULT d3d8_vertex_declaration_init(struct d3d8_vertex_declaration *declaration
     hr = wined3d_vertex_declaration_create(device->wined3d_device, wined3d_elements, wined3d_element_count,
             declaration, &d3d8_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_vertex_declaration);
     wined3d_mutex_unlock();
     hr = wined3d_vertex_declaration_create(device->wined3d_device, wined3d_elements, wined3d_element_count,
             declaration, &d3d8_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_vertex_declaration);
     wined3d_mutex_unlock();
-    HeapFree(GetProcessHeap(), 0, wined3d_elements);
+    heap_free(wined3d_elements);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, declaration->elements);
+        heap_free(declaration->elements);
         return hr;
     }
 
         return hr;
     }
 
index 0e1e904..89aa84f 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d8_private.h"
 
 #include "d3d8_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
 static inline struct d3d8_volume *impl_from_IDirect3DVolume8(IDirect3DVolume8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8_volume, IDirect3DVolume8_iface);
 static inline struct d3d8_volume *impl_from_IDirect3DVolume8(IDirect3DVolume8 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d8_volume, IDirect3DVolume8_iface);
@@ -122,8 +125,8 @@ static HRESULT WINAPI d3d8_volume_GetDesc(IDirect3DVolume8 *iface, D3DVOLUME_DES
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
     desc->Type = D3DRTYPE_VOLUME;
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
     desc->Type = D3DRTYPE_VOLUME;
-    desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-    desc->Pool = wined3d_desc.pool;
+    desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+    desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
     desc->Size = wined3d_desc.size;
     desc->Width = wined3d_desc.width;
     desc->Height = wined3d_desc.height;
     desc->Size = wined3d_desc.size;
     desc->Width = wined3d_desc.width;
     desc->Height = wined3d_desc.height;
@@ -144,7 +147,8 @@ static HRESULT WINAPI d3d8_volume_LockBox(IDirect3DVolume8 *iface,
 
     wined3d_mutex_lock();
     if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture),
 
     wined3d_mutex_lock();
     if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture),
-            volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box, flags)))
+            volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box,
+            wined3dmapflags_from_d3dmapflags(flags))))
         map_desc.data = NULL;
     wined3d_mutex_unlock();
 
         map_desc.data = NULL;
     wined3d_mutex_unlock();
 
@@ -152,6 +156,8 @@ static HRESULT WINAPI d3d8_volume_LockBox(IDirect3DVolume8 *iface,
     locked_box->SlicePitch = map_desc.slice_pitch;
     locked_box->pBits = map_desc.data;
 
     locked_box->SlicePitch = map_desc.slice_pitch;
     locked_box->pBits = map_desc.data;
 
+    if (hr == E_INVALIDARG)
+        return D3DERR_INVALIDCALL;
     return hr;
 }
 
     return hr;
 }
 
@@ -192,7 +198,7 @@ static void STDMETHODCALLTYPE volume_wined3d_object_destroyed(void *parent)
 {
     struct d3d8_volume *volume = parent;
     d3d8_resource_cleanup(&volume->resource);
 {
     struct d3d8_volume *volume = parent;
     d3d8_resource_cleanup(&volume->resource);
-    HeapFree(GetProcessHeap(), 0, volume);
+    heap_free(volume);
 }
 
 static const struct wined3d_parent_ops d3d8_volume_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d8_volume_wined3d_parent_ops =
index 9dd8b4a..223606b 100644 (file)
@@ -19,7 +19,7 @@ list(APPEND SOURCE
     texture.c
     vertexdeclaration.c
     volume.c
     texture.c
     vertexdeclaration.c
     volume.c
-    d3d9_private.h)
+    precomp.h)
 
 add_library(d3d9 SHARED
     ${SOURCE}
 
 add_library(d3d9 SHARED
     ${SOURCE}
@@ -31,5 +31,5 @@ add_library(d3d9 SHARED
 set_module_type(d3d9 win32dll UNICODE)
 target_link_libraries(d3d9 wine)
 add_importlibs(d3d9 d3dwine user32 msvcrt kernel32 ntdll)
 set_module_type(d3d9 win32dll UNICODE)
 target_link_libraries(d3d9 wine)
 add_importlibs(d3d9 d3dwine user32 msvcrt kernel32 ntdll)
-add_pch(d3d9 d3d9_private.h SOURCE)
+add_pch(d3d9 precomp.h SOURCE)
 add_cd_file(TARGET d3d9 DESTINATION reactos/system32 FOR all)
 add_cd_file(TARGET d3d9 DESTINATION reactos/system32 FOR all)
index 462ef3b..36a6ae3 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9_vertexbuffer *impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_vertexbuffer, IDirect3DVertexBuffer9_iface);
 static inline struct d3d9_vertexbuffer *impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_vertexbuffer, IDirect3DVertexBuffer9_iface);
@@ -191,7 +194,7 @@ static HRESULT WINAPI d3d9_vertexbuffer_Lock(IDirect3DVertexBuffer9 *iface, UINT
     wined3d_box.right = offset + size;
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
     wined3d_box.right = offset + size;
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
-            0, &wined3d_map_desc, &wined3d_box, flags);
+            0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags));
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
@@ -226,10 +229,10 @@ static HRESULT WINAPI d3d9_vertexbuffer_GetDesc(IDirect3DVertexBuffer9 *iface,
     wined3d_mutex_unlock();
 
     desc->Format = D3DFMT_VERTEXDATA;
     wined3d_mutex_unlock();
 
     desc->Format = D3DFMT_VERTEXDATA;
-    desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-    desc->Pool = wined3d_desc.pool;
-    desc->Size = wined3d_desc.size;
     desc->Type = D3DRTYPE_VERTEXBUFFER;
     desc->Type = D3DRTYPE_VERTEXBUFFER;
+    desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+    desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
+    desc->Size = wined3d_desc.size;
     desc->FVF = buffer->fvf;
 
     return D3D_OK;
     desc->FVF = buffer->fvf;
 
     return D3D_OK;
@@ -260,7 +263,7 @@ static void STDMETHODCALLTYPE d3d9_vertexbuffer_wined3d_object_destroyed(void *p
 {
     struct d3d9_vertexbuffer *buffer = parent;
     d3d9_resource_cleanup(&buffer->resource);
 {
     struct d3d9_vertexbuffer *buffer = parent;
     d3d9_resource_cleanup(&buffer->resource);
-    HeapFree(GetProcessHeap(), 0, buffer);
+    heap_free(buffer);
 }
 
 static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops =
@@ -271,15 +274,30 @@ static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops =
 HRESULT vertexbuffer_init(struct d3d9_vertexbuffer *buffer, struct d3d9_device *device,
         UINT size, UINT usage, DWORD fvf, D3DPOOL pool)
 {
 HRESULT vertexbuffer_init(struct d3d9_vertexbuffer *buffer, struct d3d9_device *device,
         UINT size, UINT usage, DWORD fvf, D3DPOOL pool)
 {
+    struct wined3d_buffer_desc desc;
     HRESULT hr;
 
     HRESULT hr;
 
+    if (pool == D3DPOOL_SCRATCH)
+    {
+        WARN("Vertex buffer with D3DPOOL_SCRATCH requested.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     buffer->IDirect3DVertexBuffer9_iface.lpVtbl = &d3d9_vertexbuffer_vtbl;
     buffer->fvf = fvf;
     d3d9_resource_init(&buffer->resource);
 
     buffer->IDirect3DVertexBuffer9_iface.lpVtbl = &d3d9_vertexbuffer_vtbl;
     buffer->fvf = fvf;
     d3d9_resource_init(&buffer->resource);
 
+    desc.byte_width = size;
+    desc.usage = usage & WINED3DUSAGE_MASK;
+    desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+    desc.misc_flags = 0;
+    desc.structure_byte_stride = 0;
+
     wined3d_mutex_lock();
     wined3d_mutex_lock();
-    hr = wined3d_buffer_create_vb(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
-            (enum wined3d_pool)pool, buffer, &d3d9_vertexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
+    hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
+            &d3d9_vertexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -473,7 +491,7 @@ static HRESULT WINAPI d3d9_indexbuffer_Lock(IDirect3DIndexBuffer9 *iface,
     wined3d_box.right = offset + size;
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
     wined3d_box.right = offset + size;
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
-            0, &wined3d_map_desc, &wined3d_box, flags);
+            0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags));
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
@@ -507,10 +525,10 @@ static HRESULT WINAPI d3d9_indexbuffer_GetDesc(IDirect3DIndexBuffer9 *iface, D3D
     wined3d_mutex_unlock();
 
     desc->Format = d3dformat_from_wined3dformat(buffer->format);
     wined3d_mutex_unlock();
 
     desc->Format = d3dformat_from_wined3dformat(buffer->format);
-    desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-    desc->Pool = wined3d_desc.pool;
-    desc->Size = wined3d_desc.size;
     desc->Type = D3DRTYPE_INDEXBUFFER;
     desc->Type = D3DRTYPE_INDEXBUFFER;
+    desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+    desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
+    desc->Size = wined3d_desc.size;
 
     return D3D_OK;
 }
 
     return D3D_OK;
 }
@@ -540,7 +558,7 @@ static void STDMETHODCALLTYPE d3d9_indexbuffer_wined3d_object_destroyed(void *pa
 {
     struct d3d9_indexbuffer *buffer = parent;
     d3d9_resource_cleanup(&buffer->resource);
 {
     struct d3d9_indexbuffer *buffer = parent;
     d3d9_resource_cleanup(&buffer->resource);
-    HeapFree(GetProcessHeap(), 0, buffer);
+    heap_free(buffer);
 }
 
 static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops =
@@ -551,15 +569,26 @@ static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops =
 HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *device,
         UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
 {
 HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *device,
         UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
 {
+    struct wined3d_buffer_desc desc;
     HRESULT hr;
 
     HRESULT hr;
 
+    desc.byte_width = size;
+    desc.usage = (usage & WINED3DUSAGE_MASK) | WINED3DUSAGE_STATICDECL;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+    desc.misc_flags = 0;
+    desc.structure_byte_stride = 0;
+
     buffer->IDirect3DIndexBuffer9_iface.lpVtbl = &d3d9_indexbuffer_vtbl;
     buffer->format = wined3dformat_from_d3dformat(format);
     d3d9_resource_init(&buffer->resource);
 
     wined3d_mutex_lock();
     buffer->IDirect3DIndexBuffer9_iface.lpVtbl = &d3d9_indexbuffer_vtbl;
     buffer->format = wined3dformat_from_d3dformat(format);
     d3d9_resource_init(&buffer->resource);
 
     wined3d_mutex_lock();
-    hr = wined3d_buffer_create_ib(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
-            (enum wined3d_pool)pool, buffer, &d3d9_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
+    hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
+            &d3d9_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
index 4bd80e1..c23fa54 100644 (file)
  *
  */
 
  *
  */
 
+#include "config.h"
+#include "initguid.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static int D3DPERF_event_level = 0;
 
 void WINAPI DebugSetMute(void) {
 static int D3DPERF_event_level = 0;
 
 void WINAPI DebugSetMute(void) {
@@ -35,13 +39,13 @@ IDirect3D9 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate9(UINT sdk_version)
 
     TRACE("sdk_version %#x.\n", sdk_version);
 
 
     TRACE("sdk_version %#x.\n", sdk_version);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return NULL;
 
     if (!d3d9_init(object, FALSE))
     {
         WARN("Failed to initialize d3d9.\n");
         return NULL;
 
     if (!d3d9_init(object, FALSE))
     {
         WARN("Failed to initialize d3d9.\n");
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return NULL;
     }
 
         return NULL;
     }
 
@@ -56,13 +60,13 @@ HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT sdk_version, IDirect3D9E
 
     TRACE("sdk_version %#x, d3d9ex %p.\n", sdk_version, d3d9ex);
 
 
     TRACE("sdk_version %#x, d3d9ex %p.\n", sdk_version, d3d9ex);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (!d3d9_init(object, TRUE))
     {
         WARN("Failed to initialize d3d9.\n");
         return E_OUTOFMEMORY;
 
     if (!d3d9_init(object, TRUE))
     {
         WARN("Failed to initialize d3d9.\n");
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return D3DERR_NOTAVAILABLE;
     }
 
         return D3DERR_NOTAVAILABLE;
     }
 
index d34dd73..ba19e5f 100644 (file)
 #ifndef __WINE_D3D9_PRIVATE_H
 #define __WINE_D3D9_PRIVATE_H
 
 #ifndef __WINE_D3D9_PRIVATE_H
 #define __WINE_D3D9_PRIVATE_H
 
-#include <config.h>
-
 #include <assert.h>
 #include <stdarg.h>
 
 #include <assert.h>
 #include <stdarg.h>
 
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #define COBJMACROS
-#include <windef.h>
-#include <winbase.h>
-#include <wingdi.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "wine/debug.h"
+#include "wine/heap.h"
+#include "wine/unicode.h"
 
 
-#include <wine/debug.h>
-WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+#include "d3d9.h"
+#include "wine/wined3d.h"
 
 
-#include <d3d9.h>
-#include <wine/wined3d.h>
+#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256
+#define D3D9_MAX_TEXTURE_UNITS 20
 
 #define D3DPRESENTFLAGS_MASK 0x00000fffu
 
 
 #define D3DPRESENTFLAGS_MASK 0x00000fffu
 
+#define D3D9_TEXTURE_MIPMAP_DIRTY 0x1
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
 extern const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops DECLSPEC_HIDDEN;
 
 HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN;
 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
 extern const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops DECLSPEC_HIDDEN;
 
 HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN;
 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
+unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) DECLSPEC_HIDDEN;
 void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
         const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN;
 void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN;
 void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
         const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN;
 void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN;
@@ -98,6 +101,9 @@ struct d3d9_device
     UINT index_buffer_size;
     UINT index_buffer_pos;
 
     UINT index_buffer_size;
     UINT index_buffer_pos;
 
+    struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS];
+    struct d3d9_surface *render_targets[D3D_MAX_SIMULTANEOUS_RENDERTARGETS];
+
     LONG device_state;
     BOOL in_destruction;
     BOOL in_scene;
     LONG device_state;
     BOOL in_destruction;
     BOOL in_scene;
@@ -204,6 +210,10 @@ struct d3d9_texture
     struct wined3d_texture *wined3d_texture;
     IDirect3DDevice9Ex *parent_device;
     struct list rtv_list;
     struct wined3d_texture *wined3d_texture;
     IDirect3DDevice9Ex *parent_device;
     struct list rtv_list;
+    DWORD usage;
+    BOOL flags;
+    struct wined3d_shader_resource_view *wined3d_srv;
+    D3DTEXTUREFILTERTYPE autogen_filter_type;
 };
 
 HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
 };
 
 HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
@@ -213,6 +223,8 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
 HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
         UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN;
 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface) DECLSPEC_HIDDEN;
 HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
         UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN;
 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface) DECLSPEC_HIDDEN;
+void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture) DECLSPEC_HIDDEN;
+void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture) DECLSPEC_HIDDEN;
 
 struct d3d9_stateblock
 {
 
 struct d3d9_stateblock
 {
@@ -253,9 +265,6 @@ HRESULT vertexshader_init(struct d3d9_vertexshader *shader,
         struct d3d9_device *device, const DWORD *byte_code) DECLSPEC_HIDDEN;
 struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface) DECLSPEC_HIDDEN;
 
         struct d3d9_device *device, const DWORD *byte_code) DECLSPEC_HIDDEN;
 struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface) DECLSPEC_HIDDEN;
 
-#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256
-#define D3D9_MAX_SIMULTANEOUS_RENDERTARGETS 4
-
 struct d3d9_pixelshader
 {
     IDirect3DPixelShader9 IDirect3DPixelShader9_iface;
 struct d3d9_pixelshader
 {
     IDirect3DPixelShader9 IDirect3DPixelShader9_iface;
@@ -284,4 +293,49 @@ static inline struct d3d9_device *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9E
     return CONTAINING_RECORD(iface, struct d3d9_device, IDirect3DDevice9Ex_iface);
 }
 
     return CONTAINING_RECORD(iface, struct d3d9_device, IDirect3DDevice9Ex_iface);
 }
 
+static inline DWORD d3dusage_from_wined3dusage(unsigned int usage)
+{
+    return usage & WINED3DUSAGE_MASK;
+}
+
+static inline D3DPOOL d3dpool_from_wined3daccess(unsigned int access, unsigned int usage)
+{
+    switch (access & (WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU))
+    {
+        default:
+        case WINED3D_RESOURCE_ACCESS_GPU:
+            return D3DPOOL_DEFAULT;
+        case WINED3D_RESOURCE_ACCESS_CPU:
+            if (usage & WINED3DUSAGE_SCRATCH)
+                return D3DPOOL_SCRATCH;
+            return D3DPOOL_SYSTEMMEM;
+        case WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU:
+            return D3DPOOL_MANAGED;
+    }
+}
+
+static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool, unsigned int usage)
+{
+    switch (pool)
+    {
+        case D3DPOOL_DEFAULT:
+            if (usage & D3DUSAGE_DYNAMIC)
+                return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+            return WINED3D_RESOURCE_ACCESS_GPU;
+        case D3DPOOL_MANAGED:
+            return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU
+                    | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        case D3DPOOL_SYSTEMMEM:
+        case D3DPOOL_SCRATCH:
+            return WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        default:
+            return 0;
+    }
+}
+
+static inline DWORD wined3dusage_from_d3dusage(unsigned int usage)
+{
+    return usage & WINED3DUSAGE_MASK;
+}
+
 #endif /* __WINE_D3D9_PRIVATE_H */
 #endif /* __WINE_D3D9_PRIVATE_H */
index b3e085f..bc73699 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
-#include <winuser.h>
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
 
 static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {}
 
 
 static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {}
 
@@ -159,6 +160,30 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
     }
 }
 
     }
 }
 
+unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags)
+{
+    static const unsigned int handled = D3DLOCK_NOSYSLOCK
+            | D3DLOCK_NOOVERWRITE
+            | D3DLOCK_DISCARD
+            | D3DLOCK_DONOTWAIT
+            | D3DLOCK_NO_DIRTY_UPDATE;
+    unsigned int wined3d_flags;
+
+    wined3d_flags = flags & handled;
+    if (!(flags & (D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD)))
+        wined3d_flags |= WINED3D_MAP_READ;
+    if (!(flags & D3DLOCK_READONLY))
+        wined3d_flags |= WINED3D_MAP_WRITE;
+    if (!(wined3d_flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE)))
+        wined3d_flags |= WINED3D_MAP_READ | WINED3D_MAP_WRITE;
+    flags &= ~(handled | D3DLOCK_READONLY);
+
+    if (flags)
+        FIXME("Unhandled flags %#x.\n", flags);
+
+    return wined3d_flags;
+}
+
 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
 {
     switch (primitive_type)
 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
 {
     switch (primitive_type)
@@ -185,6 +210,26 @@ static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, U
     }
 }
 
     }
 }
 
+static D3DSWAPEFFECT d3dswapeffect_from_wined3dswapeffect(enum wined3d_swap_effect effect)
+{
+    switch (effect)
+    {
+        case WINED3D_SWAP_EFFECT_DISCARD:
+            return D3DSWAPEFFECT_DISCARD;
+        case WINED3D_SWAP_EFFECT_SEQUENTIAL:
+            return D3DSWAPEFFECT_FLIP;
+        case WINED3D_SWAP_EFFECT_COPY:
+            return D3DSWAPEFFECT_COPY;
+        case WINED3D_SWAP_EFFECT_OVERLAY:
+            return D3DSWAPEFFECT_OVERLAY;
+        case WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL:
+            return D3DSWAPEFFECT_FLIPEX;
+        default:
+            FIXME("Unhandled swap effect %#x.\n", effect);
+            return D3DSWAPEFFECT_FLIP;
+    }
+}
+
 void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
         const struct wined3d_swapchain_desc *swapchain_desc)
 {
 void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
         const struct wined3d_swapchain_desc *swapchain_desc)
 {
@@ -194,7 +239,7 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese
     present_parameters->BackBufferCount = swapchain_desc->backbuffer_count;
     present_parameters->MultiSampleType = swapchain_desc->multisample_type;
     present_parameters->MultiSampleQuality = swapchain_desc->multisample_quality;
     present_parameters->BackBufferCount = swapchain_desc->backbuffer_count;
     present_parameters->MultiSampleType = swapchain_desc->multisample_type;
     present_parameters->MultiSampleQuality = swapchain_desc->multisample_quality;
-    present_parameters->SwapEffect = swapchain_desc->swap_effect;
+    present_parameters->SwapEffect = d3dswapeffect_from_wined3dswapeffect(swapchain_desc->swap_effect);
     present_parameters->hDeviceWindow = swapchain_desc->device_window;
     present_parameters->Windowed = swapchain_desc->windowed;
     present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
     present_parameters->hDeviceWindow = swapchain_desc->device_window;
     present_parameters->Windowed = swapchain_desc->windowed;
     present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
@@ -205,6 +250,26 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese
     present_parameters->PresentationInterval = swapchain_desc->swap_interval;
 }
 
     present_parameters->PresentationInterval = swapchain_desc->swap_interval;
 }
 
+static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect)
+{
+    switch (effect)
+    {
+        case D3DSWAPEFFECT_DISCARD:
+            return WINED3D_SWAP_EFFECT_DISCARD;
+        case D3DSWAPEFFECT_FLIP:
+            return WINED3D_SWAP_EFFECT_SEQUENTIAL;
+        case D3DSWAPEFFECT_COPY:
+            return WINED3D_SWAP_EFFECT_COPY;
+        case D3DSWAPEFFECT_OVERLAY:
+            return WINED3D_SWAP_EFFECT_OVERLAY;
+        case D3DSWAPEFFECT_FLIPEX:
+            return WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL;
+        default:
+            FIXME("Unhandled swap effect %#x.\n", effect);
+            return WINED3D_SWAP_EFFECT_SEQUENTIAL;
+    }
+}
+
 static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
         const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended)
 {
 static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
         const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended)
 {
@@ -228,9 +293,10 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
     swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
     swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
     swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount);
     swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
     swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
     swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount);
+    swapchain_desc->backbuffer_usage = WINED3DUSAGE_RENDERTARGET;
     swapchain_desc->multisample_type = present_parameters->MultiSampleType;
     swapchain_desc->multisample_quality = present_parameters->MultiSampleQuality;
     swapchain_desc->multisample_type = present_parameters->MultiSampleType;
     swapchain_desc->multisample_quality = present_parameters->MultiSampleQuality;
-    swapchain_desc->swap_effect = present_parameters->SwapEffect;
+    swapchain_desc->swap_effect = wined3dswapeffect_from_d3dswapeffect(present_parameters->SwapEffect);
     swapchain_desc->device_window = present_parameters->hDeviceWindow;
     swapchain_desc->windowed = present_parameters->Windowed;
     swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
     swapchain_desc->device_window = present_parameters->hDeviceWindow;
     swapchain_desc->windowed = present_parameters->Windowed;
     swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
@@ -387,7 +453,7 @@ void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps)
         D3DPTEXTURECAPS_CUBEMAP_POW2   | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
 
     caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
         D3DPTEXTURECAPS_CUBEMAP_POW2   | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
 
     caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
-    caps->NumSimultaneousRTs = min(D3D9_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs);
+    caps->NumSimultaneousRTs = min(D3D_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs);
 
     if (caps->PixelShaderVersion > 3)
     {
 
     if (caps->PixelShaderVersion > 3)
     {
@@ -478,14 +544,14 @@ static ULONG WINAPI DECLSPEC_HOTPATCH d3d9_device_Release(IDirect3DDevice9Ex *if
         {
             wined3d_vertex_declaration_decref(device->fvf_decls[i].decl);
         }
         {
             wined3d_vertex_declaration_decref(device->fvf_decls[i].decl);
         }
-        HeapFree(GetProcessHeap(), 0, device->fvf_decls);
+        heap_free(device->fvf_decls);
 
         if (device->vertex_buffer)
             wined3d_buffer_decref(device->vertex_buffer);
         if (device->index_buffer)
             wined3d_buffer_decref(device->index_buffer);
 
 
         if (device->vertex_buffer)
             wined3d_buffer_decref(device->vertex_buffer);
         if (device->index_buffer)
             wined3d_buffer_decref(device->index_buffer);
 
-        HeapFree(GetProcessHeap(), 0, device->implicit_swapchains);
+        heap_free(device->implicit_swapchains);
 
         wined3d_device_uninit_3d(device->wined3d_device);
         wined3d_device_release_focus_window(device->wined3d_device);
 
         wined3d_device_uninit_3d(device->wined3d_device);
         wined3d_device_release_focus_window(device->wined3d_device);
@@ -494,7 +560,7 @@ static ULONG WINAPI DECLSPEC_HOTPATCH d3d9_device_Release(IDirect3DDevice9Ex *if
 
         IDirect3D9Ex_Release(&device->d3d_parent->IDirect3D9Ex_iface);
 
 
         IDirect3D9Ex_Release(&device->d3d_parent->IDirect3D9Ex_iface);
 
-        HeapFree(GetProcessHeap(), 0, device);
+        heap_free(device);
     }
 
     return refcount;
     }
 
     return refcount;
@@ -764,7 +830,7 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
     IUnknown *parent;
 
     wined3d_resource_get_desc(resource, &desc);
     IUnknown *parent;
 
     wined3d_resource_get_desc(resource, &desc);
-    if (desc.pool != WINED3D_POOL_DEFAULT)
+    if (desc.access & WINED3D_RESOURCE_ACCESS_CPU)
         return D3D_OK;
 
     if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D)
         return D3D_OK;
 
     if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D)
@@ -794,8 +860,7 @@ static HRESULT d3d9_device_get_swapchains(struct d3d9_device *device)
     UINT i, new_swapchain_count = wined3d_device_get_swapchain_count(device->wined3d_device);
     struct wined3d_swapchain *wined3d_swapchain;
 
     UINT i, new_swapchain_count = wined3d_device_get_swapchain_count(device->wined3d_device);
     struct wined3d_swapchain *wined3d_swapchain;
 
-    if (!(device->implicit_swapchains = HeapAlloc(GetProcessHeap(), 0,
-            new_swapchain_count * sizeof(*device->implicit_swapchains))))
+    if (!(device->implicit_swapchains = heap_alloc(new_swapchain_count * sizeof(*device->implicit_swapchains))))
         return E_OUTOFMEMORY;
 
     for (i = 0; i < new_swapchain_count; ++i)
         return E_OUTOFMEMORY;
 
     for (i = 0; i < new_swapchain_count; ++i)
@@ -814,9 +879,10 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
     BOOL extended = device->d3d_parent->extended;
     struct wined3d_swapchain_desc swapchain_desc;
     struct wined3d_display_mode wined3d_mode;
     BOOL extended = device->d3d_parent->extended;
     struct wined3d_swapchain_desc swapchain_desc;
     struct wined3d_display_mode wined3d_mode;
+    struct wined3d_rendertarget_view *rtv;
+    unsigned int i;
     HRESULT hr;
 
     HRESULT hr;
 
-
     if (!extended && device->device_state == D3D9_DEVICE_STATE_LOST)
     {
         WARN("App not active, returning D3DERR_DEVICELOST.\n");
     if (!extended && device->device_state == D3D9_DEVICE_STATE_LOST)
     {
         WARN("App not active, returning D3DERR_DEVICELOST.\n");
@@ -854,7 +920,7 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
     if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
             mode ? &wined3d_mode : NULL, reset_enum_callback, !extended)))
     {
     if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
             mode ? &wined3d_mode : NULL, reset_enum_callback, !extended)))
     {
-        HeapFree(GetProcessHeap(), 0, device->implicit_swapchains);
+        heap_free(device->implicit_swapchains);
 
         if (!extended)
         {
 
         if (!extended)
         {
@@ -876,6 +942,15 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
 
             device->device_state = D3D9_DEVICE_STATE_OK;
         }
 
             device->device_state = D3D9_DEVICE_STATE_OK;
         }
+
+        if (!device->d3d_parent->extended)
+            for (i = 0; i < ARRAY_SIZE(device->textures); ++i)
+                device->textures[i] = NULL;
+
+        rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0);
+        device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
+        for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i)
+            device->render_targets[i] = NULL;
     }
     else if (!extended)
     {
     }
     else if (!extended)
     {
@@ -917,7 +992,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex *
     for (i = 0; i < device->implicit_swapchain_count; ++i)
     {
         if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
     for (i = 0; i < device->implicit_swapchain_count; ++i)
     {
         if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
-                src_rect, dst_rect, dst_window_override, 0)))
+                src_rect, dst_rect, dst_window_override, 0, 0)))
         {
             wined3d_mutex_unlock();
             return hr;
         {
             wined3d_mutex_unlock();
             return hr;
@@ -1050,15 +1125,14 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface,
         }
     }
 
         }
     }
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = texture_init(object, device, width, height, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize texture, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = texture_init(object, device, width, height, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize texture, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -1103,15 +1177,14 @@ static HRESULT WINAPI d3d9_device_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize volume texture, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize volume texture, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -1149,15 +1222,14 @@ static HRESULT WINAPI d3d9_device_CreateCubeTexture(IDirect3DDevice9Ex *iface,
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize cube texture, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize cube texture, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -1194,15 +1266,14 @@ static HRESULT WINAPI d3d9_device_CreateVertexBuffer(IDirect3DDevice9Ex *iface,
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = vertexbuffer_init(object, device, size, usage, fvf, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = vertexbuffer_init(object, device, size, usage, fvf, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -1239,15 +1310,14 @@ static HRESULT WINAPI d3d9_device_CreateIndexBuffer(IDirect3DDevice9Ex *iface, U
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = indexbuffer_init(object, device, size, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize index buffer, hr %#x.\n", hr);
         return D3DERR_OUTOFVIDEOMEMORY;
 
     hr = indexbuffer_init(object, device, size, usage, format, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize index buffer, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -1276,7 +1346,10 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
     desc.multisample_type = multisample_type;
     desc.multisample_quality = multisample_quality;
     desc.usage = usage & WINED3DUSAGE_MASK;
     desc.multisample_type = multisample_type;
     desc.multisample_quality = multisample_quality;
     desc.usage = usage & WINED3DUSAGE_MASK;
-    desc.pool = pool;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     desc.width = width;
     desc.height = height;
     desc.depth = 1;
     desc.width = width;
     desc.height = height;
     desc.depth = 1;
@@ -1428,6 +1501,9 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface,
             wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0,
             dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture),
             src->sub_resource_idx, &src_box);
             wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0,
             dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture),
             src->sub_resource_idx, &src_box);
+    if (SUCCEEDED(hr) && dst->texture)
+        d3d9_texture_flag_auto_gen_mipmap(dst->texture);
+
     wined3d_mutex_unlock();
 
     if (FAILED(hr))
     wined3d_mutex_unlock();
 
     if (FAILED(hr))
@@ -1451,6 +1527,8 @@ static HRESULT WINAPI d3d9_device_UpdateTexture(IDirect3DDevice9Ex *iface,
     wined3d_mutex_lock();
     hr = wined3d_device_update_texture(device->wined3d_device,
             src_impl->wined3d_texture, dst_impl->wined3d_texture);
     wined3d_mutex_lock();
     hr = wined3d_device_update_texture(device->wined3d_device,
             src_impl->wined3d_texture, dst_impl->wined3d_texture);
+    if (SUCCEEDED(hr))
+        d3d9_texture_flag_auto_gen_mipmap(dst_impl);
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -1534,6 +1612,23 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect
         src_rect = &s;
     }
 
         src_rect = &s;
     }
 
+    if (dst_desc.access & WINED3D_RESOURCE_ACCESS_CPU)
+    {
+        WARN("Destination resource is not in DEFAULT pool.\n");
+        goto done;
+    }
+    if (src_desc.access & WINED3D_RESOURCE_ACCESS_CPU)
+    {
+        WARN("Source resource is not in DEFAULT pool.\n");
+        goto done;
+    }
+
+    if (dst->texture && !(dst_desc.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)))
+    {
+        WARN("Destination is a regular texture.\n");
+        goto done;
+    }
+
     if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
     {
         if (device->in_scene)
     if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
     {
         if (device->in_scene)
@@ -1569,6 +1664,8 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect
             src->wined3d_texture, src->sub_resource_idx, src_rect, 0, NULL, filter);
     if (hr == WINEDDERR_INVALIDRECT)
         hr = D3DERR_INVALIDCALL;
             src->wined3d_texture, src->sub_resource_idx, src_rect, 0, NULL, filter);
     if (hr == WINEDDERR_INVALIDRECT)
         hr = D3DERR_INVALIDCALL;
+    if (SUCCEEDED(hr) && dst->texture)
+        d3d9_texture_flag_auto_gen_mipmap(dst->texture);
 
 done:
     wined3d_mutex_unlock();
 
 done:
     wined3d_mutex_unlock();
@@ -1602,10 +1699,10 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface,
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    if (desc.pool != WINED3D_POOL_DEFAULT)
+    if (desc.access & WINED3D_RESOURCE_ACCESS_CPU)
     {
         wined3d_mutex_unlock();
     {
         wined3d_mutex_unlock();
-        WARN("Colorfill is not allowed on surfaces in pool %#x, returning D3DERR_INVALIDCALL.\n", desc.pool);
+        WARN("Colour fills are not allowed on surfaces with resource access %#x.\n", desc.access);
         return D3DERR_INVALIDCALL;
     }
     if ((desc.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_TEXTURE)) == WINED3DUSAGE_TEXTURE)
         return D3DERR_INVALIDCALL;
     }
     if ((desc.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_TEXTURE)) == WINED3DUSAGE_TEXTURE)
@@ -1625,6 +1722,8 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface,
     hr = wined3d_device_clear_rendertarget_view(device->wined3d_device,
             rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0);
     d3d9_surface_release_rendertarget_view(surface_impl, rtv);
     hr = wined3d_device_clear_rendertarget_view(device->wined3d_device,
             rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0);
     d3d9_surface_release_rendertarget_view(surface_impl, rtv);
+    if (SUCCEEDED(hr) && surface_impl->texture)
+        d3d9_texture_flag_auto_gen_mipmap(surface_impl->texture);
 
     wined3d_mutex_unlock();
 
 
     wined3d_mutex_unlock();
 
@@ -1685,7 +1784,7 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO
 
     TRACE("iface %p, idx %u, surface %p.\n", iface, idx, surface);
 
 
     TRACE("iface %p, idx %u, surface %p.\n", iface, idx, surface);
 
-    if (idx >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
+    if (idx >= D3D_MAX_SIMULTANEOUS_RENDERTARGETS)
     {
         WARN("Invalid index %u specified.\n", idx);
         return D3DERR_INVALIDCALL;
     {
         WARN("Invalid index %u specified.\n", idx);
         return D3DERR_INVALIDCALL;
@@ -1707,6 +1806,8 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO
     rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL;
     hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, rtv, TRUE);
     d3d9_surface_release_rendertarget_view(surface_impl, rtv);
     rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL;
     hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, rtv, TRUE);
     d3d9_surface_release_rendertarget_view(surface_impl, rtv);
+    if (SUCCEEDED(hr))
+        device->render_targets[idx] = surface_impl;
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -1724,7 +1825,7 @@ static HRESULT WINAPI d3d9_device_GetRenderTarget(IDirect3DDevice9Ex *iface, DWO
     if (!surface)
         return D3DERR_INVALIDCALL;
 
     if (!surface)
         return D3DERR_INVALIDCALL;
 
-    if (idx >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
+    if (idx >= D3D_MAX_SIMULTANEOUS_RENDERTARGETS)
     {
         WARN("Invalid index %u specified.\n", idx);
         return D3DERR_INVALIDCALL;
     {
         WARN("Invalid index %u specified.\n", idx);
         return D3DERR_INVALIDCALL;
@@ -1827,6 +1928,19 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_EndScene(IDirect3DDevice9Ex
     return hr;
 }
 
     return hr;
 }
 
+static void d3d9_rts_flag_auto_gen_mipmap(struct d3d9_device *device)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(device->render_targets); ++i)
+    {
+        struct d3d9_surface *surface = device->render_targets[i];
+
+        if (surface && surface->texture)
+            d3d9_texture_flag_auto_gen_mipmap(surface->texture);
+    }
+}
+
 static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count,
         const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
 {
 static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count,
         const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
 {
@@ -1851,6 +1965,8 @@ static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_co
 
     wined3d_mutex_lock();
     hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
 
     wined3d_mutex_lock();
     hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
+    if (SUCCEEDED(hr))
+        d3d9_rts_flag_auto_gen_mipmap(device);
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -2104,15 +2220,14 @@ static HRESULT WINAPI d3d9_device_CreateStateBlock(IDirect3DDevice9Ex *iface,
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = stateblock_init(object, device, type, NULL);
     if (FAILED(hr))
     {
         WARN("Failed to initialize stateblock, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = stateblock_init(object, device, type, NULL);
     if (FAILED(hr))
     {
         WARN("Failed to initialize stateblock, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -2154,8 +2269,7 @@ static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDire
        return hr;
     }
 
        return hr;
     }
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         wined3d_mutex_lock();
         wined3d_stateblock_decref(wined3d_stateblock);
     {
         wined3d_mutex_lock();
         wined3d_stateblock_decref(wined3d_stateblock);
@@ -2170,7 +2284,7 @@ static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDire
         wined3d_mutex_lock();
         wined3d_stateblock_decref(wined3d_stateblock);
         wined3d_mutex_unlock();
         wined3d_mutex_lock();
         wined3d_stateblock_decref(wined3d_stateblock);
         wined3d_mutex_unlock();
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -2248,6 +2362,13 @@ static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD st
     wined3d_mutex_lock();
     hr = wined3d_device_set_texture(device->wined3d_device, stage,
             texture_impl ? texture_impl->wined3d_texture : NULL);
     wined3d_mutex_lock();
     hr = wined3d_device_set_texture(device->wined3d_device, stage,
             texture_impl ? texture_impl->wined3d_texture : NULL);
+    if (SUCCEEDED(hr))
+    {
+        unsigned int i = stage >= D3DVERTEXTEXTURESAMPLER0 ? stage - D3DVERTEXTEXTURESAMPLER0 + 16 : stage;
+
+        if (stage < ARRAY_SIZE(device->textures))
+            device->textures[i] = texture_impl;
+    }
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -2297,7 +2418,7 @@ static HRESULT WINAPI d3d9_device_GetTextureStageState(IDirect3DDevice9Ex *iface
 
     TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, stage, state, value);
 
 
     TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, stage, state, value);
 
-    if (state >= sizeof(tss_lookup) / sizeof(*tss_lookup))
+    if (state >= ARRAY_SIZE(tss_lookup))
     {
         WARN("Invalid state %#x passed.\n", state);
         return D3D_OK;
     {
         WARN("Invalid state %#x passed.\n", state);
         return D3D_OK;
@@ -2317,7 +2438,7 @@ static HRESULT WINAPI d3d9_device_SetTextureStageState(IDirect3DDevice9Ex *iface
 
     TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, state, value);
 
 
     TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, state, value);
 
-    if (state >= sizeof(tss_lookup) / sizeof(*tss_lookup))
+    if (state >= ARRAY_SIZE(tss_lookup))
     {
         WARN("Invalid state %#x passed.\n", state);
         return D3D_OK;
     {
         WARN("Invalid state %#x passed.\n", state);
         return D3D_OK;
@@ -2488,6 +2609,16 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface)
     return ret;
 }
 
     return ret;
 }
 
+/* wined3d critical section must be taken by the caller. */
+static void d3d9_generate_auto_mipmaps(struct d3d9_device *device)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(device->textures); ++i)
+        if (device->textures[i])
+            d3d9_texture_gen_auto_mipmap(device->textures[i]);
+}
+
 static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
         D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count)
 {
 static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
         D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count)
 {
@@ -2504,9 +2635,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
         WARN("Called without a valid vertex declaration set.\n");
         return D3DERR_INVALIDCALL;
     }
         WARN("Called without a valid vertex declaration set.\n");
         return D3DERR_INVALIDCALL;
     }
+    d3d9_generate_auto_mipmaps(device);
     wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
             vertex_count_from_primitive_count(primitive_type, primitive_count));
     wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
             vertex_count_from_primitive_count(primitive_type, primitive_count));
+    if (SUCCEEDED(hr))
+        d3d9_rts_flag_auto_gen_mipmap(device);
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -2531,10 +2665,13 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
         WARN("Called without a valid vertex declaration set.\n");
         return D3DERR_INVALIDCALL;
     }
         WARN("Called without a valid vertex declaration set.\n");
         return D3DERR_INVALIDCALL;
     }
+    d3d9_generate_auto_mipmaps(device);
     wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx);
     wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
             vertex_count_from_primitive_count(primitive_type, primitive_count));
     wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx);
     wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
             vertex_count_from_primitive_count(primitive_type, primitive_count));
+    if (SUCCEEDED(hr))
+        d3d9_rts_flag_auto_gen_mipmap(device);
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -2548,15 +2685,22 @@ static HRESULT d3d9_device_prepare_vertex_buffer(struct d3d9_device *device, UIN
     if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
     {
         UINT size = max(device->vertex_buffer_size * 2, min_size);
     if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
     {
         UINT size = max(device->vertex_buffer_size * 2, min_size);
+        struct wined3d_buffer_desc desc;
         struct wined3d_buffer *buffer;
 
         TRACE("Growing vertex buffer to %u bytes.\n", size);
 
         struct wined3d_buffer *buffer;
 
         TRACE("Growing vertex buffer to %u bytes.\n", size);
 
-        hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
-                WINED3D_POOL_DEFAULT, NULL, &d3d9_null_wined3d_parent_ops, &buffer);
-        if (FAILED(hr))
+        desc.byte_width = size;
+        desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY;
+        desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        desc.misc_flags = 0;
+        desc.structure_byte_stride = 0;
+
+        if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc,
+                NULL, NULL, &d3d9_null_wined3d_parent_ops, &buffer)))
         {
         {
-            ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x.\n", device, hr);
+            ERR("Failed to create vertex buffer, hr %#x.\n", hr);
             return hr;
         }
 
             return hr;
         }
 
@@ -2616,7 +2760,7 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface,
     wined3d_box.right = vb_pos + size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = vb_pos + size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
-            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, data, size);
     wined3d_resource_unmap(vb, 0);
         goto done;
     memcpy(wined3d_map_desc.data, data, size);
     wined3d_resource_unmap(vb, 0);
@@ -2626,9 +2770,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface,
     if (FAILED(hr))
         goto done;
 
     if (FAILED(hr))
         goto done;
 
+    d3d9_generate_auto_mipmaps(device);
     wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count);
     wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
     wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count);
     wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
+    if (SUCCEEDED(hr))
+        d3d9_rts_flag_auto_gen_mipmap(device);
 
 done:
     wined3d_mutex_unlock();
 
 done:
     wined3d_mutex_unlock();
@@ -2643,15 +2790,22 @@ static HRESULT d3d9_device_prepare_index_buffer(struct d3d9_device *device, UINT
     if (device->index_buffer_size < min_size || !device->index_buffer)
     {
         UINT size = max(device->index_buffer_size * 2, min_size);
     if (device->index_buffer_size < min_size || !device->index_buffer)
     {
         UINT size = max(device->index_buffer_size * 2, min_size);
+        struct wined3d_buffer_desc desc;
         struct wined3d_buffer *buffer;
 
         TRACE("Growing index buffer to %u bytes.\n", size);
 
         struct wined3d_buffer *buffer;
 
         TRACE("Growing index buffer to %u bytes.\n", size);
 
-        hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
-                WINED3D_POOL_DEFAULT, NULL, &d3d9_null_wined3d_parent_ops, &buffer);
-        if (FAILED(hr))
+        desc.byte_width = size;
+        desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_STATICDECL;
+        desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        desc.misc_flags = 0;
+        desc.structure_byte_stride = 0;
+
+        if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc,
+                NULL, NULL, &d3d9_null_wined3d_parent_ops, &buffer)))
         {
         {
-            ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x.\n", device, hr);
+            ERR("Failed to create index buffer, hr %#x.\n", hr);
             return hr;
         }
 
             return hr;
         }
 
@@ -2717,7 +2871,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa
     wined3d_box.right = vb_pos + vtx_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = vb_pos + vtx_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
-            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, (char *)vertex_data + min_vertex_idx * vertex_stride, vtx_size);
     wined3d_resource_unmap(vb, 0);
         goto done;
     memcpy(wined3d_map_desc.data, (char *)vertex_data + min_vertex_idx * vertex_stride, vtx_size);
     wined3d_resource_unmap(vb, 0);
@@ -2739,7 +2893,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa
     wined3d_box.right = ib_pos + idx_size;
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = ib_pos + idx_size;
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
-            ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, index_data, idx_size);
     wined3d_resource_unmap(ib, 0);
         goto done;
     memcpy(wined3d_map_desc.data, index_data, idx_size);
     wined3d_resource_unmap(ib, 0);
@@ -2749,6 +2903,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa
     if (FAILED(hr))
         goto done;
 
     if (FAILED(hr))
         goto done;
 
+    d3d9_generate_auto_mipmaps(device);
     wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer,
             wined3dformat_from_d3dformat(index_format), 0);
     wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx);
     wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer,
             wined3dformat_from_d3dformat(index_format), 0);
     wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx);
@@ -2760,6 +2915,9 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa
     wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0);
     wined3d_device_set_base_vertex_index(device->wined3d_device, 0);
 
     wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0);
     wined3d_device_set_base_vertex_index(device->wined3d_device, 0);
 
+    if (SUCCEEDED(hr))
+        d3d9_rts_flag_auto_gen_mipmap(device);
+
 done:
     wined3d_mutex_unlock();
     return hr;
 done:
     wined3d_mutex_unlock();
     return hr;
@@ -2887,7 +3045,7 @@ static struct wined3d_vertex_declaration *device_get_fvf_declaration(struct d3d9
         return NULL;
 
     hr = d3d9_vertex_declaration_create(device, elements, &d3d9_declaration);
         return NULL;
 
     hr = d3d9_vertex_declaration_create(device, elements, &d3d9_declaration);
-    HeapFree(GetProcessHeap(), 0, elements);
+    heap_free(elements);
     if (FAILED(hr))
         return NULL;
 
     if (FAILED(hr))
         return NULL;
 
@@ -2895,8 +3053,7 @@ static struct wined3d_vertex_declaration *device_get_fvf_declaration(struct d3d9
     {
         UINT grow = max(device->fvf_decl_size / 2, 8);
 
     {
         UINT grow = max(device->fvf_decl_size / 2, 8);
 
-        fvf_decls = HeapReAlloc(GetProcessHeap(), 0, fvf_decls, sizeof(*fvf_decls) * (device->fvf_decl_size + grow));
-        if (!fvf_decls)
+        if (!(fvf_decls = heap_realloc(fvf_decls, sizeof(*fvf_decls) * (device->fvf_decl_size + grow))))
         {
             IDirect3DVertexDeclaration9_Release(&d3d9_declaration->IDirect3DVertexDeclaration9_iface);
             return NULL;
         {
             IDirect3DVertexDeclaration9_Release(&d3d9_declaration->IDirect3DVertexDeclaration9_iface);
             return NULL;
@@ -2982,15 +3139,14 @@ static HRESULT WINAPI d3d9_device_CreateVertexShader(IDirect3DDevice9Ex *iface,
 
     TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
 
 
     TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = vertexshader_init(object, device, byte_code);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = vertexshader_init(object, device, byte_code);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -3280,8 +3436,7 @@ static HRESULT WINAPI d3d9_device_CreatePixelShader(IDirect3DDevice9Ex *iface,
 
     TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
 
 
     TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         FIXME("Failed to allocate pixel shader memory.\n");
         return E_OUTOFMEMORY;
     {
         FIXME("Failed to allocate pixel shader memory.\n");
         return E_OUTOFMEMORY;
@@ -3291,7 +3446,7 @@ static HRESULT WINAPI d3d9_device_CreatePixelShader(IDirect3DDevice9Ex *iface,
     if (FAILED(hr))
     {
         WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -3468,15 +3623,14 @@ static HRESULT WINAPI d3d9_device_CreateQuery(IDirect3DDevice9Ex *iface, D3DQUER
 
     TRACE("iface %p, type %#x, query %p.\n", iface, type, query);
 
 
     TRACE("iface %p, type %#x, query %p.\n", iface, type, query);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = query_init(object, device, type);
     if (FAILED(hr))
     {
         WARN("Failed to initialize query, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = query_init(object, device, type);
     if (FAILED(hr))
     {
         WARN("Failed to initialize query, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -3530,7 +3684,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex
     for (i = 0; i < device->implicit_swapchain_count; ++i)
     {
         if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
     for (i = 0; i < device->implicit_swapchain_count; ++i)
     {
         if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
-                src_rect, dst_rect, dst_window_override, flags)))
+                src_rect, dst_rect, dst_window_override, 0, flags)))
         {
             wined3d_mutex_unlock();
             return hr;
         {
             wined3d_mutex_unlock();
             return hr;
@@ -3905,7 +4059,7 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
     TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
-    if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
+    if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
         return E_OUTOFMEMORY;
 
     surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
         return E_OUTOFMEMORY;
 
     surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
@@ -3924,7 +4078,7 @@ static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *
     TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
-    if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume))))
+    if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
         return E_OUTOFMEMORY;
 
     volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
         return E_OUTOFMEMORY;
 
     volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
@@ -4075,8 +4229,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
         }
     }
 
         }
     }
 
-    swapchain_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain_desc) * count);
-    if (!swapchain_desc)
+    if (!(swapchain_desc = heap_alloc(sizeof(*swapchain_desc) * count)))
     {
         ERR("Failed to allocate wined3d parameters.\n");
         wined3d_device_release_focus_window(device->wined3d_device);
     {
         ERR("Failed to allocate wined3d parameters.\n");
         wined3d_device_release_focus_window(device->wined3d_device);
@@ -4092,7 +4245,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
         {
             wined3d_device_release_focus_window(device->wined3d_device);
             wined3d_device_decref(device->wined3d_device);
         {
             wined3d_device_release_focus_window(device->wined3d_device);
             wined3d_device_decref(device->wined3d_device);
-            HeapFree(GetProcessHeap(), 0, swapchain_desc);
+            heap_free(swapchain_desc);
             wined3d_mutex_unlock();
             return D3DERR_INVALIDCALL;
         }
             wined3d_mutex_unlock();
             return D3DERR_INVALIDCALL;
         }
@@ -4102,7 +4255,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
     {
         WARN("Failed to initialize 3D, hr %#x.\n", hr);
         wined3d_device_release_focus_window(device->wined3d_device);
     {
         WARN("Failed to initialize 3D, hr %#x.\n", hr);
         wined3d_device_release_focus_window(device->wined3d_device);
-        HeapFree(GetProcessHeap(), 0, swapchain_desc);
+        heap_free(swapchain_desc);
         wined3d_device_decref(device->wined3d_device);
         wined3d_mutex_unlock();
         return hr;
         wined3d_device_decref(device->wined3d_device);
         wined3d_mutex_unlock();
         return hr;
@@ -4127,16 +4280,15 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
 
     wined3d_mutex_unlock();
 
 
     wined3d_mutex_unlock();
 
-    HeapFree(GetProcessHeap(), 0, swapchain_desc);
+    heap_free(swapchain_desc);
 
     /* Initialize the converted declaration array. This creates a valid pointer
      * and when adding decls HeapReAlloc() can be used without further checking. */
 
     /* Initialize the converted declaration array. This creates a valid pointer
      * and when adding decls HeapReAlloc() can be used without further checking. */
-    device->fvf_decls = HeapAlloc(GetProcessHeap(), 0, 0);
-    if (!device->fvf_decls)
+    if (!(device->fvf_decls = heap_alloc(0)))
     {
         ERR("Failed to allocate FVF vertex declaration map memory.\n");
         wined3d_mutex_lock();
     {
         ERR("Failed to allocate FVF vertex declaration map memory.\n");
         wined3d_mutex_lock();
-        HeapFree(GetProcessHeap(), 0, device->implicit_swapchains);
+        heap_free(device->implicit_swapchains);
         wined3d_device_uninit_3d(device->wined3d_device);
         wined3d_device_release_focus_window(device->wined3d_device);
         wined3d_device_decref(device->wined3d_device);
         wined3d_device_uninit_3d(device->wined3d_device);
         wined3d_device_release_focus_window(device->wined3d_device);
         wined3d_device_decref(device->wined3d_device);
@@ -4144,6 +4296,14 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
         return E_OUTOFMEMORY;
     }
 
         return E_OUTOFMEMORY;
     }
 
+    /* We could also simply ignore the initial rendertarget since it's known
+     * not to be a texture (we currently use these only for automatic mipmap
+     * generation). */
+    wined3d_mutex_lock();
+    device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(
+            wined3d_device_get_rendertarget_view(device->wined3d_device, 0));
+    wined3d_mutex_unlock();
+
     IDirect3D9Ex_AddRef(&parent->IDirect3D9Ex_iface);
     device->d3d_parent = parent;
 
     IDirect3D9Ex_AddRef(&parent->IDirect3D9Ex_iface);
     device->d3d_parent = parent;
 
index ab153a9..644766c 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9 *impl_from_IDirect3D9Ex(IDirect3D9Ex *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9, IDirect3D9Ex_iface);
 static inline struct d3d9 *impl_from_IDirect3D9Ex(IDirect3D9Ex *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9, IDirect3D9Ex_iface);
@@ -83,7 +86,7 @@ static ULONG WINAPI d3d9_Release(IDirect3D9Ex *iface)
         wined3d_decref(d3d9->wined3d);
         wined3d_mutex_unlock();
 
         wined3d_decref(d3d9->wined3d);
         wined3d_mutex_unlock();
 
-        HeapFree(GetProcessHeap(), 0, d3d9);
+        heap_free(d3d9);
     }
 
     return refcount;
     }
 
     return refcount;
@@ -397,15 +400,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_CreateDevice(IDirect3D9Ex *iface, U
     TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, device %p.\n",
             iface, adapter, device_type, focus_window, flags, parameters, device);
 
     TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, device %p.\n",
             iface, adapter, device_type, focus_window, flags, parameters, device);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = device_init(object, d3d9, d3d9->wined3d, adapter, device_type, focus_window, flags, parameters, NULL);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = device_init(object, d3d9, d3d9->wined3d, adapter, device_type, focus_window, flags, parameters, NULL);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -505,15 +507,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_CreateDeviceEx(IDirect3D9Ex *iface,
     TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, mode %p, device %p.\n",
             iface, adapter, device_type, focus_window, flags, parameters, mode, device);
 
     TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, mode %p, device %p.\n",
             iface, adapter, device_type, focus_window, flags, parameters, mode, device);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = device_init(object, d3d9, d3d9->wined3d, adapter, device_type, focus_window, flags, parameters, mode);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = device_init(object, d3d9, d3d9->wined3d, adapter, device_type, focus_window, flags, parameters, mode);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -578,7 +579,7 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
     DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
             | WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR
             | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING
     DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
             | WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR
             | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING
-            | WINED3D_NORMALIZED_DEPTH_BIAS;
+            | WINED3D_NORMALIZED_DEPTH_BIAS | WINED3D_LIMIT_VIEWPORT;
 
     if (!extended)
         flags |= WINED3D_VIDMEM_ACCOUNTING;
 
     if (!extended)
         flags |= WINED3D_VIDMEM_ACCOUNTING;
diff --git a/dll/directx/wine/d3d9/precomp.h b/dll/directx/wine/d3d9/precomp.h
new file mode 100644 (file)
index 0000000..3d1e183
--- /dev/null
@@ -0,0 +1,13 @@
+
+#ifndef __WINE_D3D9_PRECOMP_H
+#define __WINE_D3D9_PRECOMP_H
+
+#include <wine/config.h>
+
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#include "d3d9_private.h"
+
+#endif /* __WINE_D3D9_PRECOMP_H */
index 8681502..12ff95b 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9_query *impl_from_IDirect3DQuery9(IDirect3DQuery9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_query, IDirect3DQuery9_iface);
 static inline struct d3d9_query *impl_from_IDirect3DQuery9(IDirect3DQuery9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_query, IDirect3DQuery9_iface);
@@ -69,7 +72,7 @@ static ULONG WINAPI d3d9_query_Release(IDirect3DQuery9 *iface)
         wined3d_mutex_unlock();
 
         IDirect3DDevice9Ex_Release(query->parent_device);
         wined3d_mutex_unlock();
 
         IDirect3DDevice9Ex_Release(query->parent_device);
-        HeapFree(GetProcessHeap(), 0, query);
+        heap_free(query);
     }
     return refcount;
 }
     }
     return refcount;
 }
index 75dfc0f..9cb3983 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9_vertexshader *impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_vertexshader, IDirect3DVertexShader9_iface);
 static inline struct d3d9_vertexshader *impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_vertexshader, IDirect3DVertexShader9_iface);
@@ -123,7 +126,7 @@ static const IDirect3DVertexShader9Vtbl d3d9_vertexshader_vtbl =
 
 static void STDMETHODCALLTYPE d3d9_vertexshader_wined3d_object_destroyed(void *parent)
 {
 
 static void STDMETHODCALLTYPE d3d9_vertexshader_wined3d_object_destroyed(void *parent)
 {
-    HeapFree(GetProcessHeap(), 0, parent);
+    heap_free(parent);
 }
 
 static const struct wined3d_parent_ops d3d9_vertexshader_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_vertexshader_wined3d_parent_ops =
@@ -277,7 +280,7 @@ static const IDirect3DPixelShader9Vtbl d3d9_pixelshader_vtbl =
 
 static void STDMETHODCALLTYPE d3d9_pixelshader_wined3d_object_destroyed(void *parent)
 {
 
 static void STDMETHODCALLTYPE d3d9_pixelshader_wined3d_object_destroyed(void *parent)
 {
-    HeapFree(GetProcessHeap(), 0, parent);
+    heap_free(parent);
 }
 
 static const struct wined3d_parent_ops d3d9_pixelshader_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_pixelshader_wined3d_parent_ops =
index 9355d9d..62b3bac 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9_stateblock *impl_from_IDirect3DStateBlock9(IDirect3DStateBlock9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_stateblock, IDirect3DStateBlock9_iface);
 static inline struct d3d9_stateblock *impl_from_IDirect3DStateBlock9(IDirect3DStateBlock9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_stateblock, IDirect3DStateBlock9_iface);
@@ -69,7 +72,7 @@ static ULONG WINAPI d3d9_stateblock_Release(IDirect3DStateBlock9 *iface)
         wined3d_mutex_unlock();
 
         IDirect3DDevice9Ex_Release(stateblock->parent_device);
         wined3d_mutex_unlock();
 
         IDirect3DDevice9Ex_Release(stateblock->parent_device);
-        HeapFree(GetProcessHeap(), 0, stateblock);
+        heap_free(stateblock);
     }
 
     return refcount;
     }
 
     return refcount;
index 47b5267..0605e71 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9_surface *impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_surface, IDirect3DSurface9_iface);
 static inline struct d3d9_surface *impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_surface, IDirect3DSurface9_iface);
@@ -220,8 +223,8 @@ static HRESULT WINAPI d3d9_surface_GetDesc(IDirect3DSurface9 *iface, D3DSURFACE_
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
     desc->Type = D3DRTYPE_SURFACE;
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
     desc->Type = D3DRTYPE_SURFACE;
-    desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-    desc->Pool = wined3d_desc.pool;
+    desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+    desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
     desc->MultiSampleType = wined3d_desc.multisample_type;
     desc->MultiSampleQuality = wined3d_desc.multisample_quality;
     desc->Width = wined3d_desc.width;
     desc->MultiSampleType = wined3d_desc.multisample_type;
     desc->MultiSampleQuality = wined3d_desc.multisample_quality;
     desc->Width = wined3d_desc.width;
@@ -246,7 +249,7 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface,
 
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx,
 
     wined3d_mutex_lock();
     hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx,
-            &map_desc, rect ? &box : NULL, flags);
+            &map_desc, rect ? &box : NULL, wined3dmapflags_from_d3dmapflags(flags));
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
@@ -267,6 +270,8 @@ static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface)
 
     wined3d_mutex_lock();
     hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx);
 
     wined3d_mutex_lock();
     hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx);
+    if (SUCCEEDED(hr) && surface->texture)
+        d3d9_texture_flag_auto_gen_mipmap(surface->texture);
     wined3d_mutex_unlock();
 
     if (hr == WINEDDERR_NOTLOCKED)
     wined3d_mutex_unlock();
 
     if (hr == WINEDDERR_NOTLOCKED)
@@ -304,6 +309,8 @@ static HRESULT WINAPI d3d9_surface_ReleaseDC(IDirect3DSurface9 *iface, HDC dc)
 
     wined3d_mutex_lock();
     hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, dc);
 
     wined3d_mutex_lock();
     hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, dc);
+    if (SUCCEEDED(hr) && surface->texture)
+        d3d9_texture_flag_auto_gen_mipmap(surface->texture);
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -337,7 +344,7 @@ static void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
 {
     struct d3d9_surface *surface = parent;
     d3d9_resource_cleanup(&surface->resource);
 {
     struct d3d9_surface *surface = parent;
     d3d9_resource_cleanup(&surface->resource);
-    HeapFree(GetProcessHeap(), 0, surface);
+    heap_free(surface);
 }
 
 static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops =
index 7b2dc7e..dbb3f45 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9Ex(IDirect3DSwapChain9Ex *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9Ex_iface);
 static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9Ex(IDirect3DSwapChain9Ex *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9Ex_iface);
@@ -134,7 +137,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
-            src_rect, dst_rect, dst_window_override, flags);
+            src_rect, dst_rect, dst_window_override, 0, flags);
     wined3d_mutex_unlock();
 
     return hr;
     wined3d_mutex_unlock();
 
     return hr;
@@ -332,7 +335,7 @@ static const struct IDirect3DSwapChain9ExVtbl d3d9_swapchain_vtbl =
 
 static void STDMETHODCALLTYPE d3d9_swapchain_wined3d_object_released(void *parent)
 {
 
 static void STDMETHODCALLTYPE d3d9_swapchain_wined3d_object_released(void *parent)
 {
-    HeapFree(GetProcessHeap(), 0, parent);
+    heap_free(parent);
 }
 
 static const struct wined3d_parent_ops d3d9_swapchain_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_swapchain_wined3d_parent_ops =
@@ -371,13 +374,13 @@ HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapcha
     struct d3d9_swapchain *object;
     HRESULT hr;
 
     struct d3d9_swapchain *object;
     HRESULT hr;
 
-    if (!(object = HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = swapchain_init(object, device, desc)))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = swapchain_init(object, device, desc)))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
index 16909d6..c97fa6b 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
 {
 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 
 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
 {
 }
 
 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 
 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
 {
 }
 
 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+}
+
+static void STDMETHODCALLTYPE srv_wined3d_object_destroyed(void *parent)
+{
+    struct d3d9_texture *texture = parent;
+
+    texture->wined3d_srv = NULL;
+}
+
+static const struct wined3d_parent_ops d3d9_srv_wined3d_parent_ops =
+{
+    srv_wined3d_object_destroyed,
+};
+
+/* wined3d critical section must be taken by the caller. */
+static struct wined3d_shader_resource_view *d3d9_texture_acquire_shader_resource_view(struct d3d9_texture *texture)
+{
+    struct wined3d_sub_resource_desc sr_desc;
+    struct wined3d_view_desc desc;
+    HRESULT hr;
+
+    if (texture->wined3d_srv)
+        return texture->wined3d_srv;
+
+    wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, 0, &sr_desc);
+    desc.format_id = sr_desc.format;
+    desc.flags = 0;
+    desc.u.texture.level_idx = 0;
+    desc.u.texture.level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
+    desc.u.texture.layer_idx = 0;
+    desc.u.texture.layer_count = sr_desc.usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1;
+    if (FAILED(hr = wined3d_shader_resource_view_create(&desc,
+            wined3d_texture_get_resource(texture->wined3d_texture), texture,
+            &d3d9_srv_wined3d_parent_ops, &texture->wined3d_srv)))
+    {
+        ERR("Failed to create shader resource view, hr %#x.\n", hr);
+        return NULL;
+    }
+
+    return texture->wined3d_srv;
+}
+
+static void d3d9_texture_cleanup(struct d3d9_texture *texture)
+{
+    IDirect3DDevice9Ex *parent_device = texture->parent_device;
+    struct d3d9_surface *surface;
+
+    wined3d_mutex_lock();
+    if (texture->wined3d_srv)
+        wined3d_shader_resource_view_decref(texture->wined3d_srv);
+    LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
+        wined3d_rendertarget_view_decref(surface->wined3d_rtv);
+    wined3d_texture_decref(texture->wined3d_texture);
+    wined3d_mutex_unlock();
+
+    /* Release the device last, as it may cause the device to be destroyed. */
+    IDirect3DDevice9Ex_Release(parent_device);
+}
+
+/* wined3d critical section must be taken by the caller. */
+void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture)
+{
+    if (!(texture->flags & D3D9_TEXTURE_MIPMAP_DIRTY))
+        return;
+    d3d9_texture_acquire_shader_resource_view(texture);
+    wined3d_shader_resource_view_generate_mipmaps(texture->wined3d_srv);
+    texture->flags &= ~D3D9_TEXTURE_MIPMAP_DIRTY;
+}
+
+void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture)
+{
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
+        texture->flags |= D3D9_TEXTURE_MIPMAP_DIRTY;
 }
 
 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
 }
 
 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
@@ -87,21 +163,7 @@ static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (!ref)
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (!ref)
-    {
-        IDirect3DDevice9Ex *parent_device = texture->parent_device;
-        struct d3d9_surface *surface;
-
-        wined3d_mutex_lock();
-        LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
-        {
-            wined3d_rendertarget_view_decref(surface->wined3d_rtv);
-        }
-        wined3d_texture_decref(texture->wined3d_texture);
-        wined3d_mutex_unlock();
-
-        /* Release the device last, as it may cause the device to be destroyed. */
-        IDirect3DDevice9Ex_Release(parent_device);
-    }
+        d3d9_texture_cleanup(texture);
     return ref;
 }
 
     return ref;
 }
 
@@ -232,6 +294,9 @@ static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
 
     TRACE("iface %p.\n", iface);
 
 
     TRACE("iface %p.\n", iface);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
+        return 1;
+
     wined3d_mutex_lock();
     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
     wined3d_mutex_unlock();
     wined3d_mutex_lock();
     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
     wined3d_mutex_unlock();
@@ -242,35 +307,44 @@ static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    HRESULT hr;
 
     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
 
 
     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
 
-    wined3d_mutex_lock();
-    hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
-            (enum wined3d_texture_filter_type)filter_type);
-    wined3d_mutex_unlock();
+    if (filter_type == D3DTEXF_NONE)
+    {
+        WARN("Invalid filter type D3DTEXF_NONE specified.\n");
+        return D3DERR_INVALIDCALL;
+    }
+    if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
+        WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
+    else if (filter_type != D3DTEXF_LINEAR)
+        FIXME("Unsupported filter type %u.\n", filter_type);
 
 
-    return hr;
+    texture->autogen_filter_type = filter_type;
+    return D3D_OK;
 }
 
 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
 }
 
 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    D3DTEXTUREFILTERTYPE ret;
 
     TRACE("iface %p.\n", iface);
 
 
     TRACE("iface %p.\n", iface);
 
-    wined3d_mutex_lock();
-    ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
-    wined3d_mutex_unlock();
+    if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
+        WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
 
 
-    return ret;
+    return texture->autogen_filter_type;
 }
 
 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
 {
 }
 
 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
 {
+    struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+
     TRACE("iface %p.\n", iface);
     TRACE("iface %p.\n", iface);
+
+    wined3d_mutex_lock();
+    d3d9_texture_gen_auto_mipmap(texture);
+    wined3d_mutex_unlock();
 }
 
 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
 }
 
 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
@@ -281,13 +355,19 @@ static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UIN
 
     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
 
 
     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
+    {
+        WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     wined3d_mutex_lock();
     if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_SURFACE;
     wined3d_mutex_lock();
     if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_SURFACE;
-        desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-        desc->Pool = wined3d_desc.pool;
+        desc->Usage = texture->usage;
+        desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
         desc->MultiSampleType = wined3d_desc.multisample_type;
         desc->MultiSampleQuality = wined3d_desc.multisample_quality;
         desc->Width = wined3d_desc.width;
         desc->MultiSampleType = wined3d_desc.multisample_type;
         desc->MultiSampleQuality = wined3d_desc.multisample_quality;
         desc->Width = wined3d_desc.width;
@@ -306,6 +386,12 @@ static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
 
     TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
 
 
     TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
+    {
+        WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     wined3d_mutex_lock();
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
     {
     wined3d_mutex_lock();
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
     {
@@ -330,6 +416,12 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
     TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
             iface, level, locked_rect, rect, flags);
 
     TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
             iface, level, locked_rect, rect, flags);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
+    {
+        WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     wined3d_mutex_lock();
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
         hr = D3DERR_INVALIDCALL;
     wined3d_mutex_lock();
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
         hr = D3DERR_INVALIDCALL;
@@ -348,6 +440,12 @@ static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT
 
     TRACE("iface %p, level %u.\n", iface, level);
 
 
     TRACE("iface %p, level %u.\n", iface, level);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
+    {
+        WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     wined3d_mutex_lock();
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
         hr = D3DERR_INVALIDCALL;
     wined3d_mutex_lock();
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
         hr = D3DERR_INVALIDCALL;
@@ -463,23 +561,7 @@ static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (!ref)
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (!ref)
-    {
-        IDirect3DDevice9Ex *parent_device = texture->parent_device;
-        struct d3d9_surface *surface;
-
-        TRACE("Releasing child %p.\n", texture->wined3d_texture);
-
-        wined3d_mutex_lock();
-        LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
-        {
-            wined3d_rendertarget_view_decref(surface->wined3d_rtv);
-        }
-        wined3d_texture_decref(texture->wined3d_texture);
-        wined3d_mutex_unlock();
-
-        /* Release the device last, as it may cause the device to be destroyed. */
-        IDirect3DDevice9Ex_Release(parent_device);
-    }
+        d3d9_texture_cleanup(texture);
     return ref;
 }
 
     return ref;
 }
 
@@ -610,6 +692,9 @@ static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface
 
     TRACE("iface %p.\n", iface);
 
 
     TRACE("iface %p.\n", iface);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
+        return 1;
+
     wined3d_mutex_lock();
     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
     wined3d_mutex_unlock();
     wined3d_mutex_lock();
     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
     wined3d_mutex_unlock();
@@ -621,35 +706,44 @@ static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTextur
         D3DTEXTUREFILTERTYPE filter_type)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
         D3DTEXTUREFILTERTYPE filter_type)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    HRESULT hr;
 
     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
 
 
     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
 
-    wined3d_mutex_lock();
-    hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
-            (enum wined3d_texture_filter_type)filter_type);
-    wined3d_mutex_unlock();
+    if (filter_type == D3DTEXF_NONE)
+    {
+        WARN("Invalid filter type D3DTEXF_NONE specified.\n");
+        return D3DERR_INVALIDCALL;
+    }
+    if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
+        WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
+    else if (filter_type != D3DTEXF_LINEAR)
+        FIXME("Unsupported filter type %u.\n", filter_type);
 
 
-    return hr;
+    texture->autogen_filter_type = filter_type;
+    return D3D_OK;
 }
 
 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
 }
 
 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    D3DTEXTUREFILTERTYPE ret;
 
     TRACE("iface %p.\n", iface);
 
 
     TRACE("iface %p.\n", iface);
 
-    wined3d_mutex_lock();
-    ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
-    wined3d_mutex_unlock();
+    if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
+        WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
 
 
-    return ret;
+    return texture->autogen_filter_type;
 }
 
 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
 {
 }
 
 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
 {
+    struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+
     TRACE("iface %p.\n", iface);
     TRACE("iface %p.\n", iface);
+
+    wined3d_mutex_lock();
+    d3d9_texture_gen_auto_mipmap(texture);
+    wined3d_mutex_unlock();
 }
 
 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
 }
 
 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
@@ -661,6 +755,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac
 
     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
 
 
     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
+    {
+        WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     wined3d_mutex_lock();
     level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
     if (level >= level_count)
     wined3d_mutex_lock();
     level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
     if (level >= level_count)
@@ -673,8 +773,8 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_SURFACE;
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_SURFACE;
-        desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-        desc->Pool = wined3d_desc.pool;
+        desc->Usage = texture->usage;
+        desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
         desc->MultiSampleType = wined3d_desc.multisample_type;
         desc->MultiSampleQuality = wined3d_desc.multisample_quality;
         desc->Width = wined3d_desc.width;
         desc->MultiSampleType = wined3d_desc.multisample_type;
         desc->MultiSampleQuality = wined3d_desc.multisample_quality;
         desc->Width = wined3d_desc.width;
@@ -695,6 +795,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9
 
     TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
 
 
     TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
+    {
+        WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     wined3d_mutex_lock();
     level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
     if (level >= level_count)
     wined3d_mutex_lock();
     level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
     if (level >= level_count)
@@ -729,6 +835,12 @@ static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
     TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
             iface, face, level, locked_rect, rect, flags);
 
     TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
             iface, face, level, locked_rect, rect, flags);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
+    {
+        WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     wined3d_mutex_lock();
     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
     wined3d_mutex_lock();
     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
@@ -750,6 +862,12 @@ static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
 
     TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
 
 
     TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
 
+    if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
+    {
+        WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     wined3d_mutex_lock();
     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
     wined3d_mutex_lock();
     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
     if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
@@ -861,16 +979,7 @@ static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (!ref)
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (!ref)
-    {
-        IDirect3DDevice9Ex *parent_device = texture->parent_device;
-
-        wined3d_mutex_lock();
-        wined3d_texture_decref(texture->wined3d_texture);
-        wined3d_mutex_unlock();
-
-        /* Release the device last, as it may cause the device to be destroyed. */
-        IDirect3DDevice9Ex_Release(parent_device);
-    }
+        d3d9_texture_cleanup(texture);
     return ref;
 }
 
     return ref;
 }
 
@@ -1011,31 +1120,16 @@ static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface
 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
         D3DTEXTUREFILTERTYPE filter_type)
 {
 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
         D3DTEXTUREFILTERTYPE filter_type)
 {
-    struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    HRESULT hr;
-
     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
 
     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
 
-    wined3d_mutex_lock();
-    hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
-            (enum wined3d_texture_filter_type)filter_type);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return D3DERR_INVALIDCALL;
 }
 
 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
 {
 }
 
 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
 {
-    struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    D3DTEXTUREFILTERTYPE filter_type;
-
     TRACE("iface %p.\n", iface);
 
     TRACE("iface %p.\n", iface);
 
-    wined3d_mutex_lock();
-    filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
-    wined3d_mutex_unlock();
-
-    return filter_type;
+    return D3DTEXF_NONE;
 }
 
 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
 }
 
 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
@@ -1056,8 +1150,8 @@ static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *ifac
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_VOLUME;
     {
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
         desc->Type = D3DRTYPE_VOLUME;
-        desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-        desc->Pool = wined3d_desc.pool;
+        desc->Usage = texture->usage;
+        desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
         desc->Width = wined3d_desc.width;
         desc->Height = wined3d_desc.height;
         desc->Depth = wined3d_desc.depth;
         desc->Width = wined3d_desc.width;
         desc->Height = wined3d_desc.height;
         desc->Depth = wined3d_desc.depth;
@@ -1192,7 +1286,7 @@ static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent
 {
     struct d3d9_texture *texture = parent;
     d3d9_resource_cleanup(&texture->resource);
 {
     struct d3d9_texture *texture = parent;
     d3d9_resource_cleanup(&texture->resource);
-    HeapFree(GetProcessHeap(), 0, texture);
+    heap_free(texture);
 }
 
 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
@@ -1210,14 +1304,18 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
     d3d9_resource_init(&texture->resource);
     list_init(&texture->rtv_list);
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
     d3d9_resource_init(&texture->resource);
     list_init(&texture->rtv_list);
+    texture->usage = usage;
 
     desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
 
     desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
-    desc.usage = usage & WINED3DUSAGE_MASK;
+    desc.usage = wined3dusage_from_d3dusage(usage);
     desc.usage |= WINED3DUSAGE_TEXTURE;
     desc.usage |= WINED3DUSAGE_TEXTURE;
-    desc.pool = pool;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     desc.width = width;
     desc.height = height;
     desc.depth = 1;
     desc.width = width;
     desc.height = height;
     desc.depth = 1;
@@ -1229,13 +1327,28 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
     if (is_gdi_compat_wined3dformat(desc.format))
         flags |= WINED3D_TEXTURE_CREATE_GET_DC;
 
     if (is_gdi_compat_wined3dformat(desc.format))
         flags |= WINED3D_TEXTURE_CREATE_GET_DC;
 
-    if (!levels)
+    if (usage & D3DUSAGE_AUTOGENMIPMAP)
     {
     {
-        if (usage & D3DUSAGE_AUTOGENMIPMAP)
-            levels = 1;
-        else
-            levels = wined3d_log2i(max(width, height)) + 1;
+        if (pool == D3DPOOL_SYSTEMMEM)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
+            return D3DERR_INVALIDCALL;
+        }
+        if (levels && levels != 1)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
+            return D3DERR_INVALIDCALL;
+        }
+        flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
+        texture->autogen_filter_type = D3DTEXF_LINEAR;
+        levels = 0;
+    }
+    else
+    {
+        texture->autogen_filter_type = D3DTEXF_NONE;
     }
     }
+    if (!levels)
+        levels = wined3d_log2i(max(width, height)) + 1;
 
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
 
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
@@ -1263,14 +1376,18 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
     d3d9_resource_init(&texture->resource);
     list_init(&texture->rtv_list);
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
     d3d9_resource_init(&texture->resource);
     list_init(&texture->rtv_list);
+    texture->usage = usage;
 
     desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
 
     desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
-    desc.usage = usage & WINED3DUSAGE_MASK;
+    desc.usage = wined3dusage_from_d3dusage(usage);
     desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
     desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
-    desc.pool = pool;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.access = wined3daccess_from_d3dpool(pool, usage)
+            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     desc.width = edge_length;
     desc.height = edge_length;
     desc.depth = 1;
     desc.width = edge_length;
     desc.height = edge_length;
     desc.depth = 1;
@@ -1282,13 +1399,28 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
     if (is_gdi_compat_wined3dformat(desc.format))
         flags |= WINED3D_TEXTURE_CREATE_GET_DC;
 
     if (is_gdi_compat_wined3dformat(desc.format))
         flags |= WINED3D_TEXTURE_CREATE_GET_DC;
 
-    if (!levels)
+    if (usage & D3DUSAGE_AUTOGENMIPMAP)
+    {
+        if (pool == D3DPOOL_SYSTEMMEM)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
+            return D3DERR_INVALIDCALL;
+        }
+        if (levels && levels != 1)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
+            return D3DERR_INVALIDCALL;
+        }
+        flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
+        texture->autogen_filter_type = D3DTEXF_LINEAR;
+        levels = 0;
+    }
+    else
     {
     {
-        if (usage & D3DUSAGE_AUTOGENMIPMAP)
-            levels = 1;
-        else
-            levels = wined3d_log2i(edge_length) + 1;
+        texture->autogen_filter_type = D3DTEXF_NONE;
     }
     }
+    if (!levels)
+        levels = wined3d_log2i(edge_length) + 1;
 
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
 
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
@@ -1315,26 +1447,29 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
     d3d9_resource_init(&texture->resource);
     list_init(&texture->rtv_list);
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
     d3d9_resource_init(&texture->resource);
     list_init(&texture->rtv_list);
+    texture->usage = usage;
 
     desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
 
     desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
-    desc.usage = usage & WINED3DUSAGE_MASK;
+    desc.usage = wined3dusage_from_d3dusage(usage);
     desc.usage |= WINED3DUSAGE_TEXTURE;
     desc.usage |= WINED3DUSAGE_TEXTURE;
-    desc.pool = pool;
+    if (pool == D3DPOOL_SCRATCH)
+        desc.usage |= WINED3DUSAGE_SCRATCH;
+    desc.access = wined3daccess_from_d3dpool(pool, usage);
     desc.width = width;
     desc.height = height;
     desc.depth = depth;
     desc.size = 0;
 
     desc.width = width;
     desc.height = height;
     desc.depth = depth;
     desc.size = 0;
 
-    if (!levels)
+    if (usage & D3DUSAGE_AUTOGENMIPMAP)
     {
     {
-        if (usage & D3DUSAGE_AUTOGENMIPMAP)
-            levels = 1;
-        else
-            levels = wined3d_log2i(max(max(width, height), depth)) + 1;
+        WARN("D3DUSAGE_AUTOGENMIPMAP volume texture is not supported, returning D3DERR_INVALIDCALL.\n");
+        return D3DERR_INVALIDCALL;
     }
     }
+    if (!levels)
+        levels = wined3d_log2i(max(max(width, height), depth)) + 1;
 
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
 
     wined3d_mutex_lock();
     hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
index e9248be..5075309 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static const struct
 {
     enum wined3d_format_id format;
 static const struct
 {
     enum wined3d_format_id format;
@@ -86,8 +89,8 @@ HRESULT vdecl_convert_fvf(
            has_psize + has_diffuse + has_specular + num_textures + 1;
 
     /* convert the declaration */
            has_psize + has_diffuse + has_specular + num_textures + 1;
 
     /* convert the declaration */
-    elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(D3DVERTEXELEMENT9));
-    if (!elements) return D3DERR_OUTOFVIDEOMEMORY;
+    if (!(elements = heap_alloc(size * sizeof(*elements))))
+        return D3DERR_OUTOFVIDEOMEMORY;
 
     elements[size-1] = end_element;
     idx = 0;
 
     elements[size-1] = end_element;
     idx = 0;
@@ -307,8 +310,8 @@ struct d3d9_vertex_declaration *unsafe_impl_from_IDirect3DVertexDeclaration9(IDi
 static void STDMETHODCALLTYPE d3d9_vertexdeclaration_wined3d_object_destroyed(void *parent)
 {
     struct d3d9_vertex_declaration *declaration = parent;
 static void STDMETHODCALLTYPE d3d9_vertexdeclaration_wined3d_object_destroyed(void *parent)
 {
     struct d3d9_vertex_declaration *declaration = parent;
-    HeapFree(GetProcessHeap(), 0, declaration->elements);
-    HeapFree(GetProcessHeap(), 0, declaration);
+    heap_free(declaration->elements);
+    heap_free(declaration);
 }
 
 static const struct wined3d_parent_ops d3d9_vertexdeclaration_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_vertexdeclaration_wined3d_parent_ops =
@@ -333,18 +336,18 @@ static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9 *d3d9_elem
     /* Skip the END element */
     --count;
 
     /* Skip the END element */
     --count;
 
-    *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, count * sizeof(**wined3d_elements));
-    if (!*wined3d_elements) {
+    if (!(*wined3d_elements = heap_alloc(count * sizeof(**wined3d_elements))))
+    {
         FIXME("Memory allocation failed\n");
         return D3DERR_OUTOFVIDEOMEMORY;
     }
 
     for (i = 0; i < count; ++i)
     {
         FIXME("Memory allocation failed\n");
         return D3DERR_OUTOFVIDEOMEMORY;
     }
 
     for (i = 0; i < count; ++i)
     {
-        if (d3d9_elements[i].Type >= (sizeof(d3d_dtype_lookup) / sizeof(*d3d_dtype_lookup)))
+        if (d3d9_elements[i].Type >= ARRAY_SIZE(d3d_dtype_lookup))
         {
             WARN("Invalid element type %#x.\n", d3d9_elements[i].Type);
         {
             WARN("Invalid element type %#x.\n", d3d9_elements[i].Type);
-            HeapFree(GetProcessHeap(), 0, *wined3d_elements);
+            heap_free(*wined3d_elements);
             return E_FAIL;
         }
         (*wined3d_elements)[i].format = d3d_dtype_lookup[d3d9_elements[i].Type].format;
             return E_FAIL;
         }
         (*wined3d_elements)[i].format = d3d_dtype_lookup[d3d9_elements[i].Type].format;
@@ -382,10 +385,9 @@ static HRESULT vertexdeclaration_init(struct d3d9_vertex_declaration *declaratio
     declaration->refcount = 1;
 
     element_count = wined3d_element_count + 1;
     declaration->refcount = 1;
 
     element_count = wined3d_element_count + 1;
-    declaration->elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(*declaration->elements));
-    if (!declaration->elements)
+    if (!(declaration->elements = heap_alloc(element_count * sizeof(*declaration->elements))))
     {
     {
-        HeapFree(GetProcessHeap(), 0, wined3d_elements);
+        heap_free(wined3d_elements);
         ERR("Failed to allocate vertex declaration elements memory.\n");
         return D3DERR_OUTOFVIDEOMEMORY;
     }
         ERR("Failed to allocate vertex declaration elements memory.\n");
         return D3DERR_OUTOFVIDEOMEMORY;
     }
@@ -396,10 +398,10 @@ static HRESULT vertexdeclaration_init(struct d3d9_vertex_declaration *declaratio
     hr = wined3d_vertex_declaration_create(device->wined3d_device, wined3d_elements, wined3d_element_count,
             declaration, &d3d9_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_declaration);
     wined3d_mutex_unlock();
     hr = wined3d_vertex_declaration_create(device->wined3d_device, wined3d_elements, wined3d_element_count,
             declaration, &d3d9_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_declaration);
     wined3d_mutex_unlock();
-    HeapFree(GetProcessHeap(), 0, wined3d_elements);
+    heap_free(wined3d_elements);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        HeapFree(GetProcessHeap(), 0, declaration->elements);
+        heap_free(declaration->elements);
         WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr);
         return hr;
     }
         WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr);
         return hr;
     }
@@ -416,15 +418,14 @@ HRESULT d3d9_vertex_declaration_create(struct d3d9_device *device,
     struct d3d9_vertex_declaration *object;
     HRESULT hr;
 
     struct d3d9_vertex_declaration *object;
     HRESULT hr;
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = vertexdeclaration_init(object, device, elements);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = vertexdeclaration_init(object, device, elements);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
index 5c6a068..f4c43bc 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include "d3d9_private.h"
 
 #include "d3d9_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
 static inline struct d3d9_volume *impl_from_IDirect3DVolume9(IDirect3DVolume9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_volume, IDirect3DVolume9_iface);
 static inline struct d3d9_volume *impl_from_IDirect3DVolume9(IDirect3DVolume9 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d9_volume, IDirect3DVolume9_iface);
@@ -123,8 +126,8 @@ static HRESULT WINAPI d3d9_volume_GetDesc(IDirect3DVolume9 *iface, D3DVOLUME_DES
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
     desc->Type = D3DRTYPE_VOLUME;
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
     desc->Type = D3DRTYPE_VOLUME;
-    desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
-    desc->Pool = wined3d_desc.pool;
+    desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage);
+    desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
     desc->Width = wined3d_desc.width;
     desc->Height = wined3d_desc.height;
     desc->Depth = wined3d_desc.depth;
     desc->Width = wined3d_desc.width;
     desc->Height = wined3d_desc.height;
     desc->Depth = wined3d_desc.depth;
@@ -144,7 +147,8 @@ static HRESULT WINAPI d3d9_volume_LockBox(IDirect3DVolume9 *iface,
 
     wined3d_mutex_lock();
     if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture),
 
     wined3d_mutex_lock();
     if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture),
-            volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box, flags)))
+            volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box,
+            wined3dmapflags_from_d3dmapflags(flags))))
         map_desc.data = NULL;
     wined3d_mutex_unlock();
 
         map_desc.data = NULL;
     wined3d_mutex_unlock();
 
@@ -152,6 +156,8 @@ static HRESULT WINAPI d3d9_volume_LockBox(IDirect3DVolume9 *iface,
     locked_box->SlicePitch = map_desc.slice_pitch;
     locked_box->pBits = map_desc.data;
 
     locked_box->SlicePitch = map_desc.slice_pitch;
     locked_box->pBits = map_desc.data;
 
+    if (hr == E_INVALIDARG)
+        return D3DERR_INVALIDCALL;
     return hr;
 }
 
     return hr;
 }
 
@@ -192,7 +198,7 @@ static void STDMETHODCALLTYPE volume_wined3d_object_destroyed(void *parent)
 {
     struct d3d9_volume *volume = parent;
     d3d9_resource_cleanup(&volume->resource);
 {
     struct d3d9_volume *volume = parent;
     d3d9_resource_cleanup(&volume->resource);
-    HeapFree(GetProcessHeap(), 0, volume);
+    heap_free(volume);
 }
 
 static const struct wined3d_parent_ops d3d9_volume_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops d3d9_volume_wined3d_parent_ops =
index ed7801e..6141d63 100644 (file)
@@ -20,7 +20,7 @@ list(APPEND SOURCE
     utils.c
     vertexbuffer.c
     viewport.c
     utils.c
     vertexbuffer.c
     viewport.c
-    ddraw_private.h
+    precomp.h
     ${CMAKE_CURRENT_BINARY_DIR}/ddraw_stubs.c)
 
 if(MSVC)
     ${CMAKE_CURRENT_BINARY_DIR}/ddraw_stubs.c)
 
 if(MSVC)
@@ -38,5 +38,5 @@ set_module_type(ddraw win32dll)
 target_link_libraries(ddraw wine uuid dxguid ${PSEH_LIB})
 add_importlibs(ddraw advapi32 gdi32 user32 d3dwine msvcrt kernel32 ntdll)
 add_dependencies(ddraw wineheaders)
 target_link_libraries(ddraw wine uuid dxguid ${PSEH_LIB})
 add_importlibs(ddraw advapi32 gdi32 user32 d3dwine msvcrt kernel32 ntdll)
 add_dependencies(ddraw wineheaders)
-add_pch(ddraw ddraw_private.h SOURCE)
+add_pch(ddraw precomp.h SOURCE)
 add_cd_file(TARGET ddraw DESTINATION reactos/system32 FOR all)
 add_cd_file(TARGET ddraw DESTINATION reactos/system32 FOR all)
index f1fadd4..01cac40 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 static inline struct ddraw_clipper *impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
 {
     return CONTAINING_RECORD(iface, struct ddraw_clipper, IDirectDrawClipper_iface);
 static inline struct ddraw_clipper *impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
 {
     return CONTAINING_RECORD(iface, struct ddraw_clipper, IDirectDrawClipper_iface);
@@ -67,7 +72,7 @@ static ULONG WINAPI ddraw_clipper_Release(IDirectDrawClipper *iface)
     {
         if (clipper->region)
             DeleteObject(clipper->region);
     {
         if (clipper->region)
             DeleteObject(clipper->region);
-        HeapFree(GetProcessHeap(), 0, clipper);
+        heap_free(clipper);
     }
 
     return refcount;
     }
 
     return refcount;
index 2ab9edd..e5205c0 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
-#include <wine/exception.h>
+#include "wine/exception.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
 static const struct ddraw *exclusive_ddraw;
 static HWND exclusive_window;
 
 static const struct ddraw *exclusive_ddraw;
 static HWND exclusive_window;
@@ -45,6 +50,7 @@ static struct enum_device_entry
     char interface_name[100];
     char device_name[100];
     const GUID *device_guid;
     char interface_name[100];
     char device_name[100];
     const GUID *device_guid;
+    DWORD remove_caps;
 } device_list7[] =
 {
     /* T&L HAL device */
 } device_list7[] =
 {
     /* T&L HAL device */
@@ -52,6 +58,7 @@ static struct enum_device_entry
         "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D",
         "Wine D3D7 T&L HAL",
         &IID_IDirect3DTnLHalDevice,
         "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D",
         "Wine D3D7 T&L HAL",
         &IID_IDirect3DTnLHalDevice,
+        0,
     },
 
     /* HAL device */
     },
 
     /* HAL device */
@@ -59,6 +66,7 @@ static struct enum_device_entry
         "WINE Direct3D7 Hardware acceleration using WineD3D",
         "Direct3D HAL",
         &IID_IDirect3DHALDevice,
         "WINE Direct3D7 Hardware acceleration using WineD3D",
         "Direct3D HAL",
         &IID_IDirect3DHALDevice,
+        0,
     },
 
     /* RGB device */
     },
 
     /* RGB device */
@@ -66,6 +74,7 @@ static struct enum_device_entry
         "WINE Direct3D7 RGB Software Emulation using WineD3D",
         "Wine D3D7 RGB",
         &IID_IDirect3DRGBDevice,
         "WINE Direct3D7 RGB Software Emulation using WineD3D",
         "Wine D3D7 RGB",
         &IID_IDirect3DRGBDevice,
+        D3DDEVCAPS_HWTRANSFORMANDLIGHT,
     },
 };
 
     },
 };
 
@@ -371,7 +380,7 @@ static void ddraw_destroy_swapchain(struct ddraw *ddraw)
         {
             wined3d_vertex_declaration_decref(ddraw->decls[i].decl);
         }
         {
             wined3d_vertex_declaration_decref(ddraw->decls[i].decl);
         }
-        HeapFree(GetProcessHeap(), 0, ddraw->decls);
+        heap_free(ddraw->decls);
         ddraw->numConvertedDecls = 0;
 
         if (FAILED(wined3d_device_uninit_3d(ddraw->wined3d_device)))
         ddraw->numConvertedDecls = 0;
 
         if (FAILED(wined3d_device_uninit_3d(ddraw->wined3d_device)))
@@ -437,7 +446,7 @@ static void ddraw_destroy(struct ddraw *This)
         This->d3ddevice->ddraw = NULL;
 
     /* Now free the object */
         This->d3ddevice->ddraw = NULL;
 
     /* Now free the object */
-    HeapFree(GetProcessHeap(), 0, This);
+    heap_free(This);
 }
 
 /*****************************************************************************
 }
 
 /*****************************************************************************
@@ -595,8 +604,7 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw,
     }
 
     ddraw->declArraySize = 2;
     }
 
     ddraw->declArraySize = 2;
-    ddraw->decls = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ddraw->decls) * ddraw->declArraySize);
-    if (!ddraw->decls)
+    if (!(ddraw->decls = heap_alloc_zero(ddraw->declArraySize * sizeof(*ddraw->decls))))
     {
         ERR("Error allocating an array for the converted vertex decls.\n");
         ddraw->declArraySize = 0;
     {
         ERR("Error allocating an array for the converted vertex decls.\n");
         ddraw->declArraySize = 0;
@@ -625,6 +633,7 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win
     swapchain_desc.backbuffer_width = mode.width;
     swapchain_desc.backbuffer_height = mode.height;
     swapchain_desc.backbuffer_format = mode.format_id;
     swapchain_desc.backbuffer_width = mode.width;
     swapchain_desc.backbuffer_height = mode.height;
     swapchain_desc.backbuffer_format = mode.format_id;
+    swapchain_desc.backbuffer_usage = WINED3DUSAGE_RENDERTARGET;
     swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
     swapchain_desc.device_window = window;
     swapchain_desc.windowed = windowed;
     swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
     swapchain_desc.device_window = window;
     swapchain_desc.windowed = windowed;
@@ -1430,6 +1439,28 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps)
     return DD_OK;
 }
 
     return DD_OK;
 }
 
+HRESULT CALLBACK enum_zbuffer(DDPIXELFORMAT *format, void *ctx)
+{
+    DDCAPS *caps = ctx;
+
+    switch (format->u1.dwZBufferBitDepth)
+    {
+        case 8:
+            caps->dwZBufferBitDepths |= DDBD_8;
+            break;
+        case 16:
+            caps->dwZBufferBitDepths |= DDBD_16;
+            break;
+        case 24:
+            caps->dwZBufferBitDepths |= DDBD_24;
+            break;
+        case 32:
+            caps->dwZBufferBitDepths |= DDBD_32;
+            break;
+    }
+    return D3DENUMRET_OK;
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetCaps
  *
 /*****************************************************************************
  * IDirectDraw7::GetCaps
  *
@@ -1510,6 +1541,10 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD
     caps.dwCaps |= DDCAPS_ALIGNSTRIDE;
     caps.dwAlignStrideAlign = DDRAW_STRIDE_ALIGNMENT;
 
     caps.dwCaps |= DDCAPS_ALIGNSTRIDE;
     caps.dwAlignStrideAlign = DDRAW_STRIDE_ALIGNMENT;
 
+    caps.ddsOldCaps.dwCaps = caps.ddsCaps.dwCaps;
+
+    IDirect3D7_EnumZBufferFormats(&ddraw->IDirect3D7_iface, &IID_IDirect3DHALDevice, enum_zbuffer, &caps);
+
     if(DriverCaps)
     {
         DD_STRUCT_COPY_BYSIZE(DriverCaps, &caps);
     if(DriverCaps)
     {
         DD_STRUCT_COPY_BYSIZE(DriverCaps, &caps);
@@ -1733,7 +1768,7 @@ static HRESULT WINAPI ddraw7_GetFourCCCodes(IDirectDraw7 *iface, DWORD *NumCodes
 
     outsize = NumCodes && Codes ? *NumCodes : 0;
 
 
     outsize = NumCodes && Codes ? *NumCodes : 0;
 
-    for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); ++i)
+    for (i = 0; i < ARRAY_SIZE(formats); ++i)
     {
         if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL,
                 mode.format_id, 0, WINED3D_RTYPE_TEXTURE_2D, formats[i])))
     {
         if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL,
                 mode.format_id, 0, WINED3D_RTYPE_TEXTURE_2D, formats[i])))
@@ -2057,7 +2092,14 @@ static HRESULT WINAPI d3d1_Initialize(IDirect3D *iface, REFIID riid)
  *****************************************************************************/
 static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface)
 {
  *****************************************************************************/
 static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface)
 {
-    FIXME("iface %p stub!\n", iface);
+    struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
+
+    TRACE("iface %p.\n", iface);
+
+    ddraw->flags |= DDRAW_GDI_FLIP;
+
+    if (ddraw->primary)
+        ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE);
 
     return DD_OK;
 }
 
     return DD_OK;
 }
@@ -2384,13 +2426,13 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
     if (!cb)
         return DDERR_INVALIDPARAMS;
 
     if (!cb)
         return DDERR_INVALIDPARAMS;
 
-    enum_modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*enum_modes) * enum_mode_array_size);
-    if (!enum_modes) return DDERR_OUTOFMEMORY;
+    if (!(enum_modes = heap_alloc(enum_mode_array_size * sizeof(*enum_modes))))
+        return DDERR_OUTOFMEMORY;
 
     wined3d_mutex_lock();
 
     pixelformat.dwSize = sizeof(pixelformat);
 
     wined3d_mutex_lock();
 
     pixelformat.dwSize = sizeof(pixelformat);
-    for(fmt = 0; fmt < (sizeof(checkFormatList) / sizeof(checkFormatList[0])); fmt++)
+    for(fmt = 0; fmt < ARRAY_SIZE(checkFormatList); fmt++)
     {
         modenum = 0;
         while (wined3d_enum_adapter_modes(ddraw->wined3d, WINED3DADAPTER_DEFAULT, checkFormatList[fmt],
     {
         modenum = 0;
         while (wined3d_enum_adapter_modes(ddraw->wined3d, WINED3DADAPTER_DEFAULT, checkFormatList[fmt],
@@ -2449,7 +2491,7 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
             if(cb(&callback_sd, Context) == DDENUMRET_CANCEL)
             {
                 TRACE("Application asked to terminate the enumeration\n");
             if(cb(&callback_sd, Context) == DDENUMRET_CANCEL)
             {
                 TRACE("Application asked to terminate the enumeration\n");
-                HeapFree(GetProcessHeap(), 0, enum_modes);
+                heap_free(enum_modes);
                 wined3d_mutex_unlock();
                 return DD_OK;
             }
                 wined3d_mutex_unlock();
                 return DD_OK;
             }
@@ -2459,11 +2501,9 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
                 struct wined3d_display_mode *new_enum_modes;
 
                 enum_mode_array_size *= 2;
                 struct wined3d_display_mode *new_enum_modes;
 
                 enum_mode_array_size *= 2;
-                new_enum_modes = HeapReAlloc(GetProcessHeap(), 0, enum_modes,
-                                             sizeof(*new_enum_modes) * enum_mode_array_size);
-                if (!new_enum_modes)
+                if (!(new_enum_modes = heap_realloc(enum_modes, enum_mode_array_size * sizeof(*new_enum_modes))))
                 {
                 {
-                    HeapFree(GetProcessHeap(), 0, enum_modes);
+                    heap_free(enum_modes);
                     wined3d_mutex_unlock();
                     return DDERR_OUTOFMEMORY;
                 }
                     wined3d_mutex_unlock();
                     return DDERR_OUTOFMEMORY;
                 }
@@ -2475,7 +2515,7 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
     }
 
     TRACE("End of enumeration\n");
     }
 
     TRACE("End of enumeration\n");
-    HeapFree(GetProcessHeap(), 0, enum_modes);
+    heap_free(enum_modes);
     wined3d_mutex_unlock();
 
     return DD_OK;
     wined3d_mutex_unlock();
 
     return DD_OK;
@@ -3108,7 +3148,7 @@ static BOOL ddraw_match_surface_desc(const DDSURFACEDESC2 *requested, const DDSU
     if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags)
         return FALSE;
 
     if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags)
         return FALSE;
 
-    for (i=0; i < sizeof(compare)/sizeof(compare[0]); i++)
+    for (i=0; i < ARRAY_SIZE(compare); i++)
     {
         if (requested->dwFlags & compare[i].flag
             && memcmp((const char *)provided + compare[i].offset,
     {
         if (requested->dwFlags & compare[i].flag
             && memcmp((const char *)provided + compare[i].offset,
@@ -3189,46 +3229,97 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags,
 {
     struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
     struct ddraw_surface *surf;
 {
     struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
     struct ddraw_surface *surf;
-    BOOL all, nomatch;
-    DDSURFACEDESC2 desc;
-    struct list *entry, *entry2;
+    DWORD match_flags = Flags & (DDENUMSURFACES_ALL | DDENUMSURFACES_NOMATCH | DDENUMSURFACES_MATCH);
 
     TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
             iface, Flags, DDSD, Context, Callback);
 
 
     TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
             iface, Flags, DDSD, Context, Callback);
 
-    all = Flags & DDENUMSURFACES_ALL;
-    nomatch = Flags & DDENUMSURFACES_NOMATCH;
-
     if (!Callback)
         return DDERR_INVALIDPARAMS;
 
     if (!Callback)
         return DDERR_INVALIDPARAMS;
 
-    wined3d_mutex_lock();
-
-    /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */
-    LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list)
+    if (Flags & DDENUMSURFACES_CANBECREATED)
     {
     {
-        surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry);
+         IDirectDrawSurface7 *surface;
+         DDSURFACEDESC2 testdesc;
+         HRESULT hr;
+
+        if (match_flags != DDENUMSURFACES_MATCH)
+            return DDERR_INVALIDPARAMS;
 
 
-        if (!surf->iface_count)
+        if (!DDSD)
+            return DDERR_INVALIDPARAMS;
+
+        memcpy(&testdesc, DDSD, sizeof(testdesc));
+        if (!(testdesc.dwFlags & DDSD_WIDTH))
         {
         {
-            WARN("Not enumerating surface %p because it doesn't have any references.\n", surf);
-            continue;
+            testdesc.dwFlags |= DDSD_WIDTH;
+            testdesc.dwWidth = 512;
         }
         }
+        if (!(testdesc.dwFlags & DDSD_HEIGHT))
+        {
+            testdesc.dwFlags |= DDSD_HEIGHT;
+            testdesc.dwHeight = 512;
+        }
+
+        hr = IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL);
+        if (SUCCEEDED(hr))
+        {
+            surf = unsafe_impl_from_IDirectDrawSurface7(surface);
+            Callback(NULL, &surf->surface_desc, Context);
+            IDirectDrawSurface7_Release(surface);
+        }
+        else
+            ERR("Failed to create surface, hr %#x.\n", hr);
+    }
+    else if (Flags & DDENUMSURFACES_DOESEXIST)
+    {
+        BOOL all, nomatch;
+        DDSURFACEDESC2 desc;
+        struct list *entry, *entry2;
+
+        /* a combination of match flags is not allowed */
+        if (match_flags != 0 &&
+                match_flags != DDENUMSURFACES_ALL &&
+                match_flags != DDENUMSURFACES_MATCH &&
+                match_flags != DDENUMSURFACES_NOMATCH)
+            return DDERR_INVALIDPARAMS;
+
+        all = (Flags & DDENUMSURFACES_ALL) != 0;
+        nomatch = (Flags & DDENUMSURFACES_NOMATCH) != 0;
+
+        if (!all && !DDSD)
+            return DDERR_INVALIDPARAMS;
+
+        wined3d_mutex_lock();
 
 
-        if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc)))
+        /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */
+        LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list)
         {
         {
-            TRACE("Enumerating surface %p.\n", surf);
-            desc = surf->surface_desc;
-            IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface);
-            if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_OK)
+            surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry);
+
+            if (!surf->iface_count)
             {
             {
-                wined3d_mutex_unlock();
-                return DD_OK;
+                WARN("Not enumerating surface %p because it doesn't have any references.\n", surf);
+                continue;
+            }
+
+            if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc)))
+            {
+                TRACE("Enumerating surface %p.\n", surf);
+                desc = surf->surface_desc;
+                IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface);
+                if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_OK)
+                {
+                    wined3d_mutex_unlock();
+                    return DD_OK;
+                }
             }
         }
             }
         }
-    }
 
 
-    wined3d_mutex_unlock();
+        wined3d_mutex_unlock();
+    }
+    else
+        return DDERR_INVALIDPARAMS;
 
     return DD_OK;
 }
 
     return DD_OK;
 }
@@ -3313,8 +3404,7 @@ HRESULT WINAPI DirectDrawCreateClipper(DWORD flags, IDirectDrawClipper **clipper
 
     wined3d_mutex_lock();
 
 
     wined3d_mutex_lock();
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         wined3d_mutex_unlock();
         return E_OUTOFMEMORY;
     {
         wined3d_mutex_unlock();
         return E_OUTOFMEMORY;
@@ -3324,7 +3414,7 @@ HRESULT WINAPI DirectDrawCreateClipper(DWORD flags, IDirectDrawClipper **clipper
     if (FAILED(hr))
     {
         WARN("Failed to initialize clipper, hr %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize clipper, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         wined3d_mutex_unlock();
         return hr;
     }
         wined3d_mutex_unlock();
         return hr;
     }
@@ -3424,8 +3514,7 @@ static HRESULT WINAPI ddraw7_CreatePalette(IDirectDraw7 *iface, DWORD Flags,
         return DDERR_NOCOOPERATIVELEVELSET;
     }
 
         return DDERR_NOCOOPERATIVELEVELSET;
     }
 
-    object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc(sizeof(*object))))
     {
         ERR("Out of memory when allocating memory for a palette implementation\n");
         wined3d_mutex_unlock();
     {
         ERR("Out of memory when allocating memory for a palette implementation\n");
         wined3d_mutex_unlock();
@@ -3436,7 +3525,7 @@ static HRESULT WINAPI ddraw7_CreatePalette(IDirectDraw7 *iface, DWORD Flags,
     if (FAILED(hr))
     {
         WARN("Failed to initialize palette, hr %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize palette, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         wined3d_mutex_unlock();
         return hr;
     }
         wined3d_mutex_unlock();
         return hr;
     }
@@ -3626,6 +3715,7 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA
 {
     struct ddraw *ddraw = impl_from_IDirect3D7(iface);
     D3DDEVICEDESC7 device_desc7;
 {
     struct ddraw *ddraw = impl_from_IDirect3D7(iface);
     D3DDEVICEDESC7 device_desc7;
+    DWORD dev_caps;
     HRESULT hr;
     size_t i;
 
     HRESULT hr;
     size_t i;
 
@@ -3642,11 +3732,15 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA
         return hr;
     }
 
         return hr;
     }
 
-    for (i = 0; i < sizeof(device_list7)/sizeof(device_list7[0]); i++)
+    dev_caps = device_desc7.dwDevCaps;
+
+    for (i = 0; i < ARRAY_SIZE(device_list7); i++)
     {
         HRESULT ret;
 
         device_desc7.deviceGUID = *device_list7[i].device_guid;
     {
         HRESULT ret;
 
         device_desc7.deviceGUID = *device_list7[i].device_guid;
+        device_desc7.dwDevCaps  = dev_caps & ~device_list7[i].remove_caps;
+
         ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context);
         if (ret != DDENUMRET_OK)
         {
         ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context);
         if (ret != DDENUMRET_OK)
         {
@@ -3832,10 +3926,10 @@ static HRESULT WINAPI d3d3_CreateLight(IDirect3D3 *iface, IDirect3DLight **light
 
     TRACE("iface %p, light %p, outer_unknown %p.\n", iface, light, outer_unknown);
 
 
     TRACE("iface %p, light %p, outer_unknown %p.\n", iface, light, outer_unknown);
 
-    if (outer_unknown) return CLASS_E_NOAGGREGATION;
+    if (outer_unknown)
+        return CLASS_E_NOAGGREGATION;
 
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         ERR("Failed to allocate light memory.\n");
         return DDERR_OUTOFMEMORY;
     {
         ERR("Failed to allocate light memory.\n");
         return DDERR_OUTOFMEMORY;
@@ -3982,8 +4076,7 @@ static HRESULT WINAPI d3d3_CreateViewport(IDirect3D3 *iface, IDirect3DViewport3
 
     if (outer_unknown) return CLASS_E_NOAGGREGATION;
 
 
     if (outer_unknown) return CLASS_E_NOAGGREGATION;
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         ERR("Failed to allocate viewport memory.\n");
         return DDERR_OUTOFMEMORY;
     {
         ERR("Failed to allocate viewport memory.\n");
         return DDERR_OUTOFMEMORY;
@@ -4044,8 +4137,8 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd
 
     if (!fds || !fdr) return DDERR_INVALIDPARAMS;
 
 
     if (!fds || !fdr) return DDERR_INVALIDPARAMS;
 
-    if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH)
-            || fdr->dwSize != sizeof(D3DFINDDEVICERESULT))
+    if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH) || (fdr->dwSize != sizeof(D3DFINDDEVICERESULT1) &&
+        fdr->dwSize != sizeof(D3DFINDDEVICERESULT2) && fdr->dwSize != sizeof(D3DFINDDEVICERESULT)))
         return DDERR_INVALIDPARAMS;
 
     if ((fds->dwFlags & D3DFDS_COLORMODEL)
         return DDERR_INVALIDPARAMS;
 
     if ((fds->dwFlags & D3DFDS_COLORMODEL)
@@ -4074,8 +4167,24 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd
     /* Now return our own GUID */
     ddraw_d3dcaps1_from_7(&desc1, &desc7);
     fdr->guid = IID_D3DDEVICE_WineD3D;
     /* Now return our own GUID */
     ddraw_d3dcaps1_from_7(&desc1, &desc7);
     fdr->guid = IID_D3DDEVICE_WineD3D;
-    fdr->ddHwDesc = desc1;
-    fdr->ddSwDesc = desc1;
+
+    if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT1))
+    {
+        D3DFINDDEVICERESULT1 *fdr1 = (D3DFINDDEVICERESULT1 *)fdr;
+        memcpy(&fdr1->ddHwDesc, &desc1, sizeof(fdr1->ddHwDesc));
+        memcpy(&fdr1->ddSwDesc, &desc1, sizeof(fdr1->ddSwDesc));
+    }
+    else if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT2))
+    {
+        D3DFINDDEVICERESULT2 *fdr2 = (D3DFINDDEVICERESULT2 *)fdr;
+        memcpy(&fdr2->ddHwDesc, &desc1, sizeof(fdr2->ddHwDesc));
+        memcpy(&fdr2->ddSwDesc, &desc1, sizeof(fdr2->ddSwDesc));
+    }
+    else
+    {
+        fdr->ddHwDesc = desc1;
+        fdr->ddSwDesc = desc1;
+    }
 
     TRACE("Returning Wine's wined3d device with (undumped) capabilities.\n");
 
 
     TRACE("Returning Wine's wined3d device with (undumped) capabilities.\n");
 
@@ -4132,7 +4241,7 @@ static HRESULT WINAPI d3d7_CreateDevice(IDirect3D7 *iface, REFCLSID riid,
     TRACE("iface %p, riid %s, surface %p, device %p.\n", iface, debugstr_guid(riid), surface, device);
 
     wined3d_mutex_lock();
     TRACE("iface %p, riid %s, surface %p, device %p.\n", iface, debugstr_guid(riid), surface, device);
 
     wined3d_mutex_lock();
-    if (SUCCEEDED(hr = d3d_device_create(ddraw, target, (IUnknown *)surface, 7, &object, NULL)))
+    if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, target, (IUnknown *)surface, 7, &object, NULL)))
     {
         *device = &object->IDirect3DDevice7_iface;
     }
     {
         *device = &object->IDirect3DDevice7_iface;
     }
@@ -4161,7 +4270,7 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid,
         return CLASS_E_NOAGGREGATION;
 
     wined3d_mutex_lock();
         return CLASS_E_NOAGGREGATION;
 
     wined3d_mutex_lock();
-    if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL)))
+    if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL)))
     {
         *device = &device_impl->IDirect3DDevice3_iface;
     }
     {
         *device = &device_impl->IDirect3DDevice3_iface;
     }
@@ -4187,7 +4296,7 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid,
             iface, debugstr_guid(riid), surface, device);
 
     wined3d_mutex_lock();
             iface, debugstr_guid(riid), surface, device);
 
     wined3d_mutex_lock();
-    if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL)))
+    if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL)))
     {
         *device = &device_impl->IDirect3DDevice2_iface;
     }
     {
         *device = &device_impl->IDirect3DDevice2_iface;
     }
@@ -4357,7 +4466,7 @@ static HRESULT WINAPI d3d7_EnumZBufferFormats(IDirect3D7 *iface, REFCLSID device
         return hr;
     }
 
         return hr;
     }
 
-    for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
+    for (i = 0; i < ARRAY_SIZE(formats); ++i)
     {
         if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, type, mode.format_id,
                 WINED3DUSAGE_DEPTHSTENCIL, WINED3D_RTYPE_TEXTURE_2D, formats[i])))
     {
         if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, type, mode.format_id,
                 WINED3DUSAGE_DEPTHSTENCIL, WINED3D_RTYPE_TEXTURE_2D, formats[i])))
@@ -4559,7 +4668,7 @@ static const struct IDirectDraw2Vtbl ddraw2_vtbl =
     ddraw2_GetAvailableVidMem,
 };
 
     ddraw2_GetAvailableVidMem,
 };
 
-static const struct IDirectDrawVtbl ddraw1_vtbl =
+static struct IDirectDrawVtbl ddraw1_vtbl =
 {
     /* IUnknown */
     ddraw1_QueryInterface,
 {
     /* IUnknown */
     ddraw1_QueryInterface,
@@ -4698,11 +4807,12 @@ struct wined3d_vertex_declaration *ddraw_find_decl(struct ddraw *This, DWORD fvf
             fvf, This, &ddraw_null_wined3d_parent_ops, &pDecl);
     if (hr != S_OK) return NULL;
 
             fvf, This, &ddraw_null_wined3d_parent_ops, &pDecl);
     if (hr != S_OK) return NULL;
 
-    if(This->declArraySize == This->numConvertedDecls) {
-        int grow = max(This->declArraySize / 2, 8);
-        convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
-                                     sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
-        if (!convertedDecls)
+    if (This->declArraySize == This->numConvertedDecls)
+    {
+        unsigned int grow = max(This->declArraySize / 2, 8);
+
+        if (!(convertedDecls = heap_realloc(convertedDecls,
+                (This->numConvertedDecls + grow) * sizeof(*convertedDecls))))
         {
             wined3d_vertex_declaration_decref(pDecl);
             return NULL;
         {
             wined3d_vertex_declaration_decref(pDecl);
             return NULL;
@@ -4818,7 +4928,7 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
         return DD_OK;
     }
 
         return DD_OK;
     }
 
-    if (!(ddraw_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ddraw_surface))))
+    if (!(ddraw_surface = heap_alloc_zero(sizeof(*ddraw_surface))))
     {
         ERR("Failed to allocate surface memory.\n");
         return DDERR_OUTOFVIDEOMEMORY;
     {
         ERR("Failed to allocate surface memory.\n");
         return DDERR_OUTOFVIDEOMEMORY;
index 04ee59c..1454e80 100644 (file)
 #ifndef __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H
 #define __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H
 
 #ifndef __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H
 #define __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H
 
-#include <config.h>
-#include <wine/port.h>
-
 #include <assert.h>
 #include <assert.h>
-#include <stdarg.h>
-
-#define _INC_WINDOWS
-#define COM_NO_WINDOW_H
-
+#include <limits.h>
 #define COBJMACROS
 #define NONAMELESSSTRUCT
 #define NONAMELESSUNION
 #define COBJMACROS
 #define NONAMELESSSTRUCT
 #define NONAMELESSUNION
+#include "wine/debug.h"
+#include "wine/heap.h"
 
 
-#include <windef.h>
-#include <winbase.h>
-#include <wingdi.h>
-#include <winuser.h>
-#include <d3d.h>
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
 
 
-#include <wine/debug.h>
-#include <wine/list.h>
-#include <wine/wined3d.h>
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+#include "d3d.h"
+#include "ddraw.h"
+#ifdef DDRAW_INIT_GUID
+#include "initguid.h"
+#endif
+#include "wine/list.h"
+#include "wine/wined3d.h"
 
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
 
 
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
 
@@ -64,13 +59,14 @@ struct FvfToDecl
 #define DDRAW_NO3D              0x00000008
 #define DDRAW_SCL_DDRAW1        0x00000010
 #define DDRAW_SCL_RECURSIVE     0x00000020
 #define DDRAW_NO3D              0x00000008
 #define DDRAW_SCL_DDRAW1        0x00000010
 #define DDRAW_SCL_RECURSIVE     0x00000020
+#define DDRAW_GDI_FLIP          0x00000040
 
 #define DDRAW_STRIDE_ALIGNMENT  8
 
 #define DDRAW_WINED3D_FLAGS     (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \
         | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \
         | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \
 
 #define DDRAW_STRIDE_ALIGNMENT  8
 
 #define DDRAW_WINED3D_FLAGS     (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \
         | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \
         | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \
-        | WINED3D_LEGACY_CUBEMAP_FILTERING)
+        | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT)
 
 enum ddraw_device_state
 {
 
 enum ddraw_device_state
 {
@@ -309,6 +305,7 @@ struct d3d_device
     IUnknown IUnknown_inner;
     LONG ref;
     UINT version;
     IUnknown IUnknown_inner;
     LONG ref;
     UINT version;
+    BOOL hw;
 
     IUnknown *outer_unknown;
     struct wined3d_device *wined3d_device;
 
     IUnknown *outer_unknown;
     struct wined3d_device *wined3d_device;
@@ -353,7 +350,7 @@ struct d3d_device
     struct wined3d_vec4 user_clip_planes[D3DMAXUSERCLIPPLANES];
 };
 
     struct wined3d_vec4 user_clip_planes[D3DMAXUSERCLIPPLANES];
 };
 
-HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface,
+HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface,
         UINT version, struct d3d_device **device, IUnknown *outer_unknown) DECLSPEC_HIDDEN;
 enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device *device) DECLSPEC_HIDDEN;
 
         UINT version, struct d3d_device **device, IUnknown *outer_unknown) DECLSPEC_HIDDEN;
 enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device *device) DECLSPEC_HIDDEN;
 
@@ -592,6 +589,7 @@ void ddrawformat_from_wined3dformat(DDPIXELFORMAT *ddraw_format,
 BOOL wined3d_colour_from_ddraw_colour(const DDPIXELFORMAT *pf, const struct ddraw_palette *palette,
         DWORD colour, struct wined3d_color *wined3d_colour) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *format) DECLSPEC_HIDDEN;
 BOOL wined3d_colour_from_ddraw_colour(const DDPIXELFORMAT *pf, const struct ddraw_palette *palette,
         DWORD colour, struct wined3d_color *wined3d_colour) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *format) DECLSPEC_HIDDEN;
+unsigned int wined3dmapflags_from_ddrawmapflags(unsigned int flags) DECLSPEC_HIDDEN;
 void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd) DECLSPEC_HIDDEN;
 void dump_D3DMATRIX(const D3DMATRIX *mat) DECLSPEC_HIDDEN;
 void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) DECLSPEC_HIDDEN;
 void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd) DECLSPEC_HIDDEN;
 void dump_D3DMATRIX(const D3DMATRIX *mat) DECLSPEC_HIDDEN;
 void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) DECLSPEC_HIDDEN;
index fe48ad3..24dbd3b 100644 (file)
  *
  */
 
  *
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
 /* The device ID */
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
 /* The device ID */
@@ -318,7 +322,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
             This->ddraw->d3ddevice = NULL;
 
         /* Now free the structure */
             This->ddraw->d3ddevice = NULL;
 
         /* Now free the structure */
-        HeapFree(GetProcessHeap(), 0, This);
+        heap_free(This);
         wined3d_mutex_unlock();
     }
 
         wined3d_mutex_unlock();
     }
 
@@ -659,8 +663,7 @@ static HRESULT WINAPI d3d_device1_CreateExecuteBuffer(IDirect3DDevice *iface,
         return CLASS_E_NOAGGREGATION;
 
     /* Allocate the new Execute Buffer */
         return CLASS_E_NOAGGREGATION;
 
     /* Allocate the new Execute Buffer */
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if(!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         ERR("Failed to allocate execute buffer memory.\n");
         return DDERR_OUTOFMEMORY;
     {
         ERR("Failed to allocate execute buffer memory.\n");
         return DDERR_OUTOFMEMORY;
@@ -670,7 +673,7 @@ static HRESULT WINAPI d3d_device1_CreateExecuteBuffer(IDirect3DDevice *iface,
     if (FAILED(hr))
     {
         WARN("Failed to initialize execute buffer, hr %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize execute buffer, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -1083,7 +1086,7 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface,
         return hr;
     }
 
         return hr;
     }
 
-    for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i)
+    for (i = 0; i < ARRAY_SIZE(FormatList); ++i)
     {
         if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL,
                 mode.format_id, WINED3DUSAGE_TEXTURE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK)
     {
         if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL,
                 mode.format_id, WINED3DUSAGE_TEXTURE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK)
@@ -1105,7 +1108,7 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface,
         }
     }
 
         }
     }
 
-    for (i = 0; i < sizeof(BumpFormatList) / sizeof(*BumpFormatList); ++i)
+    for (i = 0; i < ARRAY_SIZE(BumpFormatList); ++i)
     {
         if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT,
                 WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
     {
         if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT,
                 WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
@@ -1211,7 +1214,7 @@ static HRESULT WINAPI d3d_device2_EnumTextureFormats(IDirect3DDevice2 *iface,
         return hr;
     }
 
         return hr;
     }
 
-    for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i)
+    for (i = 0; i < ARRAY_SIZE(FormatList); ++i)
     {
         if (wined3d_check_device_format(device->ddraw->wined3d, 0, WINED3D_DEVICE_TYPE_HAL,
                 mode.format_id, WINED3DUSAGE_TEXTURE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK)
     {
         if (wined3d_check_device_format(device->ddraw->wined3d, 0, WINED3D_DEVICE_TYPE_HAL,
                 mode.format_id, WINED3DUSAGE_TEXTURE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK)
@@ -1270,7 +1273,7 @@ static HRESULT WINAPI d3d_device1_EnumTextureFormats(IDirect3DDevice *iface,
 static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
 {
     struct d3d_device *device = impl_from_IDirect3DDevice(iface);
 static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
 {
     struct d3d_device *device = impl_from_IDirect3DDevice(iface);
-    D3DMATRIX *Matrix;
+    D3DMATRIX *matrix;
     DWORD h;
 
     TRACE("iface %p, matrix_handle %p.\n", iface, D3DMatHandle);
     DWORD h;
 
     TRACE("iface %p, matrix_handle %p.\n", iface, D3DMatHandle);
@@ -1278,8 +1281,7 @@ static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIX
     if(!D3DMatHandle)
         return DDERR_INVALIDPARAMS;
 
     if(!D3DMatHandle)
         return DDERR_INVALIDPARAMS;
 
-    Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
-    if(!Matrix)
+    if (!(matrix = heap_alloc_zero(sizeof(*matrix))))
     {
         ERR("Out of memory when allocating a D3DMATRIX\n");
         return DDERR_OUTOFMEMORY;
     {
         ERR("Out of memory when allocating a D3DMATRIX\n");
         return DDERR_OUTOFMEMORY;
@@ -1287,11 +1289,11 @@ static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIX
 
     wined3d_mutex_lock();
 
 
     wined3d_mutex_lock();
 
-    h = ddraw_allocate_handle(&device->handle_table, Matrix, DDRAW_HANDLE_MATRIX);
+    h = ddraw_allocate_handle(&device->handle_table, matrix, DDRAW_HANDLE_MATRIX);
     if (h == DDRAW_INVALID_HANDLE)
     {
         ERR("Failed to allocate a matrix handle.\n");
     if (h == DDRAW_INVALID_HANDLE)
     {
         ERR("Failed to allocate a matrix handle.\n");
-        HeapFree(GetProcessHeap(), 0, Matrix);
+        heap_free(matrix);
         wined3d_mutex_unlock();
         return DDERR_OUTOFMEMORY;
     }
         wined3d_mutex_unlock();
         return DDERR_OUTOFMEMORY;
     }
@@ -1442,7 +1444,7 @@ static HRESULT WINAPI d3d_device1_DeleteMatrix(IDirect3DDevice *iface, D3DMATRIX
 
     wined3d_mutex_unlock();
 
 
     wined3d_mutex_unlock();
 
-    HeapFree(GetProcessHeap(), 0, m);
+    heap_free(m);
 
     return D3D_OK;
 }
 
     return D3D_OK;
 }
@@ -1852,7 +1854,7 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface,
         return DDERR_INVALIDCAPS;
     }
 
         return DDERR_INVALIDCAPS;
     }
 
-    if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
+    if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
     {
         WARN("Surface %p is not in video memory.\n", target_impl);
         wined3d_mutex_unlock();
     {
         WARN("Surface %p is not in video memory.\n", target_impl);
         wined3d_mutex_unlock();
@@ -1928,7 +1930,7 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface,
         return DDERR_INVALIDPIXELFORMAT;
     }
 
         return DDERR_INVALIDPIXELFORMAT;
     }
 
-    if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
+    if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
     {
         WARN("Surface %p is not in video memory.\n", target_impl);
         IDirectDrawSurface4_AddRef(target);
     {
         WARN("Surface %p is not in video memory.\n", target_impl);
         IDirectDrawSurface4_AddRef(target);
@@ -1977,7 +1979,7 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface,
         return DDERR_INVALIDPIXELFORMAT;
     }
 
         return DDERR_INVALIDPIXELFORMAT;
     }
 
-    if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
+    if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
     {
         WARN("Surface %p is not in video memory.\n", target_impl);
         IDirectDrawSurface_AddRef(target);
     {
         WARN("Surface %p is not in video memory.\n", target_impl);
         IDirectDrawSurface_AddRef(target);
@@ -2214,11 +2216,11 @@ static HRESULT WINAPI d3d_device3_Vertex(IDirect3DDevice3 *iface, void *vertex)
 
         device->buffer_size = device->buffer_size ? device->buffer_size * 2 : device->vertex_size * 3;
         old_buffer = device->sysmem_vertex_buffer;
 
         device->buffer_size = device->buffer_size ? device->buffer_size * 2 : device->vertex_size * 3;
         old_buffer = device->sysmem_vertex_buffer;
-        device->sysmem_vertex_buffer = HeapAlloc(GetProcessHeap(), 0, device->buffer_size);
+        device->sysmem_vertex_buffer = heap_alloc(device->buffer_size);
         if (old_buffer)
         {
             memcpy(device->sysmem_vertex_buffer, old_buffer, device->nb_vertices * device->vertex_size);
         if (old_buffer)
         {
             memcpy(device->sysmem_vertex_buffer, old_buffer, device->nb_vertices * device->vertex_size);
-            HeapFree(GetProcessHeap(), 0, old_buffer);
+            heap_free(old_buffer);
         }
     }
 
         }
     }
 
@@ -3461,15 +3463,22 @@ static HRESULT d3d_device_prepare_vertex_buffer(struct d3d_device *device, UINT
     if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
     {
         UINT size = max(device->vertex_buffer_size * 2, min_size);
     if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
     {
         UINT size = max(device->vertex_buffer_size * 2, min_size);
+        struct wined3d_buffer_desc desc;
         struct wined3d_buffer *buffer;
 
         TRACE("Growing vertex buffer to %u bytes\n", size);
 
         struct wined3d_buffer *buffer;
 
         TRACE("Growing vertex buffer to %u bytes\n", size);
 
-        hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
-                WINED3D_POOL_DEFAULT, NULL, &ddraw_null_wined3d_parent_ops, &buffer);
-        if (FAILED(hr))
+        desc.byte_width = size;
+        desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY;
+        desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        desc.misc_flags = 0;
+        desc.structure_byte_stride = 0;
+
+        if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc,
+                NULL, NULL, &ddraw_null_wined3d_parent_ops, &buffer)))
         {
         {
-            ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device, hr);
+            ERR("Failed to create vertex buffer, hr %#x.\n", hr);
             return hr;
         }
 
             return hr;
         }
 
@@ -3524,7 +3533,7 @@ static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface,
     wined3d_box.right = vb_pos + size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = vb_pos + size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
-            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, vertices, size);
     wined3d_resource_unmap(vb, 0);
         goto done;
     memcpy(wined3d_map_desc.data, vertices, size);
     wined3d_resource_unmap(vb, 0);
@@ -3646,15 +3655,22 @@ static HRESULT d3d_device_prepare_index_buffer(struct d3d_device *device, UINT m
     if (device->index_buffer_size < min_size || !device->index_buffer)
     {
         UINT size = max(device->index_buffer_size * 2, min_size);
     if (device->index_buffer_size < min_size || !device->index_buffer)
     {
         UINT size = max(device->index_buffer_size * 2, min_size);
+        struct wined3d_buffer_desc desc;
         struct wined3d_buffer *buffer;
 
         TRACE("Growing index buffer to %u bytes\n", size);
 
         struct wined3d_buffer *buffer;
 
         TRACE("Growing index buffer to %u bytes\n", size);
 
-        hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
-                WINED3D_POOL_DEFAULT, NULL, &ddraw_null_wined3d_parent_ops, &buffer);
-        if (FAILED(hr))
+        desc.byte_width = size;
+        desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_STATICDECL;
+        desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        desc.misc_flags = 0;
+        desc.structure_byte_stride = 0;
+
+        if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc,
+                NULL, NULL, &ddraw_null_wined3d_parent_ops, &buffer)))
         {
         {
-            ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device, hr);
+            ERR("Failed to create index buffer, hr %#x.\n", hr);
             return hr;
         }
 
             return hr;
         }
 
@@ -3709,7 +3725,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
     wined3d_box.right = vb_pos + vtx_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = vb_pos + vtx_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
-            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, vertices, vtx_size);
     wined3d_resource_unmap(vb, 0);
         goto done;
     memcpy(wined3d_map_desc.data, vertices, vtx_size);
     wined3d_resource_unmap(vb, 0);
@@ -3726,7 +3742,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
     wined3d_box.right = ib_pos + idx_size;
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = ib_pos + idx_size;
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
-            ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, indices, idx_size);
     wined3d_resource_unmap(ib, 0);
         goto done;
     memcpy(wined3d_map_desc.data, indices, idx_size);
     wined3d_resource_unmap(ib, 0);
@@ -4040,7 +4056,7 @@ static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIM
     wined3d_box.right = vb_pos + dst_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = vb_pos + dst_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
-            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     pack_strided_data(wined3d_map_desc.data, vertex_count, strided_data, fvf);
     wined3d_resource_unmap(vb, 0);
         goto done;
     pack_strided_data(wined3d_map_desc.data, vertex_count, strided_data, fvf);
     wined3d_resource_unmap(vb, 0);
@@ -4156,7 +4172,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
     wined3d_box.right = vb_pos + vtx_dst_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = vb_pos + vtx_dst_size;
     vb = wined3d_buffer_get_resource(device->vertex_buffer);
     if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box,
-            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     pack_strided_data(wined3d_map_desc.data, vertex_count, strided_data, fvf);
     wined3d_resource_unmap(vb, 0);
         goto done;
     pack_strided_data(wined3d_map_desc.data, vertex_count, strided_data, fvf);
     wined3d_resource_unmap(vb, 0);
@@ -4173,7 +4189,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
     wined3d_box.right = ib_pos + idx_size;
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = ib_pos + idx_size;
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
-            ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
         goto done;
     memcpy(wined3d_map_desc.data, indices, idx_size);
     wined3d_resource_unmap(ib, 0);
         goto done;
     memcpy(wined3d_map_desc.data, indices, idx_size);
     wined3d_resource_unmap(ib, 0);
@@ -4393,7 +4409,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
     wined3d_box.right = ib_pos + index_count * sizeof(WORD);
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
     wined3d_box.right = ib_pos + index_count * sizeof(WORD);
     ib = wined3d_buffer_get_resource(device->index_buffer);
     if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box,
-            ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))
+            WINED3D_MAP_WRITE | (ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
     {
         ERR("Failed to map buffer, hr %#x.\n", hr);
         wined3d_mutex_unlock();
     {
         ERR("Failed to map buffer, hr %#x.\n", hr);
         wined3d_mutex_unlock();
@@ -6887,7 +6903,7 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device
     return WINED3D_ZB_TRUE;
 }
 
     return WINED3D_ZB_TRUE;
 }
 
-static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw,
+static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, BOOL hw,
         struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown)
 {
     static const D3DMATRIX ident =
         struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown)
 {
     static const D3DMATRIX ident =
@@ -6910,6 +6926,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw,
     device->IUnknown_inner.lpVtbl = &d3d_device_inner_vtbl;
     device->ref = 1;
     device->version = version;
     device->IUnknown_inner.lpVtbl = &d3d_device_inner_vtbl;
     device->ref = 1;
     device->version = version;
+    device->hw = hw;
 
     if (outer_unknown)
         device->outer_unknown = outer_unknown;
 
     if (outer_unknown)
         device->outer_unknown = outer_unknown;
@@ -6960,14 +6977,18 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw,
     return D3D_OK;
 }
 
     return D3D_OK;
 }
 
-HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface,
+HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface,
         UINT version, struct d3d_device **device, IUnknown *outer_unknown)
 {
     struct d3d_device *object;
         UINT version, struct d3d_device **device, IUnknown *outer_unknown)
 {
     struct d3d_device *object;
+    BOOL hw = TRUE;
     HRESULT hr;
 
     HRESULT hr;
 
-    TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n",
-            ddraw, target, version, device, outer_unknown);
+    TRACE("ddraw %p, guid %s, target %p, version %u, device %p, outer_unknown %p.\n",
+            ddraw, debugstr_guid(guid), target, version, device, outer_unknown);
+
+    if (IsEqualGUID(guid, &IID_IDirect3DRGBDevice))
+        hw = FALSE;
 
     if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
             || (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
 
     if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
             || (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
@@ -6982,7 +7003,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUn
         return DDERR_NOPALETTEATTACHED;
     }
 
         return DDERR_NOPALETTEATTACHED;
     }
 
-    if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
+    if (hw && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
     {
         WARN("Surface %p is not in video memory.\n", target);
         return D3DERR_SURFACENOTINVIDMEM;
     {
         WARN("Surface %p is not in video memory.\n", target);
         return D3DERR_SURFACENOTINVIDMEM;
@@ -7002,17 +7023,16 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUn
         return DDERR_INVALIDPARAMS;
     }
 
         return DDERR_INVALIDPARAMS;
     }
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         ERR("Failed to allocate device memory.\n");
         return DDERR_OUTOFMEMORY;
     }
 
     {
         ERR("Failed to allocate device memory.\n");
         return DDERR_OUTOFMEMORY;
     }
 
-    if (FAILED(hr = d3d_device_init(object, ddraw, target, rt_iface, version, outer_unknown)))
+    if (FAILED(hr = d3d_device_init(object, ddraw, hw, target, rt_iface, version, outer_unknown)))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
index 7b68bd7..17bea27 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 /*****************************************************************************
  * _dump_executedata
  * _dump_D3DEXECUTEBUFFERDESC
 /*****************************************************************************
  * _dump_executedata
  * _dump_D3DEXECUTEBUFFERDESC
@@ -119,13 +124,20 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
 
                 if (buffer->index_size < index_count)
                 {
 
                 if (buffer->index_size < index_count)
                 {
-                    struct wined3d_buffer *new_buffer;
                     unsigned int new_size = max(buffer->index_size * 2, index_count);
                     unsigned int new_size = max(buffer->index_size * 2, index_count);
-
-                    hr = wined3d_buffer_create_ib(device->wined3d_device, new_size * sizeof(*indices),
-                            WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_DEFAULT,
-                            NULL, &ddraw_null_wined3d_parent_ops, &new_buffer);
-                    if (FAILED(hr))
+                    struct wined3d_buffer *new_buffer;
+                    struct wined3d_buffer_desc desc;
+
+                    desc.byte_width = new_size * sizeof(*indices);
+                    desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_STATICDECL;
+                    desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
+                    desc.access = WINED3D_RESOURCE_ACCESS_GPU
+                            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+                    desc.misc_flags = 0;
+                    desc.structure_byte_stride = 0;
+
+                    if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc,
+                            NULL, NULL, &ddraw_null_wined3d_parent_ops, &new_buffer)))
                         return hr;
 
                     buffer->index_size = new_size;
                         return hr;
 
                     buffer->index_size = new_size;
@@ -141,9 +153,8 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
 
                 box.left = index_pos * sizeof(*indices);
                 box.right = (index_pos + index_count) * sizeof(*indices);
 
                 box.left = index_pos * sizeof(*indices);
                 box.right = (index_pos + index_count) * sizeof(*indices);
-                hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->index_buffer), 0,
-                        &map_desc, &box, index_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
-                if (FAILED(hr))
+                if (FAILED(hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->index_buffer), 0, &map_desc,
+                        &box, WINED3D_MAP_WRITE | (index_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))))
                     return hr;
                 indices = map_desc.data;
 
                     return hr;
                 indices = map_desc.data;
 
@@ -297,7 +308,10 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
                             ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags);
 
                     if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
                             ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags);
 
                     if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
-                        FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
+                    {
+                        static int once;
+                        if (!once++) FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
+                    }
                     if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
                         FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n");
 
                     if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
                         FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n");
 
@@ -497,7 +511,7 @@ static ULONG WINAPI d3d_execute_buffer_Release(IDirect3DExecuteBuffer *iface)
     if (!ref)
     {
         if (buffer->need_free)
     if (!ref)
     {
         if (buffer->need_free)
-            HeapFree(GetProcessHeap(), 0, buffer->desc.lpData);
+            heap_free(buffer->desc.lpData);
         if (buffer->index_buffer)
             wined3d_buffer_decref(buffer->index_buffer);
         if (buffer->dst_vertex_buffer)
         if (buffer->index_buffer)
             wined3d_buffer_decref(buffer->index_buffer);
         if (buffer->dst_vertex_buffer)
@@ -505,7 +519,7 @@ static ULONG WINAPI d3d_execute_buffer_Release(IDirect3DExecuteBuffer *iface)
             wined3d_buffer_decref(buffer->src_vertex_buffer);
             wined3d_buffer_decref(buffer->dst_vertex_buffer);
         }
             wined3d_buffer_decref(buffer->src_vertex_buffer);
             wined3d_buffer_decref(buffer->dst_vertex_buffer);
         }
-        HeapFree(GetProcessHeap(), 0, buffer);
+        heap_free(buffer);
     }
 
     return ref;
     }
 
     return ref;
@@ -606,17 +620,25 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
     {
         unsigned int new_size = max(data->dwVertexCount, buffer->vertex_size * 2);
         struct wined3d_buffer *src_buffer, *dst_buffer;
     {
         unsigned int new_size = max(data->dwVertexCount, buffer->vertex_size * 2);
         struct wined3d_buffer *src_buffer, *dst_buffer;
+        struct wined3d_buffer_desc desc;
 
 
-        hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DVERTEX),
-                WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_SYSTEM_MEM,
-                NULL, &ddraw_null_wined3d_parent_ops, &src_buffer);
-        if (FAILED(hr))
+        desc.byte_width = new_size * sizeof(D3DVERTEX);
+        desc.usage = 0;
+        desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
+        desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+        desc.misc_flags = 0;
+        desc.structure_byte_stride = 0;
+
+        if (FAILED(hr = wined3d_buffer_create(buffer->d3ddev->wined3d_device, &desc,
+                NULL, NULL, &ddraw_null_wined3d_parent_ops, &src_buffer)))
             return hr;
 
             return hr;
 
-        hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DTLVERTEX),
-                WINED3DUSAGE_STATICDECL, WINED3D_POOL_DEFAULT,
-                NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer);
-        if (FAILED(hr))
+        desc.byte_width = new_size * sizeof(D3DTLVERTEX);
+        desc.usage = WINED3DUSAGE_STATICDECL;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+
+        if (FAILED(hr = wined3d_buffer_create(buffer->d3ddev->wined3d_device, &desc,
+                NULL, NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer)))
         {
             wined3d_buffer_decref(src_buffer);
             return hr;
         {
             wined3d_buffer_decref(src_buffer);
             return hr;
@@ -641,9 +663,8 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
     {
         box.left = buffer->src_vertex_pos * sizeof(D3DVERTEX);
         box.right = box.left + data->dwVertexCount * sizeof(D3DVERTEX);
     {
         box.left = buffer->src_vertex_pos * sizeof(D3DVERTEX);
         box.right = box.left + data->dwVertexCount * sizeof(D3DVERTEX);
-        hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0,
-                &map_desc, &box, buffer->src_vertex_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
-        if (FAILED(hr))
+        if (FAILED(hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->src_vertex_buffer),
+                0, &map_desc, &box, WINED3D_MAP_WRITE)))
             return hr;
 
         memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset,
             return hr;
 
         memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset,
@@ -773,8 +794,7 @@ HRESULT d3d_execute_buffer_init(struct d3d_execute_buffer *execute_buffer,
     if (!execute_buffer->desc.lpData && execute_buffer->desc.dwBufferSize)
     {
         execute_buffer->need_free = TRUE;
     if (!execute_buffer->desc.lpData && execute_buffer->desc.dwBufferSize)
     {
         execute_buffer->need_free = TRUE;
-        execute_buffer->desc.lpData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, execute_buffer->desc.dwBufferSize);
-        if (!execute_buffer->desc.lpData)
+        if (!(execute_buffer->desc.lpData = heap_alloc_zero(execute_buffer->desc.dwBufferSize)))
         {
             ERR("Failed to allocate execute buffer data.\n");
             return DDERR_OUTOFMEMORY;
         {
             ERR("Failed to allocate execute buffer data.\n");
             return DDERR_OUTOFMEMORY;
index d20c132..9d0bb60 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 /*****************************************************************************
  * light_update
  *
 /*****************************************************************************
  * light_update
  *
@@ -128,7 +133,7 @@ static ULONG WINAPI d3d_light_Release(IDirect3DLight *iface)
 
     if (!ref)
     {
 
     if (!ref)
     {
-        HeapFree(GetProcessHeap(), 0, light);
+        heap_free(light);
         return 0;
     }
     return ref;
         return 0;
     }
     return ref;
index ea3cbbe..9c0a81c 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#define DDRAW_INIT_GUID
 #include "ddraw_private.h"
 #include "ddraw_private.h"
-#include <winreg.h>
-#include <rpcproxy.h>
+#include "rpcproxy.h"
 
 #include "wine/exception.h"
 
 #include "wine/exception.h"
+#include "winreg.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
 static struct list global_ddraw_list = LIST_INIT(global_ddraw_list);
 
 
 static struct list global_ddraw_list = LIST_INIT(global_ddraw_list);
 
@@ -86,8 +92,7 @@ static void ddraw_enumerate_secondary_devices(struct wined3d *wined3d, LPDDENUMC
 /* Handle table functions */
 BOOL ddraw_handle_table_init(struct ddraw_handle_table *t, UINT initial_size)
 {
 /* Handle table functions */
 BOOL ddraw_handle_table_init(struct ddraw_handle_table *t, UINT initial_size)
 {
-    t->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(*t->entries));
-    if (!t->entries)
+    if (!(t->entries = heap_alloc_zero(initial_size * sizeof(*t->entries))))
     {
         ERR("Failed to allocate handle table memory.\n");
         return FALSE;
     {
         ERR("Failed to allocate handle table memory.\n");
         return FALSE;
@@ -101,7 +106,7 @@ BOOL ddraw_handle_table_init(struct ddraw_handle_table *t, UINT initial_size)
 
 void ddraw_handle_table_destroy(struct ddraw_handle_table *t)
 {
 
 void ddraw_handle_table_destroy(struct ddraw_handle_table *t)
 {
-    HeapFree(GetProcessHeap(), 0, t->entries);
+    heap_free(t->entries);
     memset(t, 0, sizeof(*t));
 }
 
     memset(t, 0, sizeof(*t));
 }
 
@@ -130,9 +135,9 @@ DWORD ddraw_allocate_handle(struct ddraw_handle_table *t, void *object, enum ddr
     {
         /* Grow the table */
         UINT new_size = t->table_size + (t->table_size >> 1);
     {
         /* Grow the table */
         UINT new_size = t->table_size + (t->table_size >> 1);
-        struct ddraw_handle_entry *new_entries = HeapReAlloc(GetProcessHeap(),
-                0, t->entries, new_size * sizeof(*t->entries));
-        if (!new_entries)
+        struct ddraw_handle_entry *new_entries;
+
+        if (!(new_entries = heap_realloc(t->entries, new_size * sizeof(*t->entries))))
         {
             ERR("Failed to grow the handle table.\n");
             return DDRAW_INVALID_HANDLE;
         {
             ERR("Failed to grow the handle table.\n");
             return DDRAW_INVALID_HANDLE;
@@ -292,8 +297,7 @@ DDRAW_Create(const GUID *guid,
         flags = WINED3D_LEGACY_FFP_LIGHTING;
 
     /* DirectDraw creation comes here */
         flags = WINED3D_LEGACY_FFP_LIGHTING;
 
     /* DirectDraw creation comes here */
-    ddraw = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ddraw));
-    if (!ddraw)
+    if (!(ddraw = heap_alloc_zero(sizeof(*ddraw))))
     {
         ERR("Out of memory when creating DirectDraw\n");
         return E_OUTOFMEMORY;
     {
         ERR("Out of memory when creating DirectDraw\n");
         return E_OUTOFMEMORY;
@@ -303,7 +307,7 @@ DDRAW_Create(const GUID *guid,
     if (FAILED(hr))
     {
         WARN("Failed to initialize ddraw object, hr %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize ddraw object, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, ddraw);
+        heap_free(ddraw);
         return hr;
     }
 
         return hr;
     }
 
@@ -664,7 +668,7 @@ static ULONG WINAPI ddraw_class_factory_Release(IClassFactory *iface)
     TRACE("%p decreasing refcount to %u.\n", factory, ref);
 
     if (!ref)
     TRACE("%p decreasing refcount to %u.\n", factory, ref);
 
     if (!ref)
-        HeapFree(GetProcessHeap(), 0, factory);
+        heap_free(factory);
 
     return ref;
 }
 
     return ref;
 }
@@ -736,20 +740,20 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **out)
             && !IsEqualGUID(&IID_IUnknown, riid))
         return E_NOINTERFACE;
 
             && !IsEqualGUID(&IID_IUnknown, riid))
         return E_NOINTERFACE;
 
-    for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
+    for (i=0; i < ARRAY_SIZE(object_creation); i++)
     {
         if (IsEqualGUID(object_creation[i].clsid, rclsid))
             break;
     }
 
     {
         if (IsEqualGUID(object_creation[i].clsid, rclsid))
             break;
     }
 
-    if (i == sizeof(object_creation)/sizeof(object_creation[0]))
+    if (i == ARRAY_SIZE(object_creation))
     {
         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
         return CLASS_E_CLASSNOTAVAILABLE;
     }
 
     {
         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
         return CLASS_E_CLASSNOTAVAILABLE;
     }
 
-    factory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*factory));
-    if (factory == NULL) return E_OUTOFMEMORY;
+    if (!(factory = heap_alloc_zero(sizeof(*factory))))
+        return E_OUTOFMEMORY;
 
     factory->IClassFactory_iface.lpVtbl = &IClassFactory_Vtbl;
     factory->ref = 1;
 
     factory->IClassFactory_iface.lpVtbl = &IClassFactory_Vtbl;
     factory->ref = 1;
index 027a329..1fbf093 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 static void dump_material(const D3DMATERIAL *mat)
 {
     TRACE("  dwSize : %d\n", mat->dwSize);
 static void dump_material(const D3DMATERIAL *mat)
 {
     TRACE("  dwSize : %d\n", mat->dwSize);
@@ -145,7 +150,7 @@ static ULONG WINAPI d3d_material3_Release(IDirect3DMaterial3 *iface)
             wined3d_mutex_unlock();
         }
 
             wined3d_mutex_unlock();
         }
 
-        HeapFree(GetProcessHeap(), 0, material);
+        heap_free(material);
     }
 
     return ref;
     }
 
     return ref;
@@ -497,8 +502,7 @@ struct d3d_material *d3d_material_create(struct ddraw *ddraw)
 {
     struct d3d_material *material;
 
 {
     struct d3d_material *material;
 
-    material = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*material));
-    if (!material)
+    if (!(material = heap_alloc_zero(sizeof(*material))))
         return NULL;
 
     material->IDirect3DMaterial3_iface.lpVtbl = &d3d_material3_vtbl;
         return NULL;
 
     material->IDirect3DMaterial3_iface.lpVtbl = &d3d_material3_vtbl;
index 2f12138..5148832 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 /*****************************************************************************
  * IDirectDrawPalette::QueryInterface
  *
 /*****************************************************************************
  * IDirectDrawPalette::QueryInterface
  *
@@ -95,7 +100,7 @@ static ULONG WINAPI ddraw_palette_Release(IDirectDrawPalette *iface)
             IUnknown_Release(palette->ifaceToRelease);
         wined3d_mutex_unlock();
 
             IUnknown_Release(palette->ifaceToRelease);
         wined3d_mutex_unlock();
 
-        HeapFree(GetProcessHeap(), 0, palette);
+        heap_free(palette);
     }
 
     return ref;
     }
 
     return ref;
diff --git a/dll/directx/wine/ddraw/precomp.h b/dll/directx/wine/ddraw/precomp.h
new file mode 100644 (file)
index 0000000..308faea
--- /dev/null
@@ -0,0 +1,15 @@
+
+#ifndef _WINE_DDRAW_PRECOMP_H
+#define _WINE_DDRAW_PRECOMP_H
+
+#include <wine/config.h>
+#include <wine/port.h>
+
+#include <stdarg.h>
+
+#define _INC_WINDOWS
+#define COM_NO_WINDOW_H
+
+#include "ddraw_private.h"
+
+#endif /* !_WINE_DDRAW_PRECOMP_H */
index abae18b..5eefc22 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2 *iface);
 static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface);
 
 static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2 *iface);
 static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface);
 
@@ -37,6 +42,7 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra
  * to support windowless rendering first. */
 HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read)
 {
  * to support windowless rendering first. */
 HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read)
 {
+    struct ddraw *ddraw = surface->ddraw;
     HDC surface_dc, screen_dc;
     int x, y, w, h;
     HRESULT hr;
     HDC surface_dc, screen_dc;
     int x, y, w, h;
     HRESULT hr;
@@ -57,14 +63,14 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE
     if (w <= 0 || h <= 0)
         return DD_OK;
 
     if (w <= 0 || h <= 0)
         return DD_OK;
 
-    if (surface->ddraw->swapchain_window)
+    if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP))
     {
         /* Nothing to do, we control the frontbuffer, or at least the parts we
          * care about. */
         if (read)
             return DD_OK;
 
     {
         /* Nothing to do, we control the frontbuffer, or at least the parts we
          * care about. */
         if (read)
             return DD_OK;
 
-        return wined3d_texture_blt(surface->ddraw->wined3d_frontbuffer, 0, rect,
+        return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect,
                 surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT);
     }
 
                 surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT);
     }
 
@@ -203,7 +209,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface,
             {
                 HRESULT hr;
 
             {
                 HRESULT hr;
 
-                if (FAILED(hr = d3d_device_create(This->ddraw, This, (IUnknown *)&This->IDirectDrawSurface_iface,
+                if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface,
                         1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface)))
                 {
                     This->device1 = NULL;
                         1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface)))
                 {
                     This->device1 = NULL;
@@ -987,7 +993,8 @@ static HRESULT surface_lock(struct ddraw_surface *surface,
         hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE);
     if (SUCCEEDED(hr))
         hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture),
         hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE);
     if (SUCCEEDED(hr))
         hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture),
-                surface->sub_resource_idx, &map_desc, rect ? &box : NULL, flags);
+                surface->sub_resource_idx, &map_desc, rect ? &box : NULL,
+                wined3dmapflags_from_ddrawmapflags(flags));
     if (FAILED(hr))
     {
         wined3d_mutex_unlock();
     if (FAILED(hr))
     {
         wined3d_mutex_unlock();
@@ -1500,7 +1507,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
         return hr;
     }
 
         return hr;
     }
 
-    if (!(clip_list = HeapAlloc(GetProcessHeap(), 0, clip_list_size)))
+    if (!(clip_list = heap_alloc(clip_list_size)))
     {
         WARN("Failed to allocate clip list.\n");
         return E_OUTOFMEMORY;
     {
         WARN("Failed to allocate clip list.\n");
         return E_OUTOFMEMORY;
@@ -1510,7 +1517,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
             &dst_rect, clip_list, &clip_list_size)))
     {
         WARN("Failed to get clip list, hr %#x.\n", hr);
             &dst_rect, clip_list, &clip_list_size)))
     {
         WARN("Failed to get clip list, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, clip_list);
+        heap_free(clip_list);
         return hr;
     }
 
         return hr;
     }
 
@@ -1544,7 +1551,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
         }
     }
 
         }
     }
 
-    HeapFree(GetProcessHeap(), 0, clip_list);
+    heap_free(clip_list);
     return hr;
 }
 
     return hr;
 }
 
@@ -2063,7 +2070,7 @@ static HRESULT ddraw_surface_delete_attached_surface(struct ddraw_surface *surfa
      * particular, modify the QueryInterface() pointer in the surface vtbl
      * but don't cleanup properly after the relevant dll is unloaded. */
     if (attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER
      * particular, modify the QueryInterface() pointer in the surface vtbl
      * but don't cleanup properly after the relevant dll is unloaded. */
     if (attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER
-            && wined3d_device_get_depth_stencil_view(surface->ddraw->wined3d_device) == surface->wined3d_rtv)
+            && wined3d_device_get_depth_stencil_view(surface->ddraw->wined3d_device) == attachment->wined3d_rtv)
         wined3d_device_set_depth_stencil_view(surface->ddraw->wined3d_device, NULL);
     wined3d_mutex_unlock();
 
         wined3d_device_set_depth_stencil_view(surface->ddraw->wined3d_device, NULL);
     wined3d_mutex_unlock();
 
@@ -5180,6 +5187,46 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface)
     return impl_from_IDirectDrawSurface7(next_level);
 }
 
     return impl_from_IDirectDrawSurface7(next_level);
 }
 
+static BOOL compare_format(DDPIXELFORMAT *format1, DDPIXELFORMAT *format2)
+{
+    if ((format1->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC)) !=
+        (format2->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC)))
+        return FALSE;
+
+    if (format1->dwFlags & (DDPF_RGB|DDPF_YUV))
+    {
+        if (!(format1->dwFlags & DDPF_ALPHA))
+        {
+            /* The RGB and YUV bits are stored in the same fields */
+            if (format1->u1.dwRGBBitCount != format2->u1.dwRGBBitCount)
+                return FALSE;
+
+            if (format1->u2.dwRBitMask != format2->u2.dwRBitMask)
+                return FALSE;
+
+            if (format1->u3.dwGBitMask != format2->u3.dwGBitMask)
+                return FALSE;
+
+            if (format1->u4.dwBBitMask != format2->u4.dwBBitMask)
+                return FALSE;
+        }
+
+        if (format1->dwFlags & (DDPF_ALPHAPIXELS | DDPF_ALPHA))
+        {
+            if (format1->u5.dwRGBAlphaBitMask != format2->u5.dwRGBAlphaBitMask)
+                return FALSE;
+        }
+    }
+
+    if (format1->dwFlags & DDPF_FOURCC)
+    {
+        if (format1->dwFourCC != format2->dwFourCC)
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
 /*****************************************************************************
  * IDirect3DTexture2::Load
  *
 /*****************************************************************************
  * IDirect3DTexture2::Load
  *
@@ -5201,7 +5248,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
 {
     struct ddraw_surface *dst_surface = impl_from_IDirect3DTexture2(iface);
     struct ddraw_surface *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture);
 {
     struct ddraw_surface *dst_surface = impl_from_IDirect3DTexture2(iface);
     struct ddraw_surface *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture);
-    struct wined3d_resource *dst_resource, *src_resource;
+    RECT src_rect, dst_rect;
     HRESULT hr;
 
     TRACE("iface %p, src_texture %p.\n", iface, src_texture);
     HRESULT hr;
 
     TRACE("iface %p, src_texture %p.\n", iface, src_texture);
@@ -5214,90 +5261,60 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
 
     wined3d_mutex_lock();
 
 
     wined3d_mutex_lock();
 
-    dst_resource = wined3d_texture_get_resource(dst_surface->wined3d_texture);
-    src_resource = wined3d_texture_get_resource(src_surface->wined3d_texture);
-
-    if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
-            != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP))
-            || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount))
-    {
-        ERR("Trying to load surfaces with different mip-map counts.\n");
-    }
-
     for (;;)
     {
     for (;;)
     {
-        struct ddraw_palette *dst_pal, *src_pal;
-        DDSURFACEDESC *src_desc, *dst_desc;
+        DDSURFACEDESC *src_desc = (DDSURFACEDESC *)&src_surface->surface_desc;
 
         TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface);
 
 
         TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface);
 
-        /* Suppress the ALLOCONLOAD flag */
-        dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
-
-        /* Get the palettes */
-        dst_pal = dst_surface->palette;
-        src_pal = src_surface->palette;
-
-        if (src_pal)
+        if (compare_format(&src_surface->surface_desc.u4.ddpfPixelFormat,
+                           &dst_surface->surface_desc.u4.ddpfPixelFormat))
         {
         {
-            PALETTEENTRY palent[256];
+            struct ddraw_palette *dst_pal, *src_pal;
 
 
-            if (!dst_pal)
-            {
-                wined3d_mutex_unlock();
-                return DDERR_NOPALETTEATTACHED;
-            }
-            IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent);
-            IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent);
-        }
+            /* Get the palettes */
+            dst_pal = dst_surface->palette;
+            src_pal = src_surface->palette;
 
 
-        /* Copy one surface on the other */
-        dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc);
-        src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc);
+            if (src_pal)
+            {
+                PALETTEENTRY palent[256];
 
 
-        if ((src_desc->dwWidth != dst_desc->dwWidth) || (src_desc->dwHeight != dst_desc->dwHeight))
-        {
-            /* Should also check for same pixel format, u1.lPitch, ... */
-            ERR("Error in surface sizes.\n");
-            wined3d_mutex_unlock();
-            return D3DERR_TEXTURE_LOAD_FAILED;
-        }
-        else
-        {
-            struct wined3d_map_desc src_map_desc, dst_map_desc;
+                if (!dst_pal)
+                {
+                    wined3d_mutex_unlock();
+                    return DDERR_NOPALETTEATTACHED;
+                }
+                IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent);
+                IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent);
+            }
 
 
-            /* Copy the src blit color key if the source has one, don't erase
-             * the destination's ckey if the source has none */
             if (src_desc->dwFlags & DDSD_CKSRCBLT)
             {
                 IDirectDrawSurface7_SetColorKey(&dst_surface->IDirectDrawSurface7_iface,
                         DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt);
             }
             if (src_desc->dwFlags & DDSD_CKSRCBLT)
             {
                 IDirectDrawSurface7_SetColorKey(&dst_surface->IDirectDrawSurface7_iface,
                         DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt);
             }
+        }
+        else
+        {
+            if (src_desc->dwFlags & DDSD_CKSRCBLT)
+                return E_FAIL;
+        }
 
 
-            if (FAILED(hr = wined3d_resource_map(src_resource,
-                    src_surface->sub_resource_idx, &src_map_desc, NULL, 0)))
-            {
-                ERR("Failed to lock source surface, hr %#x.\n", hr);
-                wined3d_mutex_unlock();
-                return D3DERR_TEXTURE_LOAD_FAILED;
-            }
-
-            if (FAILED(hr = wined3d_resource_map(dst_resource,
-                    dst_surface->sub_resource_idx, &dst_map_desc, NULL, 0)))
-            {
-                ERR("Failed to lock destination surface, hr %#x.\n", hr);
-                wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx);
-                wined3d_mutex_unlock();
-                return D3DERR_TEXTURE_LOAD_FAILED;
-            }
+        /* Suppress the ALLOCONLOAD flag */
+        dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
 
 
-            if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
-                memcpy(dst_map_desc.data, src_map_desc.data, src_surface->surface_desc.u1.dwLinearSize);
-            else
-                memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight);
+        SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth, src_surface->surface_desc.dwHeight);
+        SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth, dst_surface->surface_desc.dwHeight);
 
 
-            wined3d_resource_unmap(dst_resource, dst_surface->sub_resource_idx);
-            wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx);
+        hr = wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, &dst_rect,
+                                 src_surface->wined3d_texture, src_surface->sub_resource_idx, &src_rect,
+                                 0, NULL, WINED3D_TEXF_LINEAR);
+        if (FAILED(hr))
+        {
+            ERR("Failed to blit surface, hr %#x.\n", hr);
+            wined3d_mutex_unlock();
+            return hr;
         }
 
         if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
         }
 
         if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
@@ -5310,12 +5327,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
         else
             dst_surface = NULL;
 
         else
             dst_surface = NULL;
 
+        if (src_surface && !dst_surface)
+            return DDERR_NOTFOUND;
+
         if (!src_surface || !dst_surface)
         if (!src_surface || !dst_surface)
-        {
-            if (src_surface != dst_surface)
-                ERR("Loading surface with different mipmap structure.\n");
             break;
             break;
-        }
     }
 
     wined3d_mutex_unlock();
     }
 
     wined3d_mutex_unlock();
@@ -5545,7 +5561,7 @@ static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl =
     ddraw_surface2_PageUnlock,
 };
 
     ddraw_surface2_PageUnlock,
 };
 
-static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl =
+static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl =
 {
     /* IUnknown */
     ddraw_surface1_QueryInterface,
 {
     /* IUnknown */
     ddraw_surface1_QueryInterface,
@@ -5745,7 +5761,7 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren
 
     wined3d_private_store_cleanup(&surface->private_store);
 
 
     wined3d_private_store_cleanup(&surface->private_store);
 
-    HeapFree(GetProcessHeap(), 0, surface);
+    heap_free(surface);
 }
 
 static const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops =
@@ -5757,7 +5773,7 @@ static void STDMETHODCALLTYPE ddraw_texture_wined3d_object_destroyed(void *paren
 {
     TRACE("parent %p.\n", parent);
 
 {
     TRACE("parent %p.\n", parent);
 
-    HeapFree(GetProcessHeap(), 0, parent);
+    heap_free(parent);
 }
 
 static const struct wined3d_parent_ops ddraw_texture_wined3d_parent_ops =
 }
 
 static const struct wined3d_parent_ops ddraw_texture_wined3d_parent_ops =
@@ -5799,7 +5815,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
     if (!surface)
         return E_POINTER;
 
     if (!surface)
         return E_POINTER;
 
-    if (!(texture = HeapAlloc(GetProcessHeap(), 0, sizeof(*texture))))
+    if (!(texture = heap_alloc(sizeof(*texture))))
         return E_OUTOFMEMORY;
 
     texture->version = version;
         return E_OUTOFMEMORY;
 
     texture->version = version;
@@ -5814,28 +5830,28 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
         if (!(desc->dwFlags & DDSD_BACKBUFFERCOUNT) || !desc->u5.dwBackBufferCount)
         {
             WARN("Tried to create a flippable surface without any back buffers.\n");
         if (!(desc->dwFlags & DDSD_BACKBUFFERCOUNT) || !desc->u5.dwBackBufferCount)
         {
             WARN("Tried to create a flippable surface without any back buffers.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDCAPS;
         }
 
         if (!(desc->ddsCaps.dwCaps & DDSCAPS_COMPLEX))
         {
             WARN("Tried to create a flippable surface without DDSCAPS_COMPLEX.\n");
             return DDERR_INVALIDCAPS;
         }
 
         if (!(desc->ddsCaps.dwCaps & DDSCAPS_COMPLEX))
         {
             WARN("Tried to create a flippable surface without DDSCAPS_COMPLEX.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDCAPS;
         }
 
         if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
         {
             WARN("Tried to create a flippable cubemap.\n");
             return DDERR_INVALIDCAPS;
         }
 
         if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
         {
             WARN("Tried to create a flippable cubemap.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDPARAMS;
         }
 
         if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
         {
             FIXME("Flippable textures not implemented.\n");
             return DDERR_INVALIDPARAMS;
         }
 
         if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
         {
             FIXME("Flippable textures not implemented.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDCAPS;
         }
     }
             return DDERR_INVALIDCAPS;
         }
     }
@@ -5845,7 +5861,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
         {
             WARN("Tried to specify a back buffer count for a non-flippable surface.\n");
             hr = desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP ? DDERR_INVALIDPARAMS : DDERR_INVALIDCAPS;
         {
             WARN("Tried to specify a back buffer count for a non-flippable surface.\n");
             hr = desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP ? DDERR_INVALIDPARAMS : DDERR_INVALIDCAPS;
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return hr;
         }
     }
             return hr;
         }
     }
@@ -5855,21 +5871,21 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
         if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
         {
             WARN("Tried to create a primary surface with DDSCAPS_TEXTURE.\n");
         if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
         {
             WARN("Tried to create a primary surface with DDSCAPS_TEXTURE.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDCAPS;
         }
 
         if ((desc->ddsCaps.dwCaps & DDSCAPS_COMPLEX) && !(desc->ddsCaps.dwCaps & DDSCAPS_FLIP))
         {
             WARN("Tried to create a flippable primary surface without both DDSCAPS_FLIP and DDSCAPS_COMPLEX.\n");
             return DDERR_INVALIDCAPS;
         }
 
         if ((desc->ddsCaps.dwCaps & DDSCAPS_COMPLEX) && !(desc->ddsCaps.dwCaps & DDSCAPS_FLIP))
         {
             WARN("Tried to create a flippable primary surface without both DDSCAPS_FLIP and DDSCAPS_COMPLEX.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDCAPS;
         }
 
         if ((desc->ddsCaps.dwCaps & DDSCAPS_FLIP) && !(ddraw->cooperative_level & DDSCL_EXCLUSIVE))
         {
             WARN("Tried to create a flippable primary surface without DDSCL_EXCLUSIVE.\n");
             return DDERR_INVALIDCAPS;
         }
 
         if ((desc->ddsCaps.dwCaps & DDSCAPS_FLIP) && !(ddraw->cooperative_level & DDSCL_EXCLUSIVE))
         {
             WARN("Tried to create a flippable primary surface without DDSCL_EXCLUSIVE.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_NOEXCLUSIVEMODE;
         }
     }
             return DDERR_NOEXCLUSIVEMODE;
         }
     }
@@ -5879,7 +5895,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             == (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY))
     {
         WARN("Tried to create a surface in both system and video memory.\n");
             == (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY))
     {
         WARN("Tried to create a surface in both system and video memory.\n");
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return DDERR_INVALIDCAPS;
     }
 
         return DDERR_INVALIDCAPS;
     }
 
@@ -5887,7 +5903,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             && !(desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE))
     {
         WARN("Caps %#x require DDSCAPS_TEXTURE.\n", desc->ddsCaps.dwCaps);
             && !(desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE))
     {
         WARN("Caps %#x require DDSCAPS_TEXTURE.\n", desc->ddsCaps.dwCaps);
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return DDERR_INVALIDCAPS;
     }
 
         return DDERR_INVALIDCAPS;
     }
 
@@ -5895,7 +5911,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             && !(desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
     {
         WARN("Cube map faces requested without cube map flag.\n");
             && !(desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
     {
         WARN("Cube map faces requested without cube map flag.\n");
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return DDERR_INVALIDCAPS;
     }
 
         return DDERR_INVALIDCAPS;
     }
 
@@ -5903,7 +5919,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             && !(desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES))
     {
         WARN("Cube map without faces requested.\n");
             && !(desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES))
     {
         WARN("Cube map without faces requested.\n");
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return DDERR_INVALIDPARAMS;
     }
 
         return DDERR_INVALIDPARAMS;
     }
 
@@ -5916,14 +5932,14 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
         if (!(desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE))
         {
             WARN("DDSCAPS2_TEXTUREMANAGE used without DDSCAPS_TEXTURE, returning DDERR_INVALIDCAPS.\n");
         if (!(desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE))
         {
             WARN("DDSCAPS2_TEXTUREMANAGE used without DDSCAPS_TEXTURE, returning DDERR_INVALIDCAPS.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDCAPS;
         }
         if (desc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY))
         {
             WARN("DDSCAPS2_TEXTUREMANAGE used width DDSCAPS_VIDEOMEMORY "
                     "or DDSCAPS_SYSTEMMEMORY, returning DDERR_INVALIDCAPS.\n");
             return DDERR_INVALIDCAPS;
         }
         if (desc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY))
         {
             WARN("DDSCAPS2_TEXTUREMANAGE used width DDSCAPS_VIDEOMEMORY "
                     "or DDSCAPS_SYSTEMMEMORY, returning DDERR_INVALIDCAPS.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDCAPS;
         }
     }
             return DDERR_INVALIDCAPS;
         }
     }
@@ -5931,7 +5947,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
     if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
     {
         ERR("Failed to get display mode, hr %#x.\n", hr);
     if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
     {
         ERR("Failed to get display mode, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return hr_ddraw_from_wined3d(hr);
     }
 
         return hr_ddraw_from_wined3d(hr);
     }
 
@@ -5948,7 +5964,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
     if (wined3d_desc.format == WINED3DFMT_UNKNOWN)
     {
         WARN("Unsupported / unknown pixelformat.\n");
     if (wined3d_desc.format == WINED3DFMT_UNKNOWN)
     {
         WARN("Unsupported / unknown pixelformat.\n");
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return DDERR_INVALIDPIXELFORMAT;
     }
 
         return DDERR_INVALIDPIXELFORMAT;
     }
 
@@ -5958,7 +5974,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
         if (!(desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
         {
             WARN("No width / height specified.\n");
         if (!(desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
         {
             WARN("No width / height specified.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDPARAMS;
         }
 
             return DDERR_INVALIDPARAMS;
         }
 
@@ -5969,7 +5985,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
 
     if (!desc->dwWidth || !desc->dwHeight)
     {
 
     if (!desc->dwWidth || !desc->dwHeight)
     {
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return DDERR_INVALIDPARAMS;
     }
 
         return DDERR_INVALIDPARAMS;
     }
 
@@ -5994,7 +6010,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
                     &swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE)))
             {
                 ERR("Failed to reset device.\n");
                     &swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE)))
             {
                 ERR("Failed to reset device.\n");
-                HeapFree(GetProcessHeap(), 0, texture);
+                heap_free(texture);
                 return hr_ddraw_from_wined3d(hr);
             }
 
                 return hr_ddraw_from_wined3d(hr);
             }
 
@@ -6006,7 +6022,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
     wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     wined3d_desc.multisample_quality = 0;
     wined3d_desc.usage = 0;
     wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     wined3d_desc.multisample_quality = 0;
     wined3d_desc.usage = 0;
-    wined3d_desc.pool = WINED3D_POOL_DEFAULT;
+    wined3d_desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     wined3d_desc.width = desc->dwWidth;
     wined3d_desc.height = desc->dwHeight;
     wined3d_desc.depth = 1;
     wined3d_desc.width = desc->dwWidth;
     wined3d_desc.height = desc->dwHeight;
     wined3d_desc.depth = 1;
@@ -6028,7 +6044,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
                 /* Mipmap count is given, should not be 0. */
                 if (!desc->u2.dwMipMapCount)
                 {
                 /* Mipmap count is given, should not be 0. */
                 if (!desc->u2.dwMipMapCount)
                 {
-                    HeapFree(GetProcessHeap(), 0, texture);
+                    heap_free(texture);
                     return DDERR_INVALIDPARAMS;
                 }
             }
                     return DDERR_INVALIDPARAMS;
                 }
             }
@@ -6089,13 +6105,31 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             == (DDSCAPS_OVERLAY | DDSCAPS_SYSTEMMEMORY))
     {
         WARN("System memory overlays are not allowed.\n");
             == (DDSCAPS_OVERLAY | DDSCAPS_SYSTEMMEMORY))
     {
         WARN("System memory overlays are not allowed.\n");
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return DDERR_NOOVERLAYHW;
     }
 
     if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
     {
         return DDERR_NOOVERLAYHW;
     }
 
     if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
     {
-        wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM;
+        /*
+         * The ddraw RGB device allows to use system memory surfaces as rendering target.
+         * This does not cause problems because the RGB device does software rasterization
+         * though it will fail with hardware accelerated ddraw. In order to be partially
+         * compatible with games requesting explicitly the RGB device, we ignore the
+         * specified location and try to create rendering targets in video memory if
+         * possible.
+         */
+        if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) &&
+            SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
+                        WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_RENDERTARGET,
+                        WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format)))
+        {
+            FIXME("Application wants to create rendering target in system memory, using video memory instead\n");
+            wined3d_desc.usage |= WINED3DUSAGE_RENDERTARGET;
+        }
+        else
+            wined3d_desc.access = WINED3D_RESOURCE_ACCESS_CPU
+                | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     }
     else
     {
     }
     else
     {
@@ -6108,7 +6142,8 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
 
         if (desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE))
         {
 
         if (desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE))
         {
-            wined3d_desc.pool = WINED3D_POOL_MANAGED;
+            wined3d_desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU
+                    | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
             /* Managed textures have the system memory flag set. */
             desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
         }
             /* Managed textures have the system memory flag set. */
             desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
         }
@@ -6123,24 +6158,24 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
 
     if (desc->dwFlags & DDSD_LPSURFACE)
     {
 
     if (desc->dwFlags & DDSD_LPSURFACE)
     {
-        if (wined3d_desc.pool != WINED3D_POOL_SYSTEM_MEM)
+        if (wined3d_desc.access & WINED3D_RESOURCE_ACCESS_GPU)
         {
         {
-            WARN("User memory surfaces should be in the system memory pool.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            WARN("User memory surfaces should not be GPU accessible.\n");
+            heap_free(texture);
             return DDERR_INVALIDCAPS;
         }
 
         if (version < 4)
         {
             WARN("User memory surfaces not supported before version 4.\n");
             return DDERR_INVALIDCAPS;
         }
 
         if (version < 4)
         {
             WARN("User memory surfaces not supported before version 4.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDPARAMS;
         }
 
         if (!desc->lpSurface)
         {
             WARN("NULL surface memory pointer specified.\n");
             return DDERR_INVALIDPARAMS;
         }
 
         if (!desc->lpSurface)
         {
             WARN("NULL surface memory pointer specified.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
+            heap_free(texture);
             return DDERR_INVALIDPARAMS;
         }
 
             return DDERR_INVALIDPARAMS;
         }
 
@@ -6149,14 +6184,14 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             if (version != 4 && (desc->dwFlags & DDSD_PITCH))
             {
                 WARN("Pitch specified on a compressed user memory surface.\n");
             if (version != 4 && (desc->dwFlags & DDSD_PITCH))
             {
                 WARN("Pitch specified on a compressed user memory surface.\n");
-                HeapFree(GetProcessHeap(), 0, texture);
+                heap_free(texture);
                 return DDERR_INVALIDPARAMS;
             }
 
             if (!(desc->dwFlags & (DDSD_LINEARSIZE | DDSD_PITCH)))
             {
                 WARN("Compressed user memory surfaces should explicitly specify the linear size.\n");
                 return DDERR_INVALIDPARAMS;
             }
 
             if (!(desc->dwFlags & (DDSD_LINEARSIZE | DDSD_PITCH)))
             {
                 WARN("Compressed user memory surfaces should explicitly specify the linear size.\n");
-                HeapFree(GetProcessHeap(), 0, texture);
+                heap_free(texture);
                 return DDERR_INVALIDPARAMS;
             }
 
                 return DDERR_INVALIDPARAMS;
             }
 
@@ -6165,7 +6200,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
                             wined3d_desc.format, wined3d_desc.width) * ((desc->dwHeight + 3) / 4))
             {
                 WARN("Invalid linear size %u specified.\n", desc->u1.dwLinearSize);
                             wined3d_desc.format, wined3d_desc.width) * ((desc->dwHeight + 3) / 4))
             {
                 WARN("Invalid linear size %u specified.\n", desc->u1.dwLinearSize);
-                HeapFree(GetProcessHeap(), 0, texture);
+                heap_free(texture);
                 return DDERR_INVALIDPARAMS;
             }
         }
                 return DDERR_INVALIDPARAMS;
             }
         }
@@ -6174,7 +6209,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             if (!(desc->dwFlags & DDSD_PITCH))
             {
                 WARN("User memory surfaces should explicitly specify the pitch.\n");
             if (!(desc->dwFlags & DDSD_PITCH))
             {
                 WARN("User memory surfaces should explicitly specify the pitch.\n");
-                HeapFree(GetProcessHeap(), 0, texture);
+                heap_free(texture);
                 return DDERR_INVALIDPARAMS;
             }
 
                 return DDERR_INVALIDPARAMS;
             }
 
@@ -6182,7 +6217,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
                     wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
             {
                 WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
                     wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
             {
                 WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
-                HeapFree(GetProcessHeap(), 0, texture);
+                heap_free(texture);
                 return DDERR_INVALIDPARAMS;
             }
 
                 return DDERR_INVALIDPARAMS;
             }
 
@@ -6200,7 +6235,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             && desc->ddckCKSrcBlt.dwColorSpaceLowValue != desc->ddckCKSrcBlt.dwColorSpaceHighValue))
     {
         WARN("Range color keys not supported, returning DDERR_NOCOLORKEYHW.\n");
             && desc->ddckCKSrcBlt.dwColorSpaceLowValue != desc->ddckCKSrcBlt.dwColorSpaceHighValue))
     {
         WARN("Range color keys not supported, returning DDERR_NOCOLORKEYHW.\n");
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return DDERR_NOCOLORKEYHW;
     }
 
         return DDERR_NOCOLORKEYHW;
     }
 
@@ -6227,7 +6262,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
     {
         WARN("Failed to create wined3d texture, hr %#x.\n", hr);
             &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
     {
         WARN("Failed to create wined3d texture, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, texture);
+        heap_free(texture);
         return hr_ddraw_from_wined3d(hr);
     }
 
         return hr_ddraw_from_wined3d(hr);
     }
 
@@ -6324,7 +6359,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
         attach = &last->complex_array[0];
         for (i = 0; i < count; ++i)
         {
         attach = &last->complex_array[0];
         for (i = 0; i < count; ++i)
         {
-            if (!(texture = HeapAlloc(GetProcessHeap(), 0, sizeof(*texture))))
+            if (!(texture = heap_alloc(sizeof(*texture))))
             {
                 hr = E_OUTOFMEMORY;
                 goto fail;
             {
                 hr = E_OUTOFMEMORY;
                 goto fail;
@@ -6346,7 +6381,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
                     WINED3D_TEXTURE_CREATE_GET_DC_LENIENT, NULL, texture,
                     &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
             {
                     WINED3D_TEXTURE_CREATE_GET_DC_LENIENT, NULL, texture,
                     &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
             {
-                HeapFree(GetProcessHeap(), 0, texture);
+                heap_free(texture);
                 hr = hr_ddraw_from_wined3d(hr);
                 goto fail;
             }
                 hr = hr_ddraw_from_wined3d(hr);
                 goto fail;
             }
index 11d6cd4..65f24dc 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 static void DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf);
 
 void ddrawformat_from_wined3dformat(DDPIXELFORMAT *DDPixelFormat, enum wined3d_format_id wined3d_format)
 static void DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf);
 
 void ddrawformat_from_wined3dformat(DDPIXELFORMAT *DDPixelFormat, enum wined3d_format_id wined3d_format)
@@ -556,6 +561,31 @@ enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *DDPix
     return WINED3DFMT_UNKNOWN;
 }
 
     return WINED3DFMT_UNKNOWN;
 }
 
+unsigned int wined3dmapflags_from_ddrawmapflags(unsigned int flags)
+{
+    static const unsigned int handled = DDLOCK_NOSYSLOCK
+            | DDLOCK_NOOVERWRITE
+            | DDLOCK_DISCARDCONTENTS
+            | DDLOCK_DONOTWAIT;
+    unsigned int wined3d_flags;
+
+    wined3d_flags = flags & handled;
+    if (!(flags & (DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS)))
+        wined3d_flags |= WINED3D_MAP_READ;
+    if (!(flags & DDLOCK_READONLY))
+        wined3d_flags |= WINED3D_MAP_WRITE;
+    if (!(wined3d_flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE)))
+        wined3d_flags |= WINED3D_MAP_READ | WINED3D_MAP_WRITE;
+    if (flags & DDLOCK_NODIRTYUPDATE)
+        wined3d_flags |= WINED3D_MAP_NO_DIRTY_UPDATE;
+    flags &= ~(handled | DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_NODIRTYUPDATE);
+
+    if (flags)
+        FIXME("Unhandled flags %#x.\n", flags);
+
+    return wined3d_flags;
+}
+
 static float colour_to_float(DWORD colour, DWORD mask)
 {
     if (!mask)
 static float colour_to_float(DWORD colour, DWORD mask)
 {
     if (!mask)
@@ -738,8 +768,8 @@ void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in)
         FE(DDSCAPS2_STEREOSURFACELEFT)
     };
 
         FE(DDSCAPS2_STEREOSURFACELEFT)
     };
 
-    DDRAW_dump_flags_nolf(in->dwCaps, flags, sizeof(flags)/sizeof(flags[0]));
-    DDRAW_dump_flags(in->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]));
+    DDRAW_dump_flags_nolf(in->dwCaps, flags, ARRAY_SIZE(flags));
+    DDRAW_dump_flags(in->dwCaps2, flags2, ARRAY_SIZE(flags2));
 }
 
 static void
 }
 
 static void
@@ -776,7 +806,7 @@ DDRAW_dump_pixelformat_flag(DWORD flagmask)
         FE(DDPF_ZPIXELS)
     };
 
         FE(DDPF_ZPIXELS)
     };
 
-    DDRAW_dump_flags_nolf(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
+    DDRAW_dump_flags_nolf(flagmask, flags, ARRAY_SIZE(flags));
 }
 
 static void DDRAW_dump_members(DWORD flags, const void *data, const struct member_info *mems, size_t num_mems)
 }
 
 static void DDRAW_dump_members(DWORD flags, const void *data, const struct member_info *mems, size_t num_mems)
@@ -876,8 +906,7 @@ void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd)
       {
           DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1);
       }
       {
           DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1);
       }
-      DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members,
-                          sizeof(members)/sizeof(members[0]));
+      DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members, ARRAY_SIZE(members));
     }
 }
 
     }
 }
 
@@ -954,7 +983,7 @@ void DDRAW_dump_cooperativelevel(DWORD cooplevel)
     if (TRACE_ON(ddraw))
     {
         TRACE(" - ");
     if (TRACE_ON(ddraw))
     {
         TRACE(" - ");
-        DDRAW_dump_flags(cooplevel, flags, sizeof(flags)/sizeof(flags[0]));
+        DDRAW_dump_flags(cooplevel, flags, ARRAY_SIZE(flags));
     }
 }
 
     }
 }
 
@@ -1113,13 +1142,13 @@ void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps)
     };
 
     TRACE(" - dwSize : %d\n", lpcaps->dwSize);
     };
 
     TRACE(" - dwSize : %d\n", lpcaps->dwSize);
-    TRACE(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, sizeof(flags1)/sizeof(flags1[0]));
-    TRACE(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]));
-    TRACE(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, sizeof(flags3)/sizeof(flags3[0]));
-    TRACE(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, sizeof(flags4)/sizeof(flags4[0]));
-    TRACE(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, sizeof(flags5)/sizeof(flags5[0]));
-    TRACE(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, sizeof(flags6)/sizeof(flags6[0]));
-    TRACE(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, sizeof(flags7)/sizeof(flags7[0]));
+    TRACE(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, ARRAY_SIZE(flags1));
+    TRACE(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, ARRAY_SIZE(flags2));
+    TRACE(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, ARRAY_SIZE(flags3));
+    TRACE(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, ARRAY_SIZE(flags4));
+    TRACE(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, ARRAY_SIZE(flags5));
+    TRACE(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, ARRAY_SIZE(flags6));
+    TRACE(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, ARRAY_SIZE(flags7));
     TRACE("...\n");
     TRACE(" - dwNumFourCCCodes : %d\n", lpcaps->dwNumFourCCCodes);
     TRACE(" - dwCurrVisibleOverlays : %d\n", lpcaps->dwCurrVisibleOverlays);
     TRACE("...\n");
     TRACE(" - dwNumFourCCCodes : %d\n", lpcaps->dwNumFourCCCodes);
     TRACE(" - dwCurrVisibleOverlays : %d\n", lpcaps->dwCurrVisibleOverlays);
index 155a8dd..3ad8f7e 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 static inline struct d3d_vertex_buffer *impl_from_IDirect3DVertexBuffer7(IDirect3DVertexBuffer7 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d_vertex_buffer, IDirect3DVertexBuffer7_iface);
 static inline struct d3d_vertex_buffer *impl_from_IDirect3DVertexBuffer7(IDirect3DVertexBuffer7 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d_vertex_buffer, IDirect3DVertexBuffer7_iface);
@@ -97,7 +102,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
         if (buffer->version == 7)
             IDirectDraw7_Release(&buffer->ddraw->IDirectDraw7_iface);
 
         if (buffer->version == 7)
             IDirectDraw7_Release(&buffer->ddraw->IDirectDraw7_iface);
 
-        HeapFree(GetProcessHeap(), 0, buffer);
+        heap_free(buffer);
     }
 
     return ref;
     }
 
     return ref;
@@ -110,22 +115,24 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
 static HRESULT d3d_vertex_buffer_create_wined3d_buffer(struct d3d_vertex_buffer *buffer, BOOL dynamic,
         struct wined3d_buffer **wined3d_buffer)
 {
 static HRESULT d3d_vertex_buffer_create_wined3d_buffer(struct d3d_vertex_buffer *buffer, BOOL dynamic,
         struct wined3d_buffer **wined3d_buffer)
 {
-    DWORD usage = WINED3DUSAGE_STATICDECL;
-    enum wined3d_pool pool;
-
-    if (buffer->Caps & D3DVBCAPS_SYSTEMMEMORY)
-        pool = WINED3D_POOL_SYSTEM_MEM;
-    else
-        pool = WINED3D_POOL_DEFAULT;
+    struct wined3d_buffer_desc desc;
 
 
+    desc.byte_width = buffer->size;
+    desc.usage = WINED3DUSAGE_STATICDECL;
     if (buffer->Caps & D3DVBCAPS_WRITEONLY)
     if (buffer->Caps & D3DVBCAPS_WRITEONLY)
-        usage |= WINED3DUSAGE_WRITEONLY;
+        desc.usage |= WINED3DUSAGE_WRITEONLY;
     if (dynamic)
     if (dynamic)
-        usage |= WINED3DUSAGE_DYNAMIC;
+        desc.usage |= WINED3DUSAGE_DYNAMIC;
+    desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
+    if (buffer->Caps & D3DVBCAPS_SYSTEMMEMORY)
+        desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+    else
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+    desc.misc_flags = 0;
+    desc.structure_byte_stride = 0;
 
 
-    return wined3d_buffer_create_vb(buffer->ddraw->wined3d_device,
-        buffer->size, usage, pool, buffer, &ddraw_null_wined3d_parent_ops,
-        wined3d_buffer);
+    return wined3d_buffer_create(buffer->ddraw->wined3d_device, &desc,
+            NULL, buffer, &ddraw_null_wined3d_parent_ops, wined3d_buffer);
 }
 
 /*****************************************************************************
 }
 
 /*****************************************************************************
@@ -155,26 +162,16 @@ static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface,
     struct wined3d_resource *wined3d_resource;
     struct wined3d_map_desc wined3d_map_desc;
     HRESULT hr;
     struct wined3d_resource *wined3d_resource;
     struct wined3d_map_desc wined3d_map_desc;
     HRESULT hr;
-    DWORD wined3d_flags = 0;
 
     TRACE("iface %p, flags %#x, data %p, data_size %p.\n", iface, flags, data, data_size);
 
     if (buffer->version != 7)
         flags &= ~(DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS);
 
 
     TRACE("iface %p, flags %#x, data %p, data_size %p.\n", iface, flags, data, data_size);
 
     if (buffer->version != 7)
         flags &= ~(DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS);
 
-    /* Writeonly: Pointless. Event: Unsupported by native according to the sdk
-     * nosyslock: Not applicable
-     */
     if (!(flags & DDLOCK_WAIT))
     if (!(flags & DDLOCK_WAIT))
-        wined3d_flags |= WINED3D_MAP_DONOTWAIT;
-    if (flags & DDLOCK_READONLY)
-        wined3d_flags |= WINED3D_MAP_READONLY;
-    if (flags & DDLOCK_NOOVERWRITE)
-        wined3d_flags |= WINED3D_MAP_NOOVERWRITE;
+        flags |= DDLOCK_DONOTWAIT;
     if (flags & DDLOCK_DISCARDCONTENTS)
     {
     if (flags & DDLOCK_DISCARDCONTENTS)
     {
-        wined3d_flags |= WINED3D_MAP_DISCARD;
-
         if (!buffer->dynamic)
         {
             struct wined3d_buffer *new_buffer;
         if (!buffer->dynamic)
         {
             struct wined3d_buffer *new_buffer;
@@ -204,7 +201,7 @@ static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface,
     }
 
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
     }
 
     hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
-            0, &wined3d_map_desc, NULL, wined3d_flags);
+            0, &wined3d_map_desc, NULL, wined3dmapflags_from_ddrawmapflags(flags));
     *data = wined3d_map_desc.data;
 
     wined3d_mutex_unlock();
     *data = wined3d_map_desc.data;
 
     wined3d_mutex_unlock();
@@ -444,8 +441,7 @@ HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf,
     TRACE("    FVF %#x\n", desc->dwFVF);
     TRACE("    dwNumVertices %u\n", desc->dwNumVertices);
 
     TRACE("    FVF %#x\n", desc->dwFVF);
     TRACE("    dwNumVertices %u\n", desc->dwNumVertices);
 
-    buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*buffer));
-    if (!buffer)
+    if (!(buffer = heap_alloc_zero(sizeof(*buffer))))
         return DDERR_OUTOFMEMORY;
 
     buffer->IDirect3DVertexBuffer7_iface.lpVtbl = &d3d_vertex_buffer7_vtbl;
         return DDERR_OUTOFMEMORY;
 
     buffer->IDirect3DVertexBuffer7_iface.lpVtbl = &d3d_vertex_buffer7_vtbl;
@@ -482,7 +478,7 @@ end:
     if (hr == D3D_OK)
         *vertex_buf = buffer;
     else
     if (hr == D3D_OK)
         *vertex_buf = buffer;
     else
-        HeapFree(GetProcessHeap(), 0, buffer);
+        heap_free(buffer);
 
     return hr;
 }
 
     return hr;
 }
index a62cc31..6ef3226 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "ddraw_private.h"
 
 #include "ddraw_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
 /*****************************************************************************
  * Helper functions
  *****************************************************************************/
 /*****************************************************************************
  * Helper functions
  *****************************************************************************/
@@ -216,7 +221,7 @@ static ULONG WINAPI d3d_viewport_Release(IDirect3DViewport3 *iface)
     TRACE("%p decreasing refcount to %u.\n", viewport, ref);
 
     if (!ref)
     TRACE("%p decreasing refcount to %u.\n", viewport, ref);
 
     if (!ref)
-        HeapFree(GetProcessHeap(), 0, viewport);
+        heap_free(viewport);
 
     return ref;
 }
 
     return ref;
 }
@@ -1127,7 +1132,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport2(IDirect3DViewport2 *ifa
     /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */
     if (!iface) return NULL;
     assert(iface->lpVtbl == (IDirect3DViewport2Vtbl *)&d3d_viewport_vtbl);
     /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */
     if (!iface) return NULL;
     assert(iface->lpVtbl == (IDirect3DViewport2Vtbl *)&d3d_viewport_vtbl);
-    return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface);
+    return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface);
 }
 
 struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface)
 }
 
 struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface)
@@ -1135,7 +1140,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface
     /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */
     if (!iface) return NULL;
     assert(iface->lpVtbl == (IDirect3DViewportVtbl *)&d3d_viewport_vtbl);
     /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */
     if (!iface) return NULL;
     assert(iface->lpVtbl == (IDirect3DViewportVtbl *)&d3d_viewport_vtbl);
-    return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface);
+    return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface);
 }
 
 void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw)
 }
 
 void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw)
index 22fa8b0..235adab 100644 (file)
@@ -19,7 +19,6 @@ list(APPEND SOURCE
     cs.c
     device.c
     directx.c
     cs.c
     device.c
     directx.c
-    drawprim.c
     dxtn.c
     gl_compat.c
     glsl_shader.c
     dxtn.c
     gl_compat.c
     glsl_shader.c
@@ -40,7 +39,7 @@ list(APPEND SOURCE
     vertexdeclaration.c
     view.c
     wined3d_main.c
     vertexdeclaration.c
     view.c
     wined3d_main.c
-    wined3d_private.h)
+    precomp.h)
 
 add_library(d3dwine SHARED
     ${SOURCE}
 
 add_library(d3dwine SHARED
     ${SOURCE}
@@ -50,5 +49,5 @@ add_library(d3dwine SHARED
 set_module_type(d3dwine win32dll)
 target_link_libraries(d3dwine wine)
 add_importlibs(d3dwine user32 opengl32 gdi32 advapi32 msvcrt kernel32 ntdll)
 set_module_type(d3dwine win32dll)
 target_link_libraries(d3dwine wine)
 add_importlibs(d3dwine user32 opengl32 gdi32 advapi32 msvcrt kernel32 ntdll)
-add_pch(d3dwine wined3d_private.h SOURCE)
+add_pch(d3dwine precomp.h SOURCE)
 add_cd_file(TARGET d3dwine DESTINATION reactos/system32 FOR all)
 add_cd_file(TARGET d3dwine DESTINATION reactos/system32 FOR all)
index 00a260f..f86c167 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
@@ -3875,7 +3880,7 @@ static void clone_sig(struct wined3d_shader_signature *new, const struct wined3d
     char *name;
 
     new->element_count = sig->element_count;
     char *name;
 
     new->element_count = sig->element_count;
-    new->elements = wined3d_calloc(new->element_count, sizeof(*new->elements));
+    new->elements = heap_calloc(new->element_count, sizeof(*new->elements));
     for (i = 0; i < sig->element_count; ++i)
     {
         new->elements[i] = sig->elements[i];
     for (i = 0; i < sig->element_count; ++i)
     {
         new->elements[i] = sig->elements[i];
@@ -3884,7 +3889,7 @@ static void clone_sig(struct wined3d_shader_signature *new, const struct wined3d
             continue;
 
         /* Clone the semantic string */
             continue;
 
         /* Clone the semantic string */
-        name = HeapAlloc(GetProcessHeap(), 0, strlen(sig->elements[i].semantic_name) + 1);
+        name = heap_alloc(strlen(sig->elements[i].semantic_name) + 1);
         strcpy(name, sig->elements[i].semantic_name);
         new->elements[i].semantic_name = name;
     }
         strcpy(name, sig->elements[i].semantic_name);
         new->elements[i].semantic_name = name;
     }
@@ -3901,7 +3906,7 @@ static DWORD find_input_signature(struct shader_arb_priv *priv, const struct win
         TRACE("Found existing signature %u\n", found_sig->idx);
         return found_sig->idx;
     }
         TRACE("Found existing signature %u\n", found_sig->idx);
         return found_sig->idx;
     }
-    found_sig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*found_sig));
+    found_sig = heap_alloc_zero(sizeof(*found_sig));
     clone_sig(&found_sig->sig, sig);
     found_sig->idx = priv->ps_sig_number++;
     TRACE("New signature stored and assigned number %u\n", found_sig->idx);
     clone_sig(&found_sig->sig, sig);
     found_sig->idx = priv->ps_sig_number++;
     TRACE("New signature stored and assigned number %u\n", found_sig->idx);
@@ -4253,7 +4258,7 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh
     {
         struct shader_arb_priv *priv = device->shader_priv;
 
     {
         struct shader_arb_priv *priv = device->shader_priv;
 
-        shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+        shader->backend_data = heap_alloc_zero(sizeof(*shader_data));
         shader_data = shader->backend_data;
         shader_data->clamp_consts = shader->reg_maps.shader_version.major == 1;
 
         shader_data = shader->backend_data;
         shader_data->clamp_consts = shader->reg_maps.shader_version.major == 1;
 
@@ -4289,8 +4294,10 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh
             new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
             new_array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shader_data->gl_shaders,
                                     new_size * sizeof(*shader_data->gl_shaders));
             new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
             new_array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shader_data->gl_shaders,
                                     new_size * sizeof(*shader_data->gl_shaders));
-        } else {
-            new_array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data->gl_shaders));
+        }
+        else
+        {
+            new_array = heap_alloc_zero(sizeof(*shader_data->gl_shaders));
             new_size = 1;
         }
 
             new_size = 1;
         }
 
@@ -4348,7 +4355,7 @@ static struct arb_vs_compiled_shader *find_arb_vshader(struct wined3d_shader *sh
     {
         const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
 
     {
         const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
 
-        shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+        shader->backend_data = heap_alloc_zero(sizeof(*shader_data));
         shader_data = shader->backend_data;
 
         if ((gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT)
         shader_data = shader->backend_data;
 
         if ((gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT)
@@ -4388,8 +4395,10 @@ static struct arb_vs_compiled_shader *find_arb_vshader(struct wined3d_shader *sh
             new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
             new_array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shader_data->gl_shaders,
                                     new_size * sizeof(*shader_data->gl_shaders));
             new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
             new_array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shader_data->gl_shaders,
                                     new_size * sizeof(*shader_data->gl_shaders));
-        } else {
-            new_array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data->gl_shaders));
+        }
+        else
+        {
+            new_array = heap_alloc_zero(sizeof(*shader_data->gl_shaders));
             new_size = 1;
         }
 
             new_size = 1;
         }
 
@@ -4757,8 +4766,8 @@ static void shader_arb_destroy(struct wined3d_shader *shader)
             context_release(context);
         }
 
             context_release(context);
         }
 
-        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
-        HeapFree(GetProcessHeap(), 0, shader_data);
+        heap_free(shader_data->gl_shaders);
+        heap_free(shader_data);
         shader->backend_data = NULL;
     }
     else
         shader->backend_data = NULL;
     }
     else
@@ -4781,8 +4790,8 @@ static void shader_arb_destroy(struct wined3d_shader *shader)
             context_release(context);
         }
 
             context_release(context);
         }
 
-        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
-        HeapFree(GetProcessHeap(), 0, shader_data);
+        heap_free(shader_data->gl_shaders);
+        heap_free(shader_data);
         shader->backend_data = NULL;
     }
 }
         shader->backend_data = NULL;
     }
 }
@@ -4796,15 +4805,18 @@ static int sig_tree_compare(const void *key, const struct wine_rb_entry *entry)
 static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
         const struct fragment_pipeline *fragment_pipe)
 {
 static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
         const struct fragment_pipeline *fragment_pipe)
 {
-    struct shader_arb_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv));
+    const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
     struct fragment_caps fragment_caps;
     void *vertex_priv, *fragment_priv;
     struct fragment_caps fragment_caps;
     void *vertex_priv, *fragment_priv;
-    const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+    struct shader_arb_priv *priv;
+
+    if (!(priv = heap_alloc_zero(sizeof(*priv))))
+        return E_OUTOFMEMORY;
 
     if (!(vertex_priv = vertex_pipe->vp_alloc(&arb_program_shader_backend, priv)))
     {
         ERR("Failed to initialize vertex pipe.\n");
 
     if (!(vertex_priv = vertex_pipe->vp_alloc(&arb_program_shader_backend, priv)))
     {
         ERR("Failed to initialize vertex pipe.\n");
-        HeapFree(GetProcessHeap(), 0, priv);
+        heap_free(priv);
         return E_FAIL;
     }
 
         return E_FAIL;
     }
 
@@ -4812,7 +4824,7 @@ static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wine
     {
         ERR("Failed to initialize fragment pipe.\n");
         vertex_pipe->vp_free(device);
     {
         ERR("Failed to initialize fragment pipe.\n");
         vertex_pipe->vp_free(device);
-        HeapFree(GetProcessHeap(), 0, priv);
+        heap_free(priv);
         return E_FAIL;
     }
 
         return E_FAIL;
     }
 
@@ -4842,10 +4854,10 @@ static void release_signature(struct wine_rb_entry *entry, void *context)
 
     for (i = 0; i < sig->sig.element_count; ++i)
     {
 
     for (i = 0; i < sig->sig.element_count; ++i)
     {
-        HeapFree(GetProcessHeap(), 0, (char *)sig->sig.elements[i].semantic_name);
+        heap_free((char *)sig->sig.elements[i].semantic_name);
     }
     }
-    HeapFree(GetProcessHeap(), 0, sig->sig.elements);
-    HeapFree(GetProcessHeap(), 0, sig);
+    heap_free(sig->sig.elements);
+    heap_free(sig);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -4856,7 +4868,7 @@ static void shader_arb_free(struct wined3d_device *device)
     wine_rb_destroy(&priv->signature_tree, release_signature, NULL);
     priv->fragment_pipe->free_private(device);
     priv->vertex_pipe->vp_free(device);
     wine_rb_destroy(&priv->signature_tree, release_signature, NULL);
     priv->fragment_pipe->free_private(device);
     priv->vertex_pipe->vp_free(device);
-    HeapFree(GetProcessHeap(), 0, device->shader_priv);
+    heap_free(device->shader_priv);
 }
 
 static BOOL shader_arb_allocate_context_data(struct wined3d_context *context)
 }
 
 static BOOL shader_arb_allocate_context_data(struct wined3d_context *context)
@@ -5324,39 +5336,38 @@ static void get_loop_control_const(const struct wined3d_shader_instruction *ins,
 
 static void record_instruction(struct list *list, const struct wined3d_shader_instruction *ins)
 {
 
 static void record_instruction(struct list *list, const struct wined3d_shader_instruction *ins)
 {
-    unsigned int i;
-    struct wined3d_shader_dst_param *dst_param;
     struct wined3d_shader_src_param *src_param = NULL, *rel_addr;
     struct wined3d_shader_src_param *src_param = NULL, *rel_addr;
-    struct recorded_instruction *rec = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rec));
-    if(!rec)
+    struct wined3d_shader_dst_param *dst_param;
+    struct recorded_instruction *rec;
+    unsigned int i;
+
+    if (!(rec = heap_alloc_zero(sizeof(*rec))))
     {
         ERR("Out of memory\n");
         return;
     }
 
     rec->ins = *ins;
     {
         ERR("Out of memory\n");
         return;
     }
 
     rec->ins = *ins;
-    dst_param = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_param));
-    if(!dst_param) goto free;
+    if (!(dst_param = heap_alloc(sizeof(*dst_param))))
+        goto free;
     *dst_param = *ins->dst;
     if (ins->dst->reg.idx[0].rel_addr)
     {
     *dst_param = *ins->dst;
     if (ins->dst->reg.idx[0].rel_addr)
     {
-        rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*rel_addr));
-        if (!rel_addr)
+        if (!(rel_addr = heap_alloc(sizeof(*rel_addr))))
             goto free;
         *rel_addr = *ins->dst->reg.idx[0].rel_addr;
         dst_param->reg.idx[0].rel_addr = rel_addr;
     }
     rec->ins.dst = dst_param;
 
             goto free;
         *rel_addr = *ins->dst->reg.idx[0].rel_addr;
         dst_param->reg.idx[0].rel_addr = rel_addr;
     }
     rec->ins.dst = dst_param;
 
-    if (!(src_param = wined3d_calloc(ins->src_count, sizeof(*src_param))))
+    if (!(src_param = heap_calloc(ins->src_count, sizeof(*src_param))))
         goto free;
     for (i = 0; i < ins->src_count; ++i)
     {
         src_param[i] = ins->src[i];
         if (ins->src[i].reg.idx[0].rel_addr)
         {
         goto free;
     for (i = 0; i < ins->src_count; ++i)
     {
         src_param[i] = ins->src[i];
         if (ins->src[i].reg.idx[0].rel_addr)
         {
-            rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*rel_addr));
-            if (!rel_addr)
+            if (!(rel_addr = heap_alloc(sizeof(*rel_addr))))
                 goto free;
             *rel_addr = *ins->src[i].reg.idx[0].rel_addr;
             src_param[i].reg.idx[0].rel_addr = rel_addr;
                 goto free;
             *rel_addr = *ins->src[i].reg.idx[0].rel_addr;
             src_param[i].reg.idx[0].rel_addr = rel_addr;
@@ -5368,20 +5379,20 @@ static void record_instruction(struct list *list, const struct wined3d_shader_in
 
 free:
     ERR("Out of memory\n");
 
 free:
     ERR("Out of memory\n");
-    if(dst_param)
+    if (dst_param)
     {
     {
-        HeapFree(GetProcessHeap(), 0, (void *)dst_param->reg.idx[0].rel_addr);
-        HeapFree(GetProcessHeap(), 0, dst_param);
+        heap_free((void *)dst_param->reg.idx[0].rel_addr);
+        heap_free(dst_param);
     }
     }
-    if(src_param)
+    if (src_param)
     {
     {
-        for(i = 0; i < ins->src_count; i++)
+        for (i = 0; i < ins->src_count; ++i)
         {
         {
-            HeapFree(GetProcessHeap(), 0, (void *)src_param[i].reg.idx[0].rel_addr);
+            heap_free((void *)src_param[i].reg.idx[0].rel_addr);
         }
         }
-        HeapFree(GetProcessHeap(), 0, src_param);
+        heap_free(src_param);
     }
     }
-    HeapFree(GetProcessHeap(), 0, rec);
+    heap_free(rec);
 }
 
 static void free_recorded_instruction(struct list *list)
 }
 
 static void free_recorded_instruction(struct list *list)
@@ -5394,18 +5405,18 @@ static void free_recorded_instruction(struct list *list)
         list_remove(&rec_ins->entry);
         if (rec_ins->ins.dst)
         {
         list_remove(&rec_ins->entry);
         if (rec_ins->ins.dst)
         {
-            HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.dst->reg.idx[0].rel_addr);
-            HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.dst);
+            heap_free((void *)rec_ins->ins.dst->reg.idx[0].rel_addr);
+            heap_free((void *)rec_ins->ins.dst);
         }
         if (rec_ins->ins.src)
         {
             for (i = 0; i < rec_ins->ins.src_count; ++i)
             {
         }
         if (rec_ins->ins.src)
         {
             for (i = 0; i < rec_ins->ins.src_count; ++i)
             {
-                HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.src[i].reg.idx[0].rel_addr);
+                heap_free((void *)rec_ins->ins.src[i].reg.idx[0].rel_addr);
             }
             }
-            HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.src);
+            heap_free((void *)rec_ins->ins.src);
         }
         }
-        HeapFree(GetProcessHeap(), 0, rec_ins);
+        heap_free(rec_ins);
     }
 }
 
     }
 }
 
@@ -5419,7 +5430,7 @@ static void pop_control_frame(const struct wined3d_shader_instruction *ins)
         struct list *e = list_head(&priv->control_frames);
         control_frame = LIST_ENTRY(e, struct control_frame, entry);
         list_remove(&control_frame->entry);
         struct list *e = list_head(&priv->control_frames);
         control_frame = LIST_ENTRY(e, struct control_frame, entry);
         list_remove(&control_frame->entry);
-        HeapFree(GetProcessHeap(), 0, control_frame);
+        heap_free(control_frame);
         priv->loop_depth--;
     }
     else if (ins->handler_idx == WINED3DSIH_ENDIF)
         priv->loop_depth--;
     }
     else if (ins->handler_idx == WINED3DSIH_ENDIF)
@@ -5428,7 +5439,7 @@ static void pop_control_frame(const struct wined3d_shader_instruction *ins)
         struct list *e = list_head(&priv->control_frames);
         control_frame = LIST_ENTRY(e, struct control_frame, entry);
         list_remove(&control_frame->entry);
         struct list *e = list_head(&priv->control_frames);
         control_frame = LIST_ENTRY(e, struct control_frame, entry);
         list_remove(&control_frame->entry);
-        HeapFree(GetProcessHeap(), 0, control_frame);
+        heap_free(control_frame);
     }
 }
 
     }
 }
 
@@ -5442,7 +5453,7 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio
 
     if(ins->handler_idx == WINED3DSIH_LOOP || ins->handler_idx == WINED3DSIH_REP)
     {
 
     if(ins->handler_idx == WINED3DSIH_LOOP || ins->handler_idx == WINED3DSIH_REP)
     {
-        control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+        control_frame = heap_alloc_zero(sizeof(*control_frame));
         list_add_head(&priv->control_frames, &control_frame->entry);
 
         if(ins->handler_idx == WINED3DSIH_LOOP) control_frame->type = LOOP;
         list_add_head(&priv->control_frames, &control_frame->entry);
 
         if(ins->handler_idx == WINED3DSIH_LOOP) control_frame->type = LOOP;
@@ -5539,13 +5550,13 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio
                 shader_addline(buffer, "#end loop/rep\n");
 
                 free_recorded_instruction(&copy);
                 shader_addline(buffer, "#end loop/rep\n");
 
                 free_recorded_instruction(&copy);
-                HeapFree(GetProcessHeap(), 0, control_frame);
+                heap_free(control_frame);
                 return; /* Instruction is handled */
             }
             else
             {
                 /* This is a nested loop. Proceed to the normal recording function */
                 return; /* Instruction is handled */
             }
             else
             {
                 /* This is a nested loop. Proceed to the normal recording function */
-                HeapFree(GetProcessHeap(), 0, control_frame);
+                heap_free(control_frame);
             }
         }
     }
             }
         }
     }
@@ -5559,7 +5570,7 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio
     /* boolean if */
     if(ins->handler_idx == WINED3DSIH_IF)
     {
     /* boolean if */
     if(ins->handler_idx == WINED3DSIH_IF)
     {
-        control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+        control_frame = heap_alloc_zero(sizeof(*control_frame));
         list_add_head(&priv->control_frames, &control_frame->entry);
         control_frame->type = IF;
 
         list_add_head(&priv->control_frames, &control_frame->entry);
         control_frame->type = IF;
 
@@ -5579,7 +5590,7 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio
     else if(ins->handler_idx == WINED3DSIH_IFC)
     {
         /* IF(bool) and if_cond(a, b) use the same ELSE and ENDIF tokens */
     else if(ins->handler_idx == WINED3DSIH_IFC)
     {
         /* IF(bool) and if_cond(a, b) use the same ELSE and ENDIF tokens */
-        control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+        control_frame = heap_alloc_zero(sizeof(*control_frame));
         control_frame->type = IFC;
         control_frame->no.ifc = priv->num_ifcs++;
         list_add_head(&priv->control_frames, &control_frame->entry);
         control_frame->type = IFC;
         control_frame->no.ifc = priv->num_ifcs++;
         list_add_head(&priv->control_frames, &control_frame->entry);
@@ -5614,7 +5625,7 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio
             shader_addline(buffer, "#} endif\n");
             if(control_frame->muting) priv->muted = FALSE;
             list_remove(&control_frame->entry);
             shader_addline(buffer, "#} endif\n");
             if(control_frame->muting) priv->muted = FALSE;
             list_remove(&control_frame->entry);
-            HeapFree(GetProcessHeap(), 0, control_frame);
+            heap_free(control_frame);
             return; /* Instruction is handled */
         }
         /* In case of an ifc, generate a HW shader instruction */
             return; /* Instruction is handled */
         }
         /* In case of an ifc, generate a HW shader instruction */
@@ -5714,7 +5725,7 @@ static void *arbfp_alloc(const struct wined3d_shader_backend_ops *shader_backend
      * or not. */
     if (shader_backend == &arb_program_shader_backend)
         priv = shader_priv;
      * or not. */
     if (shader_backend == &arb_program_shader_backend)
         priv = shader_priv;
-    else if (!(priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv))))
+    else if (!(priv = heap_alloc_zero(sizeof(*priv))))
         return NULL;
 
     wine_rb_init(&priv->fragment_shaders, wined3d_ffp_frag_program_key_compare);
         return NULL;
 
     wine_rb_init(&priv->fragment_shaders, wined3d_ffp_frag_program_key_compare);
@@ -5731,7 +5742,7 @@ static void arbfp_free_ffpshader(struct wine_rb_entry *entry, void *context)
 
     GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
     checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)");
 
     GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
     checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)");
-    HeapFree(GetProcessHeap(), 0, entry_arb);
+    heap_free(entry_arb);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -5743,9 +5754,7 @@ static void arbfp_free(struct wined3d_device *device)
     priv->use_arbfp_fixed_func = FALSE;
 
     if (device->shader_backend != &arb_program_shader_backend)
     priv->use_arbfp_fixed_func = FALSE;
 
     if (device->shader_backend != &arb_program_shader_backend)
-    {
-        HeapFree(GetProcessHeap(), 0, device->fragment_priv);
-    }
+        heap_free(device->fragment_priv);
 }
 
 static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
 }
 
 static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
@@ -6568,8 +6577,9 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
         desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
         if (!desc)
         {
         desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
         if (!desc)
         {
-            struct arbfp_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
-            if (!new_desc)
+            struct arbfp_ffp_desc *new_desc;
+
+            if (!(new_desc = heap_alloc(sizeof(*new_desc))))
             {
                 ERR("Out of memory\n");
                 return;
             {
                 ERR("Out of memory\n");
                 return;
@@ -6894,7 +6904,7 @@ static void arbfp_free_blit_shader(struct wine_rb_entry *entry, void *ctx)
 
     GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
     checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)");
 
     GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
     checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)");
-    HeapFree(GetProcessHeap(), 0, entry_arb);
+    heap_free(entry_arb);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -6915,7 +6925,7 @@ static void arbfp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3
     if (arbfp_blitter->palette_texture)
         gl_info->gl_ops.gl.p_glDeleteTextures(1, &arbfp_blitter->palette_texture);
 
     if (arbfp_blitter->palette_texture)
         gl_info->gl_ops.gl.p_glDeleteTextures(1, &arbfp_blitter->palette_texture);
 
-    HeapFree(GetProcessHeap(), 0, arbfp_blitter);
+    heap_free(arbfp_blitter);
 }
 
 static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
 }
 
 static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
@@ -7557,9 +7567,9 @@ static GLuint arbfp_gen_plain_shader(const struct wined3d_gl_info *gl_info, cons
 
 /* Context activation is done by the caller. */
 static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wined3d_context *context,
 
 /* Context activation is done by the caller. */
 static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wined3d_context *context,
-        const struct wined3d_surface *surface, const struct wined3d_color_key *color_key)
+        const struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        const struct wined3d_color_key *color_key)
 {
 {
-    const struct wined3d_texture *texture = surface->container;
     enum complex_fixup fixup;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wine_rb_entry *entry;
     enum complex_fixup fixup;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wine_rb_entry *entry;
@@ -7567,10 +7577,12 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine
     struct arbfp_blit_desc *desc;
     struct wined3d_color float_color_key[2];
     struct wined3d_vec4 size;
     struct arbfp_blit_desc *desc;
     struct wined3d_color float_color_key[2];
     struct wined3d_vec4 size;
+    unsigned int level;
     GLuint shader;
 
     GLuint shader;
 
-    size.x = wined3d_texture_get_level_pow2_width(texture, surface->texture_level);
-    size.y = wined3d_texture_get_level_pow2_height(texture, surface->texture_level);
+    level = sub_resource_idx % texture->level_count;
+    size.x = wined3d_texture_get_level_pow2_width(texture, level);
+    size.y = wined3d_texture_get_level_pow2_height(texture, level);
     size.z = 1.0f;
     size.w = 1.0f;
 
     size.z = 1.0f;
     size.w = 1.0f;
 
@@ -7642,8 +7654,7 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine
             return E_NOTIMPL;
         }
 
             return E_NOTIMPL;
         }
 
-        desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*desc));
-        if (!desc)
+        if (!(desc = heap_alloc(sizeof(*desc))))
             goto err_out;
 
         desc->type = type;
             goto err_out;
 
         desc->type = type;
@@ -7656,7 +7667,7 @@ err_out:
             checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader))");
             GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0));
             checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)");
             checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader))");
             GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0));
             checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)");
-            HeapFree(GetProcessHeap(), 0, desc);
+            heap_free(desc);
             return E_OUTOFMEMORY;
         }
     }
             return E_OUTOFMEMORY;
         }
     }
@@ -7690,15 +7701,16 @@ static void arbfp_blit_unset(const struct wined3d_gl_info *gl_info)
     checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
 }
 
     checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
 }
 
-static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info,
-        const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
-        enum wined3d_pool src_pool, const struct wined3d_format *src_format, DWORD src_location,
-        enum wined3d_pool dst_pool, const struct wined3d_format *dst_format, DWORD dst_location)
+static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const struct wined3d_context *context,
+        const struct wined3d_resource *src_resource, DWORD src_location,
+        const struct wined3d_resource *dst_resource, DWORD dst_location)
 {
 {
+    const struct wined3d_format *src_format = src_resource->format;
+    const struct wined3d_format *dst_format = dst_resource->format;
     enum complex_fixup src_fixup;
     BOOL decompress;
 
     enum complex_fixup src_fixup;
     BOOL decompress;
 
-    if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
+    if (!context->gl_info->supported[ARB_FRAGMENT_PROGRAM])
         return FALSE;
 
     if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id)
         return FALSE;
 
     if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id)
@@ -7712,7 +7724,7 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info,
     switch (blit_op)
     {
         case WINED3D_BLIT_OP_COLOR_BLIT_CKEY:
     switch (blit_op)
     {
         case WINED3D_BLIT_OP_COLOR_BLIT_CKEY:
-            if (!d3d_info->shader_color_key)
+            if (!context->d3d_info->shader_color_key)
             {
                 /* The conversion modifies the alpha channel so the color key might no longer match. */
                 TRACE("Color keying not supported with converted textures.\n");
             {
                 /* The conversion modifies the alpha channel so the color key might no longer match. */
                 TRACE("Color keying not supported with converted textures.\n");
@@ -7729,7 +7741,7 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info,
 
     decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
             && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED);
 
     decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
             && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED);
-    if (!decompress && (dst_pool == WINED3D_POOL_SYSTEM_MEM || src_pool == WINED3D_POOL_SYSTEM_MEM))
+    if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU))
         return FALSE;
 
     src_fixup = get_complex_fixup(src_format->color_fixup);
         return FALSE;
 
     src_fixup = get_complex_fixup(src_format->color_fixup);
@@ -7787,6 +7799,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
         const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
         const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
 {
         const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
         const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
 {
+    unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
     struct wined3d_texture *src_texture = src_surface->container;
     struct wined3d_texture *dst_texture = dst_surface->container;
     struct wined3d_device *device = dst_texture->resource.device;
     struct wined3d_texture *src_texture = src_surface->container;
     struct wined3d_texture *dst_texture = dst_surface->container;
     struct wined3d_device *device = dst_texture->resource.device;
@@ -7795,9 +7808,8 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
     struct wined3d_blitter *next;
     RECT s, d;
 
     struct wined3d_blitter *next;
     RECT s, d;
 
-    if (!arbfp_blit_supported(&device->adapter->gl_info, &device->adapter->d3d_info, op,
-            src_texture->resource.pool, src_texture->resource.format, src_location,
-            dst_texture->resource.pool, dst_texture->resource.format, dst_location))
+    if (!arbfp_blit_supported(op, context, &src_texture->resource, src_location,
+            &dst_texture->resource, dst_location))
     {
         if ((next = blitter->next))
             return next->ops->blitter_blit(next, op, context, src_surface, src_location,
     {
         if ((next = blitter->next))
             return next->ops->blitter_blit(next, op, context, src_surface, src_location,
@@ -7813,6 +7825,8 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
             == WINED3D_LOCATION_DRAWABLE
             && !wined3d_resource_is_offscreen(&src_texture->resource))
     {
             == WINED3D_LOCATION_DRAWABLE
             && !wined3d_resource_is_offscreen(&src_texture->resource))
     {
+        unsigned int src_level = src_sub_resource_idx % src_texture->level_count;
+
         /* Without FBO blits transferring from the drawable to the texture is
          * expensive, because we have to flip the data in sysmem. Since we can
          * flip in the blitter, we don't actually need that flip anyway. So we
         /* Without FBO blits transferring from the drawable to the texture is
          * expensive, because we have to flip the data in sysmem. Since we can
          * flip in the blitter, we don't actually need that flip anyway. So we
@@ -7821,8 +7835,8 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
         surface_load_fb_texture(src_surface, FALSE, context);
 
         s = *src_rect;
         surface_load_fb_texture(src_surface, FALSE, context);
 
         s = *src_rect;
-        s.top = wined3d_texture_get_level_height(src_texture, src_surface->texture_level) - s.top;
-        s.bottom = wined3d_texture_get_level_height(src_texture, src_surface->texture_level) - s.bottom;
+        s.top = wined3d_texture_get_level_height(src_texture, src_level) - s.top;
+        s.bottom = wined3d_texture_get_level_height(src_texture, src_level) - s.bottom;
         src_rect = &s;
     }
     else
         src_rect = &s;
     }
     else
@@ -7865,10 +7879,10 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
         color_key = &alpha_test_key;
     }
 
         color_key = &alpha_test_key;
     }
 
-    arbfp_blit_set(arbfp_blitter, context, src_surface, color_key);
+    arbfp_blit_set(arbfp_blitter, context, src_texture, src_sub_resource_idx, color_key);
 
     /* Draw a textured quad */
 
     /* Draw a textured quad */
-    draw_textured_quad(src_surface, context, src_rect, dst_rect, filter);
+    draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter);
 
     /* Leave the opengl state valid for blitting */
     arbfp_blit_unset(context->gl_info);
 
     /* Leave the opengl state valid for blitting */
     arbfp_blit_unset(context->gl_info);
@@ -7913,7 +7927,7 @@ void wined3d_arbfp_blitter_create(struct wined3d_blitter **next, const struct wi
     if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
         return;
 
     if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
         return;
 
-    if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
+    if (!(blitter = heap_alloc(sizeof(*blitter))))
     {
         ERR("Failed to allocate blitter.\n");
         return;
     {
         ERR("Failed to allocate blitter.\n");
         return;
index bf36f93..9d6837a 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
@@ -1020,8 +1025,9 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined
     desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
     if (!desc)
     {
     desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
     if (!desc)
     {
-        struct atifs_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*new_desc));
-        if (!new_desc)
+        struct atifs_ffp_desc *new_desc;
+
+        if (!(new_desc = heap_alloc_zero(sizeof(*new_desc))))
         {
             ERR("Out of memory\n");
             return;
         {
             ERR("Out of memory\n");
             return;
@@ -1315,7 +1321,7 @@ static void *atifs_alloc(const struct wined3d_shader_backend_ops *shader_backend
 {
     struct atifs_private_data *priv;
 
 {
     struct atifs_private_data *priv;
 
-    if (!(priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv))))
+    if (!(priv = heap_alloc_zero(sizeof(*priv))))
         return NULL;
 
     wine_rb_init(&priv->fragment_shaders, wined3d_ffp_frag_program_key_compare);
         return NULL;
 
     wine_rb_init(&priv->fragment_shaders, wined3d_ffp_frag_program_key_compare);
@@ -1330,7 +1336,7 @@ static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *cb_ctx)
 
     GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader));
     checkGLcall("glDeleteFragmentShaderATI(entry->shader)");
 
     GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader));
     checkGLcall("glDeleteFragmentShaderATI(entry->shader)");
-    HeapFree(GetProcessHeap(), 0, entry_ati);
+    heap_free(entry_ati);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -1340,7 +1346,7 @@ static void atifs_free(struct wined3d_device *device)
 
     wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, &device->adapter->gl_info);
 
 
     wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, &device->adapter->gl_info);
 
-    HeapFree(GetProcessHeap(), 0, priv);
+    heap_free(priv);
     device->fragment_priv = NULL;
 }
 
     device->fragment_priv = NULL;
 }
 
@@ -1353,8 +1359,9 @@ static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup)
 
 static BOOL atifs_alloc_context_data(struct wined3d_context *context)
 {
 
 static BOOL atifs_alloc_context_data(struct wined3d_context *context)
 {
-    struct atifs_context_private_data *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv));
-    if (!priv)
+    struct atifs_context_private_data *priv;
+
+    if (!(priv = heap_alloc_zero(sizeof(*priv))))
         return FALSE;
     context->fragment_pipe_data = priv;
     return TRUE;
         return FALSE;
     context->fragment_pipe_data = priv;
     return TRUE;
@@ -1362,7 +1369,7 @@ static BOOL atifs_alloc_context_data(struct wined3d_context *context)
 
 static void atifs_free_context_data(struct wined3d_context *context)
 {
 
 static void atifs_free_context_data(struct wined3d_context *context)
 {
-    HeapFree(GetProcessHeap(), 0, context->fragment_pipe_data);
+    heap_free(context->fragment_pipe_data);
 }
 
 const struct fragment_pipeline atifs_fragment_pipeline = {
 }
 
 const struct fragment_pipeline atifs_fragment_pipeline = {
index 0e8f5a3..cae7ef8 100644 (file)
@@ -22,6 +22,9 @@
  *
  */
 
  *
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -299,8 +302,8 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *buffer,
              */
             TRACE("Reconverting because converted attributes occur, and the stride changed.\n");
             buffer->stride = *stride_this_run;
              */
             TRACE("Reconverting because converted attributes occur, and the stride changed.\n");
             buffer->stride = *stride_this_run;
-            HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer->conversion_map);
-            buffer->conversion_map = wined3d_calloc(buffer->stride, sizeof(*buffer->conversion_map));
+            heap_free(buffer->conversion_map);
+            buffer->conversion_map = heap_calloc(buffer->stride, sizeof(*buffer->conversion_map));
             ret = TRUE;
         }
     }
             ret = TRUE;
         }
     }
@@ -382,7 +385,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_s
         TRACE("No fixup required.\n");
         if(This->conversion_map)
         {
         TRACE("No fixup required.\n");
         if(This->conversion_map)
         {
-            HeapFree(GetProcessHeap(), 0, This->conversion_map);
+            heap_free(This->conversion_map);
             This->conversion_map = NULL;
             This->stride = 0;
             return TRUE;
             This->conversion_map = NULL;
             This->stride = 0;
             return TRUE;
@@ -471,8 +474,9 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_s
     if (!stride_this_run && This->conversion_map)
     {
         /* Sanity test */
     if (!stride_this_run && This->conversion_map)
     {
         /* Sanity test */
-        if (!ret) ERR("no converted attributes found, old conversion map exists, and no declaration change?\n");
-        HeapFree(GetProcessHeap(), 0, This->conversion_map);
+        if (!ret)
+            ERR("no converted attributes found, old conversion map exists, and no declaration change?\n");
+        heap_free(This->conversion_map);
         This->conversion_map = NULL;
         This->stride = 0;
     }
         This->conversion_map = NULL;
         This->stride = 0;
     }
@@ -560,7 +564,7 @@ static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined
     /* Now for each vertex in the buffer that needs conversion. */
     vertex_count = buffer->resource.size / buffer->stride;
 
     /* Now for each vertex in the buffer that needs conversion. */
     vertex_count = buffer->resource.size / buffer->stride;
 
-    if (!(data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size)))
+    if (!(data = heap_alloc(buffer->resource.size)))
     {
         ERR("Out of memory.\n");
         return;
     {
         ERR("Out of memory.\n");
         return;
@@ -598,7 +602,7 @@ static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined
 
     wined3d_buffer_upload_ranges(buffer, context, data, 0, buffer->modified_areas, buffer->maps);
 
 
     wined3d_buffer_upload_ranges(buffer, context, data, 0, buffer->modified_areas, buffer->maps);
 
-    HeapFree(GetProcessHeap(), 0, data);
+    heap_free(data);
 }
 
 static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
 }
 
 static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
@@ -750,7 +754,7 @@ static void buffer_unload(struct wined3d_resource *resource)
 
         context_release(context);
 
 
         context_release(context);
 
-        HeapFree(GetProcessHeap(), 0, buffer->conversion_map);
+        heap_free(buffer->conversion_map);
         buffer->conversion_map = NULL;
         buffer->stride = 0;
         buffer->conversion_stride = 0;
         buffer->conversion_map = NULL;
         buffer->stride = 0;
         buffer->conversion_stride = 0;
@@ -777,11 +781,11 @@ static void wined3d_buffer_destroy_object(void *object)
         buffer_destroy_buffer_object(buffer, context);
         context_release(context);
 
         buffer_destroy_buffer_object(buffer, context);
         context_release(context);
 
-        HeapFree(GetProcessHeap(), 0, buffer->conversion_map);
+        heap_free(buffer->conversion_map);
     }
 
     }
 
-    HeapFree(GetProcessHeap(), 0, buffer->maps);
-    HeapFree(GetProcessHeap(), 0, buffer);
+    heap_free(buffer->maps);
+    heap_free(buffer);
 }
 
 ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
 }
 
 ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
@@ -1020,8 +1024,8 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI
             dirty_size = 0;
         }
 
             dirty_size = 0;
         }
 
-        if (!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD | WINED3D_MAP_READONLY))
-                || ((flags & WINED3D_MAP_READONLY) && (buffer->locations & WINED3D_LOCATION_SYSMEM))
+        if (((flags & WINED3D_MAP_WRITE) && !(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)))
+                || (!(flags & WINED3D_MAP_WRITE) && (buffer->locations & WINED3D_LOCATION_SYSMEM))
                 || buffer->flags & WINED3D_BUFFER_PIN_SYSMEM)
         {
             if (!(buffer->locations & WINED3D_LOCATION_SYSMEM))
                 || buffer->flags & WINED3D_BUFFER_PIN_SYSMEM)
         {
             if (!(buffer->locations & WINED3D_LOCATION_SYSMEM))
@@ -1031,7 +1035,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI
                 context_release(context);
             }
 
                 context_release(context);
             }
 
-            if (!(flags & WINED3D_MAP_READONLY))
+            if (flags & WINED3D_MAP_WRITE)
                 wined3d_buffer_invalidate_range(buffer, WINED3D_LOCATION_BUFFER, dirty_offset, dirty_size);
         }
         else
                 wined3d_buffer_invalidate_range(buffer, WINED3D_LOCATION_BUFFER, dirty_offset, dirty_size);
         }
         else
@@ -1046,7 +1050,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI
             else
                 wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER);
 
             else
                 wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER);
 
-            if (!(flags & WINED3D_MAP_READONLY))
+            if (flags & WINED3D_MAP_WRITE)
                 buffer_invalidate_bo_range(buffer, dirty_offset, dirty_size);
 
             if ((flags & WINED3D_MAP_DISCARD) && buffer->resource.heap_memory)
                 buffer_invalidate_bo_range(buffer, dirty_offset, dirty_size);
 
             if ((flags & WINED3D_MAP_DISCARD) && buffer->resource.heap_memory)
@@ -1276,6 +1280,24 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
     return wined3d_buffer_map(buffer, offset, size, (BYTE **)&map_desc->data, flags);
 }
 
     return wined3d_buffer_map(buffer, offset, size, (BYTE **)&map_desc->data, flags);
 }
 
+static HRESULT buffer_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+        struct wined3d_map_info *info, DWORD flags)
+{
+    struct wined3d_buffer *buffer = buffer_from_resource(resource);
+
+    if (sub_resource_idx)
+    {
+        WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
+        return E_INVALIDARG;
+    }
+
+    info->row_pitch   = buffer->desc.byte_width;
+    info->slice_pitch = buffer->desc.byte_width;
+    info->size        = buffer->resource.size;
+
+    return WINED3D_OK;
+}
+
 static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
 {
     if (sub_resource_idx)
 static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
 {
     if (sub_resource_idx)
@@ -1295,6 +1317,7 @@ static const struct wined3d_resource_ops buffer_resource_ops =
     buffer_resource_preload,
     buffer_unload,
     buffer_resource_sub_resource_map,
     buffer_resource_preload,
     buffer_unload,
     buffer_resource_sub_resource_map,
+    buffer_resource_sub_resource_map_info,
     buffer_resource_sub_resource_unmap,
 };
 
     buffer_resource_sub_resource_unmap,
 };
 
@@ -1321,7 +1344,7 @@ static GLenum buffer_type_hint_from_bind_flags(const struct wined3d_gl_info *gl_
 }
 
 static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device,
 }
 
 static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device,
-        UINT size, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, unsigned int bind_flags,
+        UINT size, DWORD usage, enum wined3d_format_id format_id, unsigned int access, unsigned int bind_flags,
         const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops)
 {
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
         const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops)
 {
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@@ -1347,9 +1370,8 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
         return E_INVALIDARG;
     }
 
         return E_INVALIDARG;
     }
 
-    hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format,
-            WINED3D_MULTISAMPLE_NONE, 0, usage, pool, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops);
-    if (FAILED(hr))
+    if (FAILED(hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format, WINED3D_MULTISAMPLE_NONE,
+            0, usage, access, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops)))
     {
         WARN("Failed to initialize resource, hr %#x.\n", hr);
         return hr;
     {
         WARN("Failed to initialize resource, hr %#x.\n", hr);
         return hr;
@@ -1362,7 +1384,8 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
             buffer, buffer->resource.size, buffer->resource.usage,
             debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory);
 
             buffer, buffer->resource.size, buffer->resource.usage,
             debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory);
 
-    if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING || pool == WINED3D_POOL_MANAGED)
+    if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING
+            || wined3d_resource_access_is_managed(access))
     {
         /* SWvp and managed buffers always return the same pointer in buffer
          * maps and retain data in DISCARD maps. Keep a system memory copy of
     {
         /* SWvp and managed buffers always return the same pointer in buffer
          * maps and retain data in DISCARD maps. Keep a system memory copy of
@@ -1380,9 +1403,9 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
     {
         TRACE("Not creating a BO because GL_ARB_vertex_buffer is not supported.\n");
     }
     {
         TRACE("Not creating a BO because GL_ARB_vertex_buffer is not supported.\n");
     }
-    else if (buffer->resource.pool == WINED3D_POOL_SYSTEM_MEM)
+    else if (!(access & WINED3D_RESOURCE_ACCESS_GPU))
     {
     {
-        TRACE("Not creating a BO because the buffer is in system memory.\n");
+        TRACE("Not creating a BO because the buffer is not GPU accessible.\n");
     }
     else if (!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
     {
     }
     else if (!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
     {
@@ -1393,7 +1416,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
         buffer->flags |= WINED3D_BUFFER_USE_BO;
     }
 
         buffer->flags |= WINED3D_BUFFER_USE_BO;
     }
 
-    if (!(buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps))))
+    if (!(buffer->maps = heap_alloc(sizeof(*buffer->maps))))
     {
         ERR("Out of memory.\n");
         buffer_unload(&buffer->resource);
     {
         ERR("Out of memory.\n");
         buffer_unload(&buffer->resource);
@@ -1420,16 +1443,14 @@ HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct
     TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n",
             device, desc, data, parent, parent_ops, buffer);
 
     TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n",
             device, desc, data, parent, parent_ops, buffer);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
         return E_OUTOFMEMORY;
 
-    FIXME("Ignoring access flags (pool).\n");
-
     if (FAILED(hr = buffer_init(object, device, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN,
     if (FAILED(hr = buffer_init(object, device, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN,
-            WINED3D_POOL_MANAGED, desc->bind_flags, data, parent, parent_ops)))
+            desc->access, desc->bind_flags, data, parent, parent_ops)))
     {
         WARN("Failed to initialize buffer, hr %#x.\n", hr);
     {
         WARN("Failed to initialize buffer, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
     object->desc = *desc;
         return hr;
     }
     object->desc = *desc;
@@ -1440,75 +1461,3 @@ HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
-
-HRESULT CDECL wined3d_buffer_create_vb(struct wined3d_device *device, UINT size, DWORD usage, enum wined3d_pool pool,
-        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)
-{
-    struct wined3d_buffer *object;
-    HRESULT hr;
-
-    TRACE("device %p, size %u, usage %#x, pool %#x, parent %p, parent_ops %p, buffer %p.\n",
-            device, size, usage, pool, parent, parent_ops, buffer);
-
-    if (pool == WINED3D_POOL_SCRATCH)
-    {
-        /* The d3d9 tests shows that this is not allowed. It doesn't make much
-         * sense anyway, SCRATCH buffers wouldn't be usable anywhere. */
-        WARN("Vertex buffer in WINED3D_POOL_SCRATCH requested, returning WINED3DERR_INVALIDCALL.\n");
-        *buffer = NULL;
-        return WINED3DERR_INVALIDCALL;
-    }
-
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
-    {
-        *buffer = NULL;
-        return WINED3DERR_OUTOFVIDEOMEMORY;
-    }
-
-    hr = buffer_init(object, device, size, usage, WINED3DFMT_UNKNOWN,
-            pool, WINED3D_BIND_VERTEX_BUFFER, NULL, parent, parent_ops);
-    if (FAILED(hr))
-    {
-        WARN("Failed to initialize buffer, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
-        return hr;
-    }
-
-    TRACE("Created buffer %p.\n", object);
-    *buffer = object;
-
-    return WINED3D_OK;
-}
-
-HRESULT CDECL wined3d_buffer_create_ib(struct wined3d_device *device, UINT size, DWORD usage, enum wined3d_pool pool,
-        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)
-{
-    struct wined3d_buffer *object;
-    HRESULT hr;
-
-    TRACE("device %p, size %u, usage %#x, pool %#x, parent %p, parent_ops %p, buffer %p.\n",
-            device, size, usage, pool, parent, parent_ops, buffer);
-
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
-    {
-        *buffer = NULL;
-        return WINED3DERR_OUTOFVIDEOMEMORY;
-    }
-
-    hr = buffer_init(object, device, size, usage | WINED3DUSAGE_STATICDECL,
-            WINED3DFMT_UNKNOWN, pool, WINED3D_BIND_INDEX_BUFFER, NULL,
-            parent, parent_ops);
-    if (FAILED(hr))
-    {
-        WARN("Failed to initialize buffer, hr %#x\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
-        return hr;
-    }
-
-    TRACE("Created buffer %p.\n", object);
-    *buffer = object;
-
-    return WINED3D_OK;
-}
index bd0ae56..8a8d952 100644 (file)
@@ -1,6 +1,11 @@
 /*
  * Context and render target management in wined3d
  *
 /*
  * Context and render target management in wined3d
  *
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2002-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006, 2008 Henri Verbeet
  * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
  * Copyright 2009-2011 Henri Verbeet for CodeWeavers
  *
  * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
  * Copyright 2009-2011 Henri Verbeet for CodeWeavers
  *
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
 #include "wined3d_private.h"
 
 #include "wined3d_private.h"
 
+#ifdef __REACTOS__
+#include <reactos/undocuser.h>
+#endif
+
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_synchronous);
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_synchronous);
@@ -131,7 +148,8 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
         gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment,
                 resource->object, resource->level);
     }
         gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment,
                 resource->object, resource->level);
     }
-    else if (resource->target == GL_TEXTURE_2D_ARRAY || resource->target == GL_TEXTURE_3D)
+    else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY ||
+            resource->target == GL_TEXTURE_3D)
     {
         if (!gl_info->fbo_ops.glFramebufferTextureLayer)
         {
     {
         if (!gl_info->fbo_ops.glFramebufferTextureLayer)
         {
@@ -142,6 +160,12 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
         gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment,
                 resource->object, resource->level, resource->layer);
     }
         gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment,
                 resource->object, resource->level, resource->layer);
     }
+    else if (resource->target == GL_TEXTURE_1D)
+    {
+        gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment,
+                resource->target, resource->object, resource->level);
+        checkGLcall("glFramebufferTexture1D()");
+    }
     else
     {
         gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment,
     else
     {
         gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment,
@@ -200,7 +224,6 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
 
     if (resource->object)
     {
 
     if (resource->object)
     {
-
         if (rb_namespace)
         {
             gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
         if (rb_namespace)
         {
             gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
@@ -230,12 +253,17 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G
     }
     texture_type[] =
     {
     }
     texture_type[] =
     {
-        {GL_TEXTURE_2D,            GL_TEXTURE_BINDING_2D,            "2d",        WINED3D_GL_EXT_NONE},
-        {GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BINDING_RECTANGLE_ARB, "rectangle", ARB_TEXTURE_RECTANGLE},
-        {GL_TEXTURE_2D_ARRAY,      GL_TEXTURE_BINDING_2D_ARRAY,      "2d-array",  EXT_TEXTURE_ARRAY},
+        {GL_TEXTURE_2D,                   GL_TEXTURE_BINDING_2D,                   "2d",          WINED3D_GL_EXT_NONE},
+        {GL_TEXTURE_RECTANGLE_ARB,        GL_TEXTURE_BINDING_RECTANGLE_ARB,        "rectangle",   ARB_TEXTURE_RECTANGLE},
+        {GL_TEXTURE_2D_ARRAY,             GL_TEXTURE_BINDING_2D_ARRAY,             "2d-array" ,   EXT_TEXTURE_ARRAY},
+        {GL_TEXTURE_CUBE_MAP,             GL_TEXTURE_BINDING_CUBE_MAP,             "cube",        ARB_TEXTURE_CUBE_MAP},
+        {GL_TEXTURE_2D_MULTISAMPLE,       GL_TEXTURE_BINDING_2D_MULTISAMPLE,       "2d-ms",       ARB_TEXTURE_MULTISAMPLE},
+        {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, "2d-array-ms", ARB_TEXTURE_MULTISAMPLE},
     };
 
     GLint type, name, samples, width, height, old_texture, level, face, fmt, tex_target;
     };
 
     GLint type, name, samples, width, height, old_texture, level, face, fmt, tex_target;
+    const char *tex_type_str;
+    unsigned int i;
 
     gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
             GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name);
 
     gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
             GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name);
@@ -257,30 +285,38 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G
     }
     else if (type == GL_TEXTURE)
     {
     }
     else if (type == GL_TEXTURE)
     {
-        const char *tex_type_str;
-
         gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
                 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &level);
         gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
                 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &face);
 
         gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
                 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &level);
         gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
                 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &face);
 
-        if (face)
+        if (gl_info->gl_ops.ext.p_glGetTextureParameteriv)
         {
         {
-            gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &old_texture);
+            GL_EXTCALL(glGetTextureParameteriv(name, GL_TEXTURE_TARGET, &tex_target));
 
 
+            for (i = 0; i < ARRAY_SIZE(texture_type); ++i)
+            {
+                if (texture_type[i].target == tex_target)
+                {
+                    tex_type_str = texture_type[i].str;
+                    break;
+                }
+            }
+            if (i == ARRAY_SIZE(texture_type))
+                tex_type_str = wine_dbg_sprintf("%#x", tex_target);
+        }
+        else if (face)
+        {
+            gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &old_texture);
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, name);
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, name);
-            gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
-            gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_WIDTH, &width);
-            gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_HEIGHT, &height);
 
             tex_target = GL_TEXTURE_CUBE_MAP;
             tex_type_str = "cube";
         }
         else
         {
 
             tex_target = GL_TEXTURE_CUBE_MAP;
             tex_type_str = "cube";
         }
         else
         {
-            unsigned int i;
-
             tex_type_str = NULL;
             tex_type_str = NULL;
+
             for (i = 0; i < ARRAY_SIZE(texture_type); ++i)
             {
                 if (!gl_info->supported[texture_type[i].extension])
             for (i = 0; i < ARRAY_SIZE(texture_type); ++i)
             {
                 if (!gl_info->supported[texture_type[i].extension])
@@ -298,22 +334,36 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G
                 }
                 gl_info->gl_ops.gl.p_glBindTexture(texture_type[i].target, old_texture);
             }
                 }
                 gl_info->gl_ops.gl.p_glBindTexture(texture_type[i].target, old_texture);
             }
+
             if (!tex_type_str)
             {
                 FIXME("Cannot find type of texture %d.\n", name);
                 return;
             }
             if (!tex_type_str)
             {
                 FIXME("Cannot find type of texture %d.\n", name);
                 return;
             }
+        }
 
 
+        if (gl_info->gl_ops.ext.p_glGetTextureParameteriv)
+        {
+            GL_EXTCALL(glGetTextureLevelParameteriv(name, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt));
+            GL_EXTCALL(glGetTextureLevelParameteriv(name, level, GL_TEXTURE_WIDTH, &width));
+            GL_EXTCALL(glGetTextureLevelParameteriv(name, level, GL_TEXTURE_HEIGHT, &height));
+            GL_EXTCALL(glGetTextureLevelParameteriv(name, level, GL_TEXTURE_SAMPLES, &samples));
+        }
+        else
+        {
             gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
             gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_WIDTH, &width);
             gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_HEIGHT, &height);
             gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
             gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_WIDTH, &width);
             gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_HEIGHT, &height);
-        }
+            if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+                gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_SAMPLES, &samples);
+            else
+                samples = 1;
 
 
-        FIXME("    %s: %s texture %d, %dx%d, format %#x.\n", debug_fboattachment(attachment),
-                tex_type_str, name, width, height, fmt);
+            gl_info->gl_ops.gl.p_glBindTexture(tex_target, old_texture);
+        }
 
 
-        gl_info->gl_ops.gl.p_glBindTexture(tex_target, old_texture);
-        checkGLcall("Guess texture type");
+        FIXME("    %s: %s texture %d, %dx%d, %d samples, format %#x.\n",
+                debug_fboattachment(attachment), tex_type_str, name, width, height, samples, fmt);
     }
     else if (type == GL_NONE)
     {
     }
     else if (type == GL_NONE)
     {
@@ -323,6 +373,8 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G
     {
         ERR("    %s: Unknown attachment %#x.\n", debug_fboattachment(attachment), type);
     }
     {
         ERR("    %s: Unknown attachment %#x.\n", debug_fboattachment(attachment), type);
     }
+
+    checkGLcall("dump FBO attachment");
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -331,18 +383,19 @@ void context_check_fbo_status(const struct wined3d_context *context, GLenum targ
     const struct wined3d_gl_info *gl_info = context->gl_info;
     GLenum status;
 
     const struct wined3d_gl_info *gl_info = context->gl_info;
     GLenum status;
 
-    if (!FIXME_ON(d3d)) return;
+    if (!FIXME_ON(d3d))
+        return;
 
     status = gl_info->fbo_ops.glCheckFramebufferStatus(target);
     if (status == GL_FRAMEBUFFER_COMPLETE)
     {
 
     status = gl_info->fbo_ops.glCheckFramebufferStatus(target);
     if (status == GL_FRAMEBUFFER_COMPLETE)
     {
-        TRACE("FBO complete\n");
+        TRACE("FBO complete.\n");
     }
     else
     {
         unsigned int i;
 
     }
     else
     {
         unsigned int i;
 
-        FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status);
+        FIXME("FBO status %s (%#x).\n", debug_fbostatus(status), status);
 
         if (!context->current_fbo)
         {
 
         if (!context->current_fbo)
         {
@@ -355,7 +408,6 @@ void context_check_fbo_status(const struct wined3d_context *context, GLenum targ
 
         for (i = 0; i < gl_info->limits.buffers; ++i)
             context_dump_fbo_attachment(gl_info, target, GL_COLOR_ATTACHMENT0 + i);
 
         for (i = 0; i < gl_info->limits.buffers; ++i)
             context_dump_fbo_attachment(gl_info, target, GL_COLOR_ATTACHMENT0 + i);
-        checkGLcall("Dump FBO attachments");
     }
 }
 
     }
 }
 
@@ -377,7 +429,7 @@ static inline DWORD context_generate_rt_mask_from_resource(struct wined3d_resour
 }
 
 static inline void context_set_fbo_key_for_render_target(const struct wined3d_context *context,
 }
 
 static inline void context_set_fbo_key_for_render_target(const struct wined3d_context *context,
-        struct wined3d_fbo_entry_key *key, unsigned int idx, struct wined3d_rendertarget_info *render_target,
+        struct wined3d_fbo_entry_key *key, unsigned int idx, const struct wined3d_rendertarget_info *render_target,
         DWORD location)
 {
     unsigned int sub_resource_idx = render_target->sub_resource_idx;
         DWORD location)
 {
     unsigned int sub_resource_idx = render_target->sub_resource_idx;
@@ -416,17 +468,11 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co
             key->rb_namespace |= 1 << idx;
             return;
         }
             key->rb_namespace |= 1 << idx;
             return;
         }
-
-        key->objects[idx].target = surface->texture_target;
-        key->objects[idx].level = surface->texture_level;
-        key->objects[idx].layer = surface->texture_layer;
-    }
-    else
-    {
-        key->objects[idx].target = texture->target;
-        key->objects[idx].level = sub_resource_idx % texture->level_count;
-        key->objects[idx].layer = sub_resource_idx / texture->level_count;
     }
     }
+    key->objects[idx].target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+    key->objects[idx].level = sub_resource_idx % texture->level_count;
+    key->objects[idx].layer = sub_resource_idx / texture->level_count;
+
     if (render_target->layer_count != 1)
         key->objects[idx].layer = WINED3D_ALL_LAYERS;
 
     if (render_target->layer_count != 1)
         key->objects[idx].layer = WINED3D_ALL_LAYERS;
 
@@ -457,44 +503,36 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co
 }
 
 static void context_generate_fbo_key(const struct wined3d_context *context,
 }
 
 static void context_generate_fbo_key(const struct wined3d_context *context,
-        struct wined3d_fbo_entry_key *key, struct wined3d_rendertarget_info *render_targets,
-        struct wined3d_surface *depth_stencil_surface, DWORD color_location,
-        DWORD ds_location)
+        struct wined3d_fbo_entry_key *key, const struct wined3d_rendertarget_info *render_targets,
+        const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location)
 {
 {
-    struct wined3d_rendertarget_info depth_stencil = {{0}};
+    unsigned int buffers = context->gl_info->limits.buffers;
     unsigned int i;
 
     key->rb_namespace = 0;
     unsigned int i;
 
     key->rb_namespace = 0;
-    if (depth_stencil_surface)
-    {
-        depth_stencil.resource = &depth_stencil_surface->container->resource;
-        depth_stencil.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil_surface);
-        depth_stencil.layer_count = 1;
-    }
-    context_set_fbo_key_for_render_target(context, key, 0, &depth_stencil, ds_location);
+    context_set_fbo_key_for_render_target(context, key, 0, depth_stencil, ds_location);
 
 
-    for (i = 0; i < context->gl_info->limits.buffers; ++i)
+    for (i = 0; i < buffers; ++i)
         context_set_fbo_key_for_render_target(context, key, i + 1, &render_targets[i], color_location);
         context_set_fbo_key_for_render_target(context, key, i + 1, &render_targets[i], color_location);
+
+    memset(&key->objects[buffers + 1], 0, (ARRAY_SIZE(key->objects) - buffers - 1) * sizeof(*key->objects));
 }
 
 static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
 }
 
 static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
-        struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
+        const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil,
         DWORD color_location, DWORD ds_location)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
         DWORD color_location, DWORD ds_location)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int object_count = gl_info->limits.buffers + 1;
     struct fbo_entry *entry;
 
     struct fbo_entry *entry;
 
-    entry = HeapAlloc(GetProcessHeap(), 0,
-            FIELD_OFFSET(struct fbo_entry, key.objects[object_count]));
-    memset(&entry->key, 0, FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[object_count]));
+    entry = heap_alloc(sizeof(*entry));
     context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location);
     entry->flags = 0;
     context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location);
     entry->flags = 0;
-    if (depth_stencil)
+    if (depth_stencil->resource)
     {
     {
-        if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_DEPTH)
+        if (depth_stencil->resource->format_flags & WINED3DFMT_FLAG_DEPTH)
             entry->flags |= WINED3D_FBO_ENTRY_FLAG_DEPTH;
             entry->flags |= WINED3D_FBO_ENTRY_FLAG_DEPTH;
-        if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_STENCIL)
+        if (depth_stencil->resource->format_flags & WINED3DFMT_FLAG_STENCIL)
             entry->flags |= WINED3D_FBO_ENTRY_FLAG_STENCIL;
     }
     entry->rt_mask = context_generate_rt_mask(GL_COLOR_ATTACHMENT0);
             entry->flags |= WINED3D_FBO_ENTRY_FLAG_STENCIL;
     }
     entry->rt_mask = context_generate_rt_mask(GL_COLOR_ATTACHMENT0);
@@ -507,7 +545,7 @@ static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *
 
 /* Context activation is done by the caller. */
 static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target,
 
 /* Context activation is done by the caller. */
 static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target,
-        struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
+        const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil,
         DWORD color_location, DWORD ds_location, struct fbo_entry *entry)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
         DWORD color_location, DWORD ds_location, struct fbo_entry *entry)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -517,11 +555,11 @@ static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum targ
 
     context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location);
     entry->flags = 0;
 
     context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location);
     entry->flags = 0;
-    if (depth_stencil)
+    if (depth_stencil->resource)
     {
     {
-        if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_DEPTH)
+        if (depth_stencil->resource->format_flags & WINED3DFMT_FLAG_DEPTH)
             entry->flags |= WINED3D_FBO_ENTRY_FLAG_DEPTH;
             entry->flags |= WINED3D_FBO_ENTRY_FLAG_DEPTH;
-        if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_STENCIL)
+        if (depth_stencil->resource->format_flags & WINED3DFMT_FLAG_STENCIL)
             entry->flags |= WINED3D_FBO_ENTRY_FLAG_STENCIL;
     }
 }
             entry->flags |= WINED3D_FBO_ENTRY_FLAG_STENCIL;
     }
 }
@@ -536,33 +574,36 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb
     }
     --context->fbo_entry_count;
     list_remove(&entry->entry);
     }
     --context->fbo_entry_count;
     list_remove(&entry->entry);
-    HeapFree(GetProcessHeap(), 0, entry);
+    heap_free(entry);
 }
 
 /* Context activation is done by the caller. */
 static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target,
 }
 
 /* Context activation is done by the caller. */
 static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target,
-        struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
+        const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil,
         DWORD color_location, DWORD ds_location)
 {
         DWORD color_location, DWORD ds_location)
 {
+    static const struct wined3d_rendertarget_info ds_null = {{0}};
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int object_count = gl_info->limits.buffers + 1;
     struct wined3d_texture *rt_texture, *ds_texture;
     struct wined3d_texture *rt_texture, *ds_texture;
+    struct wined3d_fbo_entry_key fbo_key;
+    unsigned int i, ds_level, rt_level;
     struct fbo_entry *entry;
     struct fbo_entry *entry;
-    unsigned int i, level;
 
 
-    if (depth_stencil && render_targets[0].resource && render_targets[0].resource->type != WINED3D_RTYPE_BUFFER)
+    if (depth_stencil->resource && depth_stencil->resource->type != WINED3D_RTYPE_BUFFER
+            && render_targets[0].resource && render_targets[0].resource->type != WINED3D_RTYPE_BUFFER)
     {
         rt_texture = wined3d_texture_from_resource(render_targets[0].resource);
     {
         rt_texture = wined3d_texture_from_resource(render_targets[0].resource);
-        level = render_targets[0].sub_resource_idx % rt_texture->level_count;
-        ds_texture = depth_stencil->container;
-
-        if (wined3d_texture_get_level_width(ds_texture, depth_stencil->texture_level)
-                < wined3d_texture_get_level_width(rt_texture, level)
-                || wined3d_texture_get_level_height(ds_texture, depth_stencil->texture_level)
-                < wined3d_texture_get_level_height(rt_texture, level))
+        rt_level = render_targets[0].sub_resource_idx % rt_texture->level_count;
+        ds_texture = wined3d_texture_from_resource(depth_stencil->resource);
+        ds_level = depth_stencil->sub_resource_idx % ds_texture->level_count;
+
+        if (wined3d_texture_get_level_width(ds_texture, ds_level)
+                < wined3d_texture_get_level_width(rt_texture, rt_level)
+                || wined3d_texture_get_level_height(ds_texture, ds_level)
+                < wined3d_texture_get_level_height(rt_texture, rt_level))
         {
             WARN("Depth stencil is smaller than the primary color buffer, disabling.\n");
         {
             WARN("Depth stencil is smaller than the primary color buffer, disabling.\n");
-            depth_stencil = NULL;
+            depth_stencil = &ds_null;
         }
         else if (ds_texture->resource.multisample_type != rt_texture->resource.multisample_type
                 || ds_texture->resource.multisample_quality != rt_texture->resource.multisample_quality)
         }
         else if (ds_texture->resource.multisample_type != rt_texture->resource.multisample_type
                 || ds_texture->resource.multisample_quality != rt_texture->resource.multisample_quality)
@@ -570,26 +611,30 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
             WARN("Color multisample type %u and quality %u, depth stencil has %u and %u, disabling ds buffer.\n",
                     rt_texture->resource.multisample_type, rt_texture->resource.multisample_quality,
                     ds_texture->resource.multisample_type, ds_texture->resource.multisample_quality);
             WARN("Color multisample type %u and quality %u, depth stencil has %u and %u, disabling ds buffer.\n",
                     rt_texture->resource.multisample_type, rt_texture->resource.multisample_quality,
                     ds_texture->resource.multisample_type, ds_texture->resource.multisample_quality);
-            depth_stencil = NULL;
+            depth_stencil = &ds_null;
+        }
+        else if (depth_stencil->resource->type == WINED3D_RTYPE_TEXTURE_2D)
+        {
+            struct wined3d_surface *surface;
+
+            surface = ds_texture->sub_resources[depth_stencil->sub_resource_idx].u.surface;
+            surface_set_compatible_renderbuffer(surface, &render_targets[0]);
         }
         }
-        else
-            surface_set_compatible_renderbuffer(depth_stencil, &render_targets[0]);
     }
 
     }
 
-    context_generate_fbo_key(context, context->fbo_key, render_targets, depth_stencil, color_location,
-            ds_location);
+    context_generate_fbo_key(context, &fbo_key, render_targets, depth_stencil, color_location, ds_location);
 
     if (TRACE_ON(d3d))
     {
 
     if (TRACE_ON(d3d))
     {
+        struct wined3d_resource *resource;
+        unsigned int width, height;
+        const char *resource_type;
+
         TRACE("Dumping FBO attachments:\n");
         for (i = 0; i < gl_info->limits.buffers; ++i)
         {
         TRACE("Dumping FBO attachments:\n");
         for (i = 0; i < gl_info->limits.buffers; ++i)
         {
-            struct wined3d_resource *resource;
             if ((resource = render_targets[i].resource))
             {
             if ((resource = render_targets[i].resource))
             {
-                unsigned int width, height;
-                const char *resource_type;
-
                 if (resource->type == WINED3D_RTYPE_BUFFER)
                 {
                     width = resource->size;
                 if (resource->type == WINED3D_RTYPE_BUFFER)
                 {
                     width = resource->size;
@@ -599,34 +644,45 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
                 else
                 {
                     rt_texture = wined3d_texture_from_resource(resource);
                 else
                 {
                     rt_texture = wined3d_texture_from_resource(resource);
-                    level = render_targets[i].sub_resource_idx % rt_texture->level_count;
-                    width = wined3d_texture_get_level_pow2_width(rt_texture, level);
-                    height = wined3d_texture_get_level_pow2_height(rt_texture, level);
+                    rt_level = render_targets[i].sub_resource_idx % rt_texture->level_count;
+                    width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level);
+                    height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level);
                     resource_type = "texture";
                 }
 
                 TRACE("    Color attachment %u: %p, %u format %s, %s %u, %ux%u, %u samples.\n",
                         i, resource, render_targets[i].sub_resource_idx, debug_d3dformat(resource->format->id),
                     resource_type = "texture";
                 }
 
                 TRACE("    Color attachment %u: %p, %u format %s, %s %u, %ux%u, %u samples.\n",
                         i, resource, render_targets[i].sub_resource_idx, debug_d3dformat(resource->format->id),
-                        context->fbo_key->rb_namespace & (1 << (i + 1)) ? "renderbuffer" : resource_type,
-                        context->fbo_key->objects[i + 1].object, width, height, resource->multisample_type);
+                        fbo_key.rb_namespace & (1 << (i + 1)) ? "renderbuffer" : resource_type,
+                        fbo_key.objects[i + 1].object, width, height, resource->multisample_type);
             }
         }
             }
         }
-        if (depth_stencil)
+        if ((resource = depth_stencil->resource))
         {
         {
-            ds_texture = depth_stencil->container;
-            TRACE("    Depth attachment: %p format %s, %s %u, %ux%u, %u samples.\n",
-                    depth_stencil, debug_d3dformat(ds_texture->resource.format->id),
-                    context->fbo_key->rb_namespace & (1 << 0) ? "renderbuffer" : "texture",
-                    context->fbo_key->objects[0].object,
-                    wined3d_texture_get_level_pow2_width(ds_texture, depth_stencil->texture_level),
-                    wined3d_texture_get_level_pow2_height(ds_texture, depth_stencil->texture_level),
-                    ds_texture->resource.multisample_type);
+            if (resource->type == WINED3D_RTYPE_BUFFER)
+            {
+                width = resource->size;
+                height = 1;
+                resource_type = "buffer";
+            }
+            else
+            {
+                ds_texture = wined3d_texture_from_resource(resource);
+                ds_level = depth_stencil->sub_resource_idx % ds_texture->level_count;
+                width = wined3d_texture_get_level_pow2_width(ds_texture, ds_level);
+                height = wined3d_texture_get_level_pow2_height(ds_texture, ds_level);
+                resource_type = "texture";
+            }
+
+            TRACE("    Depth attachment: %p, %u format %s, %s %u, %ux%u, %u samples.\n",
+                    resource, depth_stencil->sub_resource_idx, debug_d3dformat(resource->format->id),
+                    fbo_key.rb_namespace & (1 << 0) ? "renderbuffer" : resource_type,
+                    fbo_key.objects[0].object, width, height, resource->multisample_type);
         }
     }
 
     LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
     {
         }
     }
 
     LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
     {
-        if (memcmp(context->fbo_key, &entry->key, FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[object_count])))
+        if (memcmp(&fbo_key, &entry->key, sizeof(fbo_key)))
             continue;
 
         list_remove(&entry->entry);
             continue;
 
         list_remove(&entry->entry);
@@ -655,8 +711,8 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
 static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int i;
     GLuint read_binding, draw_binding;
     GLuint read_binding, draw_binding;
+    unsigned int i;
 
     if (entry->flags & WINED3D_FBO_ENTRY_FLAG_ATTACHED)
     {
 
     if (entry->flags & WINED3D_FBO_ENTRY_FLAG_ATTACHED)
     {
@@ -668,6 +724,16 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ
     draw_binding = context->fbo_draw_binding;
     context_bind_fbo(context, GL_FRAMEBUFFER, entry->id);
 
     draw_binding = context->fbo_draw_binding;
     context_bind_fbo(context, GL_FRAMEBUFFER, entry->id);
 
+    if (gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS])
+    {
+        GL_EXTCALL(glFramebufferParameteri(GL_FRAMEBUFFER,
+                GL_FRAMEBUFFER_DEFAULT_WIDTH, gl_info->limits.framebuffer_width));
+        GL_EXTCALL(glFramebufferParameteri(GL_FRAMEBUFFER,
+                GL_FRAMEBUFFER_DEFAULT_HEIGHT, gl_info->limits.framebuffer_height));
+        GL_EXTCALL(glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_LAYERS, 1));
+        GL_EXTCALL(glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, 1));
+    }
+
     /* Apply render targets */
     for (i = 0; i < gl_info->limits.buffers; ++i)
     {
     /* Apply render targets */
     for (i = 0; i < gl_info->limits.buffers; ++i)
     {
@@ -718,8 +784,16 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ
     }
     else
     {
     }
     else
     {
-        context->current_fbo = context_find_fbo_entry(context, target, render_targets, depth_stencil,
-                color_location, ds_location);
+        struct wined3d_rendertarget_info ds = {{0}};
+
+        if (depth_stencil)
+        {
+            ds.resource = &depth_stencil->container->resource;
+            ds.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil);
+            ds.layer_count = 1;
+        }
+        context->current_fbo = context_find_fbo_entry(context, target,
+                render_targets, &ds, color_location, ds_location);
         context_apply_fbo_entry(context, target, context->current_fbo);
     }
 }
         context_apply_fbo_entry(context, target, context->current_fbo);
     }
 }
@@ -728,7 +802,7 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ
 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
         struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location)
 {
 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
         struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location)
 {
-    memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof(*context->blit_targets));
+    memset(context->blit_targets, 0, sizeof(context->blit_targets));
     if (render_target)
     {
         context->blit_targets[0].resource = &render_target->container->resource;
     if (render_target)
     {
         context->blit_targets[0].resource = &render_target->container->resource;
@@ -967,7 +1041,7 @@ typedef void (context_fbo_entry_func_t)(struct wined3d_context *context, struct
 static void context_enum_fbo_entries(const struct wined3d_device *device,
         GLuint name, BOOL rb_namespace, context_fbo_entry_func_t *callback)
 {
 static void context_enum_fbo_entries(const struct wined3d_device *device,
         GLuint name, BOOL rb_namespace, context_fbo_entry_func_t *callback)
 {
-    UINT i;
+    unsigned int i, j;
 
     for (i = 0; i < device->context_count; ++i)
     {
 
     for (i = 0; i < device->context_count; ++i)
     {
@@ -977,8 +1051,6 @@ static void context_enum_fbo_entries(const struct wined3d_device *device,
 
         LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
         {
 
         LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
         {
-            UINT j;
-
             for (j = 0; j < gl_info->limits.buffers + 1; ++j)
             {
                 if (entry->key.objects[j].object == name
             for (j = 0; j < gl_info->limits.buffers + 1; ++j)
             {
                 if (entry->key.objects[j].object == name
@@ -1397,11 +1469,11 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
         checkGLcall("context cleanup");
     }
 
         checkGLcall("context cleanup");
     }
 
-    HeapFree(GetProcessHeap(), 0, context->free_so_statistics_queries);
-    HeapFree(GetProcessHeap(), 0, context->free_pipeline_statistics_queries);
-    HeapFree(GetProcessHeap(), 0, context->free_timestamp_queries);
-    HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
-    HeapFree(GetProcessHeap(), 0, context->free_fences);
+    heap_free(context->free_so_statistics_queries);
+    heap_free(context->free_pipeline_statistics_queries);
+    heap_free(context->free_timestamp_queries);
+    heap_free(context->free_occlusion_queries);
+    heap_free(context->free_fences);
 
     context_restore_pixel_format(context);
     if (restore_ctx)
 
     context_restore_pixel_format(context);
     if (restore_ctx)
@@ -1453,8 +1525,8 @@ BOOL context_set_current(struct wined3d_context *ctx)
         {
             TRACE("Switching away from destroyed context %p.\n", old);
             context_destroy_gl_resources(old);
         {
             TRACE("Switching away from destroyed context %p.\n", old);
             context_destroy_gl_resources(old);
-            HeapFree(GetProcessHeap(), 0, (void *)old->gl_info);
-            HeapFree(GetProcessHeap(), 0, old);
+            heap_free((void *)old->gl_info);
+            heap_free(old);
         }
         else
         {
         }
         else
         {
@@ -1691,36 +1763,45 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC
 /* Context activation is done by the caller. */
 void context_bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context)
 {
 /* Context activation is done by the caller. */
 void context_bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context)
 {
+    const struct wined3d_dummy_textures *textures = &context->device->dummy_textures;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int i;
 
     for (i = 0; i < gl_info->limits.combined_samplers; ++i)
     {
         GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i));
     const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int i;
 
     for (i = 0; i < gl_info->limits.combined_samplers; ++i)
     {
         GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i));
-        checkGLcall("glActiveTexture");
 
 
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
 
         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
 
         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
-            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect);
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures->tex_rect);
 
         if (gl_info->supported[EXT_TEXTURE3D])
 
         if (gl_info->supported[EXT_TEXTURE3D])
-            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d);
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, textures->tex_3d);
 
         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
 
         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
-            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube);
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, textures->tex_cube);
 
         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
 
         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
-            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, device->dummy_textures.tex_cube_array);
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures->tex_cube_array);
 
         if (gl_info->supported[EXT_TEXTURE_ARRAY])
 
         if (gl_info->supported[EXT_TEXTURE_ARRAY])
-            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array);
-
+        {
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
+        }
         if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
         if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
-            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, device->dummy_textures.tex_buffer);
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer);
 
 
-        checkGLcall("Bind dummy textures");
+        if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+        {
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textures->tex_2d_ms);
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, textures->tex_2d_ms_array);
+        }
     }
     }
+
+    checkGLcall("bind dummy textures");
 }
 
 void wined3d_check_gl_call(const struct wined3d_gl_info *gl_info,
 }
 
 void wined3d_check_gl_call(const struct wined3d_gl_info *gl_info,
@@ -1825,35 +1906,23 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
 
     wined3d_from_cs(device->cs);
 
 
     wined3d_from_cs(device->cs);
 
-    ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
-    if (!ret)
+    if (!(ret = heap_alloc_zero(sizeof(*ret))))
         return NULL;
 
         return NULL;
 
-    if (!(ret->blit_targets = wined3d_calloc(gl_info->limits.buffers, sizeof(*ret->blit_targets))))
-        goto out;
-
-    if (!(ret->draw_buffers = wined3d_calloc(gl_info->limits.buffers, sizeof(*ret->draw_buffers))))
-        goto out;
-
-    ret->fbo_key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-            FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[gl_info->limits.buffers + 1]));
-    if (!ret->fbo_key)
-        goto out;
-
     ret->free_timestamp_query_size = 4;
     ret->free_timestamp_query_size = 4;
-    if (!(ret->free_timestamp_queries = wined3d_calloc(ret->free_timestamp_query_size,
+    if (!(ret->free_timestamp_queries = heap_calloc(ret->free_timestamp_query_size,
             sizeof(*ret->free_timestamp_queries))))
         goto out;
     list_init(&ret->timestamp_queries);
 
     ret->free_occlusion_query_size = 4;
             sizeof(*ret->free_timestamp_queries))))
         goto out;
     list_init(&ret->timestamp_queries);
 
     ret->free_occlusion_query_size = 4;
-    if (!(ret->free_occlusion_queries = wined3d_calloc(ret->free_occlusion_query_size,
+    if (!(ret->free_occlusion_queries = heap_calloc(ret->free_occlusion_query_size,
             sizeof(*ret->free_occlusion_queries))))
         goto out;
     list_init(&ret->occlusion_queries);
 
     ret->free_fence_size = 4;
             sizeof(*ret->free_occlusion_queries))))
         goto out;
     list_init(&ret->occlusion_queries);
 
     ret->free_fence_size = 4;
-    if (!(ret->free_fences = wined3d_calloc(ret->free_fence_size, sizeof(*ret->free_fences))))
+    if (!(ret->free_fences = heap_calloc(ret->free_fence_size, sizeof(*ret->free_fences))))
         goto out;
     list_init(&ret->fences);
 
         goto out;
     list_init(&ret->fences);
 
@@ -1909,7 +1978,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
         }
     }
 
         }
     }
 
-    if (!(ret->texture_type = wined3d_calloc(gl_info->limits.combined_samplers,
+    if (!(ret->texture_type = heap_calloc(gl_info->limits.combined_samplers,
             sizeof(*ret->texture_type))))
         goto out;
 
             sizeof(*ret->texture_type))))
         goto out;
 
@@ -2210,14 +2279,11 @@ out:
         wined3d_release_dc(swapchain->win_handle, ret->hdc);
     device->shader_backend->shader_free_context_data(ret);
     device->adapter->fragment_pipe->free_context_data(ret);
         wined3d_release_dc(swapchain->win_handle, ret->hdc);
     device->shader_backend->shader_free_context_data(ret);
     device->adapter->fragment_pipe->free_context_data(ret);
-    HeapFree(GetProcessHeap(), 0, ret->texture_type);
-    HeapFree(GetProcessHeap(), 0, ret->free_fences);
-    HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
-    HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries);
-    HeapFree(GetProcessHeap(), 0, ret->fbo_key);
-    HeapFree(GetProcessHeap(), 0, ret->draw_buffers);
-    HeapFree(GetProcessHeap(), 0, ret->blit_targets);
-    HeapFree(GetProcessHeap(), 0, ret);
+    heap_free(ret->texture_type);
+    heap_free(ret->free_fences);
+    heap_free(ret->free_occlusion_queries);
+    heap_free(ret->free_timestamp_queries);
+    heap_free(ret);
     return NULL;
 }
 
     return NULL;
 }
 
@@ -2250,7 +2316,7 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont
     {
         /* Make a copy of gl_info for context_destroy_gl_resources use, the one
            in wined3d_adapter may go away in the meantime */
     {
         /* Make a copy of gl_info for context_destroy_gl_resources use, the one
            in wined3d_adapter may go away in the meantime */
-        struct wined3d_gl_info *gl_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_info));
+        struct wined3d_gl_info *gl_info = heap_alloc(sizeof(*gl_info));
         *gl_info = *context->gl_info;
         context->gl_info = gl_info;
         context->destroyed = 1;
         *gl_info = *context->gl_info;
         context->gl_info = gl_info;
         context->destroyed = 1;
@@ -2259,12 +2325,10 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont
 
     device->shader_backend->shader_free_context_data(context);
     device->adapter->fragment_pipe->free_context_data(context);
 
     device->shader_backend->shader_free_context_data(context);
     device->adapter->fragment_pipe->free_context_data(context);
-    HeapFree(GetProcessHeap(), 0, context->texture_type);
-    HeapFree(GetProcessHeap(), 0, context->fbo_key);
-    HeapFree(GetProcessHeap(), 0, context->draw_buffers);
-    HeapFree(GetProcessHeap(), 0, context->blit_targets);
+    heap_free(context->texture_type);
     device_context_remove(device, context);
     device_context_remove(device, context);
-    if (destroy) HeapFree(GetProcessHeap(), 0, context);
+    if (destroy)
+        heap_free(context);
 }
 
 const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context,
 }
 
 const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context,
@@ -2360,16 +2424,16 @@ void context_enable_clip_distances(struct wined3d_context *context, unsigned int
     context->clip_distance_mask = enable_mask;
 
     enable_mask &= ~current_mask;
     context->clip_distance_mask = enable_mask;
 
     enable_mask &= ~current_mask;
-    for (i = 0; enable_mask; enable_mask >>= 1, ++i)
+    while (enable_mask)
     {
     {
-        if (enable_mask & 1)
-            gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i);
+        i = wined3d_bit_scan(&enable_mask);
+        gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i);
     }
     disable_mask &= current_mask;
     }
     disable_mask &= current_mask;
-    for (i = 0; disable_mask; disable_mask >>= 1, ++i)
+    while (disable_mask)
     {
     {
-        if (disable_mask & 1)
-            gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
+        i = wined3d_bit_scan(&disable_mask);
+        gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
     }
     checkGLcall("toggle clip distances");
 }
     }
     checkGLcall("toggle clip distances");
 }
@@ -2544,10 +2608,8 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
     }
     gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
     checkGLcall("glColorMask");
     }
     gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
     checkGLcall("glColorMask");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
+    for (i = 0; i < MAX_RENDER_TARGETS; ++i)
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
     if (gl_info->supported[EXT_SECONDARY_COLOR])
     {
         gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
     if (gl_info->supported[EXT_SECONDARY_COLOR])
     {
         gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
@@ -2590,16 +2652,15 @@ static inline GLenum draw_buffer_from_rt_mask(DWORD rt_mask)
 static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt_mask)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt_mask)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
+    GLenum draw_buffers[MAX_RENDER_TARGET_VIEWS];
 
     if (!rt_mask)
     {
         gl_info->gl_ops.gl.p_glDrawBuffer(GL_NONE);
 
     if (!rt_mask)
     {
         gl_info->gl_ops.gl.p_glDrawBuffer(GL_NONE);
-        checkGLcall("glDrawBuffer()");
     }
     else if (is_rt_mask_onscreen(rt_mask))
     {
         gl_info->gl_ops.gl.p_glDrawBuffer(draw_buffer_from_rt_mask(rt_mask));
     }
     else if (is_rt_mask_onscreen(rt_mask))
     {
         gl_info->gl_ops.gl.p_glDrawBuffer(draw_buffer_from_rt_mask(rt_mask));
-        checkGLcall("glDrawBuffer()");
     }
     else
     {
     }
     else
     {
@@ -2610,9 +2671,9 @@ static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt
             while (rt_mask)
             {
                 if (rt_mask & 1)
             while (rt_mask)
             {
                 if (rt_mask & 1)
-                    context->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i;
+                    draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i;
                 else
                 else
-                    context->draw_buffers[i] = GL_NONE;
+                    draw_buffers[i] = GL_NONE;
 
                 rt_mask >>= 1;
                 ++i;
 
                 rt_mask >>= 1;
                 ++i;
@@ -2620,13 +2681,11 @@ static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt
 
             if (gl_info->supported[ARB_DRAW_BUFFERS])
             {
 
             if (gl_info->supported[ARB_DRAW_BUFFERS])
             {
-                GL_EXTCALL(glDrawBuffers(i, context->draw_buffers));
-                checkGLcall("glDrawBuffers()");
+                GL_EXTCALL(glDrawBuffers(i, draw_buffers));
             }
             else
             {
             }
             else
             {
-                gl_info->gl_ops.gl.p_glDrawBuffer(context->draw_buffers[0]);
-                checkGLcall("glDrawBuffer()");
+                gl_info->gl_ops.gl.p_glDrawBuffer(draw_buffers[0]);
             }
         }
         else
             }
         }
         else
@@ -2634,6 +2693,8 @@ static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt
             ERR("Unexpected draw buffers mask with backbuffer ORM.\n");
         }
     }
             ERR("Unexpected draw buffers mask with backbuffer ORM.\n");
         }
     }
+
+    checkGLcall("apply draw buffers");
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -2672,6 +2733,7 @@ void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint nam
 
 void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name)
 {
 
 void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name)
 {
+    const struct wined3d_dummy_textures *textures = &context->device->dummy_textures;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     DWORD unit = context->active_texture;
     DWORD old_texture_type = context->texture_type[unit];
     const struct wined3d_gl_info *gl_info = context->gl_info;
     DWORD unit = context->active_texture;
     DWORD old_texture_type = context->texture_type[unit];
@@ -2679,7 +2741,6 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint
     if (name)
     {
         gl_info->gl_ops.gl.p_glBindTexture(target, name);
     if (name)
     {
         gl_info->gl_ops.gl.p_glBindTexture(target, name);
-        checkGLcall("glBindTexture");
     }
     else
     {
     }
     else
     {
@@ -2688,40 +2749,45 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint
 
     if (old_texture_type != target)
     {
 
     if (old_texture_type != target)
     {
-        const struct wined3d_device *device = context->device;
-
         switch (old_texture_type)
         {
             case GL_NONE:
                 /* nothing to do */
                 break;
         switch (old_texture_type)
         {
             case GL_NONE:
                 /* nothing to do */
                 break;
-            case GL_TEXTURE_2D:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d);
+            case GL_TEXTURE_1D:
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
                 checkGLcall("glBindTexture");
                 break;
                 checkGLcall("glBindTexture");
                 break;
-            case GL_TEXTURE_2D_ARRAY:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array);
+            case GL_TEXTURE_1D_ARRAY:
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
                 checkGLcall("glBindTexture");
                 break;
                 checkGLcall("glBindTexture");
                 break;
+            case GL_TEXTURE_2D:
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
+                break;
+            case GL_TEXTURE_2D_ARRAY:
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
+                break;
             case GL_TEXTURE_RECTANGLE_ARB:
             case GL_TEXTURE_RECTANGLE_ARB:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect);
-                checkGLcall("glBindTexture");
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures->tex_rect);
                 break;
             case GL_TEXTURE_CUBE_MAP:
                 break;
             case GL_TEXTURE_CUBE_MAP:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube);
-                checkGLcall("glBindTexture");
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, textures->tex_cube);
                 break;
             case GL_TEXTURE_CUBE_MAP_ARRAY:
                 break;
             case GL_TEXTURE_CUBE_MAP_ARRAY:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, device->dummy_textures.tex_cube_array);
-                checkGLcall("glBindTexture");
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures->tex_cube_array);
                 break;
             case GL_TEXTURE_3D:
                 break;
             case GL_TEXTURE_3D:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d);
-                checkGLcall("glBindTexture");
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, textures->tex_3d);
                 break;
             case GL_TEXTURE_BUFFER:
                 break;
             case GL_TEXTURE_BUFFER:
-                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, device->dummy_textures.tex_buffer);
-                checkGLcall("glBindTexture");
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer);
+                break;
+            case GL_TEXTURE_2D_MULTISAMPLE:
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textures->tex_2d_ms);
+                break;
+            case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, textures->tex_2d_ms_array);
                 break;
             default:
                 ERR("Unexpected texture target %#x.\n", old_texture_type);
                 break;
             default:
                 ERR("Unexpected texture target %#x.\n", old_texture_type);
@@ -2729,6 +2795,8 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint
 
         context->texture_type[unit] = target;
     }
 
         context->texture_type[unit] = target;
     }
+
+    checkGLcall("bind texture");
 }
 
 void *context_map_bo_address(struct wined3d_context *context,
 }
 
 void *context_map_bo_address(struct wined3d_context *context,
@@ -2796,8 +2864,8 @@ void context_copy_bo_address(struct wined3d_context *context,
         }
         else
         {
         }
         else
         {
-            src_ptr = context_map_bo_address(context, src, size, src_binding, WINED3D_MAP_READONLY);
-            dst_ptr = context_map_bo_address(context, dst, size, dst_binding, 0);
+            src_ptr = context_map_bo_address(context, src, size, src_binding, WINED3D_MAP_READ);
+            dst_ptr = context_map_bo_address(context, dst, size, dst_binding, WINED3D_MAP_WRITE);
 
             memcpy(dst_ptr, src_ptr, size);
 
 
             memcpy(dst_ptr, src_ptr, size);
 
@@ -2918,8 +2986,6 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
-        context_validate_onscreen_formats(context, NULL);
-
         if (context->render_offscreen)
         {
             wined3d_texture_load(rt, context, FALSE);
         if (context->render_offscreen)
         {
             wined3d_texture_load(rt, context, FALSE);
@@ -2960,12 +3026,13 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
     context_invalidate_state(context, STATE_FRAMEBUFFER);
 }
 
     context_invalidate_state(context, STATE_FRAMEBUFFER);
 }
 
-static BOOL context_validate_rt_config(UINT rt_count, struct wined3d_rendertarget_view * const *rts,
+static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts,
         const struct wined3d_rendertarget_view *ds)
 {
     unsigned int i;
 
         const struct wined3d_rendertarget_view *ds)
 {
     unsigned int i;
 
-    if (ds) return TRUE;
+    if (ds)
+        return TRUE;
 
     for (i = 0; i < rt_count; ++i)
     {
 
     for (i = 0; i < rt_count; ++i)
     {
@@ -2973,7 +3040,6 @@ static BOOL context_validate_rt_config(UINT rt_count, struct wined3d_rendertarge
             return TRUE;
     }
 
             return TRUE;
     }
 
-    WARN("Invalid render target config, need at least one attachment.\n");
     return FALSE;
 }
 
     return FALSE;
 }
 
@@ -2981,7 +3047,7 @@ static BOOL context_validate_rt_config(UINT rt_count, struct wined3d_rendertarge
 BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
         UINT rt_count, const struct wined3d_fb_state *fb)
 {
 BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
         UINT rt_count, const struct wined3d_fb_state *fb)
 {
-    struct wined3d_rendertarget_view **rts = fb->render_targets;
+    struct wined3d_rendertarget_view * const *rts = fb->render_targets;
     struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     DWORD rt_mask = 0, *cur_mask;
     struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     DWORD rt_mask = 0, *cur_mask;
@@ -2990,8 +3056,11 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
     if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
             || rt_count != gl_info->limits.buffers)
     {
     if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
             || rt_count != gl_info->limits.buffers)
     {
-        if (!context_validate_rt_config(rt_count, rts, dsv))
+        if (!have_framebuffer_attachment(rt_count, rts, dsv))
+        {
+            WARN("Invalid render target config, need at least one attachment.\n");
             return FALSE;
             return FALSE;
+        }
 
         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
         {
 
         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
         {
@@ -2999,7 +3068,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
 
             if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))
             {
 
             if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))
             {
-                memset(context->blit_targets, 0, gl_info->limits.buffers * sizeof(*context->blit_targets));
+                memset(context->blit_targets, 0, sizeof(context->blit_targets));
                 for (i = 0; i < rt_count; ++i)
                 {
                     if (rts[i])
                 for (i = 0; i < rt_count; ++i)
                 {
                     if (rts[i])
@@ -3090,9 +3159,9 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
 
 static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state)
 {
 
 static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state)
 {
-    struct wined3d_rendertarget_view **rts = state->fb->render_targets;
+    struct wined3d_rendertarget_view * const *rts = state->fb->render_targets;
     struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL];
     struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL];
-    DWORD rt_mask, rt_mask_bits;
+    DWORD rt_mask, mask;
     unsigned int i;
 
     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
     unsigned int i;
 
     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
@@ -3100,17 +3169,24 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const
     else if (!context->render_offscreen)
         return context_generate_rt_mask_from_resource(rts[0]->resource);
 
     else if (!context->render_offscreen)
         return context_generate_rt_mask_from_resource(rts[0]->resource);
 
+    /* If we attach more buffers than supported in dual blend mode, the NVIDIA
+     * driver generates the following error:
+     *      GL_INVALID_OPERATION error generated. State(s) are invalid: blend.
+     * DX11 does not treat this configuration as invalid, so disable the unused ones.
+     */
     rt_mask = ps ? ps->reg_maps.rt_mask : 1;
     rt_mask = ps ? ps->reg_maps.rt_mask : 1;
-    rt_mask &= context->d3d_info->valid_rt_mask;
-    rt_mask_bits = rt_mask;
+    if (wined3d_dualblend_enabled(state, context->gl_info))
+        rt_mask &= context->d3d_info->valid_dual_rt_mask;
+    else
+        rt_mask &= context->d3d_info->valid_rt_mask;
+
+    mask = rt_mask;
     i = 0;
     i = 0;
-    while (rt_mask_bits)
+    while (mask)
     {
     {
-        rt_mask_bits &= ~(1u << i);
+        i = wined3d_bit_scan(&mask);
         if (!rts[i] || rts[i]->format->id == WINED3DFMT_NULL)
             rt_mask &= ~(1u << i);
         if (!rts[i] || rts[i]->format->id == WINED3DFMT_NULL)
             rt_mask &= ~(1u << i);
-
-        i++;
     }
 
     return rt_mask;
     }
 
     return rt_mask;
@@ -3121,6 +3197,7 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat
 {
     DWORD rt_mask = find_draw_buffers_mask(context, state);
     const struct wined3d_fb_state *fb = state->fb;
 {
     DWORD rt_mask = find_draw_buffers_mask(context, state);
     const struct wined3d_fb_state *fb = state->fb;
+    DWORD color_location = 0;
     DWORD *cur_mask;
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     DWORD *cur_mask;
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
@@ -3134,21 +3211,23 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat
         {
             unsigned int i;
 
         {
             unsigned int i;
 
-            memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof (*context->blit_targets));
+            memset(context->blit_targets, 0, sizeof(context->blit_targets));
             for (i = 0; i < context->gl_info->limits.buffers; ++i)
             {
             for (i = 0; i < context->gl_info->limits.buffers; ++i)
             {
-                if (fb->render_targets[i])
-                {
-                    context->blit_targets[i].gl_view = fb->render_targets[i]->gl_view;
-                    context->blit_targets[i].resource = fb->render_targets[i]->resource;
-                    context->blit_targets[i].sub_resource_idx = fb->render_targets[i]->sub_resource_idx;
-                    context->blit_targets[i].layer_count = fb->render_targets[i]->layer_count;
-                }
+                if (!fb->render_targets[i])
+                    continue;
+
+                context->blit_targets[i].gl_view = fb->render_targets[i]->gl_view;
+                context->blit_targets[i].resource = fb->render_targets[i]->resource;
+                context->blit_targets[i].sub_resource_idx = fb->render_targets[i]->sub_resource_idx;
+                context->blit_targets[i].layer_count = fb->render_targets[i]->layer_count;
+
+                if (!color_location)
+                    color_location = fb->render_targets[i]->resource->draw_binding;
             }
             context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
                     wined3d_rendertarget_view_get_surface(fb->depth_stencil),
             }
             context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
                     wined3d_rendertarget_view_get_surface(fb->depth_stencil),
-                    fb->render_targets[0] ? fb->render_targets[0]->resource->draw_binding : 0,
-                    fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0);
+                    color_location, fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0);
         }
     }
 
         }
     }
 
@@ -3865,7 +3944,7 @@ static void context_load_stream_output_buffers(struct wined3d_context *context,
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
-BOOL context_apply_draw_state(struct wined3d_context *context,
+static BOOL context_apply_draw_state(struct wined3d_context *context,
         const struct wined3d_device *device, const struct wined3d_state *state)
 {
     const struct StateEntry *state_table = context->state_table;
         const struct wined3d_device *device, const struct wined3d_state *state)
 {
     const struct StateEntry *state_table = context->state_table;
@@ -3874,8 +3953,16 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
     unsigned int i;
     WORD map;
 
     unsigned int i;
     WORD map;
 
-    if (!context_validate_rt_config(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil))
-        return FALSE;
+    if (!have_framebuffer_attachment(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil))
+    {
+        if (!gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS])
+        {
+            FIXME("OpenGL implementation does not support framebuffers with no attachments.\n");
+            return FALSE;
+        }
+
+        context_set_render_offscreen(context, TRUE);
+    }
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && isStateDirty(context, STATE_FRAMEBUFFER))
     {
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && isStateDirty(context, STATE_FRAMEBUFFER))
     {
@@ -3970,12 +4057,12 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
     return TRUE;
 }
 
     return TRUE;
 }
 
-void context_apply_compute_state(struct wined3d_context *context,
+static void context_apply_compute_state(struct wined3d_context *context,
         const struct wined3d_device *device, const struct wined3d_state *state)
 {
     const struct StateEntry *state_table = context->state_table;
     const struct wined3d_gl_info *gl_info = context->gl_info;
         const struct wined3d_device *device, const struct wined3d_state *state)
 {
     const struct StateEntry *state_table = context->state_table;
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int state_id, i, j;
+    unsigned int state_id, i;
 
     context_load_shader_resources(context, state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
     context_load_unordered_access_resources(context, state->shader[WINED3D_SHADER_TYPE_COMPUTE],
 
     context_load_shader_resources(context, state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
     context_load_unordered_access_resources(context, state->shader[WINED3D_SHADER_TYPE_COMPUTE],
@@ -3983,11 +4070,13 @@ void context_apply_compute_state(struct wined3d_context *context,
 
     for (i = 0, state_id = STATE_COMPUTE_OFFSET; i < ARRAY_SIZE(context->dirty_compute_states); ++i)
     {
 
     for (i = 0, state_id = STATE_COMPUTE_OFFSET; i < ARRAY_SIZE(context->dirty_compute_states); ++i)
     {
-        for (j = 0; j < sizeof(*context->dirty_compute_states) * CHAR_BIT; ++j, ++state_id)
+        unsigned int dirty_mask = context->dirty_compute_states[i];
+        while (dirty_mask)
         {
         {
-            if (context->dirty_compute_states[i] & (1u << j))
-                state_table[state_id].apply(context, state, state_id);
+            unsigned int current_state_id = state_id + wined3d_bit_scan(&dirty_mask);
+            state_table[current_state_id].apply(context, state, current_state_id);
         }
         }
+        state_id += sizeof(*context->dirty_compute_states) * CHAR_BIT;
     }
     memset(context->dirty_compute_states, 0, sizeof(*context->dirty_compute_states));
 
     }
     memset(context->dirty_compute_states, 0, sizeof(*context->dirty_compute_states));
 
@@ -4027,6 +4116,14 @@ void context_apply_compute_state(struct wined3d_context *context,
     context->last_was_blit = FALSE;
 }
 
     context->last_was_blit = FALSE;
 }
 
+static BOOL use_transform_feedback(const struct wined3d_state *state)
+{
+    const struct wined3d_shader *shader;
+    if (!(shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]))
+        return FALSE;
+    return shader->u.gs.so_desc.element_count;
+}
+
 void context_end_transform_feedback(struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 void context_end_transform_feedback(struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -4039,6 +4136,27 @@ void context_end_transform_feedback(struct wined3d_context *context)
     }
 }
 
     }
 }
 
+static void context_pause_transform_feedback(struct wined3d_context *context, BOOL force)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    if (!context->transform_feedback_active || context->transform_feedback_paused)
+        return;
+
+    if (gl_info->supported[ARB_TRANSFORM_FEEDBACK2])
+    {
+        GL_EXTCALL(glPauseTransformFeedback());
+        checkGLcall("glPauseTransformFeedback");
+        context->transform_feedback_paused = 1;
+        return;
+    }
+
+    WARN("Cannot pause transform feedback operations.\n");
+
+    if (force)
+        context_end_transform_feedback(context);
+}
+
 static void context_setup_target(struct wined3d_context *context,
         struct wined3d_texture *texture, unsigned int sub_resource_idx)
 {
 static void context_setup_target(struct wined3d_context *context,
         struct wined3d_texture *texture, unsigned int sub_resource_idx)
 {
@@ -4101,6 +4219,26 @@ static void context_setup_target(struct wined3d_context *context,
     context_set_render_offscreen(context, render_offscreen);
 }
 
     context_set_render_offscreen(context, render_offscreen);
 }
 
+static void context_activate(struct wined3d_context *context,
+        struct wined3d_texture *texture, unsigned int sub_resource_idx)
+{
+    context_enter(context);
+    context_update_window(context);
+    context_setup_target(context, texture, sub_resource_idx);
+    if (!context->valid)
+        return;
+
+    if (context != context_get_current())
+    {
+        if (!context_set_current(context))
+            ERR("Failed to activate the new context.\n");
+    }
+    else if (context->needs_set)
+    {
+        context_set_gl_context(context);
+    }
+}
+
 struct wined3d_context *context_acquire(const struct wined3d_device *device,
         struct wined3d_texture *texture, unsigned int sub_resource_idx)
 {
 struct wined3d_context *context_acquire(const struct wined3d_device *device,
         struct wined3d_texture *texture, unsigned int sub_resource_idx)
 {
@@ -4159,36 +4297,852 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device,
             context = swapchain_get_context(device->swapchains[0]);
     }
 
             context = swapchain_get_context(device->swapchains[0]);
     }
 
-    context_enter(context);
-    context_update_window(context);
-    context_setup_target(context, texture, sub_resource_idx);
-    if (!context->valid)
+    context_activate(context, texture, sub_resource_idx);
+
+    return context;
+}
+
+struct wined3d_context *context_reacquire(const struct wined3d_device *device,
+        struct wined3d_context *context)
+{
+    struct wined3d_context *acquired_context;
+
+    wined3d_from_cs(device->cs);
+
+    if (!context || context->tid != GetCurrentThreadId())
+        return NULL;
+
+    if (context->current_rt.texture)
+    {
+        context_activate(context, context->current_rt.texture, context->current_rt.sub_resource_idx);
         return context;
         return context;
+    }
+
+    acquired_context = context_acquire(device, NULL, 0);
+    if (acquired_context != context)
+        ERR("Acquired context %p instead of %p.\n", acquired_context, context);
+    return acquired_context;
+}
+
+void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state,
+        const struct wined3d_dispatch_parameters *parameters)
+{
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
 
 
-    if (context != current_context)
+    context = context_acquire(device, NULL, 0);
+    if (!context->valid)
     {
     {
-        if (!context_set_current(context))
-            ERR("Failed to activate the new context.\n");
+        context_release(context);
+        WARN("Invalid context, skipping dispatch.\n");
+        return;
     }
     }
-    else if (context->needs_set)
+    gl_info = context->gl_info;
+
+    if (!gl_info->supported[ARB_COMPUTE_SHADER])
     {
     {
-        context_set_gl_context(context);
+        context_release(context);
+        FIXME("OpenGL implementation does not support compute shaders.\n");
+        return;
     }
 
     }
 
-    return context;
+    if (parameters->indirect)
+        wined3d_buffer_load(parameters->u.indirect.buffer, context, state);
+
+    context_apply_compute_state(context, device, state);
+
+    if (!state->shader[WINED3D_SHADER_TYPE_COMPUTE])
+    {
+        context_release(context);
+        WARN("No compute shader bound, skipping dispatch.\n");
+        return;
+    }
+
+    if (parameters->indirect)
+    {
+        const struct wined3d_indirect_dispatch_parameters *indirect = &parameters->u.indirect;
+        struct wined3d_buffer *buffer = indirect->buffer;
+
+        GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer->buffer_object));
+        GL_EXTCALL(glDispatchComputeIndirect((GLintptr)indirect->offset));
+        GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0));
+    }
+    else
+    {
+        const struct wined3d_direct_dispatch_parameters *direct = &parameters->u.direct;
+        GL_EXTCALL(glDispatchCompute(direct->group_count_x, direct->group_count_y, direct->group_count_z));
+    }
+    checkGLcall("dispatch compute");
+
+    GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
+    checkGLcall("glMemoryBarrier");
+
+    if (wined3d_settings.strict_draw_ordering)
+        gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+    context_release(context);
 }
 
 }
 
-struct wined3d_context *context_reacquire(const struct wined3d_device *device,
-        struct wined3d_context *context)
+/* Context activation is done by the caller. */
+static void draw_primitive_arrays(struct wined3d_context *context, const struct wined3d_state *state,
+        const void *idx_data, unsigned int idx_size, int base_vertex_idx, unsigned int start_idx,
+        unsigned int count, unsigned int start_instance, unsigned int instance_count)
 {
 {
-    struct wined3d_context *current_context;
+    const struct wined3d_ffp_attrib_ops *ops = &context->d3d_info->ffp_attrib_ops;
+    GLenum idx_type = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
+    const struct wined3d_stream_info *si = &context->stream_info;
+    unsigned int instanced_elements[ARRAY_SIZE(si->elements)];
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned int instanced_element_count = 0;
+    GLenum mode = state->gl_primitive_type;
+    const void *indices;
+    unsigned int i, j;
 
 
-    if (!context || context->tid != GetCurrentThreadId())
-        return NULL;
+    indices = (const char *)idx_data + idx_size * start_idx;
+
+    if (!instance_count)
+    {
+        if (!idx_size)
+        {
+            gl_info->gl_ops.gl.p_glDrawArrays(mode, start_idx, count);
+            checkGLcall("glDrawArrays");
+            return;
+        }
+
+        if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
+        {
+            GL_EXTCALL(glDrawElementsBaseVertex(mode, count, idx_type, indices, base_vertex_idx));
+            checkGLcall("glDrawElementsBaseVertex");
+            return;
+        }
+
+        gl_info->gl_ops.gl.p_glDrawElements(mode, count, idx_type, indices);
+        checkGLcall("glDrawElements");
+        return;
+    }
+
+    if (start_instance && !(gl_info->supported[ARB_BASE_INSTANCE] && gl_info->supported[ARB_INSTANCED_ARRAYS]))
+        FIXME("Start instance (%u) not supported.\n", start_instance);
+
+    if (gl_info->supported[ARB_INSTANCED_ARRAYS])
+    {
+        if (!idx_size)
+        {
+            if (gl_info->supported[ARB_BASE_INSTANCE])
+            {
+                GL_EXTCALL(glDrawArraysInstancedBaseInstance(mode, start_idx, count, instance_count, start_instance));
+                checkGLcall("glDrawArraysInstancedBaseInstance");
+                return;
+            }
+
+            GL_EXTCALL(glDrawArraysInstanced(mode, start_idx, count, instance_count));
+            checkGLcall("glDrawArraysInstanced");
+            return;
+        }
+
+        if (gl_info->supported[ARB_BASE_INSTANCE])
+        {
+            GL_EXTCALL(glDrawElementsInstancedBaseVertexBaseInstance(mode, count, idx_type,
+                    indices, instance_count, base_vertex_idx, start_instance));
+            checkGLcall("glDrawElementsInstancedBaseVertexBaseInstance");
+            return;
+        }
+        if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
+        {
+            GL_EXTCALL(glDrawElementsInstancedBaseVertex(mode, count, idx_type,
+                    indices, instance_count, base_vertex_idx));
+            checkGLcall("glDrawElementsInstancedBaseVertex");
+            return;
+        }
+
+        GL_EXTCALL(glDrawElementsInstanced(mode, count, idx_type, indices, instance_count));
+        checkGLcall("glDrawElementsInstanced");
+        return;
+    }
+
+    /* Instancing emulation by mixing immediate mode and arrays. */
+
+    /* This is a nasty thing. MSDN says no hardware supports this and
+     * applications have to use software vertex processing. We don't support
+     * this for now.
+     *
+     * Shouldn't be too hard to support with OpenGL, in theory just call
+     * glDrawArrays() instead of drawElements(). But the stream fequency value
+     * has a different meaning in that situation. */
+    if (!idx_size)
+    {
+        FIXME("Non-indexed instanced drawing is not supported.\n");
+        return;
+    }
 
 
-    current_context = context_acquire(device, context->current_rt.texture,
-            context->current_rt.sub_resource_idx);
-    if (current_context != context)
-        ERR("Acquired context %p instead of %p.\n", current_context, context);
-    return current_context;
+    for (i = 0; i < ARRAY_SIZE(si->elements); ++i)
+    {
+        if (!(si->use_map & (1u << i)))
+            continue;
+
+        if (state->streams[si->elements[i].stream_idx].flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
+            instanced_elements[instanced_element_count++] = i;
+    }
+
+    for (i = 0; i < instance_count; ++i)
+    {
+        /* Specify the instanced attributes using immediate mode calls. */
+        for (j = 0; j < instanced_element_count; ++j)
+        {
+            const struct wined3d_stream_info_element *element;
+            unsigned int element_idx;
+            const BYTE *ptr;
+
+            element_idx = instanced_elements[j];
+            element = &si->elements[element_idx];
+            ptr = element->data.addr + element->stride * i;
+            if (element->data.buffer_object)
+                ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(state->streams[element->stream_idx].buffer, context);
+            ops->generic[element->format->emit_idx](element_idx, ptr);
+        }
+
+        if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
+        {
+            GL_EXTCALL(glDrawElementsBaseVertex(mode, count, idx_type, indices, base_vertex_idx));
+            checkGLcall("glDrawElementsBaseVertex");
+        }
+        else
+        {
+            gl_info->gl_ops.gl.p_glDrawElements(mode, count, idx_type, indices);
+            checkGLcall("glDrawElements");
+        }
+    }
+}
+
+static const BYTE *software_vertex_blending(struct wined3d_context *context,
+        const struct wined3d_state *state, const struct wined3d_stream_info *si,
+        unsigned int element_idx, unsigned int stride_idx, float *result)
+{
+#define SI_FORMAT(idx) (si->elements[(idx)].format->emit_idx)
+#define SI_PTR(idx1, idx2) (si->elements[(idx1)].data.addr + si->elements[(idx1)].stride * (idx2))
+
+    const float *data = (const float *)SI_PTR(element_idx, stride_idx);
+    float vector[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+    float cur_weight, weight_sum = 0.0f;
+    struct wined3d_matrix m;
+    const BYTE *blend_index;
+    const float *weights;
+    int i, num_weights;
+
+    if (element_idx != WINED3D_FFP_POSITION && element_idx != WINED3D_FFP_NORMAL)
+        return (BYTE *)data;
+
+    if (!use_indexed_vertex_blending(state, si) || !use_software_vertex_processing(context->device))
+        return (BYTE *)data;
+
+    if (!si->elements[WINED3D_FFP_BLENDINDICES].data.addr ||
+        !si->elements[WINED3D_FFP_BLENDWEIGHT].data.addr)
+    {
+        FIXME("no blend indices / weights set\n");
+        return (BYTE *)data;
+    }
+
+    if (SI_FORMAT(WINED3D_FFP_BLENDINDICES) != WINED3D_FFP_EMIT_UBYTE4)
+    {
+        FIXME("unsupported blend index format: %u\n", SI_FORMAT(WINED3D_FFP_BLENDINDICES));
+        return (BYTE *)data;
+    }
+
+    /* FIXME: validate weight format */
+    switch (state->render_states[WINED3D_RS_VERTEXBLEND])
+    {
+        case WINED3D_VBF_0WEIGHTS: num_weights = 0; break;
+        case WINED3D_VBF_1WEIGHTS: num_weights = 1; break;
+        case WINED3D_VBF_2WEIGHTS: num_weights = 2; break;
+        case WINED3D_VBF_3WEIGHTS: num_weights = 3; break;
+        default:
+            FIXME("unsupported vertex blend render state: %u\n", state->render_states[WINED3D_RS_VERTEXBLEND]);
+            return (BYTE *)data;
+    }
+
+    switch (SI_FORMAT(element_idx))
+    {
+        case WINED3D_FFP_EMIT_FLOAT4: vector[3] = data[3];
+        case WINED3D_FFP_EMIT_FLOAT3: vector[2] = data[2];
+        case WINED3D_FFP_EMIT_FLOAT2: vector[1] = data[1];
+        default:
+            FIXME("unsupported value format: %u\n", SI_FORMAT(element_idx));
+            return (BYTE *)data;
+    }
+
+    blend_index = SI_PTR(WINED3D_FFP_BLENDINDICES, stride_idx);
+    weights = (const float *)SI_PTR(WINED3D_FFP_BLENDWEIGHT, stride_idx);
+    result[0] = result[1] = result[2] = result[3] = 0.0f;
+
+    for (i = 0; i < num_weights + 1; i++)
+    {
+        cur_weight = (i < num_weights) ? weights[i] : 1.0f - weight_sum;
+        get_modelview_matrix(context, state, blend_index[i], &m);
+
+        if (element_idx == WINED3D_FFP_POSITION)
+        {
+            result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._21 + vector[2] * m._31 + vector[3] * m._41);
+            result[1] += cur_weight * (vector[0] * m._12 + vector[1] * m._22 + vector[2] * m._32 + vector[3] * m._42);
+            result[2] += cur_weight * (vector[0] * m._13 + vector[1] * m._23 + vector[2] * m._33 + vector[3] * m._43);
+            result[3] += cur_weight * (vector[0] * m._14 + vector[1] * m._24 + vector[2] * m._34 + vector[3] * m._44);
+        }
+        else
+        {
+            if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING)
+                invert_matrix_3d(&m, &m);
+            else
+                invert_matrix(&m, &m);
+
+            /* multiply with transposed M */
+            result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._12 + vector[2] * m._13);
+            result[1] += cur_weight * (vector[0] * m._21 + vector[1] * m._22 + vector[2] * m._23);
+            result[2] += cur_weight * (vector[0] * m._31 + vector[1] * m._32 + vector[2] * m._33);
+        }
+
+        weight_sum += weights[i];
+    }
+
+#undef SI_FORMAT
+#undef SI_PTR
+
+    return (BYTE *)result;
+}
+
+static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size,
+        unsigned int base_vertex_idx, unsigned int start_idx, unsigned int vertex_idx)
+{
+    if (!idx_data)
+        return start_idx + vertex_idx;
+    if (idx_size == 2)
+        return ((const WORD *)idx_data)[start_idx + vertex_idx] + base_vertex_idx;
+    return ((const DWORD *)idx_data)[start_idx + vertex_idx] + base_vertex_idx;
+}
+
+/* Context activation is done by the caller. */
+static void draw_primitive_immediate_mode(struct wined3d_context *context, const struct wined3d_state *state,
+        const struct wined3d_stream_info *si, const void *idx_data, unsigned int idx_size,
+        int base_vertex_idx, unsigned int start_idx, unsigned int vertex_count, unsigned int instance_count)
+{
+    const BYTE *position = NULL, *normal = NULL, *diffuse = NULL, *specular = NULL;
+    const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+    unsigned int coord_idx, stride_idx, texture_idx, vertex_idx;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    const struct wined3d_stream_info_element *element;
+    const BYTE *tex_coords[WINED3DDP_MAXTEXCOORD];
+    unsigned int texture_unit, texture_stages;
+    const struct wined3d_ffp_attrib_ops *ops;
+    unsigned int untracked_material_count;
+    unsigned int tex_mask = 0;
+    BOOL specular_fog = FALSE;
+    BOOL ps = use_ps(state);
+    const void *ptr;
+    float tmp[4];
+
+    static unsigned int once;
+
+    if (!once++)
+        FIXME_(d3d_perf)("Drawing using immediate mode.\n");
+    else
+        WARN_(d3d_perf)("Drawing using immediate mode.\n");
+
+    if (!idx_size && idx_data)
+        ERR("Non-NULL idx_data with 0 idx_size, this should never happen.\n");
+
+    if (instance_count)
+        FIXME("Instancing not implemented.\n");
+
+    /* Immediate mode drawing can't make use of indices in a VBO - get the
+     * data from the index buffer. */
+    if (idx_size)
+        idx_data = wined3d_buffer_load_sysmem(state->index_buffer, context) + state->index_offset;
+
+    ops = &d3d_info->ffp_attrib_ops;
+
+    gl_info->gl_ops.gl.p_glBegin(state->gl_primitive_type);
+
+    if (use_vs(state) || d3d_info->ffp_generic_attributes)
+    {
+        for (vertex_idx = 0; vertex_idx < vertex_count; ++vertex_idx)
+        {
+            unsigned int use_map = si->use_map;
+            unsigned int element_idx;
+
+            stride_idx = get_stride_idx(idx_data, idx_size, base_vertex_idx, start_idx, vertex_idx);
+            for (element_idx = MAX_ATTRIBS - 1; use_map; use_map &= ~(1u << element_idx), --element_idx)
+            {
+                if (!(use_map & 1u << element_idx))
+                    continue;
+
+                ptr = software_vertex_blending(context, state, si, element_idx, stride_idx, tmp);
+                ops->generic[si->elements[element_idx].format->emit_idx](element_idx, ptr);
+            }
+        }
+
+        gl_info->gl_ops.gl.p_glEnd();
+        return;
+    }
+
+    if (si->use_map & (1u << WINED3D_FFP_POSITION))
+        position = si->elements[WINED3D_FFP_POSITION].data.addr;
+
+    if (si->use_map & (1u << WINED3D_FFP_NORMAL))
+        normal = si->elements[WINED3D_FFP_NORMAL].data.addr;
+    else
+        gl_info->gl_ops.gl.p_glNormal3f(0.0f, 0.0f, 0.0f);
+
+    untracked_material_count = context->num_untracked_materials;
+    if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
+    {
+        element = &si->elements[WINED3D_FFP_DIFFUSE];
+        diffuse = element->data.addr;
+
+        if (untracked_material_count && element->format->id != WINED3DFMT_B8G8R8A8_UNORM)
+            FIXME("Implement diffuse color tracking from %s.\n", debug_d3dformat(element->format->id));
+    }
+    else
+    {
+        gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+    }
+
+    if (si->use_map & (1u << WINED3D_FFP_SPECULAR))
+    {
+        element = &si->elements[WINED3D_FFP_SPECULAR];
+        specular = element->data.addr;
+
+        /* Special case where the fog density is stored in the specular alpha channel. */
+        if (state->render_states[WINED3D_RS_FOGENABLE]
+                && (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE
+                    || si->elements[WINED3D_FFP_POSITION].format->id == WINED3DFMT_R32G32B32A32_FLOAT)
+                && state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
+        {
+            if (gl_info->supported[EXT_FOG_COORD])
+            {
+                if (element->format->id == WINED3DFMT_B8G8R8A8_UNORM)
+                    specular_fog = TRUE;
+                else
+                    FIXME("Implement fog coordinates from %s.\n", debug_d3dformat(element->format->id));
+            }
+            else
+            {
+                static unsigned int once;
+
+                if (!once++)
+                    FIXME("Implement fog for transformed vertices in software.\n");
+            }
+        }
+    }
+    else if (gl_info->supported[EXT_SECONDARY_COLOR])
+    {
+        GL_EXTCALL(glSecondaryColor3fEXT)(0.0f, 0.0f, 0.0f);
+    }
+
+    texture_stages = d3d_info->limits.ffp_blend_stages;
+    for (texture_idx = 0; texture_idx < texture_stages; ++texture_idx)
+    {
+        if (!gl_info->supported[ARB_MULTITEXTURE] && texture_idx > 0)
+        {
+            FIXME("Program using multiple concurrent textures which this OpenGL implementation doesn't support.\n");
+            continue;
+        }
+
+        if (!ps && !state->textures[texture_idx])
+            continue;
+
+        texture_unit = context->tex_unit_map[texture_idx];
+        if (texture_unit == WINED3D_UNMAPPED_STAGE)
+            continue;
+
+        coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
+        if (coord_idx > 7)
+        {
+            TRACE("Skipping generated coordinates (%#x) for texture %u.\n", coord_idx, texture_idx);
+            continue;
+        }
+
+        if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))
+        {
+            tex_coords[coord_idx] = si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].data.addr;
+            tex_mask |= (1u << texture_idx);
+        }
+        else
+        {
+            TRACE("Setting default coordinates for texture %u.\n", texture_idx);
+            if (gl_info->supported[ARB_MULTITEXTURE])
+                GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_unit, 0.0f, 0.0f, 0.0f, 1.0f));
+            else
+                gl_info->gl_ops.gl.p_glTexCoord4f(0.0f, 0.0f, 0.0f, 1.0f);
+        }
+    }
+
+    /* Blending data and point sizes are not supported by this function. They
+     * are not supported by the fixed function pipeline at all. A FIXME for
+     * them is printed after decoding the vertex declaration. */
+    for (vertex_idx = 0; vertex_idx < vertex_count; ++vertex_idx)
+    {
+        unsigned int tmp_tex_mask;
+
+        stride_idx = get_stride_idx(idx_data, idx_size, base_vertex_idx, start_idx, vertex_idx);
+
+        if (normal)
+        {
+            ptr = software_vertex_blending(context, state, si, WINED3D_FFP_NORMAL, stride_idx, tmp);
+            ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptr);
+        }
+
+        if (diffuse)
+        {
+            ptr = diffuse + stride_idx * si->elements[WINED3D_FFP_DIFFUSE].stride;
+            ops->diffuse[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptr);
+
+            if (untracked_material_count)
+            {
+                struct wined3d_color color;
+                unsigned int i;
+
+                wined3d_color_from_d3dcolor(&color, *(const DWORD *)ptr);
+                for (i = 0; i < untracked_material_count; ++i)
+                {
+                    gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], &color.r);
+                }
+            }
+        }
+
+        if (specular)
+        {
+            ptr = specular + stride_idx * si->elements[WINED3D_FFP_SPECULAR].stride;
+            ops->specular[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptr);
+
+            if (specular_fog)
+                GL_EXTCALL(glFogCoordfEXT((float)(*(const DWORD *)ptr >> 24)));
+        }
+
+        tmp_tex_mask = tex_mask;
+        for (texture_idx = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture_idx)
+        {
+            if (!(tmp_tex_mask & 1))
+                continue;
+
+            coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
+            ptr = tex_coords[coord_idx] + (stride_idx * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);
+            ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx](
+                    GL_TEXTURE0_ARB + context->tex_unit_map[texture_idx], ptr);
+        }
+
+        if (position)
+        {
+            ptr = software_vertex_blending(context, state, si, WINED3D_FFP_POSITION, stride_idx, tmp);
+            ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptr);
+        }
+    }
+
+    gl_info->gl_ops.gl.p_glEnd();
+    checkGLcall("draw immediate mode");
+}
+
+static void draw_indirect(struct wined3d_context *context, const struct wined3d_state *state,
+        const struct wined3d_indirect_draw_parameters *parameters, unsigned int idx_size)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct wined3d_buffer *buffer = parameters->buffer;
+    const void *offset;
+
+    if (!gl_info->supported[ARB_DRAW_INDIRECT])
+    {
+        FIXME("OpenGL implementation does not support indirect draws.\n");
+        return;
+    }
+
+    GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->buffer_object));
+
+    offset = (void *)(GLintptr)parameters->offset;
+    if (idx_size)
+    {
+        GLenum idx_type = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
+        if (state->index_offset)
+            FIXME("Ignoring index offset %u.\n", state->index_offset);
+        GL_EXTCALL(glDrawElementsIndirect(state->gl_primitive_type, idx_type, offset));
+    }
+    else
+    {
+        GL_EXTCALL(glDrawArraysIndirect(state->gl_primitive_type, offset));
+    }
+
+    GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0));
+
+    checkGLcall("draw indirect");
+}
+
+static void remove_vbos(struct wined3d_context *context,
+        const struct wined3d_state *state, struct wined3d_stream_info *s)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(s->elements); ++i)
+    {
+        struct wined3d_stream_info_element *e;
+
+        if (!(s->use_map & (1u << i)))
+            continue;
+
+        e = &s->elements[i];
+        if (e->data.buffer_object)
+        {
+            struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer;
+            e->data.buffer_object = 0;
+            e->data.addr += (ULONG_PTR)wined3d_buffer_load_sysmem(vb, context);
+        }
+    }
+}
+
+static GLenum gl_tfb_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
+{
+    GLenum gl_primitive_type = gl_primitive_type_from_d3d(primitive_type);
+    switch (gl_primitive_type)
+    {
+        case GL_POINTS:
+            return GL_POINTS;
+
+        case GL_LINE_STRIP:
+        case GL_LINE_STRIP_ADJACENCY:
+        case GL_LINES_ADJACENCY:
+        case GL_LINES:
+            return GL_LINES;
+
+        case GL_TRIANGLE_FAN:
+        case GL_TRIANGLE_STRIP:
+        case GL_TRIANGLE_STRIP_ADJACENCY:
+        case GL_TRIANGLES_ADJACENCY:
+        case GL_TRIANGLES:
+            return GL_TRIANGLES;
+
+        default:
+            return gl_primitive_type;
+    }
+}
+
+/* Routine common to the draw primitive and draw indexed primitive routines */
+void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state,
+        const struct wined3d_draw_parameters *parameters)
+{
+    BOOL emulation = FALSE, rasterizer_discard = FALSE;
+    const struct wined3d_fb_state *fb = state->fb;
+    const struct wined3d_stream_info *stream_info;
+    struct wined3d_rendertarget_view *dsv, *rtv;
+    struct wined3d_stream_info si_emulated;
+    struct wined3d_fence *ib_fence = NULL;
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
+    unsigned int i, idx_size = 0;
+    const void *idx_data = NULL;
+
+    if (!parameters->indirect && !parameters->u.direct.index_count)
+        return;
+
+    if (!(rtv = fb->render_targets[0]))
+        rtv = fb->depth_stencil;
+    if (rtv)
+        context = context_acquire(device, wined3d_texture_from_resource(rtv->resource), rtv->sub_resource_idx);
+    else
+        context = context_acquire(device, NULL, 0);
+    if (!context->valid)
+    {
+        context_release(context);
+        WARN("Invalid context, skipping draw.\n");
+        return;
+    }
+    gl_info = context->gl_info;
+
+    if (!use_transform_feedback(state))
+        context_pause_transform_feedback(context, TRUE);
+
+    for (i = 0; i < gl_info->limits.buffers; ++i)
+    {
+        if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL)
+            continue;
+
+        if (state->render_states[WINED3D_RS_COLORWRITE(i)])
+        {
+            wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding);
+            wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding);
+        }
+        else
+        {
+            wined3d_rendertarget_view_prepare_location(rtv, context, rtv->resource->draw_binding);
+        }
+    }
+
+    if ((dsv = fb->depth_stencil))
+    {
+        /* Note that this depends on the context_acquire() call above to set
+         * context->render_offscreen properly. We don't currently take the
+         * Z-compare function into account, but we could skip loading the
+         * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note
+         * that we never copy the stencil data.*/
+        DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
+
+        if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE])
+            wined3d_rendertarget_view_load_location(dsv, context, location);
+        else
+            wined3d_rendertarget_view_prepare_location(dsv, context, location);
+    }
+
+    if (parameters->indirect)
+        wined3d_buffer_load(parameters->u.indirect.buffer, context, state);
+
+    if (!context_apply_draw_state(context, device, state))
+    {
+        context_release(context);
+        WARN("Unable to apply draw state, skipping draw.\n");
+        return;
+    }
+
+    if (dsv && state->render_states[WINED3D_RS_ZWRITEENABLE])
+    {
+        DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
+
+        wined3d_rendertarget_view_validate_location(dsv, location);
+        wined3d_rendertarget_view_invalidate_location(dsv, ~location);
+    }
+
+    stream_info = &context->stream_info;
+
+    if (parameters->indexed)
+    {
+        struct wined3d_buffer *index_buffer = state->index_buffer;
+        if (!index_buffer->buffer_object || !stream_info->all_vbo)
+        {
+            idx_data = index_buffer->resource.heap_memory;
+        }
+        else
+        {
+            ib_fence = index_buffer->fence;
+            idx_data = NULL;
+        }
+        idx_data = (const BYTE *)idx_data + state->index_offset;
+
+        if (state->index_format == WINED3DFMT_R16_UINT)
+            idx_size = 2;
+        else
+            idx_size = 4;
+    }
+
+    if (!use_vs(state))
+    {
+        if (!stream_info->position_transformed && context->num_untracked_materials
+                && state->render_states[WINED3D_RS_LIGHTING])
+        {
+            static BOOL warned;
+
+            if (!warned++)
+                FIXME("Using software emulation because not all material properties could be tracked.\n");
+            else
+                WARN_(d3d_perf)("Using software emulation because not all material properties could be tracked.\n");
+            emulation = TRUE;
+        }
+        else if (context->fog_coord && state->render_states[WINED3D_RS_FOGENABLE])
+        {
+            static BOOL warned;
+
+            /* Either write a pipeline replacement shader or convert the
+             * specular alpha from unsigned byte to a float in the vertex
+             * buffer. */
+            if (!warned++)
+                FIXME("Using software emulation because manual fog coordinates are provided.\n");
+            else
+                WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n");
+            emulation = TRUE;
+        }
+         else if (use_indexed_vertex_blending(state, stream_info) && use_software_vertex_processing(context->device))
+        {
+            WARN_(d3d_perf)("Using software emulation because application requested SVP.\n");
+            emulation = TRUE;
+        }
+
+
+        if (emulation)
+        {
+            si_emulated = context->stream_info;
+            remove_vbos(context, state, &si_emulated);
+            stream_info = &si_emulated;
+        }
+    }
+
+    if (use_transform_feedback(state))
+    {
+        const struct wined3d_shader *shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
+
+        if (is_rasterization_disabled(shader))
+        {
+            glEnable(GL_RASTERIZER_DISCARD);
+            checkGLcall("enable rasterizer discard");
+            rasterizer_discard = TRUE;
+        }
+
+        if (context->transform_feedback_paused)
+        {
+            GL_EXTCALL(glResumeTransformFeedback());
+            checkGLcall("glResumeTransformFeedback");
+            context->transform_feedback_paused = 0;
+        }
+        else if (!context->transform_feedback_active)
+        {
+            GLenum mode = gl_tfb_primitive_type_from_d3d(shader->u.gs.output_type);
+            GL_EXTCALL(glBeginTransformFeedback(mode));
+            checkGLcall("glBeginTransformFeedback");
+            context->transform_feedback_active = 1;
+        }
+    }
+
+    if (state->gl_primitive_type == GL_PATCHES)
+    {
+        GL_EXTCALL(glPatchParameteri(GL_PATCH_VERTICES, state->gl_patch_vertices));
+        checkGLcall("glPatchParameteri");
+    }
+
+    if (parameters->indirect)
+    {
+        if (!context->use_immediate_mode_draw && !emulation)
+            draw_indirect(context, state, &parameters->u.indirect, idx_size);
+        else
+            FIXME("Indirect draws with immediate mode/emulation are not supported.\n");
+    }
+    else
+    {
+        unsigned int instance_count = parameters->u.direct.instance_count;
+        if (context->instance_count)
+            instance_count = context->instance_count;
+
+        if (context->use_immediate_mode_draw || emulation)
+            draw_primitive_immediate_mode(context, state, stream_info, idx_data,
+                    idx_size, parameters->u.direct.base_vertex_idx,
+                    parameters->u.direct.start_idx, parameters->u.direct.index_count, instance_count);
+        else
+            draw_primitive_arrays(context, state, idx_data, idx_size, parameters->u.direct.base_vertex_idx,
+                    parameters->u.direct.start_idx, parameters->u.direct.index_count,
+                    parameters->u.direct.start_instance, instance_count);
+    }
+
+    if (context->uses_uavs)
+    {
+        GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
+        checkGLcall("glMemoryBarrier");
+    }
+
+    context_pause_transform_feedback(context, FALSE);
+
+    if (rasterizer_discard)
+    {
+        glDisable(GL_RASTERIZER_DISCARD);
+        checkGLcall("disable rasterizer discard");
+    }
+
+    if (ib_fence)
+        wined3d_fence_issue(ib_fence, device);
+    for (i = 0; i < context->buffer_fence_count; ++i)
+        wined3d_fence_issue(context->buffer_fences[i], device);
+
+    if (wined3d_settings.strict_draw_ordering)
+        gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+    context_release(context);
 }
 }
index d264d1c..460fe12 100644 (file)
@@ -16,6 +16,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -46,6 +48,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW,
     WINED3D_CS_OP_SET_SAMPLER,
     WINED3D_CS_OP_SET_SHADER,
     WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW,
     WINED3D_CS_OP_SET_SAMPLER,
     WINED3D_CS_OP_SET_SHADER,
+    WINED3D_CS_OP_SET_BLEND_STATE,
     WINED3D_CS_OP_SET_RASTERIZER_STATE,
     WINED3D_CS_OP_SET_RENDER_STATE,
     WINED3D_CS_OP_SET_TEXTURE_STATE,
     WINED3D_CS_OP_SET_RASTERIZER_STATE,
     WINED3D_CS_OP_SET_RENDER_STATE,
     WINED3D_CS_OP_SET_TEXTURE_STATE,
@@ -91,6 +94,7 @@ struct wined3d_cs_present
     struct wined3d_swapchain *swapchain;
     RECT src_rect;
     RECT dst_rect;
     struct wined3d_swapchain *swapchain;
     RECT src_rect;
     RECT dst_rect;
+    DWORD swap_interval;
     DWORD flags;
 };
 
     DWORD flags;
 };
 
@@ -254,6 +258,12 @@ struct wined3d_cs_set_shader
     struct wined3d_shader *shader;
 };
 
     struct wined3d_shader *shader;
 };
 
+struct wined3d_cs_set_blend_state
+{
+    enum wined3d_cs_op opcode;
+    struct wined3d_blend_state *state;
+};
+
 struct wined3d_cs_set_rasterizer_state
 {
     enum wined3d_cs_op opcode;
 struct wined3d_cs_set_rasterizer_state
 {
     enum wined3d_cs_op opcode;
@@ -396,6 +406,9 @@ struct wined3d_cs_update_sub_resource
     unsigned int sub_resource_idx;
     struct wined3d_box box;
     struct wined3d_sub_resource_data data;
     unsigned int sub_resource_idx;
     struct wined3d_box box;
     struct wined3d_sub_resource_data data;
+#if defined(STAGING_CSMT)
+    BYTE copy_data[1];
+#endif /* STAGING_CSMT */
 };
 
 struct wined3d_cs_add_dirty_texture_region
 };
 
 struct wined3d_cs_add_dirty_texture_region
@@ -444,6 +457,12 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
     swapchain = op->swapchain;
     wined3d_swapchain_set_window(swapchain, op->dst_window_override);
 
     swapchain = op->swapchain;
     wined3d_swapchain_set_window(swapchain, op->dst_window_override);
 
+    if (op->swap_interval && swapchain->desc.swap_interval != op->swap_interval)
+    {
+        swapchain->desc.swap_interval = op->swap_interval;
+        swapchain_update_swap_interval(swapchain);
+    }
+
     swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags);
 
     wined3d_resource_release(&swapchain->front_buffer->resource);
     swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags);
 
     wined3d_resource_release(&swapchain->front_buffer->resource);
@@ -456,7 +475,8 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
 }
 
 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
 }
 
 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
-        const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags)
+        const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
+        DWORD swap_interval, DWORD flags)
 {
     struct wined3d_cs_present *op;
     unsigned int i;
 {
     struct wined3d_cs_present *op;
     unsigned int i;
@@ -468,6 +488,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw
     op->swapchain = swapchain;
     op->src_rect = *src_rect;
     op->dst_rect = *dst_rect;
     op->swapchain = swapchain;
     op->src_rect = *src_rect;
     op->dst_rect = *dst_rect;
+    op->swap_interval = swap_interval;
     op->flags = flags;
 
     pending = InterlockedIncrement(&cs->pending_presents);
     op->flags = flags;
 
     pending = InterlockedIncrement(&cs->pending_presents);
@@ -492,14 +513,11 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw
 
 static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data)
 {
 
 static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data)
 {
-    const struct wined3d_state *state = &cs->state;
     const struct wined3d_cs_clear *op = data;
     struct wined3d_device *device;
     unsigned int i;
     const struct wined3d_cs_clear *op = data;
     struct wined3d_device *device;
     unsigned int i;
-    RECT draw_rect;
 
     device = cs->device;
 
     device = cs->device;
-    wined3d_get_draw_rect(state, &draw_rect);
     device->blitter->ops->blitter_clear(device->blitter, device, op->rt_count, op->fb,
             op->rect_count, op->rects, &op->draw_rect, op->flags, &op->color, op->depth, op->stencil);
 
     device->blitter->ops->blitter_clear(device->blitter, device, op->rt_count, op->fb,
             op->rect_count, op->rects, &op->draw_rect, op->flags, &op->color, op->depth, op->stencil);
 
@@ -520,6 +538,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *
 {
     unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers;
     const struct wined3d_state *state = &cs->device->state;
 {
     unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers;
     const struct wined3d_state *state = &cs->device->state;
+    const struct wined3d_viewport *vp = &state->viewport;
     struct wined3d_cs_clear *op;
     unsigned int i;
 
     struct wined3d_cs_clear *op;
     unsigned int i;
 
@@ -529,7 +548,9 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *
     op->flags = flags;
     op->rt_count = rt_count;
     op->fb = &cs->fb;
     op->flags = flags;
     op->rt_count = rt_count;
     op->fb = &cs->fb;
-    wined3d_get_draw_rect(state, &op->draw_rect);
+    SetRect(&op->draw_rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
+    if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
+        IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rect);
     op->color = *color;
     op->depth = depth;
     op->stencil = stencil;
     op->color = *color;
     op->depth = depth;
     op->stencil = stencil;
@@ -554,17 +575,11 @@ void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined
         const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
 {
     struct wined3d_cs_clear *op;
         const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
 {
     struct wined3d_cs_clear *op;
-    struct
-    {
-        struct wined3d_rendertarget_view *rt;
-        struct wined3d_fb_state fb;
-    } *extra;
+    size_t size;
 
 
-    op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[1]) + sizeof(*extra),
-            WINED3D_CS_QUEUE_DEFAULT);
-    extra = (void *)&op->rects[1];
-    extra->fb.render_targets = &extra->rt;
-    op->fb = &extra->fb;
+    size = FIELD_OFFSET(struct wined3d_cs_clear, rects[1]) + sizeof(struct wined3d_fb_state);
+    op = cs->ops->require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT);
+    op->fb = (void *)&op->rects[1];
 
     op->opcode = WINED3D_CS_OP_CLEAR;
     op->flags = flags;
 
     op->opcode = WINED3D_CS_OP_CLEAR;
     op->flags = flags;
@@ -985,7 +1000,7 @@ static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const v
 {
     const struct wined3d_cs_set_rendertarget_view *op = data;
 
 {
     const struct wined3d_cs_set_rendertarget_view *op = data;
 
-    cs->state.fb->render_targets[op->view_idx] = op->view;
+    cs->fb.render_targets[op->view_idx] = op->view;
     device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
 }
 
     device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
 }
 
@@ -1029,6 +1044,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE));
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE));
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
         device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
+        device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIASCLAMP));
     }
     else if (prev && prev->format->depth_bias_scale != op->view->format->depth_bias_scale)
     {
     }
     else if (prev && prev->format->depth_bias_scale != op->view->format->depth_bias_scale)
     {
@@ -1430,6 +1446,25 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
+static void wined3d_cs_exec_set_blend_state(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_set_blend_state *op = data;
+
+    cs->state.blend_state = op->state;
+    device_invalidate_state(cs->device, STATE_BLEND);
+}
+
+void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state)
+{
+    struct wined3d_cs_set_blend_state *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_SET_BLEND_STATE;
+    op->state = state;
+
+    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+}
+
 static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_set_rasterizer_state *op = data;
 static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_set_rasterizer_state *op = data;
@@ -1669,7 +1704,7 @@ static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data)
     if (!(light_info = wined3d_state_get_light(&cs->state, light_idx)))
     {
         TRACE("Adding new light.\n");
     if (!(light_info = wined3d_state_get_light(&cs->state, light_idx)))
     {
         TRACE("Adding new light.\n");
-        if (!(light_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*light_info))))
+        if (!(light_info = heap_alloc_zero(sizeof(*light_info))))
         {
             ERR("Failed to allocate light info.\n");
             return;
         {
             ERR("Failed to allocate light info.\n");
             return;
@@ -2168,31 +2203,31 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_reso
 static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_update_sub_resource *op = data;
 static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_update_sub_resource *op = data;
+    struct wined3d_resource *resource = op->resource;
     const struct wined3d_box *box = &op->box;
     unsigned int width, height, depth, level;
     struct wined3d_const_bo_address addr;
     struct wined3d_context *context;
     struct wined3d_texture *texture;
 
     const struct wined3d_box *box = &op->box;
     unsigned int width, height, depth, level;
     struct wined3d_const_bo_address addr;
     struct wined3d_context *context;
     struct wined3d_texture *texture;
 
-    if (op->resource->type == WINED3D_RTYPE_BUFFER)
+    context = context_acquire(cs->device, NULL, 0);
+
+    if (resource->type == WINED3D_RTYPE_BUFFER)
     {
     {
-        struct wined3d_buffer *buffer = buffer_from_resource(op->resource);
+        struct wined3d_buffer *buffer = buffer_from_resource(resource);
 
 
-        context = context_acquire(op->resource->device, NULL, 0);
         if (!wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER))
         {
             ERR("Failed to load buffer location.\n");
         if (!wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER))
         {
             ERR("Failed to load buffer location.\n");
-            context_release(context);
             goto done;
         }
 
         wined3d_buffer_upload_data(buffer, context, box, op->data.data);
         wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER);
             goto done;
         }
 
         wined3d_buffer_upload_data(buffer, context, box, op->data.data);
         wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER);
-        context_release(context);
         goto done;
     }
 
         goto done;
     }
 
-    texture = wined3d_texture_from_resource(op->resource);
+    texture = wined3d_texture_from_resource(resource);
 
     level = op->sub_resource_idx % texture->level_count;
     width = wined3d_texture_get_level_width(texture, level);
 
     level = op->sub_resource_idx % texture->level_count;
     width = wined3d_texture_get_level_width(texture, level);
@@ -2202,8 +2237,6 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
     addr.buffer_object = 0;
     addr.addr = op->data.data;
 
     addr.buffer_object = 0;
     addr.addr = op->data.data;
 
-    context = context_acquire(op->resource->device, NULL, 0);
-
     /* Only load the sub-resource for partial updates. */
     if (!box->left && !box->top && !box->front
             && box->right == width && box->bottom == height && box->back == depth)
     /* Only load the sub-resource for partial updates. */
     if (!box->left && !box->top && !box->front
             && box->right == width && box->bottom == height && box->back == depth)
@@ -2215,13 +2248,13 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
     wined3d_texture_upload_data(texture, op->sub_resource_idx, context,
             box, &addr, op->data.row_pitch, op->data.slice_pitch);
 
     wined3d_texture_upload_data(texture, op->sub_resource_idx, context,
             box, &addr, op->data.row_pitch, op->data.slice_pitch);
 
-    context_release(context);
-
     wined3d_texture_validate_location(texture, op->sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_invalidate_location(texture, op->sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
 
 done:
     wined3d_texture_validate_location(texture, op->sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_invalidate_location(texture, op->sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
 
 done:
-    wined3d_resource_release(op->resource);
+    context_release(context);
+
+    wined3d_resource_release(resource);
 }
 
 void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource,
 }
 
 void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource,
@@ -2229,6 +2262,53 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r
         unsigned int slice_pitch)
 {
     struct wined3d_cs_update_sub_resource *op;
         unsigned int slice_pitch)
 {
     struct wined3d_cs_update_sub_resource *op;
+#if defined(STAGING_CSMT)
+    size_t data_size, size;
+
+    if (resource->type != WINED3D_RTYPE_BUFFER && resource->format_flags & WINED3DFMT_FLAG_BLOCKS)
+        goto no_async;
+
+    data_size = 0;
+    switch (resource->type)
+    {
+        case WINED3D_RTYPE_TEXTURE_3D:
+            data_size += (box->back - box->front - 1) * slice_pitch;
+            /* fall-through */
+        case WINED3D_RTYPE_TEXTURE_2D:
+            data_size += (box->bottom - box->top - 1) * row_pitch;
+            /* fall-through */
+        case WINED3D_RTYPE_TEXTURE_1D:
+            data_size += (box->right - box->left) * resource->format->byte_count;
+            break;
+        case WINED3D_RTYPE_BUFFER:
+            data_size = box->right - box->left;
+            break;
+        case WINED3D_RTYPE_NONE:
+            return;
+    }
+
+    size = FIELD_OFFSET(struct wined3d_cs_update_sub_resource, copy_data[data_size]);
+    if (!cs->ops->check_space(cs, size, WINED3D_CS_QUEUE_DEFAULT))
+        goto no_async;
+
+    op = cs->ops->require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
+    op->resource = resource;
+    op->sub_resource_idx = sub_resource_idx;
+    op->box = *box;
+    op->data.row_pitch = row_pitch;
+    op->data.slice_pitch = slice_pitch;
+    op->data.data = op->copy_data;
+    memcpy(op->copy_data, data, data_size);
+
+    wined3d_resource_acquire(resource);
+
+    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+    return;
+
+no_async:
+    wined3d_resource_wait_idle(resource);
+#endif /* STAGING_CSMT */
 
     op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP);
     op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
 
     op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP);
     op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
@@ -2242,8 +2322,10 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r
     wined3d_resource_acquire(resource);
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP);
     wined3d_resource_acquire(resource);
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP);
+#if !defined(STAGING_CSMT)
     /* The data pointer may go away, so we need to wait until it is read.
      * Copying the data may be faster if it's small. */
     /* The data pointer may go away, so we need to wait until it is read.
      * Copying the data may be faster if it's small. */
+#endif /* STAGING_CSMT */
     cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP);
 }
 
     cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP);
 }
 
@@ -2322,6 +2404,7 @@ static void wined3d_cs_exec_copy_uav_counter(struct wined3d_cs *cs, const void *
     context_release(context);
 
     wined3d_resource_release(&op->buffer->resource);
     context_release(context);
 
     wined3d_resource_release(&op->buffer->resource);
+    wined3d_resource_release(view->resource);
 }
 
 void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer,
 }
 
 void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer,
@@ -2336,6 +2419,7 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buff
     op->view = uav;
 
     wined3d_resource_acquire(&dst_buffer->resource);
     op->view = uav;
 
     wined3d_resource_acquire(&dst_buffer->resource);
+    wined3d_resource_acquire(uav->resource);
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
@@ -2397,6 +2481,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW   */ wined3d_cs_exec_set_unordered_access_view,
     /* WINED3D_CS_OP_SET_SAMPLER                 */ wined3d_cs_exec_set_sampler,
     /* WINED3D_CS_OP_SET_SHADER                  */ wined3d_cs_exec_set_shader,
     /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW   */ wined3d_cs_exec_set_unordered_access_view,
     /* WINED3D_CS_OP_SET_SAMPLER                 */ wined3d_cs_exec_set_sampler,
     /* WINED3D_CS_OP_SET_SHADER                  */ wined3d_cs_exec_set_shader,
+    /* WINED3D_CS_OP_SET_BLEND_STATE             */ wined3d_cs_exec_set_blend_state,
     /* WINED3D_CS_OP_SET_RASTERIZER_STATE        */ wined3d_cs_exec_set_rasterizer_state,
     /* WINED3D_CS_OP_SET_RENDER_STATE            */ wined3d_cs_exec_set_render_state,
     /* WINED3D_CS_OP_SET_TEXTURE_STATE           */ wined3d_cs_exec_set_texture_state,
     /* WINED3D_CS_OP_SET_RASTERIZER_STATE        */ wined3d_cs_exec_set_rasterizer_state,
     /* WINED3D_CS_OP_SET_RENDER_STATE            */ wined3d_cs_exec_set_render_state,
     /* WINED3D_CS_OP_SET_TEXTURE_STATE           */ wined3d_cs_exec_set_texture_state,
@@ -2423,6 +2508,13 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_GENERATE_MIPMAPS            */ wined3d_cs_exec_generate_mipmaps,
 };
 
     /* WINED3D_CS_OP_GENERATE_MIPMAPS            */ wined3d_cs_exec_generate_mipmaps,
 };
 
+#if defined(STAGING_CSMT)
+static BOOL wined3d_cs_st_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
+{
+    return TRUE;
+}
+
+#endif /* STAGING_CSMT */
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
 {
     if (size > (cs->data_size - cs->end))
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
 {
     if (size > (cs->data_size - cs->end))
@@ -2432,9 +2524,9 @@ static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enu
 
         new_size = max(size, cs->data_size * 2);
         if (!cs->end)
 
         new_size = max(size, cs->data_size * 2);
         if (!cs->end)
-            new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, new_size);
+            new_data = heap_realloc(cs->data, new_size);
         else
         else
-            new_data = HeapAlloc(GetProcessHeap(), 0, new_size);
+            new_data = heap_alloc(new_size);
         if (!new_data)
             return NULL;
 
         if (!new_data)
             return NULL;
 
@@ -2467,7 +2559,7 @@ static void wined3d_cs_st_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id
     if (cs->data == data)
         cs->start = cs->end = start;
     else if (!start)
     if (cs->data == data)
         cs->start = cs->end = start;
     else if (!start)
-        HeapFree(GetProcessHeap(), 0, data);
+        heap_free(data);
 }
 
 static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id)
 }
 
 static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id)
@@ -2476,6 +2568,9 @@ static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id
 
 static const struct wined3d_cs_ops wined3d_cs_st_ops =
 {
 
 static const struct wined3d_cs_ops wined3d_cs_st_ops =
 {
+#if defined(STAGING_CSMT)
+    wined3d_cs_st_check_space,
+#endif /* STAGING_CSMT */
     wined3d_cs_st_require_space,
     wined3d_cs_st_submit,
     wined3d_cs_st_finish,
     wined3d_cs_st_require_space,
     wined3d_cs_st_submit,
     wined3d_cs_st_finish,
@@ -2512,6 +2607,21 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id
     wined3d_cs_queue_submit(&cs->queue[queue_id], cs);
 }
 
     wined3d_cs_queue_submit(&cs->queue[queue_id], cs);
 }
 
+#if defined(STAGING_CSMT)
+static BOOL wined3d_cs_queue_check_space(struct wined3d_cs_queue *queue, size_t size)
+{
+    size_t queue_size = ARRAY_SIZE(queue->data);
+    size_t header_size, packet_size, remaining;
+
+    header_size = FIELD_OFFSET(struct wined3d_cs_packet, data[0]);
+    size = (size + header_size - 1) & ~(header_size - 1);
+    packet_size = FIELD_OFFSET(struct wined3d_cs_packet, data[size]);
+
+    remaining = queue_size - queue->head;
+    return (remaining >= packet_size);
+}
+
+#endif /* STAGING_CSMT */
 static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size, struct wined3d_cs *cs)
 {
     size_t queue_size = ARRAY_SIZE(queue->data);
 static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size, struct wined3d_cs *cs)
 {
     size_t queue_size = ARRAY_SIZE(queue->data);
@@ -2573,6 +2683,16 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size
     return packet->data;
 }
 
     return packet->data;
 }
 
+#if defined(STAGING_CSMT)
+static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
+{
+    if (cs->thread_id == GetCurrentThreadId())
+        return wined3d_cs_st_check_space(cs, size, queue_id);
+
+    return wined3d_cs_queue_check_space(&cs->queue[queue_id], size);
+}
+
+#endif /* STAGING_CSMT */
 static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
 {
     if (cs->thread_id == GetCurrentThreadId())
 static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
 {
     if (cs->thread_id == GetCurrentThreadId())
@@ -2595,6 +2715,9 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id
 
 static const struct wined3d_cs_ops wined3d_cs_mt_ops =
 {
 
 static const struct wined3d_cs_ops wined3d_cs_mt_ops =
 {
+#if defined(STAGING_CSMT)
+    wined3d_cs_mt_check_space,
+#endif /* STAGING_CSMT */
     wined3d_cs_mt_require_space,
     wined3d_cs_mt_submit,
     wined3d_cs_mt_finish,
     wined3d_cs_mt_require_space,
     wined3d_cs_mt_submit,
     wined3d_cs_mt_finish,
@@ -2707,23 +2830,17 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct wined3d_cs *cs;
 
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct wined3d_cs *cs;
 
-    if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs))))
+    if (!(cs = heap_alloc_zero(sizeof(*cs))))
         return NULL;
 
     cs->ops = &wined3d_cs_st_ops;
     cs->device = device;
 
         return NULL;
 
     cs->ops = &wined3d_cs_st_ops;
     cs->device = device;
 
-    if (!(cs->fb.render_targets = wined3d_calloc(gl_info->limits.buffers, sizeof(*cs->fb.render_targets))))
-    {
-        HeapFree(GetProcessHeap(), 0, cs);
-        return NULL;
-    }
-
     state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info,
             WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
 
     cs->data_size = WINED3D_INITIAL_CS_SIZE;
     state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info,
             WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
 
     cs->data_size = WINED3D_INITIAL_CS_SIZE;
-    if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size)))
+    if (!(cs->data = heap_alloc(cs->data_size)))
         goto fail;
 
     if (wined3d_settings.cs_multithreaded
         goto fail;
 
     if (wined3d_settings.cs_multithreaded
@@ -2734,7 +2851,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
         if (!(cs->event = CreateEventW(NULL, FALSE, FALSE, NULL)))
         {
             ERR("Failed to create command stream event.\n");
         if (!(cs->event = CreateEventW(NULL, FALSE, FALSE, NULL)))
         {
             ERR("Failed to create command stream event.\n");
-            HeapFree(GetProcessHeap(), 0, cs->data);
+            heap_free(cs->data);
             goto fail;
         }
 
             goto fail;
         }
 
@@ -2743,7 +2860,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
         {
             ERR("Failed to get wined3d module handle.\n");
             CloseHandle(cs->event);
         {
             ERR("Failed to get wined3d module handle.\n");
             CloseHandle(cs->event);
-            HeapFree(GetProcessHeap(), 0, cs->data);
+            heap_free(cs->data);
             goto fail;
         }
 
             goto fail;
         }
 
@@ -2752,7 +2869,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
             ERR("Failed to create wined3d command stream thread.\n");
             FreeLibrary(cs->wined3d_module);
             CloseHandle(cs->event);
             ERR("Failed to create wined3d command stream thread.\n");
             FreeLibrary(cs->wined3d_module);
             CloseHandle(cs->event);
-            HeapFree(GetProcessHeap(), 0, cs->data);
+            heap_free(cs->data);
             goto fail;
         }
     }
             goto fail;
         }
     }
@@ -2761,8 +2878,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
 
 fail:
     state_cleanup(&cs->state);
 
 fail:
     state_cleanup(&cs->state);
-    HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
-    HeapFree(GetProcessHeap(), 0, cs);
+    heap_free(cs);
     return NULL;
 }
 
     return NULL;
 }
 
@@ -2777,7 +2893,6 @@ void wined3d_cs_destroy(struct wined3d_cs *cs)
     }
 
     state_cleanup(&cs->state);
     }
 
     state_cleanup(&cs->state);
-    HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
-    HeapFree(GetProcessHeap(), 0, cs->data);
-    HeapFree(GetProcessHeap(), 0, cs);
+    heap_free(cs->data);
+    heap_free(cs);
 }
 }
index fdc4f95..e2b27e0 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -141,11 +149,7 @@ BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *c
 
     TRACE("Adding context %p.\n", context);
 
 
     TRACE("Adding context %p.\n", context);
 
-    if (!device->contexts) new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array));
-    else new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts,
-            sizeof(*new_array) * (device->context_count + 1));
-
-    if (!new_array)
+    if (!(new_array = heap_realloc(device->contexts, sizeof(*new_array) * (device->context_count + 1))))
     {
         ERR("Failed to grow the context array.\n");
         return FALSE;
     {
         ERR("Failed to grow the context array.\n");
         return FALSE;
@@ -181,14 +185,13 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context
 
     if (!--device->context_count)
     {
 
     if (!--device->context_count)
     {
-        HeapFree(GetProcessHeap(), 0, device->contexts);
+        heap_free(device->contexts);
         device->contexts = NULL;
         return;
     }
 
     memmove(&device->contexts[i], &device->contexts[i + 1], (device->context_count - i) * sizeof(*device->contexts));
         device->contexts = NULL;
         return;
     }
 
     memmove(&device->contexts[i], &device->contexts[i + 1], (device->context_count - i) * sizeof(*device->contexts));
-    new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, device->context_count * sizeof(*device->contexts));
-    if (!new_array)
+    if (!(new_array = heap_realloc(device->contexts, device->context_count * sizeof(*device->contexts))))
     {
         ERR("Failed to shrink context array. Oh well.\n");
         return;
     {
         ERR("Failed to shrink context array. Oh well.\n");
         return;
@@ -197,10 +200,14 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context
     device->contexts = new_array;
 }
 
     device->contexts = new_array;
 }
 
-static BOOL is_full_clear(const struct wined3d_surface *target, const RECT *draw_rect, const RECT *clear_rect)
+static BOOL is_full_clear(const struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        const RECT *draw_rect, const RECT *clear_rect)
 {
 {
-    unsigned int height = wined3d_texture_get_level_height(target->container, target->texture_level);
-    unsigned int width = wined3d_texture_get_level_width(target->container, target->texture_level);
+    unsigned int width, height, level;
+
+    level = sub_resource_idx % texture->level_count;
+    width = wined3d_texture_get_level_width(texture, level);
+    height = wined3d_texture_get_level_height(texture, level);
 
     /* partial draw rect */
     if (draw_rect->left || draw_rect->top || draw_rect->right < width || draw_rect->bottom < height)
 
     /* partial draw rect */
     if (draw_rect->left || draw_rect->top || draw_rect->right < width || draw_rect->bottom < height)
@@ -259,7 +266,8 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
         {
             struct wined3d_texture *rt = wined3d_texture_from_resource(rtv->resource);
 
         {
             struct wined3d_texture *rt = wined3d_texture_from_resource(rtv->resource);
 
-            if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, rect_count ? clear_rect : NULL))
+            if (flags & WINED3DCLEAR_TARGET && !is_full_clear(rt, rtv->sub_resource_idx,
+                    draw_rect, rect_count ? clear_rect : NULL))
                 wined3d_texture_load_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding);
             else
                 wined3d_texture_prepare_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding);
                 wined3d_texture_load_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding);
             else
                 wined3d_texture_prepare_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding);
@@ -273,23 +281,29 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
     }
     else
     {
     }
     else
     {
+        unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->container->level_count;
+
         render_offscreen = TRUE;
         render_offscreen = TRUE;
-        drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil->container,
-                depth_stencil->texture_level);
-        drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil->container,
-                depth_stencil->texture_level);
+        drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil->container, ds_level);
+        drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil->container, ds_level);
     }
 
     }
 
-    if (depth_stencil && render_offscreen)
-        wined3d_texture_prepare_location(depth_stencil->container,
-                dsv->sub_resource_idx, context, dsv->resource->draw_binding);
-
-    if (flags & WINED3DCLEAR_ZBUFFER)
+    if (depth_stencil)
     {
     {
-        DWORD location = render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
+        DWORD ds_location = render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
+        struct wined3d_texture *ds = wined3d_texture_from_resource(dsv->resource);
 
 
-        wined3d_texture_load_location(depth_stencil->container,
-                dsv->sub_resource_idx, context, location);
+        if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)
+                && !is_full_clear(ds, dsv->sub_resource_idx, draw_rect, rect_count ? clear_rect : NULL))
+            wined3d_texture_load_location(ds, dsv->sub_resource_idx, context, ds_location);
+        else
+            wined3d_texture_prepare_location(ds, dsv->sub_resource_idx, context, ds_location);
+
+        if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
+        {
+            wined3d_texture_validate_location(ds, dsv->sub_resource_idx, ds_location);
+            wined3d_texture_invalidate_location(ds, dsv->sub_resource_idx, ~ds_location);
+        }
     }
 
     if (!context_apply_clear_state(context, state, rt_count, fb))
     }
 
     if (!context_apply_clear_state(context, state, rt_count, fb))
@@ -316,11 +330,6 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
 
     if (flags & WINED3DCLEAR_ZBUFFER)
     {
 
     if (flags & WINED3DCLEAR_ZBUFFER)
     {
-        DWORD location = render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
-
-        wined3d_texture_validate_location(depth_stencil->container, dsv->sub_resource_idx, location);
-        wined3d_texture_invalidate_location(depth_stencil->container, dsv->sub_resource_idx, ~location);
-
         gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE);
         context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE));
         gl_info->gl_ops.gl.p_glClearDepth(depth);
         gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE);
         context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE));
         gl_info->gl_ops.gl.p_glClearDepth(depth);
@@ -374,10 +383,8 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
         }
 
         gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
         }
 
         gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
+        for (i = 0; i < MAX_RENDER_TARGETS; ++i)
+            context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
         gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b, color->a);
         checkGLcall("glClearColor");
         clear_mask = clear_mask | GL_COLOR_BUFFER_BIT;
         gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b, color->a);
         checkGLcall("glClearColor");
         clear_mask = clear_mask | GL_COLOR_BUFFER_BIT;
@@ -482,7 +489,7 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
 
         for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
         {
 
         for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
         {
-            HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
+            heap_free(device->multistate_funcs[i]);
             device->multistate_funcs[i] = NULL;
         }
 
             device->multistate_funcs[i] = NULL;
         }
 
@@ -509,7 +516,7 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
 
         wined3d_decref(device->wined3d);
         device->wined3d = NULL;
 
         wined3d_decref(device->wined3d);
         device->wined3d = NULL;
-        HeapFree(GetProcessHeap(), 0, device);
+        heap_free(device);
         TRACE("Freed device %p.\n", device);
     }
 
         TRACE("Freed device %p.\n", device);
     }
 
@@ -562,7 +569,7 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
     desc.usage = WINED3DUSAGE_DYNAMIC;
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
     desc.usage = WINED3DUSAGE_DYNAMIC;
-    desc.pool = WINED3D_POOL_DEFAULT;
+    desc.access = WINED3D_RESOURCE_ACCESS_GPU;
     desc.width = bm.bmWidth;
     desc.height = bm.bmHeight;
     desc.depth = 1;
     desc.width = bm.bmWidth;
     desc.height = bm.bmHeight;
     desc.depth = 1;
@@ -598,6 +605,7 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
 {
     const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
 {
     const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    struct wined3d_dummy_textures *textures = &device->dummy_textures;
     unsigned int i;
     DWORD color;
 
     unsigned int i;
     DWORD color;
 
@@ -612,59 +620,45 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
      * to each texture stage when the currently set D3D texture is NULL. */
     context_active_texture(context, gl_info, 0);
 
      * to each texture stage when the currently set D3D texture is NULL. */
     context_active_texture(context, gl_info, 0);
 
-    gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_2d);
-    checkGLcall("glGenTextures");
-    TRACE("Dummy 2D texture given name %u.\n", device->dummy_textures.tex_2d);
-
-    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d);
-    checkGLcall("glBindTexture");
+    gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d);
+    TRACE("Dummy 1D texture given name %u.\n", textures->tex_1d);
+    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
+    gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 1, 0,
+            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
 
 
+    gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d);
+    TRACE("Dummy 2D texture given name %u.\n", textures->tex_2d);
+    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
     gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0,
             GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
     gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0,
             GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
-    checkGLcall("glTexImage2D");
 
     if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
     {
 
     if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
     {
-        gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_rect);
-        checkGLcall("glGenTextures");
-        TRACE("Dummy rectangle texture given name %u.\n", device->dummy_textures.tex_rect);
-
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect);
-        checkGLcall("glBindTexture");
-
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_rect);
+        TRACE("Dummy rectangle texture given name %u.\n", textures->tex_rect);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures->tex_rect);
         gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 1, 1, 0,
                 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
         gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 1, 1, 0,
                 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
-        checkGLcall("glTexImage2D");
     }
 
     if (gl_info->supported[EXT_TEXTURE3D])
     {
     }
 
     if (gl_info->supported[EXT_TEXTURE3D])
     {
-        gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_3d);
-        checkGLcall("glGenTextures");
-        TRACE("Dummy 3D texture given name %u.\n", device->dummy_textures.tex_3d);
-
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d);
-        checkGLcall("glBindTexture");
-
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_3d);
+        TRACE("Dummy 3D texture given name %u.\n", textures->tex_3d);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, textures->tex_3d);
         GL_EXTCALL(glTexImage3D(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");
     }
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
     {
     }
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
     {
-        gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_cube);
-        checkGLcall("glGenTextures");
-        TRACE("Dummy cube texture given name %u.\n", device->dummy_textures.tex_cube);
-
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube);
-        checkGLcall("glBindTexture");
-
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_cube);
+        TRACE("Dummy cube texture given name %u.\n", textures->tex_cube);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, textures->tex_cube);
         for (i = GL_TEXTURE_CUBE_MAP_POSITIVE_X; i <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++i)
         {
             gl_info->gl_ops.gl.p_glTexImage2D(i, 0, GL_RGBA8, 1, 1, 0,
                     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
         for (i = GL_TEXTURE_CUBE_MAP_POSITIVE_X; i <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++i)
         {
             gl_info->gl_ops.gl.p_glTexImage2D(i, 0, GL_RGBA8, 1, 1, 0,
                     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
-            checkGLcall("glTexImage2D");
         }
     }
 
         }
     }
 
@@ -672,32 +666,29 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
     {
         DWORD cube_array_data[6];
 
     {
         DWORD cube_array_data[6];
 
-        gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_cube_array);
-        checkGLcall("glGenTextures");
-        TRACE("Dummy cube array texture given name %u.\n", device->dummy_textures.tex_cube_array);
-
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, device->dummy_textures.tex_cube_array);
-        checkGLcall("glBindTexture");
-
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_cube_array);
+        TRACE("Dummy cube array texture given name %u.\n", textures->tex_cube_array);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures->tex_cube_array);
         for (i = 0; i < ARRAY_SIZE(cube_array_data); ++i)
             cube_array_data[i] = color;
         GL_EXTCALL(glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA8, 1, 1, 6, 0,
                     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, cube_array_data));
         for (i = 0; i < ARRAY_SIZE(cube_array_data); ++i)
             cube_array_data[i] = color;
         GL_EXTCALL(glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA8, 1, 1, 6, 0,
                     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, cube_array_data));
-        checkGLcall("glTexImage3D");
     }
 
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
     {
     }
 
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
     {
-        gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_2d_array);
-        checkGLcall("glGenTextures");
-        TRACE("Dummy 2D array texture given name %u.\n", device->dummy_textures.tex_2d_array);
 
 
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array);
-        checkGLcall("glBindTexture");
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d_array);
+        TRACE("Dummy 1D array texture given name %u.\n", textures->tex_1d_array);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
+        gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA8, 1, 1, 0,
+                GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
 
 
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d_array);
+        TRACE("Dummy 2D array texture given name %u.\n", textures->tex_2d_array);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
         GL_EXTCALL(glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 1, 0,
                     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
         GL_EXTCALL(glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 1, 0,
                     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
-        checkGLcall("glTexImage3D");
     }
 
     if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
     }
 
     if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
@@ -708,52 +699,81 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
         GL_EXTCALL(glBindBuffer(GL_TEXTURE_BUFFER, buffer));
         GL_EXTCALL(glBufferData(GL_TEXTURE_BUFFER, sizeof(color), &color, GL_STATIC_DRAW));
         GL_EXTCALL(glBindBuffer(GL_TEXTURE_BUFFER, 0));
         GL_EXTCALL(glBindBuffer(GL_TEXTURE_BUFFER, buffer));
         GL_EXTCALL(glBufferData(GL_TEXTURE_BUFFER, sizeof(color), &color, GL_STATIC_DRAW));
         GL_EXTCALL(glBindBuffer(GL_TEXTURE_BUFFER, 0));
-        checkGLcall("Create buffer object");
-
-        gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_buffer);
-        checkGLcall("glGenTextures");
-        TRACE("Dummy buffer texture given name %u.\n", device->dummy_textures.tex_buffer);
 
 
-        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, device->dummy_textures.tex_buffer);
-        checkGLcall("glBindTexture");
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_buffer);
+        TRACE("Dummy buffer texture given name %u.\n", textures->tex_buffer);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer);
         GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA8, buffer));
         GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA8, buffer));
-        checkGLcall("glTexBuffer");
-
         GL_EXTCALL(glDeleteBuffers(1, &buffer));
         GL_EXTCALL(glDeleteBuffers(1, &buffer));
-        checkGLcall("glDeleteBuffers");
     }
 
     }
 
+    if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+    {
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d_ms);
+        TRACE("Dummy multisample texture given name %u.\n", textures->tex_2d_ms);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textures->tex_2d_ms);
+        GL_EXTCALL(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_TRUE));
+
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d_ms_array);
+        TRACE("Dummy multisample array texture given name %u.\n", textures->tex_2d_ms_array);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, textures->tex_2d_ms_array);
+        GL_EXTCALL(glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, GL_RGBA8, 1, 1, 1, GL_TRUE));
+
+        if (gl_info->supported[ARB_CLEAR_TEXTURE])
+        {
+            GL_EXTCALL(glClearTexImage(textures->tex_2d_ms, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
+            GL_EXTCALL(glClearTexImage(textures->tex_2d_ms_array, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
+        }
+        else
+        {
+            WARN("ARB_clear_texture is currently required to clear dummy multisample textures.\n");
+        }
+    }
+
+    checkGLcall("create dummy textures");
+
     context_bind_dummy_textures(device, context);
 }
 
 /* Context activation is done by the caller. */
 static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d_context *context)
 {
     context_bind_dummy_textures(device, context);
 }
 
 /* Context activation is done by the caller. */
 static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d_context *context)
 {
+    struct wined3d_dummy_textures *dummy_textures = &device->dummy_textures;
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
+    if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+    {
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_ms);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_ms_array);
+    }
+
     if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
     if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_buffer);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_buffer);
 
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
 
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d_array);
+    {
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d_array);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array);
+    }
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_cube_array);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_cube_array);
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_cube);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_cube);
 
     if (gl_info->supported[EXT_TEXTURE3D])
 
     if (gl_info->supported[EXT_TEXTURE3D])
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_3d);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_3d);
 
     if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
 
     if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_rect);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_rect);
 
 
-    gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d);
+    gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d);
+    gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d);
 
 
-    checkGLcall("Delete dummy textures");
+    checkGLcall("delete dummy textures");
 
 
-    memset(&device->dummy_textures, 0, sizeof(device->dummy_textures));
+    memset(dummy_textures, 0, sizeof(*dummy_textures));
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -944,15 +964,12 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi
     BOOL ds_enable = swapchain->desc.enable_auto_depth_stencil;
     unsigned int i;
 
     BOOL ds_enable = swapchain->desc.enable_auto_depth_stencil;
     unsigned int i;
 
-    if (device->fb.render_targets)
+    for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
     {
     {
-        for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
-        {
-            wined3d_device_set_rendertarget_view(device, i, NULL, FALSE);
-        }
-        if (device->back_buffer_view)
-            wined3d_device_set_rendertarget_view(device, 0, device->back_buffer_view, TRUE);
+        wined3d_device_set_rendertarget_view(device, i, NULL, FALSE);
     }
     }
+    if (device->back_buffer_view)
+        wined3d_device_set_rendertarget_view(device, 0, device->back_buffer_view, TRUE);
 
     wined3d_device_set_depth_stencil_view(device, ds_enable ? device->auto_depth_stencil_view : NULL);
 }
 
     wined3d_device_set_depth_stencil_view(device, ds_enable ? device->auto_depth_stencil_view : NULL);
 }
@@ -1045,7 +1062,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
         struct wined3d_swapchain_desc *swapchain_desc)
 {
     static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f};
         struct wined3d_swapchain_desc *swapchain_desc)
 {
     static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f};
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct wined3d_swapchain *swapchain = NULL;
     DWORD clear_flags = 0;
     HRESULT hr;
     struct wined3d_swapchain *swapchain = NULL;
     DWORD clear_flags = 0;
     HRESULT hr;
@@ -1057,16 +1073,14 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
     if (device->wined3d->flags & WINED3D_NO3D)
         return WINED3DERR_INVALIDCALL;
 
     if (device->wined3d->flags & WINED3D_NO3D)
         return WINED3DERR_INVALIDCALL;
 
-    if (!(device->fb.render_targets = wined3d_calloc(gl_info->limits.buffers, sizeof(*device->fb.render_targets))))
-        return E_OUTOFMEMORY;
+    memset(device->fb.render_targets, 0, sizeof(device->fb.render_targets));
 
     /* Setup the implicit swapchain. This also initializes a context. */
 
     /* Setup the implicit swapchain. This also initializes a context. */
-    TRACE("Creating implicit swapchain\n");
-    hr = device->device_parent->ops->create_swapchain(device->device_parent,
-            swapchain_desc, &swapchain);
-    if (FAILED(hr))
+    TRACE("Creating implicit swapchain.\n");
+    if (FAILED(hr = device->device_parent->ops->create_swapchain(device->device_parent,
+            swapchain_desc, &swapchain)))
     {
     {
-        WARN("Failed to create implicit swapchain\n");
+        WARN("Failed to create implicit swapchain.\n");
         goto err_out;
     }
 
         goto err_out;
     }
 
@@ -1090,7 +1104,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
     }
 
     device->swapchain_count = 1;
     }
 
     device->swapchain_count = 1;
-    if (!(device->swapchains = wined3d_calloc(device->swapchain_count, sizeof(*device->swapchains))))
+    if (!(device->swapchains = heap_calloc(device->swapchain_count, sizeof(*device->swapchains))))
     {
         ERR("Out of memory!\n");
         goto err_out;
     {
         ERR("Out of memory!\n");
         goto err_out;
@@ -1103,7 +1117,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
 
     device->contexts[0]->last_was_rhw = 0;
 
 
     device->contexts[0]->last_was_rhw = 0;
 
-    TRACE("All defaults now set up, leaving 3D init.\n");
+    TRACE("All defaults now set up.\n");
 
     /* Clear the screen */
     if (swapchain->back_buffers && swapchain->back_buffers[0])
 
     /* Clear the screen */
     if (swapchain->back_buffers && swapchain->back_buffers[0])
@@ -1120,13 +1134,12 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
     return WINED3D_OK;
 
 err_out:
     return WINED3D_OK;
 
 err_out:
-    HeapFree(GetProcessHeap(), 0, device->swapchains);
+    heap_free(device->swapchains);
     device->swapchain_count = 0;
     if (device->back_buffer_view)
         wined3d_rendertarget_view_decref(device->back_buffer_view);
     if (swapchain)
         wined3d_swapchain_decref(swapchain);
     device->swapchain_count = 0;
     if (device->back_buffer_view)
         wined3d_rendertarget_view_decref(device->back_buffer_view);
     if (swapchain)
         wined3d_swapchain_decref(swapchain);
-    HeapFree(GetProcessHeap(), 0, device->fb.render_targets);
 
     return hr;
 }
 
     return hr;
 }
@@ -1150,7 +1163,7 @@ HRESULT CDECL wined3d_device_init_gdi(struct wined3d_device *device,
     }
 
     device->swapchain_count = 1;
     }
 
     device->swapchain_count = 1;
-    if (!(device->swapchains = wined3d_calloc(device->swapchain_count, sizeof(*device->swapchains))))
+    if (!(device->swapchains = heap_calloc(device->swapchain_count, sizeof(*device->swapchains))))
     {
         ERR("Out of memory!\n");
         goto err_out;
     {
         ERR("Out of memory!\n");
         goto err_out;
@@ -1160,7 +1173,7 @@ HRESULT CDECL wined3d_device_init_gdi(struct wined3d_device *device,
     if (!(device->blitter = wined3d_cpu_blitter_create()))
     {
         ERR("Failed to create CPU blitter.\n");
     if (!(device->blitter = wined3d_cpu_blitter_create()))
     {
         ERR("Failed to create CPU blitter.\n");
-        HeapFree(GetProcessHeap(), 0, device->swapchains);
+        heap_free(device->swapchains);
         device->swapchain_count = 0;
         goto err_out;
     }
         device->swapchain_count = 0;
         goto err_out;
     }
@@ -1181,7 +1194,7 @@ static void device_free_sampler(struct wine_rb_entry *entry, void *context)
 
 HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
 {
 
 HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
 {
-    UINT i;
+    unsigned int i;
 
     TRACE("device %p.\n", device);
 
 
     TRACE("device %p.\n", device);
 
@@ -1199,6 +1212,9 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
 
     wine_rb_clear(&device->samplers, device_free_sampler, NULL);
 
 
     wine_rb_clear(&device->samplers, device_free_sampler, NULL);
 
+#if defined(STAGING_CSMT)
+    context_set_current(NULL);
+#endif /* STAGING_CSMT */
     wined3d_device_delete_opengl_contexts(device);
 
     if (device->fb.depth_stencil)
     wined3d_device_delete_opengl_contexts(device);
 
     if (device->fb.depth_stencil)
@@ -1237,13 +1253,10 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
             FIXME("Something's still holding the implicit swapchain.\n");
     }
 
             FIXME("Something's still holding the implicit swapchain.\n");
     }
 
-    HeapFree(GetProcessHeap(), 0, device->swapchains);
+    heap_free(device->swapchains);
     device->swapchains = NULL;
     device->swapchain_count = 0;
 
     device->swapchains = NULL;
     device->swapchain_count = 0;
 
-    HeapFree(GetProcessHeap(), 0, device->fb.render_targets);
-    device->fb.render_targets = NULL;
-
     device->d3d_initialized = FALSE;
 
     return WINED3D_OK;
     device->d3d_initialized = FALSE;
 
     return WINED3D_OK;
@@ -1262,7 +1275,7 @@ HRESULT CDECL wined3d_device_uninit_gdi(struct wined3d_device *device)
             FIXME("Something's still holding the implicit swapchain.\n");
     }
 
             FIXME("Something's still holding the implicit swapchain.\n");
     }
 
-    HeapFree(GetProcessHeap(), 0, device->swapchains);
+    heap_free(device->swapchains);
     device->swapchains = NULL;
     device->swapchain_count = 0;
     return WINED3D_OK;
     device->swapchains = NULL;
     device->swapchain_count = 0;
     return WINED3D_OK;
@@ -1284,8 +1297,33 @@ void CDECL wined3d_device_set_multithreaded(struct wined3d_device *device)
 
 UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device *device)
 {
 
 UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device *device)
 {
+    /* const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; */
+
     TRACE("device %p.\n", device);
 
     TRACE("device %p.\n", device);
 
+    /* We can not acquire the context unless there is a swapchain. */
+    /*
+    if (device->swapchains && gl_info->supported[NVX_GPU_MEMORY_INFO] &&
+            !wined3d_settings.emulated_textureram)
+    {
+        GLint vram_free_kb;
+        UINT64 vram_free;
+
+        struct wined3d_context *context = context_acquire(device, NULL, 0);
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &vram_free_kb);
+        vram_free = (UINT64)vram_free_kb * 1024;
+        context_release(context);
+
+        TRACE("Total 0x%s bytes. emulation 0x%s left, driver 0x%s left.\n",
+                wine_dbgstr_longlong(device->adapter->vram_bytes),
+                wine_dbgstr_longlong(device->adapter->vram_bytes - device->adapter->vram_bytes_used),
+                wine_dbgstr_longlong(vram_free));
+
+        vram_free = min(vram_free, device->adapter->vram_bytes - device->adapter->vram_bytes_used);
+        return min(UINT_MAX, vram_free);
+    }
+    */
+
     TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n",
             wine_dbgstr_longlong(device->adapter->vram_bytes),
             wine_dbgstr_longlong(device->adapter->vram_bytes_used),
     TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n",
             wine_dbgstr_longlong(device->adapter->vram_bytes),
             wine_dbgstr_longlong(device->adapter->vram_bytes_used),
@@ -1580,8 +1618,7 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device,
     if (!(object = wined3d_state_get_light(device->update_state, light_idx)))
     {
         TRACE("Adding new light\n");
     if (!(object = wined3d_state_get_light(device->update_state, light_idx)))
     {
         TRACE("Adding new light\n");
-        object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-        if (!object)
+        if (!(object = heap_alloc_zero(sizeof(*object))))
             return E_OUTOFMEMORY;
 
         list_add_head(&device->update_state->light_map[hash_idx], &object->entry);
             return E_OUTOFMEMORY;
 
         list_add_head(&device->update_state->light_map[hash_idx], &object->entry);
@@ -1917,28 +1954,48 @@ void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, stru
     *viewport = device->state.viewport;
 }
 
     *viewport = device->state.viewport;
 }
 
-static void resolve_depth_buffer(struct wined3d_state *state)
+static void resolve_depth_buffer(struct wined3d_device *device)
 {
 {
-    struct wined3d_texture *dst_texture = state->textures[0];
+    const struct wined3d_state *state = &device->state;
     struct wined3d_rendertarget_view *src_view;
     struct wined3d_rendertarget_view *src_view;
-    RECT src_rect, dst_rect;
+    struct wined3d_resource *dst_resource;
+    struct wined3d_texture *dst_texture;
 
 
-    if (!dst_texture || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
-            || !(dst_texture->resource.format_flags & WINED3DFMT_FLAG_DEPTH))
+    if (!(dst_texture = state->textures[0]))
+        return;
+    dst_resource = &dst_texture->resource;
+    if (!(dst_resource->format_flags & WINED3DFMT_FLAG_DEPTH))
         return;
         return;
-
     if (!(src_view = state->fb->depth_stencil))
         return;
     if (!(src_view = state->fb->depth_stencil))
         return;
-    if (src_view->resource->type == WINED3D_RTYPE_BUFFER)
-    {
-        FIXME("Not supported on buffer resources.\n");
+
+    wined3d_device_resolve_sub_resource(device, dst_resource, 0,
+            src_view->resource, src_view->sub_resource_idx, dst_resource->format->id);
+}
+
+void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state)
+{
+    struct wined3d_blend_state *prev;
+
+    TRACE("device %p, blend_state %p.\n", device, blend_state);
+
+    prev = device->update_state->blend_state;
+    if (prev == blend_state)
         return;
         return;
-    }
 
 
-    SetRect(&dst_rect, 0, 0, dst_texture->resource.width, dst_texture->resource.height);
-    SetRect(&src_rect, 0, 0, src_view->width, src_view->height);
-    wined3d_texture_blt(dst_texture, 0, &dst_rect, texture_from_resource(src_view->resource),
-            src_view->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
+    if (blend_state)
+        wined3d_blend_state_incref(blend_state);
+    device->update_state->blend_state = blend_state;
+    wined3d_cs_emit_set_blend_state(device->cs, blend_state);
+    if (prev)
+        wined3d_blend_state_decref(prev);
+}
+
+struct wined3d_blend_state * CDECL wined3d_device_get_blend_state(const struct wined3d_device *device)
+{
+    TRACE("device %p.\n", device);
+
+    return device->state.blend_state;
 }
 
 void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device,
 }
 
 void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device,
@@ -2000,7 +2057,7 @@ void CDECL wined3d_device_set_render_state(struct wined3d_device *device,
     if (state == WINED3D_RS_POINTSIZE && value == WINED3D_RESZ_CODE)
     {
         TRACE("RESZ multisampled depth buffer resolve triggered.\n");
     if (state == WINED3D_RS_POINTSIZE && value == WINED3D_RESZ_CODE)
     {
         TRACE("RESZ multisampled depth buffer resolve triggered.\n");
-        resolve_depth_buffer(&device->state);
+        resolve_depth_buffer(device);
     }
 }
 
     }
 }
 
@@ -3059,7 +3116,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
     vertex_size = get_flexible_vertex_size(DestFVF);
     box.left = dwDestIndex * vertex_size;
     box.right = box.left + dwCount * vertex_size;
     vertex_size = get_flexible_vertex_size(DestFVF);
     box.left = dwDestIndex * vertex_size;
     box.right = box.left + dwCount * vertex_size;
-    if (FAILED(hr = wined3d_resource_map(&dest->resource, 0, &map_desc, &box, 0)))
+    if (FAILED(hr = wined3d_resource_map(&dest->resource, 0, &map_desc, &box, WINED3D_MAP_WRITE)))
     {
         WARN("Failed to map buffer, hr %#x.\n", hr);
         return hr;
     {
         WARN("Failed to map buffer, hr %#x.\n", hr);
         return hr;
@@ -3323,7 +3380,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device,
         resource = &state->streams[e->stream_idx].buffer->resource;
         box.left = src_start_idx * e->stride;
         box.right = box.left + vertex_count * e->stride;
         resource = &state->streams[e->stream_idx].buffer->resource;
         box.left = src_start_idx * e->stride;
         box.right = box.left + vertex_count * e->stride;
-        if (FAILED(wined3d_resource_map(resource, 0, &map_desc, &box, WINED3D_MAP_READONLY)))
+        if (FAILED(wined3d_resource_map(resource, 0, &map_desc, &box, WINED3D_MAP_READ)))
             ERR("Failed to map resource.\n");
         e->data.buffer_object = 0;
         e->data.addr += (ULONG_PTR)map_desc.data;
             ERR("Failed to map resource.\n");
         e->data.buffer_object = 0;
         e->data.addr += (ULONG_PTR)map_desc.data;
@@ -3419,7 +3476,7 @@ HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device,
         return WINED3D_OK;
     }
 
         return WINED3D_OK;
     }
 
-    if (texture && texture->resource.pool == WINED3D_POOL_SCRATCH)
+    if (texture && texture->resource.usage & WINED3DUSAGE_SCRATCH)
     {
         WARN("Rejecting attempt to set scratch texture.\n");
         return WINED3DERR_INVALIDCALL;
     {
         WARN("Rejecting attempt to set scratch texture.\n");
         return WINED3DERR_INVALIDCALL;
@@ -3468,10 +3525,17 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d
 
 HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps)
 {
 
 HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps)
 {
+    HRESULT hr;
+
     TRACE("device %p, caps %p.\n", device, caps);
 
     TRACE("device %p, caps %p.\n", device, caps);
 
-    return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
+    hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
             device->create_parms.device_type, caps);
             device->create_parms.device_type, caps);
+
+    if (SUCCEEDED(hr) && use_software_vertex_processing(device))
+        caps->MaxVertexBlendMatrixIndex = 255;
+
+    return hr;
 }
 
 HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
 }
 
 HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
@@ -3760,14 +3824,15 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM)
+    if (src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU
+            || src_texture->resource.usage & WINED3DUSAGE_SCRATCH)
     {
     {
-        WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n");
+        WARN("Source resource is GPU accessible or a scratch resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
         return WINED3DERR_INVALIDCALL;
     }
-    if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT)
+    if (dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU)
     {
     {
-        WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n");
+        WARN("Destination resource is CPU accessible.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
@@ -3901,31 +3966,15 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device
 
 void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software)
 {
 
 void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software)
 {
-    static BOOL warned;
-
     TRACE("device %p, software %#x.\n", device, software);
 
     TRACE("device %p, software %#x.\n", device, software);
 
-    if (!warned)
-    {
-        FIXME("device %p, software %#x stub!\n", device, software);
-        warned = TRUE;
-    }
-
     device->softwareVertexProcessing = software;
 }
 
 BOOL CDECL wined3d_device_get_software_vertex_processing(const struct wined3d_device *device)
 {
     device->softwareVertexProcessing = software;
 }
 
 BOOL CDECL wined3d_device_get_software_vertex_processing(const struct wined3d_device *device)
 {
-    static BOOL warned;
-
     TRACE("device %p.\n", device);
 
     TRACE("device %p.\n", device);
 
-    if (!warned)
-    {
-        TRACE("device %p stub!\n", device);
-        warned = TRUE;
-    }
-
     return device->softwareVertexProcessing;
 }
 
     return device->softwareVertexProcessing;
 }
 
@@ -3982,6 +4031,12 @@ void CDECL wined3d_device_copy_uav_counter(struct wined3d_device *device,
     TRACE("device %p, dst_buffer %p, offset %u, uav %p.\n",
             device, dst_buffer, offset, uav);
 
     TRACE("device %p, dst_buffer %p, offset %u, uav %p.\n",
             device, dst_buffer, offset, uav);
 
+    if (offset + sizeof(GLuint) > dst_buffer->resource.size)
+    {
+        WARN("Offset %u too large.\n", offset);
+        return;
+    }
+
     wined3d_cs_emit_copy_uav_counter(device->cs, dst_buffer, offset, uav);
 }
 
     wined3d_cs_emit_copy_uav_counter(device->cs, dst_buffer, offset, uav);
 }
 
@@ -4156,6 +4211,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
             return WINED3DERR_INVALIDCALL;
         }
 
             return WINED3DERR_INVALIDCALL;
         }
 
+#if !defined(STAGING_CSMT)
         if (dst_texture->sub_resources[dst_sub_resource_idx].map_count)
         {
             WARN("Destination sub-resource %u is mapped.\n", dst_sub_resource_idx);
         if (dst_texture->sub_resources[dst_sub_resource_idx].map_count)
         {
             WARN("Destination sub-resource %u is mapped.\n", dst_sub_resource_idx);
@@ -4166,6 +4222,19 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
         {
             WARN("Source sub-resource %u is mapped.\n", src_sub_resource_idx);
             return WINED3DERR_INVALIDCALL;
         {
             WARN("Source sub-resource %u is mapped.\n", src_sub_resource_idx);
             return WINED3DERR_INVALIDCALL;
+#else  /* STAGING_CSMT */
+        if (dst_texture->sub_resources[dst_sub_resource_idx].map_count ||
+            src_texture->sub_resources[src_sub_resource_idx].map_count)
+        {
+            struct wined3d_device *device = dst_texture->resource.device;
+            device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
+            if (dst_texture->sub_resources[dst_sub_resource_idx].map_count ||
+                src_texture->sub_resources[src_sub_resource_idx].map_count)
+            {
+                WARN("Destination or source sub-resource is mapped.\n");
+                return WINEDDERR_SURFACEBUSY;
+            }
+#endif /* STAGING_CSMT */
         }
 
         if (!src_box)
         }
 
         if (!src_box)
@@ -4231,7 +4300,8 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
         height = 1;
         depth = 1;
     }
         height = 1;
         depth = 1;
     }
-    else if (resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D)
+    else if (resource->type == WINED3D_RTYPE_TEXTURE_1D ||
+            resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D)
     {
         struct wined3d_texture *texture = texture_from_resource(resource);
         unsigned int level;
     {
         struct wined3d_texture *texture = texture_from_resource(resource);
         unsigned int level;
@@ -4266,11 +4336,59 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
         return;
     }
 
         return;
     }
 
+#if !defined(STAGING_CSMT)
     wined3d_resource_wait_idle(resource);
 
     wined3d_resource_wait_idle(resource);
 
+#endif /* STAGING_CSMT */
     wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch);
 }
 
     wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch);
 }
 
+void CDECL wined3d_device_resolve_sub_resource(struct wined3d_device *device,
+        struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx,
+        struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx,
+        enum wined3d_format_id format_id)
+{
+    struct wined3d_texture *dst_texture, *src_texture;
+    unsigned int dst_level, src_level;
+    RECT dst_rect, src_rect;
+
+    TRACE("device %p, dst_resource %p, dst_sub_resource_idx %u, "
+            "src_resource %p, src_sub_resource_idx %u, format %s.\n",
+            device, dst_resource, dst_sub_resource_idx,
+            src_resource, src_sub_resource_idx, debug_d3dformat(format_id));
+
+    if (wined3d_format_is_typeless(dst_resource->format)
+            || wined3d_format_is_typeless(src_resource->format))
+    {
+        FIXME("Unhandled multisample resolve, dst_format %s, src_format %s, format %s.\n",
+                debug_d3dformat(dst_resource->format->id), debug_d3dformat(src_resource->format->id),
+                debug_d3dformat(format_id));
+        return;
+    }
+    if (dst_resource->type != WINED3D_RTYPE_TEXTURE_2D)
+    {
+        WARN("Invalid destination resource type %s.\n", debug_d3dresourcetype(dst_resource->type));
+        return;
+    }
+    if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D)
+    {
+        WARN("Invalid source resource type %s.\n", debug_d3dresourcetype(src_resource->type));
+        return;
+    }
+
+    dst_texture = texture_from_resource(dst_resource);
+    src_texture = texture_from_resource(src_resource);
+
+    dst_level = dst_sub_resource_idx % dst_texture->level_count;
+    SetRect(&dst_rect, 0, 0, wined3d_texture_get_level_width(dst_texture, dst_level),
+            wined3d_texture_get_level_height(dst_texture, dst_level));
+    src_level = src_sub_resource_idx % src_texture->level_count;
+    SetRect(&src_rect, 0, 0, wined3d_texture_get_level_width(src_texture, src_level),
+            wined3d_texture_get_level_height(src_texture, src_level));
+    wined3d_texture_blt(dst_texture, dst_sub_resource_idx, &dst_rect,
+            src_texture, src_sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
+}
+
 HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device,
         struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
         const struct wined3d_color *color, float depth, DWORD stencil)
 HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device,
         struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
         const struct wined3d_color *color, float depth, DWORD stencil)
@@ -4433,7 +4551,7 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined
     struct wined3d_texture *texture;
     HRESULT hr;
 
     struct wined3d_texture *texture;
     HRESULT hr;
 
-    if (FAILED(wined3d_resource_map(&cursor_image->resource, sub_resource_idx, &map_desc, NULL, WINED3D_MAP_READONLY)))
+    if (FAILED(wined3d_resource_map(&cursor_image->resource, sub_resource_idx, &map_desc, NULL, WINED3D_MAP_READ)))
     {
         ERR("Failed to map source texture.\n");
         return NULL;
     {
         ERR("Failed to map source texture.\n");
         return NULL;
@@ -4448,7 +4566,7 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
     desc.usage = WINED3DUSAGE_DYNAMIC;
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
     desc.usage = WINED3DUSAGE_DYNAMIC;
-    desc.pool = WINED3D_POOL_DEFAULT;
+    desc.access = WINED3D_RESOURCE_ACCESS_GPU;
     desc.width = wined3d_texture_get_level_width(cursor_image, texture_level);
     desc.height = wined3d_texture_get_level_height(cursor_image, texture_level);
     desc.depth = 1;
     desc.width = wined3d_texture_get_level_width(cursor_image, texture_level);
     desc.height = wined3d_texture_get_level_height(cursor_image, texture_level);
     desc.depth = 1;
@@ -4532,12 +4650,12 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device
         /* 32-bit user32 cursors ignore the alpha channel if it's all
          * zeroes, and use the mask instead. Fill the mask with all ones
          * to ensure we still get a fully transparent cursor. */
         /* 32-bit user32 cursors ignore the alpha channel if it's all
          * zeroes, and use the mask instead. Fill the mask with all ones
          * to ensure we still get a fully transparent cursor. */
-        if (!(mask_bits = HeapAlloc(GetProcessHeap(), 0, mask_size)))
+        if (!(mask_bits = heap_alloc(mask_size)))
             return E_OUTOFMEMORY;
         memset(mask_bits, 0xff, mask_size);
 
         wined3d_resource_map(&texture->resource, sub_resource_idx, &map_desc, NULL,
             return E_OUTOFMEMORY;
         memset(mask_bits, 0xff, mask_size);
 
         wined3d_resource_map(&texture->resource, sub_resource_idx, &map_desc, NULL,
-                WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY);
+                WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READ);
         cursor_info.fIcon = FALSE;
         cursor_info.xHotspot = x_hotspot;
         cursor_info.yHotspot = y_hotspot;
         cursor_info.fIcon = FALSE;
         cursor_info.xHotspot = x_hotspot;
         cursor_info.yHotspot = y_hotspot;
@@ -4557,7 +4675,7 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device
         if (device->bCursorVisible)
             SetCursor(cursor);
 
         if (device->bCursorVisible)
             SetCursor(cursor);
 
-        HeapFree(GetProcessHeap(), 0, mask_bits);
+        heap_free(mask_bits);
     }
 
     TRACE("New cursor dimensions are %ux%u.\n", cursor_width, cursor_height);
     }
 
     TRACE("New cursor dimensions are %ux%u.\n", cursor_width, cursor_height);
@@ -4642,7 +4760,7 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device)
     {
         TRACE("Checking resource %p for eviction.\n", resource);
 
     {
         TRACE("Checking resource %p for eviction.\n", resource);
 
-        if (resource->pool == WINED3D_POOL_MANAGED && !resource->map_count)
+        if (wined3d_resource_access_is_managed(resource->access) && !resource->map_count)
         {
             TRACE("Evicting %p.\n", resource);
             wined3d_cs_emit_unload_resource(device->cs, resource);
         {
             TRACE("Evicting %p.\n", resource);
             wined3d_cs_emit_unload_resource(device->cs, resource);
@@ -4687,12 +4805,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         state_unbind_resources(&device->state);
     }
 
         state_unbind_resources(&device->state);
     }
 
-    if (device->fb.render_targets)
+    for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
     {
     {
-        for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
-        {
-            wined3d_device_set_rendertarget_view(device, i, NULL, FALSE);
-        }
+        wined3d_device_set_rendertarget_view(device, i, NULL, FALSE);
     }
     wined3d_device_set_depth_stencil_view(device, NULL);
 
     }
     wined3d_device_set_depth_stencil_view(device, NULL);
 
@@ -4724,6 +4839,14 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     TRACE("swap_interval %u\n", swapchain_desc->swap_interval);
     TRACE("auto_restore_display_mode %#x\n", swapchain_desc->auto_restore_display_mode);
 
     TRACE("swap_interval %u\n", swapchain_desc->swap_interval);
     TRACE("auto_restore_display_mode %#x\n", swapchain_desc->auto_restore_display_mode);
 
+    if (swapchain_desc->backbuffer_usage != WINED3DUSAGE_RENDERTARGET)
+        FIXME("Got unexpected backbuffer usage %#x.\n", swapchain_desc->backbuffer_usage);
+
+    if (swapchain_desc->swap_effect != WINED3D_SWAP_EFFECT_DISCARD
+            && swapchain_desc->swap_effect != WINED3D_SWAP_EFFECT_SEQUENTIAL
+            && swapchain_desc->swap_effect != WINED3D_SWAP_EFFECT_COPY)
+        FIXME("Unimplemented swap effect %#x.\n", swapchain_desc->swap_effect);
+
     /* No special treatment of these parameters. Just store them */
     swapchain->desc.swap_effect = swapchain_desc->swap_effect;
     swapchain->desc.enable_auto_depth_stencil = swapchain_desc->enable_auto_depth_stencil;
     /* No special treatment of these parameters. Just store them */
     swapchain->desc.swap_effect = swapchain_desc->swap_effect;
     swapchain->desc.enable_auto_depth_stencil = swapchain_desc->enable_auto_depth_stencil;
@@ -4793,7 +4916,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         texture_desc.multisample_type = swapchain->desc.multisample_type;
         texture_desc.multisample_quality = swapchain->desc.multisample_quality;
         texture_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
         texture_desc.multisample_type = swapchain->desc.multisample_type;
         texture_desc.multisample_quality = swapchain->desc.multisample_quality;
         texture_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
-        texture_desc.pool = WINED3D_POOL_DEFAULT;
+        texture_desc.access = WINED3D_RESOURCE_ACCESS_GPU;
         texture_desc.width = swapchain->desc.backbuffer_width;
         texture_desc.height = swapchain->desc.backbuffer_height;
         texture_desc.depth = 1;
         texture_desc.width = swapchain->desc.backbuffer_width;
         texture_desc.height = swapchain->desc.backbuffer_height;
         texture_desc.depth = 1;
@@ -4995,6 +5118,7 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso
 
     switch (type)
     {
 
     switch (type)
     {
+        case WINED3D_RTYPE_TEXTURE_1D:
         case WINED3D_RTYPE_TEXTURE_2D:
         case WINED3D_RTYPE_TEXTURE_3D:
             for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
         case WINED3D_RTYPE_TEXTURE_2D:
         case WINED3D_RTYPE_TEXTURE_3D:
             for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
@@ -5129,7 +5253,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
 err:
     for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
     {
 err:
     for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
     {
-        HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
+        heap_free(device->multistate_funcs[i]);
     }
     wine_rb_destroy(&device->samplers, NULL, NULL);
     wined3d_decref(device->wined3d);
     }
     wine_rb_destroy(&device->samplers, NULL, NULL);
     wined3d_decref(device->wined3d);
@@ -5215,3 +5339,58 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
     else
         return CallWindowProcA(proc, window, message, wparam, lparam);
 }
     else
         return CallWindowProcA(proc, window, message, wparam, lparam);
 }
+#if defined(STAGING_CSMT)
+
+/* Context activation is done by the caller */
+struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage,
+        GLenum type_hint, struct wined3d_context *context)
+{
+    struct wined3d_gl_bo *ret;
+    const struct wined3d_gl_info *gl_info;
+
+    TRACE("device %p, size %u, gl_usage %u, type_hint %u\n", device, size, gl_usage,
+            type_hint);
+
+    ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
+    if(!ret)
+        return NULL;
+    ret->type_hint = type_hint;
+    ret->size = size;
+    ret->usage = gl_usage;
+
+    gl_info = context->gl_info;
+
+    GL_EXTCALL(glGenBuffers(1, &ret->name));
+    if (type_hint == GL_ELEMENT_ARRAY_BUFFER)
+        context_invalidate_state(context, STATE_INDEXBUFFER);
+    GL_EXTCALL(glBindBuffer(type_hint, ret->name));
+    GL_EXTCALL(glBufferData(type_hint, size, NULL, gl_usage));
+    GL_EXTCALL(glBindBuffer(type_hint, 0));
+    checkGLcall("Create buffer object");
+
+    TRACE("Successfully created and set up buffer %u\n", ret->name);
+    return ret;
+}
+
+/* Context activation is done by the caller */
+static void wined3d_device_destroy_bo(struct wined3d_device *device, const struct wined3d_context *context,
+        struct wined3d_gl_bo *bo)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name);
+
+    GL_EXTCALL(glDeleteBuffers(1, &bo->name));
+    checkGLcall("glDeleteBuffers");
+
+    HeapFree(GetProcessHeap(), 0, bo);
+}
+
+/* Context activation is done by the caller */
+void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo,
+        const struct wined3d_context *context)
+{
+    TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name);
+
+    wined3d_device_destroy_bo(device, context, bo);
+}
+#endif /* STAGING_CSMT */
index 40262bb..d82a671 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "wined3d_private.h"
-#include <winternl.h>
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
 
 
-#include <wine/unicode.h>
+#include "wined3d_private.h"
+#include "wine/winternl.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
@@ -119,6 +122,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_cull_distance",                ARB_CULL_DISTANCE             },
     {"GL_ARB_debug_output",                 ARB_DEBUG_OUTPUT              },
     {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT        },
     {"GL_ARB_cull_distance",                ARB_CULL_DISTANCE             },
     {"GL_ARB_debug_output",                 ARB_DEBUG_OUTPUT              },
     {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT        },
+    {"GL_ARB_depth_clamp",                  ARB_DEPTH_CLAMP               },
     {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE             },
     {"GL_ARB_derivative_control",           ARB_DERIVATIVE_CONTROL        },
     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS              },
     {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE             },
     {"GL_ARB_derivative_control",           ARB_DERIVATIVE_CONTROL        },
     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS              },
@@ -132,6 +136,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_fragment_layer_viewport",      ARB_FRAGMENT_LAYER_VIEWPORT   },
     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM          },
     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER           },
     {"GL_ARB_fragment_layer_viewport",      ARB_FRAGMENT_LAYER_VIEWPORT   },
     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM          },
     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER           },
+    {"GL_ARB_framebuffer_no_attachments",   ARB_FRAMEBUFFER_NO_ATTACHMENTS},
     {"GL_ARB_framebuffer_object",           ARB_FRAMEBUFFER_OBJECT        },
     {"GL_ARB_framebuffer_sRGB",             ARB_FRAMEBUFFER_SRGB          },
     {"GL_ARB_geometry_shader4",             ARB_GEOMETRY_SHADER4          },
     {"GL_ARB_framebuffer_object",           ARB_FRAMEBUFFER_OBJECT        },
     {"GL_ARB_framebuffer_sRGB",             ARB_FRAMEBUFFER_SRGB          },
     {"GL_ARB_geometry_shader4",             ARB_GEOMETRY_SHADER4          },
@@ -181,12 +186,14 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_texture_gather",               ARB_TEXTURE_GATHER            },
     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT   },
     {"GL_ARB_texture_mirror_clamp_to_edge", ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE},
     {"GL_ARB_texture_gather",               ARB_TEXTURE_GATHER            },
     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT   },
     {"GL_ARB_texture_mirror_clamp_to_edge", ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE},
+    {"GL_ARB_texture_multisample",          ARB_TEXTURE_MULTISAMPLE       },
     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO  },
     {"GL_ARB_texture_query_levels",         ARB_TEXTURE_QUERY_LEVELS      },
     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE         },
     {"GL_ARB_texture_rg",                   ARB_TEXTURE_RG                },
     {"GL_ARB_texture_rgb10_a2ui",           ARB_TEXTURE_RGB10_A2UI        },
     {"GL_ARB_texture_storage",              ARB_TEXTURE_STORAGE           },
     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO  },
     {"GL_ARB_texture_query_levels",         ARB_TEXTURE_QUERY_LEVELS      },
     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE         },
     {"GL_ARB_texture_rg",                   ARB_TEXTURE_RG                },
     {"GL_ARB_texture_rgb10_a2ui",           ARB_TEXTURE_RGB10_A2UI        },
     {"GL_ARB_texture_storage",              ARB_TEXTURE_STORAGE           },
+    {"GL_ARB_texture_storage_multisample",  ARB_TEXTURE_STORAGE_MULTISAMPLE},
     {"GL_ARB_texture_swizzle",              ARB_TEXTURE_SWIZZLE           },
     {"GL_ARB_texture_view",                 ARB_TEXTURE_VIEW              },
     {"GL_ARB_timer_query",                  ARB_TIMER_QUERY               },
     {"GL_ARB_texture_swizzle",              ARB_TEXTURE_SWIZZLE           },
     {"GL_ARB_texture_view",                 ARB_TEXTURE_VIEW              },
     {"GL_ARB_timer_query",                  ARB_TIMER_QUERY               },
@@ -225,6 +232,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_EXT_packed_depth_stencil",         EXT_PACKED_DEPTH_STENCIL      },
     {"GL_EXT_packed_float",                 EXT_PACKED_FLOAT              },
     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS          },
     {"GL_EXT_packed_depth_stencil",         EXT_PACKED_DEPTH_STENCIL      },
     {"GL_EXT_packed_float",                 EXT_PACKED_FLOAT              },
     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS          },
+    {"GL_EXT_polygon_offset_clamp",         EXT_POLYGON_OFFSET_CLAMP      },
     {"GL_EXT_provoking_vertex",             EXT_PROVOKING_VERTEX          },
     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR           },
     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE          },
     {"GL_EXT_provoking_vertex",             EXT_PROVOKING_VERTEX          },
     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR           },
     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE          },
@@ -265,9 +273,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2            },
     {"GL_NV_vertex_program2_option",        NV_VERTEX_PROGRAM2_OPTION     },
     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3            },
     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2            },
     {"GL_NV_vertex_program2_option",        NV_VERTEX_PROGRAM2_OPTION     },
     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3            },
-
-    /* SGI */
-    {"GL_SGIS_generate_mipmap",             SGIS_GENERATE_MIPMAP          },
+    {"GL_NVX_gpu_memory_info",              NVX_GPU_MEMORY_INFO           },
 };
 
 static const struct wined3d_extension_map wgl_extension_map[] =
 };
 
 static const struct wined3d_extension_map wgl_extension_map[] =
@@ -443,8 +449,8 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount)
 
 static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
 {
 
 static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
 {
-    HeapFree(GetProcessHeap(), 0, adapter->gl_info.formats);
-    HeapFree(GetProcessHeap(), 0, adapter->cfgs);
+    heap_free(adapter->gl_info.formats);
+    heap_free(adapter->cfgs);
 }
 
 ULONG CDECL wined3d_incref(struct wined3d *wined3d)
 }
 
 ULONG CDECL wined3d_incref(struct wined3d *wined3d)
@@ -470,7 +476,7 @@ ULONG CDECL wined3d_decref(struct wined3d *wined3d)
         {
             wined3d_adapter_cleanup(&wined3d->adapters[i]);
         }
         {
             wined3d_adapter_cleanup(&wined3d->adapters[i]);
         }
-        HeapFree(GetProcessHeap(), 0, wined3d);
+        heap_free(wined3d);
     }
 
     return refcount;
     }
 
     return refcount;
@@ -1338,6 +1344,7 @@ static const struct gpu_description gpu_description_table[] =
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX550,     "NVIDIA GeForce GTX 550 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT555M,     "NVIDIA GeForce GT 555M",           DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560TI,   "NVIDIA GeForce GTX 560 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX550,     "NVIDIA GeForce GTX 550 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT555M,     "NVIDIA GeForce GT 555M",           DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560TI,   "NVIDIA GeForce GTX 560 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
+    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560M,    "NVIDIA GeForce GTX 560M",          DRIVER_NVIDIA_GEFORCE8,  3072},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560,     "NVIDIA GeForce GTX 560",           DRIVER_NVIDIA_GEFORCE8,  1024},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX570,     "NVIDIA GeForce GTX 570",           DRIVER_NVIDIA_GEFORCE8,  1280},
     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX580,     "NVIDIA GeForce GTX 580",           DRIVER_NVIDIA_GEFORCE8,  1536},
     {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},
@@ -1576,6 +1583,15 @@ static const struct gpu_description *query_gpu_description(const struct wined3d_
         TRACE("Card reports vendor PCI ID 0x%04x, device PCI ID 0x%04x, 0x%s bytes of video memory.\n",
                 vendor, device, wine_dbgstr_longlong(*vram_bytes));
     }
         TRACE("Card reports vendor PCI ID 0x%04x, device PCI ID 0x%04x, 0x%s bytes of video memory.\n",
                 vendor, device, wine_dbgstr_longlong(*vram_bytes));
     }
+    else if (gl_info->supported[NVX_GPU_MEMORY_INFO])
+    {
+        GLint vram_kb;
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &vram_kb);
+
+        *vram_bytes = (UINT64)vram_kb * 1024;
+        TRACE("Got 0x%s as video memory from NVX_GPU_MEMORY_INFO extension.\n",
+                wine_dbgstr_longlong(*vram_bytes));
+    }
 
     if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
     {
 
     if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
     {
@@ -1687,11 +1703,13 @@ static void init_driver_info(struct wined3d_driver_info *driver_info,
      * In order to avoid this application bug we limit the amount of video memory
      * to LONG_MAX for older Windows versions.
      */
      * In order to avoid this application bug we limit the amount of video memory
      * to LONG_MAX for older Windows versions.
      */
+#ifdef __i386__
     if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX)
     {
         TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX);
         driver_info->vram_bytes = LONG_MAX;
     }
     if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX)
     {
         TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX);
         driver_info->vram_bytes = LONG_MAX;
     }
+#endif
 
     /* Try to obtain driver version information for the current Windows version. This fails in
      * some cases:
 
     /* Try to obtain driver version information for the current Windows version. This fails in
      * some cases:
@@ -1788,6 +1806,7 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_in
         return GL_VENDOR_FGLRX;
 
     if (strstr(gl_vendor_string, "Mesa")
         return GL_VENDOR_FGLRX;
 
     if (strstr(gl_vendor_string, "Mesa")
+            || strstr(gl_vendor_string, "Brian Paul")
             || strstr(gl_vendor_string, "X.Org")
             || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
             || strstr(gl_vendor_string, "DRI R300 Project")
             || strstr(gl_vendor_string, "X.Org")
             || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
             || strstr(gl_vendor_string, "DRI R300 Project")
@@ -1942,6 +1961,7 @@ cards_nvidia_binary[] =
     {"GTX 580",                     CARD_NVIDIA_GEFORCE_GTX580},    /* Geforce 500 - highend */
     {"GTX 570",                     CARD_NVIDIA_GEFORCE_GTX570},    /* Geforce 500 - midend high */
     {"GTX 560 Ti",                  CARD_NVIDIA_GEFORCE_GTX560TI},  /* Geforce 500 - midend */
     {"GTX 580",                     CARD_NVIDIA_GEFORCE_GTX580},    /* Geforce 500 - highend */
     {"GTX 570",                     CARD_NVIDIA_GEFORCE_GTX570},    /* Geforce 500 - midend high */
     {"GTX 560 Ti",                  CARD_NVIDIA_GEFORCE_GTX560TI},  /* Geforce 500 - midend */
+    {"GTX 560M",                    CARD_NVIDIA_GEFORCE_GTX560M},   /* Geforce 500 - midend mobile */
     {"GTX 560",                     CARD_NVIDIA_GEFORCE_GTX560},    /* Geforce 500 - midend */
     {"GT 555M",                     CARD_NVIDIA_GEFORCE_GT555M},    /* Geforce 500 - midend mobile */
     {"GTX 550 Ti",                  CARD_NVIDIA_GEFORCE_GTX550},    /* Geforce 500 - midend */
     {"GTX 560",                     CARD_NVIDIA_GEFORCE_GTX560},    /* Geforce 500 - midend */
     {"GT 555M",                     CARD_NVIDIA_GEFORCE_GT555M},    /* Geforce 500 - midend mobile */
     {"GTX 550 Ti",                  CARD_NVIDIA_GEFORCE_GTX550},    /* Geforce 500 - midend */
@@ -2735,6 +2755,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     USE_GL_FUNC(glGetShaderPrecisionFormat)
     USE_GL_FUNC(glDepthRangef)
     USE_GL_FUNC(glClearDepthf)
     USE_GL_FUNC(glGetShaderPrecisionFormat)
     USE_GL_FUNC(glDepthRangef)
     USE_GL_FUNC(glClearDepthf)
+    /* GL_ARB_framebuffer_no_attachments */
+    USE_GL_FUNC(glFramebufferParameteri)
     /* GL_ARB_framebuffer_object */
     USE_GL_FUNC(glBindFramebuffer)
     USE_GL_FUNC(glBindRenderbuffer)
     /* GL_ARB_framebuffer_object */
     USE_GL_FUNC(glBindFramebuffer)
     USE_GL_FUNC(glBindRenderbuffer)
@@ -2885,10 +2907,18 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     USE_GL_FUNC(glCompressedTexSubImage2DARB)
     USE_GL_FUNC(glCompressedTexSubImage3DARB)
     USE_GL_FUNC(glGetCompressedTexImageARB)
     USE_GL_FUNC(glCompressedTexSubImage2DARB)
     USE_GL_FUNC(glCompressedTexSubImage3DARB)
     USE_GL_FUNC(glGetCompressedTexImageARB)
+    /* GL_ARB_texture_multisample */
+    USE_GL_FUNC(glGetMultisamplefv);
+    USE_GL_FUNC(glSampleMaski);
+    USE_GL_FUNC(glTexImage2DMultisample);
+    USE_GL_FUNC(glTexImage3DMultisample);
     /* GL_ARB_texture_storage */
     USE_GL_FUNC(glTexStorage1D)
     USE_GL_FUNC(glTexStorage2D)
     USE_GL_FUNC(glTexStorage3D)
     /* GL_ARB_texture_storage */
     USE_GL_FUNC(glTexStorage1D)
     USE_GL_FUNC(glTexStorage2D)
     USE_GL_FUNC(glTexStorage3D)
+    /* GL_ARB_texture_storage_multisample */
+    USE_GL_FUNC(glTexStorage2DMultisample);
+    USE_GL_FUNC(glTexStorage3DMultisample);
     /* GL_ARB_texture_view */
     USE_GL_FUNC(glTextureView)
     /* GL_ARB_timer_query */
     /* GL_ARB_texture_view */
     USE_GL_FUNC(glTextureView)
     /* GL_ARB_timer_query */
@@ -3103,6 +3133,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     /* GL_EXT_point_parameters */
     USE_GL_FUNC(glPointParameterfEXT)
     USE_GL_FUNC(glPointParameterfvEXT)
     /* GL_EXT_point_parameters */
     USE_GL_FUNC(glPointParameterfEXT)
     USE_GL_FUNC(glPointParameterfvEXT)
+    /* GL_EXT_polygon_offset_clamp */
+    USE_GL_FUNC(glPolygonOffsetClampEXT)
     /* GL_EXT_provoking_vertex */
     USE_GL_FUNC(glProvokingVertexEXT)
     /* GL_EXT_secondary_color */
     /* GL_EXT_provoking_vertex */
     USE_GL_FUNC(glProvokingVertexEXT)
     /* GL_EXT_secondary_color */
@@ -3197,120 +3229,122 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     USE_GL_FUNC(wglSwapIntervalEXT)
 
     /* Newer core functions */
     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(glBeginTransformFeedback)   /* OpenGL 3.0 */
-    USE_GL_FUNC(glBindAttribLocation)       /* OpenGL 2.0 */
-    USE_GL_FUNC(glBindBuffer)               /* OpenGL 1.5 */
-    USE_GL_FUNC(glBindFragDataLocation)     /* OpenGL 3.0 */
-    USE_GL_FUNC(glBindVertexArray)          /* OpenGL 3.0 */
-    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(glDebugMessageCallback)     /* OpenGL 4.3 */
-    USE_GL_FUNC(glDebugMessageControl)      /* OpenGL 4.3 */
-    USE_GL_FUNC(glDebugMessageInsert)       /* OpenGL 4.3 */
-    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(glDeleteVertexArrays)       /* OpenGL 3.0 */
-    USE_GL_FUNC(glDetachShader)             /* OpenGL 2.0 */
-    USE_GL_FUNC(glDisablei)                 /* OpenGL 3.0 */
-    USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */
-    USE_GL_FUNC(glDrawArraysInstanced)      /* OpenGL 3.1 */
-    USE_GL_FUNC(glDrawBuffers)              /* OpenGL 2.0 */
-    USE_GL_FUNC(glDrawElementsInstanced)    /* OpenGL 3.1 */
-    USE_GL_FUNC(glEnablei)                  /* OpenGL 3.0 */
-    USE_GL_FUNC(glEnableVertexAttribArray)  /* OpenGL 2.0 */
-    USE_GL_FUNC(glEndQuery)                 /* OpenGL 1.5 */
-    USE_GL_FUNC(glEndTransformFeedback)     /* OpenGL 3.0 */
-    USE_GL_FUNC(glFramebufferTexture)       /* OpenGL 3.2 */
-    USE_GL_FUNC(glGenBuffers)               /* OpenGL 1.5 */
-    USE_GL_FUNC(glGenQueries)               /* OpenGL 1.5 */
-    USE_GL_FUNC(glGenVertexArrays)          /* OpenGL 3.0 */
-    USE_GL_FUNC(glGetActiveUniform)         /* OpenGL 2.0 */
-    USE_GL_FUNC(glGetAttachedShaders)       /* OpenGL 2.0 */
-    USE_GL_FUNC(glGetAttribLocation)        /* OpenGL 2.0 */
-    USE_GL_FUNC(glGetBooleani_v)            /* OpenGL 3.0 */
-    USE_GL_FUNC(glGetBufferSubData)         /* OpenGL 1.5 */
-    USE_GL_FUNC(glGetCompressedTexImage)    /* OpenGL 1.3 */
-    USE_GL_FUNC(glGetDebugMessageLog)       /* OpenGL 4.3 */
-    USE_GL_FUNC(glGetIntegeri_v)            /* OpenGL 3.0 */
-    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(glGetStringi)               /* OpenGL 3.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(glIsEnabledi)               /* OpenGL 3.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(glTexBuffer)                /* OpenGL 3.1 */
-    USE_GL_FUNC(glTexImage3D)               /* OpenGL 1.2 */
-    USE_GL_FUNC(glTexSubImage3D)            /* OpenGL 1.2 */
-    USE_GL_FUNC(glTransformFeedbackVaryings)/* OpenGL 3.0 */
-    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(glVertexAttrib4Nub)         /* 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(glVertexAttribIPointer)     /* OpenGL 3.0 */
-    USE_GL_FUNC(glVertexAttribPointer)      /* OpenGL 2.0 */
+    USE_GL_FUNC(glActiveTexture)                               /* OpenGL 1.3 */
+    USE_GL_FUNC(glAttachShader)                                /* OpenGL 2.0 */
+    USE_GL_FUNC(glBeginQuery)                                  /* OpenGL 1.5 */
+    USE_GL_FUNC(glBeginTransformFeedback)                      /* OpenGL 3.0 */
+    USE_GL_FUNC(glBindAttribLocation)                          /* OpenGL 2.0 */
+    USE_GL_FUNC(glBindBuffer)                                  /* OpenGL 1.5 */
+    USE_GL_FUNC(glBindFragDataLocation)                        /* OpenGL 3.0 */
+    USE_GL_FUNC(glBindVertexArray)                             /* OpenGL 3.0 */
+    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(glDebugMessageCallback)                        /* OpenGL 4.3 */
+    USE_GL_FUNC(glDebugMessageControl)                         /* OpenGL 4.3 */
+    USE_GL_FUNC(glDebugMessageInsert)                          /* OpenGL 4.3 */
+    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(glDeleteVertexArrays)                          /* OpenGL 3.0 */
+    USE_GL_FUNC(glDetachShader)                                /* OpenGL 2.0 */
+    USE_GL_FUNC(glDisablei)                                    /* OpenGL 3.0 */
+    USE_GL_FUNC(glDisableVertexAttribArray)                    /* OpenGL 2.0 */
+    USE_GL_FUNC(glDrawArraysInstanced)                         /* OpenGL 3.1 */
+    USE_GL_FUNC(glDrawBuffers)                                 /* OpenGL 2.0 */
+    USE_GL_FUNC(glDrawElementsInstanced)                       /* OpenGL 3.1 */
+    USE_GL_FUNC(glEnablei)                                     /* OpenGL 3.0 */
+    USE_GL_FUNC(glEnableVertexAttribArray)                     /* OpenGL 2.0 */
+    USE_GL_FUNC(glEndQuery)                                    /* OpenGL 1.5 */
+    USE_GL_FUNC(glEndTransformFeedback)                        /* OpenGL 3.0 */
+    USE_GL_FUNC(glFramebufferTexture)                          /* OpenGL 3.2 */
+    USE_GL_FUNC(glGenBuffers)                                  /* OpenGL 1.5 */
+    USE_GL_FUNC(glGenQueries)                                  /* OpenGL 1.5 */
+    USE_GL_FUNC(glGenVertexArrays)                             /* OpenGL 3.0 */
+    USE_GL_FUNC(glGetActiveUniform)                            /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetAttachedShaders)                          /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetAttribLocation)                           /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetBooleani_v)                               /* OpenGL 3.0 */
+    USE_GL_FUNC(glGetBufferSubData)                            /* OpenGL 1.5 */
+    USE_GL_FUNC(glGetCompressedTexImage)                       /* OpenGL 1.3 */
+    USE_GL_FUNC(glGetDebugMessageLog)                          /* OpenGL 4.3 */
+    USE_GL_FUNC(glGetIntegeri_v)                               /* OpenGL 3.0 */
+    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(glGetStringi)                                  /* OpenGL 3.0 */
+    USE_GL_FUNC(glGetTextureLevelParameteriv)                  /* OpenGL 4.5 */
+    USE_GL_FUNC(glGetTextureParameteriv)                       /* OpenGL 4.5 */
+    USE_GL_FUNC(glGetUniformfv)                                /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetUniformiv)                                /* OpenGL 2.0 */
+    USE_GL_FUNC(glGetUniformLocation)                          /* OpenGL 2.0 */
+    USE_GL_FUNC(glIsEnabledi)                                  /* OpenGL 3.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(glTexBuffer)                                   /* OpenGL 3.1 */
+    USE_GL_FUNC(glTexImage3D)                                  /* OpenGL 1.2 */
+    USE_GL_FUNC(glTexSubImage3D)                               /* OpenGL 1.2 */
+    USE_GL_FUNC(glTransformFeedbackVaryings)                   /* OpenGL 3.0 */
+    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(glVertexAttrib4Nub)                            /* 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(glVertexAttribIPointer)                        /* OpenGL 3.0 */
+    USE_GL_FUNC(glVertexAttribPointer)                         /* OpenGL 2.0 */
 #undef USE_GL_FUNC
 
 #ifndef USE_WIN32_OPENGL
 #undef USE_GL_FUNC
 
 #ifndef USE_WIN32_OPENGL
@@ -3509,9 +3543,15 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
     if (gl_info->supported[ARB_DRAW_BUFFERS] && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
         gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
     if (gl_info->supported[ARB_DRAW_BUFFERS] && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
         gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
-        gl_info->limits.buffers = gl_max;
+        gl_info->limits.buffers = min(MAX_RENDER_TARGET_VIEWS, gl_max);
         TRACE("Max draw buffers: %u.\n", gl_max);
     }
         TRACE("Max draw buffers: %u.\n", gl_max);
     }
+    if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED])
+    {
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &gl_max);
+        gl_info->limits.dual_buffers = gl_max;
+        TRACE("Max dual source draw buffers: %u.\n", gl_max);
+    }
     if (gl_info->supported[ARB_MULTITEXTURE])
     {
         if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
     if (gl_info->supported[ARB_MULTITEXTURE])
     {
         if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
@@ -3764,6 +3804,19 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
         gl_info->limits.samples = gl_max;
     }
 
         gl_info->limits.samples = gl_max;
     }
 
+    if (gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS])
+    {
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &gl_max);
+        gl_info->limits.framebuffer_width = gl_max;
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &gl_max);
+        gl_info->limits.framebuffer_height = gl_max;
+    }
+    else
+    {
+        gl_info->limits.framebuffer_width = gl_info->limits.texture_size;
+        gl_info->limits.framebuffer_height = gl_info->limits.texture_size;
+    }
+
     gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] =
             min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_GL_FRAGMENT_SAMPLERS);
     sampler_count = 0;
     gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] =
             min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_GL_FRAGMENT_SAMPLERS);
     sampler_count = 0;
@@ -3865,6 +3918,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
         {ARB_PROVOKING_VERTEX,             MAKEDWORD_VERSION(3, 2)},
         {ARB_SEAMLESS_CUBE_MAP,            MAKEDWORD_VERSION(3, 2)},
         {ARB_SYNC,                         MAKEDWORD_VERSION(3, 2)},
         {ARB_PROVOKING_VERTEX,             MAKEDWORD_VERSION(3, 2)},
         {ARB_SEAMLESS_CUBE_MAP,            MAKEDWORD_VERSION(3, 2)},
         {ARB_SYNC,                         MAKEDWORD_VERSION(3, 2)},
+        {ARB_TEXTURE_MULTISAMPLE,          MAKEDWORD_VERSION(3, 2)},
         {ARB_VERTEX_ARRAY_BGRA,            MAKEDWORD_VERSION(3, 2)},
 
         {ARB_BLEND_FUNC_EXTENDED,          MAKEDWORD_VERSION(3, 3)},
         {ARB_VERTEX_ARRAY_BGRA,            MAKEDWORD_VERSION(3, 2)},
 
         {ARB_BLEND_FUNC_EXTENDED,          MAKEDWORD_VERSION(3, 3)},
@@ -3905,12 +3959,14 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
         {ARB_DEBUG_OUTPUT,                 MAKEDWORD_VERSION(4, 3)},
         {ARB_ES3_COMPATIBILITY,            MAKEDWORD_VERSION(4, 3)},
         {ARB_FRAGMENT_LAYER_VIEWPORT,      MAKEDWORD_VERSION(4, 3)},
         {ARB_DEBUG_OUTPUT,                 MAKEDWORD_VERSION(4, 3)},
         {ARB_ES3_COMPATIBILITY,            MAKEDWORD_VERSION(4, 3)},
         {ARB_FRAGMENT_LAYER_VIEWPORT,      MAKEDWORD_VERSION(4, 3)},
+        {ARB_FRAMEBUFFER_NO_ATTACHMENTS,   MAKEDWORD_VERSION(4, 3)},
         {ARB_INTERNALFORMAT_QUERY2,        MAKEDWORD_VERSION(4, 3)},
         {ARB_SHADER_IMAGE_SIZE,            MAKEDWORD_VERSION(4, 3)},
         {ARB_SHADER_STORAGE_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)},
         {ARB_STENCIL_TEXTURING,            MAKEDWORD_VERSION(4, 3)},
         {ARB_TEXTURE_BUFFER_RANGE,         MAKEDWORD_VERSION(4, 3)},
         {ARB_TEXTURE_QUERY_LEVELS,         MAKEDWORD_VERSION(4, 3)},
         {ARB_INTERNALFORMAT_QUERY2,        MAKEDWORD_VERSION(4, 3)},
         {ARB_SHADER_IMAGE_SIZE,            MAKEDWORD_VERSION(4, 3)},
         {ARB_SHADER_STORAGE_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)},
         {ARB_STENCIL_TEXTURING,            MAKEDWORD_VERSION(4, 3)},
         {ARB_TEXTURE_BUFFER_RANGE,         MAKEDWORD_VERSION(4, 3)},
         {ARB_TEXTURE_QUERY_LEVELS,         MAKEDWORD_VERSION(4, 3)},
+        {ARB_TEXTURE_STORAGE_MULTISAMPLE,  MAKEDWORD_VERSION(4, 2)},
         {ARB_TEXTURE_VIEW,                 MAKEDWORD_VERSION(4, 3)},
 
         {ARB_CLEAR_TEXTURE,                MAKEDWORD_VERSION(4, 4)},
         {ARB_TEXTURE_VIEW,                 MAKEDWORD_VERSION(4, 3)},
 
         {ARB_CLEAR_TEXTURE,                MAKEDWORD_VERSION(4, 4)},
@@ -4227,6 +4283,13 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
         WARN("Disabling ARB_draw_indirect because ARB_base_instance is not supported.\n");
         gl_info->supported[ARB_DRAW_INDIRECT] = FALSE;
     }
         WARN("Disabling ARB_draw_indirect because ARB_base_instance is not supported.\n");
         gl_info->supported[ARB_DRAW_INDIRECT] = FALSE;
     }
+    if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE] && !wined3d_settings.multisample_textures)
+        gl_info->supported[ARB_TEXTURE_MULTISAMPLE] = FALSE;
+    if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE] && !gl_info->supported[ARB_TEXTURE_STORAGE_MULTISAMPLE])
+    {
+        WARN("Disabling ARB_texture_multisample because immutable storage is not supported.\n");
+        gl_info->supported[ARB_TEXTURE_MULTISAMPLE] = FALSE;
+    }
 
     wined3d_adapter_init_limits(gl_info);
 
 
     wined3d_adapter_init_limits(gl_info);
 
@@ -4284,6 +4347,10 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
     for (i = 0; i < gl_info->limits.buffers; ++i)
         adapter->d3d_info.valid_rt_mask |= (1u << i);
 
     for (i = 0; i < gl_info->limits.buffers; ++i)
         adapter->d3d_info.valid_rt_mask |= (1u << i);
 
+    adapter->d3d_info.valid_dual_rt_mask = 0;
+    for (i = 0; i < gl_info->limits.dual_buffers; ++i)
+        adapter->d3d_info.valid_dual_rt_mask |= (1u << i);
+
     if (!adapter->d3d_info.shader_color_key)
     {
         /* We do not want to deal with re-creating immutable texture storage for color keying emulation. */
     if (!adapter->d3d_info.shader_color_key)
     {
         /* We do not want to deal with re-creating immutable texture storage for color keying emulation. */
@@ -4614,11 +4681,11 @@ HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *w
         return E_FAIL;
     }
 
         return E_FAIL;
     }
 
-    if (!(modes = wined3d_calloc(mode_count, sizeof(*modes))))
+    if (!(modes = heap_calloc(mode_count, sizeof(*modes))))
         return E_OUTOFMEMORY;
         return E_OUTOFMEMORY;
-    if (!(matching_modes = wined3d_calloc(mode_count, sizeof(*matching_modes))))
+    if (!(matching_modes = heap_calloc(mode_count, sizeof(*matching_modes))))
     {
     {
-        HeapFree(GetProcessHeap(), 0, modes);
+        heap_free(modes);
         return E_OUTOFMEMORY;
     }
 
         return E_OUTOFMEMORY;
     }
 
@@ -4627,8 +4694,8 @@ HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *w
         if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, adapter_idx,
                 mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &modes[i])))
         {
         if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, adapter_idx,
                 mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &modes[i])))
         {
-            HeapFree(GetProcessHeap(), 0, matching_modes);
-            HeapFree(GetProcessHeap(), 0, modes);
+            heap_free(matching_modes);
+            heap_free(modes);
             return hr;
         }
         matching_modes[i] = &modes[i];
             return hr;
         }
         matching_modes[i] = &modes[i];
@@ -4664,8 +4731,8 @@ HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *w
         if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx,
                 &current_mode, NULL)))
         {
         if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx,
                 &current_mode, NULL)))
         {
-            HeapFree(GetProcessHeap(), 0, matching_modes);
-            HeapFree(GetProcessHeap(), 0, modes);
+            heap_free(matching_modes);
+            heap_free(modes);
             return hr;
         }
         mode->width = current_mode.width;
             return hr;
         }
         mode->width = current_mode.width;
@@ -4687,8 +4754,8 @@ HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *w
 
     *mode = *matching_modes[j];
 
 
     *mode = *matching_modes[j];
 
-    HeapFree(GetProcessHeap(), 0, matching_modes);
-    HeapFree(GetProcessHeap(), 0, modes);
+    heap_free(matching_modes);
+    heap_free(modes);
 
     TRACE("Returning %ux%u@%u %s %#x.\n", mode->width, mode->height,
             mode->refresh_rate, debug_d3dformat(mode->format_id),
 
     TRACE("Returning %ux%u@%u %s %#x.\n", mode->width, mode->height,
             mode->refresh_rate, debug_d3dformat(mode->format_id),
@@ -5272,7 +5339,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
     const struct wined3d_format *adapter_format, *format;
     enum wined3d_gl_resource_type gl_type, gl_type_end;
     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
     const struct wined3d_format *adapter_format, *format;
     enum wined3d_gl_resource_type gl_type, gl_type_end;
-    BOOL mipmap_autogen_supported;
+    BOOL mipmap_gen_supported = TRUE;
     DWORD format_flags = 0;
     DWORD allowed_usage;
 
     DWORD format_flags = 0;
     DWORD allowed_usage;
 
@@ -5293,10 +5360,23 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
         case WINED3D_RTYPE_NONE:
             allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                     | WINED3DUSAGE_RENDERTARGET;
         case WINED3D_RTYPE_NONE:
             allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                     | WINED3DUSAGE_RENDERTARGET;
-            gl_type = WINED3D_GL_RES_TYPE_TEX_2D;
+            gl_type = WINED3D_GL_RES_TYPE_TEX_1D;
             gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
             break;
 
             gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
             break;
 
+        case WINED3D_RTYPE_TEXTURE_1D:
+            allowed_usage = WINED3DUSAGE_DYNAMIC
+                    | WINED3DUSAGE_SOFTWAREPROCESSING
+                    | WINED3DUSAGE_TEXTURE
+                    | WINED3DUSAGE_QUERY_FILTER
+                    | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+                    | WINED3DUSAGE_QUERY_SRGBREAD
+                    | WINED3DUSAGE_QUERY_SRGBWRITE
+                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+                    | WINED3DUSAGE_QUERY_WRAPANDMIP;
+            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_1D;
+            break;
+
         case WINED3D_RTYPE_TEXTURE_2D:
             allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                     | WINED3DUSAGE_RENDERTARGET
         case WINED3D_RTYPE_TEXTURE_2D:
             allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                     | WINED3DUSAGE_RENDERTARGET
@@ -5314,12 +5394,12 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
                 gl_type = gl_type_end = WINED3D_GL_RES_TYPE_RB;
                 break;
             }
                 gl_type = gl_type_end = WINED3D_GL_RES_TYPE_RB;
                 break;
             }
-            allowed_usage |= WINED3DUSAGE_AUTOGENMIPMAP
-                    | WINED3DUSAGE_DYNAMIC
+            allowed_usage |= WINED3DUSAGE_DYNAMIC
                     | WINED3DUSAGE_LEGACY_CUBEMAP
                     | WINED3DUSAGE_SOFTWAREPROCESSING
                     | WINED3DUSAGE_TEXTURE
                     | WINED3DUSAGE_QUERY_FILTER
                     | WINED3DUSAGE_LEGACY_CUBEMAP
                     | WINED3DUSAGE_SOFTWAREPROCESSING
                     | WINED3DUSAGE_TEXTURE
                     | WINED3DUSAGE_QUERY_FILTER
+                    | WINED3DUSAGE_QUERY_GENMIPMAP
                     | WINED3DUSAGE_QUERY_LEGACYBUMPMAP
                     | WINED3DUSAGE_QUERY_SRGBREAD
                     | WINED3DUSAGE_QUERY_SRGBWRITE
                     | WINED3DUSAGE_QUERY_LEGACYBUMPMAP
                     | WINED3DUSAGE_QUERY_SRGBREAD
                     | WINED3DUSAGE_QUERY_SRGBWRITE
@@ -5353,6 +5433,12 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
             gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
             break;
 
             gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
             break;
 
+        case WINED3D_RTYPE_BUFFER:
+            allowed_usage = WINED3DUSAGE_DYNAMIC
+                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE;
+            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_BUFFER;
+            break;
+
         default:
             FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
             return WINED3DERR_NOTAVAILABLE;
         default:
             FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
             return WINED3DERR_NOTAVAILABLE;
@@ -5386,7 +5472,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
         return WINED3DERR_NOTAVAILABLE;
     }
 
         return WINED3DERR_NOTAVAILABLE;
     }
 
-    mipmap_autogen_supported = gl_info->supported[SGIS_GENERATE_MIPMAP];
     for (; gl_type <= gl_type_end; ++gl_type)
     {
         if ((format->flags[gl_type] & format_flags) != format_flags)
     for (; gl_type <= gl_type_end; ++gl_type)
     {
         if ((format->flags[gl_type] & format_flags) != format_flags)
@@ -5416,17 +5501,14 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
             return WINED3DERR_NOTAVAILABLE;
         }
 
             return WINED3DERR_NOTAVAILABLE;
         }
 
-        if ((format->flags[gl_type] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING))
-                != (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING))
-        {
-            mipmap_autogen_supported = FALSE;
-        }
+        if (!(format->flags[gl_type] & WINED3DFMT_FLAG_GEN_MIPMAP))
+            mipmap_gen_supported = FALSE;
     }
 
     }
 
-    if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_autogen_supported)
+    if ((usage & WINED3DUSAGE_QUERY_GENMIPMAP) && !mipmap_gen_supported)
     {
         TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n");
     {
         TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n");
-        return WINED3DOK_NOAUTOGEN;
+        return WINED3DOK_NOMIPGEN;
     }
 
     return WINED3D_OK;
     }
 
     return WINED3D_OK;
@@ -5598,8 +5680,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
     caps->Caps2                    = WINED3DCAPS2_CANRENDERWINDOWED |
                                      WINED3DCAPS2_FULLSCREENGAMMA |
                                      WINED3DCAPS2_DYNAMICTEXTURES;
     caps->Caps2                    = WINED3DCAPS2_CANRENDERWINDOWED |
                                      WINED3DCAPS2_FULLSCREENGAMMA |
                                      WINED3DCAPS2_DYNAMICTEXTURES;
-    if (gl_info->supported[SGIS_GENERATE_MIPMAP])
-        caps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
+    if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
+        caps->Caps2 |= WINED3DCAPS2_CANGENMIPMAP;
 
     caps->Caps3                    = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
                                      WINED3DCAPS3_COPY_TO_VIDMEM                   |
 
     caps->Caps3                    = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
                                      WINED3DCAPS3_COPY_TO_VIDMEM                   |
@@ -5962,7 +6044,10 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
     caps->MaxUserClipPlanes                = vertex_caps.max_user_clip_planes;
     caps->MaxActiveLights                  = vertex_caps.max_active_lights;
     caps->MaxVertexBlendMatrices           = vertex_caps.max_vertex_blend_matrices;
     caps->MaxUserClipPlanes                = vertex_caps.max_user_clip_planes;
     caps->MaxActiveLights                  = vertex_caps.max_active_lights;
     caps->MaxVertexBlendMatrices           = vertex_caps.max_vertex_blend_matrices;
-    caps->MaxVertexBlendMatrixIndex        = vertex_caps.max_vertex_blend_matrix_index;
+    if (device_type == WINED3D_DEVICE_TYPE_HAL)
+        caps->MaxVertexBlendMatrixIndex    = vertex_caps.max_vertex_blend_matrix_index;
+    else
+        caps->MaxVertexBlendMatrixIndex    = 255;
     caps->VertexProcessingCaps             = vertex_caps.vertex_processing_caps;
     caps->FVFCaps                          = vertex_caps.fvf_caps;
     caps->RasterCaps                      |= vertex_caps.raster_caps;
     caps->VertexProcessingCaps             = vertex_caps.vertex_processing_caps;
     caps->FVFCaps                          = vertex_caps.fvf_caps;
     caps->RasterCaps                      |= vertex_caps.raster_caps;
@@ -6171,8 +6256,7 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, e
     if (wined3d->adapter_count && adapter_idx >= wined3d->adapter_count)
         return WINED3DERR_INVALIDCALL;
 
     if (wined3d->adapter_count && adapter_idx >= wined3d->adapter_count)
         return WINED3DERR_INVALIDCALL;
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = device_init(object, wined3d, adapter_idx, device_type,
         return E_OUTOFMEMORY;
 
     hr = device_init(object, wined3d, adapter_idx, device_type,
@@ -6180,7 +6264,7 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, e
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -6420,7 +6504,7 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc
         attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
         GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, 0, 0, 1, &attribute, &cfg_count));
 
         attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
         GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, 0, 0, 1, &attribute, &cfg_count));
 
-        adapter->cfgs = wined3d_calloc(cfg_count, sizeof(*adapter->cfgs));
+        adapter->cfgs = heap_calloc(cfg_count, sizeof(*adapter->cfgs));
         attribs[attrib_count++] = WGL_RED_BITS_ARB;
         attribs[attrib_count++] = WGL_GREEN_BITS_ARB;
         attribs[attrib_count++] = WGL_BLUE_BITS_ARB;
         attribs[attrib_count++] = WGL_RED_BITS_ARB;
         attribs[attrib_count++] = WGL_GREEN_BITS_ARB;
         attribs[attrib_count++] = WGL_BLUE_BITS_ARB;
@@ -6485,7 +6569,7 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc
         int cfg_count;
 
         cfg_count = DescribePixelFormat(dc, 0, 0, 0);
         int cfg_count;
 
         cfg_count = DescribePixelFormat(dc, 0, 0, 0);
-        adapter->cfgs = wined3d_calloc(cfg_count, sizeof(*adapter->cfgs));
+        adapter->cfgs = heap_calloc(cfg_count, sizeof(*adapter->cfgs));
 
         for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i)
         {
 
         for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i)
         {
@@ -6547,6 +6631,18 @@ static DWORD get_max_gl_version(const struct wined3d_gl_info *gl_info, DWORD fla
     return MAKEDWORD_VERSION(4, 4);
 }
 
     return MAKEDWORD_VERSION(4, 4);
 }
 
+static BOOL has_extension(const char *list, const char *ext)
+{
+    size_t len = strlen(ext);
+    while (list)
+    {
+        while (*list == ' ') list++;
+        if (!strncmp(list, ext, len) && (!list[len] || list[len] == ' ')) return TRUE;
+        list = strchr(list, ' ');
+    }
+    return FALSE;
+}
+
 static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags)
 {
     static const DWORD supported_gl_versions[] =
 static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags)
 {
     static const DWORD supported_gl_versions[] =
@@ -6605,6 +6701,17 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal,
     }
 
     max_gl_version = get_max_gl_version(gl_info, wined3d_creation_flags);
     }
 
     max_gl_version = get_max_gl_version(gl_info, wined3d_creation_flags);
+
+    if (wined3d_creation_flags & WINED3D_REQUEST_D3D10)
+    {
+        const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
+        if (!has_extension(gl_extensions, "GL_ARB_compatibility"))
+        {
+            ERR_(winediag)("GL_ARB_compatibility not supported, requesting context with GL version 3.2.\n");
+            max_gl_version = MAKEDWORD_VERSION(3, 2);
+        }
+    }
+
     for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
     {
         if (supported_gl_versions[i] <= max_gl_version)
     for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
     {
         if (supported_gl_versions[i] <= max_gl_version)
@@ -6646,7 +6753,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal,
     {
         WARN("No suitable pixel formats found.\n");
         wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
     {
         WARN("No suitable pixel formats found.\n");
         wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
-        HeapFree(GetProcessHeap(), 0, adapter->cfgs);
+        heap_free(adapter->cfgs);
         return FALSE;
     }
 
         return FALSE;
     }
 
@@ -6654,7 +6761,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal,
     {
         ERR("Failed to initialize GL format info.\n");
         wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
     {
         ERR("Failed to initialize GL format info.\n");
         wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
-        HeapFree(GetProcessHeap(), 0, adapter->cfgs);
+        heap_free(adapter->cfgs);
         return FALSE;
     }
 
         return FALSE;
     }
 
diff --git a/dll/directx/wine/wined3d/drawprim.c b/dll/directx/wine/wined3d/drawprim.c
deleted file mode 100644 (file)
index fa6d508..0000000
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * WINED3D draw functions
- *
- * Copyright 2002-2004 Jason Edmeades
- * Copyright 2002-2004 Raphael Junqueira
- * Copyright 2004 Christian Costa
- * Copyright 2005 Oliver Stieber
- * Copyright 2006, 2008 Henri Verbeet
- * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
- * Copyright 2009 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
- * 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"
-
-WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
-WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
-WINE_DECLARE_DEBUG_CHANNEL(d3d);
-
-/* Context activation is done by the caller. */
-static void draw_primitive_arrays(struct wined3d_context *context, const struct wined3d_state *state,
-        const void *idx_data, unsigned int idx_size, int base_vertex_idx, unsigned int start_idx,
-        unsigned int count, unsigned int start_instance, unsigned int instance_count)
-{
-    const struct wined3d_ffp_attrib_ops *ops = &context->d3d_info->ffp_attrib_ops;
-    GLenum idx_type = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
-    const struct wined3d_stream_info *si = &context->stream_info;
-    unsigned int instanced_elements[ARRAY_SIZE(si->elements)];
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int instanced_element_count = 0;
-    unsigned int i, j;
-
-    if (!instance_count)
-    {
-        if (!idx_size)
-        {
-            gl_info->gl_ops.gl.p_glDrawArrays(state->gl_primitive_type, start_idx, count);
-            checkGLcall("glDrawArrays");
-            return;
-        }
-
-        if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
-        {
-            GL_EXTCALL(glDrawElementsBaseVertex(state->gl_primitive_type, count, idx_type,
-                    (const char *)idx_data + (idx_size * start_idx), base_vertex_idx));
-            checkGLcall("glDrawElementsBaseVertex");
-            return;
-        }
-
-        gl_info->gl_ops.gl.p_glDrawElements(state->gl_primitive_type, count,
-                idx_type, (const char *)idx_data + (idx_size * start_idx));
-        checkGLcall("glDrawElements");
-        return;
-    }
-
-    if (start_instance && !(gl_info->supported[ARB_BASE_INSTANCE] && gl_info->supported[ARB_INSTANCED_ARRAYS]))
-        FIXME("Start instance (%u) not supported.\n", start_instance);
-
-    if (gl_info->supported[ARB_INSTANCED_ARRAYS])
-    {
-        if (!idx_size)
-        {
-            if (gl_info->supported[ARB_BASE_INSTANCE])
-            {
-                GL_EXTCALL(glDrawArraysInstancedBaseInstance(state->gl_primitive_type, start_idx, count, instance_count, start_instance));
-                checkGLcall("glDrawArraysInstancedBaseInstance");
-                return;
-            }
-
-            GL_EXTCALL(glDrawArraysInstanced(state->gl_primitive_type, start_idx, count, instance_count));
-            checkGLcall("glDrawArraysInstanced");
-            return;
-        }
-
-        if (gl_info->supported[ARB_BASE_INSTANCE])
-        {
-            GL_EXTCALL(glDrawElementsInstancedBaseVertexBaseInstance(state->gl_primitive_type, count, idx_type,
-                        (const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_idx, start_instance));
-            checkGLcall("glDrawElementsInstancedBaseVertexBaseInstance");
-            return;
-        }
-        if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
-        {
-            GL_EXTCALL(glDrawElementsInstancedBaseVertex(state->gl_primitive_type, count, idx_type,
-                        (const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_idx));
-            checkGLcall("glDrawElementsInstancedBaseVertex");
-            return;
-        }
-
-        GL_EXTCALL(glDrawElementsInstanced(state->gl_primitive_type, count, idx_type,
-                    (const char *)idx_data + (idx_size * start_idx), instance_count));
-        checkGLcall("glDrawElementsInstanced");
-        return;
-    }
-
-    /* Instancing emulation by mixing immediate mode and arrays. */
-
-    /* This is a nasty thing. MSDN says no hardware supports this and
-     * applications have to use software vertex processing. We don't support
-     * this for now.
-     *
-     * Shouldn't be too hard to support with OpenGL, in theory just call
-     * glDrawArrays() instead of drawElements(). But the stream fequency value
-     * has a different meaning in that situation. */
-    if (!idx_size)
-    {
-        FIXME("Non-indexed instanced drawing is not supported\n");
-        return;
-    }
-
-    for (i = 0; i < ARRAY_SIZE(si->elements); ++i)
-    {
-        if (!(si->use_map & (1u << i)))
-            continue;
-
-        if (state->streams[si->elements[i].stream_idx].flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
-            instanced_elements[instanced_element_count++] = i;
-    }
-
-    for (i = 0; i < instance_count; ++i)
-    {
-        /* Specify the instanced attributes using immediate mode calls. */
-        for (j = 0; j < instanced_element_count; ++j)
-        {
-            const struct wined3d_stream_info_element *element;
-            unsigned int element_idx;
-            const BYTE *ptr;
-
-            element_idx = instanced_elements[j];
-            element = &si->elements[element_idx];
-            ptr = element->data.addr + element->stride * i;
-            if (element->data.buffer_object)
-                ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(state->streams[element->stream_idx].buffer, context);
-            ops->generic[element->format->emit_idx](element_idx, ptr);
-        }
-
-        if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
-        {
-            GL_EXTCALL(glDrawElementsBaseVertex(state->gl_primitive_type, count, idx_type,
-                        (const char *)idx_data + (idx_size * start_idx), base_vertex_idx));
-            checkGLcall("glDrawElementsBaseVertex");
-        }
-        else
-        {
-            gl_info->gl_ops.gl.p_glDrawElements(state->gl_primitive_type, count, idx_type,
-                        (const char *)idx_data + (idx_size * start_idx));
-            checkGLcall("glDrawElements");
-        }
-    }
-}
-
-static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size,
-        unsigned int base_vertex_idx, unsigned int start_idx, unsigned int vertex_idx)
-{
-    if (!idx_data)
-        return start_idx + vertex_idx;
-    if (idx_size == 2)
-        return ((const WORD *)idx_data)[start_idx + vertex_idx] + base_vertex_idx;
-    return ((const DWORD *)idx_data)[start_idx + vertex_idx] + base_vertex_idx;
-}
-
-/* Context activation is done by the caller. */
-static void draw_primitive_immediate_mode(struct wined3d_context *context, const struct wined3d_state *state,
-        const struct wined3d_stream_info *si, const void *idx_data, unsigned int idx_size,
-        int base_vertex_idx, unsigned int start_idx, unsigned int vertex_count, unsigned int instance_count)
-{
-    const BYTE *position = NULL, *normal = NULL, *diffuse = NULL, *specular = NULL;
-    const struct wined3d_d3d_info *d3d_info = context->d3d_info;
-    unsigned int coord_idx, stride_idx, texture_idx, vertex_idx;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    const struct wined3d_stream_info_element *element;
-    const BYTE *tex_coords[WINED3DDP_MAXTEXCOORD];
-    unsigned int texture_unit, texture_stages;
-    const struct wined3d_ffp_attrib_ops *ops;
-    unsigned int untracked_material_count;
-    unsigned int tex_mask = 0;
-    BOOL specular_fog = FALSE;
-    BOOL ps = use_ps(state);
-    const void *ptr;
-
-    static unsigned int once;
-
-    if (!once++)
-        FIXME_(d3d_perf)("Drawing using immediate mode.\n");
-    else
-        WARN_(d3d_perf)("Drawing using immediate mode.\n");
-
-    if (!idx_size && idx_data)
-        ERR("Non-NULL idx_data with 0 idx_size, this should never happen.\n");
-
-    if (instance_count)
-        FIXME("Instancing not implemented.\n");
-
-    /* Immediate mode drawing can't make use of indices in a VBO - get the
-     * data from the index buffer. */
-    if (idx_size)
-        idx_data = wined3d_buffer_load_sysmem(state->index_buffer, context) + state->index_offset;
-
-    ops = &d3d_info->ffp_attrib_ops;
-
-    gl_info->gl_ops.gl.p_glBegin(state->gl_primitive_type);
-
-    if (use_vs(state) || d3d_info->ffp_generic_attributes)
-    {
-        for (vertex_idx = 0; vertex_idx < vertex_count; ++vertex_idx)
-        {
-            unsigned int use_map = si->use_map;
-            unsigned int element_idx;
-
-            stride_idx = get_stride_idx(idx_data, idx_size, base_vertex_idx, start_idx, vertex_idx);
-            for (element_idx = MAX_ATTRIBS - 1; use_map; use_map &= ~(1u << element_idx), --element_idx)
-            {
-                if (!(use_map & 1u << element_idx))
-                    continue;
-
-                ptr = si->elements[element_idx].data.addr + si->elements[element_idx].stride * stride_idx;
-                ops->generic[si->elements[element_idx].format->emit_idx](element_idx, ptr);
-            }
-        }
-
-        gl_info->gl_ops.gl.p_glEnd();
-        return;
-    }
-
-    if (si->use_map & (1u << WINED3D_FFP_POSITION))
-        position = si->elements[WINED3D_FFP_POSITION].data.addr;
-
-    if (si->use_map & (1u << WINED3D_FFP_NORMAL))
-        normal = si->elements[WINED3D_FFP_NORMAL].data.addr;
-    else
-        gl_info->gl_ops.gl.p_glNormal3f(0.0f, 0.0f, 0.0f);
-
-    untracked_material_count = context->num_untracked_materials;
-    if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
-    {
-        element = &si->elements[WINED3D_FFP_DIFFUSE];
-        diffuse = element->data.addr;
-
-        if (untracked_material_count && element->format->id != WINED3DFMT_B8G8R8A8_UNORM)
-            FIXME("Implement diffuse color tracking from %s.\n", debug_d3dformat(element->format->id));
-    }
-    else
-    {
-        gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-    }
-
-    if (si->use_map & (1u << WINED3D_FFP_SPECULAR))
-    {
-        element = &si->elements[WINED3D_FFP_SPECULAR];
-        specular = element->data.addr;
-
-        /* Special case where the fog density is stored in the specular alpha channel. */
-        if (state->render_states[WINED3D_RS_FOGENABLE]
-                && (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE
-                    || si->elements[WINED3D_FFP_POSITION].format->id == WINED3DFMT_R32G32B32A32_FLOAT)
-                && state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
-        {
-            if (gl_info->supported[EXT_FOG_COORD])
-            {
-                if (element->format->id == WINED3DFMT_B8G8R8A8_UNORM)
-                    specular_fog = TRUE;
-                else
-                    FIXME("Implement fog coordinates from %s.\n", debug_d3dformat(element->format->id));
-            }
-            else
-            {
-                static unsigned int once;
-
-                if (!once++)
-                    FIXME("Implement fog for transformed vertices in software.\n");
-            }
-        }
-    }
-    else if (gl_info->supported[EXT_SECONDARY_COLOR])
-    {
-        GL_EXTCALL(glSecondaryColor3fEXT)(0.0f, 0.0f, 0.0f);
-    }
-
-    texture_stages = d3d_info->limits.ffp_blend_stages;
-    for (texture_idx = 0; texture_idx < texture_stages; ++texture_idx)
-    {
-        if (!gl_info->supported[ARB_MULTITEXTURE] && texture_idx > 0)
-        {
-            FIXME("Program using multiple concurrent textures which this OpenGL implementation doesn't support.\n");
-            continue;
-        }
-
-        if (!ps && !state->textures[texture_idx])
-            continue;
-
-        texture_unit = context->tex_unit_map[texture_idx];
-        if (texture_unit == WINED3D_UNMAPPED_STAGE)
-            continue;
-
-        coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
-        if (coord_idx > 7)
-        {
-            TRACE("Skipping generated coordinates (%#x) for texture %u.\n", coord_idx, texture_idx);
-            continue;
-        }
-
-        if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))
-        {
-            tex_coords[coord_idx] = si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].data.addr;
-            tex_mask |= (1u << texture_idx);
-        }
-        else
-        {
-            TRACE("Setting default coordinates for texture %u.\n", texture_idx);
-            if (gl_info->supported[ARB_MULTITEXTURE])
-                GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_unit, 0.0f, 0.0f, 0.0f, 1.0f));
-            else
-                gl_info->gl_ops.gl.p_glTexCoord4f(0.0f, 0.0f, 0.0f, 1.0f);
-        }
-    }
-
-    /* Blending data and point sizes are not supported by this function. They
-     * are not supported by the fixed function pipeline at all. A FIXME for
-     * them is printed after decoding the vertex declaration. */
-    for (vertex_idx = 0; vertex_idx < vertex_count; ++vertex_idx)
-    {
-        unsigned int tmp_tex_mask;
-
-        stride_idx = get_stride_idx(idx_data, idx_size, base_vertex_idx, start_idx, vertex_idx);
-
-        if (normal)
-        {
-            ptr = normal + stride_idx * si->elements[WINED3D_FFP_NORMAL].stride;
-            ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptr);
-        }
-
-        if (diffuse)
-        {
-            ptr = diffuse + stride_idx * si->elements[WINED3D_FFP_DIFFUSE].stride;
-            ops->diffuse[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptr);
-
-            if (untracked_material_count)
-            {
-                struct wined3d_color color;
-                unsigned int i;
-
-                wined3d_color_from_d3dcolor(&color, *(const DWORD *)ptr);
-                for (i = 0; i < untracked_material_count; ++i)
-                {
-                    gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], &color.r);
-                }
-            }
-        }
-
-        if (specular)
-        {
-            ptr = specular + stride_idx * si->elements[WINED3D_FFP_SPECULAR].stride;
-            ops->specular[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptr);
-
-            if (specular_fog)
-                GL_EXTCALL(glFogCoordfEXT((float)(*(const DWORD *)ptr >> 24)));
-        }
-
-        tmp_tex_mask = tex_mask;
-        for (texture_idx = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture_idx)
-        {
-            if (!(tmp_tex_mask & 1))
-                continue;
-
-            coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
-            ptr = tex_coords[coord_idx] + (stride_idx * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);
-            ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx](
-                    GL_TEXTURE0_ARB + context->tex_unit_map[texture_idx], ptr);
-        }
-
-        if (position)
-        {
-            ptr = position + stride_idx * si->elements[WINED3D_FFP_POSITION].stride;
-            ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptr);
-        }
-    }
-
-    gl_info->gl_ops.gl.p_glEnd();
-    checkGLcall("glEnd and previous calls");
-}
-
-static void draw_indirect(struct wined3d_context *context, const struct wined3d_state *state,
-        const struct wined3d_indirect_draw_parameters *parameters, unsigned int idx_size)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_buffer *buffer = parameters->buffer;
-
-    if (!gl_info->supported[ARB_DRAW_INDIRECT])
-    {
-        FIXME("OpenGL implementation does not support indirect draws.\n");
-        return;
-    }
-
-    GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->buffer_object));
-
-    if (idx_size)
-    {
-        GLenum idx_type = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
-        if (state->index_offset)
-            FIXME("Ignoring index offset %u.\n", state->index_offset);
-        GL_EXTCALL(glDrawElementsIndirect(state->gl_primitive_type, idx_type,
-                (void *)(GLintptr)parameters->offset));
-    }
-    else
-    {
-        GL_EXTCALL(glDrawArraysIndirect(state->gl_primitive_type,
-                (void *)(GLintptr)parameters->offset));
-    }
-
-    GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0));
-
-    checkGLcall("draw indirect");
-}
-
-static void remove_vbos(struct wined3d_context *context,
-        const struct wined3d_state *state, struct wined3d_stream_info *s)
-{
-    unsigned int i;
-
-    for (i = 0; i < ARRAY_SIZE(s->elements); ++i)
-    {
-        struct wined3d_stream_info_element *e;
-
-        if (!(s->use_map & (1u << i)))
-            continue;
-
-        e = &s->elements[i];
-        if (e->data.buffer_object)
-        {
-            struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer;
-            e->data.buffer_object = 0;
-            e->data.addr += (ULONG_PTR)wined3d_buffer_load_sysmem(vb, context);
-        }
-    }
-}
-
-static BOOL use_transform_feedback(const struct wined3d_state *state)
-{
-    const struct wined3d_shader *shader;
-    if (!(shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]))
-        return FALSE;
-    return shader->u.gs.so_desc.element_count;
-}
-
-static void context_pause_transform_feedback(struct wined3d_context *context, BOOL force)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-
-    if (!context->transform_feedback_active || context->transform_feedback_paused)
-        return;
-
-    if (gl_info->supported[ARB_TRANSFORM_FEEDBACK2])
-    {
-        GL_EXTCALL(glPauseTransformFeedback());
-        checkGLcall("glPauseTransformFeedback");
-        context->transform_feedback_paused = 1;
-        return;
-    }
-
-    WARN("Cannot pause transform feedback operations.\n");
-
-    if (force)
-        context_end_transform_feedback(context);
-}
-
-static GLenum gl_tfb_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
-{
-    GLenum gl_primitive_type = gl_primitive_type_from_d3d(primitive_type);
-    switch (gl_primitive_type)
-    {
-        case GL_POINTS:
-            return GL_POINTS;
-
-        case GL_LINE_STRIP:
-        case GL_LINE_STRIP_ADJACENCY:
-        case GL_LINES_ADJACENCY:
-        case GL_LINES:
-            return GL_LINES;
-
-        case GL_TRIANGLE_FAN:
-        case GL_TRIANGLE_STRIP:
-        case GL_TRIANGLE_STRIP_ADJACENCY:
-        case GL_TRIANGLES_ADJACENCY:
-        case GL_TRIANGLES:
-            return GL_TRIANGLES;
-
-        default:
-            return gl_primitive_type;
-    }
-}
-
-/* Routine common to the draw primitive and draw indexed primitive routines */
-void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state,
-        const struct wined3d_draw_parameters *parameters)
-{
-    BOOL emulation = FALSE, rasterizer_discard = FALSE;
-    const struct wined3d_fb_state *fb = state->fb;
-    const struct wined3d_stream_info *stream_info;
-    struct wined3d_rendertarget_view *dsv, *rtv;
-    struct wined3d_stream_info si_emulated;
-    struct wined3d_fence *ib_fence = NULL;
-    const struct wined3d_gl_info *gl_info;
-    struct wined3d_context *context;
-    unsigned int i, idx_size = 0;
-    const void *idx_data = NULL;
-
-    if (!parameters->indirect && !parameters->u.direct.index_count)
-        return;
-
-    if (!(rtv = fb->render_targets[0]))
-        rtv = fb->depth_stencil;
-    if (rtv)
-        context = context_acquire(device, wined3d_texture_from_resource(rtv->resource), rtv->sub_resource_idx);
-    else
-        context = context_acquire(device, NULL, 0);
-    if (!context->valid)
-    {
-        context_release(context);
-        WARN("Invalid context, skipping draw.\n");
-        return;
-    }
-    gl_info = context->gl_info;
-
-    if (!use_transform_feedback(state))
-        context_pause_transform_feedback(context, TRUE);
-
-    for (i = 0; i < gl_info->limits.buffers; ++i)
-    {
-        if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL)
-            continue;
-
-        if (state->render_states[WINED3D_RS_COLORWRITEENABLE])
-        {
-            wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding);
-            wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding);
-        }
-        else
-        {
-            wined3d_rendertarget_view_prepare_location(rtv, context, rtv->resource->draw_binding);
-        }
-    }
-
-    if ((dsv = fb->depth_stencil))
-    {
-        /* Note that this depends on the context_acquire() call above to set
-         * context->render_offscreen properly. We don't currently take the
-         * Z-compare function into account, but we could skip loading the
-         * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note
-         * that we never copy the stencil data.*/
-        DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
-
-        if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE])
-            wined3d_rendertarget_view_load_location(dsv, context, location);
-        else
-            wined3d_rendertarget_view_prepare_location(dsv, context, location);
-    }
-
-    if (parameters->indirect)
-        wined3d_buffer_load(parameters->u.indirect.buffer, context, state);
-
-    if (!context_apply_draw_state(context, device, state))
-    {
-        context_release(context);
-        WARN("Unable to apply draw state, skipping draw.\n");
-        return;
-    }
-
-    if (dsv && state->render_states[WINED3D_RS_ZWRITEENABLE])
-    {
-        DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
-
-        wined3d_rendertarget_view_validate_location(dsv, location);
-        wined3d_rendertarget_view_invalidate_location(dsv, ~location);
-    }
-
-    stream_info = &context->stream_info;
-
-    if (parameters->indexed)
-    {
-        struct wined3d_buffer *index_buffer = state->index_buffer;
-        if (!index_buffer->buffer_object || !stream_info->all_vbo)
-        {
-            idx_data = index_buffer->resource.heap_memory;
-        }
-        else
-        {
-            ib_fence = index_buffer->fence;
-            idx_data = NULL;
-        }
-        idx_data = (const BYTE *)idx_data + state->index_offset;
-
-        if (state->index_format == WINED3DFMT_R16_UINT)
-            idx_size = 2;
-        else
-            idx_size = 4;
-    }
-
-    if (!use_vs(state))
-    {
-        if (!stream_info->position_transformed && context->num_untracked_materials
-                && state->render_states[WINED3D_RS_LIGHTING])
-        {
-            static BOOL warned;
-
-            if (!warned++)
-                FIXME("Using software emulation because not all material properties could be tracked.\n");
-            else
-                WARN_(d3d_perf)("Using software emulation because not all material properties could be tracked.\n");
-            emulation = TRUE;
-        }
-        else if (context->fog_coord && state->render_states[WINED3D_RS_FOGENABLE])
-        {
-            static BOOL warned;
-
-            /* Either write a pipeline replacement shader or convert the
-             * specular alpha from unsigned byte to a float in the vertex
-             * buffer. */
-            if (!warned++)
-                FIXME("Using software emulation because manual fog coordinates are provided.\n");
-            else
-                WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n");
-            emulation = TRUE;
-        }
-
-        if (emulation)
-        {
-            si_emulated = context->stream_info;
-            remove_vbos(context, state, &si_emulated);
-            stream_info = &si_emulated;
-        }
-    }
-
-    if (use_transform_feedback(state))
-    {
-        const struct wined3d_shader *shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
-
-        if (is_rasterization_disabled(shader))
-        {
-            glEnable(GL_RASTERIZER_DISCARD);
-            checkGLcall("enable rasterizer discard");
-            rasterizer_discard = TRUE;
-        }
-
-        if (context->transform_feedback_paused)
-        {
-            GL_EXTCALL(glResumeTransformFeedback());
-            checkGLcall("glResumeTransformFeedback");
-            context->transform_feedback_paused = 0;
-        }
-        else if (!context->transform_feedback_active)
-        {
-            GLenum mode = gl_tfb_primitive_type_from_d3d(shader->u.gs.output_type);
-            GL_EXTCALL(glBeginTransformFeedback(mode));
-            checkGLcall("glBeginTransformFeedback");
-            context->transform_feedback_active = 1;
-        }
-    }
-
-    if (state->gl_primitive_type == GL_PATCHES)
-    {
-        GL_EXTCALL(glPatchParameteri(GL_PATCH_VERTICES, state->gl_patch_vertices));
-        checkGLcall("glPatchParameteri");
-    }
-
-    if (parameters->indirect)
-    {
-        if (!context->use_immediate_mode_draw && !emulation)
-            draw_indirect(context, state, &parameters->u.indirect, idx_size);
-        else
-            FIXME("Indirect draws with immediate mode/emulation are not supported.\n");
-    }
-    else
-    {
-        unsigned int instance_count = parameters->u.direct.instance_count;
-        if (context->instance_count)
-            instance_count = context->instance_count;
-
-        if (context->use_immediate_mode_draw || emulation)
-            draw_primitive_immediate_mode(context, state, stream_info, idx_data,
-                    idx_size, parameters->u.direct.base_vertex_idx,
-                    parameters->u.direct.start_idx, parameters->u.direct.index_count, instance_count);
-        else
-            draw_primitive_arrays(context, state, idx_data, idx_size, parameters->u.direct.base_vertex_idx,
-                    parameters->u.direct.start_idx, parameters->u.direct.index_count,
-                    parameters->u.direct.start_instance, instance_count);
-    }
-
-    if (context->uses_uavs)
-    {
-        GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
-        checkGLcall("glMemoryBarrier");
-    }
-
-    context_pause_transform_feedback(context, FALSE);
-
-    if (rasterizer_discard)
-    {
-        glDisable(GL_RASTERIZER_DISCARD);
-        checkGLcall("disable rasterizer discard");
-    }
-
-    if (ib_fence)
-        wined3d_fence_issue(ib_fence, device);
-    for (i = 0; i < context->buffer_fence_count; ++i)
-        wined3d_fence_issue(context->buffer_fences[i], device);
-
-    if (wined3d_settings.strict_draw_ordering)
-        gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
-
-    context_release(context);
-
-    TRACE("Done all gl drawing.\n");
-}
-
-void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state,
-        const struct wined3d_dispatch_parameters *parameters)
-{
-    const struct wined3d_gl_info *gl_info;
-    struct wined3d_context *context;
-
-    context = context_acquire(device, NULL, 0);
-    if (!context->valid)
-    {
-        context_release(context);
-        WARN("Invalid context, skipping dispatch.\n");
-        return;
-    }
-    gl_info = context->gl_info;
-
-    if (!gl_info->supported[ARB_COMPUTE_SHADER])
-    {
-        context_release(context);
-        FIXME("OpenGL implementation does not support compute shaders.\n");
-        return;
-    }
-
-    if (parameters->indirect)
-        wined3d_buffer_load(parameters->u.indirect.buffer, context, state);
-
-    context_apply_compute_state(context, device, state);
-
-    if (!state->shader[WINED3D_SHADER_TYPE_COMPUTE])
-    {
-        context_release(context);
-        WARN("No compute shader bound, skipping dispatch.\n");
-        return;
-    }
-
-    if (parameters->indirect)
-    {
-        const struct wined3d_indirect_dispatch_parameters *indirect = &parameters->u.indirect;
-        struct wined3d_buffer *buffer = indirect->buffer;
-
-        GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer->buffer_object));
-        GL_EXTCALL(glDispatchComputeIndirect((GLintptr)indirect->offset));
-        GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0));
-    }
-    else
-    {
-        const struct wined3d_direct_dispatch_parameters *direct = &parameters->u.direct;
-        GL_EXTCALL(glDispatchCompute(direct->group_count_x, direct->group_count_y, direct->group_count_z));
-    }
-    checkGLcall("dispatch compute");
-
-    GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
-    checkGLcall("glMemoryBarrier");
-
-    if (wined3d_settings.strict_draw_ordering)
-        gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
-
-    context_release(context);
-}
index 8c6f2c5..03e4b26 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 #include "wined3d_private.h"
-
-#include <wine/library.h>
+#include "wine/library.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
index d4e36d9..7e6b510 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(gl_compat);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(gl_compat);
index 3796865..4c879f9 100644 (file)
  * mask for the destination parameter into account.
  */
 
  * mask for the destination parameter into account.
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <limits.h>
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
@@ -82,6 +91,7 @@ struct glsl_sample_function
     enum wined3d_data_type data_type;
     BOOL output_single_component;
     unsigned int offset_size;
     enum wined3d_data_type data_type;
     BOOL output_single_component;
     unsigned int offset_size;
+    enum wined3d_shader_resource_type emulate_lod;
 };
 
 enum heap_node_op
 };
 
 enum heap_node_op
@@ -134,9 +144,9 @@ struct glsl_vs_program
     GLint uniform_b_locations[WINED3D_MAX_CONSTS_B];
     GLint pos_fixup_location;
 
     GLint uniform_b_locations[WINED3D_MAX_CONSTS_B];
     GLint pos_fixup_location;
 
-    GLint modelview_matrix_location[MAX_VERTEX_BLENDS];
+    GLint modelview_matrix_location[MAX_VERTEX_INDEX_BLENDS];
+    GLint normal_matrix_location[MAX_VERTEX_INDEX_BLENDS];
     GLint projection_matrix_location;
     GLint projection_matrix_location;
-    GLint normal_matrix_location;
     GLint texture_matrix_location[MAX_TEXTURES];
     GLint material_ambient_location;
     GLint material_diffuse_location;
     GLint texture_matrix_location[MAX_TEXTURES];
     GLint material_ambient_location;
     GLint material_diffuse_location;
@@ -465,7 +475,7 @@ void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL
     {
         const char *ptr, *line;
 
     {
         const char *ptr, *line;
 
-        log = HeapAlloc(GetProcessHeap(), 0, length);
+        log = heap_alloc(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
         /* 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
@@ -487,7 +497,7 @@ void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL
             FIXME("Info log received from GLSL shader #%u:\n", id);
             while ((line = get_info_log_line(&ptr))) FIXME("    %.*s", (int)(ptr - line), line);
         }
             FIXME("Info log received from GLSL shader #%u:\n", id);
             while ((line = get_info_log_line(&ptr))) FIXME("    %.*s", (int)(ptr - line), line);
         }
-        HeapFree(GetProcessHeap(), 0, log);
+        heap_free(log);
     }
 }
 
     }
 }
 
@@ -519,7 +529,7 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf
     char *source = NULL;
 
     GL_EXTCALL(glGetProgramiv(program, GL_ATTACHED_SHADERS, &shader_count));
     char *source = NULL;
 
     GL_EXTCALL(glGetProgramiv(program, GL_ATTACHED_SHADERS, &shader_count));
-    if (!(shaders = wined3d_calloc(shader_count, sizeof(*shaders))))
+    if (!(shaders = heap_calloc(shader_count, sizeof(*shaders))))
     {
         ERR("Failed to allocate shader array memory.\n");
         return;
     {
         ERR("Failed to allocate shader array memory.\n");
         return;
@@ -535,13 +545,12 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf
 
         if (source_size < tmp)
         {
 
         if (source_size < tmp)
         {
-            HeapFree(GetProcessHeap(), 0, source);
+            heap_free(source);
 
 
-            source = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, tmp);
-            if (!source)
+            if (!(source = heap_alloc_zero(tmp)))
             {
                 ERR("Failed to allocate %d bytes for shader source.\n", tmp);
             {
                 ERR("Failed to allocate %d bytes for shader source.\n", tmp);
-                HeapFree(GetProcessHeap(), 0, shaders);
+                heap_free(shaders);
                 return;
             }
             source_size = tmp;
                 return;
             }
             source_size = tmp;
@@ -560,8 +569,8 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf
         FIXME("\n");
     }
 
         FIXME("\n");
     }
 
-    HeapFree(GetProcessHeap(), 0, source);
-    HeapFree(GetProcessHeap(), 0, shaders);
+    heap_free(source);
+    heap_free(shaders);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -935,16 +944,16 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co
 
     shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode);
 
 
     shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode);
 
-    if (!(varyings = wined3d_calloc(count, sizeof(*varyings))))
+    if (!(varyings = heap_calloc(count, sizeof(*varyings))))
     {
         ERR("Out of memory.\n");
         string_buffer_release(&priv->string_buffers, buffer);
         return;
     }
     {
         ERR("Out of memory.\n");
         string_buffer_release(&priv->string_buffers, buffer);
         return;
     }
-    if (!(strings = wined3d_calloc(length, sizeof(*strings))))
+    if (!(strings = heap_calloc(length, sizeof(*strings))))
     {
         ERR("Out of memory.\n");
     {
         ERR("Out of memory.\n");
-        HeapFree(GetProcessHeap(), 0, varyings);
+        heap_free(varyings);
         string_buffer_release(&priv->string_buffers, buffer);
         return;
     }
         string_buffer_release(&priv->string_buffers, buffer);
         return;
     }
@@ -953,8 +962,8 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co
     GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode));
     checkGLcall("glTransformFeedbackVaryings");
 
     GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode));
     checkGLcall("glTransformFeedbackVaryings");
 
-    HeapFree(GetProcessHeap(), 0, varyings);
-    HeapFree(GetProcessHeap(), 0, strings);
+    heap_free(varyings);
+    heap_free(strings);
     string_buffer_release(&priv->string_buffers, buffer);
 }
 
     string_buffer_release(&priv->string_buffers, buffer);
 }
 
@@ -1228,320 +1237,6 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps
     GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, &np2fixup_constants[0].sx));
 }
 
     GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, &np2fixup_constants[0].sx));
 }
 
-/* Taken and adapted from Mesa. */
-static BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in)
-{
-    float pos, neg, t, det;
-    struct wined3d_matrix temp;
-
-    /* Calculate the determinant of upper left 3x3 submatrix and
-     * determine if the matrix is singular. */
-    pos = neg = 0.0f;
-    t =  in->_11 * in->_22 * in->_33;
-    if (t >= 0.0f)
-        pos += t;
-    else
-        neg += t;
-
-    t =  in->_21 * in->_32 * in->_13;
-    if (t >= 0.0f)
-        pos += t;
-    else
-        neg += t;
-    t =  in->_31 * in->_12 * in->_23;
-    if (t >= 0.0f)
-        pos += t;
-    else
-        neg += t;
-
-    t = -in->_31 * in->_22 * in->_13;
-    if (t >= 0.0f)
-        pos += t;
-    else
-        neg += t;
-    t = -in->_21 * in->_12 * in->_33;
-    if (t >= 0.0f)
-        pos += t;
-    else
-        neg += t;
-
-    t = -in->_11 * in->_32 * in->_23;
-    if (t >= 0.0f)
-        pos += t;
-    else
-        neg += t;
-
-    det = pos + neg;
-
-    if (fabsf(det) < 1e-25f)
-        return FALSE;
-
-    det = 1.0f / det;
-    temp._11 =  (in->_22 * in->_33 - in->_32 * in->_23) * det;
-    temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det;
-    temp._13 =  (in->_12 * in->_23 - in->_22 * in->_13) * det;
-    temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det;
-    temp._22 =  (in->_11 * in->_33 - in->_31 * in->_13) * det;
-    temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det;
-    temp._31 =  (in->_21 * in->_32 - in->_31 * in->_22) * det;
-    temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det;
-    temp._33 =  (in->_11 * in->_22 - in->_21 * in->_12) * det;
-
-    *out = temp;
-    return TRUE;
-}
-
-static void swap_rows(float **a, float **b)
-{
-    float *tmp = *a;
-
-    *a = *b;
-    *b = tmp;
-}
-
-static BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m)
-{
-    float wtmp[4][8];
-    float m0, m1, m2, m3, s;
-    float *r0, *r1, *r2, *r3;
-
-    r0 = wtmp[0];
-    r1 = wtmp[1];
-    r2 = wtmp[2];
-    r3 = wtmp[3];
-
-    r0[0] = m->_11;
-    r0[1] = m->_12;
-    r0[2] = m->_13;
-    r0[3] = m->_14;
-    r0[4] = 1.0f;
-    r0[5] = r0[6] = r0[7] = 0.0f;
-
-    r1[0] = m->_21;
-    r1[1] = m->_22;
-    r1[2] = m->_23;
-    r1[3] = m->_24;
-    r1[5] = 1.0f;
-    r1[4] = r1[6] = r1[7] = 0.0f;
-
-    r2[0] = m->_31;
-    r2[1] = m->_32;
-    r2[2] = m->_33;
-    r2[3] = m->_34;
-    r2[6] = 1.0f;
-    r2[4] = r2[5] = r2[7] = 0.0f;
-
-    r3[0] = m->_41;
-    r3[1] = m->_42;
-    r3[2] = m->_43;
-    r3[3] = m->_44;
-    r3[7] = 1.0f;
-    r3[4] = r3[5] = r3[6] = 0.0f;
-
-    /* Choose pivot - or die. */
-    if (fabsf(r3[0]) > fabsf(r2[0]))
-        swap_rows(&r3, &r2);
-    if (fabsf(r2[0]) > fabsf(r1[0]))
-        swap_rows(&r2, &r1);
-    if (fabsf(r1[0]) > fabsf(r0[0]))
-        swap_rows(&r1, &r0);
-    if (r0[0] == 0.0f)
-        return FALSE;
-
-    /* Eliminate first variable. */
-    m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0];
-    s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
-    s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
-    s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
-    s = r0[4];
-    if (s != 0.0f)
-    {
-        r1[4] -= m1 * s;
-        r2[4] -= m2 * s;
-        r3[4] -= m3 * s;
-    }
-    s = r0[5];
-    if (s != 0.0f)
-    {
-        r1[5] -= m1 * s;
-        r2[5] -= m2 * s;
-        r3[5] -= m3 * s;
-    }
-    s = r0[6];
-    if (s != 0.0f)
-    {
-        r1[6] -= m1 * s;
-        r2[6] -= m2 * s;
-        r3[6] -= m3 * s;
-    }
-    s = r0[7];
-    if (s != 0.0f)
-    {
-        r1[7] -= m1 * s;
-        r2[7] -= m2 * s;
-        r3[7] -= m3 * s;
-    }
-
-    /* Choose pivot - or die. */
-    if (fabsf(r3[1]) > fabsf(r2[1]))
-        swap_rows(&r3, &r2);
-    if (fabsf(r2[1]) > fabsf(r1[1]))
-        swap_rows(&r2, &r1);
-    if (r1[1] == 0.0f)
-        return FALSE;
-
-    /* Eliminate second variable. */
-    m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1];
-    r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
-    r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
-    s = r1[4];
-    if (s != 0.0f)
-    {
-        r2[4] -= m2 * s;
-        r3[4] -= m3 * s;
-    }
-    s = r1[5];
-    if (s != 0.0f)
-    {
-        r2[5] -= m2 * s;
-        r3[5] -= m3 * s;
-    }
-    s = r1[6];
-    if (s != 0.0f)
-    {
-        r2[6] -= m2 * s;
-        r3[6] -= m3 * s;
-    }
-    s = r1[7];
-    if (s != 0.0f)
-    {
-        r2[7] -= m2 * s;
-        r3[7] -= m3 * s;
-    }
-
-    /* Choose pivot - or die. */
-    if (fabsf(r3[2]) > fabsf(r2[2]))
-        swap_rows(&r3, &r2);
-    if (r2[2] == 0.0f)
-        return FALSE;
-
-    /* Eliminate third variable. */
-    m3 = r3[2] / r2[2];
-    r3[3] -= m3 * r2[3];
-    r3[4] -= m3 * r2[4];
-    r3[5] -= m3 * r2[5];
-    r3[6] -= m3 * r2[6];
-    r3[7] -= m3 * r2[7];
-
-    /* Last check. */
-    if (r3[3] == 0.0f)
-        return FALSE;
-
-    /* Back substitute row 3. */
-    s = 1.0f / r3[3];
-    r3[4] *= s;
-    r3[5] *= s;
-    r3[6] *= s;
-    r3[7] *= s;
-
-    /* Back substitute row 2. */
-    m2 = r2[3];
-    s = 1.0f / r2[2];
-    r2[4] = s * (r2[4] - r3[4] * m2);
-    r2[5] = s * (r2[5] - r3[5] * m2);
-    r2[6] = s * (r2[6] - r3[6] * m2);
-    r2[7] = s * (r2[7] - r3[7] * m2);
-    m1 = r1[3];
-    r1[4] -= r3[4] * m1;
-    r1[5] -= r3[5] * m1;
-    r1[6] -= r3[6] * m1;
-    r1[7] -= r3[7] * m1;
-    m0 = r0[3];
-    r0[4] -= r3[4] * m0;
-    r0[5] -= r3[5] * m0;
-    r0[6] -= r3[6] * m0;
-    r0[7] -= r3[7] * m0;
-
-    /* Back substitute row 1. */
-    m1 = r1[2];
-    s = 1.0f / r1[1];
-    r1[4] = s * (r1[4] - r2[4] * m1);
-    r1[5] = s * (r1[5] - r2[5] * m1);
-    r1[6] = s * (r1[6] - r2[6] * m1);
-    r1[7] = s * (r1[7] - r2[7] * m1);
-    m0 = r0[2];
-    r0[4] -= r2[4] * m0;
-    r0[5] -= r2[5] * m0;
-    r0[6] -= r2[6] * m0;
-    r0[7] -= r2[7] * m0;
-
-    /* Back substitute row 0. */
-    m0 = r0[1];
-    s = 1.0f / r0[0];
-    r0[4] = s * (r0[4] - r1[4] * m0);
-    r0[5] = s * (r0[5] - r1[5] * m0);
-    r0[6] = s * (r0[6] - r1[6] * m0);
-    r0[7] = s * (r0[7] - r1[7] * m0);
-
-    out->_11 = r0[4];
-    out->_12 = r0[5];
-    out->_13 = r0[6];
-    out->_14 = r0[7];
-    out->_21 = r1[4];
-    out->_22 = r1[5];
-    out->_23 = r1[6];
-    out->_24 = r1[7];
-    out->_31 = r2[4];
-    out->_32 = r2[5];
-    out->_33 = r2[6];
-    out->_34 = r2[7];
-    out->_41 = r3[4];
-    out->_42 = r3[5];
-    out->_43 = r3[6];
-    out->_44 = r3[7];
-
-    return TRUE;
-}
-
-static void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m)
-{
-    struct wined3d_matrix temp;
-    unsigned int i, j;
-
-    for (i = 0; i < 4; ++i)
-        for (j = 0; j < 4; ++j)
-            (&temp._11)[4 * j + i] = (&m->_11)[4 * i + j];
-
-    *out = temp;
-}
-
-static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_context *context,
-        const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    float mat[3 * 3];
-    struct wined3d_matrix mv;
-    unsigned int i, j;
-
-    if (prog->vs.normal_matrix_location == -1)
-        return;
-
-    get_modelview_matrix(context, state, 0, &mv);
-    if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING)
-        invert_matrix_3d(&mv, &mv);
-    else
-        invert_matrix(&mv, &mv);
-    /* Tests show that singular modelview matrices are used unchanged as normal
-     * matrices on D3D3 and older. There seems to be no clearly consistent
-     * behavior on newer D3D versions so always follow older ddraw behavior. */
-    for (i = 0; i < 3; ++i)
-        for (j = 0; j < 3; ++j)
-            mat[i * 3 + j] = (&mv._11)[j * 4 + i];
-
-    GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location, 1, FALSE, mat));
-    checkGLcall("glUniformMatrix3fv");
-}
-
 static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context *context,
         const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog)
 {
 static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context *context,
         const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog)
 {
@@ -1739,6 +1434,23 @@ static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps
     GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r));
 }
 
     GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r));
 }
 
+/* Context activation is done by the caller. */
+static void get_normal_matrix(struct wined3d_context *context, struct wined3d_matrix *mat, float *normal)
+{
+    int i, j;
+
+    if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING)
+        invert_matrix_3d(mat, mat);
+    else
+        invert_matrix(mat, mat);
+    /* Tests show that singular modelview matrices are used unchanged as normal
+     * matrices on D3D3 and older. There seems to be no clearly consistent
+     * behavior on newer D3D versions so always follow older ddraw behavior. */
+    for (i = 0; i < 3; ++i)
+        for (j = 0; j < 3; ++j)
+            normal[i * 3 + j] = (&mat->_11)[j * 4 + i];
+}
+
 /* Context activation is done by the caller (state handler). */
 static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context,
         const struct wined3d_state *state)
 /* Context activation is done by the caller (state handler). */
 static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context,
         const struct wined3d_state *state)
@@ -1749,6 +1461,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_priv *priv = shader_priv;
     float position_fixup[4];
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_priv *priv = shader_priv;
     float position_fixup[4];
+    float normal[3 * 3];
     DWORD update_mask;
 
     struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
     DWORD update_mask;
 
     struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
@@ -1803,21 +1516,29 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
         GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11));
         checkGLcall("glUniformMatrix4fv");
 
         GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11));
         checkGLcall("glUniformMatrix4fv");
 
-        shader_glsl_ffp_vertex_normalmatrix_uniform(context, state, prog);
+        get_normal_matrix(context, &mat, normal);
+        GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[0], 1, FALSE, normal));
+        checkGLcall("glUniformMatrix3fv");
     }
 
     if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND)
     {
         struct wined3d_matrix mat;
 
     }
 
     if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND)
     {
         struct wined3d_matrix mat;
 
-        for (i = 1; i < MAX_VERTEX_BLENDS; ++i)
+        for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i)
         {
             if (prog->vs.modelview_matrix_location[i] == -1)
                 break;
         {
             if (prog->vs.modelview_matrix_location[i] == -1)
                 break;
+            if (!(update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i)))
+                continue;
 
             get_modelview_matrix(context, state, i, &mat);
             GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11));
             checkGLcall("glUniformMatrix4fv");
 
             get_modelview_matrix(context, state, i, &mat);
             GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11));
             checkGLcall("glUniformMatrix4fv");
+
+            get_normal_matrix(context, &mat, normal);
+            GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[i], 1, FALSE, normal));
+            checkGLcall("glUniformMatrix3fv");
         }
     }
 
         }
     }
 
@@ -2236,11 +1957,6 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_
     }
 }
 
     }
 }
 
-static const char *get_fragment_output(const struct wined3d_gl_info *gl_info)
-{
-    return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" : "ps_out";
-}
-
 static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
 {
     switch (primitive_type)
 static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
 {
     switch (primitive_type)
@@ -2568,6 +2284,13 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
                     sampler_type = "samplerCube";
                 break;
 
                     sampler_type = "samplerCube";
                 break;
 
+            case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY:
+                if (shadow_sampler)
+                    sampler_type = "sampler1DArrayShadow";
+                else
+                    sampler_type = "sampler1DArray";
+                break;
+
             case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
                 if (shadow_sampler)
                     sampler_type = "sampler2DArrayShadow";
             case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
                 if (shadow_sampler)
                     sampler_type = "sampler2DArrayShadow";
@@ -2582,6 +2305,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
                     sampler_type = "samplerCubeArray";
                 break;
 
                     sampler_type = "samplerCubeArray";
                 break;
 
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DMS:
+                sampler_type = "sampler2DMS";
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY:
+                sampler_type = "sampler2DMSArray";
+                break;
+
             default:
                 sampler_type = "unsupported_sampler";
                 FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[entry->resource_idx].type);
             default:
                 sampler_type = "unsupported_sampler";
                 FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[entry->resource_idx].type);
@@ -2990,11 +2721,13 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             break;
 
         case WINED3DSPR_COLOROUT:
             break;
 
         case WINED3DSPR_COLOROUT:
+            /* FIXME: should check dual_buffers when dual blending is enabled */
             if (reg->idx[0].offset >= gl_info->limits.buffers)
                 WARN("Write to render target %u, only %d supported.\n",
                         reg->idx[0].offset, gl_info->limits.buffers);
 
             if (reg->idx[0].offset >= gl_info->limits.buffers)
                 WARN("Write to render target %u, only %d supported.\n",
                         reg->idx[0].offset, gl_info->limits.buffers);
 
-            sprintf(register_name, "%s[%u]", get_fragment_output(gl_info), reg->idx[0].offset);
+            sprintf(register_name, needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[%u]" : "ps_out%u",
+                    reg->idx[0].offset);
             break;
 
         case WINED3DSPR_RASTOUT:
             break;
 
         case WINED3DSPR_RASTOUT:
@@ -3510,6 +3243,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
     struct shader_glsl_ctx_priv *priv = ctx->backend_data;
     const struct wined3d_gl_info *gl_info = ctx->gl_info;
     enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
     struct shader_glsl_ctx_priv *priv = ctx->backend_data;
     const struct wined3d_gl_info *gl_info = ctx->gl_info;
+    BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
     BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx);
     BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
     BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
     BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx);
     BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
     BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
@@ -3522,6 +3256,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     unsigned int coord_size, deriv_size;
 
     sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type;
     unsigned int coord_size, deriv_size;
 
     sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type;
+    sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE;
 
     if (resource_type >= ARRAY_SIZE(resource_type_info))
     {
 
     if (resource_type >= ARRAY_SIZE(resource_type_info))
     {
@@ -3533,7 +3268,30 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
         projected = FALSE;
 
     if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
         projected = FALSE;
 
-    if (needs_legacy_glsl_syntax(gl_info))
+    if (shadow && lod)
+    {
+        switch (resource_type)
+        {
+            /* emulate textureLod(sampler2DArrayShadow, ...) using textureGradOffset */
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
+                sample_function->emulate_lod = resource_type;
+                grad = offset = TRUE;
+                lod = FALSE;
+                break;
+
+            /* emulate textureLod(samplerCubeShadow, ...) using shadowCubeGrad */
+            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+                sample_function->emulate_lod = resource_type;
+                grad = legacy_syntax = TRUE;
+                lod = FALSE;
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    if (legacy_syntax)
     {
         if (shadow)
             base = "shadow";
     {
         if (shadow)
             base = "shadow";
@@ -3573,7 +3331,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     sample_function->offset_size = offset ? deriv_size : 0;
     sample_function->coord_mask = (1u << coord_size) - 1;
     sample_function->deriv_mask = (1u << deriv_size) - 1;
     sample_function->offset_size = offset ? deriv_size : 0;
     sample_function->coord_mask = (1u << coord_size) - 1;
     sample_function->deriv_mask = (1u << deriv_size) - 1;
-    sample_function->output_single_component = shadow && !needs_legacy_glsl_syntax(gl_info);
+    sample_function->output_single_component = shadow && !legacy_syntax;
 }
 
 static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx,
 }
 
 static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx,
@@ -3694,6 +3452,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
         const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset,
         const char *coord_reg_fmt, ...)
 {
         const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset,
         const char *coord_reg_fmt, ...)
 {
+    static const struct wined3d_shader_texel_offset dummy_offset = {0, 0, 0};
     const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
     char dst_swizzle[6];
     struct color_fixup_desc fixup;
     const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
     char dst_swizzle[6];
     struct color_fixup_desc fixup;
@@ -3762,6 +3521,26 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
                 break;
         }
     }
                 break;
         }
     }
+    if (sample_function->emulate_lod)
+    {
+        if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod level %s\n", bias);
+        switch (sample_function->emulate_lod)
+        {
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
+                if (!dx) dx = "vec2(0.0, 0.0)";
+                if (!dy) dy = "vec2(0.0, 0.0)";
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+                if (!dx) dx = "vec3(0.0, 0.0, 0.0)";
+                if (!dy) dy = "vec3(0.0, 0.0, 0.0)";
+                break;
+
+            default:
+                break;
+        }
+        if (!offset) offset = &dummy_offset;
+    }
     if (dx && dy)
         shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy);
     else if (bias)
     if (dx && dy)
         shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy);
     else if (bias)
@@ -5877,15 +5656,28 @@ static void shader_glsl_bufinfo(const struct wined3d_shader_instruction *ins)
     shader_addline(buffer, ", %u)%s);\n", resource_info->stride, dst_swizzle);
 }
 
     shader_addline(buffer, ", %u)%s);\n", resource_info->stride, dst_swizzle);
 }
 
+static BOOL is_multisampled(enum wined3d_shader_resource_type resource_type)
+{
+    return resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2DMS
+            || resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY;
+}
+
+static BOOL is_mipmapped(enum wined3d_shader_resource_type resource_type)
+{
+    return resource_type != WINED3D_SHADER_RESOURCE_BUFFER && !is_multisampled(resource_type);
+}
+
 static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
     const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
 static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
     const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
+    struct wined3d_string_buffer *buffer = ins->ctx->buffer;
     enum wined3d_shader_resource_type resource_type;
     enum wined3d_shader_register_type reg_type;
     unsigned int resource_idx, bind_idx, i;
     enum wined3d_data_type dst_data_type;
     struct glsl_src_param lod_param;
     enum wined3d_shader_resource_type resource_type;
     enum wined3d_shader_register_type reg_type;
     unsigned int resource_idx, bind_idx, i;
     enum wined3d_data_type dst_data_type;
     struct glsl_src_param lod_param;
+    BOOL supports_mipmaps;
     char dst_swizzle[6];
     DWORD write_mask;
 
     char dst_swizzle[6];
     DWORD write_mask;
 
@@ -5895,9 +5687,6 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
     else if (ins->flags)
         FIXME("Unhandled flags %#x.\n", ins->flags);
 
     else if (ins->flags)
         FIXME("Unhandled flags %#x.\n", ins->flags);
 
-    write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], dst_data_type);
-    shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle);
-
     reg_type = ins->src[1].reg.type;
     resource_idx = ins->src[1].reg.idx[0].offset;
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &lod_param);
     reg_type = ins->src[1].reg.type;
     resource_idx = ins->src[1].reg.idx[0].offset;
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &lod_param);
@@ -5916,54 +5705,62 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
     if (resource_type >= ARRAY_SIZE(resource_type_info))
     {
         ERR("Unexpected resource type %#x.\n", resource_type);
     if (resource_type >= ARRAY_SIZE(resource_type_info))
     {
         ERR("Unexpected resource type %#x.\n", resource_type);
-        resource_type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
+        return;
     }
 
     }
 
+    write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], dst_data_type);
+    shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle);
+
     if (dst_data_type == WINED3D_DATA_UINT)
     if (dst_data_type == WINED3D_DATA_UINT)
-        shader_addline(ins->ctx->buffer, "uvec4(");
+        shader_addline(buffer, "uvec4(");
     else
     else
-        shader_addline(ins->ctx->buffer, "vec4(");
+        shader_addline(buffer, "vec4(");
 
     if (reg_type == WINED3DSPR_RESOURCE)
     {
 
     if (reg_type == WINED3DSPR_RESOURCE)
     {
-        shader_addline(ins->ctx->buffer, "textureSize(%s_sampler%u, %s), ",
-                shader_glsl_get_prefix(version->type), bind_idx, lod_param.param_str);
+        shader_addline(buffer, "textureSize(%s_sampler%u",
+                shader_glsl_get_prefix(version->type), bind_idx);
+    }
+    else
+    {
+        shader_addline(buffer, "imageSize(%s_image%u",
+                shader_glsl_get_prefix(version->type), bind_idx);
+    }
+
+    supports_mipmaps = is_mipmapped(resource_type) && reg_type != WINED3DSPR_UAV;
+    if (supports_mipmaps)
+        shader_addline(buffer, ", %s", lod_param.param_str);
+    shader_addline(buffer, "), ");
 
 
-        for (i = 0; i < 3 - resource_type_info[resource_type].resinfo_size; ++i)
-            shader_addline(ins->ctx->buffer, "0, ");
+    for (i = 0; i < 3 - resource_type_info[resource_type].resinfo_size; ++i)
+        shader_addline(buffer, "0, ");
 
 
+    if (supports_mipmaps)
+    {
         if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS])
         {
         if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS])
         {
-            shader_addline(ins->ctx->buffer, "textureQueryLevels(%s_sampler%u)",
+            shader_addline(buffer, "textureQueryLevels(%s_sampler%u)",
                     shader_glsl_get_prefix(version->type), bind_idx);
         }
         else
         {
                     shader_glsl_get_prefix(version->type), bind_idx);
         }
         else
         {
-            FIXME("textureQueryLevels is not supported, returning 1 mipmap level.\n");
-            shader_addline(ins->ctx->buffer, "1");
+            FIXME("textureQueryLevels is not supported, returning 1 level.\n");
+            shader_addline(buffer, "1");
         }
     }
     else
     {
         }
     }
     else
     {
-        shader_addline(ins->ctx->buffer, "imageSize(%s_image%u), ",
-                shader_glsl_get_prefix(version->type), bind_idx);
-
-        for (i = 0; i < 3 - resource_type_info[resource_type].resinfo_size; ++i)
-            shader_addline(ins->ctx->buffer, "0, ");
-
-        /* For UAVs the returned miplevel count is always 1. */
-        shader_addline(ins->ctx->buffer, "1");
+        shader_addline(buffer, "1");
     }
 
     }
 
-    shader_addline(ins->ctx->buffer, ")%s);\n", dst_swizzle);
+    shader_addline(buffer, ")%s);\n", dst_swizzle);
 }
 
 }
 
-/* FIXME: The current implementation does not handle multisample textures correctly. */
 static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
 static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
+    struct glsl_src_param coord_param, lod_param, sample_param;
     unsigned int resource_idx, sampler_idx, sampler_bind_idx;
     unsigned int resource_idx, sampler_idx, sampler_bind_idx;
-    struct glsl_src_param coord_param, lod_param;
     struct glsl_sample_function sample_function;
     DWORD flags = WINED3D_GLSL_SAMPLE_LOAD;
     BOOL has_lod_param;
     struct glsl_sample_function sample_function;
     DWORD flags = WINED3D_GLSL_SAMPLE_LOAD;
     BOOL has_lod_param;
@@ -5979,15 +5776,24 @@ static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
         ERR("Invalid resource index %u.\n", resource_idx);
         return;
     }
         ERR("Invalid resource index %u.\n", resource_idx);
         return;
     }
-    has_lod_param = reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_BUFFER;
+    has_lod_param = is_mipmapped(reg_maps->resource_info[resource_idx].type);
 
     shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function);
     shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
     sampler_bind_idx = shader_glsl_find_sampler(&reg_maps->sampler_map, resource_idx, sampler_idx);
 
     shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function);
     shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
     sampler_bind_idx = shader_glsl_find_sampler(&reg_maps->sampler_map, resource_idx, sampler_idx);
-    shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
-            NULL, NULL, has_lod_param ? lod_param.param_str : NULL, &ins->texel_offset,
-            "%s", coord_param.param_str);
+    if (is_multisampled(reg_maps->resource_info[resource_idx].type))
+    {
+        shader_glsl_add_src_param(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &sample_param);
+        shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
+                NULL, NULL, NULL, &ins->texel_offset, "%s, %s", coord_param.param_str, sample_param.param_str);
+    }
+    else
+    {
+        shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
+                NULL, NULL, has_lod_param ? lod_param.param_str : NULL, &ins->texel_offset,
+                "%s", coord_param.param_str);
+    }
     shader_glsl_release_sample_function(ins->ctx, &sample_function);
 }
 
     shader_glsl_release_sample_function(ins->ctx, &sample_function);
 }
 
@@ -6805,7 +6611,7 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struc
         list_remove(&entry->ps.shader_entry);
     if (entry->cs.id)
         list_remove(&entry->cs.shader_entry);
         list_remove(&entry->ps.shader_entry);
     if (entry->cs.id)
         list_remove(&entry->cs.shader_entry);
-    HeapFree(GetProcessHeap(), 0, entry);
+    heap_free(entry);
 }
 
 static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
 }
 
 static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
@@ -6824,7 +6630,7 @@ static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
     unsigned int i, j;
     char reg_mask[6];
 
     unsigned int i, j;
     char reg_mask[6];
 
-    set = wined3d_calloc(max_varyings, sizeof(*set));
+    set = heap_calloc(max_varyings, sizeof(*set));
 
     for (i = 0; i < input_signature->element_count; ++i)
     {
 
     for (i = 0; i < input_signature->element_count; ++i)
     {
@@ -6908,7 +6714,7 @@ static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
             shader_addline(buffer, "%s.%s = vec%u(0.0);\n", destination->buffer, reg_mask, size);
     }
 
             shader_addline(buffer, "%s.%s = vec%u(0.0);\n", destination->buffer, reg_mask, size);
     }
 
-    HeapFree(GetProcessHeap(), 0, set);
+    heap_free(set);
     string_buffer_release(&priv->string_buffers, destination);
 }
 
     string_buffer_release(&priv->string_buffers, destination);
 }
 
@@ -7344,20 +7150,20 @@ static void shader_glsl_generate_patch_constant_setup(struct wined3d_string_buff
 static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info)
 {
 static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info)
 {
-    const char *output = get_fragment_output(gl_info);
+    const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0";
 
 
-    shader_addline(buffer, "tmp0.xyz = pow(%s[0].xyz, vec3(srgb_const0.x));\n", output);
+    shader_addline(buffer, "tmp0.xyz = pow(%s.xyz, vec3(srgb_const0.x));\n", output);
     shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n");
     shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n");
-    shader_addline(buffer, "tmp1.xyz = %s[0].xyz * vec3(srgb_const0.w);\n", output);
-    shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s[0].xyz, vec3(srgb_const1.x));\n", output);
-    shader_addline(buffer, "%s[0].xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output);
-    shader_addline(buffer, "%s[0] = clamp(%s[0], 0.0, 1.0);\n", output, output);
+    shader_addline(buffer, "tmp1.xyz = %s.xyz * vec3(srgb_const0.w);\n", output);
+    shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s.xyz, vec3(srgb_const1.x));\n", output);
+    shader_addline(buffer, "%s.xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output);
+    shader_addline(buffer, "%s = clamp(%s, 0.0, 1.0);\n", output, output);
 }
 
 static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode)
 {
 }
 
 static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode)
 {
-    const char *output = get_fragment_output(gl_info);
+    const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0";
 
     switch (mode)
     {
 
     switch (mode)
     {
@@ -7382,13 +7188,15 @@ static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer,
             return;
     }
 
             return;
     }
 
-    shader_addline(buffer, "%s[0].xyz = mix(ffp_fog.color.xyz, %s[0].xyz, clamp(fog, 0.0, 1.0));\n",
+    shader_addline(buffer, "%s.xyz = mix(ffp_fog.color.xyz, %s.xyz, clamp(fog, 0.0, 1.0));\n",
             output, output);
 }
 
 static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func)
 {
             output, output);
 }
 
 static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer,
         const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func)
 {
+    const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0";
+
     /* alpha_func is the PASS condition, not the DISCARD condition. Instead of
      * flipping all the operators here, just negate the comparison below. */
     static const char * const comparison_operator[] =
     /* alpha_func is the PASS condition, not the DISCARD condition. Instead of
      * flipping all the operators here, just negate the comparison below. */
     static const char * const comparison_operator[] =
@@ -7407,8 +7215,8 @@ static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer
         return;
 
     if (alpha_func != WINED3D_CMP_NEVER)
         return;
 
     if (alpha_func != WINED3D_CMP_NEVER)
-        shader_addline(buffer, "if (!(%s[0].a %s alpha_test_ref))\n",
-                get_fragment_output(gl_info), comparison_operator[alpha_func - WINED3D_CMP_NEVER]);
+        shader_addline(buffer, "if (!(%s.a %s alpha_test_ref))\n",
+                output, comparison_operator[alpha_func - WINED3D_CMP_NEVER]);
     shader_addline(buffer, "    discard;\n");
 }
 
     shader_addline(buffer, "    discard;\n");
 }
 
@@ -7452,10 +7260,11 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in
         const struct ps_compile_args *args)
 {
     const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
         const struct ps_compile_args *args)
 {
     const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+    const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0";
 
     /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */
     if (reg_maps->shader_version.major < 2)
 
     /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */
     if (reg_maps->shader_version.major < 2)
-        shader_addline(buffer, "%s[0] = R0;\n", get_fragment_output(gl_info));
+        shader_addline(buffer, "%s = R0;\n", output);
 
     if (args->srgb_correction)
         shader_glsl_generate_srgb_write_correction(buffer, gl_info);
 
     if (args->srgb_correction)
         shader_glsl_generate_srgb_write_correction(buffer, gl_info);
@@ -7645,9 +7454,24 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
 
     if (!needs_legacy_glsl_syntax(gl_info))
     {
 
     if (!needs_legacy_glsl_syntax(gl_info))
     {
-        if (shader_glsl_use_explicit_attrib_location(gl_info))
-            shader_addline(buffer, "layout(location = 0) ");
-        shader_addline(buffer, "out vec4 ps_out[%u];\n", gl_info->limits.buffers);
+        if (args->dual_source_blend)
+        {
+            for (i = 0; i < gl_info->limits.dual_buffers * 2; i++)
+            {
+                if (shader_glsl_use_explicit_attrib_location(gl_info))
+                    shader_addline(buffer, "layout(location = %u, index = %u) ", i / 2, i % 2);
+                shader_addline(buffer, "out vec4 ps_out%u;\n", i);
+            }
+        }
+        else
+        {
+            for (i = 0; i < gl_info->limits.buffers; i++)
+            {
+                if (shader_glsl_use_explicit_attrib_location(gl_info))
+                    shader_addline(buffer, "layout(location = %u) ", i);
+                shader_addline(buffer, "out vec4 ps_out%u;\n", i);
+            }
+        }
     }
 
     if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants)
     }
 
     if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants)
@@ -8249,8 +8073,7 @@ static GLuint find_glsl_pshader(const struct wined3d_context *context,
 
     if (!shader->backend_data)
     {
 
     if (!shader->backend_data)
     {
-        shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
-        if (!shader->backend_data)
+        if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
@@ -8274,16 +8097,16 @@ static GLuint find_glsl_pshader(const struct wined3d_context *context,
     }
 
     TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
     }
 
     TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
-    if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+    if (shader_data->shader_array_size == shader_data->num_gl_shaders)
+    {
         if (shader_data->num_gl_shaders)
         {
             new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
         if (shader_data->num_gl_shaders)
         {
             new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
-            new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders.ps,
-                    new_size * sizeof(*gl_shaders));
+            new_array = heap_realloc(shader_data->gl_shaders.ps, new_size * sizeof(*gl_shaders));
         }
         else
         {
         }
         else
         {
-            new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders));
+            new_array = heap_alloc(sizeof(*gl_shaders));
             new_size = 1;
         }
 
             new_size = 1;
         }
 
@@ -8341,8 +8164,7 @@ static GLuint find_glsl_vshader(const struct wined3d_context *context, struct sh
 
     if (!shader->backend_data)
     {
 
     if (!shader->backend_data)
     {
-        shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
-        if (!shader->backend_data)
+        if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
@@ -8363,16 +8185,16 @@ static GLuint find_glsl_vshader(const struct wined3d_context *context, struct sh
 
     TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
 
 
     TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
 
-    if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+    if (shader_data->shader_array_size == shader_data->num_gl_shaders)
+    {
         if (shader_data->num_gl_shaders)
         {
             new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
         if (shader_data->num_gl_shaders)
         {
             new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
-            new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders.vs,
-                    new_size * sizeof(*gl_shaders));
+            new_array = heap_realloc(shader_data->gl_shaders.vs, new_size * sizeof(*gl_shaders));
         }
         else
         {
         }
         else
         {
-            new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders));
+            new_array = heap_alloc(sizeof(*gl_shaders));
             new_size = 1;
         }
 
             new_size = 1;
         }
 
@@ -8404,7 +8226,7 @@ static GLuint find_glsl_hull_shader(const struct wined3d_context *context,
 
     if (!shader->backend_data)
     {
 
     if (!shader->backend_data)
     {
-        if (!(shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data))))
+        if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
@@ -8422,9 +8244,8 @@ static GLuint find_glsl_hull_shader(const struct wined3d_context *context,
     TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
 
     assert(!shader_data->gl_shaders.hs);
     TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
 
     assert(!shader_data->gl_shaders.hs);
-    new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array));
     new_size = 1;
     new_size = 1;
-    if (!new_array)
+    if (!(new_array = heap_alloc(sizeof(*new_array))))
     {
         ERR("Failed to allocate GL shaders array.\n");
         return 0;
     {
         ERR("Failed to allocate GL shaders array.\n");
         return 0;
@@ -8450,7 +8271,7 @@ static GLuint find_glsl_domain_shader(const struct wined3d_context *context,
 
     if (!shader->backend_data)
     {
 
     if (!shader->backend_data)
     {
-        if (!(shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data))))
+        if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
@@ -8470,12 +8291,11 @@ static GLuint find_glsl_domain_shader(const struct wined3d_context *context,
     if (shader_data->num_gl_shaders)
     {
         new_size = shader_data->shader_array_size + 1;
     if (shader_data->num_gl_shaders)
     {
         new_size = shader_data->shader_array_size + 1;
-        new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders.ds,
-                new_size * sizeof(*new_array));
+        new_array = heap_realloc(shader_data->gl_shaders.ds, new_size * sizeof(*new_array));
     }
     else
     {
     }
     else
     {
-        new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array));
+        new_array = heap_alloc(sizeof(*new_array));
         new_size = 1;
     }
 
         new_size = 1;
     }
 
@@ -8506,7 +8326,7 @@ static GLuint find_glsl_geometry_shader(const struct wined3d_context *context,
 
     if (!shader->backend_data)
     {
 
     if (!shader->backend_data)
     {
-        if (!(shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data))))
+        if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
         {
             ERR("Failed to allocate backend data.\n");
             return 0;
@@ -8526,12 +8346,11 @@ static GLuint find_glsl_geometry_shader(const struct wined3d_context *context,
     if (shader_data->num_gl_shaders)
     {
         new_size = shader_data->shader_array_size + 1;
     if (shader_data->num_gl_shaders)
     {
         new_size = shader_data->shader_array_size + 1;
-        new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders.gs,
-                new_size * sizeof(*new_array));
+        new_array = heap_realloc(shader_data->gl_shaders.gs, new_size * sizeof(*new_array));
     }
     else
     {
     }
     else
     {
-        new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array));
+        new_array = heap_alloc(sizeof(*new_array));
         new_size = 1;
     }
 
         new_size = 1;
     }
 
@@ -8717,8 +8536,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
     {
         {"vec4", "ffp_attrib_position"},        /* WINED3D_FFP_POSITION */
         {"vec4", "ffp_attrib_blendweight"},     /* WINED3D_FFP_BLENDWEIGHT */
     {
         {"vec4", "ffp_attrib_position"},        /* WINED3D_FFP_POSITION */
         {"vec4", "ffp_attrib_blendweight"},     /* WINED3D_FFP_BLENDWEIGHT */
-        /* TODO: Indexed vertex blending */
-        {"float", ""},                          /* WINED3D_FFP_BLENDINDICES */
+        {"vec4", "ffp_attrib_blendindices"},    /* WINED3D_FFP_BLENDINDICES */
         {"vec3", "ffp_attrib_normal"},          /* WINED3D_FFP_NORMAL */
         {"float", "ffp_attrib_psize"},          /* WINED3D_FFP_PSIZE */
         {"vec4", "ffp_attrib_diffuse"},         /* WINED3D_FFP_DIFFUSE */
         {"vec3", "ffp_attrib_normal"},          /* WINED3D_FFP_NORMAL */
         {"float", "ffp_attrib_psize"},          /* WINED3D_FFP_PSIZE */
         {"vec4", "ffp_attrib_diffuse"},         /* WINED3D_FFP_DIFFUSE */
@@ -8730,6 +8548,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
     BOOL legacy_lighting = priv->legacy_lighting;
     GLuint shader_obj;
     unsigned int i;
     BOOL legacy_lighting = priv->legacy_lighting;
     GLuint shader_obj;
     unsigned int i;
+    char var[64];
 
     string_buffer_clear(buffer);
 
 
     string_buffer_clear(buffer);
 
@@ -8748,9 +8567,9 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
     }
     shader_addline(buffer, "\n");
 
     }
     shader_addline(buffer, "\n");
 
-    shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_BLENDS);
+    shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS);
+    shader_addline(buffer, "uniform mat3 ffp_normal_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS);
     shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n");
     shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n");
-    shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n");
     shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES);
 
     shader_addline(buffer, "uniform struct\n{\n");
     shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES);
 
     shader_addline(buffer, "uniform struct\n{\n");
@@ -8835,12 +8654,22 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
     }
     else
     {
     }
     else
     {
-        for (i = 0; i < settings->vertexblends; ++i)
-            shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i);
+        if (!settings->sw_blending)
+        {
+            for (i = 0; i < settings->vertexblends; ++i)
+                shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i);
 
 
-        shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
-        for (i = 0; i < settings->vertexblends + 1; ++i)
-            shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i);
+            shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
+            for (i = 0; i < settings->vertexblends + 1; ++i)
+            {
+                sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
+                shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%s] * ffp_attrib_position);\n", i, var);
+            }
+        }
+        else
+        {
+            shader_addline(buffer, "vec4 ec_pos = ffp_attrib_position;\n");
+        }
 
         shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n");
         if (settings->clipping)
 
         shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n");
         if (settings->clipping)
@@ -8857,14 +8686,17 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
     shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
     if (settings->normal)
     {
     shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
     if (settings->normal)
     {
-        if (!settings->vertexblends)
+        if (!settings->sw_blending)
         {
         {
-            shader_addline(buffer, "normal = ffp_normal_matrix * ffp_attrib_normal;\n");
+            for (i = 0; i < settings->vertexblends + 1; ++i)
+            {
+                sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
+                shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (ffp_normal_matrix[%s] * ffp_attrib_normal);\n", i, var);
+            }
         }
         else
         {
         }
         else
         {
-            for (i = 0; i < settings->vertexblends + 1; ++i)
-                shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i);
+            shader_addline(buffer, "normal = ffp_attrib_normal;\n");
         }
 
         if (settings->normalize)
         }
 
         if (settings->normalize)
@@ -9230,6 +9062,7 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un
 static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *priv,
         const struct ffp_frag_settings *settings, const struct wined3d_context *context)
 {
 static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *priv,
         const struct ffp_frag_settings *settings, const struct wined3d_context *context)
 {
+    const char *output = needs_legacy_glsl_syntax(context->gl_info) ? "gl_FragData[0]" : "ps_out0";
     struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers);
     enum wined3d_cmp_func alpha_test_func = settings->alpha_test_func + 1;
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
     struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers);
     enum wined3d_cmp_func alpha_test_func = settings->alpha_test_func + 1;
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
@@ -9318,7 +9151,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
     {
         if (shader_glsl_use_explicit_attrib_location(gl_info))
             shader_addline(buffer, "layout(location = 0) ");
     {
         if (shader_glsl_use_explicit_attrib_location(gl_info))
             shader_addline(buffer, "layout(location = 0) ");
-        shader_addline(buffer, "out vec4 ps_out[1];\n");
+        shader_addline(buffer, "out vec4 ps_out0;\n");
     }
 
     shader_addline(buffer, "vec4 tmp0, tmp1;\n");
     }
 
     shader_addline(buffer, "vec4 tmp0, tmp1;\n");
@@ -9649,8 +9482,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
         }
     }
 
         }
     }
 
-    shader_addline(buffer, "%s[0] = ffp_varying_specular * specular_enable + ret;\n",
-            get_fragment_output(gl_info));
+    shader_addline(buffer, "%s = ffp_varying_specular * specular_enable + ret;\n", output);
 
     if (settings->sRGB_write)
         shader_glsl_generate_srgb_write_correction(buffer, gl_info);
 
     if (settings->sRGB_write)
         shader_glsl_generate_srgb_write_correction(buffer, gl_info);
@@ -9677,7 +9509,7 @@ static struct glsl_ffp_vertex_shader *shader_glsl_find_ffp_vertex_shader(struct
     if ((entry = wine_rb_get(&priv->ffp_vertex_shaders, settings)))
         return WINE_RB_ENTRY_VALUE(entry, struct glsl_ffp_vertex_shader, desc.entry);
 
     if ((entry = wine_rb_get(&priv->ffp_vertex_shaders, settings)))
         return WINE_RB_ENTRY_VALUE(entry, struct glsl_ffp_vertex_shader, desc.entry);
 
-    if (!(shader = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader))))
+    if (!(shader = heap_alloc(sizeof(*shader))))
         return NULL;
 
     shader->desc.settings = *settings;
         return NULL;
 
     shader->desc.settings = *settings;
@@ -9698,7 +9530,7 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str
     if ((desc = find_ffp_frag_shader(&priv->ffp_fragment_shaders, args)))
         return CONTAINING_RECORD(desc, struct glsl_ffp_fragment_shader, entry);
 
     if ((desc = find_ffp_frag_shader(&priv->ffp_fragment_shaders, args)))
         return CONTAINING_RECORD(desc, struct glsl_ffp_fragment_shader, entry);
 
-    if (!(glsl_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*glsl_desc))))
+    if (!(glsl_desc = heap_alloc(sizeof(*glsl_desc))))
         return NULL;
 
     glsl_desc->entry.settings = *args;
         return NULL;
 
     glsl_desc->entry.settings = *args;
@@ -9737,13 +9569,17 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *
 
     vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup"));
 
 
     vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup"));
 
-    for (i = 0; i < MAX_VERTEX_BLENDS; ++i)
+    for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i)
     {
         string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i);
         vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
     {
         string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i);
         vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
+    for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i)
+    {
+        string_buffer_sprintf(name, "ffp_normal_matrix[%u]", i);
+        vs->normal_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
+    }
     vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix"));
     vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix"));
-    vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix"));
     for (i = 0; i < MAX_TEXTURES; ++i)
     {
         string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i);
     for (i = 0; i < MAX_TEXTURES; ++i)
     {
         string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i);
@@ -9870,26 +9706,26 @@ static HRESULT shader_glsl_compile_compute_shader(struct shader_glsl_priv *priv,
     struct glsl_shader_prog_link *entry;
     GLuint shader_id, program_id;
 
     struct glsl_shader_prog_link *entry;
     GLuint shader_id, program_id;
 
-    if (!(entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry))))
+    if (!(entry = heap_alloc(sizeof(*entry))))
     {
         ERR("Out of memory.\n");
         return E_OUTOFMEMORY;
     }
 
     {
         ERR("Out of memory.\n");
         return E_OUTOFMEMORY;
     }
 
-    if (!(shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data))))
+    if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
     {
         ERR("Failed to allocate backend data.\n");
     {
         ERR("Failed to allocate backend data.\n");
-        HeapFree(GetProcessHeap(), 0, entry);
+        heap_free(entry);
         return E_OUTOFMEMORY;
     }
     shader_data = shader->backend_data;
     gl_shaders = shader_data->gl_shaders.cs;
 
         return E_OUTOFMEMORY;
     }
     shader_data = shader->backend_data;
     gl_shaders = shader_data->gl_shaders.cs;
 
-    if (!(shader_data->gl_shaders.cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders))))
+    if (!(shader_data->gl_shaders.cs = heap_alloc(sizeof(*gl_shaders))))
     {
         ERR("Failed to allocate GL shader array.\n");
     {
         ERR("Failed to allocate GL shader array.\n");
-        HeapFree(GetProcessHeap(), 0, entry);
-        HeapFree(GetProcessHeap(), 0, shader->backend_data);
+        heap_free(entry);
+        heap_free(shader->backend_data);
         shader->backend_data = NULL;
         return E_OUTOFMEMORY;
     }
         shader->backend_data = NULL;
         return E_OUTOFMEMORY;
     }
@@ -10005,7 +9841,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     GLuint ds_id = 0;
     GLuint gs_id = 0;
     GLuint ps_id = 0;
     GLuint ds_id = 0;
     GLuint gs_id = 0;
     GLuint ps_id = 0;
-    struct list *ps_list, *vs_list;
+    struct list *ps_list = NULL, *vs_list = NULL;
     WORD attribs_map;
     struct wined3d_string_buffer *tmp_name;
 
     WORD attribs_map;
     struct wined3d_string_buffer *tmp_name;
 
@@ -10122,7 +9958,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     TRACE("Created new GLSL shader program %u.\n", program_id);
 
     /* Create the entry */
     TRACE("Created new GLSL shader program %u.\n", program_id);
 
     /* Create the entry */
-    entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
+    entry = heap_alloc(sizeof(*entry));
     entry->id = program_id;
     entry->vs.id = vs_id;
     entry->hs.id = hs_id;
     entry->id = program_id;
     entry->vs.id = vs_id;
     entry->hs.id = hs_id;
@@ -10203,8 +10039,26 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
 
         if (!needs_legacy_glsl_syntax(gl_info))
         {
 
         if (!needs_legacy_glsl_syntax(gl_info))
         {
-            GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out"));
-            checkGLcall("glBindFragDataLocation");
+            char var[12];
+
+            if (wined3d_dualblend_enabled(state, gl_info))
+            {
+                for (i = 0; i < gl_info->limits.dual_buffers * 2; i++)
+                {
+                    sprintf(var, "ps_out%u", i);
+                    GL_EXTCALL(glBindFragDataLocationIndexed(program_id, i / 2, i % 2, var));
+                    checkGLcall("glBindFragDataLocationIndexed");
+                }
+            }
+            else
+            {
+                for (i = 0; i < gl_info->limits.buffers; i++)
+                {
+                    sprintf(var, "ps_out%u", i);
+                    GL_EXTCALL(glBindFragDataLocation(program_id, i, var));
+                    checkGLcall("glBindFragDataLocation");
+                }
+            }
         }
     }
 
         }
     }
 
@@ -10311,7 +10165,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
         entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW
                 | WINED3D_SHADER_CONST_FFP_PROJ;
 
         entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW
                 | WINED3D_SHADER_CONST_FFP_PROJ;
 
-        for (i = 1; i < MAX_VERTEX_BLENDS; ++i)
+        for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i)
         {
             if (entry->vs.modelview_matrix_location[i] != -1)
             {
         {
             if (entry->vs.modelview_matrix_location[i] != -1)
             {
@@ -10566,7 +10420,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
 
     if (!shader_data || !shader_data->num_gl_shaders)
     {
 
     if (!shader_data || !shader_data->num_gl_shaders)
     {
-        HeapFree(GetProcessHeap(), 0, shader_data);
+        heap_free(shader_data);
         shader->backend_data = NULL;
         return;
     }
         shader->backend_data = NULL;
         return;
     }
@@ -10593,7 +10447,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
-                HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ps);
+                heap_free(shader_data->gl_shaders.ps);
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, ps.shader_entry)
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, ps.shader_entry)
@@ -10615,7 +10469,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
-                HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.vs);
+                heap_free(shader_data->gl_shaders.vs);
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, vs.shader_entry)
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, vs.shader_entry)
@@ -10637,7 +10491,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
-                HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.hs);
+                heap_free(shader_data->gl_shaders.hs);
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, hs.shader_entry)
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, hs.shader_entry)
@@ -10659,7 +10513,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
-                HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ds);
+                heap_free(shader_data->gl_shaders.ds);
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, ds.shader_entry)
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, ds.shader_entry)
@@ -10681,7 +10535,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
-                HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.gs);
+                heap_free(shader_data->gl_shaders.gs);
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, gs.shader_entry)
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, gs.shader_entry)
@@ -10703,7 +10557,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
                     GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
                     checkGLcall("glDeleteShader");
                 }
-                HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.cs);
+                heap_free(shader_data->gl_shaders.cs);
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, cs.shader_entry)
 
                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
                         struct glsl_shader_prog_link, cs.shader_entry)
@@ -10721,7 +10575,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
         }
     }
 
         }
     }
 
-    HeapFree(GetProcessHeap(), 0, shader->backend_data);
+    heap_free(shader->backend_data);
     shader->backend_data = NULL;
 
     context_release(context);
     shader->backend_data = NULL;
 
     context_release(context);
@@ -10759,9 +10613,9 @@ static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant
     SIZE_T size = (constant_count + 1) * sizeof(*heap->entries)
             + constant_count * sizeof(*heap->contained)
             + constant_count * sizeof(*heap->positions);
     SIZE_T size = (constant_count + 1) * sizeof(*heap->entries)
             + constant_count * sizeof(*heap->contained)
             + constant_count * sizeof(*heap->positions);
-    void *mem = HeapAlloc(GetProcessHeap(), 0, size);
+    void *mem;
 
 
-    if (!mem)
+    if (!(mem = heap_alloc(size)))
     {
         ERR("Failed to allocate memory\n");
         return FALSE;
     {
         ERR("Failed to allocate memory\n");
         return FALSE;
@@ -10779,24 +10633,27 @@ static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant
 
 static void constant_heap_free(struct constant_heap *heap)
 {
 
 static void constant_heap_free(struct constant_heap *heap)
 {
-    HeapFree(GetProcessHeap(), 0, heap->entries);
+    heap_free(heap->entries);
 }
 
 static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
         const struct fragment_pipeline *fragment_pipe)
 {
 }
 
 static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
         const struct fragment_pipeline *fragment_pipe)
 {
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
-    struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
     SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1;
     SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct fragment_caps fragment_caps;
     void *vertex_priv, *fragment_priv;
     struct fragment_caps fragment_caps;
     void *vertex_priv, *fragment_priv;
+    struct shader_glsl_priv *priv;
+
+    if (!(priv = heap_alloc_zero(sizeof(*priv))))
+        return E_OUTOFMEMORY;
 
     string_buffer_list_init(&priv->string_buffers);
 
     if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
     {
         ERR("Failed to initialize vertex pipe.\n");
 
     string_buffer_list_init(&priv->string_buffers);
 
     if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
     {
         ERR("Failed to initialize vertex pipe.\n");
-        HeapFree(GetProcessHeap(), 0, priv);
+        heap_free(priv);
         return E_FAIL;
     }
 
         return E_FAIL;
     }
 
@@ -10804,7 +10661,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
     {
         ERR("Failed to initialize fragment pipe.\n");
         vertex_pipe->vp_free(device);
     {
         ERR("Failed to initialize fragment pipe.\n");
         vertex_pipe->vp_free(device);
-        HeapFree(GetProcessHeap(), 0, priv);
+        heap_free(priv);
         return E_FAIL;
     }
 
         return E_FAIL;
     }
 
@@ -10814,7 +10671,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
         goto fail;
     }
 
         goto fail;
     }
 
-    if (!(priv->stack = wined3d_calloc(stack_size, sizeof(*priv->stack))))
+    if (!(priv->stack = heap_calloc(stack_size, sizeof(*priv->stack))))
     {
         ERR("Failed to allocate memory.\n");
         goto fail;
     {
         ERR("Failed to allocate memory.\n");
         goto fail;
@@ -10850,11 +10707,11 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
 fail:
     constant_heap_free(&priv->pconst_heap);
     constant_heap_free(&priv->vconst_heap);
 fail:
     constant_heap_free(&priv->pconst_heap);
     constant_heap_free(&priv->vconst_heap);
-    HeapFree(GetProcessHeap(), 0, priv->stack);
+    heap_free(priv->stack);
     string_buffer_free(&priv->shader_buffer);
     fragment_pipe->free_private(device);
     vertex_pipe->vp_free(device);
     string_buffer_free(&priv->shader_buffer);
     fragment_pipe->free_private(device);
     vertex_pipe->vp_free(device);
-    HeapFree(GetProcessHeap(), 0, priv);
+    heap_free(priv);
     return E_OUTOFMEMORY;
 }
 
     return E_OUTOFMEMORY;
 }
 
@@ -10866,20 +10723,21 @@ static void shader_glsl_free(struct wined3d_device *device)
     wine_rb_destroy(&priv->program_lookup, NULL, NULL);
     constant_heap_free(&priv->pconst_heap);
     constant_heap_free(&priv->vconst_heap);
     wine_rb_destroy(&priv->program_lookup, NULL, NULL);
     constant_heap_free(&priv->pconst_heap);
     constant_heap_free(&priv->vconst_heap);
-    HeapFree(GetProcessHeap(), 0, priv->stack);
+    heap_free(priv->stack);
     string_buffer_list_cleanup(&priv->string_buffers);
     string_buffer_free(&priv->shader_buffer);
     priv->fragment_pipe->free_private(device);
     priv->vertex_pipe->vp_free(device);
 
     string_buffer_list_cleanup(&priv->string_buffers);
     string_buffer_free(&priv->shader_buffer);
     priv->fragment_pipe->free_private(device);
     priv->vertex_pipe->vp_free(device);
 
-    HeapFree(GetProcessHeap(), 0, device->shader_priv);
+    heap_free(device->shader_priv);
     device->shader_priv = NULL;
 }
 
 static BOOL shader_glsl_allocate_context_data(struct wined3d_context *context)
 {
     struct glsl_context_data *ctx_data;
     device->shader_priv = NULL;
 }
 
 static BOOL shader_glsl_allocate_context_data(struct wined3d_context *context)
 {
     struct glsl_context_data *ctx_data;
-    if (!(ctx_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx_data))))
+
+    if (!(ctx_data = heap_alloc_zero(sizeof(*ctx_data))))
         return FALSE;
     ctx_data->vertex_color_clamp = GL_FIXED_ONLY_ARB;
     context->shader_backend_data = ctx_data;
         return FALSE;
     ctx_data->vertex_color_clamp = GL_FIXED_ONLY_ARB;
     context->shader_backend_data = ctx_data;
@@ -10888,7 +10746,7 @@ static BOOL shader_glsl_allocate_context_data(struct wined3d_context *context)
 
 static void shader_glsl_free_context_data(struct wined3d_context *context)
 {
 
 static void shader_glsl_free_context_data(struct wined3d_context *context)
 {
-    HeapFree(GetProcessHeap(), 0, context->shader_backend_data);
+    heap_free(context->shader_backend_data);
 }
 
 static void shader_glsl_init_context_state(struct wined3d_context *context)
 }
 
 static void shader_glsl_init_context_state(struct wined3d_context *context)
@@ -11130,7 +10988,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_ITOF                             */ shader_glsl_to_float,
     /* WINED3DSIH_LABEL                            */ shader_glsl_label,
     /* WINED3DSIH_LD                               */ shader_glsl_ld,
     /* WINED3DSIH_ITOF                             */ shader_glsl_to_float,
     /* WINED3DSIH_LABEL                            */ shader_glsl_label,
     /* WINED3DSIH_LD                               */ shader_glsl_ld,
-    /* WINED3DSIH_LD2DMS                           */ NULL,
+    /* WINED3DSIH_LD2DMS                           */ shader_glsl_ld,
     /* WINED3DSIH_LD_RAW                           */ shader_glsl_ld_raw_structured,
     /* WINED3DSIH_LD_STRUCTURED                    */ shader_glsl_ld_raw_structured,
     /* WINED3DSIH_LD_UAV_TYPED                     */ shader_glsl_ld_uav,
     /* WINED3DSIH_LD_RAW                           */ shader_glsl_ld_raw_structured,
     /* WINED3DSIH_LD_STRUCTURED                    */ shader_glsl_ld_raw_structured,
     /* WINED3DSIH_LD_UAV_TYPED                     */ shader_glsl_ld_uav,
@@ -11279,7 +11137,7 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info,
     caps->ffp_generic_attributes = TRUE;
     caps->max_active_lights = MAX_ACTIVE_LIGHTS;
     caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;
     caps->ffp_generic_attributes = TRUE;
     caps->max_active_lights = MAX_ACTIVE_LIGHTS;
     caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;
-    caps->max_vertex_blend_matrix_index = 0;
+    caps->max_vertex_blend_matrix_index = MAX_VERTEX_INDEX_BLENDS - 1;
     caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN
             | WINED3DVTXPCAPS_MATERIALSOURCE7
             | WINED3DVTXPCAPS_VERTEXFOG
     caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN
             | WINED3DVTXPCAPS_MATERIALSOURCE7
             | WINED3DVTXPCAPS_VERTEXFOG
@@ -11328,7 +11186,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_glDeleteShader(shader->id);
         delete_glsl_program_entry(ctx->priv, ctx->gl_info, program);
     }
     ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id);
-    HeapFree(GetProcessHeap(), 0, shader);
+    heap_free(shader);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -11474,7 +11332,8 @@ static void glsl_vertex_pipe_world(struct wined3d_context *context,
 static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
 static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
-    context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND;
+    int i = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
+    context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i);
 }
 
 static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 }
 
 static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -11657,6 +11516,11 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] =
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
     {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
+    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
+    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
+    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
+    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
+    {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)),                {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)),                glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE    },
     {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE       },
     {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE       },
     {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE       },
     {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE       },
     {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE       },
     {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE       },
@@ -11825,7 +11689,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_glDeleteShader(shader->id);
         delete_glsl_program_entry(ctx->priv, ctx->gl_info, program);
     }
     ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id);
-    HeapFree(GetProcessHeap(), 0, shader);
+    heap_free(shader);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
index 1033ec8..0baa414 100644 (file)
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
  * 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 "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
 
 #include "wined3d_private.h"
 
 
 #include "wined3d_private.h"
 
index f24f883..6730809 100644 (file)
@@ -18,7 +18,8 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
  * 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 "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -34,7 +35,7 @@ ULONG CDECL wined3d_palette_incref(struct wined3d_palette *palette)
 
 static void wined3d_palette_destroy_object(void *object)
 {
 
 static void wined3d_palette_destroy_object(void *object)
 {
-    HeapFree(GetProcessHeap(), 0, object);
+    heap_free(object);
 }
 
 ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette)
 }
 
 ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette)
@@ -167,14 +168,13 @@ HRESULT CDECL wined3d_palette_create(struct wined3d_device *device, DWORD flags,
     TRACE("device %p, flags %#x, entry_count %u, entries %p, palette %p.\n",
             device, flags, entry_count, entries, palette);
 
     TRACE("device %p, flags %#x, entry_count %u, entries %p, palette %p.\n",
             device, flags, entry_count, entries, palette);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_palette_init(object, device, flags, entry_count, entries)))
     {
         WARN("Failed to initialize palette, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_palette_init(object, device, flags, entry_count, entries)))
     {
         WARN("Failed to initialize palette, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
diff --git a/dll/directx/wine/wined3d/precomp.h b/dll/directx/wine/wined3d/precomp.h
new file mode 100644 (file)
index 0000000..4443eec
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Direct3D wine internal private include file
+ *
+ * Copyright 2002-2003 The wine-d3d team
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2002-2003, 2004 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006-2011, 2013 Stefan Dösinger for CodeWeavers
+ *
+ * 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
+ */
+
+#ifndef __WINE_WINED3D_PRECOMP_H
+#define __WINE_WINED3D_PRECOMP_H
+
+#include <wine/config.h>
+#include <wine/port.h>
+
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
+#include <stdio.h>
+
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#include "wined3d_private.h"
+
+#include <reactos/undocuser.h>
+
+#endif /* !__WINE_WINED3D_PRECOMP_H */
index fe175d1..5ea79b6 100644 (file)
@@ -19,6 +19,8 @@
  */
 
 
  */
 
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -284,7 +286,7 @@ static void wined3d_fence_free(struct wined3d_fence *fence)
 void wined3d_fence_destroy(struct wined3d_fence *fence)
 {
     wined3d_fence_free(fence);
 void wined3d_fence_destroy(struct wined3d_fence *fence)
 {
     wined3d_fence_free(fence);
-    HeapFree(GetProcessHeap(), 0, fence);
+    heap_free(fence);
 }
 
 static HRESULT wined3d_fence_init(struct wined3d_fence *fence, const struct wined3d_gl_info *gl_info)
 }
 
 static HRESULT wined3d_fence_init(struct wined3d_fence *fence, const struct wined3d_gl_info *gl_info)
@@ -306,12 +308,12 @@ HRESULT wined3d_fence_create(struct wined3d_device *device, struct wined3d_fence
 
     TRACE("device %p, fence %p.\n", device, fence);
 
 
     TRACE("device %p, fence %p.\n", device, fence);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_fence_init(object, gl_info)))
     {
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_fence_init(object, gl_info)))
     {
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -911,12 +913,40 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD
     return poll;
 }
 
     return poll;
 }
 
+static BOOL wined3d_statistics_query_ops_poll(struct wined3d_query *query, DWORD flags)
+{
+    TRACE("query %p, flags %#x.\n", query, flags);
+
+    return TRUE;
+}
+
+static BOOL wined3d_statistics_query_ops_issue(struct wined3d_query *query, DWORD flags)
+{
+    FIXME("query %p, flags %#x.\n", query, flags);
+
+    return FALSE;
+}
+
+static BOOL wined3d_overflow_query_ops_poll(struct wined3d_query *query, DWORD flags)
+{
+    TRACE("query %p, flags %#x.\n", query, flags);
+
+    return TRUE;
+}
+
+static BOOL wined3d_overflow_query_ops_issue(struct wined3d_query *query, DWORD flags)
+{
+    FIXME("query %p, flags %#x.\n", query, flags);
+
+    return FALSE;
+}
+
 static void wined3d_event_query_ops_destroy(struct wined3d_query *query)
 {
     struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
 
     wined3d_fence_free(&event_query->fence);
 static void wined3d_event_query_ops_destroy(struct wined3d_query *query)
 {
     struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
 
     wined3d_fence_free(&event_query->fence);
-    HeapFree(GetProcessHeap(), 0, event_query);
+    heap_free(event_query);
 }
 
 static const struct wined3d_query_ops event_query_ops =
 }
 
 static const struct wined3d_query_ops event_query_ops =
@@ -937,13 +967,13 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device,
     TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
             device, type, parent, parent_ops, query);
 
     TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
             device, type, parent, parent_ops, query);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_fence_init(&object->fence, gl_info)))
     {
         WARN("Event queries not supported.\n");
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_fence_init(&object->fence, gl_info)))
     {
         WARN("Event queries not supported.\n");
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -962,7 +992,7 @@ static void wined3d_occlusion_query_ops_destroy(struct wined3d_query *query)
 
     if (oq->context)
         context_free_occlusion_query(oq);
 
     if (oq->context)
         context_free_occlusion_query(oq);
-    HeapFree(GetProcessHeap(), 0, oq);
+    heap_free(oq);
 }
 
 static const struct wined3d_query_ops occlusion_query_ops =
 }
 
 static const struct wined3d_query_ops occlusion_query_ops =
@@ -988,7 +1018,7 @@ static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device,
         return WINED3DERR_NOTAVAILABLE;
     }
 
         return WINED3DERR_NOTAVAILABLE;
     }
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     wined3d_query_init(&object->query, device, type, &object->samples,
         return E_OUTOFMEMORY;
 
     wined3d_query_init(&object->query, device, type, &object->samples,
@@ -1006,7 +1036,7 @@ static void wined3d_timestamp_query_ops_destroy(struct wined3d_query *query)
 
     if (tq->context)
         context_free_timestamp_query(tq);
 
     if (tq->context)
         context_free_timestamp_query(tq);
-    HeapFree(GetProcessHeap(), 0, tq);
+    heap_free(tq);
 }
 
 static const struct wined3d_query_ops timestamp_query_ops =
 }
 
 static const struct wined3d_query_ops timestamp_query_ops =
@@ -1032,7 +1062,7 @@ static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device,
         return WINED3DERR_NOTAVAILABLE;
     }
 
         return WINED3DERR_NOTAVAILABLE;
     }
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     wined3d_query_init(&object->query, device, type, &object->timestamp,
         return E_OUTOFMEMORY;
 
     wined3d_query_init(&object->query, device, type, &object->timestamp,
@@ -1046,7 +1076,7 @@ static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device,
 
 static void wined3d_timestamp_disjoint_query_ops_destroy(struct wined3d_query *query)
 {
 
 static void wined3d_timestamp_disjoint_query_ops_destroy(struct wined3d_query *query)
 {
-    HeapFree(GetProcessHeap(), 0, query);
+    heap_free(query);
 }
 
 static const struct wined3d_query_ops timestamp_disjoint_query_ops =
 }
 
 static const struct wined3d_query_ops timestamp_disjoint_query_ops =
@@ -1072,7 +1102,7 @@ static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *de
         return WINED3DERR_NOTAVAILABLE;
     }
 
         return WINED3DERR_NOTAVAILABLE;
     }
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT)
         return E_OUTOFMEMORY;
 
     if (type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT)
@@ -1102,7 +1132,7 @@ static void wined3d_so_statistics_query_ops_destroy(struct wined3d_query *query)
 
     if (pq->context)
         context_free_so_statistics_query(pq);
 
     if (pq->context)
         context_free_so_statistics_query(pq);
-    HeapFree(GetProcessHeap(), 0, pq);
+    heap_free(pq);
 }
 
 static const struct wined3d_query_ops so_statistics_query_ops =
 }
 
 static const struct wined3d_query_ops so_statistics_query_ops =
@@ -1139,7 +1169,7 @@ static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device,
         return WINED3DERR_NOTAVAILABLE;
     }
 
         return WINED3DERR_NOTAVAILABLE;
     }
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     wined3d_query_init(&object->query, device, type, &object->statistics,
         return E_OUTOFMEMORY;
 
     wined3d_query_init(&object->query, device, type, &object->statistics,
@@ -1157,7 +1187,7 @@ static void wined3d_pipeline_query_ops_destroy(struct wined3d_query *query)
     struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query);
     if (pq->context)
         context_free_pipeline_statistics_query(pq);
     struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query);
     if (pq->context)
         context_free_pipeline_statistics_query(pq);
-    HeapFree(GetProcessHeap(), 0, pq);
+    heap_free(pq);
 }
 
 static const struct wined3d_query_ops pipeline_query_ops =
 }
 
 static const struct wined3d_query_ops pipeline_query_ops =
@@ -1183,7 +1213,7 @@ static HRESULT wined3d_pipeline_query_create(struct wined3d_device *device,
         return WINED3DERR_NOTAVAILABLE;
     }
 
         return WINED3DERR_NOTAVAILABLE;
     }
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     wined3d_query_init(&object->query, device, type, &object->statistics,
         return E_OUTOFMEMORY;
 
     wined3d_query_init(&object->query, device, type, &object->statistics,
@@ -1195,6 +1225,72 @@ static HRESULT wined3d_pipeline_query_create(struct wined3d_device *device,
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+static void wined3d_statistics_query_ops_destroy(struct wined3d_query *query)
+{
+    HeapFree(GetProcessHeap(), 0, query);
+}
+
+static const struct wined3d_query_ops statistics_query_ops =
+{
+    wined3d_statistics_query_ops_poll,
+    wined3d_statistics_query_ops_issue,
+    wined3d_statistics_query_ops_destroy,
+};
+
+static HRESULT wined3d_statistics_query_create(struct wined3d_device *device,
+        enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
+        struct wined3d_query **query)
+{
+    static const struct wined3d_query_data_so_statistics statistics = { 1, 1 };
+    struct wined3d_query *object;
+
+    FIXME("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query);
+
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    wined3d_query_init(object, device, type, &statistics,
+            sizeof(statistics), &statistics_query_ops, parent, parent_ops);
+
+    TRACE("Created query %p.\n", object);
+    *query = object;
+
+    return WINED3D_OK;
+}
+
+static void wined3d_overflow_query_ops_destroy(struct wined3d_query *query)
+{
+    HeapFree(GetProcessHeap(), 0, query);
+}
+
+static const struct wined3d_query_ops overflow_query_ops =
+{
+    wined3d_overflow_query_ops_poll,
+    wined3d_overflow_query_ops_issue,
+    wined3d_overflow_query_ops_destroy,
+};
+
+static HRESULT wined3d_overflow_query_create(struct wined3d_device *device,
+        enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
+        struct wined3d_query **query)
+{
+    static const BOOL overflow = FALSE;
+    struct wined3d_query *object;
+
+    FIXME("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query);
+
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    wined3d_query_init(object, device, type, &overflow,
+            sizeof(overflow), &overflow_query_ops, parent, parent_ops);
+
+    TRACE("Created query %p.\n", object);
+    *query = object;
+
+    return WINED3D_OK;
+}
+
 HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
 {
 HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
 {
@@ -1225,6 +1321,12 @@ HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_q
         case WINED3D_QUERY_TYPE_PIPELINE_STATISTICS:
             return wined3d_pipeline_query_create(device, type, parent, parent_ops, query);
 
         case WINED3D_QUERY_TYPE_PIPELINE_STATISTICS:
             return wined3d_pipeline_query_create(device, type, parent, parent_ops, query);
 
+        case WINED3D_QUERY_TYPE_SO_STATISTICS:
+            return wined3d_statistics_query_create(device, type, parent, parent_ops, query);
+
+        case WINED3D_QUERY_TYPE_SO_OVERFLOW:
+            return wined3d_overflow_query_create(device, type, parent, parent_ops, query);
+
         default:
             FIXME("Unhandled query type %#x.\n", type);
             return WINED3DERR_NOTAVAILABLE;
         default:
             FIXME("Unhandled query type %#x.\n", type);
             return WINED3DERR_NOTAVAILABLE;
index 0788146..8b7f17b 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
 
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
 
-static DWORD resource_access_from_pool(enum wined3d_pool pool)
-{
-    switch (pool)
-    {
-        case WINED3D_POOL_DEFAULT:
-            return WINED3D_RESOURCE_ACCESS_GPU;
-
-        case WINED3D_POOL_MANAGED:
-            return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU;
-
-        case WINED3D_POOL_SCRATCH:
-        case WINED3D_POOL_SYSTEM_MEM:
-            return WINED3D_RESOURCE_ACCESS_CPU;
-
-        default:
-            FIXME("Unhandled pool %#x.\n", pool);
-            return 0;
-    }
-}
-
 static void resource_check_usage(DWORD usage)
 {
 static void resource_check_usage(DWORD usage)
 {
-    static const DWORD handled = WINED3DUSAGE_RENDERTARGET
+    static DWORD handled = WINED3DUSAGE_RENDERTARGET
             | WINED3DUSAGE_DEPTHSTENCIL
             | WINED3DUSAGE_WRITEONLY
             | WINED3DUSAGE_DYNAMIC
             | WINED3DUSAGE_DEPTHSTENCIL
             | WINED3DUSAGE_WRITEONLY
             | WINED3DUSAGE_DYNAMIC
-            | WINED3DUSAGE_AUTOGENMIPMAP
             | WINED3DUSAGE_STATICDECL
             | WINED3DUSAGE_OVERLAY
             | WINED3DUSAGE_STATICDECL
             | WINED3DUSAGE_OVERLAY
+            | WINED3DUSAGE_SCRATCH
             | WINED3DUSAGE_PRIVATE
             | WINED3DUSAGE_LEGACY_CUBEMAP
             | WINED3DUSAGE_TEXTURE;
             | WINED3DUSAGE_PRIVATE
             | WINED3DUSAGE_LEGACY_CUBEMAP
             | WINED3DUSAGE_TEXTURE;
@@ -66,16 +48,19 @@ static void resource_check_usage(DWORD usage)
      * driver. */
 
     if (usage & ~handled)
      * driver. */
 
     if (usage & ~handled)
+    {
         FIXME("Unhandled usage flags %#x.\n", 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");
 }
 
 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
         enum wined3d_resource_type type, const struct wined3d_format *format,
     if ((usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY)) == WINED3DUSAGE_DYNAMIC)
         WARN_(d3d_perf)("WINED3DUSAGE_DYNAMIC used without WINED3DUSAGE_WRITEONLY.\n");
 }
 
 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
         enum wined3d_resource_type type, const struct wined3d_format *format,
-        enum wined3d_multisample_type multisample_type, UINT multisample_quality,
-        DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
-        void *parent, const struct wined3d_parent_ops *parent_ops,
+        enum wined3d_multisample_type multisample_type, unsigned int multisample_quality,
+        unsigned int usage, unsigned int access, unsigned int width, unsigned int height, unsigned int depth,
+        unsigned int size, void *parent, const struct wined3d_parent_ops *parent_ops,
         const struct wined3d_resource_ops *resource_ops)
 {
     enum wined3d_gl_resource_type base_type = WINED3D_GL_RES_TYPE_COUNT;
         const struct wined3d_resource_ops *resource_ops)
 {
     enum wined3d_gl_resource_type base_type = WINED3D_GL_RES_TYPE_COUNT;
@@ -93,6 +78,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
     resource_types[] =
     {
         {WINED3D_RTYPE_BUFFER,      0,                              WINED3D_GL_RES_TYPE_BUFFER},
     resource_types[] =
     {
         {WINED3D_RTYPE_BUFFER,      0,                              WINED3D_GL_RES_TYPE_BUFFER},
+        {WINED3D_RTYPE_TEXTURE_1D,  0,                              WINED3D_GL_RES_TYPE_TEX_1D},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_TEX_2D},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_TEX_RECT},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_RB},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_TEX_2D},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_TEX_RECT},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_RB},
@@ -102,6 +88,13 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
 
     resource_check_usage(usage);
 
 
     resource_check_usage(usage);
 
+    if (usage & WINED3DUSAGE_SCRATCH && access & WINED3D_RESOURCE_ACCESS_GPU)
+    {
+        ERR("Trying to create a scratch resource with access flags %s.\n",
+                wined3d_debug_resource_access(access));
+        return WINED3DERR_INVALIDCALL;
+    }
+
     for (i = 0; i < ARRAY_SIZE(resource_types); ++i)
     {
         if (resource_types[i].type != type
     for (i = 0; i < ARRAY_SIZE(resource_types); ++i)
     {
         if (resource_types[i].type != type
@@ -155,7 +148,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
              * Use 2D textures, the texture code will pad to a power of 2 size. */
             gl_type = WINED3D_GL_RES_TYPE_TEX_2D;
         }
              * Use 2D textures, the texture code will pad to a power of 2 size. */
             gl_type = WINED3D_GL_RES_TYPE_TEX_2D;
         }
-        else if (pool == WINED3D_POOL_SCRATCH)
+        else if (usage & WINED3DUSAGE_SCRATCH)
         {
             /* Needed for proper format information. */
             gl_type = base_type;
         {
             /* Needed for proper format information. */
             gl_type = base_type;
@@ -188,10 +181,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
     resource->multisample_type = multisample_type;
     resource->multisample_quality = multisample_quality;
     resource->usage = usage;
     resource->multisample_type = multisample_type;
     resource->multisample_quality = multisample_quality;
     resource->usage = usage;
-    resource->pool = pool;
-    resource->access_flags = resource_access_from_pool(pool);
-    if (usage & WINED3DUSAGE_DYNAMIC)
-        resource->access_flags |= WINED3D_RESOURCE_ACCESS_CPU;
+    resource->access = access;
     resource->width = width;
     resource->height = height;
     resource->depth = depth;
     resource->width = width;
     resource->height = height;
     resource->depth = depth;
@@ -218,7 +208,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
     if (!(usage & WINED3DUSAGE_PRIVATE))
     {
         /* Check that we have enough video ram left */
     if (!(usage & WINED3DUSAGE_PRIVATE))
     {
         /* Check that we have enough video ram left */
-        if (pool == WINED3D_POOL_DEFAULT && device->wined3d->flags & WINED3D_VIDMEM_ACCOUNTING)
+        if (!(access & WINED3D_RESOURCE_ACCESS_CPU) && device->wined3d->flags & WINED3D_VIDMEM_ACCOUNTING)
         {
             if (size > wined3d_device_get_available_texture_mem(device))
             {
         {
             if (size > wined3d_device_get_available_texture_mem(device))
             {
@@ -252,7 +242,7 @@ void resource_cleanup(struct wined3d_resource *resource)
 
     if (!(resource->usage & WINED3DUSAGE_PRIVATE))
     {
 
     if (!(resource->usage & WINED3DUSAGE_PRIVATE))
     {
-        if (resource->pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
+        if (!(resource->access & WINED3D_RESOURCE_ACCESS_CPU) && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
         {
             TRACE("Decrementing device memory pool by %u.\n", resource->size);
             adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size);
         {
             TRACE("Decrementing device memory pool by %u.\n", resource->size);
             adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size);
@@ -274,7 +264,7 @@ DWORD CDECL wined3d_resource_set_priority(struct wined3d_resource *resource, DWO
 {
     DWORD prev;
 
 {
     DWORD prev;
 
-    if (resource->pool != WINED3D_POOL_MANAGED)
+    if (!wined3d_resource_access_is_managed(resource->access))
     {
         WARN("Called on non-managed resource %p, ignoring.\n", resource);
         return 0;
     {
         WARN("Called on non-managed resource %p, ignoring.\n", resource);
         return 0;
@@ -309,7 +299,7 @@ void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, st
     desc->multisample_type = resource->multisample_type;
     desc->multisample_quality = resource->multisample_quality;
     desc->usage = resource->usage;
     desc->multisample_type = resource->multisample_type;
     desc->multisample_quality = resource->multisample_quality;
     desc->usage = resource->usage;
-    desc->pool = resource->pool;
+    desc->access = resource->access;
     desc->width = resource->width;
     desc->height = resource->height;
     desc->depth = resource->depth;
     desc->width = resource->width;
     desc->height = resource->height;
     desc->depth = resource->depth;
@@ -320,17 +310,17 @@ static DWORD wined3d_resource_sanitise_map_flags(const struct wined3d_resource *
 {
     /* Not all flags make sense together, but Windows never returns an error.
      * Catch the cases that could cause issues. */
 {
     /* Not all flags make sense together, but Windows never returns an error.
      * Catch the cases that could cause issues. */
-    if (flags & WINED3D_MAP_READONLY)
+    if (flags & WINED3D_MAP_READ)
     {
         if (flags & WINED3D_MAP_DISCARD)
         {
     {
         if (flags & WINED3D_MAP_DISCARD)
         {
-            WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
-            return 0;
+            WARN("WINED3D_MAP_READ combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
+            return flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE);
         }
         if (flags & WINED3D_MAP_NOOVERWRITE)
         {
         }
         if (flags & WINED3D_MAP_NOOVERWRITE)
         {
-            WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
-            return 0;
+            WARN("WINED3D_MAP_READ combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
+            return flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE);
         }
     }
     else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
         }
     }
     else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
@@ -338,7 +328,7 @@ static DWORD wined3d_resource_sanitise_map_flags(const struct wined3d_resource *
         if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
         {
             WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
         if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
         {
             WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
-            return 0;
+            return flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE);
         }
         if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
                 == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
         }
         if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
                 == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
@@ -357,12 +347,38 @@ HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource, unsigned i
     TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n",
             resource, sub_resource_idx, map_desc, debug_box(box), flags);
 
     TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n",
             resource, sub_resource_idx, map_desc, debug_box(box), flags);
 
+    if (!(flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE)))
+    {
+        WARN("No read/write flags specified.\n");
+        return E_INVALIDARG;
+    }
+
+    if ((flags & WINED3D_MAP_READ) && !(resource->access & WINED3D_RESOURCE_ACCESS_MAP_R))
+    {
+        WARN("Resource does not have MAP_R access.\n");
+        return E_INVALIDARG;
+    }
+
+    if ((flags & WINED3D_MAP_WRITE) && !(resource->access & WINED3D_RESOURCE_ACCESS_MAP_W))
+    {
+        WARN("Resource does not have MAP_W access.\n");
+        return E_INVALIDARG;
+    }
+
     flags = wined3d_resource_sanitise_map_flags(resource, flags);
     wined3d_resource_wait_idle(resource);
 
     return wined3d_cs_map(resource->device->cs, resource, sub_resource_idx, map_desc, box, flags);
 }
 
     flags = wined3d_resource_sanitise_map_flags(resource, flags);
     wined3d_resource_wait_idle(resource);
 
     return wined3d_cs_map(resource->device->cs, resource, sub_resource_idx, map_desc, box, flags);
 }
 
+HRESULT CDECL wined3d_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+        struct wined3d_map_info *info, DWORD flags)
+{
+    TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx);
+
+    return resource->resource_ops->resource_map_info(resource, sub_resource_idx, info, flags);
+}
+
 HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
 {
     TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx);
 HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
 {
     TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx);
@@ -370,6 +386,99 @@ HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned
     return wined3d_cs_unmap(resource->device->cs, resource, sub_resource_idx);
 }
 
     return wined3d_cs_unmap(resource->device->cs, resource, sub_resource_idx);
 }
 
+UINT CDECL wined3d_resource_update_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+        const struct wined3d_box *box, unsigned int row_pitch, unsigned int depth_pitch)
+{
+    unsigned int width, height, depth;
+    struct wined3d_box b;
+    UINT data_size;
+
+    TRACE("resource %p, sub_resource_idx %u, box %s, row_pitch %u, depth_pitch %u.\n",
+            resource, sub_resource_idx, debug_box(box), row_pitch, depth_pitch);
+
+    if (resource->type == WINED3D_RTYPE_BUFFER)
+    {
+        if (sub_resource_idx > 0)
+        {
+            WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
+            return 0;
+        }
+
+        width = resource->size;
+        height = 1;
+        depth = 1;
+    }
+    else if (resource->type == WINED3D_RTYPE_TEXTURE_1D ||
+            resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D)
+    {
+        struct wined3d_texture *texture = texture_from_resource(resource);
+        unsigned int level;
+
+        if (sub_resource_idx >= texture->level_count * texture->layer_count)
+        {
+            WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
+            return 0;
+        }
+
+        level = sub_resource_idx % texture->level_count;
+        width = wined3d_texture_get_level_width(texture, level);
+        height = wined3d_texture_get_level_height(texture, level);
+        depth = wined3d_texture_get_level_depth(texture, level);
+    }
+    else
+    {
+        FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
+        return 0;
+    }
+
+    if (!box)
+    {
+        wined3d_box_set(&b, 0, 0, width, height, 0, depth);
+        box = &b;
+    }
+    else if (box->left >= box->right || box->right > width
+            || box->top >= box->bottom || box->bottom > height
+            || box->front >= box->back || box->back > depth)
+    {
+        WARN("Invalid box %s specified.\n", debug_box(box));
+        return 0;
+    }
+
+    if (resource->format_flags & WINED3DFMT_FLAG_BLOCKS)
+    {
+        if (resource->type != WINED3D_RTYPE_TEXTURE_2D)
+        {
+            FIXME("Calculation of block formats not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
+            return 0;
+        }
+
+        height  = (box->bottom - box->top  + resource->format->block_height - 1) / resource->format->block_height;
+        width   = (box->right  - box->left + resource->format->block_width  - 1) / resource->format->block_width;
+        return (height - 1) * row_pitch + width * resource->format->block_byte_count;
+    }
+
+    data_size = 0;
+    switch (resource->type)
+    {
+        case WINED3D_RTYPE_TEXTURE_3D:
+            data_size += (box->back - box->front - 1) * depth_pitch;
+            /* fall-through */
+        case WINED3D_RTYPE_TEXTURE_2D:
+            data_size += (box->bottom - box->top - 1) * row_pitch;
+            /* fall-through */
+        case WINED3D_RTYPE_TEXTURE_1D:
+            data_size += (box->right - box->left) * resource->format->byte_count;
+            break;
+        case WINED3D_RTYPE_BUFFER:
+            data_size = box->right - box->left;
+            break;
+        case WINED3D_RTYPE_NONE:
+            break;
+    }
+
+    return data_size;
+}
+
 void CDECL wined3d_resource_preload(struct wined3d_resource *resource)
 {
     wined3d_cs_emit_preload_resource(resource->device->cs, resource);
 void CDECL wined3d_resource_preload(struct wined3d_resource *resource)
 {
     wined3d_cs_emit_preload_resource(resource->device->cs, resource);
@@ -381,7 +490,7 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource)
     SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p);
     void *mem;
 
     SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p);
     void *mem;
 
-    if (!(mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, resource->size + align)))
+    if (!(mem = heap_alloc_zero(resource->size + align)))
         return FALSE;
 
     p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1;
         return FALSE;
 
     p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1;
@@ -399,7 +508,7 @@ void wined3d_resource_free_sysmem(struct wined3d_resource *resource)
     if (!p)
         return;
 
     if (!p)
         return;
 
-    HeapFree(GetProcessHeap(), 0, *(--p));
+    heap_free(*(--p));
     resource->heap_memory = NULL;
 }
 
     resource->heap_memory = NULL;
 }
 
@@ -407,9 +516,9 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
 {
     GLbitfield ret = 0;
 
 {
     GLbitfield ret = 0;
 
-    if (!(d3d_flags & WINED3D_MAP_READONLY))
+    if (d3d_flags & WINED3D_MAP_WRITE)
         ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
         ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
-    if (!(d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
+    if (d3d_flags & WINED3D_MAP_READ)
         ret |= GL_MAP_READ_BIT;
 
     if (d3d_flags & WINED3D_MAP_DISCARD)
         ret |= GL_MAP_READ_BIT;
 
     if (d3d_flags & WINED3D_MAP_DISCARD)
@@ -422,11 +531,17 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
 
 GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags)
 {
 
 GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags)
 {
-    if (d3d_flags & WINED3D_MAP_READONLY)
-        return GL_READ_ONLY_ARB;
-    if (d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
-        return GL_WRITE_ONLY_ARB;
-    return GL_READ_WRITE_ARB;
+    switch (d3d_flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE))
+    {
+        case WINED3D_MAP_READ:
+            return GL_READ_ONLY_ARB;
+
+        case WINED3D_MAP_WRITE:
+            return GL_WRITE_ONLY_ARB;
+
+        default:
+            return GL_READ_WRITE_ARB;
+    }
 }
 
 BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource)
 }
 
 BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource)
@@ -453,11 +568,23 @@ BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource)
 void wined3d_resource_update_draw_binding(struct wined3d_resource *resource)
 {
     if (!wined3d_resource_is_offscreen(resource) || wined3d_settings.offscreen_rendering_mode != ORM_FBO)
 void wined3d_resource_update_draw_binding(struct wined3d_resource *resource)
 {
     if (!wined3d_resource_is_offscreen(resource) || wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+    {
         resource->draw_binding = WINED3D_LOCATION_DRAWABLE;
         resource->draw_binding = WINED3D_LOCATION_DRAWABLE;
+    }
     else if (resource->multisample_type)
     else if (resource->multisample_type)
-        resource->draw_binding = WINED3D_LOCATION_RB_MULTISAMPLE;
+    {
+        const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info;
+        if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+            resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB;
+        else
+            resource->draw_binding = WINED3D_LOCATION_RB_MULTISAMPLE;
+    }
     else if (resource->gl_type == WINED3D_GL_RES_TYPE_RB)
     else if (resource->gl_type == WINED3D_GL_RES_TYPE_RB)
+    {
         resource->draw_binding = WINED3D_LOCATION_RB_RESOLVED;
         resource->draw_binding = WINED3D_LOCATION_RB_RESOLVED;
+    }
     else
     else
+    {
         resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB;
         resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB;
+    }
 }
 }
index 1c5f677..82fbe2c 100644 (file)
@@ -17,6 +17,9 @@
  *
  */
 
  *
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -44,7 +47,7 @@ static void wined3d_sampler_destroy_object(void *object)
         context_release(context);
     }
 
         context_release(context);
     }
 
-    HeapFree(GetProcessHeap(), 0, sampler);
+    heap_free(sampler);
 }
 
 ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
 }
 
 ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
@@ -141,7 +144,7 @@ HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct
             || desc->mip_filter > WINED3D_TEXF_LINEAR)
         return WINED3DERR_INVALIDCALL;
 
             || desc->mip_filter > WINED3D_TEXF_LINEAR)
         return WINED3DERR_INVALIDCALL;
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     wined3d_sampler_init(object, device, desc, parent, parent_ops);
         return E_OUTOFMEMORY;
 
     wined3d_sampler_init(object, device, desc, parent, parent_ops);
index a42f35d..0513c9e 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#include <string.h>
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
@@ -422,7 +428,7 @@ void string_buffer_clear(struct wined3d_string_buffer *buffer)
 BOOL string_buffer_init(struct wined3d_string_buffer *buffer)
 {
     buffer->buffer_size = 32;
 BOOL string_buffer_init(struct wined3d_string_buffer *buffer)
 {
     buffer->buffer_size = 32;
-    if (!(buffer->buffer = HeapAlloc(GetProcessHeap(), 0, buffer->buffer_size)))
+    if (!(buffer->buffer = heap_alloc(buffer->buffer_size)))
     {
         ERR("Failed to allocate shader buffer memory.\n");
         return FALSE;
     {
         ERR("Failed to allocate shader buffer memory.\n");
         return FALSE;
@@ -434,7 +440,7 @@ BOOL string_buffer_init(struct wined3d_string_buffer *buffer)
 
 void string_buffer_free(struct wined3d_string_buffer *buffer)
 {
 
 void string_buffer_free(struct wined3d_string_buffer *buffer)
 {
-    HeapFree(GetProcessHeap(), 0, buffer->buffer);
+    heap_free(buffer->buffer);
 }
 
 BOOL string_buffer_resize(struct wined3d_string_buffer *buffer, int rc)
 }
 
 BOOL string_buffer_resize(struct wined3d_string_buffer *buffer, int rc)
@@ -444,7 +450,7 @@ BOOL string_buffer_resize(struct wined3d_string_buffer *buffer, int rc)
 
     while (rc > 0 && (unsigned int)rc >= new_buffer_size - buffer->content_size)
         new_buffer_size *= 2;
 
     while (rc > 0 && (unsigned int)rc >= new_buffer_size - buffer->content_size)
         new_buffer_size *= 2;
-    if (!(new_buffer = HeapReAlloc(GetProcessHeap(), 0, buffer->buffer, new_buffer_size)))
+    if (!(new_buffer = heap_realloc(buffer->buffer, new_buffer_size)))
     {
         ERR("Failed to grow buffer.\n");
         buffer->buffer[buffer->content_size] = '\0';
     {
         ERR("Failed to grow buffer.\n");
         buffer->buffer[buffer->content_size] = '\0';
@@ -492,11 +498,11 @@ struct wined3d_string_buffer *string_buffer_get(struct wined3d_string_buffer_lis
 
     if (list_empty(&list->list))
     {
 
     if (list_empty(&list->list))
     {
-        buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer));
+        buffer = heap_alloc(sizeof(*buffer));
         if (!buffer || !string_buffer_init(buffer))
         {
             ERR("Couldn't allocate buffer for temporary string.\n");
         if (!buffer || !string_buffer_init(buffer))
         {
             ERR("Couldn't allocate buffer for temporary string.\n");
-            HeapFree(GetProcessHeap(), 0, buffer);
+            heap_free(buffer);
             return NULL;
         }
     }
             return NULL;
         }
     }
@@ -553,7 +559,7 @@ void string_buffer_list_cleanup(struct wined3d_string_buffer_list *list)
     LIST_FOR_EACH_ENTRY_SAFE(buffer, buffer_next, &list->list, struct wined3d_string_buffer, entry)
     {
         string_buffer_free(buffer);
     LIST_FOR_EACH_ENTRY_SAFE(buffer, buffer_next, &list->list, struct wined3d_string_buffer, entry)
     {
         string_buffer_free(buffer);
-        HeapFree(GetProcessHeap(), 0, buffer);
+        heap_free(buffer);
     }
     list_init(&list->list);
 }
     }
     list_init(&list->list);
 }
@@ -579,7 +585,7 @@ static void shader_delete_constant_list(struct list *clist)
     struct wined3d_shader_lconst *constant, *constant_next;
 
     LIST_FOR_EACH_ENTRY_SAFE(constant, constant_next, clist, struct wined3d_shader_lconst, entry)
     struct wined3d_shader_lconst *constant, *constant_next;
 
     LIST_FOR_EACH_ENTRY_SAFE(constant, constant_next, clist, struct wined3d_shader_lconst, entry)
-        HeapFree(GetProcessHeap(), 0, constant);
+        heap_free(constant);
     list_init(clist);
 }
 
     list_init(clist);
 }
 
@@ -820,7 +826,7 @@ static void shader_record_sample(struct wined3d_shader_reg_maps *reg_maps,
 
     if (!map->size)
     {
 
     if (!map->size)
     {
-        if (!(entries = wined3d_calloc(4, sizeof(*entries))))
+        if (!(entries = heap_calloc(4, sizeof(*entries))))
         {
             ERR("Failed to allocate sampler map entries.\n");
             return;
         {
             ERR("Failed to allocate sampler map entries.\n");
             return;
@@ -833,7 +839,7 @@ static void shader_record_sample(struct wined3d_shader_reg_maps *reg_maps,
         size_t new_size = map->size * 2;
 
         if (sizeof(*entries) * new_size <= sizeof(*entries) * 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)))
+                || !(entries = heap_realloc(entries, sizeof(*entries) * new_size)))
         {
             ERR("Failed to resize sampler map entries.\n");
             return;
         {
             ERR("Failed to resize sampler map entries.\n");
             return;
@@ -919,10 +925,9 @@ static HRESULT shader_record_shader_phase(struct wined3d_shader *shader,
             if (shader->u.hs.phases.control_point)
             {
                 FIXME("Multiple control point phases.\n");
             if (shader->u.hs.phases.control_point)
             {
                 FIXME("Multiple control point phases.\n");
-                HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.control_point);
+                heap_free(shader->u.hs.phases.control_point);
             }
             }
-            if (!(shader->u.hs.phases.control_point = HeapAlloc(GetProcessHeap(),
-                    HEAP_ZERO_MEMORY, sizeof(*shader->u.hs.phases.control_point))))
+            if (!(shader->u.hs.phases.control_point = heap_alloc_zero(sizeof(*shader->u.hs.phases.control_point))))
                 return E_OUTOFMEMORY;
             phase = shader->u.hs.phases.control_point;
             break;
                 return E_OUTOFMEMORY;
             phase = shader->u.hs.phases.control_point;
             break;
@@ -952,27 +957,19 @@ static HRESULT shader_record_shader_phase(struct wined3d_shader *shader,
 }
 
 static HRESULT shader_calculate_clip_or_cull_distance_mask(
 }
 
 static HRESULT shader_calculate_clip_or_cull_distance_mask(
-        const struct wined3d_shader_signature_element *e, DWORD *mask)
+        const struct wined3d_shader_signature_element *e, unsigned int *mask)
 {
 {
-    unsigned int i;
-
-    *mask = 0;
-
-    /* Cull and clip distances are packed in 4 component registers. 0 and 1 are
+    /* Clip and cull distances are packed in 4 component registers. 0 and 1 are
      * the only allowed semantic indices.
      */
     if (e->semantic_idx >= MAX_CLIP_DISTANCES / 4)
     {
      * the only allowed semantic indices.
      */
     if (e->semantic_idx >= MAX_CLIP_DISTANCES / 4)
     {
+        *mask = 0;
         WARN("Invalid clip/cull distance index %u.\n", e->semantic_idx);
         return WINED3DERR_INVALIDCALL;
     }
 
         WARN("Invalid clip/cull distance index %u.\n", e->semantic_idx);
         return WINED3DERR_INVALIDCALL;
     }
 
-    for (i = 0; i < 4; ++i)
-    {
-        if (e->mask & (WINED3DSP_WRITEMASK_0 << i))
-            *mask |= 1u << (4 * e->semantic_idx + i);
-    }
-
+    *mask = (e->mask & WINED3DSP_WRITEMASK_ALL) << (4 * e->semantic_idx);
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -1013,7 +1010,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
 
     shader_set_limits(shader);
 
 
     shader_set_limits(shader);
 
-    if (!(reg_maps->constf = wined3d_calloc(((min(shader->limits->constant_float, constf_size) + 31) / 32),
+    if (!(reg_maps->constf = heap_calloc(((min(shader->limits->constant_float, constf_size) + 31) / 32),
             sizeof(*reg_maps->constf))))
     {
         ERR("Failed to allocate constant map memory.\n");
             sizeof(*reg_maps->constf))))
     {
         ERR("Failed to allocate constant map memory.\n");
@@ -1158,7 +1155,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             {
                 struct wined3d_shader_indexable_temp *reg;
 
             {
                 struct wined3d_shader_indexable_temp *reg;
 
-                if (!(reg = HeapAlloc(GetProcessHeap(), 0, sizeof(*reg))))
+                if (!(reg = heap_alloc(sizeof(*reg))))
                     return E_OUTOFMEMORY;
 
                 *reg = ins.declaration.indexable_temp;
                     return E_OUTOFMEMORY;
 
                 *reg = ins.declaration.indexable_temp;
@@ -1338,9 +1335,11 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         }
         else if (ins.handler_idx == WINED3DSIH_DEF)
         {
         }
         else if (ins.handler_idx == WINED3DSIH_DEF)
         {
-            struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
+            struct wined3d_shader_lconst *lconst;
             float *value;
             float *value;
-            if (!lconst) return E_OUTOFMEMORY;
+
+            if (!(lconst = heap_alloc(sizeof(*lconst))))
+                return E_OUTOFMEMORY;
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.u.immconst_data, 4 * sizeof(DWORD));
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.u.immconst_data, 4 * sizeof(DWORD));
@@ -1369,8 +1368,10 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         }
         else if (ins.handler_idx == WINED3DSIH_DEFI)
         {
         }
         else if (ins.handler_idx == WINED3DSIH_DEFI)
         {
-            struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
-            if (!lconst) return E_OUTOFMEMORY;
+            struct wined3d_shader_lconst *lconst;
+
+            if (!(lconst = heap_alloc(sizeof(*lconst))))
+                return E_OUTOFMEMORY;
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.u.immconst_data, 4 * sizeof(DWORD));
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.u.immconst_data, 4 * sizeof(DWORD));
@@ -1380,8 +1381,10 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         }
         else if (ins.handler_idx == WINED3DSIH_DEFB)
         {
         }
         else if (ins.handler_idx == WINED3DSIH_DEFB)
         {
-            struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
-            if (!lconst) return E_OUTOFMEMORY;
+            struct wined3d_shader_lconst *lconst;
+
+            if (!(lconst = heap_alloc(sizeof(*lconst))))
+                return E_OUTOFMEMORY;
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.u.immconst_data, sizeof(DWORD));
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.u.immconst_data, sizeof(DWORD));
@@ -1670,6 +1673,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                         WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count);
             }
             else if (ins.handler_idx == WINED3DSIH_LD
                         WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count);
             }
             else if (ins.handler_idx == WINED3DSIH_LD
+                    || ins.handler_idx == WINED3DSIH_LD2DMS
                     || (ins.handler_idx == WINED3DSIH_LD_RAW && ins.src[1].reg.type == WINED3DSPR_RESOURCE)
                     || (ins.handler_idx == WINED3DSIH_RESINFO && ins.src[1].reg.type == WINED3DSPR_RESOURCE))
             {
                     || (ins.handler_idx == WINED3DSIH_LD_RAW && ins.src[1].reg.type == WINED3DSPR_RESOURCE)
                     || (ins.handler_idx == WINED3DSIH_RESINFO && ins.src[1].reg.type == WINED3DSPR_RESOURCE))
             {
@@ -1760,7 +1764,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         struct wined3d_shader_signature_element *e;
         unsigned int i;
 
         struct wined3d_shader_signature_element *e;
         unsigned int i;
 
-        if (!(input_signature->elements = wined3d_calloc(count, sizeof(*input_signature->elements))))
+        if (!(input_signature->elements = heap_calloc(count, sizeof(*input_signature->elements))))
             return E_OUTOFMEMORY;
         input_signature->element_count = count;
 
             return E_OUTOFMEMORY;
         input_signature->element_count = count;
 
@@ -1779,7 +1783,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         for (i = 0; i < output_signature->element_count; ++i)
         {
             const struct wined3d_shader_signature_element *e = &output_signature->elements[i];
         for (i = 0; i < output_signature->element_count; ++i)
         {
             const struct wined3d_shader_signature_element *e = &output_signature->elements[i];
-            DWORD mask;
+            unsigned int mask;
 
             reg_maps->output_registers |= 1u << e->register_idx;
             if (e->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
 
             reg_maps->output_registers |= 1u << e->register_idx;
             if (e->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
@@ -1801,7 +1805,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         unsigned int count = wined3d_popcount(reg_maps->output_registers);
         struct wined3d_shader_signature_element *e;
 
         unsigned int count = wined3d_popcount(reg_maps->output_registers);
         struct wined3d_shader_signature_element *e;
 
-        if (!(output_signature->elements = wined3d_calloc(count, sizeof(*output_signature->elements))))
+        if (!(output_signature->elements = heap_calloc(count, sizeof(*output_signature->elements))))
             return E_OUTOFMEMORY;
         output_signature->element_count = count;
 
             return E_OUTOFMEMORY;
         output_signature->element_count = count;
 
@@ -1821,14 +1825,14 @@ static void shader_cleanup_reg_maps(struct wined3d_shader_reg_maps *reg_maps)
 {
     struct wined3d_shader_indexable_temp *reg, *reg_next;
 
 {
     struct wined3d_shader_indexable_temp *reg, *reg_next;
 
-    HeapFree(GetProcessHeap(), 0, reg_maps->constf);
-    HeapFree(GetProcessHeap(), 0, reg_maps->sampler_map.entries);
+    heap_free(reg_maps->constf);
+    heap_free(reg_maps->sampler_map.entries);
 
     LIST_FOR_EACH_ENTRY_SAFE(reg, reg_next, &reg_maps->indexable_temps, struct wined3d_shader_indexable_temp, entry)
 
     LIST_FOR_EACH_ENTRY_SAFE(reg, reg_next, &reg_maps->indexable_temps, struct wined3d_shader_indexable_temp, entry)
-        HeapFree(GetProcessHeap(), 0, reg);
+        heap_free(reg);
     list_init(&reg_maps->indexable_temps);
 
     list_init(&reg_maps->indexable_temps);
 
-    HeapFree(GetProcessHeap(), 0, reg_maps->tgsm);
+    heap_free(reg_maps->tgsm);
 }
 
 unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps, unsigned int max)
 }
 
 unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps, unsigned int max)
@@ -3085,22 +3089,22 @@ static void shader_cleanup(struct wined3d_shader *shader)
 {
     if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_HULL)
     {
 {
     if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_HULL)
     {
-        HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.control_point);
-        HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.fork);
-        HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.join);
+        heap_free(shader->u.hs.phases.control_point);
+        heap_free(shader->u.hs.phases.fork);
+        heap_free(shader->u.hs.phases.join);
     }
     else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
     {
     }
     else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
     {
-        HeapFree(GetProcessHeap(), 0, shader->u.gs.so_desc.elements);
+        heap_free(shader->u.gs.so_desc.elements);
     }
 
     }
 
-    HeapFree(GetProcessHeap(), 0, shader->patch_constant_signature.elements);
-    HeapFree(GetProcessHeap(), 0, shader->output_signature.elements);
-    HeapFree(GetProcessHeap(), 0, shader->input_signature.elements);
-    HeapFree(GetProcessHeap(), 0, shader->signature_strings);
+    heap_free(shader->patch_constant_signature.elements);
+    heap_free(shader->output_signature.elements);
+    heap_free(shader->input_signature.elements);
+    heap_free(shader->signature_strings);
     shader->device->shader_backend->shader_destroy(shader);
     shader_cleanup_reg_maps(&shader->reg_maps);
     shader->device->shader_backend->shader_destroy(shader);
     shader_cleanup_reg_maps(&shader->reg_maps);
-    HeapFree(GetProcessHeap(), 0, shader->function);
+    heap_free(shader->function);
     shader_delete_constant_list(&shader->constantsF);
     shader_delete_constant_list(&shader->constantsB);
     shader_delete_constant_list(&shader->constantsI);
     shader_delete_constant_list(&shader->constantsF);
     shader_delete_constant_list(&shader->constantsB);
     shader_delete_constant_list(&shader->constantsI);
@@ -3164,13 +3168,13 @@ static HRESULT shader_none_alloc(struct wined3d_device *device, const struct win
     void *vertex_priv, *fragment_priv;
     struct shader_none_priv *priv;
 
     void *vertex_priv, *fragment_priv;
     struct shader_none_priv *priv;
 
-    if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
+    if (!(priv = heap_alloc(sizeof(*priv))))
         return E_OUTOFMEMORY;
 
     if (!(vertex_priv = vertex_pipe->vp_alloc(&none_shader_backend, priv)))
     {
         ERR("Failed to initialize vertex pipe.\n");
         return E_OUTOFMEMORY;
 
     if (!(vertex_priv = vertex_pipe->vp_alloc(&none_shader_backend, priv)))
     {
         ERR("Failed to initialize vertex pipe.\n");
-        HeapFree(GetProcessHeap(), 0, priv);
+        heap_free(priv);
         return E_FAIL;
     }
 
         return E_FAIL;
     }
 
@@ -3178,7 +3182,7 @@ static HRESULT shader_none_alloc(struct wined3d_device *device, const struct win
     {
         ERR("Failed to initialize fragment pipe.\n");
         vertex_pipe->vp_free(device);
     {
         ERR("Failed to initialize fragment pipe.\n");
         vertex_pipe->vp_free(device);
-        HeapFree(GetProcessHeap(), 0, priv);
+        heap_free(priv);
         return E_FAIL;
     }
 
         return E_FAIL;
     }
 
@@ -3200,7 +3204,7 @@ static void shader_none_free(struct wined3d_device *device)
 
     priv->fragment_pipe->free_private(device);
     priv->vertex_pipe->vp_free(device);
 
     priv->fragment_pipe->free_private(device);
     priv->vertex_pipe->vp_free(device);
-    HeapFree(GetProcessHeap(), 0, priv);
+    heap_free(priv);
 }
 
 static BOOL shader_none_allocate_context_data(struct wined3d_context *context)
 }
 
 static BOOL shader_none_allocate_context_data(struct wined3d_context *context)
@@ -3354,7 +3358,7 @@ static void wined3d_shader_init_object(void *object)
 static void wined3d_shader_destroy_object(void *object)
 {
     shader_cleanup(object);
 static void wined3d_shader_destroy_object(void *object)
 {
     shader_cleanup(object);
-    HeapFree(GetProcessHeap(), 0, object);
+    heap_free(object);
 }
 
 ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader)
 }
 
 ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader)
@@ -3421,9 +3425,10 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh
 
     for (i = start_idx; i < end_idx; ++i)
     {
 
     for (i = start_idx; i < end_idx; ++i)
     {
-        struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
+        struct wined3d_shader_lconst *lconst;
         float *value;
         float *value;
-        if (!lconst)
+
+        if (!(lconst = heap_alloc(sizeof(*lconst))))
             return E_OUTOFMEMORY;
 
         lconst->idx = i;
             return E_OUTOFMEMORY;
 
         lconst->idx = i;
@@ -3555,7 +3560,7 @@ static HRESULT shader_signature_copy(struct wined3d_shader_signature *dst,
     ptr = *signature_strings;
 
     dst->element_count = src->element_count;
     ptr = *signature_strings;
 
     dst->element_count = src->element_count;
-    if (!(dst->elements = wined3d_calloc(dst->element_count, sizeof(*dst->elements))))
+    if (!(dst->elements = heap_calloc(dst->element_count, sizeof(*dst->elements))))
         return E_OUTOFMEMORY;
 
     for (i = 0; i < src->element_count; ++i)
         return E_OUTOFMEMORY;
 
     for (i = 0; i < src->element_count; ++i)
@@ -3607,26 +3612,26 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device
         return hr;
     if (FAILED(hr = shader_signature_calculate_strings_length(&desc->patch_constant_signature, &total)))
         return hr;
         return hr;
     if (FAILED(hr = shader_signature_calculate_strings_length(&desc->patch_constant_signature, &total)))
         return hr;
-    if (total && !(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total)))
+    if (total && !(shader->signature_strings = heap_alloc(total)))
         return E_OUTOFMEMORY;
     ptr = shader->signature_strings;
 
     if (FAILED(hr = shader_signature_copy(&shader->input_signature, &desc->input_signature, &ptr)))
     {
         return E_OUTOFMEMORY;
     ptr = shader->signature_strings;
 
     if (FAILED(hr = shader_signature_copy(&shader->input_signature, &desc->input_signature, &ptr)))
     {
-        HeapFree(GetProcessHeap(), 0, shader->signature_strings);
+        heap_free(shader->signature_strings);
         return hr;
     }
     if (FAILED(hr = shader_signature_copy(&shader->output_signature, &desc->output_signature, &ptr)))
     {
         return hr;
     }
     if (FAILED(hr = shader_signature_copy(&shader->output_signature, &desc->output_signature, &ptr)))
     {
-        HeapFree(GetProcessHeap(), 0, shader->input_signature.elements);
-        HeapFree(GetProcessHeap(), 0, shader->signature_strings);
+        heap_free(shader->input_signature.elements);
+        heap_free(shader->signature_strings);
         return hr;
     }
     if (FAILED(hr = shader_signature_copy(&shader->patch_constant_signature, &desc->patch_constant_signature, &ptr)))
     {
         return hr;
     }
     if (FAILED(hr = shader_signature_copy(&shader->patch_constant_signature, &desc->patch_constant_signature, &ptr)))
     {
-        HeapFree(GetProcessHeap(), 0, shader->output_signature.elements);
-        HeapFree(GetProcessHeap(), 0, shader->input_signature.elements);
-        HeapFree(GetProcessHeap(), 0, shader->signature_strings);
+        heap_free(shader->output_signature.elements);
+        heap_free(shader->input_signature.elements);
+        heap_free(shader->signature_strings);
         return hr;
     }
 
         return hr;
     }
 
@@ -3663,7 +3668,7 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device
         byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr);
     }
 
         byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr);
     }
 
-    if (!(shader->function = HeapAlloc(GetProcessHeap(), 0, byte_code_size)))
+    if (!(shader->function = heap_alloc(byte_code_size)))
     {
         shader_cleanup(shader);
         return E_OUTOFMEMORY;
     {
         shader_cleanup(shader);
         return E_OUTOFMEMORY;
@@ -3721,12 +3726,12 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3
     struct wined3d_stream_output_element *elements = NULL;
     HRESULT hr;
 
     struct wined3d_stream_output_element *elements = NULL;
     HRESULT hr;
 
-    if (so_desc && !(elements = wined3d_calloc(so_desc->element_count, sizeof(*elements))))
+    if (so_desc && !(elements = heap_calloc(so_desc->element_count, sizeof(*elements))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops)))
     {
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops)))
     {
-        HeapFree(GetProcessHeap(), 0, elements);
+        heap_free(elements);
         return hr;
     }
 
         return hr;
     }
 
@@ -4006,6 +4011,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
 
     args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]
             ? context->render_offscreen : 0;
 
     args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]
             ? context->render_offscreen : 0;
+
+    args->dual_source_blend = wined3d_dualblend_enabled(state, gl_info);
 }
 
 static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
 }
 
 static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
@@ -4103,13 +4110,13 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru
     TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, parent, parent_ops, shader);
 
     TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, parent, parent_ops, shader);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_COMPUTE, parent, parent_ops)))
     {
         WARN("Failed to initialize compute shader, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_COMPUTE, parent, parent_ops)))
     {
         WARN("Failed to initialize compute shader, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -4128,13 +4135,13 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru
     TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, parent, parent_ops, shader);
 
     TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, parent, parent_ops, shader);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_DOMAIN, parent, parent_ops)))
     {
         WARN("Failed to initialize domain shader, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_DOMAIN, parent, parent_ops)))
     {
         WARN("Failed to initialize domain shader, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -4154,13 +4161,13 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const stru
     TRACE("device %p, desc %p, so_desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, so_desc, parent, parent_ops, shader);
 
     TRACE("device %p, desc %p, so_desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, so_desc, parent, parent_ops, shader);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = geometry_shader_init(object, device, desc, so_desc, parent, parent_ops)))
     {
         WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = geometry_shader_init(object, device, desc, so_desc, parent, parent_ops)))
     {
         WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -4179,13 +4186,13 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru
     TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, parent, parent_ops, shader);
 
     TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, parent, parent_ops, shader);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_HULL, parent, parent_ops)))
     {
         WARN("Failed to initialize hull shader, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_HULL, parent, parent_ops)))
     {
         WARN("Failed to initialize hull shader, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -4204,14 +4211,13 @@ HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const stru
     TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, 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)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = pixel_shader_init(object, device, desc, parent, parent_ops)))
     {
         WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = pixel_shader_init(object, device, desc, parent, parent_ops)))
     {
         WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -4230,14 +4236,13 @@ HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const stru
     TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
             device, desc, 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)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = vertex_shader_init(object, device, desc, parent, parent_ops)))
     {
         WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = vertex_shader_init(object, device, desc, parent, parent_ops)))
     {
         WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
index 983de58..0c6bb93 100644 (file)
@@ -22,6 +22,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
@@ -546,7 +549,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size,
         return NULL;
     }
 
         return NULL;
     }
 
-    if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
+    if (!(priv = heap_alloc(sizeof(*priv))))
         return NULL;
 
     if (output_signature->element_count)
         return NULL;
 
     if (output_signature->element_count)
@@ -566,7 +569,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size,
 
         default:
             FIXME("Unrecognized shader type %#x.\n", *byte_code >> 16);
 
         default:
             FIXME("Unrecognized shader type %#x.\n", *byte_code >> 16);
-            HeapFree(GetProcessHeap(), 0, priv);
+            heap_free(priv);
             return NULL;
     }
     priv->shader_version.major = WINED3D_SM1_VERSION_MAJOR(*byte_code);
             return NULL;
     }
     priv->shader_version.major = WINED3D_SM1_VERSION_MAJOR(*byte_code);
@@ -579,7 +582,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size,
 
 static void shader_sm1_free(void *data)
 {
 
 static void shader_sm1_free(void *data)
 {
-    HeapFree(GetProcessHeap(), 0, data);
+    heap_free(data);
 }
 
 static void shader_sm1_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
 }
 
 static void shader_sm1_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
index a6ece5e..8eac746 100644 (file)
@@ -16,6 +16,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
@@ -1239,7 +1242,7 @@ static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
         return NULL;
     }
 
         return NULL;
     }
 
-    if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
+    if (!(priv = heap_alloc(sizeof(*priv))))
     {
         ERR("Failed to allocate private data\n");
         return NULL;
     {
         ERR("Failed to allocate private data\n");
         return NULL;
@@ -1308,9 +1311,9 @@ static void shader_sm4_free(void *data)
     list_move_head(&priv->src_free, &priv->src);
     LIST_FOR_EACH_ENTRY_SAFE(e1, e2, &priv->src_free, struct wined3d_shader_src_param_entry, entry)
     {
     list_move_head(&priv->src_free, &priv->src);
     LIST_FOR_EACH_ENTRY_SAFE(e1, e2, &priv->src_free, struct wined3d_shader_src_param_entry, entry)
     {
-        HeapFree(GetProcessHeap(), 0, e1);
+        heap_free(e1);
     }
     }
-    HeapFree(GetProcessHeap(), 0, priv);
+    heap_free(priv);
 }
 
 static struct wined3d_shader_src_param *get_src_param(struct wined3d_sm4_data *priv)
 }
 
 static struct wined3d_shader_src_param *get_src_param(struct wined3d_sm4_data *priv)
@@ -1325,7 +1328,7 @@ static struct wined3d_shader_src_param *get_src_param(struct wined3d_sm4_data *p
     }
     else
     {
     }
     else
     {
-        if (!(e = HeapAlloc(GetProcessHeap(), 0, sizeof(*e))))
+        if (!(e = heap_alloc(sizeof(*e))))
             return NULL;
         elem = &e->entry;
     }
             return NULL;
         elem = &e->entry;
     }
index bbb23d5..2f506c3 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
 
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
 
+ULONG CDECL wined3d_blend_state_incref(struct wined3d_blend_state *state)
+{
+    ULONG refcount = InterlockedIncrement(&state->refcount);
+
+    TRACE("%p increasing refcount to %u.\n", state, refcount);
+
+    return refcount;
+}
+
+static void wined3d_blend_state_destroy_object(void *object)
+{
+    heap_free(object);
+}
+
+ULONG CDECL wined3d_blend_state_decref(struct wined3d_blend_state *state)
+{
+    ULONG refcount = InterlockedDecrement(&state->refcount);
+    struct wined3d_device *device = state->device;
+
+    TRACE("%p decreasing refcount to %u.\n", state, refcount);
+
+    if (!refcount)
+    {
+        state->parent_ops->wined3d_object_destroyed(state->parent);
+        wined3d_cs_destroy_object(device->cs, wined3d_blend_state_destroy_object, state);
+    }
+
+    return refcount;
+}
+
+void * CDECL wined3d_blend_state_get_parent(const struct wined3d_blend_state *state)
+{
+    TRACE("state %p.\n", state);
+
+    return state->parent;
+}
+
+HRESULT CDECL wined3d_blend_state_create(struct wined3d_device *device,
+        const struct wined3d_blend_state_desc *desc, void *parent,
+        const struct wined3d_parent_ops *parent_ops, struct wined3d_blend_state **state)
+{
+    struct wined3d_blend_state *object;
+
+    TRACE("device %p, desc %p, parent %p, parent_ops %p, state %p.\n",
+            device, desc, parent, parent_ops, state);
+
+    if (!(object = heap_alloc_zero(sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    object->refcount = 1;
+    object->desc = *desc;
+    object->parent = parent;
+    object->parent_ops = parent_ops;
+    object->device = device;
+
+    TRACE("Created blend state %p.\n", object);
+    *state = object;
+
+    return WINED3D_OK;
+}
+
 ULONG CDECL wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *state)
 {
     ULONG refcount = InterlockedIncrement(&state->refcount);
 ULONG CDECL wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *state)
 {
     ULONG refcount = InterlockedIncrement(&state->refcount);
@@ -41,7 +110,7 @@ ULONG CDECL wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *sta
 
 static void wined3d_rasterizer_state_destroy_object(void *object)
 {
 
 static void wined3d_rasterizer_state_destroy_object(void *object)
 {
-    HeapFree(GetProcessHeap(), 0, object);
+    heap_free(object);
 }
 
 ULONG CDECL wined3d_rasterizer_state_decref(struct wined3d_rasterizer_state *state)
 }
 
 ULONG CDECL wined3d_rasterizer_state_decref(struct wined3d_rasterizer_state *state)
@@ -73,9 +142,10 @@ HRESULT CDECL wined3d_rasterizer_state_create(struct wined3d_device *device,
 {
     struct wined3d_rasterizer_state *object;
 
 {
     struct wined3d_rasterizer_state *object;
 
-    TRACE("device %p, desc %p, state %p.\n", device, desc, state);
+    TRACE("device %p, desc %p, parent %p, parent_ops %p, state %p.\n",
+            device, desc, parent, parent_ops, state);
 
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     object->refcount = 1;
         return E_OUTOFMEMORY;
 
     object->refcount = 1;
@@ -464,12 +534,14 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
     const struct wined3d_format *rt_format;
     GLenum src_blend, dst_blend;
     unsigned int rt_fmt_flags;
     const struct wined3d_format *rt_format;
     GLenum src_blend, dst_blend;
     unsigned int rt_fmt_flags;
+    BOOL enable_dual_blend;
     BOOL enable_blend;
 
     enable_blend = state->fb->render_targets[0] && state->render_states[WINED3D_RS_ALPHABLENDENABLE];
     BOOL enable_blend;
 
     enable_blend = state->fb->render_targets[0] && state->render_states[WINED3D_RS_ALPHABLENDENABLE];
-    if (enable_blend)
+    enable_dual_blend = wined3d_dualblend_enabled(state, context->gl_info);
+
+    if (enable_blend && !enable_dual_blend)
     {
     {
-        rt_format = state->fb->render_targets[0]->format;
         rt_fmt_flags = state->fb->render_targets[0]->format_flags;
 
         /* Disable blending in all cases even without pixelshaders.
         rt_fmt_flags = state->fb->render_targets[0]->format_flags;
 
         /* Disable blending in all cases even without pixelshaders.
@@ -479,6 +551,13 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
             enable_blend = FALSE;
     }
 
             enable_blend = FALSE;
     }
 
+    /* Dual state blending changes the assignment of the output variables */
+    if (context->last_was_dual_blend != enable_dual_blend)
+    {
+        context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
+        context->last_was_dual_blend = enable_dual_blend;
+    }
+
     if (!enable_blend)
     {
         gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
     if (!enable_blend)
     {
         gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
@@ -489,6 +568,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
     gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
     checkGLcall("glEnable(GL_BLEND)");
 
     gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
     checkGLcall("glEnable(GL_BLEND)");
 
+    rt_format = state->fb->render_targets[0]->format;
     gl_blend_from_d3d(&src_blend, &dst_blend,
             state->render_states[WINED3D_RS_SRCBLEND],
             state->render_states[WINED3D_RS_DESTBLEND], rt_format);
     gl_blend_from_d3d(&src_blend, &dst_blend,
             state->render_states[WINED3D_RS_SRCBLEND],
             state->render_states[WINED3D_RS_DESTBLEND], rt_format);
@@ -545,6 +625,28 @@ static void state_blendfactor(struct wined3d_context *context, const struct wine
     checkGLcall("glBlendColor");
 }
 
     checkGLcall("glBlendColor");
 }
 
+static void state_blend_object(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    BOOL alpha_to_coverage = FALSE;
+
+    if (!gl_info->supported[ARB_MULTISAMPLE])
+        return;
+
+    if (state->blend_state)
+    {
+        struct wined3d_blend_state_desc *desc = &state->blend_state->desc;
+        alpha_to_coverage = desc->alpha_to_coverage;
+    }
+
+    if (alpha_to_coverage)
+        gl_info->gl_ops.gl.p_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
+    else
+        gl_info->gl_ops.gl.p_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
+
+    checkGLcall("blend state");
+}
+
 void state_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 void state_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -1464,9 +1566,6 @@ static void state_debug_monitor(struct wined3d_context *context, const struct wi
 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
-    DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
-    DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
-    DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
     TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
     TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
@@ -1480,13 +1579,7 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined
             mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
     checkGLcall("glColorMask(...)");
 
             mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
     checkGLcall("glColorMask(...)");
 
-    if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
-        || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
-    {
-        FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
-            mask0, mask1, mask2, mask3);
-        FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
-    }
+    /* FIXME: WINED3D_RS_COLORWRITEENABLE1 .. WINED3D_RS_COLORWRITEENABLE7 not implemented. */
 }
 
 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
 }
 
 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
@@ -1499,24 +1592,20 @@ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DW
     checkGLcall("glColorMaski");
 }
 
     checkGLcall("glColorMaski");
 }
 
-static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static void state_colorwrite_i(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
 {
-    set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
-}
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    int index;
 
 
-static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
-{
-    set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
-}
+    if (state_id == WINED3D_RS_COLORWRITEENABLE) index = 0;
+    else if (state_id <= WINED3D_RS_COLORWRITEENABLE3) index = state_id - WINED3D_RS_COLORWRITEENABLE1 + 1;
+    else if (state_id <= WINED3D_RS_COLORWRITEENABLE7) index = state_id - WINED3D_RS_COLORWRITEENABLE4 + 4;
+    else return;
 
 
-static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
-{
-    set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
-}
+    if (index >= gl_info->limits.buffers)
+        WARN("Ignoring color write value for index %d, because gpu only supports %d render targets\n", index, gl_info->limits.buffers);
 
 
-static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
-{
-    set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
+    set_color_mask(context->gl_info, index, state->render_states[state_id]);
 }
 
 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 }
 
 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -1690,10 +1779,11 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3
         {
             DWORD d;
             float f;
         {
             DWORD d;
             float f;
-        } scale_bias, const_bias;
+        } scale_bias, const_bias, bias_clamp;
 
         scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
         const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
 
         scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
         const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
+        bias_clamp.d = state->render_states[WINED3D_RS_DEPTHBIASCLAMP];
 
         if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_DEPTH_BIAS)
         {
 
         if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_DEPTH_BIAS)
         {
@@ -1720,7 +1810,18 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3
         }
 
         gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
         }
 
         gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
-        gl_info->gl_ops.gl.p_glPolygonOffset(factor, units);
+        if (gl_info->supported[EXT_POLYGON_OFFSET_CLAMP])
+        {
+            GL_EXTCALL(glPolygonOffsetClampEXT(factor, units, bias_clamp.f));
+            checkGLcall("glPolygonOffsetClampEXT(...)");
+        }
+        else
+        {
+            if (bias_clamp.f)
+                WARN("EXT_polygon_offset_clamp extension missing, no support for depth bias clamping.\n");
+
+            gl_info->gl_ops.gl.p_glPolygonOffset(factor, units);
+        }
     }
     else
     {
     }
     else
     {
@@ -1730,6 +1831,28 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3
     checkGLcall("depth bias");
 }
 
     checkGLcall("depth bias");
 }
 
+static void state_depthclip(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    if (state->render_states[WINED3D_RS_DEPTHCLIP])
+    {
+        gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
+        checkGLcall("glDisable(GL_DEPTH_CLAMP)");
+    }
+    else
+    {
+        gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
+        checkGLcall("glEnable(GL_DEPTH_CLAMP)");
+    }
+}
+
+static void state_depthclip_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+    if (!state->render_states[WINED3D_RS_DEPTHCLIP])
+        FIXME("Depth clamping not supported by GL.\n");
+}
+
 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     if (state->render_states[WINED3D_RS_ZVISIBLE])
 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     if (state->render_states[WINED3D_RS_ZVISIBLE])
@@ -4559,96 +4682,83 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine
     }
 }
 
     }
 }
 
-static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static void get_viewport(struct wined3d_context *context, const struct wined3d_state *state,
+        struct wined3d_viewport *viewport)
 {
     const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil;
     const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
 {
     const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil;
     const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_viewport vp = state->viewport;
     unsigned int width, height;
     unsigned int width, height;
-    float y;
+
+    *viewport = state->viewport;
 
     if (target)
     {
 
     if (target)
     {
-        if (vp.width > target->width)
-            vp.width = target->width;
-        if (vp.height > target->height)
-            vp.height = target->height;
+        if (context->d3d_info->wined3d_creation_flags & WINED3D_LIMIT_VIEWPORT)
+        {
+            if (viewport->width > target->width)
+                viewport->width = target->width;
+            if (viewport->height > target->height)
+                viewport->height = target->height;
+        }
+    }
 
 
+    /*
+     * Note: GL requires lower left, DirectX supplies upper left. This is
+     * reversed when using offscreen rendering.
+     */
+    if (context->render_offscreen)
+        return;
+
+    if (target)
+    {
         wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
     }
     else if (depth_stencil)
     {
         wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
     }
     else if (depth_stencil)
     {
-        width = depth_stencil->width;
         height = depth_stencil->height;
     }
     else
     {
         height = depth_stencil->height;
     }
     else
     {
-        FIXME("No attachments draw calls not supported.\n");
+        FIXME("Could not get the height of render targets.\n");
         return;
     }
 
         return;
     }
 
+    viewport->y = height - (viewport->y + viewport->height);
+}
+
+static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct wined3d_viewport vp;
+
+    get_viewport(context, state, &vp);
+
     gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
     gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
-    checkGLcall("glDepthRange");
-    /* Note: GL requires lower left, DirectX supplies upper left. This is
-     * reversed when using offscreen rendering. */
-    y = context->render_offscreen ? vp.y : height - (vp.y + vp.height);
 
     if (gl_info->supported[ARB_VIEWPORT_ARRAY])
 
     if (gl_info->supported[ARB_VIEWPORT_ARRAY])
-        GL_EXTCALL(glViewportIndexedf(0, vp.x, y, vp.width, vp.height));
+        GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height));
     else
     else
-        gl_info->gl_ops.gl.p_glViewport(vp.x, y, vp.width, vp.height);
-    checkGLcall("glViewport");
+        gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
+    checkGLcall("setting clip space and viewport");
 }
 
 static void viewport_miscpart_cc(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
 }
 
 static void viewport_miscpart_cc(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
-    const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil;
-    const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
-    /* See get_projection_matrix() in utils.c for a discussion about those
-     * values. */
+    /* See get_projection_matrix() in utils.c for a discussion about those values. */
     float pixel_center_offset = context->d3d_info->wined3d_creation_flags
             & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     float pixel_center_offset = context->d3d_info->wined3d_creation_flags
             & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f;
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_viewport vp = state->viewport;
-    unsigned int width, height;
+    struct wined3d_viewport vp;
 
 
-    if (target)
-    {
-        if (vp.width > target->width)
-            vp.width = target->width;
-        if (vp.height > target->height)
-            vp.height = target->height;
-
-        wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
-    }
-    else if (depth_stencil)
-    {
-        width = depth_stencil->width;
-        height = depth_stencil->height;
-    }
-    else
-    {
-        FIXME("No attachments draw calls not supported.\n");
-        return;
-    }
+    get_viewport(context, state, &vp);
+    vp.x += pixel_center_offset;
+    vp.y += pixel_center_offset;
 
     gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
 
     gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
-    checkGLcall("glDepthRange");
 
 
-    if (context->render_offscreen)
-    {
-        GL_EXTCALL(glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE));
-        GL_EXTCALL(glViewportIndexedf(0, vp.x + pixel_center_offset, vp.y + pixel_center_offset,
-                vp.width, vp.height));
-    }
-    else
-    {
-        GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE));
-        GL_EXTCALL(glViewportIndexedf(0, vp.x + pixel_center_offset,
-                (height - (vp.y + vp.height)) + pixel_center_offset, vp.width, vp.height));
-    }
+    GL_EXTCALL(glClipControl(context->render_offscreen ? GL_UPPER_LEFT : GL_LOWER_LEFT, GL_ZERO_TO_ONE));
+    GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height));
     checkGLcall("setting clip space and viewport");
 }
 
     checkGLcall("setting clip space and viewport");
 }
 
@@ -5016,6 +5126,7 @@ const struct StateEntryTemplate misc_state_template[] =
     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_BLENDOPALPHA),              { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_BLENDOPALPHA),              { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
+    { STATE_BLEND,                                        { STATE_BLEND,                                        state_blend_object  }, WINED3D_GL_EXT_NONE             },
     { STATE_STREAMSRC,                                    { STATE_STREAMSRC,                                    streamsrc           }, WINED3D_GL_EXT_NONE             },
     { STATE_VDECL,                                        { STATE_VDECL,                                        vdecl_miscpart      }, WINED3D_GL_EXT_NONE             },
     { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface_cc        }, ARB_CLIP_CONTROL                },
     { STATE_STREAMSRC,                                    { STATE_STREAMSRC,                                    streamsrc           }, WINED3D_GL_EXT_NONE             },
     { STATE_VDECL,                                        { STATE_VDECL,                                        vdecl_miscpart      }, WINED3D_GL_EXT_NONE             },
     { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface_cc        }, ARB_CLIP_CONTROL                },
@@ -5154,22 +5265,33 @@ const struct StateEntryTemplate misc_state_template[] =
     { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      state_msaa_w        }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           state_multisampmask }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         state_debug_monitor }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      state_msaa_w        }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           state_multisampmask }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         state_debug_monitor }, WINED3D_GL_EXT_NONE             },
-    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite  }, EXT_DRAW_BUFFERS2               },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite_i  }, EXT_DRAW_BUFFERS2               },
     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite    }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         state_colorwrite_i  }, EXT_DRAW_BUFFERS2               },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         state_colorwrite_i  }, EXT_DRAW_BUFFERS2               },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         state_colorwrite_i  }, EXT_DRAW_BUFFERS2               },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4),         state_colorwrite_i  }, EXT_DRAW_BUFFERS2               },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5),         state_colorwrite_i  }, EXT_DRAW_BUFFERS2               },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6),         state_colorwrite_i  }, EXT_DRAW_BUFFERS2               },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7),         state_colorwrite_i  }, EXT_DRAW_BUFFERS2               },
+    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop       }, WINED3D_GL_BLEND_EQUATION       },
     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop_w     }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         state_scissor       }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS),       { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop       }, WINED3D_GL_BLEND_EQUATION       },
     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop_w     }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         state_scissor       }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS),       { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 NULL                }, WINED3D_GL_EXT_NONE             },
-    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         state_colorwrite1   }, EXT_DRAW_BUFFERS2               },
-    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
-    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         state_colorwrite2   }, EXT_DRAW_BUFFERS2               },
-    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
-    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         state_colorwrite3   }, EXT_DRAW_BUFFERS2               },
-    { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor   }, EXT_BLEND_COLOR                 },
     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor_w }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 state_depthbias     }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor   }, EXT_BLEND_COLOR                 },
     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor_w }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 state_depthbias     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_DEPTHBIASCLAMP),            { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  state_zvisible      }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  state_zvisible      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3D_RS_DEPTHCLIP),                 { STATE_RENDER(WINED3D_RS_DEPTHCLIP),                 state_depthclip     }, ARB_DEPTH_CLAMP                 },
+    { STATE_RENDER(WINED3D_RS_DEPTHCLIP),                 { STATE_RENDER(WINED3D_RS_DEPTHCLIP),                 state_depthclip_w   }, WINED3D_GL_EXT_NONE             },
     /* Samplers */
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }, WINED3D_GL_EXT_NONE             },
     /* Samplers */
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }, WINED3D_GL_EXT_NONE             },
@@ -5965,6 +6087,7 @@ static void validate_state_table(struct StateEntry *state_table)
         STATE_FRAMEBUFFER,
         STATE_POINT_ENABLE,
         STATE_COLOR_KEY,
         STATE_FRAMEBUFFER,
         STATE_POINT_ENABLE,
         STATE_COLOR_KEY,
+        STATE_BLEND,
     };
     unsigned int i, current;
 
     };
     unsigned int i, current;
 
@@ -6076,7 +6199,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
                     break;
                 case 1:
                     StateTable[cur[i].state].apply = multistate_apply_2;
                     break;
                 case 1:
                     StateTable[cur[i].state].apply = multistate_apply_2;
-                    if (!(dev_multistate_funcs[cur[i].state] = wined3d_calloc(2, sizeof(**dev_multistate_funcs))))
+                    if (!(dev_multistate_funcs[cur[i].state] = heap_calloc(2, sizeof(**dev_multistate_funcs))))
                         goto out_of_mem;
 
                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
                         goto out_of_mem;
 
                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
@@ -6084,13 +6207,9 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
                     break;
                 case 2:
                     StateTable[cur[i].state].apply = multistate_apply_3;
                     break;
                 case 2:
                     StateTable[cur[i].state].apply = multistate_apply_3;
-                    funcs_array = HeapReAlloc(GetProcessHeap(),
-                                              0,
-                                              dev_multistate_funcs[cur[i].state],
-                                              sizeof(**dev_multistate_funcs) * 3);
-                    if (!funcs_array) {
+                    if (!(funcs_array = heap_realloc(dev_multistate_funcs[cur[i].state],
+                            sizeof(**dev_multistate_funcs) * 3)))
                         goto out_of_mem;
                         goto out_of_mem;
-                    }
 
                     dev_multistate_funcs[cur[i].state] = funcs_array;
                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
 
                     dev_multistate_funcs[cur[i].state] = funcs_array;
                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
@@ -6116,8 +6235,9 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
     return WINED3D_OK;
 
 out_of_mem:
     return WINED3D_OK;
 
 out_of_mem:
-    for (i = 0; i <= STATE_HIGHEST; ++i) {
-        HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
+    for (i = 0; i <= STATE_HIGHEST; ++i)
+    {
+        heap_free(dev_multistate_funcs[i]);
     }
 
     memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
     }
 
     memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
index 4e1006c..c9b3527 100644 (file)
@@ -22,6 +22,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -43,6 +45,10 @@ static const DWORD pixel_states_render[] =
     WINED3D_RS_COLORWRITEENABLE1,
     WINED3D_RS_COLORWRITEENABLE2,
     WINED3D_RS_COLORWRITEENABLE3,
     WINED3D_RS_COLORWRITEENABLE1,
     WINED3D_RS_COLORWRITEENABLE2,
     WINED3D_RS_COLORWRITEENABLE3,
+    WINED3D_RS_COLORWRITEENABLE4,
+    WINED3D_RS_COLORWRITEENABLE5,
+    WINED3D_RS_COLORWRITEENABLE6,
+    WINED3D_RS_COLORWRITEENABLE7,
     WINED3D_RS_DEPTHBIAS,
     WINED3D_RS_DESTBLEND,
     WINED3D_RS_DESTBLENDALPHA,
     WINED3D_RS_DEPTHBIAS,
     WINED3D_RS_DESTBLEND,
     WINED3D_RS_DESTBLENDALPHA,
@@ -88,6 +94,7 @@ static const DWORD pixel_states_render[] =
     WINED3D_RS_ZENABLE,
     WINED3D_RS_ZFUNC,
     WINED3D_RS_ZWRITEENABLE,
     WINED3D_RS_ZENABLE,
     WINED3D_RS_ZFUNC,
     WINED3D_RS_ZWRITEENABLE,
+    WINED3D_RS_DEPTHCLIP,
 };
 
 static const DWORD pixel_states_texture[] =
 };
 
 static const DWORD pixel_states_texture[] =
@@ -402,7 +409,7 @@ static void stateblock_init_lights(struct wined3d_stateblock *stateblock, struct
 
         LIST_FOR_EACH_ENTRY(src_light, &light_map[i], struct wined3d_light_info, entry)
         {
 
         LIST_FOR_EACH_ENTRY(src_light, &light_map[i], struct wined3d_light_info, entry)
         {
-            struct wined3d_light_info *dst_light = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_light));
+            struct wined3d_light_info *dst_light = heap_alloc(sizeof(*dst_light));
 
             *dst_light = *src_light;
             list_add_tail(&stateblock->state.light_map[i], &dst_light->entry);
 
             *dst_light = *src_light;
             list_add_tail(&stateblock->state.light_map[i], &dst_light->entry);
@@ -537,7 +544,7 @@ void state_cleanup(struct wined3d_state *state)
         {
             struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry);
             list_remove(&light->entry);
         {
             struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry);
             list_remove(&light->entry);
-            HeapFree(GetProcessHeap(), 0, light);
+            heap_free(light);
         }
     }
 }
         }
     }
 }
@@ -551,7 +558,7 @@ ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock)
     if (!refcount)
     {
         state_cleanup(&stateblock->state);
     if (!refcount)
     {
         state_cleanup(&stateblock->state);
-        HeapFree(GetProcessHeap(), 0, stateblock);
+        heap_free(stateblock);
     }
 
     return refcount;
     }
 
     return refcount;
@@ -1209,7 +1216,6 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
     tmpfloat.f = gl_info->limits.pointsize_max;
     state->render_states[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d;
     state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE;
     tmpfloat.f = gl_info->limits.pointsize_max;
     state->render_states[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d;
     state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE;
-    state->render_states[WINED3D_RS_COLORWRITEENABLE] = 0x0000000f;
     tmpfloat.f = 0.0f;
     state->render_states[WINED3D_RS_TWEENFACTOR] = tmpfloat.d;
     state->render_states[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD;
     tmpfloat.f = 0.0f;
     state->render_states[WINED3D_RS_TWEENFACTOR] = tmpfloat.d;
     state->render_states[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD;
@@ -1235,12 +1241,12 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
     state->render_states[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
     state->render_states[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
     state->render_states[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS;
     state->render_states[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
     state->render_states[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
     state->render_states[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS;
-    state->render_states[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f;
-    state->render_states[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f;
-    state->render_states[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f;
     state->render_states[WINED3D_RS_BLENDFACTOR] = 0xffffffff;
     state->render_states[WINED3D_RS_SRGBWRITEENABLE] = 0;
     state->render_states[WINED3D_RS_DEPTHBIAS] = 0;
     state->render_states[WINED3D_RS_BLENDFACTOR] = 0xffffffff;
     state->render_states[WINED3D_RS_SRGBWRITEENABLE] = 0;
     state->render_states[WINED3D_RS_DEPTHBIAS] = 0;
+    tmpfloat.f = 0.0f;
+    state->render_states[WINED3D_RS_DEPTHBIASCLAMP] = tmpfloat.d;
+    state->render_states[WINED3D_RS_DEPTHCLIP] = TRUE;
     state->render_states[WINED3D_RS_WRAP8] = 0;
     state->render_states[WINED3D_RS_WRAP9] = 0;
     state->render_states[WINED3D_RS_WRAP10] = 0;
     state->render_states[WINED3D_RS_WRAP8] = 0;
     state->render_states[WINED3D_RS_WRAP9] = 0;
     state->render_states[WINED3D_RS_WRAP10] = 0;
@@ -1253,6 +1259,8 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
     state->render_states[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE;
     state->render_states[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO;
     state->render_states[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD;
     state->render_states[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE;
     state->render_states[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO;
     state->render_states[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD;
+    for (i = 0; i < MAX_RENDER_TARGETS; ++i)
+        state->render_states[WINED3D_RS_COLORWRITE(i)] = 0x0000000f;
 
     /* Texture Stage States - Put directly into state block, we will call function below */
     for (i = 0; i < MAX_TEXTURES; ++i)
 
     /* Texture Stage States - Put directly into state block, we will call function below */
     for (i = 0; i < MAX_TEXTURES; ++i)
@@ -1370,15 +1378,14 @@ HRESULT CDECL wined3d_stateblock_create(struct wined3d_device *device,
     TRACE("device %p, type %#x, stateblock %p.\n",
             device, type, stateblock);
 
     TRACE("device %p, type %#x, stateblock %p.\n",
             device, type, stateblock);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = stateblock_init(object, device, type);
     if (FAILED(hr))
     {
         WARN("Failed to initialize stateblock, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = stateblock_init(object, device, type);
     if (FAILED(hr))
     {
         WARN("Failed to initialize stateblock, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
index e4037ab..ae32235 100644 (file)
@@ -26,6 +26,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -58,10 +60,19 @@ static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float
     f->b = ((r->bottom * 2.0f) / h) - 1.0f;
 }
 
     f->b = ((r->bottom * 2.0f) / h) - 1.0f;
 }
 
-static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLsizei h, struct blt_info *info)
+static void texture2d_get_blt_info(const struct wined3d_texture *texture,
+        unsigned int sub_resource_idx, const RECT *rect, struct blt_info *info)
 {
     struct wined3d_vec3 *coords = info->texcoords;
     struct float_rect f;
 {
     struct wined3d_vec3 *coords = info->texcoords;
     struct float_rect f;
+    unsigned int level;
+    GLenum target;
+    GLsizei w, h;
+
+    level = sub_resource_idx % texture->level_count;
+    w = wined3d_texture_get_level_pow2_width(texture, level);
+    h = wined3d_texture_get_level_pow2_height(texture, level);
+    target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
 
     switch (target)
     {
 
     switch (target)
     {
@@ -174,16 +185,14 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
-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)
+void draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect,
+        enum wined3d_texture_filter_type filter)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_texture *texture = src_surface->container;
     struct blt_info info;
 
     struct blt_info info;
 
-    surface_get_blt_info(src_surface->texture_target, src_rect,
-            wined3d_texture_get_level_pow2_width(texture, src_surface->texture_level),
-            wined3d_texture_get_level_pow2_height(texture, src_surface->texture_level), &info);
+    texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info);
 
     gl_info->gl_ops.gl.p_glEnable(info.bind_target);
     checkGLcall("glEnable(bind_target)");
 
     gl_info->gl_ops.gl.p_glEnable(info.bind_target);
     checkGLcall("glEnable(bind_target)");
@@ -237,14 +246,14 @@ static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
     masks[2] = ((1u << format->blue_size) - 1) << format->blue_offset;
 }
 
     masks[2] = ((1u << format->blue_size) - 1) << format->blue_offset;
 }
 
-static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r)
+static BOOL texture2d_is_full_rect(const struct wined3d_texture *texture, unsigned int level, const RECT *r)
 {
     unsigned int t;
 
 {
     unsigned int t;
 
-    t = wined3d_texture_get_level_width(surface->container, surface->texture_level);
+    t = wined3d_texture_get_level_width(texture, level);
     if ((r->left && r->right) || abs(r->right - r->left) != t)
         return FALSE;
     if ((r->left && r->right) || abs(r->right - r->left) != t)
         return FALSE;
-    t = wined3d_texture_get_level_height(surface->container, surface->texture_level);
+    t = wined3d_texture_get_level_height(texture, level);
     if ((r->top && r->bottom) || abs(r->bottom - r->top) != t)
         return FALSE;
     return TRUE;
     if ((r->top && r->bottom) || abs(r->bottom - r->top) != t)
         return FALSE;
     return TRUE;
@@ -304,7 +313,7 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device,
     /* Make sure the locations are up-to-date. Loading the destination
      * surface isn't required if the entire surface is overwritten. */
     wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location);
     /* Make sure the locations are up-to-date. Loading the destination
      * surface isn't required if the entire surface is overwritten. */
     wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location);
-    if (!surface_is_full_rect(dst_surface, dst_rect))
+    if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, dst_rect))
         wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location);
     else
         wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location);
         wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location);
     else
         wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location);
@@ -348,6 +357,15 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device,
     context_release(context);
 }
 
     context_release(context);
 }
 
+static BOOL is_multisample_location(const struct wined3d_texture *texture, DWORD location)
+{
+    if (location == WINED3D_LOCATION_RB_MULTISAMPLE)
+        return TRUE;
+    if (location != WINED3D_LOCATION_TEXTURE_RGB && location != WINED3D_LOCATION_TEXTURE_SRGB)
+        return FALSE;
+    return texture->target == GL_TEXTURE_2D_MULTISAMPLE || texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+}
+
 /* Blit between surface locations. Onscreen on different swapchains is not supported.
  * Depth / stencil is not supported. Context activation is done by the caller. */
 static void surface_blt_fbo(const struct wined3d_device *device,
 /* Blit between surface locations. Onscreen on different swapchains is not supported.
  * Depth / stencil is not supported. Context activation is done by the caller. */
 static void surface_blt_fbo(const struct wined3d_device *device,
@@ -365,6 +383,7 @@ static void surface_blt_fbo(const struct wined3d_device *device,
     RECT src_rect, dst_rect;
     GLenum gl_filter;
     GLenum buffer;
     RECT src_rect, dst_rect;
     GLenum gl_filter;
     GLenum buffer;
+    int i;
 
     TRACE("device %p, filter %s,\n", device, debug_d3dtexturefiltertype(filter));
     TRACE("src_surface %p, src_location %s, src_rect %s,\n",
 
     TRACE("device %p, filter %s,\n", device, debug_d3dtexturefiltertype(filter));
     TRACE("src_surface %p, src_location %s, src_rect %s,\n",
@@ -390,7 +409,7 @@ static void surface_blt_fbo(const struct wined3d_device *device,
     }
 
     /* Resolve the source surface first if needed. */
     }
 
     /* Resolve the source surface first if needed. */
-    if (src_location == WINED3D_LOCATION_RB_MULTISAMPLE
+    if (is_multisample_location(src_texture, src_location)
             && (src_texture->resource.format->id != dst_texture->resource.format->id
                 || abs(src_rect.bottom - src_rect.top) != abs(dst_rect.bottom - dst_rect.top)
                 || abs(src_rect.right - src_rect.left) != abs(dst_rect.right - dst_rect.left)))
             && (src_texture->resource.format->id != dst_texture->resource.format->id
                 || abs(src_rect.bottom - src_rect.top) != abs(dst_rect.bottom - dst_rect.top)
                 || abs(src_rect.right - src_rect.left) != abs(dst_rect.right - dst_rect.left)))
@@ -401,7 +420,7 @@ static void surface_blt_fbo(const struct wined3d_device *device,
      * in fact harmful if we're being called by surface_load_location() with
      * the purpose of loading the destination surface.) */
     wined3d_texture_load_location(src_texture, src_sub_resource_idx, old_ctx, src_location);
      * in fact harmful if we're being called by surface_load_location() with
      * the purpose of loading the destination surface.) */
     wined3d_texture_load_location(src_texture, src_sub_resource_idx, old_ctx, src_location);
-    if (!surface_is_full_rect(dst_surface, &dst_rect))
+    if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, &dst_rect))
         wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location);
     else
         wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location);
         wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location);
     else
         wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location);
@@ -462,10 +481,8 @@ static void surface_blt_fbo(const struct wined3d_device *device,
     context_invalidate_state(context, STATE_FRAMEBUFFER);
 
     gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
     context_invalidate_state(context, STATE_FRAMEBUFFER);
 
     gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
+    for (i = 0; i < MAX_RENDER_TARGETS; ++i)
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
 
     gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
 
     gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
@@ -482,25 +499,28 @@ static void surface_blt_fbo(const struct wined3d_device *device,
         context_restore(context, restore_rt);
 }
 
         context_restore(context, restore_rt);
 }
 
-static BOOL fbo_blitter_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
-        DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, DWORD src_location,
-        DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format, DWORD dst_location)
+static BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_gl_info *gl_info,
+        const struct wined3d_resource *src_resource, DWORD src_location,
+        const struct wined3d_resource *dst_resource, DWORD dst_location)
 {
 {
+    const struct wined3d_format *src_format = src_resource->format;
+    const struct wined3d_format *dst_format = dst_resource->format;
+
     if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer)
         return FALSE;
 
     /* Source and/or destination need to be on the GL side */
     if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer)
         return FALSE;
 
     /* Source and/or destination need to be on the GL side */
-    if (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM)
+    if (!(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU))
         return FALSE;
 
     switch (blit_op)
     {
         case WINED3D_BLIT_OP_COLOR_BLIT:
             if (!((src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
         return FALSE;
 
     switch (blit_op)
     {
         case WINED3D_BLIT_OP_COLOR_BLIT:
             if (!((src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
-                    || (src_usage & WINED3DUSAGE_RENDERTARGET)))
+                    || (src_resource->usage & WINED3DUSAGE_RENDERTARGET)))
                 return FALSE;
             if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
                 return FALSE;
             if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
-                    || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
+                    || (dst_resource->usage & WINED3DUSAGE_RENDERTARGET)))
                 return FALSE;
             if ((src_format->id != dst_format->id || dst_location == WINED3D_LOCATION_DRAWABLE)
                     && (!is_identity_fixup(src_format->color_fixup) || !is_identity_fixup(dst_format->color_fixup)))
                 return FALSE;
             if ((src_format->id != dst_format->id || dst_location == WINED3D_LOCATION_DRAWABLE)
                     && (!is_identity_fixup(src_format->color_fixup) || !is_identity_fixup(dst_format->color_fixup)))
@@ -541,6 +561,8 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
     unsigned int src_row_pitch, src_slice_pitch;
     struct wined3d_bo_address data;
     BYTE *temporary_mem = NULL;
     unsigned int src_row_pitch, src_slice_pitch;
     struct wined3d_bo_address data;
     BYTE *temporary_mem = NULL;
+    unsigned int level;
+    GLenum target;
     void *mem;
 
     /* Only support read back of converted P8 surfaces. */
     void *mem;
 
     /* Only support read back of converted P8 surfaces. */
@@ -551,8 +573,10 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
     }
 
     sub_resource = &texture->sub_resources[sub_resource_idx];
     }
 
     sub_resource = &texture->sub_resources[sub_resource_idx];
+    target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+    level = sub_resource_idx % texture->level_count;
 
 
-    if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
+    if (target == GL_TEXTURE_2D_ARRAY)
     {
         if (format->download)
         {
     {
         if (format->download)
         {
@@ -566,7 +590,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
 
         WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n");
 
 
         WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n");
 
-        if (!(temporary_mem = wined3d_calloc(texture->layer_count, sub_resource->size)))
+        if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size)))
         {
             ERR("Out of memory.\n");
             return;
         {
             ERR("Out of memory.\n");
             return;
@@ -583,12 +607,12 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
             return;
         }
 
             return;
         }
 
-        wined3d_texture_get_pitch(texture, surface->texture_level, &dst_row_pitch, &dst_slice_pitch);
+        wined3d_texture_get_pitch(texture, level, &dst_row_pitch, &dst_slice_pitch);
         wined3d_format_calculate_pitch(format, texture->resource.device->surface_alignment,
         wined3d_format_calculate_pitch(format, texture->resource.device->surface_alignment,
-                wined3d_texture_get_level_pow2_width(texture, surface->texture_level),
-                wined3d_texture_get_level_pow2_height(texture, surface->texture_level),
+                wined3d_texture_get_level_pow2_width(texture, level),
+                wined3d_texture_get_level_pow2_height(texture, level),
                 &src_row_pitch, &src_slice_pitch);
                 &src_row_pitch, &src_slice_pitch);
-        if (!(temporary_mem = HeapAlloc(GetProcessHeap(), 0, src_slice_pitch)))
+        if (!(temporary_mem = heap_alloc(src_slice_pitch)))
         {
             ERR("Out of memory.\n");
             return;
         {
             ERR("Out of memory.\n");
             return;
@@ -611,13 +635,13 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
 
         f = *format;
         f.byte_count = format->conv_byte_count;
 
         f = *format;
         f.byte_count = format->conv_byte_count;
-        wined3d_texture_get_pitch(texture, surface->texture_level, &dst_row_pitch, &dst_slice_pitch);
+        wined3d_texture_get_pitch(texture, level, &dst_row_pitch, &dst_slice_pitch);
         wined3d_format_calculate_pitch(&f, texture->resource.device->surface_alignment,
         wined3d_format_calculate_pitch(&f, texture->resource.device->surface_alignment,
-                wined3d_texture_get_level_width(texture, surface->texture_level),
-                wined3d_texture_get_level_height(texture, surface->texture_level),
+                wined3d_texture_get_level_width(texture, level),
+                wined3d_texture_get_level_height(texture, level),
                 &src_row_pitch, &src_slice_pitch);
 
                 &src_row_pitch, &src_slice_pitch);
 
-        if (!(temporary_mem = HeapAlloc(GetProcessHeap(), 0, src_slice_pitch)))
+        if (!(temporary_mem = heap_alloc(src_slice_pitch)))
         {
             ERR("Failed to allocate memory.\n");
             return;
         {
             ERR("Failed to allocate memory.\n");
             return;
@@ -642,26 +666,25 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
     if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED)
     {
         TRACE("Downloading compressed surface %p, level %u, format %#x, type %#x, data %p.\n",
     if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED)
     {
         TRACE("Downloading compressed surface %p, level %u, format %#x, type %#x, data %p.\n",
-                surface, surface->texture_level, format->glFormat, format->glType, mem);
+                surface, level, format->glFormat, format->glType, mem);
 
 
-        GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, surface->texture_level, mem));
+        GL_EXTCALL(glGetCompressedTexImage(target, level, mem));
         checkGLcall("glGetCompressedTexImage");
     }
     else
     {
         TRACE("Downloading surface %p, level %u, format %#x, type %#x, data %p.\n",
         checkGLcall("glGetCompressedTexImage");
     }
     else
     {
         TRACE("Downloading surface %p, level %u, format %#x, type %#x, data %p.\n",
-                surface, surface->texture_level, format->glFormat, format->glType, mem);
+                surface, level, format->glFormat, format->glType, mem);
 
 
-        gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
-                format->glFormat, format->glType, mem);
+        gl_info->gl_ops.gl.p_glGetTexImage(target, level, format->glFormat, format->glType, mem);
         checkGLcall("glGetTexImage");
     }
 
     if (format->download)
     {
         format->download(mem, data.addr, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch,
         checkGLcall("glGetTexImage");
     }
 
     if (format->download)
     {
         format->download(mem, data.addr, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch,
-                wined3d_texture_get_level_width(texture, surface->texture_level),
-                wined3d_texture_get_level_height(texture, surface->texture_level), 1);
+                wined3d_texture_get_level_width(texture, level),
+                wined3d_texture_get_level_height(texture, level), 1);
     }
     else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
     {
     }
     else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
     {
@@ -716,7 +739,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
         src_data = mem;
         dst_data = data.addr;
         TRACE("Repacking the surface data from pitch %u to pitch %u.\n", src_row_pitch, dst_row_pitch);
         src_data = mem;
         dst_data = data.addr;
         TRACE("Repacking the surface data from pitch %u to pitch %u.\n", src_row_pitch, dst_row_pitch);
-        h = wined3d_texture_get_level_height(texture, surface->texture_level);
+        h = wined3d_texture_get_level_height(texture, level);
         for (y = 0; y < h; ++y)
         {
             memcpy(dst_data, src_data, dst_row_pitch);
         for (y = 0; y < h; ++y)
         {
             memcpy(dst_data, src_data, dst_row_pitch);
@@ -726,7 +749,8 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
     }
     else if (temporary_mem)
     {
     }
     else if (temporary_mem)
     {
-        void *src_data = temporary_mem + surface->texture_layer * sub_resource->size;
+        unsigned int layer = sub_resource_idx / texture->level_count;
+        void *src_data = temporary_mem + layer * sub_resource->size;
         if (data.buffer_object)
         {
             GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object));
         if (data.buffer_object)
         {
             GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object));
@@ -746,7 +770,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
         checkGLcall("glBindBuffer");
     }
 
         checkGLcall("glBindBuffer");
     }
 
-    HeapFree(GetProcessHeap(), 0, temporary_mem);
+    heap_free(temporary_mem);
 }
 
 /* This call just uploads data, the caller is responsible for binding the
 }
 
 /* This call just uploads data, the caller is responsible for binding the
@@ -760,6 +784,8 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
     struct wined3d_texture *texture = surface->container;
     UINT update_w = src_rect->right - src_rect->left;
     UINT update_h = src_rect->bottom - src_rect->top;
     struct wined3d_texture *texture = surface->container;
     UINT update_w = src_rect->right - src_rect->left;
     UINT update_h = src_rect->bottom - src_rect->top;
+    unsigned int level, layer;
+    GLenum target;
 
     TRACE("surface %p, gl_info %p, format %s, src_rect %s, src_pitch %u, dst_point %s, srgb %#x, data {%#x:%p}.\n",
             surface, gl_info, debug_d3dformat(format->id), wine_dbgstr_rect(src_rect), src_pitch,
 
     TRACE("surface %p, gl_info %p, format %s, src_rect %s, src_pitch %u, dst_point %s, srgb %#x, data {%#x:%p}.\n",
             surface, gl_info, debug_d3dformat(format->id), wine_dbgstr_rect(src_rect), src_pitch,
@@ -783,6 +809,10 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
         checkGLcall("glBindBuffer");
     }
 
         checkGLcall("glBindBuffer");
     }
 
+    target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+    level = sub_resource_idx % texture->level_count;
+    layer = sub_resource_idx / texture->level_count;
+
     if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
     {
         unsigned int dst_row_pitch, dst_slice_pitch;
     if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
     {
         unsigned int dst_row_pitch, dst_slice_pitch;
@@ -804,22 +834,20 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
 
         TRACE("Uploading compressed data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
                 "format %#x, image_size %#x, addr %p.\n",
 
         TRACE("Uploading compressed data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
                 "format %#x, image_size %#x, addr %p.\n",
-                surface->texture_target, surface->texture_level, surface->texture_layer,
-                dst_point->x, dst_point->y, update_w, update_h, internal, dst_slice_pitch, addr);
+                target, level, layer, dst_point->x, dst_point->y,
+                update_w, update_h, internal, dst_slice_pitch, addr);
 
         if (dst_row_pitch == src_pitch)
         {
 
         if (dst_row_pitch == src_pitch)
         {
-            if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
+            if (target == GL_TEXTURE_2D_ARRAY)
             {
             {
-                GL_EXTCALL(glCompressedTexSubImage3D(surface->texture_target, surface->texture_level,
-                            dst_point->x, dst_point->y, surface->texture_layer, update_w, update_h, 1,
-                            internal, dst_slice_pitch, addr));
+                GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_point->x, dst_point->y,
+                        layer, update_w, update_h, 1, internal, dst_slice_pitch, addr));
             }
             else
             {
             }
             else
             {
-                GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level,
-                            dst_point->x, dst_point->y, update_w, update_h,
-                            internal, dst_slice_pitch, addr));
+                GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_point->x, dst_point->y,
+                        update_w, update_h, internal, dst_slice_pitch, addr));
             }
         }
         else
             }
         }
         else
@@ -831,16 +859,15 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
              * can't use the unpack row length like for glTexSubImage2D. */
             for (row = 0, y = dst_point->y; row < row_count; ++row)
             {
              * can't use the unpack row length like for glTexSubImage2D. */
             for (row = 0, y = dst_point->y; row < row_count; ++row)
             {
-                if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
+                if (target == GL_TEXTURE_2D_ARRAY)
                 {
                 {
-                    GL_EXTCALL(glCompressedTexSubImage3D(surface->texture_target, surface->texture_level,
-                            dst_point->x, y, surface->texture_layer, update_w, format->block_height, 1,
-                            internal, dst_row_pitch, addr));
+                    GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_point->x, y,
+                            layer, update_w, format->block_height, 1, internal, dst_row_pitch, addr));
                 }
                 else
                 {
                 }
                 else
                 {
-                    GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level,
-                            dst_point->x, y, update_w, format->block_height, internal, dst_row_pitch, addr));
+                    GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_point->x, y,
+                            update_w, format->block_height, internal, dst_row_pitch, addr));
                 }
 
                 y += format->block_height;
                 }
 
                 y += format->block_height;
@@ -858,20 +885,19 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
 
         TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
                 "format %#x, type %#x, addr %p.\n",
 
         TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
                 "format %#x, type %#x, addr %p.\n",
-                surface->texture_target, surface->texture_level, surface->texture_layer,
-                dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr);
+                target, level, layer, dst_point->x, dst_point->y,
+                update_w, update_h, format->glFormat, format->glType, addr);
 
         gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count);
 
         gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count);
-        if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
+        if (target == GL_TEXTURE_2D_ARRAY)
         {
         {
-            GL_EXTCALL(glTexSubImage3D(surface->texture_target, surface->texture_level,
-                    dst_point->x, dst_point->y, surface->texture_layer, update_w, update_h, 1,
-                    format->glFormat, format->glType, addr));
+            GL_EXTCALL(glTexSubImage3D(target, level, dst_point->x, dst_point->y,
+                    layer, update_w, update_h, 1, format->glFormat, format->glType, addr));
         }
         else
         {
         }
         else
         {
-            gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, surface->texture_level,
-                    dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr);
+            gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_point->x, dst_point->y,
+                    update_w, update_h, format->glFormat, format->glType, addr);
         }
         gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
         checkGLcall("Upload surface data");
         }
         gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
         checkGLcall("Upload surface data");
@@ -907,6 +933,7 @@ static HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface,
     struct wined3d_texture *dst_texture = dst_surface->container;
     unsigned int src_row_pitch, src_slice_pitch;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_texture *dst_texture = dst_surface->container;
     unsigned int src_row_pitch, src_slice_pitch;
     const struct wined3d_gl_info *gl_info;
+    unsigned int src_level, dst_level;
     struct wined3d_context *context;
     struct wined3d_bo_address data;
     UINT update_w, update_h;
     struct wined3d_context *context;
     struct wined3d_bo_address data;
     UINT update_w, update_h;
@@ -923,16 +950,18 @@ static HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface,
      * just to overwrite them again. */
     update_w = src_rect->right - src_rect->left;
     update_h = src_rect->bottom - src_rect->top;
      * just to overwrite them again. */
     update_w = src_rect->right - src_rect->left;
     update_h = src_rect->bottom - src_rect->top;
-    if (update_w == wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level)
-            && update_h == wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level))
+    dst_level = dst_sub_resource_idx % dst_texture->level_count;
+    if (update_w == wined3d_texture_get_level_width(dst_texture, dst_level)
+            && update_h == wined3d_texture_get_level_height(dst_texture, dst_level))
         wined3d_texture_prepare_texture(dst_texture, context, FALSE);
     else
         wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
 
         wined3d_texture_prepare_texture(dst_texture, context, FALSE);
     else
         wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
 
+    src_level = src_sub_resource_idx % src_texture->level_count;
     wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data,
             src_texture->sub_resources[src_sub_resource_idx].locations);
     wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data,
             src_texture->sub_resources[src_sub_resource_idx].locations);
-    wined3d_texture_get_pitch(src_texture, src_surface->texture_level, &src_row_pitch, &src_slice_pitch);
+    wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch);
 
     wined3d_surface_upload_data(dst_surface, gl_info, src_texture->resource.format, src_rect,
             src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data));
 
     wined3d_surface_upload_data(dst_surface, gl_info, src_texture->resource.format, src_rect,
             src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data));
@@ -951,36 +980,42 @@ static HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface,
 /* Context activation is done by the caller. */
 void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt)
 {
 /* Context activation is done by the caller. */
 void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt)
 {
-    const struct wined3d_gl_info *gl_info = &surface->container->resource.device->adapter->gl_info;
+    unsigned int sub_resource_idx, width, height, level;
     struct wined3d_renderbuffer_entry *entry;
     struct wined3d_renderbuffer_entry *entry;
+    const struct wined3d_texture *texture;
+    const struct wined3d_gl_info *gl_info;
     unsigned int src_width, src_height;
     unsigned int src_width, src_height;
-    unsigned int width, height;
     GLuint renderbuffer = 0;
 
     GLuint renderbuffer = 0;
 
+    texture = surface->container;
+    gl_info = &texture->resource.device->adapter->gl_info;
+    sub_resource_idx = surface_get_sub_resource_idx(surface);
+    level = sub_resource_idx % texture->level_count;
+
     if (rt && rt->resource->format->id != WINED3DFMT_NULL)
     {
     if (rt && rt->resource->format->id != WINED3DFMT_NULL)
     {
-        struct wined3d_texture *texture;
-        unsigned int level;
+        struct wined3d_texture *rt_texture;
+        unsigned int rt_level;
 
         if (rt->resource->type == WINED3D_RTYPE_BUFFER)
         {
             FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type));
             return;
         }
 
         if (rt->resource->type == WINED3D_RTYPE_BUFFER)
         {
             FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type));
             return;
         }
-        texture = wined3d_texture_from_resource(rt->resource);
-        level = rt->sub_resource_idx % texture->level_count;
+        rt_texture = wined3d_texture_from_resource(rt->resource);
+        rt_level = rt->sub_resource_idx % rt_texture->level_count;
 
 
-        width = wined3d_texture_get_level_pow2_width(texture, level);
-        height = wined3d_texture_get_level_pow2_height(texture, level);
+        width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level);
+        height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level);
     }
     else
     {
     }
     else
     {
-        width = wined3d_texture_get_level_pow2_width(surface->container, surface->texture_level);
-        height = wined3d_texture_get_level_pow2_height(surface->container, surface->texture_level);
+        width = wined3d_texture_get_level_pow2_width(texture, level);
+        height = wined3d_texture_get_level_pow2_height(texture, level);
     }
 
     }
 
-    src_width = wined3d_texture_get_level_pow2_width(surface->container, surface->texture_level);
-    src_height = wined3d_texture_get_level_pow2_height(surface->container, surface->texture_level);
+    src_width = wined3d_texture_get_level_pow2_width(texture, level);
+    src_height = wined3d_texture_get_level_pow2_height(texture, level);
 
     /* A depth stencil smaller than the render target is not valid */
     if (width > src_width || height > src_height) return;
 
     /* A depth stencil smaller than the render target is not valid */
     if (width > src_width || height > src_height) return;
@@ -1009,9 +1044,9 @@ void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const
         gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
         gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
         gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
         gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
         gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
         gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
-                surface->container->resource.format->glInternal, width, height);
+                texture->resource.format->glInternal, width, height);
 
 
-        entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
+        entry = heap_alloc(sizeof(*entry));
         entry->width = width;
         entry->height = height;
         entry->id = renderbuffer;
         entry->width = width;
         entry->height = height;
         entry->id = renderbuffer;
@@ -1255,6 +1290,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;
 struct d3dfmt_converter_desc
 {
     enum wined3d_format_id from, to;
@@ -1271,6 +1426,33 @@ static const struct d3dfmt_converter_desc converters[] =
     {WINED3DFMT_YUY2,           WINED3DFMT_B5G6R5_UNORM,    convert_yuy2_r5g6b5},
 };
 
     {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)
 {
 static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from,
         enum wined3d_format_id to)
 {
@@ -1282,6 +1464,12 @@ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_fo
             return &converters[i];
     }
 
             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;
 }
 
     return NULL;
 }
 
@@ -1315,8 +1503,8 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr
     desc.format = dst_format->id;
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
     desc.format = dst_format->id;
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
-    desc.usage = WINED3DUSAGE_PRIVATE;
-    desc.pool = WINED3D_POOL_SCRATCH;
+    desc.usage = WINED3DUSAGE_SCRATCH | WINED3DUSAGE_PRIVATE;
+    desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
     desc.width = wined3d_texture_get_level_width(src_texture, texture_level);
     desc.height = wined3d_texture_get_level_height(src_texture, texture_level);
     desc.depth = 1;
     desc.width = wined3d_texture_get_level_width(src_texture, texture_level);
     desc.height = wined3d_texture_get_level_height(src_texture, texture_level);
     desc.depth = 1;
@@ -1355,9 +1543,9 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr
         wined3d_texture_get_memory(dst_texture, 0, &dst_data, map_binding);
 
         src = context_map_bo_address(context, &src_data,
         wined3d_texture_get_memory(dst_texture, 0, &dst_data, map_binding);
 
         src = context_map_bo_address(context, &src_data,
-                src_texture->sub_resources[sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0);
+                src_texture->sub_resources[sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
         dst = context_map_bo_address(context,
         dst = context_map_bo_address(context,
-                &dst_data, dst_texture->sub_resources[0].size, GL_PIXEL_UNPACK_BUFFER, 0);
+                &dst_data, dst_texture->sub_resources[0].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_WRITE);
 
         conv->convert(src, dst, src_row_pitch, dst_row_pitch, desc.width, desc.height);
 
 
         conv->convert(src, dst, src_row_pitch, dst_row_pitch, desc.width, desc.height);
 
@@ -1388,21 +1576,21 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr
 }
 
 static void read_from_framebuffer(struct wined3d_surface *surface,
 }
 
 static void read_from_framebuffer(struct wined3d_surface *surface,
-        struct wined3d_context *old_ctx, DWORD dst_location)
+        struct wined3d_context *old_ctx, DWORD src_location, DWORD dst_location)
 {
     unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
     struct wined3d_texture *texture = surface->container;
     struct wined3d_device *device = texture->resource.device;
 {
     unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
     struct wined3d_texture *texture = surface->container;
     struct wined3d_device *device = texture->resource.device;
-    const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context = old_ctx;
     struct wined3d_surface *restore_rt = NULL;
     struct wined3d_context *context = old_ctx;
     struct wined3d_surface *restore_rt = NULL;
+    const struct wined3d_gl_info *gl_info;
     unsigned int row_pitch, slice_pitch;
     unsigned int row_pitch, slice_pitch;
-    unsigned int width, height;
-    BYTE *mem;
-    BYTE *row, *top, *bottom;
-    int i;
-    BOOL srcIsUpsideDown;
+    unsigned int width, height, level;
     struct wined3d_bo_address data;
     struct wined3d_bo_address data;
+    BYTE *row, *top, *bottom;
+    BOOL src_is_upside_down;
+    unsigned int i;
+    BYTE *mem;
 
     wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location);
 
 
     wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location);
 
@@ -1411,21 +1599,30 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
         context = context_acquire(device, texture, sub_resource_idx);
     else
         restore_rt = NULL;
         context = context_acquire(device, texture, sub_resource_idx);
     else
         restore_rt = NULL;
-
-    context_apply_blit_state(context, device);
     gl_info = context->gl_info;
 
     gl_info = context->gl_info;
 
+    if (src_location != texture->resource.draw_binding)
+    {
+        context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, surface, NULL, src_location);
+        context_check_fbo_status(context, GL_READ_FRAMEBUFFER);
+        context_invalidate_state(context, STATE_FRAMEBUFFER);
+    }
+    else
+    {
+        context_apply_blit_state(context, device);
+    }
+
     /* Select the correct read buffer, and give some debug output.
     /* Select the correct read buffer, and give some debug output.
-     * There is no need to keep track of the current read buffer or reset it, every part of the code
-     * that reads sets the read buffer as desired.
+     * There is no need to keep track of the current read buffer or reset it,
+     * every part of the code that reads sets the read buffer as desired.
      */
      */
-    if (wined3d_resource_is_offscreen(&texture->resource))
+    if (src_location != WINED3D_LOCATION_DRAWABLE || wined3d_resource_is_offscreen(&texture->resource))
     {
         /* Mapping the primary render target which is not on a swapchain.
          * Read from the back buffer. */
         TRACE("Mapping offscreen render target.\n");
         gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context));
     {
         /* Mapping the primary render target which is not on a swapchain.
          * Read from the back buffer. */
         TRACE("Mapping offscreen render target.\n");
         gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context));
-        srcIsUpsideDown = TRUE;
+        src_is_upside_down = TRUE;
     }
     else
     {
     }
     else
     {
@@ -1433,9 +1630,9 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
         GLenum buffer = wined3d_texture_get_gl_buffer(texture);
         TRACE("Mapping %#x buffer.\n", buffer);
         gl_info->gl_ops.gl.p_glReadBuffer(buffer);
         GLenum buffer = wined3d_texture_get_gl_buffer(texture);
         TRACE("Mapping %#x buffer.\n", buffer);
         gl_info->gl_ops.gl.p_glReadBuffer(buffer);
-        checkGLcall("glReadBuffer");
-        srcIsUpsideDown = FALSE;
+        src_is_upside_down = FALSE;
     }
     }
+    checkGLcall("glReadBuffer");
 
     if (data.buffer_object)
     {
 
     if (data.buffer_object)
     {
@@ -1443,14 +1640,15 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
         checkGLcall("glBindBuffer");
     }
 
         checkGLcall("glBindBuffer");
     }
 
-    wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
+    level = sub_resource_idx % texture->level_count;
+    wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch);
 
     /* Setup pixel store pack state -- to glReadPixels into the correct place */
     gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, row_pitch / texture->resource.format->byte_count);
     checkGLcall("glPixelStorei");
 
 
     /* Setup pixel store pack state -- to glReadPixels into the correct place */
     gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, row_pitch / texture->resource.format->byte_count);
     checkGLcall("glPixelStorei");
 
-    width = wined3d_texture_get_level_width(texture, surface->texture_level);
-    height = wined3d_texture_get_level_height(texture, surface->texture_level);
+    width = wined3d_texture_get_level_width(texture, level);
+    height = wined3d_texture_get_level_height(texture, level);
     gl_info->gl_ops.gl.p_glReadPixels(0, 0, width, height,
             texture->resource.format->glFormat,
             texture->resource.format->glType, data.addr);
     gl_info->gl_ops.gl.p_glReadPixels(0, 0, width, height,
             texture->resource.format->glFormat,
             texture->resource.format->glType, data.addr);
@@ -1460,12 +1658,12 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
     gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, 0);
     checkGLcall("glPixelStorei");
 
     gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, 0);
     checkGLcall("glPixelStorei");
 
-    if (!srcIsUpsideDown)
+    if (!src_is_upside_down)
     {
         /* glReadPixels returns the image upside down, and there is no way to
          * prevent this. Flip the lines in software. */
 
     {
         /* glReadPixels returns the image upside down, and there is no way to
          * prevent this. Flip the lines in software. */
 
-        if (!(row = HeapAlloc(GetProcessHeap(), 0, row_pitch)))
+        if (!(row = heap_alloc(row_pitch)))
             goto error;
 
         if (data.buffer_object)
             goto error;
 
         if (data.buffer_object)
@@ -1486,7 +1684,7 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
             top += row_pitch;
             bottom -= row_pitch;
         }
             top += row_pitch;
             bottom -= row_pitch;
         }
-        HeapFree(GetProcessHeap(), 0, row);
+        heap_free(row);
 
         if (data.buffer_object)
             GL_EXTCALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
 
         if (data.buffer_object)
             GL_EXTCALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
@@ -1511,15 +1709,18 @@ error:
  * switch to a different context and restore the original one before return. */
 void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *old_ctx)
 {
  * switch to a different context and restore the original one before return. */
 void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *old_ctx)
 {
+    unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
     struct wined3d_texture *texture = surface->container;
     struct wined3d_device *device = texture->resource.device;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context = old_ctx;
     struct wined3d_surface *restore_rt = NULL;
     struct wined3d_texture *texture = surface->container;
     struct wined3d_device *device = texture->resource.device;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context = old_ctx;
     struct wined3d_surface *restore_rt = NULL;
+    unsigned int level;
+    GLenum target;
 
     restore_rt = context_get_rt_surface(old_ctx);
     if (restore_rt != surface)
 
     restore_rt = context_get_rt_surface(old_ctx);
     if (restore_rt != surface)
-        context = context_acquire(device, texture, surface_get_sub_resource_idx(surface));
+        context = context_acquire(device, texture, sub_resource_idx);
     else
         restore_rt = NULL;
 
     else
         restore_rt = NULL;
 
@@ -1537,9 +1738,11 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct
         gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(texture));
     checkGLcall("glReadBuffer");
 
         gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(texture));
     checkGLcall("glReadBuffer");
 
-    gl_info->gl_ops.gl.p_glCopyTexSubImage2D(surface->texture_target, surface->texture_level,
-            0, 0, 0, 0, wined3d_texture_get_level_width(texture, surface->texture_level),
-            wined3d_texture_get_level_height(texture, surface->texture_level));
+    level = sub_resource_idx % texture->level_count;
+    target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+    gl_info->gl_ops.gl.p_glCopyTexSubImage2D(target, level, 0, 0, 0, 0,
+            wined3d_texture_get_level_width(texture, level),
+            wined3d_texture_get_level_height(texture, level));
     checkGLcall("glCopyTexSubImage2D");
 
     if (restore_rt)
     checkGLcall("glCopyTexSubImage2D");
 
     if (restore_rt)
@@ -1556,12 +1759,13 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc
     struct wined3d_texture *src_texture = src_surface->container;
     struct wined3d_texture *dst_texture = dst_surface->container;
     struct wined3d_device *device = dst_texture->resource.device;
     struct wined3d_texture *src_texture = src_surface->container;
     struct wined3d_texture *dst_texture = dst_surface->container;
     struct wined3d_device *device = dst_texture->resource.device;
+    unsigned int src_height, src_level, dst_level;
     const struct wined3d_gl_info *gl_info;
     float xrel, yrel;
     struct wined3d_context *context;
     BOOL upsidedown = FALSE;
     RECT dst_rect = *dst_rect_in;
     const struct wined3d_gl_info *gl_info;
     float xrel, yrel;
     struct wined3d_context *context;
     BOOL upsidedown = FALSE;
     RECT dst_rect = *dst_rect_in;
-    unsigned int src_height;
+    GLenum dst_target;
 
     /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
      * glCopyTexSubImage is a bit picky about the parameters we pass to it
 
     /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
      * glCopyTexSubImage is a bit picky about the parameters we pass to it
@@ -1608,13 +1812,17 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc
         ERR("Texture filtering not supported in direct blit\n");
     }
 
         ERR("Texture filtering not supported in direct blit\n");
     }
 
-    src_height = wined3d_texture_get_level_height(src_texture, src_surface->texture_level);
+    src_level = src_sub_resource_idx % src_texture->level_count;
+    dst_level = dst_sub_resource_idx % dst_texture->level_count;
+
+    src_height = wined3d_texture_get_level_height(src_texture, src_level);
+    dst_target = wined3d_texture_get_sub_resource_target(dst_texture, dst_sub_resource_idx);
     if (upsidedown
             && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
             && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
     {
         /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do. */
     if (upsidedown
             && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
             && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
     {
         /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do. */
-        gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+        gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level,
                 dst_rect.left /*xoffset */, dst_rect.top /* y offset */,
                 src_rect->left, src_height - src_rect->bottom,
                 dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
                 dst_rect.left /*xoffset */, dst_rect.top /* y offset */,
                 src_rect->left, src_height - src_rect->bottom,
                 dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
@@ -1639,14 +1847,14 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc
 
                 for (col = dst_rect.left; col < dst_rect.right; ++col)
                 {
 
                 for (col = dst_rect.left; col < dst_rect.right; ++col)
                 {
-                    gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+                    gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level,
                             dst_rect.left + col /* x offset */, row /* y offset */,
                             src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1);
                 }
             }
             else
             {
                             dst_rect.left + col /* x offset */, row /* y offset */,
                             src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1);
                 }
             }
             else
             {
-                gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+                gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level,
                         dst_rect.left /* x offset */, row /* y offset */,
                         src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1);
             }
                         dst_rect.left /* x offset */, row /* y offset */,
                         src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1);
             }
@@ -1666,25 +1874,29 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc
 static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface,
         const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter)
 {
 static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface,
         const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter)
 {
+    unsigned int src_width, src_height, src_pow2_width, src_pow2_height, src_level;
     unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
     unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
     unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
     unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
-    unsigned int src_width, src_height, src_pow2_width, src_pow2_height;
     struct wined3d_texture *src_texture = src_surface->container;
     struct wined3d_texture *dst_texture = dst_surface->container;
     struct wined3d_device *device = dst_texture->resource.device;
     struct wined3d_texture *src_texture = src_surface->container;
     struct wined3d_texture *dst_texture = dst_surface->container;
     struct wined3d_device *device = dst_texture->resource.device;
+    GLenum src_target, dst_target, texture_target;
     GLuint src, backup = 0;
     float left, right, top, bottom; /* Texture coordinates */
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
     GLenum drawBuffer = GL_BACK;
     GLenum offscreen_buffer;
     GLuint src, backup = 0;
     float left, right, top, bottom; /* Texture coordinates */
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
     GLenum drawBuffer = GL_BACK;
     GLenum offscreen_buffer;
-    GLenum texture_target;
     BOOL noBackBufferBackup;
     BOOL src_offscreen;
     BOOL upsidedown = FALSE;
     RECT dst_rect = *dst_rect_in;
 
     TRACE("Using hwstretch blit\n");
     BOOL noBackBufferBackup;
     BOOL src_offscreen;
     BOOL upsidedown = FALSE;
     RECT dst_rect = *dst_rect_in;
 
     TRACE("Using hwstretch blit\n");
+
+    src_target = wined3d_texture_get_sub_resource_target(src_texture, src_sub_resource_idx);
+    dst_target = wined3d_texture_get_sub_resource_target(dst_texture, dst_sub_resource_idx);
+
     /* Activate the Proper context for reading from the source surface, set it up for blitting */
     context = context_acquire(device, src_texture, src_sub_resource_idx);
     gl_info = context->gl_info;
     /* Activate the Proper context for reading from the source surface, set it up for blitting */
     context = context_acquire(device, src_texture, src_sub_resource_idx);
     gl_info = context->gl_info;
@@ -1692,10 +1904,11 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
     wined3d_texture_load(dst_texture, context, FALSE);
 
     offscreen_buffer = context_get_offscreen_gl_buffer(context);
     wined3d_texture_load(dst_texture, context, FALSE);
 
     offscreen_buffer = context_get_offscreen_gl_buffer(context);
-    src_width = wined3d_texture_get_level_width(src_texture, src_surface->texture_level);
-    src_height = wined3d_texture_get_level_height(src_texture, src_surface->texture_level);
-    src_pow2_width = wined3d_texture_get_level_pow2_width(src_texture, src_surface->texture_level);
-    src_pow2_height = wined3d_texture_get_level_pow2_height(src_texture, src_surface->texture_level);
+    src_level = src_sub_resource_idx % src_texture->level_count;
+    src_width = wined3d_texture_get_level_width(src_texture, src_level);
+    src_height = wined3d_texture_get_level_height(src_texture, src_level);
+    src_pow2_width = wined3d_texture_get_level_pow2_width(src_texture, src_level);
+    src_pow2_height = wined3d_texture_get_level_pow2_height(src_texture, src_level);
 
     src_offscreen = wined3d_resource_is_offscreen(&src_texture->resource);
     noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO;
 
     src_offscreen = wined3d_resource_is_offscreen(&src_texture->resource);
     noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO;
@@ -1731,7 +1944,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
         /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
          * we are reading from the back buffer, the backup can be used as source texture
          */
         /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
          * we are reading from the back buffer, the backup can be used as source texture
          */
-        texture_target = src_surface->texture_target;
+        texture_target = src_target;
         context_bind_texture(context, texture_target, src_texture->texture_rgb.name);
         gl_info->gl_ops.gl.p_glEnable(texture_target);
         checkGLcall("glEnable(texture_target)");
         context_bind_texture(context, texture_target, src_texture->texture_rgb.name);
         gl_info->gl_ops.gl.p_glEnable(texture_target);
         checkGLcall("glEnable(texture_target)");
@@ -1859,11 +2072,11 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
     gl_info->gl_ops.gl.p_glEnd();
     checkGLcall("glEnd and previous");
 
     gl_info->gl_ops.gl.p_glEnd();
     checkGLcall("glEnd and previous");
 
-    if (texture_target != dst_surface->texture_target)
+    if (texture_target != dst_target)
     {
         gl_info->gl_ops.gl.p_glDisable(texture_target);
     {
         gl_info->gl_ops.gl.p_glDisable(texture_target);
-        gl_info->gl_ops.gl.p_glEnable(dst_surface->texture_target);
-        texture_target = dst_surface->texture_target;
+        gl_info->gl_ops.gl.p_glEnable(dst_target);
+        texture_target = dst_target;
     }
 
     /* Now read the stretched and upside down image into the destination texture */
     }
 
     /* Now read the stretched and upside down image into the destination texture */
@@ -1890,13 +2103,13 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
         }
         else
         {
         }
         else
         {
-            if (texture_target != src_surface->texture_target)
+            if (texture_target != src_target)
             {
                 gl_info->gl_ops.gl.p_glDisable(texture_target);
             {
                 gl_info->gl_ops.gl.p_glDisable(texture_target);
-                gl_info->gl_ops.gl.p_glEnable(src_surface->texture_target);
-                texture_target = src_surface->texture_target;
+                gl_info->gl_ops.gl.p_glEnable(src_target);
+                texture_target = src_target;
             }
             }
-            context_bind_texture(context, src_surface->texture_target, src_texture->texture_rgb.name);
+            context_bind_texture(context, src_target, src_texture->texture_rgb.name);
         }
 
         gl_info->gl_ops.gl.p_glBegin(GL_QUADS);
         }
 
         gl_info->gl_ops.gl.p_glBegin(GL_QUADS);
@@ -1985,10 +2198,10 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
             dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect),
             flags, fx, debug_d3dtexturefiltertype(filter));
 
             dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect),
             flags, fx, debug_d3dtexturefiltertype(filter));
 
-    /* Get the swapchain. One of the surfaces has to be a primary surface */
-    if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM)
+    /* Get the swapchain. One of the surfaces has to be a primary surface. */
+    if (!(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
     {
     {
-        WARN("Destination is in sysmem, rejecting gl blt\n");
+        WARN("Destination resource is not GPU accessible, rejecting GL blit.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
@@ -1997,9 +2210,9 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
     if (src_surface)
     {
         src_texture = src_surface->container;
     if (src_surface)
     {
         src_texture = src_surface->container;
-        if (src_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM)
+        if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
         {
         {
-            WARN("Src is in sysmem, rejecting gl blt\n");
+            WARN("Source resource is not GPU accessible, rejecting GL blit.\n");
             return WINED3DERR_INVALIDCALL;
         }
 
             return WINED3DERR_INVALIDCALL;
         }
 
@@ -2052,7 +2265,7 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
 
     if ((src_swapchain || src_surface == rt) && !dst_swapchain)
     {
 
     if ((src_swapchain || src_surface == rt) && !dst_swapchain)
     {
-        unsigned int src_width, src_height;
+        unsigned int src_level, src_width, src_height;
         /* Blit from render target to texture */
         BOOL stretchx;
 
         /* Blit from render target to texture */
         BOOL stretchx;
 
@@ -2086,8 +2299,9 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
          *    back buffer. This is slower than reading line per line, thus not used for flipping
          * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied
          *    pixel by pixel. */
          *    back buffer. This is slower than reading line per line, thus not used for flipping
          * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied
          *    pixel by pixel. */
-        src_width = wined3d_texture_get_level_width(src_texture, src_surface->texture_level);
-        src_height = wined3d_texture_get_level_height(src_texture, src_surface->texture_level);
+        src_level = surface_get_sub_resource_idx(src_surface) % src_texture->level_count;
+        src_width = wined3d_texture_get_level_width(src_texture, src_level);
+        src_height = wined3d_texture_get_level_height(src_texture, src_level);
         if (!stretchx || dst_rect->right - dst_rect->left > src_width
                 || dst_rect->bottom - dst_rect->top > src_height)
         {
         if (!stretchx || dst_rect->right - dst_rect->left > src_width
                 || dst_rect->bottom - dst_rect->top > src_height)
         {
@@ -2120,24 +2334,34 @@ static BOOL surface_load_sysmem(struct wined3d_surface *surface,
     sub_resource = &texture->sub_resources[sub_resource_idx];
     wined3d_texture_prepare_location(texture, sub_resource_idx, context, dst_location);
 
     sub_resource = &texture->sub_resources[sub_resource_idx];
     wined3d_texture_prepare_location(texture, sub_resource_idx, context, dst_location);
 
-    if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
-        wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
-
-    /* Download the surface to system memory. */
-    if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+    /* We cannot download data from multisample textures directly. */
+    if (is_multisample_location(texture, WINED3D_LOCATION_TEXTURE_RGB))
     {
     {
-        wined3d_texture_bind_and_dirtify(texture, context,
-                !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
-        surface_download_data(surface, gl_info, dst_location);
-        ++texture->download_count;
-
+        wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_RB_RESOLVED);
+        read_from_framebuffer(surface, context, WINED3D_LOCATION_RB_RESOLVED, dst_location);
         return TRUE;
     }
         return TRUE;
     }
+    else
+    {
+        if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
+            wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
+
+        /* Download the surface to system memory. */
+        if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+        {
+            wined3d_texture_bind_and_dirtify(texture, context,
+                    !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
+            surface_download_data(surface, gl_info, dst_location);
+            ++texture->download_count;
+
+            return TRUE;
+        }
+    }
 
     if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
             && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE))
     {
 
     if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
             && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE))
     {
-        read_from_framebuffer(surface, context, dst_location);
+        read_from_framebuffer(surface, context, texture->resource.draw_binding, dst_location);
         return TRUE;
     }
 
         return TRUE;
     }
 
@@ -2154,6 +2378,7 @@ static BOOL surface_load_drawable(struct wined3d_surface *surface,
     struct wined3d_texture *texture = surface->container;
     struct wined3d_surface *restore_rt = NULL;
     struct wined3d_device *device;
     struct wined3d_texture *texture = surface->container;
     struct wined3d_surface *restore_rt = NULL;
     struct wined3d_device *device;
+    unsigned int level;
     RECT r;
 
     if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
     RECT r;
 
     if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
@@ -2178,8 +2403,9 @@ static BOOL surface_load_drawable(struct wined3d_surface *surface,
     else
         restore_rt = NULL;
 
     else
         restore_rt = NULL;
 
-    SetRect(&r, 0, 0, wined3d_texture_get_level_width(texture, surface->texture_level),
-            wined3d_texture_get_level_height(texture, surface->texture_level));
+    level = sub_resource_idx % texture->level_count;
+    SetRect(&r, 0, 0, wined3d_texture_get_level_width(texture, level),
+            wined3d_texture_get_level_height(texture, level));
     wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
     device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context,
             surface, WINED3D_LOCATION_TEXTURE_RGB, &r,
     wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
     device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context,
             surface, WINED3D_LOCATION_TEXTURE_RGB, &r,
@@ -2195,7 +2421,7 @@ static BOOL surface_load_drawable(struct wined3d_surface *surface,
 static BOOL surface_load_texture(struct wined3d_surface *surface,
         struct wined3d_context *context, BOOL srgb)
 {
 static BOOL surface_load_texture(struct wined3d_surface *surface,
         struct wined3d_context *context, BOOL srgb)
 {
-    unsigned int width, height, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch;
+    unsigned int width, height, level, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch;
     unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_texture *texture = surface->container;
     unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_texture *texture = surface->container;
@@ -2221,17 +2447,16 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
         return TRUE;
     }
 
         return TRUE;
     }
 
-    width = wined3d_texture_get_level_width(texture, surface->texture_level);
-    height = wined3d_texture_get_level_height(texture, surface->texture_level);
+    level = sub_resource_idx % texture->level_count;
+    width = wined3d_texture_get_level_width(texture, level);
+    height = wined3d_texture_get_level_height(texture, level);
     SetRect(&src_rect, 0, 0, width, height);
 
     if (!depth && sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB)
             && (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)
     SetRect(&src_rect, 0, 0, width, height);
 
     if (!depth && sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB)
             && (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)
-            && fbo_blitter_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
-                    texture->resource.usage, texture->resource.pool,
-                    texture->resource.format, WINED3D_LOCATION_TEXTURE_RGB,
-                    texture->resource.usage, texture->resource.pool,
-                    texture->resource.format, WINED3D_LOCATION_TEXTURE_SRGB))
+            && fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info,
+                    &texture->resource, WINED3D_LOCATION_TEXTURE_RGB,
+                    &texture->resource, WINED3D_LOCATION_TEXTURE_SRGB))
     {
         if (srgb)
             surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB,
     {
         if (srgb)
             surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB,
@@ -2250,9 +2475,8 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
                 WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE;
         DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
 
                 WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE;
         DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
 
-        if (fbo_blitter_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
-                texture->resource.usage, texture->resource.pool, texture->resource.format, src_location,
-                texture->resource.usage, texture->resource.pool, texture->resource.format, dst_location))
+        if (fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info,
+                &texture->resource, src_location, &texture->resource, dst_location))
             surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location,
                     &src_rect, surface, dst_location, &src_rect);
 
             surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location,
                     &src_rect, surface, dst_location, &src_rect);
 
@@ -2289,7 +2513,7 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
 
     wined3d_texture_prepare_texture(texture, context, srgb);
     wined3d_texture_bind_and_dirtify(texture, context, srgb);
 
     wined3d_texture_prepare_texture(texture, context, srgb);
     wined3d_texture_bind_and_dirtify(texture, context, srgb);
-    wined3d_texture_get_pitch(texture, surface->texture_level, &src_row_pitch, &src_slice_pitch);
+    wined3d_texture_get_pitch(texture, level, &src_row_pitch, &src_slice_pitch);
 
     format = *texture->resource.format;
     if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
 
     format = *texture->resource.format;
     if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
@@ -2298,7 +2522,11 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
     /* Don't use PBOs for converted surfaces. During PBO conversion we look at
      * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is
      * getting called. */
     /* Don't use PBOs for converted surfaces. During PBO conversion we look at
      * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is
      * getting called. */
+#if !defined(STAGING_CSMT)
     if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer_object)
     if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer_object)
+#else  /* STAGING_CSMT */
+    if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer)
+#endif /* STAGING_CSMT */
     {
         TRACE("Removing the pbo attached to surface %p.\n", surface);
 
     {
         TRACE("Removing the pbo attached to surface %p.\n", surface);
 
@@ -2314,8 +2542,8 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
         wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch);
 
         src_mem = context_map_bo_address(context, &data, src_slice_pitch,
         wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch);
 
         src_mem = context_map_bo_address(context, &data, src_slice_pitch,
-                GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READONLY);
-        if (!(dst_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch)))
+                GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
+        if (!(dst_mem = heap_alloc(dst_slice_pitch)))
         {
             ERR("Out of memory (%u).\n", dst_slice_pitch);
             context_release(context);
         {
             ERR("Out of memory (%u).\n", dst_slice_pitch);
             context_release(context);
@@ -2338,8 +2566,8 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
                 width, height, &dst_row_pitch, &dst_slice_pitch);
 
         src_mem = context_map_bo_address(context, &data, src_slice_pitch,
                 width, height, &dst_row_pitch, &dst_slice_pitch);
 
         src_mem = context_map_bo_address(context, &data, src_slice_pitch,
-                GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READONLY);
-        if (!(dst_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch)))
+                GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
+        if (!(dst_mem = heap_alloc(dst_slice_pitch)))
         {
             ERR("Out of memory (%u).\n", dst_slice_pitch);
             context_release(context);
         {
             ERR("Out of memory (%u).\n", dst_slice_pitch);
             context_release(context);
@@ -2359,7 +2587,7 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
     wined3d_surface_upload_data(surface, gl_info, &format, &src_rect,
             src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
 
     wined3d_surface_upload_data(surface, gl_info, &format, &src_rect,
             src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
 
-    HeapFree(GetProcessHeap(), 0, dst_mem);
+    heap_free(dst_mem);
 
     return TRUE;
 }
 
     return TRUE;
 }
@@ -2369,9 +2597,10 @@ static BOOL surface_load_renderbuffer(struct wined3d_surface *surface, struct wi
         DWORD dst_location)
 {
     struct wined3d_texture *texture = surface->container;
         DWORD dst_location)
 {
     struct wined3d_texture *texture = surface->container;
+    unsigned int level = surface_get_sub_resource_idx(surface) % texture->level_count;
     const RECT rect = {0, 0,
     const RECT rect = {0, 0,
-            wined3d_texture_get_level_width(texture, surface->texture_level),
-            wined3d_texture_get_level_height(texture, surface->texture_level)};
+            wined3d_texture_get_level_width(texture, level),
+            wined3d_texture_get_level_height(texture, level)};
     DWORD locations = surface_get_sub_resource(surface)->locations;
     DWORD src_location;
 
     DWORD locations = surface_get_sub_resource(surface)->locations;
     DWORD src_location;
 
@@ -2435,7 +2664,7 @@ static void fbo_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_
     if ((next = blitter->next))
         next->ops->blitter_destroy(next, context);
 
     if ((next = blitter->next))
         next->ops->blitter_destroy(next, context);
 
-    HeapFree(GetProcessHeap(), 0, blitter);
+    heap_free(blitter);
 }
 
 static void fbo_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
 }
 
 static void fbo_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
@@ -2468,9 +2697,8 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
             blit_op = WINED3D_BLIT_OP_COLOR_BLIT;
     }
 
             blit_op = WINED3D_BLIT_OP_COLOR_BLIT;
     }
 
-    if (!fbo_blitter_supported(&device->adapter->gl_info, blit_op,
-            src_resource->usage, src_resource->pool, src_resource->format, src_location,
-            src_resource->usage, dst_resource->pool, dst_resource->format, dst_location))
+    if (!fbo_blitter_supported(blit_op, context->gl_info,
+            src_resource, src_location, dst_resource, dst_location))
     {
         if ((next = blitter->next))
             return next->ops->blitter_blit(next, op, context, src_surface, src_location,
     {
         if ((next = blitter->next))
             return next->ops->blitter_blit(next, op, context, src_surface, src_location,
@@ -2510,7 +2738,7 @@ void wined3d_fbo_blitter_create(struct wined3d_blitter **next, const struct wine
     if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer)
         return;
 
     if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer)
         return;
 
-    if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
+    if (!(blitter = heap_alloc(sizeof(*blitter))))
         return;
 
     TRACE("Created blitter %p.\n", blitter);
         return;
 
     TRACE("Created blitter %p.\n", blitter);
@@ -2528,7 +2756,7 @@ static void raw_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_
     if ((next = blitter->next))
         next->ops->blitter_destroy(next, context);
 
     if ((next = blitter->next))
         next->ops->blitter_destroy(next, context);
 
-    HeapFree(GetProcessHeap(), 0, blitter);
+    heap_free(blitter);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -2557,6 +2785,7 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int src_sub_resource_idx, dst_sub_resource_idx;
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int src_sub_resource_idx, dst_sub_resource_idx;
+    unsigned int src_level, src_layer, dst_level, dst_layer;
     struct wined3d_texture *src_texture, *dst_texture;
     struct wined3d_blitter *next;
     GLuint src_name, dst_name;
     struct wined3d_texture *src_texture, *dst_texture;
     struct wined3d_blitter *next;
     GLuint src_name, dst_name;
@@ -2587,7 +2816,12 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
     TRACE("Blit using ARB_copy_image.\n");
 
     src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
     TRACE("Blit using ARB_copy_image.\n");
 
     src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+    src_level = src_sub_resource_idx % src_texture->level_count;
+    src_layer = src_sub_resource_idx / src_texture->level_count;
+
     dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
     dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
+    dst_level = dst_sub_resource_idx % dst_texture->level_count;
+    dst_layer = dst_sub_resource_idx / dst_texture->level_count;
 
     location = src_location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB);
     if (!location)
 
     location = src_location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB);
     if (!location)
@@ -2601,7 +2835,7 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
     if (!location)
         location = dst_texture->flags & WINED3D_TEXTURE_IS_SRGB
                 ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
     if (!location)
         location = dst_texture->flags & WINED3D_TEXTURE_IS_SRGB
                 ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
-    if (surface_is_full_rect(dst_surface, dst_rect))
+    if (texture2d_is_full_rect(dst_texture, dst_level, dst_rect))
     {
         if (!wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, location))
             ERR("Failed to prepare the destination sub-resource into %s.\n", wined3d_debug_location(location));
     {
         if (!wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, location))
             ERR("Failed to prepare the destination sub-resource into %s.\n", wined3d_debug_location(location));
@@ -2613,11 +2847,10 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
     }
     dst_name = wined3d_texture_get_texture_name(dst_texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB);
 
     }
     dst_name = wined3d_texture_get_texture_name(dst_texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB);
 
-    GL_EXTCALL(glCopyImageSubData(src_name, src_texture->target, src_surface->texture_level,
-            src_rect->left, src_rect->top, src_surface->texture_layer,
-            dst_name, dst_texture->target, dst_surface->texture_level,
-            dst_rect->left, dst_rect->top, dst_surface->texture_layer,
-            src_rect->right - src_rect->left, src_rect->bottom - src_rect->top, 1));
+    GL_EXTCALL(glCopyImageSubData(src_name, src_texture->target, src_level,
+            src_rect->left, src_rect->top, src_layer, dst_name, dst_texture->target, dst_level,
+            dst_rect->left, dst_rect->top, dst_layer, src_rect->right - src_rect->left,
+            src_rect->bottom - src_rect->top, 1));
     checkGLcall("copy image data");
 
     wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, location);
     checkGLcall("copy image data");
 
     wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, location);
@@ -2642,7 +2875,7 @@ void wined3d_raw_blitter_create(struct wined3d_blitter **next, const struct wine
     if (!gl_info->supported[ARB_COPY_IMAGE])
         return;
 
     if (!gl_info->supported[ARB_COPY_IMAGE])
         return;
 
-    if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
+    if (!(blitter = heap_alloc(sizeof(*blitter))))
         return;
 
     TRACE("Created blitter %p.\n", blitter);
         return;
 
     TRACE("Created blitter %p.\n", blitter);
@@ -2660,21 +2893,22 @@ static void ffp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_
     if ((next = blitter->next))
         next->ops->blitter_destroy(next, context);
 
     if ((next = blitter->next))
         next->ops->blitter_destroy(next, context);
 
-    HeapFree(GetProcessHeap(), 0, blitter);
+    heap_free(blitter);
 }
 
 }
 
-static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info,
-        const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
-        DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, DWORD src_location,
-        DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format, DWORD dst_location)
+static BOOL ffp_blit_supported(enum wined3d_blit_op blit_op, const struct wined3d_context *context,
+        const struct wined3d_resource *src_resource, DWORD src_location,
+        const struct wined3d_resource *dst_resource, DWORD dst_location)
 {
 {
+    const struct wined3d_format *src_format = src_resource->format;
+    const struct wined3d_format *dst_format = dst_resource->format;
     BOOL decompress;
 
     decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
             && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED);
     BOOL decompress;
 
     decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
             && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED);
-    if (!decompress && (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM))
+    if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU))
     {
     {
-        TRACE("Source or destination is in system memory.\n");
+        TRACE("Source or destination resource is not GPU accessible.\n");
         return FALSE;
     }
 
         return FALSE;
     }
 
@@ -2689,14 +2923,14 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info,
     switch (blit_op)
     {
         case WINED3D_BLIT_OP_COLOR_BLIT_CKEY:
     switch (blit_op)
     {
         case WINED3D_BLIT_OP_COLOR_BLIT_CKEY:
-            if (d3d_info->shader_color_key)
+            if (context->d3d_info->shader_color_key)
             {
                 TRACE("Color keying requires converted textures.\n");
                 return FALSE;
             }
         case WINED3D_BLIT_OP_COLOR_BLIT:
         case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST:
             {
                 TRACE("Color keying requires converted textures.\n");
                 return FALSE;
             }
         case WINED3D_BLIT_OP_COLOR_BLIT:
         case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST:
-            if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+            if (!context->gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
                 return FALSE;
 
             if (TRACE_ON(d3d))
                 return FALSE;
 
             if (TRACE_ON(d3d))
@@ -2721,7 +2955,7 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info,
                 }
             }
 
                 }
             }
 
-            if (!(dst_usage & WINED3DUSAGE_RENDERTARGET))
+            if (!(dst_resource->usage & WINED3DUSAGE_RENDERTARGET))
             {
                 TRACE("Can only blit to render targets.\n");
                 return FALSE;
             {
                 TRACE("Can only blit to render targets.\n");
                 return FALSE;
@@ -2742,14 +2976,16 @@ static BOOL ffp_blitter_use_cpu_clear(struct wined3d_rendertarget_view *view)
 
     resource = view->resource;
     if (resource->type == WINED3D_RTYPE_BUFFER)
 
     resource = view->resource;
     if (resource->type == WINED3D_RTYPE_BUFFER)
-        return resource->pool == WINED3D_POOL_SYSTEM_MEM;
+        return !(resource->access & WINED3D_RESOURCE_ACCESS_GPU);
 
     texture = texture_from_resource(resource);
     locations = texture->sub_resources[view->sub_resource_idx].locations;
     if (locations & (resource->map_binding | WINED3D_LOCATION_DISCARDED))
 
     texture = texture_from_resource(resource);
     locations = texture->sub_resources[view->sub_resource_idx].locations;
     if (locations & (resource->map_binding | WINED3D_LOCATION_DISCARDED))
-        return resource->pool == WINED3D_POOL_SYSTEM_MEM || (texture->flags & WINED3D_TEXTURE_PIN_SYSMEM);
+        return !(resource->access & WINED3D_RESOURCE_ACCESS_GPU)
+                || (texture->flags & WINED3D_TEXTURE_PIN_SYSMEM);
 
 
-    return resource->pool == WINED3D_POOL_SYSTEM_MEM && !(texture->flags & WINED3D_TEXTURE_CONVERTED);
+    return !(resource->access & WINED3D_RESOURCE_ACCESS_GPU)
+            && !(texture->flags & WINED3D_TEXTURE_CONVERTED);
 }
 
 static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
 }
 
 static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
@@ -2806,6 +3042,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
         const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
         const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
 {
         const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
         const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
 {
+    unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
     struct wined3d_texture *src_texture = src_surface->container;
     struct wined3d_texture *dst_texture = dst_surface->container;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_texture *src_texture = src_surface->container;
     struct wined3d_texture *dst_texture = dst_surface->container;
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -2820,9 +3057,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
     dst_resource = &dst_texture->resource;
     device = dst_resource->device;
 
     dst_resource = &dst_texture->resource;
     device = dst_resource->device;
 
-    if (!ffp_blit_supported(&device->adapter->gl_info, &device->adapter->d3d_info, op,
-            src_resource->usage, src_resource->pool, src_resource->format, src_location,
-            dst_resource->usage, dst_resource->pool, dst_resource->format, dst_location))
+    if (!ffp_blit_supported(op, context, src_resource, src_location, dst_resource, dst_location))
     {
         if ((next = blitter->next))
             return next->ops->blitter_blit(next, op, context, src_surface, src_location,
     {
         if ((next = blitter->next))
             return next->ops->blitter_blit(next, op, context, src_surface, src_location,
@@ -2892,7 +3127,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
         checkGLcall("glAlphaFunc");
     }
 
         checkGLcall("glAlphaFunc");
     }
 
-    draw_textured_quad(src_surface, context, src_rect, dst_rect, filter);
+    draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter);
 
     if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key)
     {
 
     if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key)
     {
@@ -2936,7 +3171,7 @@ void wined3d_ffp_blitter_create(struct wined3d_blitter **next, const struct wine
 {
     struct wined3d_blitter *blitter;
 
 {
     struct wined3d_blitter *blitter;
 
-    if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
+    if (!(blitter = heap_alloc(sizeof(*blitter))))
         return;
 
     TRACE("Created blitter %p.\n", blitter);
         return;
 
     TRACE("Created blitter %p.\n", blitter);
@@ -2954,7 +3189,7 @@ static void cpu_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_
     if ((next = blitter->next))
         next->ops->blitter_destroy(next, context);
 
     if ((next = blitter->next))
         next->ops->blitter_destroy(next, context);
 
-    HeapFree(GetProcessHeap(), 0, blitter);
+    heap_free(blitter);
 }
 
 static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data,
 }
 
 static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data,
@@ -3102,7 +3337,8 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int
         wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch);
         wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding);
         dst_map.data = context_map_bo_address(context, &dst_data,
         wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch);
         wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding);
         dst_map.data = context_map_bo_address(context, &dst_data,
-                dst_texture->sub_resources[dst_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0);
+                dst_texture->sub_resources[dst_sub_resource_idx].size,
+                GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ | WINED3D_MAP_WRITE);
 
         src_map = dst_map;
         src_format = dst_texture->resource.format;
 
         src_map = dst_map;
         src_format = dst_texture->resource.format;
@@ -3138,7 +3374,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int
         wined3d_texture_get_pitch(src_texture, texture_level, &src_map.row_pitch, &src_map.slice_pitch);
         wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &src_data, map_binding);
         src_map.data = context_map_bo_address(context, &src_data,
         wined3d_texture_get_pitch(src_texture, texture_level, &src_map.row_pitch, &src_map.slice_pitch);
         wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &src_data, map_binding);
         src_map.data = context_map_bo_address(context, &src_data,
-                src_texture->sub_resources[src_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0);
+                src_texture->sub_resources[src_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
 
         map_binding = dst_texture->resource.map_binding;
         texture_level = dst_sub_resource_idx % dst_texture->level_count;
 
         map_binding = dst_texture->resource.map_binding;
         texture_level = dst_sub_resource_idx % dst_texture->level_count;
@@ -3148,7 +3384,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int
         wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch);
         wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding);
         dst_map.data = context_map_bo_address(context, &dst_data,
         wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch);
         wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding);
         dst_map.data = context_map_bo_address(context, &dst_data,
-                dst_texture->sub_resources[dst_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0);
+                dst_texture->sub_resources[dst_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_WRITE);
     }
     flags &= ~WINED3D_BLT_RAW;
 
     }
     flags &= ~WINED3D_BLT_RAW;
 
@@ -3194,7 +3430,8 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int
             && (src_width != dst_width || src_height != dst_height))
     {
         /* Can happen when d3d9 apps do a StretchRect() call which isn't handled in GL. */
             && (src_width != dst_width || src_height != dst_height))
     {
         /* Can happen when d3d9 apps do a StretchRect() call which isn't handled in GL. */
-        FIXME("Filter %s not supported in software blit.\n", debug_d3dtexturefiltertype(filter));
+        static int once;
+        if (!once++) FIXME("Filter %s not supported in software blit.\n", debug_d3dtexturefiltertype(filter));
     }
 
     xinc = (src_width << 16) / dst_width;
     }
 
     xinc = (src_width << 16) / dst_width;
@@ -3589,7 +3826,7 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view,
             &map.row_pitch, &map.slice_pitch);
     wined3d_texture_get_memory(texture, view->sub_resource_idx, &data, map_binding);
     map.data = context_map_bo_address(context, &data,
             &map.row_pitch, &map.slice_pitch);
     wined3d_texture_get_memory(texture, view->sub_resource_idx, &data, map_binding);
     map.data = context_map_bo_address(context, &data,
-            texture->sub_resources[view->sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0);
+            texture->sub_resources[view->sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_WRITE);
     map.data = (BYTE *)map.data
             + (box->front * map.slice_pitch)
             + ((box->top / view->format->block_height) * map.row_pitch)
     map.data = (BYTE *)map.data
             + (box->front * map.slice_pitch)
             + ((box->top / view->format->block_height) * map.row_pitch)
@@ -3747,7 +3984,7 @@ struct wined3d_blitter *wined3d_cpu_blitter_create(void)
 {
     struct wined3d_blitter *blitter;
 
 {
     struct wined3d_blitter *blitter;
 
-    if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
+    if (!(blitter = heap_alloc(sizeof(*blitter))))
         return NULL;
 
     TRACE("Created blitter %p.\n", blitter);
         return NULL;
 
     TRACE("Created blitter %p.\n", blitter);
@@ -3776,7 +4013,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
     DWORD src_ds_flags, dst_ds_flags;
     struct wined3d_context *context;
     enum wined3d_blit_op blit_op;
     DWORD src_ds_flags, dst_ds_flags;
     struct wined3d_context *context;
     enum wined3d_blit_op blit_op;
-    BOOL scale, convert;
+    BOOL scale, convert, resolve;
 
     static const DWORD simple_blit = WINED3D_BLT_SRC_CKEY
             | WINED3D_BLT_SRC_CKEY_OVERRIDE
 
     static const DWORD simple_blit = WINED3D_BLT_SRC_CKEY
             | WINED3D_BLT_SRC_CKEY_OVERRIDE
@@ -3819,6 +4056,16 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
         goto cpu;
     }
 
         goto cpu;
     }
 
+    /* We want to avoid invalidating the sysmem location for converted
+     * surfaces, since otherwise we'd have to convert the data back when
+     * locking them. */
+    if (dst_texture->flags & WINED3D_TEXTURE_CONVERTED || dst_texture->resource.format->conv_byte_count
+            || wined3d_format_get_color_key_conversion(dst_texture, TRUE))
+    {
+        WARN_(d3d_perf)("Converted surface, using CPU blit.\n");
+        goto cpu;
+    }
+
     if (flags & ~simple_blit)
     {
         WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags);
     if (flags & ~simple_blit)
     {
         WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags);
@@ -3842,6 +4089,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
     scale = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left
             || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top;
     convert = src_texture->resource.format->id != dst_texture->resource.format->id;
     scale = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left
             || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top;
     convert = src_texture->resource.format->id != dst_texture->resource.format->id;
+    resolve = src_texture->resource.multisample_type != dst_texture->resource.multisample_type;
 
     dst_ds_flags = dst_texture->resource.format_flags
             & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
 
     dst_ds_flags = dst_texture->resource.format_flags
             & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
@@ -3852,10 +4100,10 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
     {
         TRACE("Depth/stencil blit.\n");
 
     {
         TRACE("Depth/stencil blit.\n");
 
-        if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM)
-            dst_location = dst_texture->resource.map_binding;
-        else
+        if (dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)
             dst_location = dst_texture->resource.draw_binding;
             dst_location = dst_texture->resource.draw_binding;
+        else
+            dst_location = dst_texture->resource.map_binding;
 
         context = context_acquire(device, dst_texture, dst_sub_resource_idx);
         valid_locations = device->blitter->ops->blitter_blit(device->blitter,
 
         context = context_acquire(device, dst_texture, dst_sub_resource_idx);
         valid_locations = device->blitter->ops->blitter_blit(device->blitter,
@@ -3947,20 +4195,20 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
         /* Set the swap effect to COPY, we don't want the backbuffer to become
          * undefined. */
         dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
         /* Set the swap effect to COPY, we don't want the backbuffer to become
          * undefined. */
         dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
-        wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, 0);
+        wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, 0, 0);
         dst_swapchain->desc.swap_effect = swap_effect;
 
         return WINED3D_OK;
     }
         dst_swapchain->desc.swap_effect = swap_effect;
 
         return WINED3D_OK;
     }
-    else if ((flags & WINED3D_BLT_RAW) || (!scale && !convert))
+    else if ((flags & WINED3D_BLT_RAW) || (!scale && !convert && !resolve))
     {
         blit_op = WINED3D_BLIT_OP_RAW_BLIT;
     }
 
     {
         blit_op = WINED3D_BLIT_OP_RAW_BLIT;
     }
 
-    if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM)
-        dst_location = dst_texture->resource.map_binding;
-    else
+    if (dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)
         dst_location = dst_texture->resource.draw_binding;
         dst_location = dst_texture->resource.draw_binding;
+    else
+        dst_location = dst_texture->resource.map_binding;
 
     context = context_acquire(device, dst_texture, dst_sub_resource_idx);
     valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context,
 
     context = context_acquire(device, dst_texture, dst_sub_resource_idx);
     valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context,
index 5857c1e..8c67a0d 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 #include "wined3d_private.h"
 
+#ifdef __REACTOS__
+#include <reactos/undocuser.h>
+#endif
+
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(fps);
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(fps);
 
@@ -59,7 +65,7 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain)
             if (wined3d_texture_decref(swapchain->back_buffers[i]))
                 WARN("Something's still holding back buffer %u (%p).\n", i, swapchain->back_buffers[i]);
         }
             if (wined3d_texture_decref(swapchain->back_buffers[i]))
                 WARN("Something's still holding back buffer %u (%p).\n", i, swapchain->back_buffers[i]);
         }
-        HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
+        heap_free(swapchain->back_buffers);
         swapchain->back_buffers = NULL;
     }
 
         swapchain->back_buffers = NULL;
     }
 
@@ -118,7 +124,7 @@ ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain)
 
         swapchain_cleanup(swapchain);
         swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent);
 
         swapchain_cleanup(swapchain);
         swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent);
-        HeapFree(GetProcessHeap(), 0, swapchain);
+        heap_free(swapchain);
     }
 
     return refcount;
     }
 
     return refcount;
@@ -144,16 +150,21 @@ void CDECL wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWN
 }
 
 HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
 }
 
 HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
-        const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags)
+        const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
+        DWORD swap_interval, DWORD flags)
 {
 {
+    static DWORD notified_flags = 0;
     RECT s, d;
 
     TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, flags %#x.\n",
             swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
             dst_window_override, flags);
 
     RECT s, d;
 
     TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, flags %#x.\n",
             swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
             dst_window_override, 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)
     {
 
     if (!swapchain->back_buffers)
     {
@@ -175,7 +186,7 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
     }
 
     wined3d_cs_emit_present(swapchain->device->cs, swapchain, src_rect,
     }
 
     wined3d_cs_emit_present(swapchain->device->cs, swapchain, src_rect,
-            dst_rect, dst_window_override, flags);
+            dst_rect, dst_window_override, swap_interval, flags);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -467,16 +478,13 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
     }
 
     if (swapchain->render_to_fbo)
     }
 
     if (swapchain->render_to_fbo)
-    {
-        static unsigned int once;
-
-        if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP && !once++)
-            FIXME("WINED3D_SWAP_EFFECT_FLIP not implemented.\n");
-
         swapchain_blit(swapchain, context, src_rect, dst_rect);
         swapchain_blit(swapchain, context, src_rect, dst_rect);
-    }
 
 
+#if !defined(STAGING_CSMT)
     if (swapchain->num_contexts > 1)
     if (swapchain->num_contexts > 1)
+#else  /* STAGING_CSMT */
+    if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded)
+#endif /* STAGING_CSMT */
         gl_info->gl_ops.gl.p_glFinish();
 
     /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */
         gl_info->gl_ops.gl.p_glFinish();
 
     /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */
@@ -510,7 +518,8 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
      * The FLIP swap effect is not implemented yet. We could mark WINED3D_LOCATION_DRAWABLE
      * up to date and hope WGL flipped front and back buffers and read this data into
      * the FBO. Don't bother about this for now. */
      * The FLIP swap effect is not implemented yet. We could mark WINED3D_LOCATION_DRAWABLE
      * up to date and hope WGL flipped front and back buffers and read this data into
      * the FBO. Don't bother about this for now. */
-    if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_DISCARD)
+    if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_DISCARD
+            || swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP_DISCARD)
         wined3d_texture_validate_location(swapchain->back_buffers[swapchain->desc.backbuffer_count - 1],
                 0, WINED3D_LOCATION_DISCARDED);
 
         wined3d_texture_validate_location(swapchain->back_buffers[swapchain->desc.backbuffer_count - 1],
                 0, WINED3D_LOCATION_DISCARDED);
 
@@ -782,6 +791,11 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
                 "Please configure the application to use double buffering (1 back buffer) if possible.\n");
     }
 
                 "Please configure the application to use double buffering (1 back buffer) if possible.\n");
     }
 
+    if (desc->swap_effect != WINED3D_SWAP_EFFECT_DISCARD
+            && desc->swap_effect != WINED3D_SWAP_EFFECT_SEQUENTIAL
+            && desc->swap_effect != WINED3D_SWAP_EFFECT_COPY)
+        FIXME("Unimplemented swap effect %#x.\n", desc->swap_effect);
+
     if (device->wined3d->flags & WINED3D_NO3D)
         swapchain->swapchain_ops = &swapchain_gdi_ops;
     else
     if (device->wined3d->flags & WINED3D_NO3D)
         swapchain->swapchain_ops = &swapchain_gdi_ops;
     else
@@ -837,7 +851,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
     texture_desc.multisample_type = swapchain->desc.multisample_type;
     texture_desc.multisample_quality = swapchain->desc.multisample_quality;
     texture_desc.usage = 0;
     texture_desc.multisample_type = swapchain->desc.multisample_type;
     texture_desc.multisample_quality = swapchain->desc.multisample_quality;
     texture_desc.usage = 0;
-    texture_desc.pool = WINED3D_POOL_DEFAULT;
+    texture_desc.access = WINED3D_RESOURCE_ACCESS_GPU;
     texture_desc.width = swapchain->desc.backbuffer_width;
     texture_desc.height = swapchain->desc.backbuffer_height;
     texture_desc.depth = 1;
     texture_desc.width = swapchain->desc.backbuffer_width;
     texture_desc.height = swapchain->desc.backbuffer_height;
     texture_desc.depth = 1;
@@ -890,8 +904,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
 
     if (!(device->wined3d->flags & WINED3D_NO3D))
     {
 
     if (!(device->wined3d->flags & WINED3D_NO3D))
     {
-        swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context));
-        if (!swapchain->context)
+        if (!(swapchain->context = heap_alloc(sizeof(*swapchain->context))))
         {
             ERR("Failed to create the context array.\n");
             hr = E_OUTOFMEMORY;
         {
             ERR("Failed to create the context array.\n");
             hr = E_OUTOFMEMORY;
@@ -910,7 +923,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
 
     if (swapchain->desc.backbuffer_count > 0)
     {
 
     if (swapchain->desc.backbuffer_count > 0)
     {
-        if (!(swapchain->back_buffers = wined3d_calloc(swapchain->desc.backbuffer_count,
+        if (!(swapchain->back_buffers = heap_calloc(swapchain->desc.backbuffer_count,
                 sizeof(*swapchain->back_buffers))))
         {
             ERR("Failed to allocate backbuffer array memory.\n");
                 sizeof(*swapchain->back_buffers))))
         {
             ERR("Failed to allocate backbuffer array memory.\n");
@@ -918,7 +931,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
             goto err;
         }
 
             goto err;
         }
 
-        texture_desc.usage |= WINED3DUSAGE_RENDERTARGET;
+        texture_desc.usage = swapchain->desc.backbuffer_usage;
         for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
         {
             TRACE("Creating back buffer %u.\n", i);
         for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
         {
             TRACE("Creating back buffer %u.\n", i);
@@ -992,7 +1005,7 @@ err:
                 wined3d_texture_decref(swapchain->back_buffers[i]);
             }
         }
                 wined3d_texture_decref(swapchain->back_buffers[i]);
             }
         }
-        HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
+        heap_free(swapchain->back_buffers);
     }
 
     wined3d_cs_destroy_object(swapchain->device->cs, wined3d_swapchain_destroy_object, swapchain);
     }
 
     wined3d_cs_destroy_object(swapchain->device->cs, wined3d_swapchain_destroy_object, swapchain);
@@ -1016,15 +1029,14 @@ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct win
     TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n",
             device, desc, parent, parent_ops, swapchain);
 
     TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n",
             device, desc, parent, parent_ops, swapchain);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = swapchain_init(object, device, desc, parent, parent_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = swapchain_init(object, device, desc, parent, parent_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -1048,14 +1060,14 @@ static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain
     }
     context_release(ctx);
 
     }
     context_release(ctx);
 
-    if (!(ctx_array = wined3d_calloc(swapchain->num_contexts + 1, sizeof(*ctx_array))))
+    if (!(ctx_array = heap_calloc(swapchain->num_contexts + 1, sizeof(*ctx_array))))
     {
         ERR("Out of memory when trying to allocate a new context array\n");
         context_destroy(swapchain->device, ctx);
         return NULL;
     }
     memcpy(ctx_array, swapchain->context, sizeof(*ctx_array) * swapchain->num_contexts);
     {
         ERR("Out of memory when trying to allocate a new context array\n");
         context_destroy(swapchain->device, ctx);
         return NULL;
     }
     memcpy(ctx_array, swapchain->context, sizeof(*ctx_array) * swapchain->num_contexts);
-    HeapFree(GetProcessHeap(), 0, swapchain->context);
+    heap_free(swapchain->context);
     ctx_array[swapchain->num_contexts] = ctx;
     swapchain->context = ctx_array;
     swapchain->num_contexts++;
     ctx_array[swapchain->num_contexts] = ctx;
     swapchain->context = ctx_array;
     swapchain->num_contexts++;
@@ -1072,7 +1084,7 @@ void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain)
     {
         context_destroy(swapchain->device, swapchain->context[i]);
     }
     {
         context_destroy(swapchain->device, swapchain->context[i]);
     }
-    HeapFree(GetProcessHeap(), 0, swapchain->context);
+    heap_free(swapchain->context);
     swapchain->num_contexts = 0;
     swapchain->context = NULL;
 }
     swapchain->num_contexts = 0;
     swapchain->context = NULL;
 }
index 98a8949..e6af0c7 100644 (file)
@@ -20,6 +20,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -30,8 +32,8 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
 static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
 {
 
 static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
 {
-    return texture->resource.pool == WINED3D_POOL_DEFAULT
-            && texture->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU
+    return !(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU)
+            && texture->resource.usage & WINED3DUSAGE_DYNAMIC
             && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]
             && !texture->resource.format->conv_byte_count
             && !(texture->flags & (WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_COND_NP2_EMULATED));
             && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]
             && !texture->resource.format->conv_byte_count
             && !(texture->flags & (WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_COND_NP2_EMULATED));
@@ -99,6 +101,11 @@ static DWORD wined3d_resource_access_from_location(DWORD location)
     }
 }
 
     }
 }
 
+static BOOL is_power_of_two(UINT x)
+{
+    return (x != 0) && !(x & (x - 1));
+}
+
 static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
 {
     struct wined3d_texture_sub_resource *sub_resource;
 static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
 {
     struct wined3d_texture_sub_resource *sub_resource;
@@ -241,9 +248,9 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture,
     if (WARN_ON(d3d))
     {
         DWORD required_access = wined3d_resource_access_from_location(location);
     if (WARN_ON(d3d))
     {
         DWORD required_access = wined3d_resource_access_from_location(location);
-        if ((texture->resource.access_flags & required_access) != required_access)
+        if ((texture->resource.access & required_access) != required_access)
             WARN("Operation requires %#x access, but texture only has %#x.\n",
             WARN("Operation requires %#x access, but texture only has %#x.\n",
-                    required_access, texture->resource.access_flags);
+                    required_access, texture->resource.access);
     }
 
     if (current & WINED3D_LOCATION_DISCARDED)
     }
 
     if (current & WINED3D_LOCATION_DISCARDED)
@@ -287,7 +294,11 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su
     if (locations & WINED3D_LOCATION_BUFFER)
     {
         data->addr = NULL;
     if (locations & WINED3D_LOCATION_BUFFER)
     {
         data->addr = NULL;
+#if !defined(STAGING_CSMT)
         data->buffer_object = sub_resource->buffer_object;
         data->buffer_object = sub_resource->buffer_object;
+#else  /* STAGING_CSMT */
+        data->buffer_object = sub_resource->buffer->name;
+#endif /* STAGING_CSMT */
         return;
     }
     if (locations & WINED3D_LOCATION_USER_MEMORY)
         return;
     }
     if (locations & WINED3D_LOCATION_USER_MEMORY)
@@ -319,12 +330,12 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
     HRESULT hr;
 
     TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
     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, "
+            "multisample_type %#x, multisample_quality %#x, usage %s, access %s, width %u, height %u, depth %u, "
             "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,
             "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,
-            flags, device, parent, parent_ops, resource_ops);
+            debug_d3dusage(desc->usage), wined3d_debug_resource_access(desc->access),
+            desc->width, desc->height, desc->depth, flags, device, parent, parent_ops, resource_ops);
 
     if (!desc->width || !desc->height || !desc->depth)
         return WINED3DERR_INVALIDCALL;
 
     if (!desc->width || !desc->height || !desc->depth)
         return WINED3DERR_INVALIDCALL;
@@ -350,7 +361,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
         return WINED3DERR_INVALIDCALL;
 
     if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
         return WINED3DERR_INVALIDCALL;
 
     if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
-            desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool,
+            desc->multisample_type, desc->multisample_quality, desc->usage, desc->access,
             desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops)))
     {
         static unsigned int once;
             desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops)))
     {
         static unsigned int once;
@@ -367,13 +378,12 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
     }
     wined3d_resource_update_draw_binding(&texture->resource);
     if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE)
     }
     wined3d_resource_update_draw_binding(&texture->resource);
     if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE)
-        texture->resource.access_flags |= WINED3D_RESOURCE_ACCESS_CPU;
+        texture->resource.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
 
     texture->texture_ops = texture_ops;
 
     texture->layer_count = layer_count;
     texture->level_count = level_count;
 
     texture->texture_ops = texture_ops;
 
     texture->layer_count = layer_count;
     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 | WINED3D_TEXTURE_NORMALIZED_COORDS;
     if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)
     texture->lod = 0;
     texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS;
     if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)
@@ -384,8 +394,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
         texture->flags |= WINED3D_TEXTURE_DISCARD;
     if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS)
     {
         texture->flags |= WINED3D_TEXTURE_DISCARD;
     if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS)
     {
-        if (~format->flags[WINED3D_GL_RES_TYPE_TEX_2D]
-                & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING))
+        if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP))
             WARN("Format doesn't support mipmaps generation, "
                     "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n");
         else
             WARN("Format doesn't support mipmaps generation, "
                     "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n");
         else
@@ -397,6 +406,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
 
 /* Context activation is done by the caller. */
 static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture,
 
 /* Context activation is done by the caller. */
 static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture,
+#if !defined(STAGING_CSMT)
         unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
 {
     GLuint *buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object;
         unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
 {
     GLuint *buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object;
@@ -409,6 +419,19 @@ static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture
 
     wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER);
     *buffer_object = 0;
 
     wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER);
     *buffer_object = 0;
+#else  /* STAGING_CSMT */
+        unsigned int sub_resource_idx, struct wined3d_context *context)
+{
+    struct wined3d_gl_bo *buffer = texture->sub_resources[sub_resource_idx].buffer;
+    GLuint name = buffer->name;
+
+    wined3d_device_release_bo(texture->resource.device, buffer, context);
+    texture->sub_resources[sub_resource_idx].buffer = NULL;
+    wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER);
+
+    TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n",
+            name, texture, sub_resource_idx);
+#endif /* STAGING_CSMT */
 }
 
 static void wined3d_texture_update_map_binding(struct wined3d_texture *texture)
 }
 
 static void wined3d_texture_update_map_binding(struct wined3d_texture *texture)
@@ -428,7 +451,11 @@ static void wined3d_texture_update_map_binding(struct wined3d_texture *texture)
                 && !wined3d_texture_load_location(texture, i, context, map_binding))
             ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding));
         if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER)
                 && !wined3d_texture_load_location(texture, i, context, map_binding))
             ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding));
         if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER)
+#if !defined(STAGING_CSMT)
             wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
             wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
+#else  /* STAGING_CSMT */
+            wined3d_texture_remove_buffer_object(texture, i, context);
+#endif /* STAGING_CSMT */
     }
 
     if (context)
     }
 
     if (context)
@@ -454,46 +481,80 @@ static void gltexture_delete(struct wined3d_device *device, const struct wined3d
     tex->name = 0;
 }
 
     tex->name = 0;
 }
 
+static unsigned int wined3d_texture_get_gl_sample_count(const struct wined3d_texture *texture)
+{
+    const struct wined3d_format *format = texture->resource.format;
+
+    /* TODO: NVIDIA expose their Coverage Sample Anti-Aliasing (CSAA)
+     * feature through type == MULTISAMPLE_XX and quality != 0. This could
+     * be mapped to GL_NV_framebuffer_multisample_coverage.
+     *
+     * AMD have a similar feature called Enhanced Quality Anti-Aliasing
+     * (EQAA), but it does not have an equivalent OpenGL extension. */
+
+    /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality
+     * levels as the count of advertised multisample types for the texture
+     * format. */
+    if (texture->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
+    {
+        unsigned int i, count = 0;
+
+        for (i = 0; i < sizeof(format->multisample_types) * CHAR_BIT; ++i)
+        {
+            if (format->multisample_types & 1u << i)
+            {
+                if (texture->resource.multisample_quality == count++)
+                    break;
+            }
+        }
+        return i + 1;
+    }
+
+    return texture->resource.multisample_type;
+}
+
 /* Context activation is done by the caller. */
 /* The caller is responsible for binding the correct texture. */
 static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *texture,
         GLenum gl_internal_format, const struct wined3d_format *format,
         const struct wined3d_gl_info *gl_info)
 {
 /* Context activation is done by the caller. */
 /* The caller is responsible for binding the correct texture. */
 static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *texture,
         GLenum gl_internal_format, const struct wined3d_format *format,
         const struct wined3d_gl_info *gl_info)
 {
-    unsigned int i, sub_call_count;
+    unsigned int level, level_count, layer, layer_count;
+    GLsizei width, height;
+    GLenum target;
 
 
-    sub_call_count = texture->level_count;
-    if (texture->target != GL_TEXTURE_2D_ARRAY)
-        sub_call_count *= texture->layer_count;
+    level_count = texture->level_count;
+    layer_count = texture->target == GL_TEXTURE_2D_ARRAY ? 1 : texture->layer_count;
 
 
-    for (i = 0; i < sub_call_count; ++i)
+    for (layer = 0; layer < layer_count; ++layer)
     {
     {
-        struct wined3d_surface *surface = texture->sub_resources[i].u.surface;
-        GLsizei width, height;
+        target = wined3d_texture_get_sub_resource_target(texture, layer * level_count);
 
 
-        width = wined3d_texture_get_level_pow2_width(texture, surface->texture_level);
-        height = wined3d_texture_get_level_pow2_height(texture, surface->texture_level);
-        if (texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
+        for (level = 0; level < level_count; ++level)
         {
         {
-            height *= format->height_scale.numerator;
-            height /= format->height_scale.denominator;
-        }
+            width = wined3d_texture_get_level_pow2_width(texture, level);
+            height = wined3d_texture_get_level_pow2_height(texture, level);
+            if (texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
+            {
+                height *= format->height_scale.numerator;
+                height /= format->height_scale.denominator;
+            }
 
 
-        TRACE("surface %p, target %#x, level %u, width %u, height %u.\n",
-                surface, surface->texture_target, surface->texture_level, width, height);
+            TRACE("texture %p, layer %u, level %u, target %#x, width %u, height %u.\n",
+                    texture, layer, level, target, width, height);
 
 
-        if (texture->target == GL_TEXTURE_2D_ARRAY)
-        {
-            GL_EXTCALL(glTexImage3D(surface->texture_target, surface->texture_level,
-                    gl_internal_format, width, height, texture->layer_count, 0,
-                    format->glFormat, format->glType, NULL));
-            checkGLcall("glTexImage3D");
-        }
-        else
-        {
-            gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
-                    gl_internal_format, width, height, 0, format->glFormat, format->glType, NULL);
-            checkGLcall("glTexImage2D");
+            if (texture->target == GL_TEXTURE_2D_ARRAY)
+            {
+                GL_EXTCALL(glTexImage3D(target, level, gl_internal_format, width, height,
+                        texture->layer_count, 0, format->glFormat, format->glType, NULL));
+                checkGLcall("glTexImage3D");
+            }
+            else
+            {
+                gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format,
+                        width, height, 0, format->glFormat, format->glType, NULL);
+                checkGLcall("glTexImage2D");
+            }
         }
     }
 }
         }
     }
 }
@@ -503,21 +564,31 @@ static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *
 static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture *texture,
         GLenum gl_internal_format, const struct wined3d_gl_info *gl_info)
 {
 static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture *texture,
         GLenum gl_internal_format, const struct wined3d_gl_info *gl_info)
 {
-    GLsizei width = wined3d_texture_get_level_pow2_width(texture, 0);
+    unsigned int samples = wined3d_texture_get_gl_sample_count(texture);
     GLsizei height = wined3d_texture_get_level_pow2_height(texture, 0);
     GLsizei height = wined3d_texture_get_level_pow2_height(texture, 0);
+    GLsizei width = wined3d_texture_get_level_pow2_width(texture, 0);
 
 
-    if (texture->target == GL_TEXTURE_2D_ARRAY)
-    {
-        GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count, gl_internal_format,
-                width, height, texture->layer_count));
-        checkGLcall("glTexStorage3D");
-    }
-    else
+    switch (texture->target)
     {
     {
-        GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, gl_internal_format,
-                width, height));
-        checkGLcall("glTexStorage2D");
+        case GL_TEXTURE_2D_ARRAY:
+            GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count,
+                    gl_internal_format, width, height, texture->layer_count));
+            break;
+        case GL_TEXTURE_2D_MULTISAMPLE:
+            GL_EXTCALL(glTexStorage2DMultisample(texture->target, samples,
+                    gl_internal_format, width, height, GL_FALSE));
+            break;
+        case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+            GL_EXTCALL(glTexStorage3DMultisample(texture->target, samples,
+                    gl_internal_format, width, height, texture->layer_count, GL_FALSE));
+            break;
+        default:
+            GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
+                    gl_internal_format, width, height));
+            break;
     }
     }
+
+    checkGLcall("allocate immutable storage");
 }
 
 static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture)
 }
 
 static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture)
@@ -585,33 +656,66 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture)
     unsigned int sub_count = texture->level_count * texture->layer_count;
     struct wined3d_device *device = texture->resource.device;
     struct wined3d_context *context = NULL;
     unsigned int sub_count = texture->level_count * texture->layer_count;
     struct wined3d_device *device = texture->resource.device;
     struct wined3d_context *context = NULL;
+#if !defined(STAGING_CSMT)
     const struct wined3d_gl_info *gl_info;
     GLuint buffer_object;
     const struct wined3d_gl_info *gl_info;
     GLuint buffer_object;
+#else  /* STAGING_CSMT */
+    struct wined3d_gl_bo *buffer;
+#endif /* STAGING_CSMT */
     unsigned int i;
 
     TRACE("texture %p.\n", texture);
 
     for (i = 0; i < sub_count; ++i)
     {
     unsigned int i;
 
     TRACE("texture %p.\n", texture);
 
     for (i = 0; i < sub_count; ++i)
     {
+#if !defined(STAGING_CSMT)
         if (!(buffer_object = texture->sub_resources[i].buffer_object))
             continue;
 
         TRACE("Deleting buffer object %u.\n", buffer_object);
         if (!(buffer_object = texture->sub_resources[i].buffer_object))
             continue;
 
         TRACE("Deleting buffer object %u.\n", buffer_object);
+#else  /* STAGING_CSMT */
+        if (!(buffer = texture->sub_resources[i].buffer))
+            continue;
+
+        TRACE("Deleting buffer object %u.\n", buffer->name);
+#endif /* STAGING_CSMT */
 
         /* We may not be able to get a context in wined3d_texture_cleanup() in
          * general, but if a buffer object was previously created we can. */
         if (!context)
 
         /* We may not be able to get a context in wined3d_texture_cleanup() in
          * general, but if a buffer object was previously created we can. */
         if (!context)
+#if !defined(STAGING_CSMT)
         {
             context = context_acquire(device, NULL, 0);
             gl_info = context->gl_info;
         }
 
         GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
         {
             context = context_acquire(device, NULL, 0);
             gl_info = context->gl_info;
         }
 
         GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
+#else  /* STAGING_CSMT */
+            context = context_acquire(device, NULL, 0);
+
+        wined3d_device_release_bo(device, buffer, context);
+        texture->sub_resources[i].buffer = NULL;
+#endif /* STAGING_CSMT */
     }
     if (context)
         context_release(context);
 
     texture->texture_ops->texture_cleanup_sub_resources(texture);
     }
     if (context)
         context_release(context);
 
     texture->texture_ops->texture_cleanup_sub_resources(texture);
+    if (texture->overlay_info)
+    {
+        for (i = 0; i < sub_count; ++i)
+        {
+            struct wined3d_overlay_info *info = &texture->overlay_info[i];
+            struct wined3d_overlay_info *overlay, *cur;
+
+            list_remove(&info->entry);
+            LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry)
+            {
+                list_remove(&overlay->entry);
+            }
+        }
+        heap_free(texture->overlay_info);
+    }
     wined3d_texture_unload_gl_texture(texture);
 }
 
     wined3d_texture_unload_gl_texture(texture);
 }
 
@@ -685,12 +789,6 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
 
     context_bind_texture(context, target, gl_tex->name);
 
 
     context_bind_texture(context, target, gl_tex->name);
 
-    if (texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)
-    {
-        gl_info->gl_ops.gl.p_glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
-        checkGLcall("glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)");
-    }
-
     /* For a new texture we have to set the texture levels after binding the
      * texture. Beware that texture rectangles do not support mipmapping, but
      * set the maxmiplevel if we're relying on the partial
     /* For a new texture we have to set the texture levels after binding the
      * texture. Beware that texture rectangles do not support mipmapping, but
      * set the maxmiplevel if we're relying on the partial
@@ -919,7 +1017,7 @@ static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture)
 static void wined3d_texture_destroy_object(void *object)
 {
     wined3d_texture_cleanup(object);
 static void wined3d_texture_destroy_object(void *object)
 {
     wined3d_texture_cleanup(object);
-    HeapFree(GetProcessHeap(), 0, object);
+    heap_free(object);
 }
 
 ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
 }
 
 ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
@@ -1093,9 +1191,10 @@ DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod)
 
     /* The d3d9:texture test shows that SetLOD is ignored on non-managed
      * textures. The call always returns 0, and GetLOD always returns 0. */
 
     /* The d3d9:texture test shows that SetLOD is ignored on non-managed
      * textures. The call always returns 0, and GetLOD always returns 0. */
-    if (texture->resource.pool != WINED3D_POOL_MANAGED)
+    if (!wined3d_resource_access_is_managed(texture->resource.access))
     {
     {
-        TRACE("Ignoring SetLOD on %s texture, returning 0.\n", debug_d3dpool(texture->resource.pool));
+        TRACE("Ignoring LOD on texture with resource access %s.\n",
+                wined3d_debug_resource_access(texture->resource.access));
         return 0;
     }
 
         return 0;
     }
 
@@ -1133,29 +1232,6 @@ DWORD CDECL wined3d_texture_get_level_count(const struct wined3d_texture *textur
     return texture->level_count;
 }
 
     return texture->level_count;
 }
 
-HRESULT CDECL wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture,
-        enum wined3d_texture_filter_type filter_type)
-{
-    FIXME("texture %p, filter_type %s stub!\n", texture, debug_d3dtexturefiltertype(filter_type));
-
-    if (!(texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP))
-    {
-        WARN("Texture doesn't have AUTOGENMIPMAP usage.\n");
-        return WINED3DERR_INVALIDCALL;
-    }
-
-    texture->filter_type = filter_type;
-
-    return WINED3D_OK;
-}
-
-enum wined3d_texture_filter_type CDECL wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture)
-{
-    TRACE("texture %p.\n", texture);
-
-    return texture->filter_type;
-}
-
 HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
         DWORD flags, const struct wined3d_color_key *color_key)
 {
 HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
         DWORD flags, const struct wined3d_color_key *color_key)
 {
@@ -1210,7 +1286,8 @@ static void texture2d_create_dc(void *object)
     wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
     wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
     desc.pMemory = context_map_bo_address(context, &data,
     wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
     wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
     desc.pMemory = context_map_bo_address(context, &data,
-            texture->sub_resources[sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0);
+            texture->sub_resources[sub_resource_idx].size,
+            GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ | WINED3D_MAP_WRITE);
 
     if (context)
         context_release(context);
 
     if (context)
         context_release(context);
@@ -1302,9 +1379,15 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    if (texture->resource.type == WINED3D_RTYPE_TEXTURE_3D)
+    if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
+    {
+        WARN("Not supported on %s.\n", debug_d3dresourcetype(texture->resource.type));
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if (texture->resource.type == WINED3D_RTYPE_TEXTURE_1D)
     {
     {
-        WARN("Not supported on 3D textures.\n");
+        FIXME("Not yet supported for 1D textures.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
@@ -1358,7 +1441,12 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
     sub_resource->size = texture->slice_pitch;
     sub_resource->locations = WINED3D_LOCATION_DISCARDED;
 
     sub_resource->size = texture->slice_pitch;
     sub_resource->locations = WINED3D_LOCATION_DISCARDED;
 
-    if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
+    if (multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+        texture->target = GL_TEXTURE_2D_MULTISAMPLE;
+    else
+        texture->target = GL_TEXTURE_2D;
+
+    if ((!is_power_of_two(width) || !is_power_of_two(height)) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
             && !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
     {
         texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED;
             && !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
     {
         texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED;
@@ -1407,11 +1495,16 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
 
 /* Context activation is done by the caller. */
 static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture,
 
 /* Context activation is done by the caller. */
 static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture,
+#if !defined(STAGING_CSMT)
         unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
         unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
+#else  /* STAGING_CSMT */
+        unsigned int sub_resource_idx, struct wined3d_context *context)
+#endif /* STAGING_CSMT */
 {
     struct wined3d_texture_sub_resource *sub_resource;
 
     sub_resource = &texture->sub_resources[sub_resource_idx];
 {
     struct wined3d_texture_sub_resource *sub_resource;
 
     sub_resource = &texture->sub_resources[sub_resource_idx];
+#if !defined(STAGING_CSMT)
     if (sub_resource->buffer_object)
         return;
 
     if (sub_resource->buffer_object)
         return;
 
@@ -1423,6 +1516,16 @@ static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *textur
 
     TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
             sub_resource->buffer_object, texture, sub_resource_idx);
 
     TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
             sub_resource->buffer_object, texture, sub_resource_idx);
+#else  /* STAGING_CSMT */
+    if (sub_resource->buffer)
+        return;
+
+    sub_resource->buffer = wined3d_device_get_bo(texture->resource.device,
+            sub_resource->size, GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context);
+
+    TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
+            sub_resource->buffer->name, texture, sub_resource_idx);
+#endif /* STAGING_CSMT */
 }
 
 static void wined3d_texture_force_reload(struct wined3d_texture *texture)
 }
 
 static void wined3d_texture_force_reload(struct wined3d_texture *texture)
@@ -1474,34 +1577,7 @@ static void wined3d_texture_prepare_rb(struct wined3d_texture *texture,
         if (texture->rb_multisample)
             return;
 
         if (texture->rb_multisample)
             return;
 
-        /* TODO: NVIDIA expose their Coverage Sample Anti-Aliasing (CSAA)
-         * feature through type == MULTISAMPLE_XX and quality != 0. This could
-         * be mapped to GL_NV_framebuffer_multisample_coverage.
-         *
-         * AMD have a similar feature called Enhanced Quality Anti-Aliasing
-         * (EQAA), but it does not have an equivalent OpenGL extension. */
-
-        /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality
-         * levels as the count of advertised multisample types for the texture
-         * format. */
-        if (texture->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
-        {
-            unsigned int i, count = 0;
-
-            for (i = 0; i < sizeof(format->multisample_types) * 8; ++i)
-            {
-                if (format->multisample_types & 1u << i)
-                {
-                    if (texture->resource.multisample_quality == count++)
-                        break;
-                }
-            }
-            samples = i + 1;
-        }
-        else
-        {
-            samples = texture->resource.multisample_type;
-        }
+        samples = wined3d_texture_get_gl_sample_count(texture);
 
         gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_multisample);
         gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_multisample);
 
         gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_multisample);
         gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_multisample);
@@ -1548,7 +1624,11 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned
             return TRUE;
 
         case WINED3D_LOCATION_BUFFER:
             return TRUE;
 
         case WINED3D_LOCATION_BUFFER:
+#if !defined(STAGING_CSMT)
             wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context->gl_info);
             wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context->gl_info);
+#else  /* STAGING_CSMT */
+            wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context);
+#endif /* STAGING_CSMT */
             return TRUE;
 
         case WINED3D_LOCATION_TEXTURE_RGB:
             return TRUE;
 
         case WINED3D_LOCATION_TEXTURE_RGB:
@@ -1606,7 +1686,7 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
     }
 
     if (dirty_region)
     }
 
     if (dirty_region)
-        FIXME("Ignoring dirty_region %s.\n", debug_box(dirty_region));
+        WARN("Ignoring dirty_region %s.\n", debug_box(dirty_region));
 
     wined3d_cs_emit_add_dirty_texture_region(texture->resource.device->cs, texture, layer);
 
 
     wined3d_cs_emit_add_dirty_texture_region(texture->resource.device->cs, texture, layer);
 
@@ -1621,136 +1701,506 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
             context, box, data, row_pitch, slice_pitch);
 }
 
             context, box, data, row_pitch, slice_pitch);
 }
 
-static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
-        const struct wined3d_context *context, const struct wined3d_box *box,
-        const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch)
+
+/* This call just uploads data, the caller is responsible for binding the
+ * correct texture. */
+/* Context activation is done by the caller. */
+static void texture1d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        const struct wined3d_context *context, const struct wined3d_box *box, const struct wined3d_const_bo_address *data,
+        unsigned int row_pitch, unsigned int slice_pitch)
 {
 {
-    unsigned int texture_level;
-    POINT dst_point;
-    RECT src_rect;
+    struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
+    const struct wined3d_format *format = texture->resource.format;
+    unsigned int level = sub_resource_idx % texture->level_count;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    const void *mem = data->addr;
+    void *converted_mem = NULL;
+    unsigned int width, x, update_w;
+    GLenum target;
 
 
-    src_rect.left = 0;
-    src_rect.top = 0;
-    if (box)
+    TRACE("texture %p, sub_resource_idx %u, context %p, box %p, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n",
+            texture, sub_resource_idx, context, box, data->buffer_object, data->addr, row_pitch, slice_pitch);
+
+    width = wined3d_texture_get_level_width(texture, level);
+
+    if (!box)
     {
     {
-        dst_point.x = box->left;
-        dst_point.y = box->top;
-        src_rect.right = box->right - box->left;
-        src_rect.bottom = box->bottom - box->top;
+        x = 0;
+        update_w = width;
     }
     else
     {
     }
     else
     {
-        dst_point.x = dst_point.y = 0;
-        texture_level = sub_resource_idx % texture->level_count;
-        src_rect.right = wined3d_texture_get_level_width(texture, texture_level);
-        src_rect.bottom = wined3d_texture_get_level_height(texture, texture_level);
+        x = box->left;
+        update_w = box->right - box->left;
     }
 
     }
 
-    wined3d_surface_upload_data(texture->sub_resources[sub_resource_idx].u.surface, context->gl_info,
-            texture->resource.format, &src_rect, row_pitch, &dst_point, FALSE, data);
-}
+    if (format->upload)
+    {
+        unsigned int dst_row_pitch;
 
 
-static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
-        struct wined3d_context *context, DWORD location)
-{
-    return surface_load_location(texture->sub_resources[sub_resource_idx].u.surface, context, location);
-}
+        if (data->buffer_object)
+            ERR("Loading a converted texture from a PBO.\n");
+        if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
+            ERR("Converting a block-based format.\n");
 
 
-/* Context activation is done by the caller. */
-static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
-{
-    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;
+        dst_row_pitch = update_w * format->conv_byte_count;
 
 
-    TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id));
+        converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_row_pitch);
+        format->upload(data->addr, converted_mem, row_pitch, slice_pitch, dst_row_pitch, dst_row_pitch, update_w, 1, 1);
+        mem = converted_mem;
+    }
 
 
-    if (format->conv_byte_count)
+    if (data->buffer_object)
     {
     {
-        texture->flags |= WINED3D_TEXTURE_CONVERTED;
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
+        checkGLcall("glBindBuffer");
     }
     }
-    else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
+
+    target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+    if (target == GL_TEXTURE_1D_ARRAY)
     {
     {
-        texture->flags |= WINED3D_TEXTURE_CONVERTED;
-        format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
-        TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id));
-    }
+        gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, row_pitch / format->byte_count);
 
 
-    wined3d_texture_bind_and_dirtify(texture, context, srgb);
+        gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, x, surface->texture_layer, update_w, 1, format->glFormat, format->glType, mem);
+        checkGLcall("glTexSubImage2D");
 
 
-    if (srgb)
-        internal = format->glGammaInternal;
-    else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
-            && wined3d_resource_is_offscreen(&texture->resource))
-        internal = format->rtInternal;
+        gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    }
     else
     else
-        internal = format->glInternal;
-
-    if (!internal)
-        FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
+    {
+        gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, x, update_w, format->glFormat, format->glType, mem);
+        checkGLcall("glTexSubImage1D");
+    }
 
 
-    TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType);
+    if (data->buffer_object)
+    {
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+        checkGLcall("glBindBuffer");
+    }
 
 
-    if (wined3d_texture_use_immutable_storage(texture, gl_info))
-        wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info);
-    else
-        wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info);
+    HeapFree(GetProcessHeap(), 0, converted_mem);
 }
 
 }
 
-static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture)
+/* Context activation is done by the caller. */
+static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        const struct wined3d_context *context, const struct wined3d_bo_address *data)
 {
 {
-    unsigned int sub_count = texture->level_count * texture->layer_count;
-    struct wined3d_device *device = texture->resource.device;
+    struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
+    const struct wined3d_format *format = texture->resource.format;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_texture_sub_resource *sub_resource;
     struct wined3d_texture_sub_resource *sub_resource;
-    struct wined3d_renderbuffer_entry *entry, *entry2;
-    const struct wined3d_gl_info *gl_info = NULL;
-    struct wined3d_context *context = NULL;
-    struct wined3d_surface *overlay, *cur;
-    struct wined3d_surface *surface;
-    unsigned int i;
+    BYTE *temporary_mem = NULL;
+    void *mem;
+    GLenum target;
 
 
-    for (i = 0; i < sub_count; ++i)
-    {
-        sub_resource = &texture->sub_resources[i];
-        if (!(surface = sub_resource->u.surface))
-            continue;
+    sub_resource = &texture->sub_resources[sub_resource_idx];
 
 
-        TRACE("surface %p.\n", surface);
+    if (format->conv_byte_count)
+    {
+        FIXME("Attempting to download a converted 1d texture, format %s.\n",
+                debug_d3dformat(format->id));
+        return;
+    }
 
 
-        if (!context && !list_empty(&surface->renderbuffers))
-        {
-            context = context_acquire(device, NULL, 0);
-            gl_info = context->gl_info;
-        }
+    target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+    if (target == GL_TEXTURE_1D_ARRAY)
+    {
+         WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n");
 
 
-        LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+        if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size)))
         {
         {
-            TRACE("Deleting renderbuffer %u.\n", entry->id);
-            context_gl_resource_released(device, entry->id, TRUE);
-            gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
-            HeapFree(GetProcessHeap(), 0, entry);
+            ERR("Out of memory.\n");
+            return;
         }
 
         }
 
-        if (surface->dc)
-            texture2d_destroy_dc(surface);
+        mem = temporary_mem;
+    }
+    else if (data->buffer_object)
+    {
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
+        checkGLcall("glBindBuffer");
+        mem = data->addr;
+    }
+    else
+        mem = data->addr;
 
 
-        if (surface->overlay_dest)
-            list_remove(&surface->overlay_entry);
+    gl_info->gl_ops.gl.p_glGetTexImage(target, sub_resource_idx,
+            format->glFormat, format->glType, mem);
+    checkGLcall("glGetTexImage");
 
 
-        LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &surface->overlays, struct wined3d_surface, overlay_entry)
+    if (temporary_mem)
+    {
+        void *src_data = temporary_mem + surface->texture_layer * sub_resource->size;
+        if (data->buffer_object)
+        {
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
+            checkGLcall("glBindBuffer");
+            GL_EXTCALL(glBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, src_data));
+            checkGLcall("glBufferSubData");
+        }
+        else
         {
         {
-            list_remove(&overlay->overlay_entry);
-            overlay->overlay_dest = NULL;
+            memcpy(data->addr, src_data, sub_resource->size);
         }
     }
         }
     }
-    if (context)
-        context_release(context);
-    HeapFree(GetProcessHeap(), 0, texture->sub_resources[0].u.surface);
+
+    if (data->buffer_object)
+    {
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+        checkGLcall("glBindBuffer");
+    }
+
+    HeapFree(GetProcessHeap(), 0, temporary_mem);
 }
 
 }
 
-static const struct wined3d_texture_ops texture2d_ops =
-{
+/* Context activation is done by the caller. */
+static void texture1d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        struct wined3d_context *context, BOOL dest_is_srgb)
+{
+    struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
+    unsigned int row_pitch, slice_pitch;
+    struct wined3d_bo_address data;
+
+    WARN_(d3d_perf)("Performing slow rgb/srgb 1d texture transfer.\n");
+    data.buffer_object = 0;
+    if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size)))
+        return;
+
+    wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+    wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb);
+    texture1d_download_data(texture, sub_resource_idx, context, &data);
+    wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb);
+    texture1d_upload_data(texture, sub_resource_idx, context, NULL,
+            wined3d_const_bo_address(&data), row_pitch, slice_pitch);
+
+    HeapFree(GetProcessHeap(), 0, data.addr);
+}
+
+/* Context activation is done by the caller. */
+static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        struct wined3d_context *context, DWORD location)
+{
+    struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
+    DWORD required_access = wined3d_resource_access_from_location(location);
+    unsigned int row_pitch, slice_pitch;
+
+    TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
+            texture, sub_resource_idx, context, wined3d_debug_location(location));
+
+    TRACE("Current resource location %s.\n", wined3d_debug_location(sub_resource->locations));
+
+    if ((sub_resource->locations & location) == location)
+    {
+        TRACE("Location(s) already up to date.\n");
+        return TRUE;
+    }
+
+    if ((texture->resource.access & required_access) != required_access)
+    {
+        ERR("Operation requires %#x access, but 1d texture only has %#x.\n",
+                required_access, texture->resource.access);
+        return FALSE;
+    }
+
+    if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
+        return FALSE;
+
+    if (sub_resource->locations & WINED3D_LOCATION_DISCARDED)
+    {
+        TRACE("1d texture previously discarded, nothing to do.\n");
+        wined3d_texture_validate_location(texture, sub_resource_idx, location);
+        wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED);
+        goto done;
+    }
+
+    switch (location)
+    {
+        case WINED3D_LOCATION_TEXTURE_RGB:
+        case WINED3D_LOCATION_TEXTURE_SRGB:
+            if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
+            {
+                struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
+                data.addr += sub_resource->offset;
+                wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB);
+                wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+                texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
+            }
+            else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
+            {
+#if !defined(STAGING_CSMT)
+                struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
+#else  /* STAGING_CSMT */
+                struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL};
+#endif /* STAGING_CSMT */
+                wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB);
+                wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+                texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
+            }
+            else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+            {
+                texture1d_srgb_transfer(texture, sub_resource_idx, context, TRUE);
+            }
+            else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB)
+            {
+                texture1d_srgb_transfer(texture, sub_resource_idx, context, FALSE);
+            }
+            else
+            {
+                FIXME("Implement 1d texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
+                return FALSE;
+            }
+            break;
+
+        case WINED3D_LOCATION_SYSMEM:
+            if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+            {
+                struct wined3d_bo_address data = {0, texture->resource.heap_memory};
+
+                data.addr += sub_resource->offset;
+                if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+                    wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+                else
+                    wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+
+                texture1d_download_data(texture, sub_resource_idx, context, &data);
+                ++texture->download_count;
+            }
+            else
+            {
+                FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
+                        wined3d_debug_location(sub_resource->locations));
+                return FALSE;
+            }
+            break;
+
+        case WINED3D_LOCATION_BUFFER:
+            if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+            {
+#if !defined(STAGING_CSMT)
+                struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
+#else  /* STAGING_CSMT */
+                struct wined3d_bo_address data = {sub_resource->buffer->name, NULL};
+#endif /* STAGING_CSMT */
+
+                if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+                    wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+                else
+                    wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+
+                texture1d_download_data(texture, sub_resource_idx, context, &data);
+            }
+            else
+            {
+                FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
+                        wined3d_debug_location(sub_resource->locations));
+                return FALSE;
+            }
+            break;
+
+        default:
+            FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
+                    wined3d_debug_location(sub_resource->locations));
+            return FALSE;
+    }
+
+done:
+    wined3d_texture_validate_location(texture, sub_resource_idx, location);
+
+    return TRUE;
+}
+
+static void texture1d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
+{
+    const struct wined3d_format *format = texture->resource.format;
+    unsigned int sub_count = texture->level_count * texture->layer_count;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned int width;
+    GLenum internal;
+
+    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 (wined3d_texture_use_immutable_storage(texture, gl_info))
+    {
+        width = wined3d_texture_get_level_width(texture, 0);
+
+        if (texture->target == GL_TEXTURE_1D_ARRAY)
+        {
+            GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, internal, width, texture->layer_count));
+            checkGLcall("glTexStorage2D");
+        }
+        else
+        {
+            GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, internal, width));
+            checkGLcall("glTexStorage1D");
+        }
+    }
+    else
+    {
+        unsigned int i;
+
+        for (i = 0; i < sub_count; ++i)
+        {
+            GLenum target;
+            struct wined3d_surface *surface = texture->sub_resources[i].u.surface;
+            width = wined3d_texture_get_level_width(texture, surface->texture_level);
+            target = wined3d_texture_get_sub_resource_target(texture, i);
+
+            if (texture->target == GL_TEXTURE_1D_ARRAY)
+            {
+                gl_info->gl_ops.gl.p_glTexImage2D(target, surface->texture_level,
+                        internal, width, texture->layer_count, 0, format->glFormat, format->glType, NULL);
+                checkGLcall("glTexImage2D");
+            }
+            else
+            {
+                gl_info->gl_ops.gl.p_glTexImage1D(target, surface->texture_level,
+                        internal, width, 0, format->glFormat, format->glType, NULL);
+                checkGLcall("glTexImage1D");
+            }
+        }
+    }
+}
+
+static void texture1d_cleanup_sub_resources(struct wined3d_texture *texture)
+{
+}
+
+static const struct wined3d_texture_ops texture1d_ops =
+{
+    texture1d_upload_data,
+    texture1d_load_location,
+    texture1d_prepare_texture,
+    texture1d_cleanup_sub_resources,
+};
+
+static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        const struct wined3d_context *context, const struct wined3d_box *box,
+        const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch)
+{
+    unsigned int texture_level;
+    POINT dst_point;
+    RECT src_rect;
+
+    src_rect.left = 0;
+    src_rect.top = 0;
+    if (box)
+    {
+        dst_point.x = box->left;
+        dst_point.y = box->top;
+        src_rect.right = box->right - box->left;
+        src_rect.bottom = box->bottom - box->top;
+    }
+    else
+    {
+        dst_point.x = dst_point.y = 0;
+        texture_level = sub_resource_idx % texture->level_count;
+        src_rect.right = wined3d_texture_get_level_width(texture, texture_level);
+        src_rect.bottom = wined3d_texture_get_level_height(texture, texture_level);
+    }
+
+    wined3d_surface_upload_data(texture->sub_resources[sub_resource_idx].u.surface, context->gl_info,
+            texture->resource.format, &src_rect, row_pitch, &dst_point, FALSE, data);
+}
+
+static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        struct wined3d_context *context, DWORD location)
+{
+    return surface_load_location(texture->sub_resources[sub_resource_idx].u.surface, context, location);
+}
+
+/* Context activation is done by the caller. */
+static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
+{
+    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;
+
+    TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id));
+
+    if (format->conv_byte_count)
+    {
+        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, texture->resource.usage);
+        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);
+
+    if (wined3d_texture_use_immutable_storage(texture, gl_info))
+        wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info);
+    else
+        wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info);
+}
+
+static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture)
+{
+    unsigned int sub_count = texture->level_count * texture->layer_count;
+    struct wined3d_device *device = texture->resource.device;
+    struct wined3d_texture_sub_resource *sub_resource;
+    struct wined3d_renderbuffer_entry *entry, *entry2;
+    const struct wined3d_gl_info *gl_info = NULL;
+    struct wined3d_context *context = NULL;
+    struct wined3d_surface *surface;
+    unsigned int i;
+
+    for (i = 0; i < sub_count; ++i)
+    {
+        sub_resource = &texture->sub_resources[i];
+        if (!(surface = sub_resource->u.surface))
+            continue;
+
+        TRACE("surface %p.\n", surface);
+
+        if (!context && !list_empty(&surface->renderbuffers))
+        {
+            context = context_acquire(device, NULL, 0);
+            gl_info = context->gl_info;
+        }
+
+        LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+        {
+            TRACE("Deleting renderbuffer %u.\n", entry->id);
+            context_gl_resource_released(device, entry->id, TRUE);
+            gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+            heap_free(entry);
+        }
+
+        if (surface->dc)
+            texture2d_destroy_dc(surface);
+    }
+    if (context)
+        context_release(context);
+    heap_free(texture->sub_resources[0].u.surface);
+}
+
+static const struct wined3d_texture_ops texture2d_ops =
+{
     texture2d_upload_data,
     texture2d_load_location,
     texture2d_prepare_texture,
     texture2d_upload_data,
     texture2d_load_location,
     texture2d_prepare_texture,
@@ -1800,7 +2250,7 @@ static void wined3d_texture_unload(struct wined3d_resource *resource)
     {
         struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[i];
 
     {
         struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[i];
 
-        if (resource->pool != WINED3D_POOL_DEFAULT
+        if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
                 && wined3d_texture_load_location(texture, i, context, resource->map_binding))
         {
             wined3d_texture_invalidate_location(texture, i, ~resource->map_binding);
                 && wined3d_texture_load_location(texture, i, context, resource->map_binding))
         {
             wined3d_texture_invalidate_location(texture, i, ~resource->map_binding);
@@ -1809,15 +2259,22 @@ static void wined3d_texture_unload(struct wined3d_resource *resource)
         {
             /* We should only get here on device reset/teardown for implicit
              * resources. */
         {
             /* We should only get here on device reset/teardown for implicit
              * resources. */
-            if (resource->pool != WINED3D_POOL_DEFAULT || resource->type != WINED3D_RTYPE_TEXTURE_2D)
-                ERR("Discarding %s %p sub-resource %u in the %s pool.\n", debug_d3dresourcetype(resource->type),
-                        resource, i, debug_d3dpool(resource->pool));
+            if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
+                    || resource->type != WINED3D_RTYPE_TEXTURE_2D)
+                ERR("Discarding %s %p sub-resource %u with resource access %s.\n",
+                        debug_d3dresourcetype(resource->type), resource, i,
+                        wined3d_debug_resource_access(resource->access));
             wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_DISCARDED);
             wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED);
         }
 
             wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_DISCARDED);
             wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED);
         }
 
+#if !defined(STAGING_CSMT)
         if (sub_resource->buffer_object)
             wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
         if (sub_resource->buffer_object)
             wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
+#else  /* STAGING_CSMT */
+        if (sub_resource->buffer)
+            wined3d_texture_remove_buffer_object(texture, i, context);
+#endif /* STAGING_CSMT */
 
         if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
         {
 
         if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
         {
@@ -1829,7 +2286,7 @@ static void wined3d_texture_unload(struct wined3d_resource *resource)
                 context_gl_resource_released(device, entry->id, TRUE);
                 gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
                 list_remove(&entry->entry);
                 context_gl_resource_released(device, entry->id, TRUE);
                 gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
                 list_remove(&entry->entry);
-                HeapFree(GetProcessHeap(), 0, entry);
+                heap_free(entry);
             }
             list_init(&surface->renderbuffers);
             surface->current_renderbuffer = NULL;
             }
             list_init(&surface->renderbuffers);
             surface->current_renderbuffer = NULL;
@@ -1867,18 +2324,11 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
     if (box && FAILED(wined3d_texture_check_box_dimensions(texture, texture_level, box)))
     {
         WARN("Map box is invalid.\n");
     if (box && FAILED(wined3d_texture_check_box_dimensions(texture, texture_level, box)))
     {
         WARN("Map box is invalid.\n");
-        if (((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && resource->pool == WINED3D_POOL_DEFAULT)
+        if (((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !(resource->access & WINED3D_RESOURCE_ACCESS_CPU))
                 || resource->type != WINED3D_RTYPE_TEXTURE_2D)
             return WINED3DERR_INVALIDCALL;
     }
 
                 || resource->type != WINED3D_RTYPE_TEXTURE_2D)
             return WINED3DERR_INVALIDCALL;
     }
 
-    if (!(resource->access_flags & WINED3D_RESOURCE_ACCESS_CPU))
-    {
-        WARN("Trying to map unmappable texture.\n");
-        if (resource->type != WINED3D_RTYPE_TEXTURE_2D)
-            return WINED3DERR_INVALIDCALL;
-    }
-
     if (texture->flags & WINED3D_TEXTURE_DC_IN_USE)
     {
         WARN("DC is in use.\n");
     if (texture->flags & WINED3D_TEXTURE_DC_IN_USE)
     {
         WARN("DC is in use.\n");
@@ -1915,7 +2365,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
         return E_OUTOFMEMORY;
     }
 
         return E_OUTOFMEMORY;
     }
 
-    if (!(flags & WINED3D_MAP_READONLY)
+    if (flags & WINED3D_MAP_WRITE
             && (!(flags & WINED3D_MAP_NO_DIRTY_UPDATE) || (resource->usage & WINED3DUSAGE_DYNAMIC)))
         wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding);
 
             && (!(flags & WINED3D_MAP_NO_DIRTY_UPDATE) || (resource->usage & WINED3DUSAGE_DYNAMIC)))
         wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding);
 
@@ -1980,6 +2430,36 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+static HRESULT texture_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+        struct wined3d_map_info *info, DWORD flags)
+{
+    const struct wined3d_format *format = resource->format;
+    struct wined3d_texture_sub_resource *sub_resource;
+    unsigned int fmt_flags = resource->format_flags;
+    struct wined3d_texture *texture;
+    unsigned int texture_level;
+
+    texture = texture_from_resource(resource);
+    if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
+        return E_INVALIDARG;
+
+    texture_level = sub_resource_idx % texture->level_count;
+
+    if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
+    {
+        info->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count;
+        info->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * info->row_pitch;
+    }
+    else
+    {
+        wined3d_texture_get_pitch(texture, texture_level, &info->row_pitch, &info->slice_pitch);
+    }
+
+    info->size = info->slice_pitch * wined3d_texture_get_level_depth(texture, texture_level);
+
+    return WINED3D_OK;
+}
+
 static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
 {
     struct wined3d_texture_sub_resource *sub_resource;
 static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
 {
     struct wined3d_texture_sub_resource *sub_resource;
@@ -2031,9 +2511,133 @@ static const struct wined3d_resource_ops texture_resource_ops =
     texture_resource_preload,
     wined3d_texture_unload,
     texture_resource_sub_resource_map,
     texture_resource_preload,
     wined3d_texture_unload,
     texture_resource_sub_resource_map,
+    texture_resource_sub_resource_map_info,
     texture_resource_sub_resource_unmap,
 };
 
     texture_resource_sub_resource_unmap,
 };
 
+static HRESULT texture1d_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+        UINT layer_count, UINT level_count, struct wined3d_device *device, void *parent,
+        const struct wined3d_parent_ops *parent_ops)
+{
+    struct wined3d_device_parent *device_parent = device->device_parent;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    struct wined3d_surface *surfaces;
+    unsigned int i, j;
+    HRESULT hr;
+
+    if (layer_count > 1 && !gl_info->supported[EXT_TEXTURE_ARRAY])
+    {
+        WARN("OpenGL implementation does not support array textures.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    /* TODO: It should only be possible to create textures for formats
+     * that are reported as supported. */
+    if (WINED3DFMT_UNKNOWN >= desc->format)
+    {
+        WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
+    {
+        WARN("1d textures can not be used for cube mapping, returning D3DERR_INVALIDCALL.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if ((desc->usage & WINED3DUSAGE_DYNAMIC && wined3d_resource_access_is_managed(desc->access))
+            || (desc->usage & WINED3DUSAGE_SCRATCH))
+    {
+        WARN("Attempted to create a DYNAMIC texture in pool %s.\n", wined3d_debug_resource_access(desc->access));
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && !is_power_of_two(desc->width))
+    {
+        if (desc->usage & WINED3DUSAGE_SCRATCH)
+        {
+            WARN("Creating a scratch NPOT 1d texture despite lack of HW support.\n");
+        }
+        else
+        {
+            WARN("Attempted to create a NPOT 1d texture (%u, %u, %u) without GL support.\n",
+                    desc->width, desc->height, desc->depth);
+            return WINED3DERR_INVALIDCALL;
+        }
+    }
+
+    if (desc->usage & WINED3DUSAGE_QUERY_GENMIPMAP)
+    {
+        if (level_count != 1)
+        {
+            WARN("WINED3DUSAGE_QUERY_GENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+    }
+
+    if (FAILED(hr = wined3d_texture_init(texture, &texture1d_ops, layer_count, level_count, desc,
+            0, device, parent, parent_ops, &texture_resource_ops)))
+    {
+        WARN("Failed to initialize texture, returning %#x.\n", hr);
+        return hr;
+    }
+
+    texture->pow2_matrix[0] = 1.0f;
+    texture->pow2_matrix[5] = 1.0f;
+    texture->pow2_matrix[10] = 1.0f;
+    texture->pow2_matrix[15] = 1.0f;
+    texture->target = (layer_count > 1) ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D;
+
+    if (wined3d_texture_use_pbo(texture, gl_info))
+    {
+        wined3d_resource_free_sysmem(&texture->resource);
+        texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
+    }
+
+    if (level_count > ~(SIZE_T)0 / layer_count
+            || !(surfaces = heap_calloc(level_count * layer_count, sizeof(*surfaces))))
+    {
+        wined3d_texture_cleanup_sync(texture);
+        return E_OUTOFMEMORY;
+    }
+
+    /* Generate all the surfaces. */
+    for (i = 0; i < texture->level_count; ++i)
+    {
+        for (j = 0; j < texture->layer_count; ++j)
+        {
+            struct wined3d_texture_sub_resource *sub_resource;
+            unsigned int idx = j * texture->level_count + i;
+            struct wined3d_surface *surface;
+
+            surface = &surfaces[idx];
+            surface->container = texture;
+            surface->texture_level = i;
+            surface->texture_layer = j;
+            list_init(&surface->renderbuffers);
+
+            sub_resource = &texture->sub_resources[idx];
+            sub_resource->locations = WINED3D_LOCATION_DISCARDED;
+            sub_resource->u.surface = surface;
+
+            if (FAILED(hr = device_parent->ops->surface_created(device_parent,
+                    texture, idx, &sub_resource->parent, &sub_resource->parent_ops)))
+            {
+                WARN("Failed to create texture1d parent, hr %#x.\n", hr);
+                sub_resource->parent = NULL;
+                wined3d_texture_cleanup_sync(texture);
+                return hr;
+            }
+
+            TRACE("parent %p, parent_ops %p.\n", parent, parent_ops);
+
+            TRACE("Created 1d texture surface level %u, layer %u @ %p.\n", i, j, surface);
+        }
+    }
+
+    return WINED3D_OK;
+}
+
 static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
         unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device,
         void *parent, const struct wined3d_parent_ops *parent_ops)
 static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
         unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device,
         void *parent, const struct wined3d_parent_ops *parent_ops)
@@ -2042,7 +2646,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct wined3d_surface *surfaces;
     UINT pow2_width, pow2_height;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct wined3d_surface *surfaces;
     UINT pow2_width, pow2_height;
-    unsigned int i, j;
+    unsigned int i, j, sub_count;
     HRESULT hr;
 
     if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1
     HRESULT hr;
 
     if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1
@@ -2060,13 +2664,13 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    if (desc->usage & WINED3DUSAGE_DYNAMIC && desc->pool == WINED3D_POOL_MANAGED)
+    if (desc->usage & WINED3DUSAGE_DYNAMIC && wined3d_resource_access_is_managed(desc->access))
         FIXME("Trying to create a managed texture with dynamic usage.\n");
     if (!(desc->usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))
             && (flags & WINED3D_TEXTURE_CREATE_MAPPABLE))
         FIXME("Trying to create a managed texture with dynamic usage.\n");
     if (!(desc->usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))
             && (flags & WINED3D_TEXTURE_CREATE_MAPPABLE))
-        WARN("Creating a mappable texture in the default pool that doesn't specify dynamic usage.\n");
-    if (desc->usage & WINED3DUSAGE_RENDERTARGET && desc->pool != WINED3D_POOL_DEFAULT)
-        FIXME("Trying to create a render target that isn't in the default pool.\n");
+        WARN("Creating a mappable texture that doesn't specify dynamic usage.\n");
+    if (desc->usage & WINED3DUSAGE_RENDERTARGET && desc->access & WINED3D_RESOURCE_ACCESS_CPU)
+        FIXME("Trying to create a CPU accessible render target.\n");
 
     pow2_width = desc->width;
     pow2_height = desc->height;
 
     pow2_width = desc->width;
     pow2_height = desc->height;
@@ -2076,7 +2680,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
         /* level_count == 0 returns an error as well. */
         if (level_count != 1 || layer_count != 1)
         {
         /* level_count == 0 returns an error as well. */
         if (level_count != 1 || layer_count != 1)
         {
-            if (desc->pool != WINED3D_POOL_SCRATCH)
+            if (!(desc->usage & WINED3DUSAGE_SCRATCH))
             {
                 WARN("Attempted to create a mipmapped/cube/array NPOT texture without unconditional NPOT support.\n");
                 return WINED3DERR_INVALIDCALL;
             {
                 WARN("Attempted to create a mipmapped/cube/array NPOT texture without unconditional NPOT support.\n");
                 return WINED3DERR_INVALIDCALL;
@@ -2124,7 +2728,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
          *    Blts. Some apps (e.g. Swat 3) create textures with a height of
          *    16 and a width > 3000 and blt 16x16 letter areas from them to
          *    the render target. */
          *    Blts. Some apps (e.g. Swat 3) create textures with a height of
          *    16 and a width > 3000 and blt 16x16 letter areas from them to
          *    the render target. */
-        if (desc->pool == WINED3D_POOL_DEFAULT || desc->pool == WINED3D_POOL_MANAGED)
+        if (desc->access & WINED3D_RESOURCE_ACCESS_GPU)
         {
             WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height);
             return WINED3DERR_NOTAVAILABLE;
         {
             WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height);
             return WINED3DERR_NOTAVAILABLE;
@@ -2134,22 +2738,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
         TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height);
     }
 
         TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height);
     }
 
-    /* Calculate levels for mip mapping. */
-    if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
-    {
-        if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
-        {
-            WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-
-        if (level_count != 1)
-        {
-            WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-    }
-
     if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc,
             flags, device, parent, parent_ops, &texture_resource_ops)))
     {
     if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc,
             flags, device, parent, parent_ops, &texture_resource_ops)))
     {
@@ -2179,11 +2767,23 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
             texture->pow2_matrix[5] = 1.0f;
         }
         if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
             texture->pow2_matrix[5] = 1.0f;
         }
         if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
+        {
             texture->target = GL_TEXTURE_CUBE_MAP_ARB;
             texture->target = GL_TEXTURE_CUBE_MAP_ARB;
-        else if (layer_count > 1)
-            texture->target = GL_TEXTURE_2D_ARRAY;
+        }
+        else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+        {
+            if (layer_count > 1)
+                texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+            else
+                texture->target = GL_TEXTURE_2D_MULTISAMPLE;
+        }
         else
         else
-            texture->target = GL_TEXTURE_2D;
+        {
+            if (layer_count > 1)
+                texture->target = GL_TEXTURE_2D_ARRAY;
+            else
+                texture->target = GL_TEXTURE_2D;
+        }
     }
     texture->pow2_matrix[10] = 1.0f;
     texture->pow2_matrix[15] = 1.0f;
     }
     texture->pow2_matrix[10] = 1.0f;
     texture->pow2_matrix[15] = 1.0f;
@@ -2192,38 +2792,44 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
     if (wined3d_texture_use_pbo(texture, gl_info))
         texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
 
     if (wined3d_texture_use_pbo(texture, gl_info))
         texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
 
-    if (level_count > ~(SIZE_T)0 / layer_count
-            || !(surfaces = wined3d_calloc(level_count * layer_count, sizeof(*surfaces))))
+    sub_count = level_count * layer_count;
+    if (sub_count / layer_count != level_count
+            || !(surfaces = heap_calloc(sub_count, sizeof(*surfaces))))
     {
         wined3d_texture_cleanup_sync(texture);
         return E_OUTOFMEMORY;
     }
 
     {
         wined3d_texture_cleanup_sync(texture);
         return E_OUTOFMEMORY;
     }
 
+    if (desc->usage & WINED3DUSAGE_OVERLAY)
+    {
+        if (!(texture->overlay_info = heap_calloc(sub_count, sizeof(*texture->overlay_info))))
+        {
+            heap_free(surfaces);
+            wined3d_texture_cleanup_sync(texture);
+            return E_OUTOFMEMORY;
+        }
+
+        for (i = 0; i < sub_count; ++i)
+        {
+            list_init(&texture->overlay_info[i].entry);
+            list_init(&texture->overlay_info[i].overlays);
+        }
+    }
+
     /* Generate all the surfaces. */
     for (i = 0; i < texture->level_count; ++i)
     {
         for (j = 0; j < texture->layer_count; ++j)
         {
     /* Generate all the surfaces. */
     for (i = 0; i < texture->level_count; ++i)
     {
         for (j = 0; j < texture->layer_count; ++j)
         {
-            static const GLenum cube_targets[6] =
-            {
-                GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
-                GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
-                GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
-                GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
-                GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
-                GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
-            };
             struct wined3d_texture_sub_resource *sub_resource;
             unsigned int idx = j * texture->level_count + i;
             struct wined3d_surface *surface;
 
             surface = &surfaces[idx];
             surface->container = texture;
             struct wined3d_texture_sub_resource *sub_resource;
             unsigned int idx = j * texture->level_count + i;
             struct wined3d_surface *surface;
 
             surface = &surfaces[idx];
             surface->container = texture;
-            surface->texture_target = desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP ? cube_targets[j] : texture->target;
             surface->texture_level = i;
             surface->texture_layer = j;
             list_init(&surface->renderbuffers);
             surface->texture_level = i;
             surface->texture_layer = j;
             list_init(&surface->renderbuffers);
-            list_init(&surface->overlays);
 
             sub_resource = &texture->sub_resources[idx];
             sub_resource->locations = WINED3D_LOCATION_DISCARDED;
 
             sub_resource = &texture->sub_resources[idx];
             sub_resource->locations = WINED3D_LOCATION_DISCARDED;
@@ -2314,7 +2920,7 @@ static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int
         dst_row_pitch = update_w * format->conv_byte_count;
         dst_slice_pitch = dst_row_pitch * update_h;
 
         dst_row_pitch = update_w * format->conv_byte_count;
         dst_slice_pitch = dst_row_pitch * update_h;
 
-        converted_mem = wined3d_calloc(update_d, dst_slice_pitch);
+        converted_mem = heap_calloc(update_d, dst_slice_pitch);
         format->upload(data->addr, converted_mem, row_pitch, slice_pitch,
                 dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
         mem = converted_mem;
         format->upload(data->addr, converted_mem, row_pitch, slice_pitch,
                 dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
         mem = converted_mem;
@@ -2342,7 +2948,7 @@ static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int
         checkGLcall("glBindBuffer");
     }
 
         checkGLcall("glBindBuffer");
     }
 
-    HeapFree(GetProcessHeap(), 0, converted_mem);
+    heap_free(converted_mem);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -2393,7 +2999,7 @@ static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned in
      * for DEFAULT pool surfaces. */
     WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
     data.buffer_object = 0;
      * for DEFAULT pool surfaces. */
     WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
     data.buffer_object = 0;
-    if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size)))
+    if (!(data.addr = heap_alloc(sub_resource->size)))
         return;
 
     wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
         return;
 
     wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
@@ -2403,7 +3009,7 @@ static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned in
     texture3d_upload_data(texture, sub_resource_idx, context,
             NULL, wined3d_const_bo_address(&data), row_pitch, slice_pitch);
 
     texture3d_upload_data(texture, sub_resource_idx, context,
             NULL, wined3d_const_bo_address(&data), row_pitch, slice_pitch);
 
-    HeapFree(GetProcessHeap(), 0, data.addr);
+    heap_free(data.addr);
 }
 
 /* Context activation is done by the caller. */
 }
 
 /* Context activation is done by the caller. */
@@ -2431,7 +3037,11 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in
             }
             else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
             {
             }
             else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
             {
+#if !defined(STAGING_CSMT)
                 struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
                 struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
+#else  /* STAGING_CSMT */
+                struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL};
+#endif /* STAGING_CSMT */
                 wined3d_texture_bind_and_dirtify(texture, context,
                         location == WINED3D_LOCATION_TEXTURE_SRGB);
                 wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
                 wined3d_texture_bind_and_dirtify(texture, context,
                         location == WINED3D_LOCATION_TEXTURE_SRGB);
                 wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
@@ -2477,7 +3087,11 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in
         case WINED3D_LOCATION_BUFFER:
             if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
             {
         case WINED3D_LOCATION_BUFFER:
             if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
             {
+#if !defined(STAGING_CSMT)
                 struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
                 struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
+#else  /* STAGING_CSMT */
+                struct wined3d_bo_address data = {sub_resource->buffer->name, NULL};
+#endif /* STAGING_CSMT */
 
                 if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
                     wined3d_texture_bind_and_dirtify(texture, context, FALSE);
 
                 if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
                     wined3d_texture_bind_and_dirtify(texture, context, FALSE);
@@ -2576,45 +3190,19 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    /* Calculate levels for mip mapping. */
-    if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
+    if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access)
+            || desc->usage & WINED3DUSAGE_SCRATCH))
     {
     {
-        if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
-        {
-            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-
-        if (level_count != 1)
-        {
-            WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-    }
-
-    if (desc->usage & WINED3DUSAGE_DYNAMIC && (desc->pool == WINED3D_POOL_MANAGED
-            || desc->pool == WINED3D_POOL_SCRATCH))
-    {
-        WARN("Attempted to create a DYNAMIC texture in pool %s.\n", debug_d3dpool(desc->pool));
+        WARN("Attempted to create a DYNAMIC texture with access %s.\n",
+                wined3d_debug_resource_access(desc->access));
         return WINED3DERR_INVALIDCALL;
     }
 
     if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
     {
         return WINED3DERR_INVALIDCALL;
     }
 
     if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
     {
-        UINT pow2_w, pow2_h, pow2_d;
-        pow2_w = 1;
-        while (pow2_w < desc->width)
-            pow2_w <<= 1;
-        pow2_h = 1;
-        while (pow2_h < desc->height)
-            pow2_h <<= 1;
-        pow2_d = 1;
-        while (pow2_d < desc->depth)
-            pow2_d <<= 1;
-
-        if (pow2_w != desc->width || pow2_h != desc->height || pow2_d != desc->depth)
+        if (!is_power_of_two(desc->width) || !is_power_of_two(desc->height) || !is_power_of_two(desc->depth))
         {
         {
-            if (desc->pool == WINED3D_POOL_SCRATCH)
+            if (desc->usage & WINED3DUSAGE_SCRATCH)
             {
                 WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n");
             }
             {
                 WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n");
             }
@@ -2646,7 +3234,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
         texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
     }
 
         texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
     }
 
-    /* Generate all the surfaces. */
+    /* Generate all the sub resources. */
     for (i = 0; i < texture->level_count; ++i)
     {
         struct wined3d_texture_sub_resource *sub_resource;
     for (i = 0; i < texture->level_count; ++i)
     {
         struct wined3d_texture_sub_resource *sub_resource;
@@ -2706,8 +3294,19 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned
     if (dst_texture->sub_resources[dst_sub_resource_idx].map_count
             || src_texture->sub_resources[src_sub_resource_idx].map_count)
     {
     if (dst_texture->sub_resources[dst_sub_resource_idx].map_count
             || src_texture->sub_resources[src_sub_resource_idx].map_count)
     {
+#if !defined(STAGING_CSMT)
         WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n");
         return WINEDDERR_SURFACEBUSY;
         WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n");
         return WINEDDERR_SURFACEBUSY;
+#else  /* STAGING_CSMT */
+        struct wined3d_device *device = dst_texture->resource.device;
+        device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
+        if (dst_texture->sub_resources[dst_sub_resource_idx].map_count
+                || (src_texture && src_texture->sub_resources[src_sub_resource_idx].map_count))
+        {
+            WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n");
+            return WINEDDERR_SURFACEBUSY;
+        }
+#endif /* STAGING_CSMT */
     }
 
     if ((src_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
     }
 
     if ((src_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
@@ -2726,19 +3325,19 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned
 HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture *texture,
         unsigned int sub_resource_idx, LONG *x, LONG *y)
 {
 HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture *texture,
         unsigned int sub_resource_idx, LONG *x, LONG *y)
 {
-    struct wined3d_surface *surface;
+    struct wined3d_overlay_info *overlay;
 
     TRACE("texture %p, sub_resource_idx %u, x %p, y %p.\n", texture, sub_resource_idx, x, y);
 
 
     TRACE("texture %p, sub_resource_idx %u, x %p, y %p.\n", texture, sub_resource_idx, x, y);
 
-    if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY) || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
+    if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY)
             || sub_resource_idx >= texture->level_count * texture->layer_count)
     {
         WARN("Invalid sub-resource specified.\n");
         return WINEDDERR_NOTAOVERLAYSURFACE;
     }
 
             || sub_resource_idx >= texture->level_count * texture->layer_count)
     {
         WARN("Invalid sub-resource specified.\n");
         return WINEDDERR_NOTAOVERLAYSURFACE;
     }
 
-    surface = texture->sub_resources[sub_resource_idx].u.surface;
-    if (!surface->overlay_dest)
+    overlay = &texture->overlay_info[sub_resource_idx];
+    if (!overlay->dst)
     {
         TRACE("Overlay not visible.\n");
         *x = 0;
     {
         TRACE("Overlay not visible.\n");
         *x = 0;
@@ -2746,8 +3345,8 @@ HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture
         return WINEDDERR_OVERLAYNOTVISIBLE;
     }
 
         return WINEDDERR_OVERLAYNOTVISIBLE;
     }
 
-    *x = surface->overlay_destrect.left;
-    *y = surface->overlay_destrect.top;
+    *x = overlay->dst_rect.left;
+    *y = overlay->dst_rect.top;
 
     TRACE("Returning position %d, %d.\n", *x, *y);
 
 
     TRACE("Returning position %d, %d.\n", *x, *y);
 
@@ -2757,23 +3356,22 @@ HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture
 HRESULT CDECL wined3d_texture_set_overlay_position(struct wined3d_texture *texture,
         unsigned int sub_resource_idx, LONG x, LONG y)
 {
 HRESULT CDECL wined3d_texture_set_overlay_position(struct wined3d_texture *texture,
         unsigned int sub_resource_idx, LONG x, LONG y)
 {
-    struct wined3d_texture_sub_resource *sub_resource;
-    struct wined3d_surface *surface;
+    struct wined3d_overlay_info *overlay;
     LONG w, h;
 
     TRACE("texture %p, sub_resource_idx %u, x %d, y %d.\n", texture, sub_resource_idx, x, y);
 
     LONG w, h;
 
     TRACE("texture %p, sub_resource_idx %u, x %d, y %d.\n", texture, sub_resource_idx, x, y);
 
-    if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY) || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
-            || !(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY)
+            || sub_resource_idx >= texture->level_count * texture->layer_count)
     {
         WARN("Invalid sub-resource specified.\n");
         return WINEDDERR_NOTAOVERLAYSURFACE;
     }
 
     {
         WARN("Invalid sub-resource specified.\n");
         return WINEDDERR_NOTAOVERLAYSURFACE;
     }
 
-    surface = sub_resource->u.surface;
-    w = surface->overlay_destrect.right - surface->overlay_destrect.left;
-    h = surface->overlay_destrect.bottom - surface->overlay_destrect.top;
-    SetRect(&surface->overlay_destrect, x, y, x + w, y + h);
+    overlay = &texture->overlay_info[sub_resource_idx];
+    w = overlay->dst_rect.right - overlay->dst_rect.left;
+    h = overlay->dst_rect.bottom - overlay->dst_rect.top;
+    SetRect(&overlay->dst_rect, x, y, x + w, y + h);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -2784,6 +3382,7 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un
 {
     struct wined3d_texture_sub_resource *sub_resource, *dst_sub_resource;
     struct wined3d_surface *surface, *dst_surface;
 {
     struct wined3d_texture_sub_resource *sub_resource, *dst_sub_resource;
     struct wined3d_surface *surface, *dst_surface;
+    struct wined3d_overlay_info *overlay;
 
     TRACE("texture %p, sub_resource_idx %u, src_rect %s, dst_texture %p, "
             "dst_sub_resource_idx %u, dst_rect %s, flags %#x.\n",
 
     TRACE("texture %p, sub_resource_idx %u, src_rect %s, dst_texture %p, "
             "dst_sub_resource_idx %u, dst_rect %s, flags %#x.\n",
@@ -2804,42 +3403,44 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
+    overlay = &texture->overlay_info[sub_resource_idx];
+
     surface = sub_resource->u.surface;
     if (src_rect)
     surface = sub_resource->u.surface;
     if (src_rect)
-        surface->overlay_srcrect = *src_rect;
+        overlay->src_rect = *src_rect;
     else
     else
-        SetRect(&surface->overlay_srcrect, 0, 0,
+        SetRect(&overlay->src_rect, 0, 0,
                 wined3d_texture_get_level_width(texture, surface->texture_level),
                 wined3d_texture_get_level_height(texture, surface->texture_level));
 
     dst_surface = dst_sub_resource->u.surface;
     if (dst_rect)
                 wined3d_texture_get_level_width(texture, surface->texture_level),
                 wined3d_texture_get_level_height(texture, surface->texture_level));
 
     dst_surface = dst_sub_resource->u.surface;
     if (dst_rect)
-        surface->overlay_destrect = *dst_rect;
+        overlay->dst_rect = *dst_rect;
     else
     else
-        SetRect(&surface->overlay_destrect, 0, 0,
+        SetRect(&overlay->dst_rect, 0, 0,
                 wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level),
                 wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level));
 
                 wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level),
                 wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level));
 
-    if (surface->overlay_dest && (surface->overlay_dest != dst_surface || flags & WINEDDOVER_HIDE))
+    if (overlay->dst && (overlay->dst != dst_surface || flags & WINEDDOVER_HIDE))
     {
     {
-        surface->overlay_dest = NULL;
-        list_remove(&surface->overlay_entry);
+        overlay->dst = NULL;
+        list_remove(&overlay->entry);
     }
 
     if (flags & WINEDDOVER_SHOW)
     {
     }
 
     if (flags & WINEDDOVER_SHOW)
     {
-        if (surface->overlay_dest != dst_surface)
+        if (overlay->dst != dst_surface)
         {
         {
-            surface->overlay_dest = dst_surface;
-            list_add_tail(&dst_surface->overlays, &surface->overlay_entry);
+            overlay->dst = dst_surface;
+            list_add_tail(&texture->overlay_info[dst_sub_resource_idx].overlays, &overlay->entry);
         }
     }
     else if (flags & WINEDDOVER_HIDE)
     {
         /* Tests show that the rectangles are erased on hide. */
         }
     }
     else if (flags & WINEDDOVER_HIDE)
     {
         /* Tests show that the rectangles are erased on hide. */
-        SetRectEmpty(&surface->overlay_srcrect);
-        SetRectEmpty(&surface->overlay_destrect);
-        surface->overlay_dest = NULL;
+        SetRectEmpty(&overlay->src_rect);
+        SetRectEmpty(&overlay->dst_rect);
+        overlay->dst = NULL;
     }
 
     return WINED3D_OK;
     }
 
     return WINED3D_OK;
@@ -2896,7 +3497,7 @@ HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture
     desc->multisample_type = resource->multisample_type;
     desc->multisample_quality = resource->multisample_quality;
     desc->usage = resource->usage;
     desc->multisample_type = resource->multisample_type;
     desc->multisample_quality = resource->multisample_quality;
     desc->usage = resource->usage;
-    desc->pool = resource->pool;
+    desc->access = resource->access;
 
     level_idx = sub_resource_idx % texture->level_count;
     desc->width = wined3d_texture_get_level_width(texture, level_idx);
 
     level_idx = sub_resource_idx % texture->level_count;
     desc->width = wined3d_texture_get_level_width(texture, level_idx);
@@ -2957,12 +3558,16 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
         }
     }
 
         }
     }
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-            FIELD_OFFSET(struct wined3d_texture, sub_resources[level_count * layer_count]))))
+    if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
+            sub_resources[level_count * layer_count]))))
         return E_OUTOFMEMORY;
 
     switch (desc->resource_type)
     {
         return E_OUTOFMEMORY;
 
     switch (desc->resource_type)
     {
+        case WINED3D_RTYPE_TEXTURE_1D:
+            hr = texture1d_init(object, desc, layer_count, level_count, device, parent, parent_ops);
+            break;
+
         case WINED3D_RTYPE_TEXTURE_2D:
             hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops);
             break;
         case WINED3D_RTYPE_TEXTURE_2D:
             hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops);
             break;
@@ -2980,7 +3585,7 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
     if (FAILED(hr))
     {
         WARN("Failed to initialize texture, returning %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize texture, returning %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -2997,7 +3602,7 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
             {
                 WARN("Invalid sub-resource data specified for sub-resource %u.\n", i);
                 wined3d_texture_cleanup_sync(object);
             {
                 WARN("Invalid sub-resource data specified for sub-resource %u.\n", i);
                 wined3d_texture_cleanup_sync(object);
-                HeapFree(GetProcessHeap(), 0, object);
+                heap_free(object);
                 return E_INVALIDARG;
             }
         }
                 return E_INVALIDARG;
             }
         }
index 6b97c63..b48293e 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -1679,6 +1684,10 @@ static const struct wined3d_format_texture_info format_texture_info[] =
             GL_RGBA_INTEGER,            GL_INT,                           0,
             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
             EXT_TEXTURE_INTEGER,        NULL},
             GL_RGBA_INTEGER,            GL_INT,                           0,
             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
             EXT_TEXTURE_INTEGER,        NULL},
+    {WINED3DFMT_R24_UNORM_X8_TYPELESS,  GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
+            GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT_24_8,             0,
+            WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_TEXTURE,          NULL},
     /* Vendor-specific formats */
     {WINED3DFMT_ATI1N,                  GL_COMPRESSED_RED_RGTC1,          GL_COMPRESSED_RED_RGTC1,                0,
             GL_RED,                     GL_UNSIGNED_BYTE,                 0,
     /* Vendor-specific formats */
     {WINED3DFMT_ATI1N,                  GL_COMPRESSED_RED_RGTC1,          GL_COMPRESSED_RED_RGTC1,                0,
             GL_RED,                     GL_UNSIGNED_BYTE,                 0,
@@ -1823,7 +1832,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
     unsigned int i, j;
 
     gl_info->format_count = WINED3D_FORMAT_COUNT;
     unsigned int i, j;
 
     gl_info->format_count = WINED3D_FORMAT_COUNT;
-    if (!(gl_info->formats = wined3d_calloc(gl_info->format_count
+    if (!(gl_info->formats = heap_calloc(gl_info->format_count
             + ARRAY_SIZE(typeless_depth_stencil_formats), sizeof(*gl_info->formats))))
     {
         ERR("Failed to allocate memory.\n");
             + ARRAY_SIZE(typeless_depth_stencil_formats), sizeof(*gl_info->formats))))
     {
         ERR("Failed to allocate memory.\n");
@@ -1917,7 +1926,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
     return TRUE;
 
 fail:
     return TRUE;
 
 fail:
-    HeapFree(GetProcessHeap(), 0, gl_info->formats);
+    heap_free(gl_info->formats);
     return FALSE;
 }
 
     return FALSE;
 }
 
@@ -2800,6 +2809,7 @@ static void query_internal_format(struct wined3d_adapter *adapter,
 {
     GLint count, multisample_types[MAX_MULTISAMPLE_TYPES];
     unsigned int i, max_log2;
 {
     GLint count, multisample_types[MAX_MULTISAMPLE_TYPES];
     unsigned int i, max_log2;
+    GLenum target;
 
     if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
     {
 
     if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
     {
@@ -2872,17 +2882,17 @@ static void query_internal_format(struct wined3d_adapter *adapter,
     {
         if (gl_info->supported[ARB_INTERNALFORMAT_QUERY])
         {
     {
         if (gl_info->supported[ARB_INTERNALFORMAT_QUERY])
         {
+            target = gl_info->supported[ARB_TEXTURE_MULTISAMPLE] ? GL_TEXTURE_2D_MULTISAMPLE : GL_RENDERBUFFER;
             count = 0;
             count = 0;
-            GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal,
+            GL_EXTCALL(glGetInternalformativ(target, format->glInternal,
                     GL_NUM_SAMPLE_COUNTS, 1, &count));
                     GL_NUM_SAMPLE_COUNTS, 1, &count));
-            checkGLcall("glGetInternalformativ(GL_NUM_SAMPLE_COUNTS)");
             count = min(count, MAX_MULTISAMPLE_TYPES);
             count = min(count, MAX_MULTISAMPLE_TYPES);
-            GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal,
+            GL_EXTCALL(glGetInternalformativ(target, format->glInternal,
                     GL_SAMPLES, count, multisample_types));
                     GL_SAMPLES, count, multisample_types));
-            checkGLcall("glGetInternalformativ(GL_SAMPLES)");
+            checkGLcall("query sample counts");
             for (i = 0; i < count; ++i)
             {
             for (i = 0; i < count; ++i)
             {
-                if (multisample_types[i] > sizeof(format->multisample_types) * 8)
+                if (multisample_types[i] > sizeof(format->multisample_types) * CHAR_BIT)
                     continue;
                 format->multisample_types |= 1u << (multisample_types[i] - 1);
             }
                     continue;
                 format->multisample_types |= 1u << (multisample_types[i] - 1);
             }
@@ -2893,7 +2903,7 @@ static void query_internal_format(struct wined3d_adapter *adapter,
             if (gl_info->limits.samples) {
 #endif
                 max_log2 = wined3d_log2i(min(gl_info->limits.samples,
             if (gl_info->limits.samples) {
 #endif
                 max_log2 = wined3d_log2i(min(gl_info->limits.samples,
-                        sizeof(format->multisample_types) * 8));
+                        sizeof(format->multisample_types) * CHAR_BIT));
                 for (i = 1; i <= max_log2; ++i)
                     format->multisample_types |= 1u << ((1u << i) - 1);
 #ifdef __REACTOS__
                 for (i = 1; i <= max_log2; ++i)
                     format->multisample_types |= 1u << ((1u << i) - 1);
 #ifdef __REACTOS__
@@ -3595,6 +3605,23 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info)
     return TRUE;
 }
 
     return TRUE;
 }
 
+static void init_format_gen_mipmap_info(struct wined3d_gl_info *gl_info)
+{
+    unsigned int i, j;
+
+    if (!gl_info->fbo_ops.glGenerateMipmap)
+        return;
+
+    for (i = 0; i < gl_info->format_count; ++i)
+    {
+        struct wined3d_format *format = &gl_info->formats[i];
+
+        for (j = 0; j < ARRAY_SIZE(format->flags); ++j)
+            if (!(~format->flags[j] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)))
+                format->flags[j] |= WINED3DFMT_FLAG_GEN_MIPMAP;
+    }
+}
+
 BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx)
 {
     static const struct wined3d_color red = {1.0f, 0.0f, 0.0f, 1.0f};
 BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx)
 {
     static const struct wined3d_color red = {1.0f, 0.0f, 0.0f, 1.0f};
@@ -3783,12 +3810,13 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wi
     init_format_fbo_compat_info(ctx);
     init_format_filter_info(gl_info, adapter->driver_info.vendor);
     if (!init_typeless_formats(gl_info)) goto fail;
     init_format_fbo_compat_info(ctx);
     init_format_filter_info(gl_info, adapter->driver_info.vendor);
     if (!init_typeless_formats(gl_info)) goto fail;
+    init_format_gen_mipmap_info(gl_info);
     init_format_depth_bias_scale(ctx, &adapter->d3d_info);
 
     return TRUE;
 
 fail:
     init_format_depth_bias_scale(ctx, &adapter->d3d_info);
 
     return TRUE;
 
 fail:
-    HeapFree(GetProcessHeap(), 0, gl_info->formats);
+    heap_free(gl_info->formats);
     gl_info->formats = NULL;
     return FALSE;
 }
     gl_info->formats = NULL;
     return FALSE;
 }
@@ -4130,12 +4158,61 @@ const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
     }
 }
 
     }
 }
 
+struct debug_buffer
+{
+    char str[200]; /* wine_dbg_sprintf() limits string size to 200 */
+    char *ptr;
+    int size;
+};
+
+static void init_debug_buffer(struct debug_buffer *buffer, const char *default_string)
+{
+    strcpy(buffer->str, default_string);
+    buffer->ptr = buffer->str;
+    buffer->size = ARRAY_SIZE(buffer->str);
+}
+
+static void debug_append(struct debug_buffer *buffer, const char *str, const char *separator)
+{
+    int size;
+
+    if (!separator || buffer->ptr == buffer->str)
+        separator = "";
+    size = snprintf(buffer->ptr, buffer->size, "%s%s", separator, str);
+    if (size == -1 || size >= buffer->size)
+    {
+        buffer->size = 0;
+        strcpy(&buffer->str[ARRAY_SIZE(buffer->str) - 4], "...");
+        return;
+    }
+
+    buffer->ptr += size;
+    buffer->size -= size;
+}
+
+const char *wined3d_debug_resource_access(DWORD access)
+{
+    struct debug_buffer buffer;
+
+    init_debug_buffer(&buffer, "0");
+#define ACCESS_TO_STR(x) if (access & x) { debug_append(&buffer, #x, " | "); access &= ~x; }
+    ACCESS_TO_STR(WINED3D_RESOURCE_ACCESS_GPU);
+    ACCESS_TO_STR(WINED3D_RESOURCE_ACCESS_CPU);
+    ACCESS_TO_STR(WINED3D_RESOURCE_ACCESS_MAP_R);
+    ACCESS_TO_STR(WINED3D_RESOURCE_ACCESS_MAP_W);
+#undef ACCESS_TO_STR
+    if (access)
+        FIXME("Unrecognised access flag(s) %#x.\n", access);
+
+    return wine_dbg_sprintf("%s", buffer.str);
+}
+
 const char *debug_d3dusage(DWORD usage)
 {
 const char *debug_d3dusage(DWORD usage)
 {
-    char buf[552];
+    struct debug_buffer buffer;
 
 
-    buf[0] = '\0';
-#define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
+    init_debug_buffer(&buffer, "0");
+#define WINED3DUSAGE_TO_STR(x) if (usage & x) { debug_append(&buffer, #x, " | "); usage &= ~x; }
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
@@ -4145,7 +4222,6 @@ const char *debug_d3dusage(DWORD usage)
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
-    WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICTED_CONTENT);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICTED_CONTENT);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE);
@@ -4157,18 +4233,20 @@ const char *debug_d3dusage(DWORD usage)
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
 #undef WINED3DUSAGE_TO_STR
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
 #undef WINED3DUSAGE_TO_STR
-    if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
+    if (usage)
+        FIXME("Unrecognized usage flag(s) %#x.\n", usage);
 
 
-    return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
+    return wine_dbg_sprintf("%s", buffer.str);
 }
 
 }
 
-const char *debug_d3dusagequery(DWORD usagequery)
+const char *debug_d3dusagequery(DWORD usage)
 {
 {
-    char buf[238];
+    struct debug_buffer buffer;
 
 
-    buf[0] = '\0';
-#define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
+    init_debug_buffer(&buffer, "0");
+#define WINED3DUSAGEQUERY_TO_STR(x) if (usage & x) { debug_append(&buffer, #x, " | "); usage &= ~x; }
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
+    WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_GENMIPMAP);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
@@ -4176,9 +4254,10 @@ const char *debug_d3dusagequery(DWORD usagequery)
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
 #undef WINED3DUSAGEQUERY_TO_STR
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
 #undef WINED3DUSAGEQUERY_TO_STR
-    if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
+    if (usage)
+        FIXME("Unrecognized usage query flag(s) %#x.\n", usage);
 
 
-    return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
+    return wine_dbg_sprintf("%s", buffer.str);
 }
 
 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
 }
 
 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
@@ -4247,6 +4326,7 @@ const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
 #define WINED3D_TO_STR(x) case x: return #x
         WINED3D_TO_STR(WINED3D_RTYPE_NONE);
         WINED3D_TO_STR(WINED3D_RTYPE_BUFFER);
 #define WINED3D_TO_STR(x) case x: return #x
         WINED3D_TO_STR(WINED3D_RTYPE_NONE);
         WINED3D_TO_STR(WINED3D_RTYPE_BUFFER);
+        WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_1D);
         WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_2D);
         WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_3D);
 #undef WINED3D_TO_STR
         WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_2D);
         WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_3D);
 #undef WINED3D_TO_STR
@@ -4373,7 +4453,6 @@ const char *debug_d3drenderstate(enum wined3d_render_state state)
         D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
         D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
         D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
         D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
         D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
         D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
-        D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
         D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
         D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
         D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
         D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
         D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
         D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
@@ -4393,12 +4472,18 @@ const char *debug_d3drenderstate(enum wined3d_render_state state)
         D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILZFAIL);
         D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILPASS);
         D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFUNC);
         D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILZFAIL);
         D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILPASS);
         D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFUNC);
+        D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
+        D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE4);
+        D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE5);
+        D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE6);
+        D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE7);
         D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
         D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
         D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
         D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
         D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
         D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
+        D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIASCLAMP);
         D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
         D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
         D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
         D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
         D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
         D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
@@ -4411,6 +4496,7 @@ const char *debug_d3drenderstate(enum wined3d_render_state state)
         D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
         D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
         D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
         D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
         D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
         D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
+        D3DSTATE_TO_STR(WINED3D_RS_DEPTHCLIP);
 #undef D3DSTATE_TO_STR
         default:
             FIXME("Unrecognized %u render state!\n", state);
 #undef D3DSTATE_TO_STR
         default:
             FIXME("Unrecognized %u render state!\n", state);
@@ -4643,26 +4729,12 @@ const char *debug_d3dstate(DWORD state)
         return "STATE_COLOR_KEY";
     if (STATE_IS_STREAM_OUTPUT(state))
         return "STATE_STREAM_OUTPUT";
         return "STATE_COLOR_KEY";
     if (STATE_IS_STREAM_OUTPUT(state))
         return "STATE_STREAM_OUTPUT";
+    if (STATE_IS_BLEND(state))
+        return "STATE_BLEND";
 
     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
 }
 
 
     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
 }
 
-const char *debug_d3dpool(enum wined3d_pool pool)
-{
-    switch (pool)
-    {
-#define POOL_TO_STR(p) case p: return #p
-        POOL_TO_STR(WINED3D_POOL_DEFAULT);
-        POOL_TO_STR(WINED3D_POOL_MANAGED);
-        POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
-        POOL_TO_STR(WINED3D_POOL_SCRATCH);
-#undef  POOL_TO_STR
-        default:
-            FIXME("Unrecognized pool %#x.\n", pool);
-            return "unrecognized";
-    }
-}
-
 const char *debug_fboattachment(GLenum attachment)
 {
     switch(attachment)
 const char *debug_fboattachment(GLenum attachment)
 {
     switch(attachment)
@@ -5348,6 +5420,293 @@ void multiply_matrix(struct wined3d_matrix *dst, const struct wined3d_matrix *sr
     *dst = tmp;
 }
 
     *dst = tmp;
 }
 
+/* Taken and adapted from Mesa. */
+BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in)
+{
+    float pos, neg, t, det;
+    struct wined3d_matrix temp;
+
+    /* Calculate the determinant of upper left 3x3 submatrix and
+     * determine if the matrix is singular. */
+    pos = neg = 0.0f;
+    t =  in->_11 * in->_22 * in->_33;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+
+    t =  in->_21 * in->_32 * in->_13;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+    t =  in->_31 * in->_12 * in->_23;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+
+    t = -in->_31 * in->_22 * in->_13;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+    t = -in->_21 * in->_12 * in->_33;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+
+    t = -in->_11 * in->_32 * in->_23;
+    if (t >= 0.0f)
+        pos += t;
+    else
+        neg += t;
+
+    det = pos + neg;
+
+    if (fabsf(det) < 1e-25f)
+        return FALSE;
+
+    det = 1.0f / det;
+    temp._11 =  (in->_22 * in->_33 - in->_32 * in->_23) * det;
+    temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det;
+    temp._13 =  (in->_12 * in->_23 - in->_22 * in->_13) * det;
+    temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det;
+    temp._22 =  (in->_11 * in->_33 - in->_31 * in->_13) * det;
+    temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det;
+    temp._31 =  (in->_21 * in->_32 - in->_31 * in->_22) * det;
+    temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det;
+    temp._33 =  (in->_11 * in->_22 - in->_21 * in->_12) * det;
+
+    *out = temp;
+    return TRUE;
+}
+
+static void swap_rows(float **a, float **b)
+{
+    float *tmp = *a;
+
+    *a = *b;
+    *b = tmp;
+}
+
+BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m)
+{
+    float wtmp[4][8];
+    float m0, m1, m2, m3, s;
+    float *r0, *r1, *r2, *r3;
+
+    r0 = wtmp[0];
+    r1 = wtmp[1];
+    r2 = wtmp[2];
+    r3 = wtmp[3];
+
+    r0[0] = m->_11;
+    r0[1] = m->_12;
+    r0[2] = m->_13;
+    r0[3] = m->_14;
+    r0[4] = 1.0f;
+    r0[5] = r0[6] = r0[7] = 0.0f;
+
+    r1[0] = m->_21;
+    r1[1] = m->_22;
+    r1[2] = m->_23;
+    r1[3] = m->_24;
+    r1[5] = 1.0f;
+    r1[4] = r1[6] = r1[7] = 0.0f;
+
+    r2[0] = m->_31;
+    r2[1] = m->_32;
+    r2[2] = m->_33;
+    r2[3] = m->_34;
+    r2[6] = 1.0f;
+    r2[4] = r2[5] = r2[7] = 0.0f;
+
+    r3[0] = m->_41;
+    r3[1] = m->_42;
+    r3[2] = m->_43;
+    r3[3] = m->_44;
+    r3[7] = 1.0f;
+    r3[4] = r3[5] = r3[6] = 0.0f;
+
+    /* Choose pivot - or die. */
+    if (fabsf(r3[0]) > fabsf(r2[0]))
+        swap_rows(&r3, &r2);
+    if (fabsf(r2[0]) > fabsf(r1[0]))
+        swap_rows(&r2, &r1);
+    if (fabsf(r1[0]) > fabsf(r0[0]))
+        swap_rows(&r1, &r0);
+    if (r0[0] == 0.0f)
+        return FALSE;
+
+    /* Eliminate first variable. */
+    m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0];
+    s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
+    s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
+    s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
+    s = r0[4];
+    if (s != 0.0f)
+    {
+        r1[4] -= m1 * s;
+        r2[4] -= m2 * s;
+        r3[4] -= m3 * s;
+    }
+    s = r0[5];
+    if (s != 0.0f)
+    {
+        r1[5] -= m1 * s;
+        r2[5] -= m2 * s;
+        r3[5] -= m3 * s;
+    }
+    s = r0[6];
+    if (s != 0.0f)
+    {
+        r1[6] -= m1 * s;
+        r2[6] -= m2 * s;
+        r3[6] -= m3 * s;
+    }
+    s = r0[7];
+    if (s != 0.0f)
+    {
+        r1[7] -= m1 * s;
+        r2[7] -= m2 * s;
+        r3[7] -= m3 * s;
+    }
+
+    /* Choose pivot - or die. */
+    if (fabsf(r3[1]) > fabsf(r2[1]))
+        swap_rows(&r3, &r2);
+    if (fabsf(r2[1]) > fabsf(r1[1]))
+        swap_rows(&r2, &r1);
+    if (r1[1] == 0.0f)
+        return FALSE;
+
+    /* Eliminate second variable. */
+    m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1];
+    r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
+    r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
+    s = r1[4];
+    if (s != 0.0f)
+    {
+        r2[4] -= m2 * s;
+        r3[4] -= m3 * s;
+    }
+    s = r1[5];
+    if (s != 0.0f)
+    {
+        r2[5] -= m2 * s;
+        r3[5] -= m3 * s;
+    }
+    s = r1[6];
+    if (s != 0.0f)
+    {
+        r2[6] -= m2 * s;
+        r3[6] -= m3 * s;
+    }
+    s = r1[7];
+    if (s != 0.0f)
+    {
+        r2[7] -= m2 * s;
+        r3[7] -= m3 * s;
+    }
+
+    /* Choose pivot - or die. */
+    if (fabsf(r3[2]) > fabsf(r2[2]))
+        swap_rows(&r3, &r2);
+    if (r2[2] == 0.0f)
+        return FALSE;
+
+    /* Eliminate third variable. */
+    m3 = r3[2] / r2[2];
+    r3[3] -= m3 * r2[3];
+    r3[4] -= m3 * r2[4];
+    r3[5] -= m3 * r2[5];
+    r3[6] -= m3 * r2[6];
+    r3[7] -= m3 * r2[7];
+
+    /* Last check. */
+    if (r3[3] == 0.0f)
+        return FALSE;
+
+    /* Back substitute row 3. */
+    s = 1.0f / r3[3];
+    r3[4] *= s;
+    r3[5] *= s;
+    r3[6] *= s;
+    r3[7] *= s;
+
+    /* Back substitute row 2. */
+    m2 = r2[3];
+    s = 1.0f / r2[2];
+    r2[4] = s * (r2[4] - r3[4] * m2);
+    r2[5] = s * (r2[5] - r3[5] * m2);
+    r2[6] = s * (r2[6] - r3[6] * m2);
+    r2[7] = s * (r2[7] - r3[7] * m2);
+    m1 = r1[3];
+    r1[4] -= r3[4] * m1;
+    r1[5] -= r3[5] * m1;
+    r1[6] -= r3[6] * m1;
+    r1[7] -= r3[7] * m1;
+    m0 = r0[3];
+    r0[4] -= r3[4] * m0;
+    r0[5] -= r3[5] * m0;
+    r0[6] -= r3[6] * m0;
+    r0[7] -= r3[7] * m0;
+
+    /* Back substitute row 1. */
+    m1 = r1[2];
+    s = 1.0f / r1[1];
+    r1[4] = s * (r1[4] - r2[4] * m1);
+    r1[5] = s * (r1[5] - r2[5] * m1);
+    r1[6] = s * (r1[6] - r2[6] * m1);
+    r1[7] = s * (r1[7] - r2[7] * m1);
+    m0 = r0[2];
+    r0[4] -= r2[4] * m0;
+    r0[5] -= r2[5] * m0;
+    r0[6] -= r2[6] * m0;
+    r0[7] -= r2[7] * m0;
+
+    /* Back substitute row 0. */
+    m0 = r0[1];
+    s = 1.0f / r0[0];
+    r0[4] = s * (r0[4] - r1[4] * m0);
+    r0[5] = s * (r0[5] - r1[5] * m0);
+    r0[6] = s * (r0[6] - r1[6] * m0);
+    r0[7] = s * (r0[7] - r1[7] * m0);
+
+    out->_11 = r0[4];
+    out->_12 = r0[5];
+    out->_13 = r0[6];
+    out->_14 = r0[7];
+    out->_21 = r1[4];
+    out->_22 = r1[5];
+    out->_23 = r1[6];
+    out->_24 = r1[7];
+    out->_31 = r2[4];
+    out->_32 = r2[5];
+    out->_33 = r2[6];
+    out->_34 = r2[7];
+    out->_41 = r3[4];
+    out->_42 = r3[5];
+    out->_43 = r3[6];
+    out->_44 = r3[7];
+
+    return TRUE;
+}
+
+void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m)
+{
+    struct wined3d_matrix temp;
+    unsigned int i, j;
+
+    for (i = 0; i < 4; ++i)
+        for (j = 0; j < 4; ++j)
+            (&temp._11)[4 * j + i] = (&m->_11)[4 * i + j];
+
+    *out = temp;
+}
+
 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
     DWORD size = 0;
     int i;
 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
     DWORD size = 0;
     int i;
@@ -5734,7 +6093,27 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st
     {
         switch (texture->target)
         {
     {
         switch (texture->target)
         {
+            case GL_TEXTURE_1D:
+                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+                checkGLcall("glDisable(GL_TEXTURE_2D)");
+                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+                checkGLcall("glDisable(GL_TEXTURE_3D)");
+                if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+                {
+                    gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+                    checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+                }
+                if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+                {
+                    gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+                    checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+                }
+                gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_1D);
+                checkGLcall("glEnable(GL_TEXTURE_1D)");
+                break;
             case GL_TEXTURE_2D:
             case GL_TEXTURE_2D:
+                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+                checkGLcall("glDisable(GL_TEXTURE_1D)");
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
                 checkGLcall("glDisable(GL_TEXTURE_3D)");
                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
                 checkGLcall("glDisable(GL_TEXTURE_3D)");
                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
@@ -5751,6 +6130,8 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st
                 checkGLcall("glEnable(GL_TEXTURE_2D)");
                 break;
             case GL_TEXTURE_RECTANGLE_ARB:
                 checkGLcall("glEnable(GL_TEXTURE_2D)");
                 break;
             case GL_TEXTURE_RECTANGLE_ARB:
+                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+                checkGLcall("glDisable(GL_TEXTURE_1D)");
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
                 checkGLcall("glDisable(GL_TEXTURE_2D)");
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
                 checkGLcall("glDisable(GL_TEXTURE_2D)");
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
@@ -5774,12 +6155,16 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st
                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
                 }
                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
                 }
+                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+                checkGLcall("glDisable(GL_TEXTURE_1D)");
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
                 checkGLcall("glDisable(GL_TEXTURE_2D)");
                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
                 checkGLcall("glEnable(GL_TEXTURE_3D)");
                 break;
             case GL_TEXTURE_CUBE_MAP_ARB:
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
                 checkGLcall("glDisable(GL_TEXTURE_2D)");
                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
                 checkGLcall("glEnable(GL_TEXTURE_3D)");
                 break;
             case GL_TEXTURE_CUBE_MAP_ARB:
+                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+                checkGLcall("glDisable(GL_TEXTURE_1D)");
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
                 checkGLcall("glDisable(GL_TEXTURE_2D)");
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
                 checkGLcall("glDisable(GL_TEXTURE_2D)");
                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
@@ -5796,6 +6181,8 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st
     }
     else
     {
     }
     else
     {
+        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+        checkGLcall("glDisable(GL_TEXTURE_1D)");
         gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
         checkGLcall("glEnable(GL_TEXTURE_2D)");
         gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
         gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
         checkGLcall("glEnable(GL_TEXTURE_2D)");
         gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
@@ -5896,6 +6283,14 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
             break;
     }
 
             break;
     }
 
+    if (use_indexed_vertex_blending(state, si))
+    {
+        if (use_software_vertex_processing(context->device))
+            settings->sw_blending = 1;
+        else
+            settings->vb_indices = 1;
+    }
+
     settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
             && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
     settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL));
     settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
             && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
     settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL));
@@ -5991,21 +6386,11 @@ int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb
     return memcmp(ka, kb, sizeof(*ka));
 }
 
     return memcmp(ka, kb, sizeof(*ka));
 }
 
-void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
-{
-    const struct wined3d_viewport *vp = &state->viewport;
-
-    SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
-
-    if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
-        IntersectRect(rect, rect, &state->scissor_rect);
-}
-
 const char *wined3d_debug_location(DWORD location)
 {
 const char *wined3d_debug_location(DWORD location)
 {
+    struct debug_buffer buffer;
     const char *prefix = "";
     const char *suffix = "";
     const char *prefix = "";
     const char *suffix = "";
-    char buf[294];
 
     if (wined3d_popcount(location) > 16)
     {
 
     if (wined3d_popcount(location) > 16)
     {
@@ -6014,8 +6399,8 @@ const char *wined3d_debug_location(DWORD location)
         suffix = ")";
     }
 
         suffix = ")";
     }
 
-    buf[0] = '\0';
-#define LOCATION_TO_STR(u) if (location & u) { strcat(buf, " | "#u); location &= ~u; }
+    init_debug_buffer(&buffer, "0");
+#define LOCATION_TO_STR(x) if (location & x) { debug_append(&buffer, #x, " | "); location &= ~x; }
     LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED);
     LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM);
     LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY);
     LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED);
     LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM);
     LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY);
@@ -6026,9 +6411,10 @@ const char *wined3d_debug_location(DWORD location)
     LOCATION_TO_STR(WINED3D_LOCATION_RB_MULTISAMPLE);
     LOCATION_TO_STR(WINED3D_LOCATION_RB_RESOLVED);
 #undef LOCATION_TO_STR
     LOCATION_TO_STR(WINED3D_LOCATION_RB_MULTISAMPLE);
     LOCATION_TO_STR(WINED3D_LOCATION_RB_RESOLVED);
 #undef LOCATION_TO_STR
-    if (location) FIXME("Unrecognized location flag(s) %#x.\n", location);
+    if (location)
+        FIXME("Unrecognized location flag(s) %#x.\n", location);
 
 
-    return wine_dbg_sprintf("%s%s%s", prefix, buf[0] ? &buf[3] : "0", suffix);
+    return wine_dbg_sprintf("%s%s%s", prefix, buffer.str, suffix);
 }
 
 /* Print a floating point value with the %.8e format specifier, always using
 }
 
 /* Print a floating point value with the %.8e format specifier, always using
@@ -6149,7 +6535,7 @@ BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE
         new_capacity = count;
 
     if (!*elements)
         new_capacity = count;
 
     if (!*elements)
-        new_elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_capacity * size);
+        new_elements = heap_alloc_zero(new_capacity * size);
     else
         new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size);
     if (!new_elements)
     else
         new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size);
     if (!new_elements)
index 990aab0..82348b4 100644 (file)
@@ -22,6 +22,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl);
@@ -52,8 +54,8 @@ static void wined3d_vertex_declaration_destroy_object(void *object)
 {
     struct wined3d_vertex_declaration *declaration = object;
 
 {
     struct wined3d_vertex_declaration *declaration = object;
 
-    HeapFree(GetProcessHeap(), 0, declaration->elements);
-    HeapFree(GetProcessHeap(), 0, declaration);
+    heap_free(declaration->elements);
+    heap_free(declaration);
 }
 
 ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration)
 }
 
 ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration)
@@ -117,6 +119,15 @@ static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *e
                     return FALSE;
             }
 
                     return FALSE;
             }
 
+        case WINED3D_DECL_USAGE_BLEND_INDICES:
+            switch(element->format)
+            {
+                case WINED3DFMT_R8G8B8A8_UINT:
+                    return TRUE;
+                default:
+                    return FALSE;
+            }
+
         case WINED3D_DECL_USAGE_NORMAL:
             switch(element->format)
             {
         case WINED3D_DECL_USAGE_NORMAL:
             switch(element->format)
             {
@@ -186,7 +197,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara
     declaration->parent = parent;
     declaration->parent_ops = parent_ops;
     declaration->device = device;
     declaration->parent = parent;
     declaration->parent_ops = parent_ops;
     declaration->device = device;
-    if (!(declaration->elements = wined3d_calloc(element_count, sizeof(*declaration->elements))))
+    if (!(declaration->elements = heap_calloc(element_count, sizeof(*declaration->elements))))
     {
         ERR("Failed to allocate elements memory.\n");
         return E_OUTOFMEMORY;
     {
         ERR("Failed to allocate elements memory.\n");
         return E_OUTOFMEMORY;
@@ -221,7 +232,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara
         {
             FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n",
                     debug_d3dformat(elements[i].format));
         {
             FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n",
                     debug_d3dformat(elements[i].format));
-            HeapFree(GetProcessHeap(), 0, declaration->elements);
+            heap_free(declaration->elements);
             return E_FAIL;
         }
 
             return E_FAIL;
         }
 
@@ -245,7 +256,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara
         if (e->offset & 0x3)
         {
             WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);
         if (e->offset & 0x3)
         {
             WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);
-            HeapFree(GetProcessHeap(), 0, declaration->elements);
+            heap_free(declaration->elements);
             return E_FAIL;
         }
 
             return E_FAIL;
         }
 
@@ -268,15 +279,14 @@ HRESULT CDECL wined3d_vertex_declaration_create(struct wined3d_device *device,
     TRACE("device %p, elements %p, element_count %u, parent %p, parent_ops %p, declaration %p.\n",
             device, elements, element_count, parent, parent_ops, declaration);
 
     TRACE("device %p, elements %p, element_count %u, parent %p, parent_ops %p, declaration %p.\n",
             device, elements, element_count, parent, parent_ops, declaration);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if(!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     hr = vertexdeclaration_init(object, device, elements, element_count, parent, parent_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
         return E_OUTOFMEMORY;
 
     hr = vertexdeclaration_init(object, device, elements, element_count, parent, parent_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return hr;
     }
 
         return hr;
     }
 
@@ -344,7 +354,7 @@ static unsigned int convert_fvf_to_declaration(const struct wined3d_gl_info *gl_
            has_psize + has_diffuse + has_specular + num_textures;
 
     state.gl_info = gl_info;
            has_psize + has_diffuse + has_specular + num_textures;
 
     state.gl_info = gl_info;
-    if (!(state.elements = wined3d_calloc(size, sizeof(*state.elements))))
+    if (!(state.elements = heap_calloc(size, sizeof(*state.elements))))
         return ~0u;
     state.offset = 0;
     state.idx = 0;
         return ~0u;
     state.offset = 0;
     state.idx = 0;
@@ -443,6 +453,6 @@ HRESULT CDECL wined3d_vertex_declaration_create_from_fvf(struct wined3d_device *
     if (size == ~0U) return E_OUTOFMEMORY;
 
     hr = wined3d_vertex_declaration_create(device, elements, size, parent, parent_ops, declaration);
     if (size == ~0U) return E_OUTOFMEMORY;
 
     hr = wined3d_vertex_declaration_create(device, elements, size, parent, parent_ops, declaration);
-    HeapFree(GetProcessHeap(), 0, elements);
+    heap_free(elements);
     return hr;
 }
     return hr;
 }
index 909467c..bed39db 100644 (file)
@@ -17,6 +17,9 @@
  *
  */
 
  *
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -41,15 +44,26 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info,
     }
     view_types[] =
     {
     }
     view_types[] =
     {
-        {GL_TEXTURE_CUBE_MAP,  0,                          GL_TEXTURE_CUBE_MAP},
-        {GL_TEXTURE_RECTANGLE, 0,                          GL_TEXTURE_RECTANGLE},
-        {GL_TEXTURE_2D,        0,                          GL_TEXTURE_2D},
-        {GL_TEXTURE_2D,        WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
-        {GL_TEXTURE_2D_ARRAY,  0,                          GL_TEXTURE_2D},
-        {GL_TEXTURE_2D_ARRAY,  WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
-        {GL_TEXTURE_2D_ARRAY,  WINED3D_VIEW_TEXTURE_CUBE,  GL_TEXTURE_CUBE_MAP},
-        {GL_TEXTURE_2D_ARRAY,  WINED3D_VIEW_CUBE_ARRAY,    GL_TEXTURE_CUBE_MAP_ARRAY, ARB_TEXTURE_CUBE_MAP_ARRAY},
-        {GL_TEXTURE_3D,        0,                          GL_TEXTURE_3D},
+        {GL_TEXTURE_CUBE_MAP,  0, GL_TEXTURE_CUBE_MAP},
+        {GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_RECTANGLE},
+        {GL_TEXTURE_3D,        0, GL_TEXTURE_3D},
+
+        {GL_TEXTURE_1D,       0,                          GL_TEXTURE_1D},
+        {GL_TEXTURE_1D,       WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
+        {GL_TEXTURE_1D_ARRAY, 0,                          GL_TEXTURE_1D},
+        {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
+
+        {GL_TEXTURE_2D,       0,                          GL_TEXTURE_2D},
+        {GL_TEXTURE_2D,       WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
+        {GL_TEXTURE_2D_ARRAY, 0,                          GL_TEXTURE_2D},
+        {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
+        {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_TEXTURE_CUBE,  GL_TEXTURE_CUBE_MAP},
+        {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_CUBE_ARRAY,    GL_TEXTURE_CUBE_MAP_ARRAY, ARB_TEXTURE_CUBE_MAP_ARRAY},
+
+        {GL_TEXTURE_2D_MULTISAMPLE,       0,                          GL_TEXTURE_2D_MULTISAMPLE},
+        {GL_TEXTURE_2D_MULTISAMPLE,       WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
+        {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0,                          GL_TEXTURE_2D_MULTISAMPLE},
+        {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
     };
     unsigned int i;
 
     };
     unsigned int i;
 
@@ -328,7 +342,7 @@ static void wined3d_rendertarget_view_destroy_object(void *object)
         context_release(context);
     }
 
         context_release(context);
     }
 
-    HeapFree(GetProcessHeap(), 0, view);
+    heap_free(view);
 }
 
 ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view)
 }
 
 ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view)
@@ -591,12 +605,12 @@ HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_view_desc *d
     TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
             desc, resource, parent, parent_ops, view);
 
     TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
             desc, resource, parent, parent_ops, view);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_rendertarget_view_init(object, desc, resource, parent, parent_ops)))
     {
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_rendertarget_view_init(object, desc, resource, parent, parent_ops)))
     {
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         WARN("Failed to initialise view, hr %#x.\n", hr);
         return hr;
     }
         WARN("Failed to initialise view, hr %#x.\n", hr);
         return hr;
     }
@@ -651,7 +665,7 @@ static void wined3d_shader_resource_view_destroy_object(void *object)
         context_release(context);
     }
 
         context_release(context);
     }
 
-    HeapFree(GetProcessHeap(), 0, view);
+    heap_free(view);
 }
 
 ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view)
 }
 
 ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view)
@@ -736,6 +750,10 @@ static void wined3d_shader_resource_view_cs_init(void *object)
                     debug_d3dformat(resource->format->id), debug_d3dformat(view_format->id));
         }
     }
                     debug_d3dformat(resource->format->id), debug_d3dformat(view_format->id));
         }
     }
+#if defined(STAGING_CSMT)
+
+    wined3d_resource_release(resource);
+#endif /* STAGING_CSMT */
 }
 
 static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_view *view,
 }
 
 static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_view *view,
@@ -752,6 +770,9 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_
 
     wined3d_resource_incref(view->resource = resource);
 
 
     wined3d_resource_incref(view->resource = resource);
 
+#if defined(STAGING_CSMT)
+    wined3d_resource_acquire(resource);
+#endif /* STAGING_CSMT */
     wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_cs_init, view);
 
     return WINED3D_OK;
     wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_cs_init, view);
 
     return WINED3D_OK;
@@ -767,12 +788,12 @@ HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_view_desc
     TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
             desc, resource, parent, parent_ops, view);
 
     TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
             desc, resource, parent, parent_ops, view);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_shader_resource_view_init(object, desc, resource, parent, parent_ops)))
     {
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_shader_resource_view_init(object, desc, resource, parent, parent_ops)))
     {
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         WARN("Failed to initialise view, hr %#x.\n", hr);
         return hr;
     }
         WARN("Failed to initialise view, hr %#x.\n", hr);
         return hr;
     }
@@ -943,7 +964,7 @@ static void wined3d_unordered_access_view_destroy_object(void *object)
         context_release(context);
     }
 
         context_release(context);
     }
 
-    HeapFree(GetProcessHeap(), 0, view);
+    heap_free(view);
 }
 
 ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view *view)
 }
 
 ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view *view)
@@ -1104,6 +1125,10 @@ static void wined3d_unordered_access_view_cs_init(void *object)
                     desc, texture, view->format);
         }
     }
                     desc, texture, view->format);
         }
     }
+#if defined(STAGING_CSMT)
+
+    wined3d_resource_release(resource);
+#endif /* STAGING_CSMT */
 }
 
 static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_access_view *view,
 }
 
 static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_access_view *view,
@@ -1120,6 +1145,9 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces
 
     wined3d_resource_incref(view->resource = resource);
 
 
     wined3d_resource_incref(view->resource = resource);
 
+#if defined(STAGING_CSMT)
+    wined3d_resource_acquire(resource);
+#endif /* STAGING_CSMT */
     wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_cs_init, view);
 
     return WINED3D_OK;
     wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_cs_init, view);
 
     return WINED3D_OK;
@@ -1135,12 +1163,12 @@ HRESULT CDECL wined3d_unordered_access_view_create(const struct wined3d_view_des
     TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
             desc, resource, parent, parent_ops, view);
 
     TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
             desc, resource, parent, parent_ops, view);
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_unordered_access_view_init(object, desc, resource, parent, parent_ops)))
     {
         return E_OUTOFMEMORY;
 
     if (FAILED(hr = wined3d_unordered_access_view_init(object, desc, resource, parent, parent_ops)))
     {
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         WARN("Failed to initialise view, hr %#x.\n", hr);
         return hr;
     }
         WARN("Failed to initialise view, hr %#x.\n", hr);
         return hr;
     }
index 74e61ea..3022e20 100644 (file)
 @ cdecl wined3d_register_software_device(ptr ptr)
 @ cdecl wined3d_set_adapter_display_mode(ptr long ptr)
 
 @ cdecl wined3d_register_software_device(ptr ptr)
 @ cdecl wined3d_set_adapter_display_mode(ptr long ptr)
 
+@ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr)
+@ cdecl wined3d_blend_state_decref(ptr)
+@ cdecl wined3d_blend_state_get_parent(ptr)
+@ cdecl wined3d_blend_state_incref(ptr)
+
 @ cdecl wined3d_buffer_create(ptr ptr ptr ptr ptr ptr)
 @ cdecl wined3d_buffer_create(ptr ptr ptr ptr ptr ptr)
-@ cdecl wined3d_buffer_create_ib(ptr long long long ptr ptr ptr)
-@ cdecl wined3d_buffer_create_vb(ptr long long long ptr ptr ptr)
 @ cdecl wined3d_buffer_decref(ptr)
 @ cdecl wined3d_buffer_get_parent(ptr)
 @ cdecl wined3d_buffer_get_resource(ptr)
 @ cdecl wined3d_buffer_decref(ptr)
 @ cdecl wined3d_buffer_get_parent(ptr)
 @ cdecl wined3d_buffer_get_resource(ptr)
@@ -54,6 +57,7 @@
 @ cdecl wined3d_device_evict_managed_resources(ptr)
 @ cdecl wined3d_device_get_available_texture_mem(ptr)
 @ cdecl wined3d_device_get_base_vertex_index(ptr)
 @ cdecl wined3d_device_evict_managed_resources(ptr)
 @ cdecl wined3d_device_get_available_texture_mem(ptr)
 @ cdecl wined3d_device_get_base_vertex_index(ptr)
+@ cdecl wined3d_device_get_blend_state(ptr)
 @ cdecl wined3d_device_get_clip_plane(ptr long ptr)
 @ cdecl wined3d_device_get_clip_status(ptr ptr)
 @ cdecl wined3d_device_get_compute_shader(ptr)
 @ cdecl wined3d_device_get_clip_plane(ptr long ptr)
 @ cdecl wined3d_device_get_clip_status(ptr ptr)
 @ cdecl wined3d_device_get_compute_shader(ptr)
 @ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long)
 @ cdecl wined3d_device_release_focus_window(ptr)
 @ cdecl wined3d_device_reset(ptr ptr ptr ptr long)
 @ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long)
 @ cdecl wined3d_device_release_focus_window(ptr)
 @ cdecl wined3d_device_reset(ptr ptr ptr ptr long)
+@ cdecl wined3d_device_resolve_sub_resource(ptr ptr long ptr long long)
 @ cdecl wined3d_device_restore_fullscreen_window(ptr ptr ptr)
 @ cdecl wined3d_device_set_base_vertex_index(ptr long)
 @ cdecl wined3d_device_restore_fullscreen_window(ptr ptr ptr)
 @ cdecl wined3d_device_set_base_vertex_index(ptr long)
+@ cdecl wined3d_device_set_blend_state(ptr ptr)
 @ cdecl wined3d_device_set_clip_plane(ptr long ptr)
 @ cdecl wined3d_device_set_clip_status(ptr ptr)
 @ cdecl wined3d_device_set_compute_shader(ptr ptr)
 @ cdecl wined3d_device_set_clip_plane(ptr long ptr)
 @ cdecl wined3d_device_set_clip_status(ptr ptr)
 @ cdecl wined3d_device_set_compute_shader(ptr ptr)
 @ cdecl wined3d_resource_get_parent(ptr)
 @ cdecl wined3d_resource_get_priority(ptr)
 @ cdecl wined3d_resource_map(ptr long ptr ptr long)
 @ cdecl wined3d_resource_get_parent(ptr)
 @ cdecl wined3d_resource_get_priority(ptr)
 @ cdecl wined3d_resource_map(ptr long ptr ptr long)
+@ cdecl wined3d_resource_map_info(ptr long ptr long)
 @ cdecl wined3d_resource_preload(ptr)
 @ cdecl wined3d_resource_set_parent(ptr ptr)
 @ cdecl wined3d_resource_set_priority(ptr long)
 @ cdecl wined3d_resource_unmap(ptr long)
 @ cdecl wined3d_resource_preload(ptr)
 @ cdecl wined3d_resource_set_parent(ptr ptr)
 @ cdecl wined3d_resource_set_priority(ptr long)
 @ cdecl wined3d_resource_unmap(ptr long)
+@ cdecl wined3d_resource_update_info(ptr long ptr long long)
 
 @ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_rendertarget_view_create_from_sub_resource(ptr long ptr ptr ptr)
 
 @ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_rendertarget_view_create_from_sub_resource(ptr long ptr ptr ptr)
 @ cdecl wined3d_stateblock_decref(ptr)
 @ cdecl wined3d_stateblock_incref(ptr)
 
 @ cdecl wined3d_stateblock_decref(ptr)
 @ cdecl wined3d_stateblock_incref(ptr)
 
+@ cdecl wined3d_strictdrawing_set(long)
+
 @ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_swapchain_decref(ptr)
 @ cdecl wined3d_swapchain_get_back_buffer(ptr long)
 @ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_swapchain_decref(ptr)
 @ cdecl wined3d_swapchain_get_back_buffer(ptr long)
 @ cdecl wined3d_swapchain_get_desc(ptr ptr)
 @ cdecl wined3d_swapchain_get_raster_status(ptr ptr)
 @ cdecl wined3d_swapchain_incref(ptr)
 @ cdecl wined3d_swapchain_get_desc(ptr ptr)
 @ cdecl wined3d_swapchain_get_raster_status(ptr ptr)
 @ cdecl wined3d_swapchain_incref(ptr)
-@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr long)
+@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr long long)
 @ cdecl wined3d_swapchain_resize_buffers(ptr long long long long long long)
 @ cdecl wined3d_swapchain_resize_target(ptr ptr)
 @ cdecl wined3d_swapchain_set_fullscreen(ptr ptr ptr)
 @ cdecl wined3d_swapchain_resize_buffers(ptr long long long long long long)
 @ cdecl wined3d_swapchain_resize_target(ptr ptr)
 @ cdecl wined3d_swapchain_set_fullscreen(ptr ptr ptr)
 @ cdecl wined3d_texture_create(ptr ptr long long long ptr ptr ptr ptr)
 @ cdecl wined3d_texture_decref(ptr)
 @ cdecl wined3d_texture_from_resource(ptr)
 @ cdecl wined3d_texture_create(ptr ptr long long long ptr ptr ptr ptr)
 @ cdecl wined3d_texture_decref(ptr)
 @ cdecl wined3d_texture_from_resource(ptr)
-@ cdecl wined3d_texture_get_autogen_filter_type(ptr)
 @ cdecl wined3d_texture_get_dc(ptr long ptr)
 @ cdecl wined3d_texture_get_level_count(ptr)
 @ cdecl wined3d_texture_get_lod(ptr)
 @ cdecl wined3d_texture_get_dc(ptr long ptr)
 @ cdecl wined3d_texture_get_level_count(ptr)
 @ cdecl wined3d_texture_get_lod(ptr)
 @ cdecl wined3d_texture_get_sub_resource_parent(ptr long)
 @ cdecl wined3d_texture_incref(ptr)
 @ cdecl wined3d_texture_release_dc(ptr long ptr)
 @ cdecl wined3d_texture_get_sub_resource_parent(ptr long)
 @ cdecl wined3d_texture_incref(ptr)
 @ cdecl wined3d_texture_release_dc(ptr long 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_set_overlay_position(ptr long long long)
 @ cdecl wined3d_texture_set_color_key(ptr long ptr)
 @ cdecl wined3d_texture_set_lod(ptr long)
 @ cdecl wined3d_texture_set_overlay_position(ptr long long long)
 @ cdecl wined3d_vertex_declaration_decref(ptr)
 @ cdecl wined3d_vertex_declaration_get_parent(ptr)
 @ cdecl wined3d_vertex_declaration_incref(ptr)
 @ cdecl wined3d_vertex_declaration_decref(ptr)
 @ cdecl wined3d_vertex_declaration_get_parent(ptr)
 @ cdecl wined3d_vertex_declaration_incref(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 0894c94..87283c8 100644 (file)
@@ -55,6 +55,7 @@ enum wined3d_gl_extension
     ARB_CULL_DISTANCE,
     ARB_DEBUG_OUTPUT,
     ARB_DEPTH_BUFFER_FLOAT,
     ARB_CULL_DISTANCE,
     ARB_DEBUG_OUTPUT,
     ARB_DEPTH_BUFFER_FLOAT,
+    ARB_DEPTH_CLAMP,
     ARB_DEPTH_TEXTURE,
     ARB_DERIVATIVE_CONTROL,
     ARB_DRAW_BUFFERS,
     ARB_DEPTH_TEXTURE,
     ARB_DERIVATIVE_CONTROL,
     ARB_DRAW_BUFFERS,
@@ -68,6 +69,7 @@ enum wined3d_gl_extension
     ARB_FRAGMENT_LAYER_VIEWPORT,
     ARB_FRAGMENT_PROGRAM,
     ARB_FRAGMENT_SHADER,
     ARB_FRAGMENT_LAYER_VIEWPORT,
     ARB_FRAGMENT_PROGRAM,
     ARB_FRAGMENT_SHADER,
+    ARB_FRAMEBUFFER_NO_ATTACHMENTS,
     ARB_FRAMEBUFFER_OBJECT,
     ARB_FRAMEBUFFER_SRGB,
     ARB_GEOMETRY_SHADER4,
     ARB_FRAMEBUFFER_OBJECT,
     ARB_FRAMEBUFFER_SRGB,
     ARB_GEOMETRY_SHADER4,
@@ -117,12 +119,14 @@ enum wined3d_gl_extension
     ARB_TEXTURE_GATHER,
     ARB_TEXTURE_MIRRORED_REPEAT,
     ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE,
     ARB_TEXTURE_GATHER,
     ARB_TEXTURE_MIRRORED_REPEAT,
     ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE,
+    ARB_TEXTURE_MULTISAMPLE,
     ARB_TEXTURE_NON_POWER_OF_TWO,
     ARB_TEXTURE_QUERY_LEVELS,
     ARB_TEXTURE_RECTANGLE,
     ARB_TEXTURE_RG,
     ARB_TEXTURE_RGB10_A2UI,
     ARB_TEXTURE_STORAGE,
     ARB_TEXTURE_NON_POWER_OF_TWO,
     ARB_TEXTURE_QUERY_LEVELS,
     ARB_TEXTURE_RECTANGLE,
     ARB_TEXTURE_RG,
     ARB_TEXTURE_RGB10_A2UI,
     ARB_TEXTURE_STORAGE,
+    ARB_TEXTURE_STORAGE_MULTISAMPLE,
     ARB_TEXTURE_SWIZZLE,
     ARB_TEXTURE_VIEW,
     ARB_TIMER_QUERY,
     ARB_TEXTURE_SWIZZLE,
     ARB_TEXTURE_VIEW,
     ARB_TIMER_QUERY,
@@ -159,6 +163,7 @@ enum wined3d_gl_extension
     EXT_PACKED_DEPTH_STENCIL,
     EXT_PACKED_FLOAT,
     EXT_POINT_PARAMETERS,
     EXT_PACKED_DEPTH_STENCIL,
     EXT_PACKED_FLOAT,
     EXT_POINT_PARAMETERS,
+    EXT_POLYGON_OFFSET_CLAMP,
     EXT_PROVOKING_VERTEX,
     EXT_SECONDARY_COLOR,
     EXT_STENCIL_TWO_SIDE,
     EXT_PROVOKING_VERTEX,
     EXT_SECONDARY_COLOR,
     EXT_STENCIL_TWO_SIDE,
@@ -197,8 +202,7 @@ enum wined3d_gl_extension
     NV_VERTEX_PROGRAM2,
     NV_VERTEX_PROGRAM2_OPTION,
     NV_VERTEX_PROGRAM3,
     NV_VERTEX_PROGRAM2,
     NV_VERTEX_PROGRAM2_OPTION,
     NV_VERTEX_PROGRAM3,
-    /* SGI */
-    SGIS_GENERATE_MIPMAP,
+    NVX_GPU_MEMORY_INFO,
     /* WGL extensions */
     WGL_ARB_PIXEL_FORMAT,
     WGL_EXT_SWAP_CONTROL,
     /* WGL extensions */
     WGL_ARB_PIXEL_FORMAT,
     WGL_EXT_SWAP_CONTROL,
index a60764d..28e6fe6 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "wined3d_private.h"
+#include "config.h"
+#include "wine/port.h"
 
 
-#include <winreg.h>
+#include "initguid.h"
+#include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
@@ -70,7 +72,7 @@ static CRITICAL_SECTION wined3d_wndproc_cs = {&wined3d_wndproc_cs_debug, -1, 0,
  * where appropriate. */
 struct wined3d_settings wined3d_settings =
 {
  * where appropriate. */
 struct wined3d_settings wined3d_settings =
 {
-    FALSE,          /* No multithreaded CS by default. */
+    TRUE,           /* Multithreaded CS by default. */
     FALSE,          /* explicit_gl_version */
     MAKEDWORD_VERSION(1, 0), /* Default to legacy OpenGL */
     TRUE,           /* Use of GLSL enabled by default */
     FALSE,          /* explicit_gl_version */
     MAKEDWORD_VERSION(1, 0), /* Default to legacy OpenGL */
     TRUE,           /* Use of GLSL enabled by default */
@@ -79,6 +81,7 @@ struct wined3d_settings wined3d_settings =
     PCI_DEVICE_NONE,/* PCI Device ID */
     0,              /* The default of memory is set in init_driver_info */
     NULL,           /* No wine logo by default */
     PCI_DEVICE_NONE,/* PCI Device ID */
     0,              /* The default of memory is set in init_driver_info */
     NULL,           /* No wine logo by default */
+    TRUE,           /* Prefer multisample textures to multisample renderbuffers. */
     ~0u,            /* Don't force a specific sample count by default. */
     FALSE,          /* No strict draw ordering. */
     FALSE,          /* Don't range check relative addressing indices in float constants. */
     ~0u,            /* Don't force a specific sample count by default. */
     FALSE,          /* No strict draw ordering. */
     FALSE,          /* Don't range check relative addressing indices in float constants. */
@@ -96,8 +99,7 @@ struct wined3d * CDECL wined3d_create(DWORD flags)
     struct wined3d *object;
     HRESULT hr;
 
     struct wined3d *object;
     HRESULT hr;
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(struct wined3d, adapters[1]));
-    if (!object)
+    if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d, adapters[1]))))
     {
         ERR("Failed to allocate wined3d object memory.\n");
         return NULL;
     {
         ERR("Failed to allocate wined3d object memory.\n");
         return NULL;
@@ -110,7 +112,7 @@ struct wined3d * CDECL wined3d_create(DWORD flags)
     if (FAILED(hr))
     {
         WARN("Failed to initialize wined3d object, hr %#x.\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize wined3d object, hr %#x.\n", hr);
-        HeapFree(GetProcessHeap(), 0, object);
+        heap_free(object);
         return NULL;
     }
 
         return NULL;
     }
 
@@ -278,10 +280,13 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
         {
             size_t len = strlen(buffer) + 1;
 
         {
             size_t len = strlen(buffer) + 1;
 
-            wined3d_settings.logo = HeapAlloc(GetProcessHeap(), 0, len);
-            if (!wined3d_settings.logo) ERR("Failed to allocate logo path memory.\n");
-            else memcpy(wined3d_settings.logo, buffer, len);
+            if (!(wined3d_settings.logo = heap_alloc(len)))
+                ERR("Failed to allocate logo path memory.\n");
+            else
+                memcpy(wined3d_settings.logo, buffer, len);
         }
         }
+        if (!get_config_key_dword(hkey, appkey, "MultisampleTextures", &wined3d_settings.multisample_textures))
+            ERR_(winediag)("Setting multisample textures to %#x.\n", wined3d_settings.multisample_textures);
         if (!get_config_key_dword(hkey, appkey, "SampleCount", &wined3d_settings.sample_count))
             ERR_(winediag)("Forcing sample count to %u. This may not be compatible with all applications.\n",
                     wined3d_settings.sample_count);
         if (!get_config_key_dword(hkey, appkey, "SampleCount", &wined3d_settings.sample_count))
             ERR_(winediag)("Forcing sample count to %u. This may not be compatible with all applications.\n",
                     wined3d_settings.sample_count);
@@ -321,6 +326,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
     if (appkey) RegCloseKey( appkey );
     if (hkey) RegCloseKey( hkey );
 
     if (appkey) RegCloseKey( appkey );
     if (hkey) RegCloseKey( hkey );
 
+    wined3d_dxtn_init();
+
     return TRUE;
 }
 
     return TRUE;
 }
 
@@ -345,13 +352,16 @@ static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
          * these entries. */
         WARN("Leftover wndproc table entry %p.\n", &wndproc_table.entries[i]);
     }
          * these entries. */
         WARN("Leftover wndproc table entry %p.\n", &wndproc_table.entries[i]);
     }
-    HeapFree(GetProcessHeap(), 0, wndproc_table.entries);
+    heap_free(wndproc_table.entries);
 
 
-    HeapFree(GetProcessHeap(), 0, wined3d_settings.logo);
+    heap_free(wined3d_settings.logo);
     UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
 
     DeleteCriticalSection(&wined3d_wndproc_cs);
     DeleteCriticalSection(&wined3d_cs);
     UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
 
     DeleteCriticalSection(&wined3d_wndproc_cs);
     DeleteCriticalSection(&wined3d_cs);
+
+    wined3d_dxtn_free();
+
     return TRUE;
 }
 
     return TRUE;
 }
 
@@ -506,6 +516,11 @@ void wined3d_unregister_window(HWND window)
     wined3d_wndproc_mutex_unlock();
 }
 
     wined3d_wndproc_mutex_unlock();
 }
 
+void CDECL wined3d_strictdrawing_set(int value)
+{
+    wined3d_settings.strict_draw_ordering = value;
+}
+
 /* At process attach */
 BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
 {
 /* At process attach */
 BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
 {
index dd2967a..878a4d0 100644 (file)
 #ifndef __WINE_WINED3D_PRIVATE_H
 #define __WINE_WINED3D_PRIVATE_H
 
 #ifndef __WINE_WINED3D_PRIVATE_H
 #define __WINE_WINED3D_PRIVATE_H
 
-#include <wine/config.h>
-#include <wine/port.h>
-
 #ifdef USE_WIN32_OPENGL
 #define WINE_GLAPI __stdcall
 #else
 #define WINE_GLAPI
 #endif
 
 #ifdef USE_WIN32_OPENGL
 #define WINE_GLAPI __stdcall
 #else
 #define WINE_GLAPI
 #endif
 
-#ifdef HAVE_FLOAT_H
-# include <float.h>
-#endif
-
 #include <assert.h>
 #include <assert.h>
-#include <stdio.h>
-
-#include <ntstatus.h>
+#include <stdarg.h>
+#include <math.h>
+#include <limits.h>
+#include "ntstatus.h"
 #define WIN32_NO_STATUS
 #define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #define COBJMACROS
-
-#include <windef.h>
-#include <winbase.h>
-#include <wingdi.h>
-#include <winuser.h>
-#include <wine/winternl.h>
-#include <ddk/d3dkmthk.h>
-#include <objbase.h>
-
-#include <wine/debug.h>
-#include <wine/list.h>
-#include <wine/rbtree.h>
-#include <wine/wined3d.h>
-
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winternl.h"
+#include "ddk/d3dkmthk.h"
+#include "wine/debug.h"
+#include "wine/heap.h"
+#include "wine/unicode.h"
+
+#include "objbase.h"
+#include "wine/wined3d.h"
 #include "wined3d_gl.h"
 #include "wined3d_gl.h"
-#include <wine/wgl_driver.h>
-
-#include <reactos/undocuser.h>
+#include "wine/list.h"
+#include "wine/rbtree.h"
+#include "wine/wgl_driver.h"
 
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
 
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
@@ -204,6 +194,7 @@ struct wined3d_d3d_info
     BOOL vs_clipping;
     BOOL shader_color_key;
     DWORD valid_rt_mask;
     BOOL vs_clipping;
     BOOL shader_color_key;
     DWORD valid_rt_mask;
+    DWORD valid_dual_rt_mask;
     DWORD wined3d_creation_flags;
     BOOL shader_double_precision;
 };
     DWORD wined3d_creation_flags;
     BOOL shader_double_precision;
 };
@@ -281,10 +272,13 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup
 #define MAX_CONSTANT_BUFFERS        15
 #define MAX_SAMPLER_OBJECTS         16
 #define MAX_SHADER_RESOURCE_VIEWS   128
 #define MAX_CONSTANT_BUFFERS        15
 #define MAX_SAMPLER_OBJECTS         16
 #define MAX_SHADER_RESOURCE_VIEWS   128
+#define MAX_RENDER_TARGET_VIEWS     8
 #define MAX_UNORDERED_ACCESS_VIEWS  8
 #define MAX_TGSM_REGISTERS          8192
 #define MAX_VERTEX_BLENDS           4
 #define MAX_UNORDERED_ACCESS_VIEWS  8
 #define MAX_TGSM_REGISTERS          8192
 #define MAX_VERTEX_BLENDS           4
+#define MAX_VERTEX_INDEX_BLENDS     9
 #define MAX_MULTISAMPLE_TYPES       8
 #define MAX_MULTISAMPLE_TYPES       8
+#define MAX_RENDER_TARGETS          8
 
 struct min_lookup
 {
 
 struct min_lookup
 {
@@ -402,6 +396,7 @@ struct wined3d_settings
     /* Memory tracking and object counting. */
     UINT64 emulated_textureram;
     char *logo;
     /* Memory tracking and object counting. */
     UINT64 emulated_textureram;
     char *logo;
+    unsigned int multisample_textures;
     unsigned int sample_count;
     BOOL strict_draw_ordering;
     BOOL check_float_constants;
     unsigned int sample_count;
     BOOL strict_draw_ordering;
     BOOL check_float_constants;
@@ -446,13 +441,14 @@ enum wined3d_shader_resource_type
 #define WINED3D_SHADER_CONST_PS_Y_CORR       0x00001000
 #define WINED3D_SHADER_CONST_PS_NP2_FIXUP    0x00002000
 #define WINED3D_SHADER_CONST_FFP_MODELVIEW   0x00004000
 #define WINED3D_SHADER_CONST_PS_Y_CORR       0x00001000
 #define WINED3D_SHADER_CONST_PS_NP2_FIXUP    0x00002000
 #define WINED3D_SHADER_CONST_FFP_MODELVIEW   0x00004000
-#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0x00008000
 #define WINED3D_SHADER_CONST_FFP_PROJ        0x00010000
 #define WINED3D_SHADER_CONST_FFP_TEXMATRIX   0x00020000
 #define WINED3D_SHADER_CONST_FFP_MATERIAL    0x00040000
 #define WINED3D_SHADER_CONST_FFP_LIGHTS      0x00080000
 #define WINED3D_SHADER_CONST_FFP_PS          0x00100000
 #define WINED3D_SHADER_CONST_FFP_COLOR_KEY   0x00200000
 #define WINED3D_SHADER_CONST_FFP_PROJ        0x00010000
 #define WINED3D_SHADER_CONST_FFP_TEXMATRIX   0x00020000
 #define WINED3D_SHADER_CONST_FFP_MATERIAL    0x00040000
 #define WINED3D_SHADER_CONST_FFP_LIGHTS      0x00080000
 #define WINED3D_SHADER_CONST_FFP_PS          0x00100000
 #define WINED3D_SHADER_CONST_FFP_COLOR_KEY   0x00200000
+#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0xff000000
+#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i) (0x01000000 << ((i) - 1))
 
 enum wined3d_shader_register_type
 {
 
 enum wined3d_shader_register_type
 {
@@ -1362,7 +1358,8 @@ struct ps_compile_args
     DWORD flatshading : 1;
     DWORD alpha_test_func : 3;
     DWORD render_offscreen : 1;
     DWORD flatshading : 1;
     DWORD alpha_test_func : 3;
     DWORD render_offscreen : 1;
-    DWORD padding : 26;
+    DWORD dual_source_blend : 1;
+    DWORD padding : 25;
 };
 
 enum fog_src_type
 };
 
 enum fog_src_type
@@ -1653,7 +1650,10 @@ enum wined3d_pipeline
 #define STATE_STREAM_OUTPUT (STATE_COLOR_KEY + 1)
 #define STATE_IS_STREAM_OUTPUT(a) ((a) == STATE_STREAM_OUTPUT)
 
 #define STATE_STREAM_OUTPUT (STATE_COLOR_KEY + 1)
 #define STATE_IS_STREAM_OUTPUT(a) ((a) == STATE_STREAM_OUTPUT)
 
-#define STATE_COMPUTE_OFFSET (STATE_STREAM_OUTPUT + 1)
+#define STATE_BLEND (STATE_STREAM_OUTPUT + 1)
+#define STATE_IS_BLEND(a) ((a) == STATE_BLEND)
+
+#define STATE_COMPUTE_OFFSET (STATE_BLEND + 1)
 
 #define STATE_COMPUTE_SHADER (STATE_COMPUTE_OFFSET)
 #define STATE_IS_COMPUTE_SHADER(a) ((a) == STATE_COMPUTE_SHADER)
 
 #define STATE_COMPUTE_SHADER (STATE_COMPUTE_OFFSET)
 #define STATE_IS_COMPUTE_SHADER(a) ((a) == STATE_COMPUTE_SHADER)
@@ -1916,7 +1916,8 @@ struct wined3d_context
     DWORD transform_feedback_paused : 1;
     DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */
     DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */
     DWORD transform_feedback_paused : 1;
     DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */
     DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */
-    DWORD padding : 9;
+    DWORD last_was_dual_blend : 1;
+    DWORD padding : 8;
     DWORD constant_update_mask;
     DWORD                   numbered_array_mask;
     GLenum                  tracking_parm;     /* Which source is tracking current colour         */
     DWORD constant_update_mask;
     DWORD                   numbered_array_mask;
     GLenum                  tracking_parm;     /* Which source is tracking current colour         */
@@ -1950,9 +1951,7 @@ struct wined3d_context
     struct fbo_entry        *current_fbo;
     GLuint                  fbo_read_binding;
     GLuint                  fbo_draw_binding;
     struct fbo_entry        *current_fbo;
     GLuint                  fbo_read_binding;
     GLuint                  fbo_draw_binding;
-    struct wined3d_rendertarget_info *blit_targets;
-    struct wined3d_fbo_entry_key *fbo_key;
-    GLenum *draw_buffers;
+    struct wined3d_rendertarget_info blit_targets[MAX_RENDER_TARGET_VIEWS];
     DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */
 
     /* Queries */
     DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */
 
     /* Queries */
@@ -1999,7 +1998,7 @@ struct wined3d_context
 
 struct wined3d_fb_state
 {
 
 struct wined3d_fb_state
 {
-    struct wined3d_rendertarget_view **render_targets;
+    struct wined3d_rendertarget_view *render_targets[MAX_RENDER_TARGET_VIEWS];
     struct wined3d_rendertarget_view *depth_stencil;
 };
 
     struct wined3d_rendertarget_view *depth_stencil;
 };
 
@@ -2141,10 +2140,6 @@ void context_alloc_occlusion_query(struct wined3d_context *context,
 void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN;
 BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
         UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN;
 void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN;
 BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
         UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN;
-void context_apply_compute_state(struct wined3d_context *context,
-        const struct wined3d_device *device, const struct wined3d_state *state) DECLSPEC_HIDDEN;
-BOOL context_apply_draw_state(struct wined3d_context *context,
-        const struct wined3d_device *device, const struct wined3d_state *state) DECLSPEC_HIDDEN;
 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
         struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN;
 void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info,
 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
         struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN;
 void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info,
@@ -2352,6 +2347,7 @@ enum wined3d_pci_device
     CARD_NVIDIA_GEFORCE_GTX550      = 0x1244,
     CARD_NVIDIA_GEFORCE_GT555M      = 0x04b8,
     CARD_NVIDIA_GEFORCE_GTX560TI    = 0x1200,
     CARD_NVIDIA_GEFORCE_GTX550      = 0x1244,
     CARD_NVIDIA_GEFORCE_GT555M      = 0x04b8,
     CARD_NVIDIA_GEFORCE_GTX560TI    = 0x1200,
+    CARD_NVIDIA_GEFORCE_GTX560M     = 0x1251,
     CARD_NVIDIA_GEFORCE_GTX560      = 0x1201,
     CARD_NVIDIA_GEFORCE_GTX570      = 0x1081,
     CARD_NVIDIA_GEFORCE_GTX580      = 0x1080,
     CARD_NVIDIA_GEFORCE_GTX560      = 0x1201,
     CARD_NVIDIA_GEFORCE_GTX570      = 0x1081,
     CARD_NVIDIA_GEFORCE_GTX580      = 0x1080,
@@ -2523,6 +2519,7 @@ struct wined3d_fbo_ops
 struct wined3d_gl_limits
 {
     UINT buffers;
 struct wined3d_gl_limits
 {
     UINT buffers;
+    UINT dual_buffers;
     UINT lights;
     UINT textures;
     UINT texture_coords;
     UINT lights;
     UINT textures;
     UINT texture_coords;
@@ -2544,6 +2541,9 @@ struct wined3d_gl_limits
 
     unsigned int texture_buffer_offset_alignment;
 
 
     unsigned int texture_buffer_offset_alignment;
 
+    unsigned int framebuffer_width;
+    unsigned int framebuffer_height;
+
     UINT glsl_varyings;
     UINT glsl_vs_float_constants;
     UINT glsl_ps_float_constants;
     UINT glsl_varyings;
     UINT glsl_vs_float_constants;
     UINT glsl_ps_float_constants;
@@ -2703,7 +2703,6 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
         const struct ffp_frag_settings *settings) DECLSPEC_HIDDEN;
 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) DECLSPEC_HIDDEN;
 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
         const struct ffp_frag_settings *settings) DECLSPEC_HIDDEN;
 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) DECLSPEC_HIDDEN;
-void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) DECLSPEC_HIDDEN;
 void wined3d_ftoa(float value, char *s) DECLSPEC_HIDDEN;
 
 extern const float wined3d_srgb_const0[] DECLSPEC_HIDDEN;
 void wined3d_ftoa(float value, char *s) DECLSPEC_HIDDEN;
 
 extern const float wined3d_srgb_const0[] DECLSPEC_HIDDEN;
@@ -2748,7 +2747,8 @@ struct wined3d_ffp_vs_settings
     DWORD ortho_fog       : 1;
     DWORD flatshading     : 1;
     DWORD swizzle_map     : 16; /* MAX_ATTRIBS, 16 */
     DWORD ortho_fog       : 1;
     DWORD flatshading     : 1;
     DWORD swizzle_map     : 16; /* MAX_ATTRIBS, 16 */
-    DWORD padding         : 2;
+    DWORD vb_indices      : 1;
+    DWORD sw_blending     : 1;
 
     DWORD texgen[MAX_TEXTURES];
 };
 
     DWORD texgen[MAX_TEXTURES];
 };
@@ -2774,6 +2774,17 @@ HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN;
 BOOL wined3d_register_window(HWND window, struct wined3d_device *device) DECLSPEC_HIDDEN;
 void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
 
 BOOL wined3d_register_window(HWND window, struct wined3d_device *device) DECLSPEC_HIDDEN;
 void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
 
+struct wined3d_blend_state
+{
+    LONG refcount;
+    struct wined3d_blend_state_desc desc;
+
+    void *parent;
+    const struct wined3d_parent_ops *parent_ops;
+
+    struct wined3d_device *device;
+};
+
 struct wined3d_rasterizer_state
 {
     LONG refcount;
 struct wined3d_rasterizer_state
 {
     LONG refcount;
@@ -2852,9 +2863,51 @@ struct wined3d_state
     const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS];
 
     DWORD render_states[WINEHIGHEST_RENDER_STATE + 1];
     const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS];
 
     DWORD render_states[WINEHIGHEST_RENDER_STATE + 1];
+    struct wined3d_blend_state *blend_state;
     struct wined3d_rasterizer_state *rasterizer_state;
 };
 
     struct wined3d_rasterizer_state *rasterizer_state;
 };
 
+static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state, const struct wined3d_gl_info *gl_info)
+{
+    if (!state->fb->render_targets[0]) return FALSE;
+    if (!state->render_states[WINED3D_RS_ALPHABLENDENABLE]) return FALSE;
+    if (!gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) return FALSE;
+
+#define IS_DUAL_SOURCE_BLEND(x) ((x) >= WINED3D_BLEND_SRC1COLOR && (x) <= WINED3D_BLEND_INVSRC1ALPHA)
+    if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_SRCBLEND]))  return TRUE;
+    if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_DESTBLEND])) return TRUE;
+    if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_SRCBLENDALPHA]))  return TRUE;
+    if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_DESTBLENDALPHA])) return TRUE;
+#undef IS_DUAL_SOURCE_BLEND
+
+    return FALSE;
+}
+
+struct wined3d_dummy_textures
+{
+    GLuint tex_2d;
+    GLuint tex_1d;
+    GLuint tex_rect;
+    GLuint tex_3d;
+    GLuint tex_cube;
+    GLuint tex_cube_array;
+    GLuint tex_2d_array;
+    GLuint tex_1d_array;
+    GLuint tex_buffer;
+    GLuint tex_2d_ms;
+    GLuint tex_2d_ms_array;
+};
+
+#if defined(STAGING_CSMT)
+struct wined3d_gl_bo
+{
+    GLuint name;
+    GLenum usage;
+    GLenum type_hint;
+    UINT size;
+};
+
+#endif /* STAGING_CSMT */
 #define WINED3D_UNMAPPED_STAGE ~0u
 
 /* Multithreaded flag. Removed from the public header to signal that
 #define WINED3D_UNMAPPED_STAGE ~0u
 
 /* Multithreaded flag. Removed from the public header to signal that
@@ -2928,16 +2981,7 @@ struct wined3d_device
     struct wined3d_texture *logo_texture;
 
     /* Textures for when no other textures are mapped */
     struct wined3d_texture *logo_texture;
 
     /* Textures for when no other textures are mapped */
-    struct
-    {
-        GLuint tex_2d;
-        GLuint tex_rect;
-        GLuint tex_3d;
-        GLuint tex_cube;
-        GLuint tex_cube_array;
-        GLuint tex_2d_array;
-        GLuint tex_buffer;
-    } dummy_textures;
+    struct wined3d_dummy_textures dummy_textures;
 
     /* Default sampler used to emulate the direct resource access without using wined3d_sampler */
     struct wined3d_sampler *default_sampler;
 
     /* Default sampler used to emulate the direct resource access without using wined3d_sampler */
     struct wined3d_sampler *default_sampler;
@@ -2964,6 +3008,12 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
 void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN;
 void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN;
+#if defined(STAGING_CSMT)
+struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage,
+        GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN;
+void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo,
+        const struct wined3d_context *context) DECLSPEC_HIDDEN;
+#endif /* STAGING_CSMT */
 
 static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state)
 {
 
 static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state)
 {
@@ -2972,8 +3022,12 @@ static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD sta
     return context->isStateDirty[idx] & (1u << shift);
 }
 
     return context->isStateDirty[idx] & (1u << shift);
 }
 
-#define WINED3D_RESOURCE_ACCESS_GPU     0x1
-#define WINED3D_RESOURCE_ACCESS_CPU     0x2
+const char *wined3d_debug_resource_access(DWORD access) DECLSPEC_HIDDEN;
+
+static inline BOOL wined3d_resource_access_is_managed(unsigned int access)
+{
+    return !(~access & (WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU));
+}
 
 struct wined3d_resource_ops
 {
 
 struct wined3d_resource_ops
 {
@@ -2983,6 +3037,8 @@ struct wined3d_resource_ops
     void (*resource_unload)(struct wined3d_resource *resource);
     HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx,
             struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
     void (*resource_unload)(struct wined3d_resource *resource);
     HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx,
             struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
+    HRESULT (*resource_map_info)(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+            struct wined3d_map_info *info, DWORD flags);
     HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx);
 };
 
     HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx);
 };
 
@@ -3000,8 +3056,7 @@ struct wined3d_resource
     enum wined3d_multisample_type multisample_type;
     UINT multisample_quality;
     DWORD usage;
     enum wined3d_multisample_type multisample_type;
     UINT multisample_quality;
     DWORD usage;
-    enum wined3d_pool pool;
-    DWORD access_flags;
+    unsigned int access;
     WORD draw_binding;
     WORD map_binding;
     UINT width;
     WORD draw_binding;
     WORD map_binding;
     UINT width;
@@ -3041,9 +3096,9 @@ static inline void wined3d_resource_release(struct wined3d_resource *resource)
 void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
         enum wined3d_resource_type type, const struct wined3d_format *format,
 void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
         enum wined3d_resource_type type, const struct wined3d_format *format,
-        enum wined3d_multisample_type multisample_type, UINT multisample_quality,
-        DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
-        void *parent, const struct wined3d_parent_ops *parent_ops,
+        enum wined3d_multisample_type multisample_type, unsigned int multisample_quality,
+        unsigned int usage, unsigned int access, unsigned int width, unsigned int height, unsigned int depth,
+        unsigned int size, void *parent, const struct wined3d_parent_ops *parent_ops,
         const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
 void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
         const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
 void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
@@ -3109,7 +3164,6 @@ struct wined3d_texture
     unsigned int sysmem_count;
     float pow2_matrix[16];
     UINT lod;
     unsigned int sysmem_count;
     float pow2_matrix[16];
     UINT lod;
-    enum wined3d_texture_filter_type filter_type;
     DWORD sampler;
     DWORD flags;
     GLenum target;
     DWORD sampler;
     DWORD flags;
     GLenum target;
@@ -3136,6 +3190,15 @@ struct wined3d_texture
         DWORD color_key_flags;
     } async;
 
         DWORD color_key_flags;
     } async;
 
+    struct wined3d_overlay_info
+    {
+        struct list entry;
+        struct list overlays;
+        struct wined3d_surface *dst;
+        RECT src_rect;
+        RECT dst_rect;
+    } *overlay_info;
+
     struct wined3d_texture_sub_resource
     {
         void *parent;
     struct wined3d_texture_sub_resource
     {
         void *parent;
@@ -3150,7 +3213,11 @@ struct wined3d_texture
 
         unsigned int map_count;
         DWORD locations;
 
         unsigned int map_count;
         DWORD locations;
+#if !defined(STAGING_CSMT)
         GLuint buffer_object;
         GLuint buffer_object;
+#else  /* STAGING_CSMT */
+        struct wined3d_gl_bo *buffer;
+#endif /* STAGING_CSMT */
     } sub_resources[1];
 };
 
     } sub_resources[1];
 };
 
@@ -3159,6 +3226,23 @@ static inline struct wined3d_texture *texture_from_resource(struct wined3d_resou
     return CONTAINING_RECORD(resource, struct wined3d_texture, resource);
 }
 
     return CONTAINING_RECORD(resource, struct wined3d_texture, resource);
 }
 
+static inline GLenum wined3d_texture_get_sub_resource_target(const struct wined3d_texture *texture,
+        unsigned int sub_resource_idx)
+{
+    static const GLenum cube_targets[] =
+    {
+        GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
+        GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
+        GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
+        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
+        GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
+        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
+    };
+
+    return texture->resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP
+            ? cube_targets[sub_resource_idx / texture->level_count] : texture->target;
+}
+
 static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_texture *texture,
         BOOL srgb)
 {
 static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_texture *texture,
         BOOL srgb)
 {
@@ -3265,7 +3349,7 @@ struct fbo_entry
     struct wined3d_fbo_entry_key
     {
         DWORD rb_namespace;
     struct wined3d_fbo_entry_key
     {
         DWORD rb_namespace;
-        struct wined3d_fbo_resource objects[1];
+        struct wined3d_fbo_resource objects[MAX_RENDER_TARGET_VIEWS + 1];
     } key;
 };
 
     } key;
 };
 
@@ -3273,7 +3357,6 @@ struct wined3d_surface
 {
     struct wined3d_texture *container;
 
 {
     struct wined3d_texture *container;
 
-    GLenum texture_target;
     unsigned int texture_level;
     unsigned int texture_layer;
 
     unsigned int texture_level;
     unsigned int texture_layer;
 
@@ -3283,13 +3366,6 @@ struct wined3d_surface
 
     struct list               renderbuffers;
     const struct wined3d_renderbuffer_entry *current_renderbuffer;
 
     struct list               renderbuffers;
     const struct wined3d_renderbuffer_entry *current_renderbuffer;
-
-    /* DirectDraw Overlay handling */
-    RECT                      overlay_srcrect;
-    RECT                      overlay_destrect;
-    struct wined3d_surface *overlay_dest;
-    struct list               overlays;
-    struct list               overlay_entry;
 };
 
 static inline unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface)
 };
 
 static inline unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface)
@@ -3316,8 +3392,9 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
         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;
 
         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 draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect,
+        enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
 
 struct wined3d_sampler
 {
 
 struct wined3d_sampler
 {
@@ -3465,6 +3542,9 @@ struct wined3d_cs_queue
 
 struct wined3d_cs_ops
 {
 
 struct wined3d_cs_ops
 {
+#if defined(STAGING_CSMT)
+    BOOL (*check_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id);
+#endif /* STAGING_CSMT */
     void *(*require_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id);
     void (*submit)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id);
     void (*finish)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id);
     void *(*require_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id);
     void (*submit)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id);
     void (*finish)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id);
@@ -3523,10 +3603,11 @@ void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, GLenum primitive_type,
 void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
-void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
-        const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect,
+        const RECT *dst_rect, HWND dst_window_override, DWORD swap_interval, DWORD flags) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx,
         const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx,
         const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
@@ -3816,7 +3897,6 @@ const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_t
 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state) DECLSPEC_HIDDEN;
 const char *debug_d3dtop(enum wined3d_texture_op d3dtop) DECLSPEC_HIDDEN;
 const char *debug_d3dtstype(enum wined3d_transform_state tstype) DECLSPEC_HIDDEN;
 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state) DECLSPEC_HIDDEN;
 const char *debug_d3dtop(enum wined3d_texture_op d3dtop) DECLSPEC_HIDDEN;
 const char *debug_d3dtstype(enum wined3d_transform_state tstype) DECLSPEC_HIDDEN;
-const char *debug_d3dpool(enum wined3d_pool pool) DECLSPEC_HIDDEN;
 const char *debug_fboattachment(GLenum attachment) DECLSPEC_HIDDEN;
 const char *debug_fbostatus(GLenum status) DECLSPEC_HIDDEN;
 const char *debug_glerror(GLenum error) DECLSPEC_HIDDEN;
 const char *debug_fboattachment(GLenum attachment) DECLSPEC_HIDDEN;
 const char *debug_fbostatus(GLenum status) DECLSPEC_HIDDEN;
 const char *debug_glerror(GLenum error) DECLSPEC_HIDDEN;
@@ -3870,6 +3950,9 @@ 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;
 /* Math utils */
 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
         const struct wined3d_matrix *src2) DECLSPEC_HIDDEN;
+BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in) DECLSPEC_HIDDEN;
+BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) DECLSPEC_HIDDEN;
+void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) DECLSPEC_HIDDEN;
 
 void wined3d_release_dc(HWND window, HDC dc) DECLSPEC_HIDDEN;
 
 
 void wined3d_release_dc(HWND window, HDC dc) DECLSPEC_HIDDEN;
 
@@ -4198,6 +4281,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN
 #define WINED3DFMT_FLAG_TEXTURE                     0x00080000
 #define WINED3DFMT_FLAG_BLOCKS_NO_VERIFY            0x00100000
 #define WINED3DFMT_FLAG_INTEGER                     0x00200000
 #define WINED3DFMT_FLAG_TEXTURE                     0x00080000
 #define WINED3DFMT_FLAG_BLOCKS_NO_VERIFY            0x00100000
 #define WINED3DFMT_FLAG_INTEGER                     0x00200000
+#define WINED3DFMT_FLAG_GEN_MIPMAP                  0x00400000
 
 struct wined3d_rational
 {
 
 struct wined3d_rational
 {
@@ -4286,11 +4370,32 @@ static inline BOOL wined3d_format_is_typeless(const struct wined3d_format *forma
     return format->id == format->typeless_id && format->id != WINED3DFMT_UNKNOWN;
 }
 
     return format->id == format->typeless_id && format->id != WINED3DFMT_UNKNOWN;
 }
 
-static inline void *wined3d_calloc(SIZE_T count, SIZE_T size)
+static inline BOOL use_indexed_vertex_blending(const struct wined3d_state *state, const struct wined3d_stream_info *si)
 {
 {
-    if (count > ~(SIZE_T)0 / size)
-        return NULL;
-    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * size);
+    if (!state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE])
+        return FALSE;
+
+    if (state->render_states[WINED3D_RS_VERTEXBLEND] == WINED3D_VBF_DISABLE)
+        return FALSE;
+
+    if (!(si->use_map & (1 << WINED3D_FFP_BLENDINDICES)) || !(si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT)))
+        return FALSE;
+
+    return TRUE;
+}
+
+static inline BOOL use_software_vertex_processing(const struct wined3d_device *device)
+{
+    if (device->shader_backend != &glsl_shader_backend)
+        return FALSE;
+
+    if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING)
+        return TRUE;
+
+    if (!(device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING))
+        return FALSE;
+
+    return device->softwareVertexProcessing;
 }
 
 static inline BOOL use_vs(const struct wined3d_state *state)
 }
 
 static inline BOOL use_vs(const struct wined3d_state *state)
@@ -4361,6 +4466,13 @@ static inline BOOL is_rasterization_disabled(const struct wined3d_shader *geomet
             && geometry_shader->u.gs.so_desc.rasterizer_stream_idx == WINED3D_NO_RASTERIZER_STREAM;
 }
 
             && geometry_shader->u.gs.so_desc.rasterizer_stream_idx == WINED3D_NO_RASTERIZER_STREAM;
 }
 
+static inline int wined3d_bit_scan(unsigned int *x)
+{
+    int bit_offset = ffs(*x) - 1;
+    *x ^= 1u << bit_offset;
+    return bit_offset;
+}
+
 static inline DWORD wined3d_extract_bits(const DWORD *bitstream,
         unsigned int offset, unsigned int count)
 {
 static inline DWORD wined3d_extract_bits(const DWORD *bitstream,
         unsigned int offset, unsigned int count)
 {
@@ -4419,6 +4531,9 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs)
     assert(cs->thread_id != GetCurrentThreadId());
 }
 
     assert(cs->thread_id != GetCurrentThreadId());
 }
 
+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"
 
 /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
 #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
 
index 6b33d67..083be5f 100644 (file)
@@ -22,13 +22,13 @@ reactos/sdk/tools/wpp                   # Synced to WineStaging-2.9
 The following libraries are shared with Wine.
 
 reactos/dll/directx/wine/amstream       # Synced to WineStaging-3.3
 The following libraries are shared with Wine.
 
 reactos/dll/directx/wine/amstream       # Synced to WineStaging-3.3
-reactos/dll/directx/wine/d3d8           # Synced to Wine-3.0
-reactos/dll/directx/wine/d3d9           # Synced to Wine-3.0
+reactos/dll/directx/wine/d3d8           # Synced to WineStaging-3.3
+reactos/dll/directx/wine/d3d9           # Synced to WineStaging-3.3
 reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-3.3
 reactos/dll/directx/wine/d3drm          # Synced to WineStaging-2.16
 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-3.0
 reactos/dll/directx/wine/d3dxof         # Synced to WineStaging-2.9
 reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-3.3
 reactos/dll/directx/wine/d3drm          # Synced to WineStaging-2.16
 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-3.0
 reactos/dll/directx/wine/d3dxof         # Synced to WineStaging-2.9
-reactos/dll/directx/wine/ddraw          # Synced to Wine-3.0
+reactos/dll/directx/wine/ddraw          # Synced to WineStaging-3.3
 reactos/dll/directx/wine/devenum        # Synced to Wine-3.0
 reactos/dll/directx/wine/dinput         # Synced to Wine-3.0
 reactos/dll/directx/wine/dinput8        # Synced to WineStaging-2.9
 reactos/dll/directx/wine/devenum        # Synced to Wine-3.0
 reactos/dll/directx/wine/dinput         # Synced to Wine-3.0
 reactos/dll/directx/wine/dinput8        # Synced to WineStaging-2.9
@@ -40,7 +40,7 @@ reactos/dll/directx/wine/dxdiagn        # Synced to Wine-3.0
 reactos/dll/directx/wine/msdmo          # Synced to WineStaging-2.9
 reactos/dll/directx/wine/qedit          # Synced to Wine-3.0
 reactos/dll/directx/wine/quartz         # Synced to Wine-3.0
 reactos/dll/directx/wine/msdmo          # Synced to WineStaging-2.9
 reactos/dll/directx/wine/qedit          # Synced to Wine-3.0
 reactos/dll/directx/wine/quartz         # Synced to Wine-3.0
-reactos/dll/directx/wine/wined3d        # Synced to Wine-3.0
+reactos/dll/directx/wine/wined3d        # Synced to WineStaging-3.3
 
 reactos/dll/win32/activeds            # Synced to WineStaging-2.9
 reactos/dll/win32/actxprxy            # Synced to WineStaging-2.9
 
 reactos/dll/win32/activeds            # Synced to WineStaging-2.9
 reactos/dll/win32/actxprxy            # Synced to WineStaging-2.9
index 4b50c51..1f8171d 100644 (file)
 # error You must include config.h to use this header
 #endif
 
 # error You must include config.h to use this header
 #endif
 
-#include <wine/list.h>
+#include "wine/list.h"
+
+DEFINE_GUID(IID_IWineD3DDevice, 0xd56e2a4c, 0x5127, 0x8437, 0x65, 0x8a, 0x98, 0xc5, 0xbb, 0x78, 0x94, 0x98);
 
 #define WINED3D_OK                                              S_OK
 
 #define _FACWINED3D                                             0x876
 #define MAKE_WINED3DSTATUS(code)                                MAKE_HRESULT(0, _FACWINED3D, code)
 
 #define WINED3D_OK                                              S_OK
 
 #define _FACWINED3D                                             0x876
 #define MAKE_WINED3DSTATUS(code)                                MAKE_HRESULT(0, _FACWINED3D, code)
-#define WINED3DOK_NOAUTOGEN                                     MAKE_WINED3DSTATUS(2159)
+#define WINED3DOK_NOMIPGEN                                      MAKE_WINED3DSTATUS(2159)
 
 #define MAKE_WINED3DHRESULT(code)                               MAKE_HRESULT(1, _FACWINED3D, code)
 #define WINED3DERR_CONFLICTINGRENDERSTATE                       MAKE_WINED3DHRESULT(2081)
 
 #define MAKE_WINED3DHRESULT(code)                               MAKE_HRESULT(1, _FACWINED3D, code)
 #define WINED3DERR_CONFLICTINGRENDERSTATE                       MAKE_WINED3DHRESULT(2081)
 #define WINEDDERR_INVALIDRECT                                   MAKE_WINED3DHRESULT(150)
 #define WINEDDERR_OVERLAYNOTVISIBLE                             MAKE_WINED3DHRESULT(577)
 
 #define WINEDDERR_INVALIDRECT                                   MAKE_WINED3DHRESULT(150)
 #define WINEDDERR_OVERLAYNOTVISIBLE                             MAKE_WINED3DHRESULT(577)
 
+#define WINED3D_RESOURCE_ACCESS_GPU                             0x1u
+#define WINED3D_RESOURCE_ACCESS_CPU                             0x2u
+#define WINED3D_RESOURCE_ACCESS_MAP_R                           0x4u
+#define WINED3D_RESOURCE_ACCESS_MAP_W                           0x8u
+
 enum wined3d_light_type
 {
     WINED3D_LIGHT_POINT                     = 1,
 enum wined3d_light_type
 {
     WINED3D_LIGHT_POINT                     = 1,
@@ -381,8 +388,22 @@ enum wined3d_render_state
     WINED3D_RS_SRCBLENDALPHA                = 207,
     WINED3D_RS_DESTBLENDALPHA               = 208,
     WINED3D_RS_BLENDOPALPHA                 = 209,
     WINED3D_RS_SRCBLENDALPHA                = 207,
     WINED3D_RS_DESTBLENDALPHA               = 208,
     WINED3D_RS_BLENDOPALPHA                 = 209,
+    WINED3D_RS_DEPTHCLIP                    = 210,
+    WINED3D_RS_DEPTHBIASCLAMP               = 211,
+    WINED3D_RS_COLORWRITEENABLE4            = 212,
+    WINED3D_RS_COLORWRITEENABLE5            = 213,
+    WINED3D_RS_COLORWRITEENABLE6            = 214,
+    WINED3D_RS_COLORWRITEENABLE7            = 215,
 };
 };
-#define WINEHIGHEST_RENDER_STATE                                WINED3D_RS_BLENDOPALPHA
+#define WINEHIGHEST_RENDER_STATE                                WINED3D_RS_COLORWRITEENABLE7
+
+static inline enum wined3d_render_state WINED3D_RS_COLORWRITE(int index)
+{
+    if (index == 0) return WINED3D_RS_COLORWRITEENABLE;
+    if (index <= 3) return WINED3D_RS_COLORWRITEENABLE1 + index - 1;
+    if (index <= 7) return WINED3D_RS_COLORWRITEENABLE4 + index - 4;
+    return WINED3D_RS_COLORWRITEENABLE;
+}
 
 enum wined3d_blend
 {
 
 enum wined3d_blend
 {
@@ -501,10 +522,13 @@ enum wined3d_patch_edge_style
 
 enum wined3d_swap_effect
 {
 
 enum wined3d_swap_effect
 {
-    WINED3D_SWAP_EFFECT_DISCARD             = 1,
-    WINED3D_SWAP_EFFECT_FLIP                = 2,
-    WINED3D_SWAP_EFFECT_COPY                = 3,
-    WINED3D_SWAP_EFFECT_COPY_VSYNC          = 4,
+    WINED3D_SWAP_EFFECT_DISCARD,
+    WINED3D_SWAP_EFFECT_SEQUENTIAL,
+    WINED3D_SWAP_EFFECT_FLIP_DISCARD,
+    WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL,
+    WINED3D_SWAP_EFFECT_COPY,
+    WINED3D_SWAP_EFFECT_COPY_VSYNC,
+    WINED3D_SWAP_EFFECT_OVERLAY,
 };
 
 enum wined3d_sampler_state
 };
 
 enum wined3d_sampler_state
@@ -672,16 +696,9 @@ enum wined3d_resource_type
 {
     WINED3D_RTYPE_NONE                      = 0,
     WINED3D_RTYPE_BUFFER                    = 1,
 {
     WINED3D_RTYPE_NONE                      = 0,
     WINED3D_RTYPE_BUFFER                    = 1,
-    WINED3D_RTYPE_TEXTURE_2D                = 2,
-    WINED3D_RTYPE_TEXTURE_3D                = 3,
-};
-
-enum wined3d_pool
-{
-    WINED3D_POOL_DEFAULT                    = 0,
-    WINED3D_POOL_MANAGED                    = 1,
-    WINED3D_POOL_SYSTEM_MEM                 = 2,
-    WINED3D_POOL_SCRATCH                    = 3,
+    WINED3D_RTYPE_TEXTURE_1D                = 2,
+    WINED3D_RTYPE_TEXTURE_2D                = 3,
+    WINED3D_RTYPE_TEXTURE_3D                = 4,
 };
 
 enum wined3d_query_type
 };
 
 enum wined3d_query_type
@@ -888,14 +905,14 @@ enum wined3d_shader_byte_code_format
 #define WINED3DUSAGE_RTPATCHES                                  0x00000080
 #define WINED3DUSAGE_NPATCHES                                   0x00000100
 #define WINED3DUSAGE_DYNAMIC                                    0x00000200
 #define WINED3DUSAGE_RTPATCHES                                  0x00000080
 #define WINED3DUSAGE_NPATCHES                                   0x00000100
 #define WINED3DUSAGE_DYNAMIC                                    0x00000200
-#define WINED3DUSAGE_AUTOGENMIPMAP                              0x00000400
 #define WINED3DUSAGE_RESTRICTED_CONTENT                         0x00000800
 #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER            0x00001000
 #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE                   0x00002000
 #define WINED3DUSAGE_DMAP                                       0x00004000
 #define WINED3DUSAGE_TEXTAPI                                    0x10000000
 #define WINED3DUSAGE_RESTRICTED_CONTENT                         0x00000800
 #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER            0x00001000
 #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE                   0x00002000
 #define WINED3DUSAGE_DMAP                                       0x00004000
 #define WINED3DUSAGE_TEXTAPI                                    0x10000000
-#define WINED3DUSAGE_MASK                                       0x10007fff
+#define WINED3DUSAGE_MASK                                       0x10007bff
 
 
+#define WINED3DUSAGE_SCRATCH                                    0x00200000
 #define WINED3DUSAGE_PRIVATE                                    0x00400000
 #define WINED3DUSAGE_LEGACY_CUBEMAP                             0x00800000
 #define WINED3DUSAGE_TEXTURE                                    0x01000000
 #define WINED3DUSAGE_PRIVATE                                    0x00400000
 #define WINED3DUSAGE_LEGACY_CUBEMAP                             0x00800000
 #define WINED3DUSAGE_TEXTURE                                    0x01000000
@@ -903,6 +920,7 @@ enum wined3d_shader_byte_code_format
 #define WINED3DUSAGE_STATICDECL                                 0x04000000
 #define WINED3DUSAGE_OVERLAY                                    0x08000000
 
 #define WINED3DUSAGE_STATICDECL                                 0x04000000
 #define WINED3DUSAGE_OVERLAY                                    0x08000000
 
+#define WINED3DUSAGE_QUERY_GENMIPMAP                            0x00000400
 #define WINED3DUSAGE_QUERY_LEGACYBUMPMAP                        0x00008000
 #define WINED3DUSAGE_QUERY_FILTER                               0x00020000
 #define WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING             0x00080000
 #define WINED3DUSAGE_QUERY_LEGACYBUMPMAP                        0x00008000
 #define WINED3DUSAGE_QUERY_FILTER                               0x00020000
 #define WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING             0x00080000
@@ -910,14 +928,15 @@ enum wined3d_shader_byte_code_format
 #define WINED3DUSAGE_QUERY_SRGBWRITE                            0x00040000
 #define WINED3DUSAGE_QUERY_VERTEXTEXTURE                        0x00100000
 #define WINED3DUSAGE_QUERY_WRAPANDMIP                           0x00200000
 #define WINED3DUSAGE_QUERY_SRGBWRITE                            0x00040000
 #define WINED3DUSAGE_QUERY_VERTEXTEXTURE                        0x00100000
 #define WINED3DUSAGE_QUERY_WRAPANDMIP                           0x00200000
-#define WINED3DUSAGE_QUERY_MASK                                 0x003f8000
+#define WINED3DUSAGE_QUERY_MASK                                 0x003f8400
 
 
-#define WINED3D_MAP_READONLY                                    0x0010
-#define WINED3D_MAP_NOSYSLOCK                                   0x0800
-#define WINED3D_MAP_NOOVERWRITE                                 0x1000
-#define WINED3D_MAP_DISCARD                                     0x2000
-#define WINED3D_MAP_DONOTWAIT                                   0x4000
-#define WINED3D_MAP_NO_DIRTY_UPDATE                             0x8000
+#define WINED3D_MAP_NOSYSLOCK                                   0x00000800
+#define WINED3D_MAP_NOOVERWRITE                                 0x00001000
+#define WINED3D_MAP_DISCARD                                     0x00002000
+#define WINED3D_MAP_DONOTWAIT                                   0x00004000
+#define WINED3D_MAP_NO_DIRTY_UPDATE                             0x00008000
+#define WINED3D_MAP_WRITE                                       0x40000000
+#define WINED3D_MAP_READ                                        0x80000000
 
 #define WINED3DPRESENT_RATE_DEFAULT                             0x00000000
 
 
 #define WINED3DPRESENT_RATE_DEFAULT                             0x00000000
 
@@ -1166,7 +1185,7 @@ enum wined3d_shader_byte_code_format
 #define WINED3DCAPS2_RESERVED                                   0x02000000
 #define WINED3DCAPS2_CANMANAGERESOURCE                          0x10000000
 #define WINED3DCAPS2_DYNAMICTEXTURES                            0x20000000
 #define WINED3DCAPS2_RESERVED                                   0x02000000
 #define WINED3DCAPS2_CANMANAGERESOURCE                          0x10000000
 #define WINED3DCAPS2_DYNAMICTEXTURES                            0x20000000
-#define WINED3DCAPS2_CANAUTOGENMIPMAP                           0x40000000
+#define WINED3DCAPS2_CANGENMIPMAP                               0x40000000
 
 #define WINED3DPRASTERCAPS_DITHER                               0x00000001
 #define WINED3DPRASTERCAPS_ROP2                                 0x00000002
 
 #define WINED3DPRASTERCAPS_DITHER                               0x00000001
 #define WINED3DPRASTERCAPS_ROP2                                 0x00000002
@@ -1307,6 +1326,8 @@ enum wined3d_shader_byte_code_format
 #define WINED3D_NO_PRIMITIVE_RESTART                            0x00000800
 #define WINED3D_LEGACY_CUBEMAP_FILTERING                        0x00001000
 #define WINED3D_NORMALIZED_DEPTH_BIAS                           0x00002000
 #define WINED3D_NO_PRIMITIVE_RESTART                            0x00000800
 #define WINED3D_LEGACY_CUBEMAP_FILTERING                        0x00001000
 #define WINED3D_NORMALIZED_DEPTH_BIAS                           0x00002000
+#define WINED3D_REQUEST_D3D10                                   0x00004000
+#define WINED3D_LIMIT_VIEWPORT                                  0x00008000
 
 #define WINED3D_RESZ_CODE                                       0x7fa05000
 
 
 #define WINED3D_RESZ_CODE                                       0x7fa05000
 
@@ -1712,6 +1733,7 @@ struct wined3d_swapchain_desc
     UINT backbuffer_height;
     enum wined3d_format_id backbuffer_format;
     UINT backbuffer_count;
     UINT backbuffer_height;
     enum wined3d_format_id backbuffer_format;
     UINT backbuffer_count;
+    DWORD backbuffer_usage;
     enum wined3d_multisample_type multisample_type;
     DWORD multisample_quality;
     enum wined3d_swap_effect swap_effect;
     enum wined3d_multisample_type multisample_type;
     DWORD multisample_quality;
     enum wined3d_swap_effect swap_effect;
@@ -1730,26 +1752,26 @@ struct wined3d_resource_desc
     enum wined3d_resource_type resource_type;
     enum wined3d_format_id format;
     enum wined3d_multisample_type multisample_type;
     enum wined3d_resource_type resource_type;
     enum wined3d_format_id format;
     enum wined3d_multisample_type multisample_type;
-    UINT multisample_quality;
-    DWORD usage;
-    enum wined3d_pool pool;
-    UINT width;
-    UINT height;
-    UINT depth;
-    UINT size;
+    unsigned int multisample_quality;
+    unsigned int usage;
+    unsigned int access;
+    unsigned int width;
+    unsigned int height;
+    unsigned int depth;
+    unsigned int size;
 };
 
 struct wined3d_sub_resource_desc
 {
     enum wined3d_format_id format;
     enum wined3d_multisample_type multisample_type;
 };
 
 struct wined3d_sub_resource_desc
 {
     enum wined3d_format_id format;
     enum wined3d_multisample_type multisample_type;
-    UINT multisample_quality;
-    DWORD usage;
-    enum wined3d_pool pool;
-    UINT width;
-    UINT height;
-    UINT depth;
-    UINT size;
+    unsigned int multisample_quality;
+    unsigned int usage;
+    unsigned int access;
+    unsigned int width;
+    unsigned int height;
+    unsigned int depth;
+    unsigned int size;
 };
 
 struct wined3d_clip_status
 };
 
 struct wined3d_clip_status
@@ -1798,6 +1820,13 @@ struct wined3d_map_desc
     void *data;
 };
 
     void *data;
 };
 
+struct wined3d_map_info
+{
+    UINT row_pitch;
+    UINT slice_pitch;
+    UINT size;
+};
+
 struct wined3d_sub_resource_data
 {
     const void *data;
 struct wined3d_sub_resource_data
 {
     const void *data;
@@ -1964,13 +1993,18 @@ struct wined3d_blt_fx
 struct wined3d_buffer_desc
 {
     unsigned int byte_width;
 struct wined3d_buffer_desc
 {
     unsigned int byte_width;
-    DWORD usage;
+    unsigned int usage;
     unsigned int bind_flags;
     unsigned int bind_flags;
-    unsigned int cpu_access_flags;
+    unsigned int access;
     unsigned int misc_flags;
     unsigned int structure_byte_stride;
 };
 
     unsigned int misc_flags;
     unsigned int structure_byte_stride;
 };
 
+struct wined3d_blend_state_desc
+{
+    BOOL alpha_to_coverage;
+};
+
 struct wined3d_rasterizer_state_desc
 {
     BOOL front_ccw;
 struct wined3d_rasterizer_state_desc
 {
     BOOL front_ccw;
@@ -2081,6 +2115,7 @@ struct wined3d_buffer;
 struct wined3d_device;
 struct wined3d_palette;
 struct wined3d_query;
 struct wined3d_device;
 struct wined3d_palette;
 struct wined3d_query;
+struct wined3d_blend_state;
 struct wined3d_rasterizer_state;
 struct wined3d_rendertarget_view;
 struct wined3d_resource;
 struct wined3d_rasterizer_state;
 struct wined3d_rendertarget_view;
 struct wined3d_resource;
@@ -2184,12 +2219,6 @@ HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d,
 HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
         const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
         struct wined3d_buffer **buffer);
 HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
         const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
         struct wined3d_buffer **buffer);
-HRESULT __cdecl wined3d_buffer_create_ib(struct wined3d_device *device, UINT length, DWORD usage,
-        enum wined3d_pool pool, void *parent, const struct wined3d_parent_ops *parent_ops,
-        struct wined3d_buffer **buffer);
-HRESULT __cdecl wined3d_buffer_create_vb(struct wined3d_device *device, UINT length, DWORD usage,
-        enum wined3d_pool pool, void *parent, const struct wined3d_parent_ops *parent_ops,
-        struct wined3d_buffer **buffer);
 ULONG __cdecl wined3d_buffer_decref(struct wined3d_buffer *buffer);
 void * __cdecl wined3d_buffer_get_parent(const struct wined3d_buffer *buffer);
 struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buffer *buffer);
 ULONG __cdecl wined3d_buffer_decref(struct wined3d_buffer *buffer);
 void * __cdecl wined3d_buffer_get_parent(const struct wined3d_buffer *buffer);
 struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buffer *buffer);
@@ -2236,6 +2265,7 @@ HRESULT __cdecl wined3d_device_end_stateblock(struct wined3d_device *device, str
 void __cdecl wined3d_device_evict_managed_resources(struct wined3d_device *device);
 UINT __cdecl wined3d_device_get_available_texture_mem(const struct wined3d_device *device);
 INT __cdecl wined3d_device_get_base_vertex_index(const struct wined3d_device *device);
 void __cdecl wined3d_device_evict_managed_resources(struct wined3d_device *device);
 UINT __cdecl wined3d_device_get_available_texture_mem(const struct wined3d_device *device);
 INT __cdecl wined3d_device_get_base_vertex_index(const struct wined3d_device *device);
+struct wined3d_blend_state * __cdecl wined3d_device_get_blend_state(const struct wined3d_device *device);
 HRESULT __cdecl wined3d_device_get_clip_plane(const struct wined3d_device *device,
         UINT plane_idx, struct wined3d_vec4 *plane);
 HRESULT __cdecl wined3d_device_get_clip_status(const struct wined3d_device *device,
 HRESULT __cdecl wined3d_device_get_clip_plane(const struct wined3d_device *device,
         UINT plane_idx, struct wined3d_vec4 *plane);
 HRESULT __cdecl wined3d_device_get_clip_status(const struct wined3d_device *device,
@@ -2343,9 +2373,14 @@ void __cdecl wined3d_device_release_focus_window(struct wined3d_device *device);
 HRESULT __cdecl wined3d_device_reset(struct wined3d_device *device,
         const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode,
         wined3d_device_reset_cb callback, BOOL reset_state);
 HRESULT __cdecl wined3d_device_reset(struct wined3d_device *device,
         const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode,
         wined3d_device_reset_cb callback, BOOL reset_state);
+void __cdecl wined3d_device_resolve_sub_resource(struct wined3d_device *device,
+        struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx,
+        struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx,
+        enum wined3d_format_id format_id);
 void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window,
         const RECT *window_rect);
 void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index);
 void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window,
         const RECT *window_rect);
 void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index);
+void __cdecl wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state);
 HRESULT __cdecl wined3d_device_set_clip_plane(struct wined3d_device *device,
         UINT plane_idx, const struct wined3d_vec4 *plane);
 HRESULT __cdecl wined3d_device_set_clip_status(struct wined3d_device *device,
 HRESULT __cdecl wined3d_device_set_clip_plane(struct wined3d_device *device,
         UINT plane_idx, const struct wined3d_vec4 *plane);
 HRESULT __cdecl wined3d_device_set_clip_status(struct wined3d_device *device,
@@ -2548,6 +2583,13 @@ static inline HRESULT wined3d_private_store_set_private_data(struct wined3d_priv
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+HRESULT __cdecl wined3d_blend_state_create(struct wined3d_device *device,
+        const struct wined3d_blend_state_desc *desc, void *parent,
+        const struct wined3d_parent_ops *parent_ops, struct wined3d_blend_state **state);
+ULONG __cdecl wined3d_blend_state_decref(struct wined3d_blend_state *state);
+void * __cdecl wined3d_blend_state_get_parent(const struct wined3d_blend_state *state);
+ULONG __cdecl wined3d_blend_state_incref(struct wined3d_blend_state *state);
+
 HRESULT __cdecl wined3d_rasterizer_state_create(struct wined3d_device *device,
         const struct wined3d_rasterizer_state_desc *desc, void *parent,
         const struct wined3d_parent_ops *parent_ops, struct wined3d_rasterizer_state **state);
 HRESULT __cdecl wined3d_rasterizer_state_create(struct wined3d_device *device,
         const struct wined3d_rasterizer_state_desc *desc, void *parent,
         const struct wined3d_parent_ops *parent_ops, struct wined3d_rasterizer_state **state);
@@ -2561,10 +2603,14 @@ void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resour
 DWORD __cdecl wined3d_resource_get_priority(const struct wined3d_resource *resource);
 HRESULT __cdecl wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
         struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
 DWORD __cdecl wined3d_resource_get_priority(const struct wined3d_resource *resource);
 HRESULT __cdecl wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
         struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
+HRESULT __cdecl wined3d_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+        struct wined3d_map_info *info, DWORD flags);
 void __cdecl wined3d_resource_preload(struct wined3d_resource *resource);
 void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent);
 DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority);
 HRESULT __cdecl wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx);
 void __cdecl wined3d_resource_preload(struct wined3d_resource *resource);
 void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent);
 DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority);
 HRESULT __cdecl wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx);
+UINT __cdecl wined3d_resource_update_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+        const struct wined3d_box *box, unsigned int row_pitch, unsigned int depth_pitch);
 
 HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc,
         struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
 
 HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc,
         struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
@@ -2640,7 +2686,7 @@ HRESULT __cdecl wined3d_swapchain_get_raster_status(const struct wined3d_swapcha
         struct wined3d_raster_status *raster_status);
 ULONG __cdecl wined3d_swapchain_incref(struct wined3d_swapchain *swapchain);
 HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
         struct wined3d_raster_status *raster_status);
 ULONG __cdecl wined3d_swapchain_incref(struct wined3d_swapchain *swapchain);
 HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
-        const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags);
+        const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD swap_interval, DWORD flags);
 HRESULT __cdecl wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count,
         unsigned int width, unsigned int height, enum wined3d_format_id format_id,
         enum wined3d_multisample_type multisample_type, unsigned int multisample_quality);
 HRESULT __cdecl wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count,
         unsigned int width, unsigned int height, enum wined3d_format_id format_id,
         enum wined3d_multisample_type multisample_type, unsigned int multisample_quality);
@@ -2663,7 +2709,6 @@ HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const stru
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
 struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource);
 ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture);
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
 struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource);
 ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture);
-enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture);
 HRESULT __cdecl wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc);
 DWORD __cdecl wined3d_texture_get_level_count(const struct wined3d_texture *texture);
 DWORD __cdecl wined3d_texture_get_lod(const struct wined3d_texture *texture);
 HRESULT __cdecl wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc);
 DWORD __cdecl wined3d_texture_get_level_count(const struct wined3d_texture *texture);
 DWORD __cdecl wined3d_texture_get_lod(const struct wined3d_texture *texture);
@@ -2678,8 +2723,6 @@ HRESULT __cdecl wined3d_texture_get_sub_resource_desc(const struct wined3d_textu
 void * __cdecl wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx);
 ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture);
 HRESULT __cdecl wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc);
 void * __cdecl wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx);
 ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture);
 HRESULT __cdecl wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc);
-HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture,
-        enum wined3d_texture_filter_type filter_type);
 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_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);
@@ -2754,4 +2797,18 @@ static inline void wined3d_box_set(struct wined3d_box *box, unsigned int left, u
     box->back = back;
 }
 
     box->back = back;
 }
 
+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 */
 #endif /* __WINE_WINED3D_H */