From 9987f02917539e05268ba2ad11e62d24a3636972 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Thu, 8 Mar 2018 13:15:18 +0100 Subject: [PATCH] [D3D8][D3D9][DDRAW][WINED3D] Sync with Wine Staging 3.3. CORE-14434 --- dll/directx/wine/d3d8/CMakeLists.txt | 4 +- dll/directx/wine/d3d8/buffer.c | 55 +- dll/directx/wine/d3d8/d3d8_main.c | 89 +- dll/directx/wine/d3d8/d3d8_private.h | 63 +- dll/directx/wine/d3d8/device.c | 202 ++- dll/directx/wine/d3d8/directx.c | 22 +- dll/directx/wine/d3d8/precomp.h | 13 + dll/directx/wine/d3d8/shader.c | 12 +- dll/directx/wine/d3d8/surface.c | 11 +- dll/directx/wine/d3d8/swapchain.c | 11 +- dll/directx/wine/d3d8/texture.c | 37 +- dll/directx/wine/d3d8/vertexdeclaration.c | 18 +- dll/directx/wine/d3d8/volume.c | 14 +- dll/directx/wine/d3d9/CMakeLists.txt | 4 +- dll/directx/wine/d3d9/buffer.c | 57 +- dll/directx/wine/d3d9/d3d9_main.c | 12 +- dll/directx/wine/d3d9/d3d9_private.h | 86 +- dll/directx/wine/d3d9/device.c | 310 +++- dll/directx/wine/d3d9/directx.c | 17 +- dll/directx/wine/d3d9/precomp.h | 13 + dll/directx/wine/d3d9/query.c | 5 +- dll/directx/wine/d3d9/shader.c | 7 +- dll/directx/wine/d3d9/stateblock.c | 5 +- dll/directx/wine/d3d9/surface.c | 15 +- dll/directx/wine/d3d9/swapchain.c | 11 +- dll/directx/wine/d3d9/texture.c | 359 +++-- dll/directx/wine/d3d9/vertexdeclaration.c | 33 +- dll/directx/wine/d3d9/volume.c | 14 +- dll/directx/wine/ddraw/CMakeLists.txt | 4 +- dll/directx/wine/ddraw/clipper.c | 7 +- dll/directx/wine/ddraw/ddraw.c | 244 ++- dll/directx/wine/ddraw/ddraw_private.h | 38 +- dll/directx/wine/ddraw/device.c | 104 +- dll/directx/wine/ddraw/executebuffer.c | 68 +- dll/directx/wine/ddraw/light.c | 7 +- dll/directx/wine/ddraw/main.c | 36 +- dll/directx/wine/ddraw/material.c | 10 +- dll/directx/wine/ddraw/palette.c | 7 +- dll/directx/wine/ddraw/precomp.h | 15 + dll/directx/wine/ddraw/surface.c | 277 ++-- dll/directx/wine/ddraw/utils.c | 55 +- dll/directx/wine/ddraw/vertexbuffer.c | 52 +- dll/directx/wine/ddraw/viewport.c | 11 +- dll/directx/wine/wined3d/CMakeLists.txt | 5 +- dll/directx/wine/wined3d/arb_program_shader.c | 182 ++- .../wine/wined3d/ati_fragment_shader.c | 23 +- dll/directx/wine/wined3d/buffer.c | 149 +- dll/directx/wine/wined3d/context.c | 1436 ++++++++++++++--- dll/directx/wine/wined3d/cs.c | 211 ++- dll/directx/wine/wined3d/device.c | 545 ++++--- dll/directx/wine/wined3d/directx.c | 417 +++-- dll/directx/wine/wined3d/drawprim.c | 785 --------- dll/directx/wine/wined3d/dxtn.c | 5 +- dll/directx/wine/wined3d/gl_compat.c | 8 + dll/directx/wine/wined3d/glsl_shader.c | 796 ++++----- .../wine/wined3d/nvidia_texture_shader.c | 4 + dll/directx/wine/wined3d/palette.c | 10 +- dll/directx/wine/wined3d/precomp.h | 44 + dll/directx/wine/wined3d/query.c | 134 +- dll/directx/wine/wined3d/resource.c | 227 ++- dll/directx/wine/wined3d/sampler.c | 7 +- dll/directx/wine/wined3d/shader.c | 165 +- dll/directx/wine/wined3d/shader_sm1.c | 9 +- dll/directx/wine/wined3d/shader_sm4.c | 11 +- dll/directx/wine/wined3d/state.c | 324 ++-- dll/directx/wine/wined3d/stateblock.c | 27 +- dll/directx/wine/wined3d/surface.c | 684 +++++--- dll/directx/wine/wined3d/swapchain.c | 64 +- dll/directx/wine/wined3d/texture.c | 1103 ++++++++++--- dll/directx/wine/wined3d/utils.c | 494 +++++- dll/directx/wine/wined3d/vertexdeclaration.c | 30 +- dll/directx/wine/wined3d/view.c | 64 +- dll/directx/wine/wined3d/wined3d.spec | 26 +- dll/directx/wine/wined3d/wined3d_gl.h | 8 +- dll/directx/wine/wined3d/wined3d_main.c | 37 +- dll/directx/wine/wined3d/wined3d_private.h | 273 +++- media/doc/README.WINE | 8 +- sdk/include/reactos/wine/wined3d.h | 163 +- 78 files changed, 7054 insertions(+), 3858 deletions(-) create mode 100644 dll/directx/wine/d3d8/precomp.h create mode 100644 dll/directx/wine/d3d9/precomp.h create mode 100644 dll/directx/wine/ddraw/precomp.h delete mode 100644 dll/directx/wine/wined3d/drawprim.c create mode 100644 dll/directx/wine/wined3d/precomp.h diff --git a/dll/directx/wine/d3d8/CMakeLists.txt b/dll/directx/wine/d3d8/CMakeLists.txt index bad1641fea8..09d7a6c659d 100644 --- a/dll/directx/wine/d3d8/CMakeLists.txt +++ b/dll/directx/wine/d3d8/CMakeLists.txt @@ -17,7 +17,7 @@ list(APPEND SOURCE texture.c vertexdeclaration.c volume.c - d3d8_private.h) + precomp.h) 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) -add_pch(d3d8 d3d8_private.h SOURCE) +add_pch(d3d8 precomp.h SOURCE) add_cd_file(TARGET d3d8 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3d8/buffer.c b/dll/directx/wine/d3d8/buffer.c index d778e58360d..fb6b7bc1e92 100644 --- a/dll/directx/wine/d3d8/buffer.c +++ b/dll/directx/wine/d3d8/buffer.c @@ -16,8 +16,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -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), - 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; @@ -224,12 +227,12 @@ static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface, wined3d_resource_get_desc(wined3d_resource, &wined3d_desc); wined3d_mutex_unlock(); + desc->Format = D3DFMT_VERTEXDATA; 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->Format = D3DFMT_VERTEXDATA; 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); - HeapFree(GetProcessHeap(), 0, buffer); + heap_free(buffer); } 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) { + struct wined3d_buffer_desc desc; 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; + 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(); - 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)) { @@ -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), - 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; @@ -509,8 +527,8 @@ static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface, 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; @@ -541,7 +559,7 @@ static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *pa { 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 = @@ -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) { + struct wined3d_buffer_desc desc; 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(); - 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)) { diff --git a/dll/directx/wine/d3d8/d3d8_main.c b/dll/directx/wine/d3d8/d3d8_main.c index 144817a545b..0e686308f05 100644 --- a/dll/directx/wine/d3d8/d3d8_main.c +++ b/dll/directx/wine/d3d8/d3d8_main.c @@ -19,7 +19,12 @@ * */ +#include "config.h" +#include "initguid.h" #include "d3d8_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); 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); - 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"); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return NULL; } @@ -53,75 +58,73 @@ IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version) /*********************************************************************** * 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; + const char *message = ""; + HRESULT hr = E_FAIL; - if (TRACE_ON(d3d8) || !warned) { - FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto); - warned = TRUE; - } + TRACE("(%p %p %p %d %p): semi-stub\n", vertexshader, reserved1, reserved2, return_error, errors); - if (!vertexshader) - return E_FAIL; + if (!vertexshader) + { + message = "(Global Validation Error) Version Token: Code pointer cannot be NULL.\n"; + goto done; + } - if (reserved1 || reserved2) - return E_FAIL; - - switch(*vertexshader) { + switch (*vertexshader) + { case 0xFFFE0101: case 0xFFFE0100: - ret=S_OK; + hr = S_OK; break; + 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.@) - * - * 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; + const char *message = ""; + HRESULT hr = E_FAIL; - if (TRACE_ON(d3d8) || !warned) { - FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto); - warned = TRUE; - } + TRACE("(%p %p %d %p): semi-stub\n", pixelshader, reserved1, return_error, errors); - if (!pixelshader) - return E_FAIL; + if (!pixelshader) + return E_FAIL; - if (reserved1) - return E_FAIL; - - switch(*pixelshader) { + switch (*pixelshader) + { 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); - 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) diff --git a/dll/directx/wine/d3d8/d3d8_private.h b/dll/directx/wine/d3d8/d3d8_private.h index a85e2995cbe..cba5dd647b4 100644 --- a/dll/directx/wine/d3d8/d3d8_private.h +++ b/dll/directx/wine/d3d8/d3d8_private.h @@ -23,27 +23,19 @@ #ifndef __WINE_D3D8_PRIVATE_H #define __WINE_D3D8_PRIVATE_H -#include - #include #include -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H - #define NONAMELESSUNION #define NONAMELESSSTRUCT #define COBJMACROS -#include -#include -#include - -#include -WINE_DEFAULT_DEBUG_CHANNEL(d3d8); - -#include -#include +#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 @@ -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; +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; +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 */ diff --git a/dll/directx/wine/d3d8/device.c b/dll/directx/wine/d3d8/device.c index 6573baa355f..5daf6f46c2a 100644 --- a/dll/directx/wine/d3d8/device.c +++ b/dll/directx/wine/d3d8/device.c @@ -19,8 +19,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "wingdi.h" +#include "wine/debug.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 = @@ -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) @@ -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) { @@ -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->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; @@ -173,6 +227,24 @@ static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS 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) { @@ -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_usage = WINED3DUSAGE_RENDERTARGET; 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; @@ -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); - 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; @@ -430,7 +503,7 @@ static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface) { 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); @@ -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); - HeapFree(GetProcessHeap(), 0, device->handle_table.entries); - HeapFree(GetProcessHeap(), 0, device); + heap_free(device->handle_table.entries); + heap_free(device); 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); - if (desc.pool != WINED3D_POOL_DEFAULT) + if (desc.access & WINED3D_RESOURCE_ACCESS_CPU) 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; - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } @@ -882,15 +954,14 @@ static HRESULT WINAPI d3d8_device_CreateVolumeTexture(IDirect3DDevice8 *iface, 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } @@ -914,15 +985,14 @@ static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UIN 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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.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; @@ -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); + struct wined3d_buffer_desc desc; 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; } @@ -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, - 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); @@ -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); + struct wined3d_buffer_desc desc; 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; } @@ -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, - 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); @@ -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, - 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); @@ -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); - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) + if (!(object = heap_alloc_zero(sizeof(*object)))) { *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"); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); *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(); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); *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); - 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); - HeapFree(GetProcessHeap(), 0, d3d8_declaration); + heap_free(d3d8_declaration); return NULL; } @@ -2406,9 +2490,8 @@ static struct d3d8_vertex_declaration *d3d8_device_get_fvf_declaration(struct d3 { 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; @@ -2703,8 +2786,7 @@ static HRESULT WINAPI d3d8_device_CreatePixelShader(IDirect3DDevice8 *iface, 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(); @@ -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"); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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(); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); *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); - 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); @@ -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); - 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); @@ -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->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; @@ -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(); - HeapFree(GetProcessHeap(), 0, device->handle_table.entries); + heap_free(device->handle_table.entries); 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(); - HeapFree(GetProcessHeap(), 0, device->handle_table.entries); + heap_free(device->handle_table.entries); 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(); - HeapFree(GetProcessHeap(), 0, device->handle_table.entries); + heap_free(device->handle_table.entries); 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(); - HeapFree(GetProcessHeap(), 0, device->handle_table.entries); + heap_free(device->handle_table.entries); 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; - 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; @@ -3300,6 +3380,6 @@ err: 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; } diff --git a/dll/directx/wine/d3d8/directx.c b/dll/directx/wine/d3d8/directx.c index ffb8ddefb47..6e8f93a25c6 100644 --- a/dll/directx/wine/d3d8/directx.c +++ b/dll/directx/wine/d3d8/directx.c @@ -20,8 +20,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "wine/debug.h" +#include "wine/unicode.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); @@ -68,7 +81,7 @@ static ULONG WINAPI d3d8_Release(IDirect3D8 *iface) wined3d_decref(d3d8->wined3d); wined3d_mutex_unlock(); - HeapFree(GetProcessHeap(), 0, d3d8); + heap_free(d3d8); } 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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 - | WINED3D_LEGACY_CUBEMAP_FILTERING; + | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT; 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 index 00000000000..17c27cb7187 --- /dev/null +++ b/dll/directx/wine/d3d8/precomp.h @@ -0,0 +1,13 @@ + +#ifndef __WINE_D3D8_PRECOMP_H +#define __WINE_D3D8_PRECOMP_H + +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include "d3d8_private.h" + +#endif /* __WINE_D3D8_PRECOMP_H */ diff --git a/dll/directx/wine/d3d8/shader.c b/dll/directx/wine/d3d8/shader.c index d0361a9e837..8192b238ebd 100644 --- a/dll/directx/wine/d3d8/shader.c +++ b/dll/directx/wine/d3d8/shader.c @@ -17,13 +17,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); - HeapFree(GetProcessHeap(), 0, shader); + heap_free(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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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) { - HeapFree(GetProcessHeap(), 0, parent); + heap_free(parent); } void d3d8_pixel_shader_destroy(struct d3d8_pixel_shader *shader) diff --git a/dll/directx/wine/d3d8/surface.c b/dll/directx/wine/d3d8/surface.c index 545361644b8..fff47f5ca15 100644 --- a/dll/directx/wine/d3d8/surface.c +++ b/dll/directx/wine/d3d8/surface.c @@ -18,8 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -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->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; @@ -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, - &map_desc, rect ? &box : NULL, flags); + &map_desc, rect ? &box : NULL, wined3dmapflags_from_d3dmapflags(flags)); 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); - HeapFree(GetProcessHeap(), 0, surface); + heap_free(surface); } static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops = diff --git a/dll/directx/wine/d3d8/swapchain.c b/dll/directx/wine/d3d8/swapchain.c index d82a8ed657a..3a588b5e8c2 100644 --- a/dll/directx/wine/d3d8/swapchain.c +++ b/dll/directx/wine/d3d8/swapchain.c @@ -18,8 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -102,7 +105,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai wined3d_mutex_lock(); hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, 0); + src_rect, dst_rect, dst_window_override, 0, 0); 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) { - HeapFree(GetProcessHeap(), 0, parent); + heap_free(parent); } 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; - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } diff --git a/dll/directx/wine/d3d8/texture.c b/dll/directx/wine/d3d8/texture.c index b8608599870..87a2575cb1c 100644 --- a/dll/directx/wine/d3d8/texture.c +++ b/dll/directx/wine/d3d8/texture.c @@ -16,21 +16,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" #include "d3d8_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); + 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) { - 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) { - 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) @@ -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->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; @@ -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->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; @@ -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->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; @@ -1080,7 +1083,7 @@ static void STDMETHODCALLTYPE d3d8_texture_wined3d_object_destroyed(void *parent { 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 = @@ -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.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; @@ -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.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; @@ -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.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; diff --git a/dll/directx/wine/d3d8/vertexdeclaration.c b/dll/directx/wine/d3d8/vertexdeclaration.c index e01230e5ae2..0cae3cd8c6c 100644 --- a/dll/directx/wine/d3d8/vertexdeclaration.c +++ b/dll/directx/wine/d3d8/vertexdeclaration.c @@ -21,8 +21,11 @@ /* IDirect3DVertexDeclaration8 is internal to our implementation. * It's not visible in the API. */ +#include "config.h" #include "d3d8_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); + 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... */ - *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); @@ -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; - 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) @@ -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->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"); - HeapFree(GetProcessHeap(), 0, wined3d_elements); + heap_free(wined3d_elements); 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(); - HeapFree(GetProcessHeap(), 0, wined3d_elements); + heap_free(wined3d_elements); 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; } diff --git a/dll/directx/wine/d3d8/volume.c b/dll/directx/wine/d3d8/volume.c index 0e1e904e2f5..89aa84fdb50 100644 --- a/dll/directx/wine/d3d8/volume.c +++ b/dll/directx/wine/d3d8/volume.c @@ -18,8 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -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->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; @@ -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), - 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(); @@ -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; + if (hr == E_INVALIDARG) + return D3DERR_INVALIDCALL; 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); - HeapFree(GetProcessHeap(), 0, volume); + heap_free(volume); } static const struct wined3d_parent_ops d3d8_volume_wined3d_parent_ops = diff --git a/dll/directx/wine/d3d9/CMakeLists.txt b/dll/directx/wine/d3d9/CMakeLists.txt index 9dd8b4aa6a9..223606b87ee 100644 --- a/dll/directx/wine/d3d9/CMakeLists.txt +++ b/dll/directx/wine/d3d9/CMakeLists.txt @@ -19,7 +19,7 @@ list(APPEND SOURCE texture.c vertexdeclaration.c volume.c - d3d9_private.h) + precomp.h) 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) -add_pch(d3d9 d3d9_private.h SOURCE) +add_pch(d3d9 precomp.h SOURCE) add_cd_file(TARGET d3d9 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3d9/buffer.c b/dll/directx/wine/d3d9/buffer.c index 462ef3bb974..36a6ae3f902 100644 --- a/dll/directx/wine/d3d9/buffer.c +++ b/dll/directx/wine/d3d9/buffer.c @@ -18,8 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -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), - 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; @@ -226,10 +229,10 @@ static HRESULT WINAPI d3d9_vertexbuffer_GetDesc(IDirect3DVertexBuffer9 *iface, 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->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; @@ -260,7 +263,7 @@ static void STDMETHODCALLTYPE d3d9_vertexbuffer_wined3d_object_destroyed(void *p { 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 = @@ -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) { + struct wined3d_buffer_desc desc; 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); + 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(); - 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)) { @@ -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), - 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; @@ -507,10 +525,10 @@ static HRESULT WINAPI d3d9_indexbuffer_GetDesc(IDirect3DIndexBuffer9 *iface, D3D 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->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; } @@ -540,7 +558,7 @@ static void STDMETHODCALLTYPE d3d9_indexbuffer_wined3d_object_destroyed(void *pa { 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 = @@ -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) { + struct wined3d_buffer_desc desc; 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(); - 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)) { diff --git a/dll/directx/wine/d3d9/d3d9_main.c b/dll/directx/wine/d3d9/d3d9_main.c index 4bd80e1b916..c23fa54d99b 100644 --- a/dll/directx/wine/d3d9/d3d9_main.c +++ b/dll/directx/wine/d3d9/d3d9_main.c @@ -21,8 +21,12 @@ * */ +#include "config.h" +#include "initguid.h" #include "d3d9_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d9); + 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); - 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"); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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"); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return D3DERR_NOTAVAILABLE; } diff --git a/dll/directx/wine/d3d9/d3d9_private.h b/dll/directx/wine/d3d9/d3d9_private.h index d34dd73137f..ba19e5fb08f 100644 --- a/dll/directx/wine/d3d9/d3d9_private.h +++ b/dll/directx/wine/d3d9/d3d9_private.h @@ -23,36 +23,39 @@ #ifndef __WINE_D3D9_PRIVATE_H #define __WINE_D3D9_PRIVATE_H -#include - #include #include -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H - #define NONAMELESSUNION #define NONAMELESSSTRUCT #define COBJMACROS -#include -#include -#include +#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_DEFAULT_DEBUG_CHANNEL(d3d9); +#include "d3d9.h" +#include "wine/wined3d.h" -#include -#include +#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 +#define D3D9_MAX_TEXTURE_UNITS 20 #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; +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; @@ -98,6 +101,9 @@ struct d3d9_device UINT index_buffer_size; UINT index_buffer_pos; + struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS]; + struct d3d9_surface *render_targets[D3D_MAX_SIMULTANEOUS_RENDERTARGETS]; + LONG device_state; 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; + 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, @@ -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; +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 { @@ -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; -#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 -#define D3D9_MAX_SIMULTANEOUS_RENDERTARGETS 4 - 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); } +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 */ diff --git a/dll/directx/wine/d3d9/device.c b/dll/directx/wine/d3d9/device.c index b3e085f34de..bc73699e525 100644 --- a/dll/directx/wine/d3d9/device.c +++ b/dll/directx/wine/d3d9/device.c @@ -20,9 +20,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" #include "d3d9_private.h" -#include +WINE_DEFAULT_DEBUG_CHANNEL(d3d9); 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) @@ -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) { @@ -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->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; @@ -205,6 +250,26 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese 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) { @@ -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_usage = WINED3DUSAGE_RENDERTARGET; 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; @@ -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); - caps->NumSimultaneousRTs = min(D3D9_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs); + caps->NumSimultaneousRTs = min(D3D_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs); 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); } - 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); - 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); @@ -494,7 +560,7 @@ static ULONG WINAPI DECLSPEC_HOTPATCH d3d9_device_Release(IDirect3DDevice9Ex *if IDirect3D9Ex_Release(&device->d3d_parent->IDirect3D9Ex_iface); - HeapFree(GetProcessHeap(), 0, device); + heap_free(device); } return refcount; @@ -764,7 +830,7 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) 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) @@ -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; - 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) @@ -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; + struct wined3d_rendertarget_view *rtv; + unsigned int i; HRESULT hr; - 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))) { - HeapFree(GetProcessHeap(), 0, device->implicit_swapchains); + heap_free(device->implicit_swapchains); if (!extended) { @@ -876,6 +942,15 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, device->device_state = D3D9_DEVICE_STATE_OK; } + + if (!device->d3d_parent->extended) + for (i = 0; i < ARRAY_SIZE(device->textures); ++i) + device->textures[i] = NULL; + + rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0); + device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i) + device->render_targets[i] = NULL; } 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, - src_rect, dst_rect, dst_window_override, 0))) + src_rect, dst_rect, dst_window_override, 0, 0))) { 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); } - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); } - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); } - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); } - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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.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; @@ -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); + if (SUCCEEDED(hr) && dst->texture) + d3d9_texture_flag_auto_gen_mipmap(dst->texture); + 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); + if (SUCCEEDED(hr)) + d3d9_texture_flag_auto_gen_mipmap(dst_impl); wined3d_mutex_unlock(); return hr; @@ -1534,6 +1612,23 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect 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) @@ -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; + if (SUCCEEDED(hr) && dst->texture) + d3d9_texture_flag_auto_gen_mipmap(dst->texture); done: wined3d_mutex_unlock(); @@ -1602,10 +1699,10 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface, return D3DERR_INVALIDCALL; } - if (desc.pool != WINED3D_POOL_DEFAULT) + if (desc.access & WINED3D_RESOURCE_ACCESS_CPU) { 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) @@ -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); + if (SUCCEEDED(hr) && surface_impl->texture) + d3d9_texture_flag_auto_gen_mipmap(surface_impl->texture); 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); - if (idx >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS) + if (idx >= D3D_MAX_SIMULTANEOUS_RENDERTARGETS) { 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); + if (SUCCEEDED(hr)) + device->render_targets[idx] = surface_impl; wined3d_mutex_unlock(); return hr; @@ -1724,7 +1825,7 @@ static HRESULT WINAPI d3d9_device_GetRenderTarget(IDirect3DDevice9Ex *iface, DWO 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; @@ -1827,6 +1928,19 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_EndScene(IDirect3DDevice9Ex 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) { @@ -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); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock(); return hr; @@ -2104,15 +2220,14 @@ static HRESULT WINAPI d3d9_device_CreateStateBlock(IDirect3DDevice9Ex *iface, 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } @@ -2154,8 +2269,7 @@ static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDire 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); @@ -2170,7 +2284,7 @@ static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDire wined3d_mutex_lock(); wined3d_stateblock_decref(wined3d_stateblock); wined3d_mutex_unlock(); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); + 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; @@ -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); - if (state >= sizeof(tss_lookup) / sizeof(*tss_lookup)) + if (state >= ARRAY_SIZE(tss_lookup)) { 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); - if (state >= sizeof(tss_lookup) / sizeof(*tss_lookup)) + if (state >= ARRAY_SIZE(tss_lookup)) { WARN("Invalid state %#x passed.\n", state); return D3D_OK; @@ -2488,6 +2609,16 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface) 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) { @@ -2504,9 +2635,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, 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)); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); 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; } + 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)); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); 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); + struct wined3d_buffer_desc desc; 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; } @@ -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, - 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); @@ -2626,9 +2770,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, 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); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); 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); + struct wined3d_buffer_desc desc; 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; } @@ -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, - 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); @@ -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, - 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); @@ -2749,6 +2903,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa 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); @@ -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); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); + 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); - HeapFree(GetProcessHeap(), 0, elements); + heap_free(elements); 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); - 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; @@ -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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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; @@ -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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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, - src_rect, dst_rect, dst_window_override, flags))) + src_rect, dst_rect, dst_window_override, 0, flags))) { 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); - 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); @@ -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); - 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); @@ -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); @@ -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); - HeapFree(GetProcessHeap(), 0, swapchain_desc); + heap_free(swapchain_desc); 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); - HeapFree(GetProcessHeap(), 0, swapchain_desc); + heap_free(swapchain_desc); 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(); - 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. */ - 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(); - 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); @@ -4144,6 +4296,14 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine 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; diff --git a/dll/directx/wine/d3d9/directx.c b/dll/directx/wine/d3d9/directx.c index ab153a90305..644766c2e97 100644 --- a/dll/directx/wine/d3d9/directx.c +++ b/dll/directx/wine/d3d9/directx.c @@ -19,8 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -83,7 +86,7 @@ static ULONG WINAPI d3d9_Release(IDirect3D9Ex *iface) wined3d_decref(d3d9->wined3d); wined3d_mutex_unlock(); - HeapFree(GetProcessHeap(), 0, d3d9); + heap_free(d3d9); } 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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 - | WINED3D_NORMALIZED_DEPTH_BIAS; + | WINED3D_NORMALIZED_DEPTH_BIAS | WINED3D_LIMIT_VIEWPORT; 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 index 00000000000..3d1e1837941 --- /dev/null +++ b/dll/directx/wine/d3d9/precomp.h @@ -0,0 +1,13 @@ + +#ifndef __WINE_D3D9_PRECOMP_H +#define __WINE_D3D9_PRECOMP_H + +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include "d3d9_private.h" + +#endif /* __WINE_D3D9_PRECOMP_H */ diff --git a/dll/directx/wine/d3d9/query.c b/dll/directx/wine/d3d9/query.c index 8681502c49f..12ff95b5a06 100644 --- a/dll/directx/wine/d3d9/query.c +++ b/dll/directx/wine/d3d9/query.c @@ -20,8 +20,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -69,7 +72,7 @@ static ULONG WINAPI d3d9_query_Release(IDirect3DQuery9 *iface) wined3d_mutex_unlock(); IDirect3DDevice9Ex_Release(query->parent_device); - HeapFree(GetProcessHeap(), 0, query); + heap_free(query); } return refcount; } diff --git a/dll/directx/wine/d3d9/shader.c b/dll/directx/wine/d3d9/shader.c index 75dfc0f3941..9cb398388b9 100644 --- a/dll/directx/wine/d3d9/shader.c +++ b/dll/directx/wine/d3d9/shader.c @@ -17,8 +17,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -123,7 +126,7 @@ static const IDirect3DVertexShader9Vtbl d3d9_vertexshader_vtbl = 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 = @@ -277,7 +280,7 @@ static const IDirect3DPixelShader9Vtbl d3d9_pixelshader_vtbl = 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 = diff --git a/dll/directx/wine/d3d9/stateblock.c b/dll/directx/wine/d3d9/stateblock.c index 9355d9d51e1..62b3bacb28d 100644 --- a/dll/directx/wine/d3d9/stateblock.c +++ b/dll/directx/wine/d3d9/stateblock.c @@ -20,8 +20,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -69,7 +72,7 @@ static ULONG WINAPI d3d9_stateblock_Release(IDirect3DStateBlock9 *iface) wined3d_mutex_unlock(); IDirect3DDevice9Ex_Release(stateblock->parent_device); - HeapFree(GetProcessHeap(), 0, stateblock); + heap_free(stateblock); } return refcount; diff --git a/dll/directx/wine/d3d9/surface.c b/dll/directx/wine/d3d9/surface.c index 47b52679109..0605e7142a3 100644 --- a/dll/directx/wine/d3d9/surface.c +++ b/dll/directx/wine/d3d9/surface.c @@ -19,8 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -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->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; @@ -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, - &map_desc, rect ? &box : NULL, flags); + &map_desc, rect ? &box : NULL, wined3dmapflags_from_d3dmapflags(flags)); 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); + if (SUCCEEDED(hr) && surface->texture) + d3d9_texture_flag_auto_gen_mipmap(surface->texture); 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); + if (SUCCEEDED(hr) && surface->texture) + d3d9_texture_flag_auto_gen_mipmap(surface->texture); 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); - HeapFree(GetProcessHeap(), 0, surface); + heap_free(surface); } static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops = diff --git a/dll/directx/wine/d3d9/swapchain.c b/dll/directx/wine/d3d9/swapchain.c index 7b2dc7ea4fe..dbb3f45b91d 100644 --- a/dll/directx/wine/d3d9/swapchain.c +++ b/dll/directx/wine/d3d9/swapchain.c @@ -20,8 +20,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -134,7 +137,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai wined3d_mutex_lock(); hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, flags); + src_rect, dst_rect, dst_window_override, 0, flags); 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) { - HeapFree(GetProcessHeap(), 0, parent); + heap_free(parent); } 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; - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } diff --git a/dll/directx/wine/d3d9/texture.c b/dll/directx/wine/d3d9/texture.c index 16909d68884..c97fa6b0219 100644 --- a/dll/directx/wine/d3d9/texture.c +++ b/dll/directx/wine/d3d9/texture.c @@ -18,21 +18,97 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" #include "d3d9_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d9); + 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) { - 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) { - 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) @@ -87,21 +163,7 @@ static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface) 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; } @@ -232,6 +294,9 @@ static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *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(); @@ -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); - HRESULT hr; 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); - D3DTEXTUREFILTERTYPE ret; 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) { + struct d3d9_texture *texture = impl_from_IDirect3DTexture9(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) @@ -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); + 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; - 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; @@ -306,6 +386,12 @@ static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface, 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))) { @@ -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); + 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; @@ -348,6 +440,12 @@ static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT 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; @@ -463,23 +561,7 @@ static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface) 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; } @@ -610,6 +692,9 @@ static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *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(); @@ -621,35 +706,44 @@ static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTextur D3DTEXTUREFILTERTYPE filter_type) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - HRESULT hr; 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); - D3DTEXTUREFILTERTYPE ret; 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) { + struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(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) @@ -661,6 +755,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac 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) @@ -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->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; @@ -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); + 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) @@ -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); + 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))) @@ -750,6 +862,12 @@ static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface, 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))) @@ -861,16 +979,7 @@ static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface) 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; } @@ -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) { - struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - HRESULT hr; - 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) { - struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - D3DTEXTUREFILTERTYPE filter_type; - 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) @@ -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->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; @@ -1192,7 +1286,7 @@ static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent { 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 = @@ -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->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.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); 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; @@ -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 (!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, @@ -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->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.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); 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; @@ -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 (!levels) + if (usage & D3DUSAGE_AUTOGENMIPMAP) { - if (usage & D3DUSAGE_AUTOGENMIPMAP) - levels = 1; - else - levels = wined3d_log2i(edge_length) + 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(edge_length) + 1; 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->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.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); 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; - 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, diff --git a/dll/directx/wine/d3d9/vertexdeclaration.c b/dll/directx/wine/d3d9/vertexdeclaration.c index e9248be5ea4..5075309638f 100644 --- a/dll/directx/wine/d3d9/vertexdeclaration.c +++ b/dll/directx/wine/d3d9/vertexdeclaration.c @@ -19,8 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" #include "d3d9_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d9); + 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 */ - 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; @@ -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; - 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 = @@ -333,18 +336,18 @@ static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9 *d3d9_elem /* 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) { - 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); - HeapFree(GetProcessHeap(), 0, *wined3d_elements); + heap_free(*wined3d_elements); 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->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; } @@ -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(); - HeapFree(GetProcessHeap(), 0, wined3d_elements); + heap_free(wined3d_elements); 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; } @@ -416,15 +418,14 @@ HRESULT d3d9_vertex_declaration_create(struct d3d9_device *device, 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } diff --git a/dll/directx/wine/d3d9/volume.c b/dll/directx/wine/d3d9/volume.c index 5c6a068811e..f4c43bc589a 100644 --- a/dll/directx/wine/d3d9/volume.c +++ b/dll/directx/wine/d3d9/volume.c @@ -19,8 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.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); @@ -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->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; @@ -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), - 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(); @@ -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; + if (hr == E_INVALIDARG) + return D3DERR_INVALIDCALL; 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); - HeapFree(GetProcessHeap(), 0, volume); + heap_free(volume); } static const struct wined3d_parent_ops d3d9_volume_wined3d_parent_ops = diff --git a/dll/directx/wine/ddraw/CMakeLists.txt b/dll/directx/wine/ddraw/CMakeLists.txt index ed7801e4ceb..6141d630f3f 100644 --- a/dll/directx/wine/ddraw/CMakeLists.txt +++ b/dll/directx/wine/ddraw/CMakeLists.txt @@ -20,7 +20,7 @@ list(APPEND SOURCE utils.c vertexbuffer.c viewport.c - ddraw_private.h + precomp.h ${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) -add_pch(ddraw ddraw_private.h SOURCE) +add_pch(ddraw precomp.h SOURCE) add_cd_file(TARGET ddraw DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/ddraw/clipper.c b/dll/directx/wine/ddraw/clipper.c index f1fadd429a7..01cac40ec6e 100644 --- a/dll/directx/wine/ddraw/clipper.c +++ b/dll/directx/wine/ddraw/clipper.c @@ -19,8 +19,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.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); @@ -67,7 +72,7 @@ static ULONG WINAPI ddraw_clipper_Release(IDirectDrawClipper *iface) { if (clipper->region) DeleteObject(clipper->region); - HeapFree(GetProcessHeap(), 0, clipper); + heap_free(clipper); } return refcount; diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c index 2ab9edd015d..e5205c0d000 100644 --- a/dll/directx/wine/ddraw/ddraw.c +++ b/dll/directx/wine/ddraw/ddraw.c @@ -21,9 +21,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + #include "ddraw_private.h" -#include +#include "wine/exception.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); 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; + DWORD remove_caps; } 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, + 0, }, /* HAL device */ @@ -59,6 +66,7 @@ static struct enum_device_entry "WINE Direct3D7 Hardware acceleration using WineD3D", "Direct3D HAL", &IID_IDirect3DHALDevice, + 0, }, /* RGB device */ @@ -66,6 +74,7 @@ static struct enum_device_entry "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); } - HeapFree(GetProcessHeap(), 0, ddraw->decls); + heap_free(ddraw->decls); 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 */ - HeapFree(GetProcessHeap(), 0, This); + heap_free(This); } /***************************************************************************** @@ -595,8 +604,7 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, } 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; @@ -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_usage = WINED3DUSAGE_RENDERTARGET; 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; } +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 * @@ -1510,6 +1541,10 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD 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); @@ -1733,7 +1768,7 @@ static HRESULT WINAPI ddraw7_GetFourCCCodes(IDirectDraw7 *iface, DWORD *NumCodes 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]))) @@ -2057,7 +2092,14 @@ static HRESULT WINAPI d3d1_Initialize(IDirect3D *iface, REFIID riid) *****************************************************************************/ 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; } @@ -2384,13 +2426,13 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags, 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); - 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], @@ -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"); - HeapFree(GetProcessHeap(), 0, enum_modes); + heap_free(enum_modes); 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; - 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; } @@ -2475,7 +2515,7 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags, } TRACE("End of enumeration\n"); - HeapFree(GetProcessHeap(), 0, enum_modes); + heap_free(enum_modes); 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; - 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, @@ -3189,46 +3229,97 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags, { 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); - all = Flags & DDENUMSURFACES_ALL; - nomatch = Flags & DDENUMSURFACES_NOMATCH; - 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 (!surf->iface_count) + if (match_flags != DDENUMSURFACES_MATCH) + return DDERR_INVALIDPARAMS; + + 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; } - if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc))) + hr = IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL); + if (SUCCEEDED(hr)) { - 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 = 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(); + + /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ + LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list) + { + 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; } @@ -3313,8 +3404,7 @@ HRESULT WINAPI DirectDrawCreateClipper(DWORD flags, IDirectDrawClipper **clipper 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; @@ -3324,7 +3414,7 @@ HRESULT WINAPI DirectDrawCreateClipper(DWORD flags, IDirectDrawClipper **clipper if (FAILED(hr)) { WARN("Failed to initialize clipper, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); wined3d_mutex_unlock(); return hr; } @@ -3424,8 +3514,7 @@ static HRESULT WINAPI ddraw7_CreatePalette(IDirectDraw7 *iface, DWORD Flags, 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(); @@ -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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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; + DWORD dev_caps; HRESULT hr; size_t i; @@ -3642,11 +3732,15 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA 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; + 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) { @@ -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); - 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; @@ -3982,8 +4076,7 @@ static HRESULT WINAPI d3d3_CreateViewport(IDirect3D3 *iface, IDirect3DViewport3 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; @@ -4044,8 +4137,8 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd 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) @@ -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; - 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"); @@ -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(); - 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; } @@ -4161,7 +4270,7 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid, 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; } @@ -4187,7 +4296,7 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid, 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; } @@ -4357,7 +4466,7 @@ static HRESULT WINAPI d3d7_EnumZBufferFormats(IDirect3D7 *iface, REFCLSID device 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]))) @@ -4559,7 +4668,7 @@ static const struct IDirectDraw2Vtbl ddraw2_vtbl = ddraw2_GetAvailableVidMem, }; -static const struct IDirectDrawVtbl ddraw1_vtbl = +static struct IDirectDrawVtbl ddraw1_vtbl = { /* 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; - 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; @@ -4818,7 +4928,7 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent 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; diff --git a/dll/directx/wine/ddraw/ddraw_private.h b/dll/directx/wine/ddraw/ddraw_private.h index 04ee59c05f4..1454e8012a4 100644 --- a/dll/directx/wine/ddraw/ddraw_private.h +++ b/dll/directx/wine/ddraw/ddraw_private.h @@ -19,30 +19,25 @@ #ifndef __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H #define __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H -#include -#include - #include -#include - -#define _INC_WINDOWS -#define COM_NO_WINDOW_H - +#include #define COBJMACROS #define NONAMELESSSTRUCT #define NONAMELESSUNION +#include "wine/debug.h" +#include "wine/heap.h" -#include -#include -#include -#include -#include +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" -#include -#include -#include - -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])) @@ -64,13 +59,14 @@ struct FvfToDecl #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 \ - | WINED3D_LEGACY_CUBEMAP_FILTERING) + | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT) enum ddraw_device_state { @@ -309,6 +305,7 @@ struct d3d_device IUnknown IUnknown_inner; LONG ref; UINT version; + BOOL hw; IUnknown *outer_unknown; struct wined3d_device *wined3d_device; @@ -353,7 +350,7 @@ struct d3d_device 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; @@ -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; +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; diff --git a/dll/directx/wine/ddraw/device.c b/dll/directx/wine/ddraw/device.c index fe48ad3b36b..24dbd3be505 100644 --- a/dll/directx/wine/ddraw/device.c +++ b/dll/directx/wine/ddraw/device.c @@ -27,8 +27,12 @@ * */ +#include "config.h" +#include "wine/port.h" + #include "ddraw_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); 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 */ - HeapFree(GetProcessHeap(), 0, This); + heap_free(This); wined3d_mutex_unlock(); } @@ -659,8 +663,7 @@ static HRESULT WINAPI d3d_device1_CreateExecuteBuffer(IDirect3DDevice *iface, 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; @@ -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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } @@ -1083,7 +1086,7 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface, 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) @@ -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, @@ -1211,7 +1214,7 @@ static HRESULT WINAPI d3d_device2_EnumTextureFormats(IDirect3DDevice2 *iface, 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) @@ -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); - D3DMATRIX *Matrix; + D3DMATRIX *matrix; 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; - 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; @@ -1287,11 +1289,11 @@ static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIX 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"); - HeapFree(GetProcessHeap(), 0, Matrix); + heap_free(matrix); wined3d_mutex_unlock(); return DDERR_OUTOFMEMORY; } @@ -1442,7 +1444,7 @@ static HRESULT WINAPI d3d_device1_DeleteMatrix(IDirect3DDevice *iface, D3DMATRIX wined3d_mutex_unlock(); - HeapFree(GetProcessHeap(), 0, m); + heap_free(m); return D3D_OK; } @@ -1852,7 +1854,7 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface, 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(); @@ -1928,7 +1930,7 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, 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); @@ -1977,7 +1979,7 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, 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); @@ -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->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); - 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); + struct wined3d_buffer_desc desc; 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; } @@ -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, - 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); @@ -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); + struct wined3d_buffer_desc desc; 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; } @@ -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, - 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); @@ -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, - 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); @@ -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, - 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); @@ -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, - 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); @@ -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, - 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); @@ -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, - 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(); @@ -6887,7 +6903,7 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device 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 = @@ -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->hw = hw; 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; } -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; + BOOL hw = TRUE; 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)) @@ -6982,7 +7003,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUn 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; @@ -7002,17 +7023,16 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUn 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; } - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } diff --git a/dll/directx/wine/ddraw/executebuffer.c b/dll/directx/wine/ddraw/executebuffer.c index 7b68bd70b56..17bea2764c5 100644 --- a/dll/directx/wine/ddraw/executebuffer.c +++ b/dll/directx/wine/ddraw/executebuffer.c @@ -18,8 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + #include "ddraw_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + /***************************************************************************** * _dump_executedata * _dump_D3DEXECUTEBUFFERDESC @@ -119,13 +124,20 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, if (buffer->index_size < index_count) { - struct wined3d_buffer *new_buffer; unsigned int new_size = max(buffer->index_size * 2, index_count); + struct wined3d_buffer *new_buffer; + struct wined3d_buffer_desc desc; - 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)) + 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; @@ -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); - 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; @@ -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) - 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"); @@ -497,7 +511,7 @@ static ULONG WINAPI d3d_execute_buffer_Release(IDirect3DExecuteBuffer *iface) 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) @@ -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); } - HeapFree(GetProcessHeap(), 0, buffer); + heap_free(buffer); } 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; + 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; - 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; @@ -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); - 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, @@ -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; - 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; diff --git a/dll/directx/wine/ddraw/light.c b/dll/directx/wine/ddraw/light.c index d20c132c379..9d0bb6028f3 100644 --- a/dll/directx/wine/ddraw/light.c +++ b/dll/directx/wine/ddraw/light.c @@ -17,8 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + #include "ddraw_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + /***************************************************************************** * light_update * @@ -128,7 +133,7 @@ static ULONG WINAPI d3d_light_Release(IDirect3DLight *iface) if (!ref) { - HeapFree(GetProcessHeap(), 0, light); + heap_free(light); return 0; } return ref; diff --git a/dll/directx/wine/ddraw/main.c b/dll/directx/wine/ddraw/main.c index ea3cbbe42de..9c0a81ca18e 100644 --- a/dll/directx/wine/ddraw/main.c +++ b/dll/directx/wine/ddraw/main.c @@ -21,11 +21,17 @@ * 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 -#include +#include "rpcproxy.h" #include "wine/exception.h" +#include "winreg.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); 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) { - 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; @@ -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) { - HeapFree(GetProcessHeap(), 0, t->entries); + heap_free(t->entries); 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); - 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; @@ -292,8 +297,7 @@ DDRAW_Create(const GUID *guid, 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; @@ -303,7 +307,7 @@ DDRAW_Create(const GUID *guid, if (FAILED(hr)) { WARN("Failed to initialize ddraw object, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, ddraw); + heap_free(ddraw); 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) - HeapFree(GetProcessHeap(), 0, factory); + heap_free(factory); return ref; } @@ -736,20 +740,20 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **out) && !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 (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; } - 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; diff --git a/dll/directx/wine/ddraw/material.c b/dll/directx/wine/ddraw/material.c index 027a329407e..1fbf093e455 100644 --- a/dll/directx/wine/ddraw/material.c +++ b/dll/directx/wine/ddraw/material.c @@ -17,8 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + #include "ddraw_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + 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(); } - HeapFree(GetProcessHeap(), 0, material); + heap_free(material); } return ref; @@ -497,8 +502,7 @@ struct d3d_material *d3d_material_create(struct ddraw *ddraw) { 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; diff --git a/dll/directx/wine/ddraw/palette.c b/dll/directx/wine/ddraw/palette.c index 2f12138efa5..5148832cab6 100644 --- a/dll/directx/wine/ddraw/palette.c +++ b/dll/directx/wine/ddraw/palette.c @@ -16,8 +16,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + #include "ddraw_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + /***************************************************************************** * IDirectDrawPalette::QueryInterface * @@ -95,7 +100,7 @@ static ULONG WINAPI ddraw_palette_Release(IDirectDrawPalette *iface) IUnknown_Release(palette->ifaceToRelease); wined3d_mutex_unlock(); - HeapFree(GetProcessHeap(), 0, palette); + heap_free(palette); } return ref; diff --git a/dll/directx/wine/ddraw/precomp.h b/dll/directx/wine/ddraw/precomp.h new file mode 100644 index 00000000000..308faeaef6b --- /dev/null +++ b/dll/directx/wine/ddraw/precomp.h @@ -0,0 +1,15 @@ + +#ifndef _WINE_DDRAW_PRECOMP_H +#define _WINE_DDRAW_PRECOMP_H + +#include +#include + +#include + +#define _INC_WINDOWS +#define COM_NO_WINDOW_H + +#include "ddraw_private.h" + +#endif /* !_WINE_DDRAW_PRECOMP_H */ diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c index abae18ba6cb..5eefc228e64 100644 --- a/dll/directx/wine/ddraw/surface.c +++ b/dll/directx/wine/ddraw/surface.c @@ -21,8 +21,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.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); @@ -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) { + struct ddraw *ddraw = surface->ddraw; 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 (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; - 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); } @@ -203,7 +209,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, { 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; @@ -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), - 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(); @@ -1500,7 +1507,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons 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; @@ -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); - HeapFree(GetProcessHeap(), 0, clip_list); + heap_free(clip_list); 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; } @@ -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 - && 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(); @@ -5180,6 +5187,46 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface) 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 * @@ -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 wined3d_resource *dst_resource, *src_resource; + RECT src_rect, dst_rect; 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(); - 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 (;;) { - 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); - /* 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) + /* Get the palettes */ + dst_pal = dst_surface->palette; + src_pal = src_surface->palette; + + if (src_pal) { - wined3d_mutex_unlock(); - return DDERR_NOPALETTEATTACHED; + PALETTEENTRY palent[256]; + + 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); } - IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); - IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); - } - /* Copy one surface on the other */ - dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc); - src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc); - - 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; - - /* 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); } + } + 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; - } + /* Suppress the ALLOCONLOAD flag */ + dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; - 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; - } + 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); - 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); - - 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) @@ -5310,12 +5327,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu else dst_surface = NULL; + if (src_surface && !dst_surface) + return DDERR_NOTFOUND; + if (!src_surface || !dst_surface) - { - if (src_surface != dst_surface) - ERR("Loading surface with different mipmap structure.\n"); break; - } } wined3d_mutex_unlock(); @@ -5545,7 +5561,7 @@ static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = ddraw_surface2_PageUnlock, }; -static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = +static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = { /* 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); - HeapFree(GetProcessHeap(), 0, surface); + heap_free(surface); } 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); - HeapFree(GetProcessHeap(), 0, parent); + heap_free(parent); } 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 (!(texture = HeapAlloc(GetProcessHeap(), 0, sizeof(*texture)))) + if (!(texture = heap_alloc(sizeof(*texture)))) 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"); - 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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; - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - 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"); - 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); return DDERR_INVALIDPARAMS; } @@ -5969,7 +5985,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ if (!desc->dwWidth || !desc->dwHeight) { - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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.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; @@ -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) { - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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 { @@ -6108,7 +6142,8 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ 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; } @@ -6123,24 +6158,24 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); return DDERR_INVALIDPARAMS; } if (!desc->lpSurface) { WARN("NULL surface memory pointer specified.\n"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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"); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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); - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); 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) { - if (!(texture = HeapAlloc(GetProcessHeap(), 0, sizeof(*texture)))) + if (!(texture = heap_alloc(sizeof(*texture)))) { 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))) { - HeapFree(GetProcessHeap(), 0, texture); + heap_free(texture); hr = hr_ddraw_from_wined3d(hr); goto fail; } diff --git a/dll/directx/wine/ddraw/utils.c b/dll/directx/wine/ddraw/utils.c index 11d6cd4960b..65f24dc13fd 100644 --- a/dll/directx/wine/ddraw/utils.c +++ b/dll/directx/wine/ddraw/utils.c @@ -21,8 +21,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.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) @@ -556,6 +561,31 @@ enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *DDPix 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) @@ -738,8 +768,8 @@ void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in) 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 @@ -776,7 +806,7 @@ DDRAW_dump_pixelformat_flag(DWORD flagmask) 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) @@ -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, - 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(" - "); - 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(" - 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); diff --git a/dll/directx/wine/ddraw/vertexbuffer.c b/dll/directx/wine/ddraw/vertexbuffer.c index 155a8dd3ff8..3ad8f7e1bdd 100644 --- a/dll/directx/wine/ddraw/vertexbuffer.c +++ b/dll/directx/wine/ddraw/vertexbuffer.c @@ -17,8 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.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); @@ -97,7 +102,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface) if (buffer->version == 7) IDirectDraw7_Release(&buffer->ddraw->IDirectDraw7_iface); - HeapFree(GetProcessHeap(), 0, buffer); + heap_free(buffer); } 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) { - 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) - usage |= WINED3DUSAGE_WRITEONLY; + desc.usage |= WINED3DUSAGE_WRITEONLY; 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; - 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); - /* Writeonly: Pointless. Event: Unsupported by native according to the sdk - * nosyslock: Not applicable - */ 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) { - wined3d_flags |= WINED3D_MAP_DISCARD; - 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), - 0, &wined3d_map_desc, NULL, wined3d_flags); + 0, &wined3d_map_desc, NULL, wined3dmapflags_from_ddrawmapflags(flags)); *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); - 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; @@ -482,7 +478,7 @@ end: if (hr == D3D_OK) *vertex_buf = buffer; else - HeapFree(GetProcessHeap(), 0, buffer); + heap_free(buffer); return hr; } diff --git a/dll/directx/wine/ddraw/viewport.c b/dll/directx/wine/ddraw/viewport.c index a62cc319ec8..6ef3226c4d1 100644 --- a/dll/directx/wine/ddraw/viewport.c +++ b/dll/directx/wine/ddraw/viewport.c @@ -17,8 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + #include "ddraw_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + /***************************************************************************** * 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) - HeapFree(GetProcessHeap(), 0, viewport); + heap_free(viewport); 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); - 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) @@ -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); - 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) diff --git a/dll/directx/wine/wined3d/CMakeLists.txt b/dll/directx/wine/wined3d/CMakeLists.txt index 22fa8b0c40a..235adab9027 100644 --- a/dll/directx/wine/wined3d/CMakeLists.txt +++ b/dll/directx/wine/wined3d/CMakeLists.txt @@ -19,7 +19,6 @@ list(APPEND SOURCE cs.c device.c directx.c - drawprim.c dxtn.c gl_compat.c glsl_shader.c @@ -40,7 +39,7 @@ list(APPEND SOURCE vertexdeclaration.c view.c wined3d_main.c - wined3d_private.h) + precomp.h) 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) -add_pch(d3dwine wined3d_private.h SOURCE) +add_pch(d3dwine precomp.h SOURCE) add_cd_file(TARGET d3dwine DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/wined3d/arb_program_shader.c b/dll/directx/wine/wined3d/arb_program_shader.c index 00a260f21d1..f86c167b606 100644 --- a/dll/directx/wine/wined3d/arb_program_shader.c +++ b/dll/directx/wine/wined3d/arb_program_shader.c @@ -27,6 +27,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include + #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; - 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]; @@ -3884,7 +3889,7 @@ static void clone_sig(struct wined3d_shader_signature *new, const struct wined3d 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; } @@ -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; } - 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); @@ -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; - 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; @@ -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)); - } 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; } @@ -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; - 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) @@ -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)); - } 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; } @@ -4757,8 +4766,8 @@ static void shader_arb_destroy(struct wined3d_shader *shader) 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 @@ -4781,8 +4790,8 @@ static void shader_arb_destroy(struct wined3d_shader *shader) 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; } } @@ -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) { - 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; - 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"); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); 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); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); 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) { - 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. */ @@ -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); - HeapFree(GetProcessHeap(), 0, device->shader_priv); + heap_free(device->shader_priv); } 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) { - unsigned int i; - struct wined3d_shader_dst_param *dst_param; 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; - 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) { - 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; - 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) { - 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; @@ -5368,20 +5379,20 @@ static void record_instruction(struct list *list, const struct wined3d_shader_in 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) @@ -5394,18 +5405,18 @@ static void free_recorded_instruction(struct list *list) 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) { - 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); - HeapFree(GetProcessHeap(), 0, control_frame); + heap_free(control_frame); 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); - 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) { - 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; @@ -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(©); - 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 */ - 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) { - 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; @@ -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 */ - 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); @@ -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); - HeapFree(GetProcessHeap(), 0, control_frame); + heap_free(control_frame); 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; - 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); @@ -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)"); - HeapFree(GetProcessHeap(), 0, entry_arb); + heap_free(entry_arb); } /* 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) - { - 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) @@ -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) { - 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; @@ -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)"); - HeapFree(GetProcessHeap(), 0, entry_arb); + heap_free(entry_arb); } /* 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); - 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, @@ -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, - 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; @@ -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; + unsigned int level; 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; @@ -7642,8 +7654,7 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine return E_NOTIMPL; } - desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*desc)); - if (!desc) + if (!(desc = heap_alloc(sizeof(*desc)))) 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)"); - HeapFree(GetProcessHeap(), 0, desc); + heap_free(desc); 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)"); } -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; - 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) @@ -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: - 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"); @@ -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); - 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); @@ -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) { + 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; @@ -7795,9 +7808,8 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl 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, @@ -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)) { + 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 @@ -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; - 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 @@ -7865,10 +7879,10 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl 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_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); @@ -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 (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter)))) + if (!(blitter = heap_alloc(sizeof(*blitter)))) { ERR("Failed to allocate blitter.\n"); return; diff --git a/dll/directx/wine/wined3d/ati_fragment_shader.c b/dll/directx/wine/wined3d/ati_fragment_shader.c index bf36f937bf5..9d6837a2f22 100644 --- a/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include + #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) { - 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; @@ -1315,7 +1321,7 @@ static void *atifs_alloc(const struct wined3d_shader_backend_ops *shader_backend { 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); @@ -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)"); - HeapFree(GetProcessHeap(), 0, entry_ati); + heap_free(entry_ati); } /* 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); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); 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) { - 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; @@ -1362,7 +1369,7 @@ static BOOL atifs_alloc_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 = { diff --git a/dll/directx/wine/wined3d/buffer.c b/dll/directx/wine/wined3d/buffer.c index 0e8f5a3e015..cae7ef87885 100644 --- a/dll/directx/wine/wined3d/buffer.c +++ b/dll/directx/wine/wined3d/buffer.c @@ -22,6 +22,9 @@ * */ +#include "config.h" +#include "wine/port.h" + #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; - 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; } } @@ -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) { - HeapFree(GetProcessHeap(), 0, This->conversion_map); + heap_free(This->conversion_map); 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 (!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; } @@ -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; - if (!(data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size))) + if (!(data = heap_alloc(buffer->resource.size))) { 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); - HeapFree(GetProcessHeap(), 0, data); + heap_free(data); } 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); - HeapFree(GetProcessHeap(), 0, buffer->conversion_map); + heap_free(buffer->conversion_map); 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); - 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) @@ -1020,8 +1024,8 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI 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)) @@ -1031,7 +1035,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI 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 @@ -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); - 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) @@ -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); } +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) @@ -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_sub_resource_map_info, 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, - 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; @@ -1347,9 +1370,8 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device 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; @@ -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); - 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 @@ -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"); } - 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)) { @@ -1393,7 +1416,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device 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); @@ -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); - if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - FIXME("Ignoring access flags (pool).\n"); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } object->desc = *desc; @@ -1440,75 +1461,3 @@ HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct 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; -} diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c index bd0ae564fb7..8a8d952c3ff 100644 --- a/dll/directx/wine/wined3d/context.c +++ b/dll/directx/wine/wined3d/context.c @@ -1,6 +1,11 @@ /* * 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 * @@ -19,8 +24,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include +#ifdef HAVE_FLOAT_H +# include +#endif + #include "wined3d_private.h" +#ifdef __REACTOS__ +#include +#endif + 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); } - 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) { @@ -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); } + 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, @@ -200,7 +224,6 @@ static void context_attach_surface_fbo(struct wined3d_context *context, if (resource->object) { - 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[] = { - {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; + const char *tex_type_str; + unsigned int i; 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) { - 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); - if (face) + if (gl_info->gl_ops.ext.p_glGetTextureParameteriv) + { + 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_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 { - unsigned int i; - tex_type_str = NULL; + 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); } + 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); + if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_SAMPLES, &samples); + else + samples = 1; + + gl_info->gl_ops.gl.p_glBindTexture(tex_target, old_texture); } - 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); - 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) { @@ -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); } + + checkGLcall("dump FBO attachment"); } /* 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; - if (!FIXME_ON(d3d)) return; + if (!FIXME_ON(d3d)) + return; status = gl_info->fbo_ops.glCheckFramebufferStatus(target); if (status == GL_FRAMEBUFFER_COMPLETE) { - TRACE("FBO complete\n"); + TRACE("FBO complete.\n"); } 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) { @@ -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); - 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, - 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; @@ -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->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; - 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; - } 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, - 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; - 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); + + 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, - 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; - unsigned int object_count = gl_info->limits.buffers + 1; 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; - 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; - 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); @@ -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, - 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; @@ -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; - 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; - 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; } } @@ -536,33 +574,36 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb } --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, - 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) { + static const struct wined3d_rendertarget_info ds_null = {{0}}; 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_fbo_entry_key fbo_key; + unsigned int i, ds_level, rt_level; 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); - level = render_targets[0].sub_resource_idx % rt_texture->level_count; - ds_texture = depth_stencil->container; + 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, 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)) + 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"); - 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) @@ -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); - 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)) { + 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) { - struct wined3d_resource *resource; if ((resource = render_targets[i].resource)) { - unsigned int width, height; - const char *resource_type; - 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); - 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), - 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) { - 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); @@ -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; - unsigned int i; GLuint read_binding, draw_binding; + unsigned int i; 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); + 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) { @@ -718,8 +784,16 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ } 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); } } @@ -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) { - 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; @@ -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) { - UINT i; + unsigned int i, j; 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) { - UINT j; - 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"); } - 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) @@ -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); - HeapFree(GetProcessHeap(), 0, (void *)old->gl_info); - HeapFree(GetProcessHeap(), 0, old); + heap_free((void *)old->gl_info); + heap_free(old); } 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) { + 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)); - 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]) - 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]) - 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]) - 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]) - 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]) - 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]) - 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, @@ -1825,35 +1906,23 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, wined3d_from_cs(device->cs); - ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)); - if (!ret) + if (!(ret = heap_alloc_zero(sizeof(*ret)))) 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; - 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; - 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; - 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); @@ -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; @@ -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); - 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; } @@ -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 */ - 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; @@ -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); - 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); - if (destroy) HeapFree(GetProcessHeap(), 0, context); + if (destroy) + heap_free(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; - 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; - 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"); } @@ -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"); - 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); @@ -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; + GLenum draw_buffers[MAX_RENDER_TARGET_VIEWS]; 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)); - checkGLcall("glDrawBuffer()"); } else { @@ -2610,9 +2671,9 @@ static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt while (rt_mask) { if (rt_mask & 1) - context->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i; + draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i; else - context->draw_buffers[i] = GL_NONE; + draw_buffers[i] = GL_NONE; 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]) { - GL_EXTCALL(glDrawBuffers(i, context->draw_buffers)); - checkGLcall("glDrawBuffers()"); + GL_EXTCALL(glDrawBuffers(i, draw_buffers)); } 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 @@ -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"); } } + + checkGLcall("apply draw buffers"); } /* 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) { + 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]; @@ -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); - checkGLcall("glBindTexture"); } else { @@ -2688,40 +2749,45 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint if (old_texture_type != target) { - const struct wined3d_device *device = context->device; - 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; + case GL_TEXTURE_1D_ARRAY: + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array); + checkGLcall("glBindTexture"); + break; + case GL_TEXTURE_2D: + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d); + break; case GL_TEXTURE_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_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array); break; 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: - 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: - 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: - 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: - 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); @@ -2729,6 +2795,8 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint context->texture_type[unit] = target; } + + checkGLcall("bind texture"); } void *context_map_bo_address(struct wined3d_context *context, @@ -2796,8 +2864,8 @@ void context_copy_bo_address(struct wined3d_context *context, } 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); @@ -2918,8 +2986,6 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - context_validate_onscreen_formats(context, NULL); - 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); } -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; - if (ds) return TRUE; + if (ds) + return TRUE; 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; } - WARN("Invalid render target config, need at least one attachment.\n"); 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) { - 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; @@ -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 (!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; + } 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)) { - 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]) @@ -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) { - 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]; - DWORD rt_mask, rt_mask_bits; + DWORD rt_mask, mask; 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); + /* 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 &= 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; - 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); - - i++; } 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 color_location = 0; 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; - 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) { - 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), - 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. */ -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; @@ -3874,8 +3953,16 @@ BOOL context_apply_draw_state(struct wined3d_context *context, 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)) { @@ -3970,12 +4057,12 @@ BOOL context_apply_draw_state(struct wined3d_context *context, 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; - 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], @@ -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 (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)); @@ -4027,6 +4116,14 @@ void context_apply_compute_state(struct wined3d_context *context, 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; @@ -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) { @@ -4101,6 +4219,26 @@ static void context_setup_target(struct wined3d_context *context, 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) { @@ -4159,21 +4297,7 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, 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) - return context; - - if (context != current_context) - { - if (!context_set_current(context)) - ERR("Failed to activate the new context.\n"); - } - else if (context->needs_set) - { - context_set_gl_context(context); - } + context_activate(context, texture, sub_resource_idx); return context; } @@ -4181,14 +4305,844 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_context *context_reacquire(const struct wined3d_device *device, struct wined3d_context *context) { - struct wined3d_context *current_context; + struct wined3d_context *acquired_context; + + wined3d_from_cs(device->cs); if (!context || context->tid != GetCurrentThreadId()) return NULL; - 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; + if (context->current_rt.texture) + { + context_activate(context, context->current_rt.texture, context->current_rt.sub_resource_idx); + 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; + + 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 = ¶meters->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 = ¶meters->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); +} + +/* 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; + GLenum mode = state->gl_primitive_type; + const void *indices; + unsigned int i, j; + + 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; + } + + 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, ¶meters->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); } diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c index d264d1c9403..460fe12c7dc 100644 --- a/dll/directx/wine/wined3d/cs.c +++ b/dll/directx/wine/wined3d/cs.c @@ -16,6 +16,8 @@ * 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); @@ -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_BLEND_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; + DWORD swap_interval; DWORD flags; }; @@ -254,6 +258,12 @@ struct wined3d_cs_set_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; @@ -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; +#if defined(STAGING_CSMT) + BYTE copy_data[1]; +#endif /* STAGING_CSMT */ }; 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); + 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); @@ -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, - 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; @@ -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->swap_interval = swap_interval; 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) { - const struct wined3d_state *state = &cs->state; const struct wined3d_cs_clear *op = data; struct wined3d_device *device; unsigned int i; - RECT draw_rect; 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); @@ -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; + const struct wined3d_viewport *vp = &state->viewport; 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; - 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; @@ -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; - 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; @@ -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; - 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); } @@ -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_DEPTHBIASCLAMP)); } 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); } +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; @@ -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 = 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; @@ -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; + 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; - if (op->resource->type == WINED3D_RTYPE_BUFFER) - { - struct wined3d_buffer *buffer = buffer_from_resource(op->resource); + context = context_acquire(cs->device, NULL, 0); + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + 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"); - context_release(context); goto done; } wined3d_buffer_upload_data(buffer, context, box, op->data.data); wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER); - context_release(context); goto done; } - 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); @@ -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; - 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) @@ -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); - 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_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, @@ -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; +#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; @@ -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); +#if !defined(STAGING_CSMT) /* The data pointer may go away, so we need to wait until it is read. * Copying the data may be faster if it's small. */ +#endif /* STAGING_CSMT */ cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); } @@ -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); + wined3d_resource_release(view->resource); } 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); + wined3d_resource_acquire(uav->resource); 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_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, @@ -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, }; +#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)) @@ -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_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, new_size); + new_data = heap_realloc(cs->data, new_size); else - new_data = HeapAlloc(GetProcessHeap(), 0, new_size); + new_data = heap_alloc(new_size); 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) - HeapFree(GetProcessHeap(), 0, data); + heap_free(data); } 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 = { +#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, @@ -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); } +#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); @@ -2573,6 +2683,16 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size return packet->data; } +#if defined(STAGING_CSMT) +static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) +{ + if (cs->thread_id == GetCurrentThreadId()) + return wined3d_cs_st_check_space(cs, size, queue_id); + + return wined3d_cs_queue_check_space(&cs->queue[queue_id], size); +} + +#endif /* STAGING_CSMT */ static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { if (cs->thread_id == GetCurrentThreadId()) @@ -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 = { +#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, @@ -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; - 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; - 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; - if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) + if (!(cs->data = heap_alloc(cs->data_size))) 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"); - HeapFree(GetProcessHeap(), 0, cs->data); + heap_free(cs->data); 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); - HeapFree(GetProcessHeap(), 0, cs->data); + heap_free(cs->data); 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); - HeapFree(GetProcessHeap(), 0, cs->data); + heap_free(cs->data); goto fail; } } @@ -2761,8 +2878,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) fail: state_cleanup(&cs->state); - HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); - HeapFree(GetProcessHeap(), 0, cs); + heap_free(cs); return NULL; } @@ -2777,7 +2893,6 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) } 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); } diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c index fdc4f957af9..e2b27e0cf43 100644 --- a/dll/directx/wine/wined3d/device.c +++ b/dll/directx/wine/wined3d/device.c @@ -24,6 +24,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include +#ifdef HAVE_FLOAT_H +# include +#endif + #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); - 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; @@ -181,14 +185,13 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context 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)); - 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; @@ -197,10 +200,14 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context 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) @@ -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); - 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); @@ -273,23 +281,29 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c } else { + unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->container->level_count; + render_offscreen = TRUE; - drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil->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)) @@ -316,11 +330,6 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c 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); @@ -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); - 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; @@ -482,7 +489,7 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device) 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; } @@ -509,7 +516,7 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device) wined3d_decref(device->wined3d); device->wined3d = NULL; - HeapFree(GetProcessHeap(), 0, device); + heap_free(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.pool = WINED3D_POOL_DEFAULT; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; 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; + struct wined3d_dummy_textures *textures = &device->dummy_textures; 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); - 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); - checkGLcall("glTexImage2D"); 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); - checkGLcall("glTexImage2D"); } 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)); - checkGLcall("glTexImage3D"); } 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); - checkGLcall("glTexImage2D"); } } @@ -672,32 +666,29 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_ { 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)); - checkGLcall("glTexImage3D"); } 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)); - checkGLcall("glTexImage3D"); } 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)); - 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)); - checkGLcall("glTexBuffer"); - 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) { + struct wined3d_dummy_textures *dummy_textures = &device->dummy_textures; 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]) - 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]) - 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]) - 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]) - 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]) - 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]) - 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. */ @@ -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; - 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); } @@ -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}; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; 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->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. */ - 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; } @@ -1090,7 +1104,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, } 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; @@ -1103,7 +1117,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, 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]) @@ -1120,13 +1134,12 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, 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); - HeapFree(GetProcessHeap(), 0, device->fb.render_targets); return hr; } @@ -1150,7 +1163,7 @@ HRESULT CDECL wined3d_device_init_gdi(struct wined3d_device *device, } 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; @@ -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"); - HeapFree(GetProcessHeap(), 0, device->swapchains); + heap_free(device->swapchains); 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) { - UINT i; + unsigned int i; 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); +#if defined(STAGING_CSMT) + context_set_current(NULL); +#endif /* STAGING_CSMT */ 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"); } - HeapFree(GetProcessHeap(), 0, device->swapchains); + heap_free(device->swapchains); 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; @@ -1262,7 +1275,7 @@ HRESULT CDECL wined3d_device_uninit_gdi(struct wined3d_device *device) 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; @@ -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) { + /* const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; */ + TRACE("device %p.\n", device); + /* We can not acquire the context unless there is a swapchain. */ + /* + if (device->swapchains && gl_info->supported[NVX_GPU_MEMORY_INFO] && + !wined3d_settings.emulated_textureram) + { + GLint vram_free_kb; + UINT64 vram_free; + + struct wined3d_context *context = context_acquire(device, NULL, 0); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &vram_free_kb); + vram_free = (UINT64)vram_free_kb * 1024; + context_release(context); + + TRACE("Total 0x%s bytes. emulation 0x%s left, driver 0x%s left.\n", + wine_dbgstr_longlong(device->adapter->vram_bytes), + wine_dbgstr_longlong(device->adapter->vram_bytes - device->adapter->vram_bytes_used), + wine_dbgstr_longlong(vram_free)); + + vram_free = min(vram_free, device->adapter->vram_bytes - device->adapter->vram_bytes_used); + return min(UINT_MAX, vram_free); + } + */ + TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n", wine_dbgstr_longlong(device->adapter->vram_bytes), wine_dbgstr_longlong(device->adapter->vram_bytes_used), @@ -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"); - 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); @@ -1917,28 +1954,48 @@ void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, stru *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; - 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; - if (!(src_view = state->fb->depth_stencil)) return; - if (src_view->resource->type == WINED3D_RTYPE_BUFFER) - { - FIXME("Not supported on buffer resources.\n"); - 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); + 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; + + 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, @@ -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"); - 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; - 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; @@ -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; - 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; @@ -3419,7 +3476,7 @@ HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device, 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; @@ -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 hr; + 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); + + 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, @@ -3760,14 +3824,15 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, 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; } - 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; } @@ -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) { - static BOOL warned; - TRACE("device %p, software %#x.\n", device, software); - if (!warned) - { - FIXME("device %p, software %#x stub!\n", device, software); - warned = TRUE; - } - device->softwareVertexProcessing = software; } BOOL CDECL wined3d_device_get_software_vertex_processing(const struct wined3d_device *device) { - static BOOL warned; - TRACE("device %p.\n", device); - if (!warned) - { - TRACE("device %p stub!\n", device); - warned = TRUE; - } - return device->softwareVertexProcessing; } @@ -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); + 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); } @@ -4156,6 +4211,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev return WINED3DERR_INVALIDCALL; } +#if !defined(STAGING_CSMT) if (dst_texture->sub_resources[dst_sub_resource_idx].map_count) { WARN("Destination sub-resource %u is mapped.\n", dst_sub_resource_idx); @@ -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; +#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) @@ -4231,7 +4300,8 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str 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; @@ -4266,11 +4336,59 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str return; } +#if !defined(STAGING_CSMT) wined3d_resource_wait_idle(resource); +#endif /* STAGING_CSMT */ wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); } +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) @@ -4433,7 +4551,7 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined 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; @@ -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.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; @@ -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. */ - 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, - 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; @@ -4557,7 +4675,7 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device 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); @@ -4642,7 +4760,7 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) { 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); @@ -4687,12 +4805,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, 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); @@ -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); + 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; @@ -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.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; @@ -4995,6 +5118,7 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso switch (type) { + case WINED3D_RTYPE_TEXTURE_1D: case WINED3D_RTYPE_TEXTURE_2D: case WINED3D_RTYPE_TEXTURE_3D: for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) @@ -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) { - HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]); + heap_free(device->multistate_funcs[i]); } 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); } +#if defined(STAGING_CSMT) + +/* Context activation is done by the caller */ +struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, + GLenum type_hint, struct wined3d_context *context) +{ + struct wined3d_gl_bo *ret; + const struct wined3d_gl_info *gl_info; + + TRACE("device %p, size %u, gl_usage %u, type_hint %u\n", device, size, gl_usage, + type_hint); + + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)); + if(!ret) + return NULL; + ret->type_hint = type_hint; + ret->size = size; + ret->usage = gl_usage; + + gl_info = context->gl_info; + + GL_EXTCALL(glGenBuffers(1, &ret->name)); + if (type_hint == GL_ELEMENT_ARRAY_BUFFER) + context_invalidate_state(context, STATE_INDEXBUFFER); + GL_EXTCALL(glBindBuffer(type_hint, ret->name)); + GL_EXTCALL(glBufferData(type_hint, size, NULL, gl_usage)); + GL_EXTCALL(glBindBuffer(type_hint, 0)); + checkGLcall("Create buffer object"); + + TRACE("Successfully created and set up buffer %u\n", ret->name); + return ret; +} + +/* Context activation is done by the caller */ +static void wined3d_device_destroy_bo(struct wined3d_device *device, const struct wined3d_context *context, + struct wined3d_gl_bo *bo) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name); + + GL_EXTCALL(glDeleteBuffers(1, &bo->name)); + checkGLcall("glDeleteBuffers"); + + HeapFree(GetProcessHeap(), 0, bo); +} + +/* Context activation is done by the caller */ +void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, + const struct wined3d_context *context) +{ + TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name); + + wined3d_device_destroy_bo(device, context, bo); +} +#endif /* STAGING_CSMT */ diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c index 40262bbe598..d82a6713434 100644 --- a/dll/directx/wine/wined3d/directx.c +++ b/dll/directx/wine/wined3d/directx.c @@ -21,10 +21,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wined3d_private.h" -#include +#include "config.h" +#include "wine/port.h" -#include +#include + +#include "wined3d_private.h" +#include "wine/winternl.h" 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_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 }, @@ -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_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 }, @@ -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_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_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 }, @@ -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_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 }, @@ -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 }, - - /* 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[] = @@ -443,8 +449,8 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) 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) @@ -470,7 +476,7 @@ ULONG CDECL wined3d_decref(struct wined3d *wined3d) { wined3d_adapter_cleanup(&wined3d->adapters[i]); } - HeapFree(GetProcessHeap(), 0, wined3d); + heap_free(wined3d); } 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_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}, @@ -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)); } + 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) { @@ -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. */ +#ifdef __i386__ if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX) { TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX); driver_info->vram_bytes = LONG_MAX; } +#endif /* Try to obtain driver version information for the current Windows version. This fails in * some cases: @@ -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") + || 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") @@ -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 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 */ @@ -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) + /* GL_ARB_framebuffer_no_attachments */ + USE_GL_FUNC(glFramebufferParameteri) /* 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) + /* 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_multisample */ + USE_GL_FUNC(glTexStorage2DMultisample); + USE_GL_FUNC(glTexStorage3DMultisample); /* 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_polygon_offset_clamp */ + USE_GL_FUNC(glPolygonOffsetClampEXT) /* 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(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 @@ -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); - 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); } + 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]) @@ -3764,6 +3804,19 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) 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; @@ -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_TEXTURE_MULTISAMPLE, MAKEDWORD_VERSION(3, 2)}, {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_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_TEXTURE_STORAGE_MULTISAMPLE, MAKEDWORD_VERSION(4, 2)}, {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; } + 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); @@ -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); + 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. */ @@ -4614,11 +4681,11 @@ HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *w return E_FAIL; } - if (!(modes = wined3d_calloc(mode_count, sizeof(*modes)))) + if (!(modes = heap_calloc(mode_count, sizeof(*modes)))) 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; } @@ -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]))) { - HeapFree(GetProcessHeap(), 0, matching_modes); - HeapFree(GetProcessHeap(), 0, modes); + heap_free(matching_modes); + heap_free(modes); 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, ¤t_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; @@ -4687,8 +4754,8 @@ HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *w *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), @@ -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; - BOOL mipmap_autogen_supported; + BOOL mipmap_gen_supported = TRUE; 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; - 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; + 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 @@ -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; } - allowed_usage |= WINED3DUSAGE_AUTOGENMIPMAP - | WINED3DUSAGE_DYNAMIC + allowed_usage |= WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_SOFTWAREPROCESSING | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER + | WINED3DUSAGE_QUERY_GENMIPMAP | 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; + 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; @@ -5386,7 +5472,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad 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) @@ -5416,17 +5501,14 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad 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"); - return WINED3DOK_NOAUTOGEN; + return WINED3DOK_NOMIPGEN; } 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; - 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 | @@ -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->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; @@ -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; - 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, @@ -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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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)); - 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; @@ -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); - 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) { @@ -6547,6 +6631,18 @@ static DWORD get_max_gl_version(const struct wined3d_gl_info *gl_info, DWORD fla 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[] = @@ -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); + + 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) @@ -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); - HeapFree(GetProcessHeap(), 0, adapter->cfgs); + heap_free(adapter->cfgs); 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); - HeapFree(GetProcessHeap(), 0, adapter->cfgs); + heap_free(adapter->cfgs); return FALSE; } diff --git a/dll/directx/wine/wined3d/drawprim.c b/dll/directx/wine/wined3d/drawprim.c deleted file mode 100644 index fa6d5083273..00000000000 --- a/dll/directx/wine/wined3d/drawprim.c +++ /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, ¶meters->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 = ¶meters->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 = ¶meters->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); -} diff --git a/dll/directx/wine/wined3d/dxtn.c b/dll/directx/wine/wined3d/dxtn.c index 8c6f2c579bc..03e4b261f17 100644 --- a/dll/directx/wine/wined3d/dxtn.c +++ b/dll/directx/wine/wined3d/dxtn.c @@ -16,9 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" #include "wined3d_private.h" - -#include +#include "wine/library.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); diff --git a/dll/directx/wine/wined3d/gl_compat.c b/dll/directx/wine/wined3d/gl_compat.c index d4e36d9d0fc..7e6b5101bc4 100644 --- a/dll/directx/wine/wined3d/gl_compat.c +++ b/dll/directx/wine/wined3d/gl_compat.c @@ -18,6 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include +#ifdef HAVE_FLOAT_H +# include +#endif + #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(gl_compat); diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c index 3796865340d..4c879f9fc5e 100644 --- a/dll/directx/wine/wined3d/glsl_shader.c +++ b/dll/directx/wine/wined3d/glsl_shader.c @@ -29,6 +29,15 @@ * mask for the destination parameter into account. */ +#include "config.h" +#include "wine/port.h" + +#include +#include +#ifdef HAVE_FLOAT_H +# include +#endif + #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_shader_resource_type emulate_lod; }; 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 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 normal_matrix_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; - 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 @@ -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); } - 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)); - 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; @@ -535,13 +545,12 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf 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); - HeapFree(GetProcessHeap(), 0, shaders); + heap_free(shaders); return; } source_size = tmp; @@ -560,8 +569,8 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf FIXME("\n"); } - HeapFree(GetProcessHeap(), 0, source); - HeapFree(GetProcessHeap(), 0, shaders); + heap_free(source); + heap_free(shaders); } /* 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); - 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; } - if (!(strings = wined3d_calloc(length, sizeof(*strings)))) + if (!(strings = heap_calloc(length, sizeof(*strings)))) { ERR("Out of memory.\n"); - HeapFree(GetProcessHeap(), 0, varyings); + heap_free(varyings); 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"); - HeapFree(GetProcessHeap(), 0, varyings); - HeapFree(GetProcessHeap(), 0, strings); + heap_free(varyings); + heap_free(strings); 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)); } -/* 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) { @@ -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)); } +/* 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) @@ -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]; + float normal[3 * 3]; 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"); - 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; - 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 (!(update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i))) + continue; get_modelview_matrix(context, state, i, &mat); GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); checkGLcall("glUniformMatrix4fv"); + + get_normal_matrix(context, &mat, normal); + GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[i], 1, FALSE, normal)); + checkGLcall("glUniformMatrix3fv"); } } @@ -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) @@ -2568,6 +2284,13 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont sampler_type = "samplerCube"; break; + case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY: + if (shadow_sampler) + sampler_type = "sampler1DArrayShadow"; + else + sampler_type = "sampler1DArray"; + break; + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: if (shadow_sampler) sampler_type = "sampler2DArrayShadow"; @@ -2582,6 +2305,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont 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); @@ -2990,11 +2721,13 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; case WINED3DSPR_COLOROUT: + /* FIXME: should check dual_buffers when dual blending is enabled */ if (reg->idx[0].offset >= gl_info->limits.buffers) WARN("Write to render target %u, only %d supported.\n", reg->idx[0].offset, gl_info->limits.buffers); - sprintf(register_name, "%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: @@ -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; + 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 @@ -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; + sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE; 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 (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"; @@ -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->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, @@ -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, ...) { + 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; @@ -3762,6 +3521,26 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ break; } } + if (sample_function->emulate_lod) + { + if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod level %s\n", bias); + switch (sample_function->emulate_lod) + { + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: + if (!dx) dx = "vec2(0.0, 0.0)"; + if (!dy) dy = "vec2(0.0, 0.0)"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + if (!dx) dx = "vec3(0.0, 0.0, 0.0)"; + if (!dy) dy = "vec3(0.0, 0.0, 0.0)"; + break; + + default: + break; + } + if (!offset) offset = &dummy_offset; + } if (dx && dy) shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy); else if (bias) @@ -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); } +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; + 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; + BOOL supports_mipmaps; 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); - 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); @@ -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); - 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) - shader_addline(ins->ctx->buffer, "uvec4("); + shader_addline(buffer, "uvec4("); else - shader_addline(ins->ctx->buffer, "vec4("); + shader_addline(buffer, "vec4("); 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); + } - for (i = 0; i < 3 - resource_type_info[resource_type].resinfo_size; ++i) - shader_addline(ins->ctx->buffer, "0, "); + 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(buffer, "0, "); + + if (supports_mipmaps) + { 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 { - 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 { - 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; + struct glsl_src_param coord_param, lod_param, sample_param; 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; @@ -5979,15 +5776,24 @@ static void shader_glsl_ld(const struct wined3d_shader_instruction *ins) 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(®_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); } @@ -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); - HeapFree(GetProcessHeap(), 0, entry); + heap_free(entry); } 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]; - set = wined3d_calloc(max_varyings, sizeof(*set)); + set = heap_calloc(max_varyings, sizeof(*set)); 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); } - HeapFree(GetProcessHeap(), 0, set); + heap_free(set); 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) { - 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, "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) { - const char *output = get_fragment_output(gl_info); + const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; switch (mode) { @@ -7382,13 +7188,15 @@ static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, 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) { + 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[] = @@ -7407,8 +7215,8 @@ static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer 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"); } @@ -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 char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */ if (reg_maps->shader_version.major < 2) - shader_addline(buffer, "%s[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); @@ -7645,9 +7454,24 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context 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) @@ -8249,8 +8073,7 @@ static GLuint find_glsl_pshader(const struct wined3d_context *context, 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; @@ -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); - 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); - 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 { - new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders)); + new_array = heap_alloc(sizeof(*gl_shaders)); new_size = 1; } @@ -8341,8 +8164,7 @@ static GLuint find_glsl_vshader(const struct wined3d_context *context, struct sh 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; @@ -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); - 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); - 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 { - new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders)); + new_array = heap_alloc(sizeof(*gl_shaders)); 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 = 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; @@ -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); - new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array)); new_size = 1; - if (!new_array) + if (!(new_array = heap_alloc(sizeof(*new_array)))) { 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 = 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; @@ -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; - 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 { - new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array)); + new_array = heap_alloc(sizeof(*new_array)); 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 = 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; @@ -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; - 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 { - new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array)); + new_array = heap_alloc(sizeof(*new_array)); 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 */ - /* 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 */ @@ -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; + char var[64]; 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, "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 mat3 ffp_normal_matrix;\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 { - 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) @@ -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) { - 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 { - 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) @@ -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) { + 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; @@ -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) "); - shader_addline(buffer, "out vec4 ps_out[1];\n"); + shader_addline(buffer, "out vec4 ps_out0;\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); @@ -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 (!(shader = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader)))) + if (!(shader = heap_alloc(sizeof(*shader)))) 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 (!(glsl_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*glsl_desc)))) + if (!(glsl_desc = heap_alloc(sizeof(*glsl_desc)))) 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")); - 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)); } + for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i) + { + string_buffer_sprintf(name, "ffp_normal_matrix[%u]", i); + vs->normal_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + } vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix")); - vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix")); for (i = 0; i < MAX_TEXTURES; ++i) { string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i); @@ -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; - if (!(entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)))) + if (!(entry = heap_alloc(sizeof(*entry)))) { 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"); - HeapFree(GetProcessHeap(), 0, entry); + heap_free(entry); 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"); - 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; } @@ -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; - struct list *ps_list, *vs_list; + struct list *ps_list = NULL, *vs_list = NULL; 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 */ - 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; @@ -10203,8 +10039,26 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const 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; - 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) { @@ -10566,7 +10420,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) if (!shader_data || !shader_data->num_gl_shaders) { - HeapFree(GetProcessHeap(), 0, shader_data); + heap_free(shader_data); 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"); } - 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) @@ -10615,7 +10469,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) 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) @@ -10637,7 +10491,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) 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) @@ -10659,7 +10513,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) 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) @@ -10681,7 +10535,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) 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) @@ -10703,7 +10557,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) 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) @@ -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); @@ -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); - void *mem = HeapAlloc(GetProcessHeap(), 0, size); + void *mem; - if (!mem) + if (!(mem = heap_alloc(size))) { 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) { - 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) { - 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; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; 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"); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); 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); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); return E_FAIL; } @@ -10814,7 +10671,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win 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; @@ -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); - 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); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); 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); - 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); - 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; - 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; @@ -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) { - HeapFree(GetProcessHeap(), 0, context->shader_backend_data); + heap_free(context->shader_backend_data); } 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_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, @@ -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->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 @@ -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); - HeapFree(GetProcessHeap(), 0, shader); + heap_free(shader); } /* 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) { - 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) @@ -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(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 }, @@ -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); - HeapFree(GetProcessHeap(), 0, shader); + heap_free(shader); } /* Context activation is done by the caller. */ diff --git a/dll/directx/wine/wined3d/nvidia_texture_shader.c b/dll/directx/wine/wined3d/nvidia_texture_shader.c index 1033ec885e9..0baa414e57d 100644 --- a/dll/directx/wine/wined3d/nvidia_texture_shader.c +++ b/dll/directx/wine/wined3d/nvidia_texture_shader.c @@ -19,6 +19,10 @@ * 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 #include "wined3d_private.h" diff --git a/dll/directx/wine/wined3d/palette.c b/dll/directx/wine/wined3d/palette.c index f24f8836930..67308093c95 100644 --- a/dll/directx/wine/wined3d/palette.c +++ b/dll/directx/wine/wined3d/palette.c @@ -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 */ - +#include "config.h" +#include "wine/port.h" #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) { - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); } 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } diff --git a/dll/directx/wine/wined3d/precomp.h b/dll/directx/wine/wined3d/precomp.h new file mode 100644 index 00000000000..4443eecd341 --- /dev/null +++ b/dll/directx/wine/wined3d/precomp.h @@ -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 +#include + +#ifdef HAVE_FLOAT_H +# include +#endif + +#include + +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include "wined3d_private.h" + +#include + +#endif /* !__WINE_WINED3D_PRECOMP_H */ diff --git a/dll/directx/wine/wined3d/query.c b/dll/directx/wine/wined3d/query.c index fe175d1a6dd..5ea79b6e4a7 100644 --- a/dll/directx/wine/wined3d/query.c +++ b/dll/directx/wine/wined3d/query.c @@ -19,6 +19,8 @@ */ +#include "config.h" +#include "wine/port.h" #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); - HeapFree(GetProcessHeap(), 0, fence); + heap_free(fence); } 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); - 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))) { - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } @@ -911,12 +913,40 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD return poll; } +static BOOL wined3d_statistics_query_ops_poll(struct wined3d_query *query, DWORD flags) +{ + TRACE("query %p, flags %#x.\n", query, flags); + + return TRUE; +} + +static BOOL wined3d_statistics_query_ops_issue(struct wined3d_query *query, DWORD flags) +{ + FIXME("query %p, flags %#x.\n", query, flags); + + return FALSE; +} + +static BOOL wined3d_overflow_query_ops_poll(struct wined3d_query *query, DWORD flags) +{ + TRACE("query %p, flags %#x.\n", query, flags); + + return TRUE; +} + +static BOOL wined3d_overflow_query_ops_issue(struct wined3d_query *query, DWORD flags) +{ + FIXME("query %p, flags %#x.\n", query, flags); + + return FALSE; +} + static void wined3d_event_query_ops_destroy(struct wined3d_query *query) { struct wined3d_event_query *event_query = wined3d_event_query_from_query(query); wined3d_fence_free(&event_query->fence); - HeapFree(GetProcessHeap(), 0, event_query); + heap_free(event_query); } 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); - 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"); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - HeapFree(GetProcessHeap(), 0, oq); + heap_free(oq); } 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; } - 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, @@ -1006,7 +1036,7 @@ static void wined3d_timestamp_query_ops_destroy(struct wined3d_query *query) if (tq->context) context_free_timestamp_query(tq); - HeapFree(GetProcessHeap(), 0, tq); + heap_free(tq); } 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; } - 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, @@ -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) { - HeapFree(GetProcessHeap(), 0, query); + heap_free(query); } 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; } - 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) @@ -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); - HeapFree(GetProcessHeap(), 0, pq); + heap_free(pq); } 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; } - 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, @@ -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); - HeapFree(GetProcessHeap(), 0, pq); + heap_free(pq); } 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; } - 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, @@ -1195,6 +1225,72 @@ static HRESULT wined3d_pipeline_query_create(struct wined3d_device *device, return WINED3D_OK; } +static void wined3d_statistics_query_ops_destroy(struct wined3d_query *query) +{ + HeapFree(GetProcessHeap(), 0, query); +} + +static const struct wined3d_query_ops statistics_query_ops = +{ + wined3d_statistics_query_ops_poll, + wined3d_statistics_query_ops_issue, + wined3d_statistics_query_ops_destroy, +}; + +static HRESULT wined3d_statistics_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) +{ + static const struct wined3d_query_data_so_statistics statistics = { 1, 1 }; + struct wined3d_query *object; + + FIXME("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_query_init(object, device, type, &statistics, + sizeof(statistics), &statistics_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = object; + + return WINED3D_OK; +} + +static void wined3d_overflow_query_ops_destroy(struct wined3d_query *query) +{ + HeapFree(GetProcessHeap(), 0, query); +} + +static const struct wined3d_query_ops overflow_query_ops = +{ + wined3d_overflow_query_ops_poll, + wined3d_overflow_query_ops_issue, + wined3d_overflow_query_ops_destroy, +}; + +static HRESULT wined3d_overflow_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) +{ + static const BOOL overflow = FALSE; + struct wined3d_query *object; + + FIXME("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_query_init(object, device, type, &overflow, + sizeof(overflow), &overflow_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = object; + + return WINED3D_OK; +} + HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) { @@ -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_SO_STATISTICS: + return wined3d_statistics_query_create(device, type, parent, parent_ops, query); + + case WINED3D_QUERY_TYPE_SO_OVERFLOW: + return wined3d_overflow_query_create(device, type, parent, parent_ops, query); + default: FIXME("Unhandled query type %#x.\n", type); return WINED3DERR_NOTAVAILABLE; diff --git a/dll/directx/wine/wined3d/resource.c b/dll/directx/wine/wined3d/resource.c index 0788146106e..8b7f17bb6bd 100644 --- a/dll/directx/wine/wined3d/resource.c +++ b/dll/directx/wine/wined3d/resource.c @@ -21,40 +21,22 @@ * 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); -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 const DWORD handled = WINED3DUSAGE_RENDERTARGET + static DWORD handled = WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC - | WINED3DUSAGE_AUTOGENMIPMAP | WINED3DUSAGE_STATICDECL | WINED3DUSAGE_OVERLAY + | WINED3DUSAGE_SCRATCH | WINED3DUSAGE_PRIVATE | WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; @@ -66,16 +48,19 @@ static void resource_check_usage(DWORD usage) * driver. */ if (usage & ~handled) + { FIXME("Unhandled usage flags %#x.\n", usage & ~handled); + handled |= usage; + } if ((usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY)) == WINED3DUSAGE_DYNAMIC) WARN_(d3d_perf)("WINED3DUSAGE_DYNAMIC used without WINED3DUSAGE_WRITEONLY.\n"); } 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; @@ -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}, + {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}, @@ -102,6 +88,13 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * 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 @@ -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; } - else if (pool == WINED3D_POOL_SCRATCH) + else if (usage & WINED3DUSAGE_SCRATCH) { /* 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->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; @@ -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 (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)) { @@ -252,7 +242,7 @@ void resource_cleanup(struct wined3d_resource *resource) 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); @@ -274,7 +264,7 @@ DWORD CDECL wined3d_resource_set_priority(struct wined3d_resource *resource, DWO { 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; @@ -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->pool = resource->pool; + desc->access = resource->access; 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. */ - if (flags & WINED3D_MAP_READONLY) + if (flags & WINED3D_MAP_READ) { 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) { - 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)) @@ -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"); - return 0; + return flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE); } 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); + 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); } +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); @@ -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); } +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); @@ -381,7 +490,7 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) 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; @@ -399,7 +508,7 @@ void wined3d_resource_free_sysmem(struct wined3d_resource *resource) if (!p) return; - HeapFree(GetProcessHeap(), 0, *(--p)); + heap_free(*(--p)); resource->heap_memory = NULL; } @@ -407,9 +516,9 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) { 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; - 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) @@ -422,11 +531,17 @@ GLbitfield wined3d_resource_gl_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) @@ -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) + { resource->draw_binding = WINED3D_LOCATION_DRAWABLE; + } 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) + { resource->draw_binding = WINED3D_LOCATION_RB_RESOLVED; + } else + { resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB; + } } diff --git a/dll/directx/wine/wined3d/sampler.c b/dll/directx/wine/wined3d/sampler.c index 1c5f6779fc6..82fbe2c3be7 100644 --- a/dll/directx/wine/wined3d/sampler.c +++ b/dll/directx/wine/wined3d/sampler.c @@ -17,6 +17,9 @@ * */ +#include "config.h" +#include "wine/port.h" + #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); @@ -44,7 +47,7 @@ static void wined3d_sampler_destroy_object(void *object) context_release(context); } - HeapFree(GetProcessHeap(), 0, sampler); + heap_free(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; - 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); diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c index a42f35da6eb..0513c9e2053 100644 --- a/dll/directx/wine/wined3d/shader.c +++ b/dll/directx/wine/wined3d/shader.c @@ -22,6 +22,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include +#include + #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; - 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; @@ -434,7 +440,7 @@ BOOL string_buffer_init(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) @@ -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; - 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'; @@ -492,11 +498,11 @@ struct wined3d_string_buffer *string_buffer_get(struct wined3d_string_buffer_lis 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"); - HeapFree(GetProcessHeap(), 0, buffer); + heap_free(buffer); 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); - HeapFree(GetProcessHeap(), 0, buffer); + heap_free(buffer); } 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) - HeapFree(GetProcessHeap(), 0, constant); + heap_free(constant); list_init(clist); } @@ -820,7 +826,7 @@ static void shader_record_sample(struct wined3d_shader_reg_maps *reg_maps, 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; @@ -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 - || !(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; @@ -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"); - 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; @@ -952,27 +957,19 @@ static HRESULT shader_record_shader_phase(struct wined3d_shader *shader, } 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) { + *mask = 0; 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; } @@ -1013,7 +1010,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st 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"); @@ -1158,7 +1155,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st { 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; @@ -1338,9 +1335,11 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st } else if (ins.handler_idx == WINED3DSIH_DEF) { - struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst)); + struct wined3d_shader_lconst *lconst; 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)); @@ -1369,8 +1368,10 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st } 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)); @@ -1380,8 +1381,10 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st } 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)); @@ -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 + || 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)) { @@ -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; - 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; @@ -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]; - DWORD mask; + unsigned int mask; 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; - 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; @@ -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; - 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, ®_maps->indexable_temps, struct wined3d_shader_indexable_temp, entry) - HeapFree(GetProcessHeap(), 0, reg); + heap_free(reg); list_init(®_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) @@ -3085,22 +3089,22 @@ static void shader_cleanup(struct wined3d_shader *shader) { 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) { - 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); - 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); @@ -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; - 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"); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); 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); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); 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); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); } 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); } 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) { - struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst)); + struct wined3d_shader_lconst *lconst; float *value; - if (!lconst) + + if (!(lconst = heap_alloc(sizeof(*lconst)))) 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; - 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) @@ -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; - 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))) { - 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))) { - 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))) { - 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; } @@ -3663,7 +3668,7 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device 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; @@ -3721,12 +3726,12 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3 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))) { - HeapFree(GetProcessHeap(), 0, elements); + heap_free(elements); 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->dual_source_blend = wined3d_dualblend_enabled(state, gl_info); } 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } diff --git a/dll/directx/wine/wined3d/shader_sm1.c b/dll/directx/wine/wined3d/shader_sm1.c index 983de5875f1..0c6bb933174 100644 --- a/dll/directx/wine/wined3d/shader_sm1.c +++ b/dll/directx/wine/wined3d/shader_sm1.c @@ -22,6 +22,9 @@ * 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); @@ -546,7 +549,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size, return NULL; } - if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)))) + if (!(priv = heap_alloc(sizeof(*priv)))) 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); - HeapFree(GetProcessHeap(), 0, priv); + heap_free(priv); 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) { - HeapFree(GetProcessHeap(), 0, data); + heap_free(data); } static void shader_sm1_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version) diff --git a/dll/directx/wine/wined3d/shader_sm4.c b/dll/directx/wine/wined3d/shader_sm4.c index a6ece5e1ea2..8eac746ac50 100644 --- a/dll/directx/wine/wined3d/shader_sm4.c +++ b/dll/directx/wine/wined3d/shader_sm4.c @@ -16,6 +16,9 @@ * 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); @@ -1239,7 +1242,7 @@ static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size, return NULL; } - if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)))) + if (!(priv = heap_alloc(sizeof(*priv)))) { 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) { - 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) @@ -1325,7 +1328,7 @@ static struct wined3d_shader_src_param *get_src_param(struct wined3d_sm4_data *p } else { - if (!(e = HeapAlloc(GetProcessHeap(), 0, sizeof(*e)))) + if (!(e = heap_alloc(sizeof(*e)))) return NULL; elem = &e->entry; } diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c index bbb23d598e2..2f506c36d16 100644 --- a/dll/directx/wine/wined3d/state.c +++ b/dll/directx/wine/wined3d/state.c @@ -25,11 +25,80 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include +#ifdef HAVE_FLOAT_H +# include +#endif + #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); @@ -41,7 +110,7 @@ ULONG CDECL wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *sta 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) @@ -73,9 +142,10 @@ HRESULT CDECL wined3d_rasterizer_state_create(struct wined3d_device *device, { 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; @@ -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; + BOOL enable_dual_blend; 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. @@ -479,6 +551,13 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st 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); @@ -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)"); + 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); @@ -545,6 +625,28 @@ static void state_blendfactor(struct wined3d_context *context, const struct wine 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; @@ -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]; - 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", @@ -1480,13 +1579,7 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined 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) @@ -1499,24 +1592,20 @@ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DW 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) @@ -1690,10 +1779,11 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 { 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]; + bias_clamp.d = state->render_states[WINED3D_RS_DEPTHBIASCLAMP]; 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_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 { @@ -1730,6 +1831,28 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 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]) @@ -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_gl_info *gl_info = context->gl_info; - struct wined3d_viewport vp = state->viewport; unsigned int width, height; - float y; + + *viewport = state->viewport; 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) { - width = depth_stencil->width; height = depth_stencil->height; } else { - FIXME("No attachments draw calls not supported.\n"); + FIXME("Could not get the height of render targets.\n"); 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); - 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]) - GL_EXTCALL(glViewportIndexedf(0, vp.x, y, vp.width, vp.height)); + GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height)); 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) { - 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; - 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); - 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"); } @@ -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_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 }, @@ -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_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, 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_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_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_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_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 }, @@ -5965,6 +6087,7 @@ static void validate_state_table(struct StateEntry *state_table) STATE_FRAMEBUFFER, STATE_POINT_ENABLE, STATE_COLOR_KEY, + STATE_BLEND, }; 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; - 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]; @@ -6084,13 +6207,9 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ 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; - } 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: - 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)); diff --git a/dll/directx/wine/wined3d/stateblock.c b/dll/directx/wine/wined3d/stateblock.c index 4e1006cf892..c9b3527d891 100644 --- a/dll/directx/wine/wined3d/stateblock.c +++ b/dll/directx/wine/wined3d/stateblock.c @@ -22,6 +22,8 @@ * 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); @@ -43,6 +45,10 @@ static const DWORD pixel_states_render[] = 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, @@ -88,6 +94,7 @@ static const DWORD pixel_states_render[] = WINED3D_RS_ZENABLE, WINED3D_RS_ZFUNC, WINED3D_RS_ZWRITEENABLE, + WINED3D_RS_DEPTHCLIP, }; 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) { - 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); @@ -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); - 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); - HeapFree(GetProcessHeap(), 0, stateblock); + heap_free(stateblock); } 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; - 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; @@ -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_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; + 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; @@ -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; + 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) @@ -1370,15 +1378,14 @@ HRESULT CDECL wined3d_stateblock_create(struct wined3d_device *device, 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c index e4037abee00..ae32235a9e6 100644 --- a/dll/directx/wine/wined3d/surface.c +++ b/dll/directx/wine/wined3d/surface.c @@ -26,6 +26,8 @@ * 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); @@ -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; } -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; + 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) { @@ -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. */ -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; - struct wined3d_texture *texture = src_surface->container; 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)"); @@ -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; } -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; - 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; - 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; @@ -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); - 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); @@ -348,6 +357,15 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, 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, @@ -365,6 +383,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, 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", @@ -390,7 +409,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, } /* 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))) @@ -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); - 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); @@ -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_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)); @@ -482,25 +499,28 @@ static void surface_blt_fbo(const struct wined3d_device *device, 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 (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) - || (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) - || (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))) @@ -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 level; + GLenum target; 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]; + 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) { @@ -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"); - 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; @@ -583,12 +607,12 @@ static void surface_download_data(struct wined3d_surface *surface, const struct 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_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); - if (!(temporary_mem = HeapAlloc(GetProcessHeap(), 0, src_slice_pitch))) + if (!(temporary_mem = heap_alloc(src_slice_pitch))) { 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; - 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_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); - if (!(temporary_mem = HeapAlloc(GetProcessHeap(), 0, src_slice_pitch))) + if (!(temporary_mem = heap_alloc(src_slice_pitch))) { 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", - 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", - 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, - 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) { @@ -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); - 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); @@ -726,7 +749,8 @@ static void surface_download_data(struct wined3d_surface *surface, const struct } 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)); @@ -746,7 +770,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct checkGLcall("glBindBuffer"); } - HeapFree(GetProcessHeap(), 0, temporary_mem); + heap_free(temporary_mem); } /* 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; + 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, @@ -783,6 +809,10 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w 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; @@ -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", - 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 (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 { - 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 @@ -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) { - 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 { - 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; @@ -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", - 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); - 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 { - 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"); @@ -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; + unsigned int src_level, dst_level; 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; - 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); + 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_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)); @@ -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) { - 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; + const struct wined3d_texture *texture; + const struct wined3d_gl_info *gl_info; unsigned int src_width, src_height; - unsigned int width, height; 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) { - 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; } - 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 { - 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; @@ -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, - 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; @@ -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; @@ -1271,6 +1426,33 @@ static const struct d3dfmt_converter_desc converters[] = {WINED3DFMT_YUY2, WINED3DFMT_B5G6R5_UNORM, convert_yuy2_r5g6b5}, }; +static const struct d3dfmt_converter_desc dxtn_converters[] = +{ + /* decode DXT */ + {WINED3DFMT_DXT1, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt1_a8r8g8b8}, + {WINED3DFMT_DXT1, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt1_x8r8g8b8}, + {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt1_a4r4g4b4}, + {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt1_x4r4g4b4}, + {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5A1_UNORM, convert_dxt1_a1r5g5b5}, + {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5X1_UNORM, convert_dxt1_x1r5g5b5}, + {WINED3DFMT_DXT3, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt3_a8r8g8b8}, + {WINED3DFMT_DXT3, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt3_x8r8g8b8}, + {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt3_a4r4g4b4}, + {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt3_x4r4g4b4}, + {WINED3DFMT_DXT5, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt5_a8r8g8b8}, + {WINED3DFMT_DXT5, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt5_x8r8g8b8}, + + /* encode DXT */ + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT1, convert_a8r8g8b8_dxt1}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT1, convert_x8r8g8b8_dxt1}, + {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_DXT1, convert_a1r5g5b5_dxt1}, + {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_DXT1, convert_x1r5g5b5_dxt1}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT3, convert_a8r8g8b8_dxt3}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT3, convert_x8r8g8b8_dxt3}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT5, convert_a8r8g8b8_dxt5}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT5, convert_x8r8g8b8_dxt5} +}; + static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from, enum wined3d_format_id to) { @@ -1282,6 +1464,12 @@ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_fo return &converters[i]; } + for (i = 0; i < (sizeof(dxtn_converters) / sizeof(*dxtn_converters)); ++i) + { + if (dxtn_converters[i].from == from && dxtn_converters[i].to == to) + return wined3d_dxtn_supported() ? &dxtn_converters[i] : NULL; + } + return NULL; } @@ -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.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; @@ -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, - 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_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); @@ -1388,21 +1576,21 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr } 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; - const struct wined3d_gl_info *gl_info; 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 width, height; - BYTE *mem; - BYTE *row, *top, *bottom; - int i; - BOOL srcIsUpsideDown; + unsigned int width, height, level; 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); @@ -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_apply_blit_state(context, device); 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. - * 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)); - srcIsUpsideDown = TRUE; + src_is_upside_down = TRUE; } 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); - checkGLcall("glReadBuffer"); - srcIsUpsideDown = FALSE; + src_is_upside_down = FALSE; } + checkGLcall("glReadBuffer"); if (data.buffer_object) { @@ -1443,14 +1640,15 @@ static void read_from_framebuffer(struct wined3d_surface *surface, 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"); - 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); @@ -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"); - 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. */ - if (!(row = HeapAlloc(GetProcessHeap(), 0, row_pitch))) + if (!(row = heap_alloc(row_pitch))) 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; } - HeapFree(GetProcessHeap(), 0, row); + heap_free(row); 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) { + 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; + unsigned int level; + GLenum target; 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; @@ -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_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) @@ -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; + 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; - 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 @@ -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"); } - 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. */ - 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); @@ -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) { - 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 { - 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); } @@ -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) { + 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_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; + 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; - GLenum texture_target; 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; @@ -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); - 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; @@ -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 */ - 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)"); @@ -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"); - 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_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 */ @@ -1890,13 +2103,13 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st } 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_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); @@ -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)); - /* 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; } @@ -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_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; } @@ -2052,7 +2265,7 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE 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; @@ -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. */ - 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) { @@ -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); - 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; } + 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)) { - read_from_framebuffer(surface, context, dst_location); + read_from_framebuffer(surface, context, texture->resource.draw_binding, dst_location); 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; + unsigned int level; 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; - 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, @@ -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) { - 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; @@ -2221,17 +2447,16 @@ static BOOL surface_load_texture(struct wined3d_surface *surface, 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) - && 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, @@ -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; - 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); @@ -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_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))) @@ -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. */ +#if !defined(STAGING_CSMT) 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); @@ -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, - 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); @@ -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, - 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); @@ -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)); - HeapFree(GetProcessHeap(), 0, dst_mem); + heap_free(dst_mem); 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; + unsigned int level = surface_get_sub_resource_idx(surface) % texture->level_count; 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; @@ -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); - HeapFree(GetProcessHeap(), 0, blitter); + heap_free(blitter); } 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; } - 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, @@ -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 (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter)))) + if (!(blitter = heap_alloc(sizeof(*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); - HeapFree(GetProcessHeap(), 0, blitter); + heap_free(blitter); } /* 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; + 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; @@ -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); + 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_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) @@ -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 (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)); @@ -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); - 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); @@ -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 (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter)))) + if (!(blitter = heap_alloc(sizeof(*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); - 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); - 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; } @@ -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: - 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: - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + if (!context->gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) 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; @@ -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) - 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)) - 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, @@ -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) { + 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; @@ -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; - 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, @@ -2892,7 +3127,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit 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) { @@ -2936,7 +3171,7 @@ void wined3d_ffp_blitter_create(struct wined3d_blitter **next, const struct wine { struct wined3d_blitter *blitter; - if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter)))) + if (!(blitter = heap_alloc(sizeof(*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); - HeapFree(GetProcessHeap(), 0, blitter); + heap_free(blitter); } 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, - 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; @@ -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, - 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; @@ -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, - 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; @@ -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. */ - 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; @@ -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, - 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) @@ -3747,7 +3984,7 @@ struct wined3d_blitter *wined3d_cpu_blitter_create(void) { 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); @@ -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; - BOOL scale, convert; + BOOL scale, convert, resolve; 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; } + /* 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); @@ -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; + 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); @@ -3852,10 +4100,10 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst { 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; + 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, @@ -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; - 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; } - else if ((flags & WINED3D_BLT_RAW) || (!scale && !convert)) + else if ((flags & WINED3D_BLT_RAW) || (!scale && !convert && !resolve)) { 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; + 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, diff --git a/dll/directx/wine/wined3d/swapchain.c b/dll/directx/wine/wined3d/swapchain.c index 5857c1e191f..8c67a0d42be 100644 --- a/dll/directx/wine/wined3d/swapchain.c +++ b/dll/directx/wine/wined3d/swapchain.c @@ -20,8 +20,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" #include "wined3d_private.h" +#ifdef __REACTOS__ +#include +#endif + 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]); } - HeapFree(GetProcessHeap(), 0, swapchain->back_buffers); + heap_free(swapchain->back_buffers); 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); - HeapFree(GetProcessHeap(), 0, swapchain); + heap_free(swapchain); } 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, - 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); - 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) { @@ -175,7 +186,7 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, } 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; } @@ -467,16 +478,13 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, } 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); - } +#if !defined(STAGING_CSMT) 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 */ @@ -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. */ - 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); @@ -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"); } + 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 @@ -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.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; @@ -890,8 +904,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 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; @@ -910,7 +923,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 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"); @@ -918,7 +931,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 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); @@ -992,7 +1005,7 @@ err: 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); @@ -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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return hr; } @@ -1048,14 +1060,14 @@ static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain } 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); - HeapFree(GetProcessHeap(), 0, swapchain->context); + heap_free(swapchain->context); 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]); } - HeapFree(GetProcessHeap(), 0, swapchain->context); + heap_free(swapchain->context); swapchain->num_contexts = 0; swapchain->context = NULL; } diff --git a/dll/directx/wine/wined3d/texture.c b/dll/directx/wine/wined3d/texture.c index 98a894942c4..e6af0c75088 100644 --- a/dll/directx/wine/wined3d/texture.c +++ b/dll/directx/wine/wined3d/texture.c @@ -20,6 +20,8 @@ * 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); @@ -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) { - 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)); @@ -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; @@ -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 ((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", - required_access, texture->resource.access_flags); + required_access, texture->resource.access); } 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 !defined(STAGING_CSMT) 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) @@ -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, " - "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, - 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; @@ -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, - 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; @@ -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) - 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->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) @@ -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) { - 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 @@ -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, +#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; @@ -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; +#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) @@ -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) +#if !defined(STAGING_CSMT) 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) @@ -454,46 +481,80 @@ static void gltexture_delete(struct wined3d_device *device, const struct wined3d 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) { - 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) { - 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 width = wined3d_texture_get_level_pow2_width(texture, 0); - if (texture->target == GL_TEXTURE_2D_ARRAY) + switch (texture->target) { - GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count, gl_internal_format, - width, height, texture->layer_count)); - checkGLcall("glTexStorage3D"); - } - else - { - 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) @@ -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; +#if !defined(STAGING_CSMT) 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) { +#if !defined(STAGING_CSMT) 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) +#if !defined(STAGING_CSMT) { 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 (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); } @@ -685,12 +789,6 @@ void wined3d_texture_bind(struct wined3d_texture *texture, 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 @@ -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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); } 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. */ - 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; } @@ -1133,29 +1232,6 @@ DWORD CDECL wined3d_texture_get_level_count(const struct wined3d_texture *textur 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) { @@ -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, - 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); @@ -1302,9 +1379,15 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT return WINED3DERR_INVALIDCALL; } - if (texture->resource.type == WINED3D_RTYPE_TEXTURE_3D) + if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) { - WARN("Not supported on 3D textures.\n"); + WARN("Not supported on %s.\n", debug_d3dresourcetype(texture->resource.type)); + return WINED3DERR_INVALIDCALL; + } + + if (texture->resource.type == WINED3D_RTYPE_TEXTURE_1D) + { + FIXME("Not yet supported for 1D textures.\n"); 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; - 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; @@ -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, +#if !defined(STAGING_CSMT) 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]; +#if !defined(STAGING_CSMT) 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); +#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) @@ -1474,34 +1577,7 @@ static void wined3d_texture_prepare_rb(struct wined3d_texture *texture, 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); @@ -1548,7 +1624,11 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned return TRUE; case WINED3D_LOCATION_BUFFER: +#if !defined(STAGING_CSMT) 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: @@ -1606,7 +1686,7 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, } 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); @@ -1621,6 +1701,386 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s context, box, data, row_pitch, 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) +{ + 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; + + 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) + { + x = 0; + update_w = width; + } + else + { + x = box->left; + update_w = box->right - box->left; + } + + if (format->upload) + { + unsigned int dst_row_pitch; + + 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"); + + dst_row_pitch = update_w * format->conv_byte_count; + + 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 (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + } + + target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); + if (target == GL_TEXTURE_1D_ARRAY) + { + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, row_pitch / format->byte_count); + + gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, x, surface->texture_layer, update_w, 1, format->glFormat, format->glType, mem); + checkGLcall("glTexSubImage2D"); + + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + } + else + { + gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, x, update_w, format->glFormat, format->glType, mem); + checkGLcall("glTexSubImage1D"); + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + HeapFree(GetProcessHeap(), 0, converted_mem); +} + +/* 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) +{ + 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; + BYTE *temporary_mem = NULL; + void *mem; + GLenum target; + + sub_resource = &texture->sub_resources[sub_resource_idx]; + + if (format->conv_byte_count) + { + FIXME("Attempting to download a converted 1d texture, format %s.\n", + debug_d3dformat(format->id)); + return; + } + + 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"); + + if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size))) + { + ERR("Out of memory.\n"); + return; + } + + 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; + + gl_info->gl_ops.gl.p_glGetTexImage(target, sub_resource_idx, + format->glFormat, format->glType, mem); + checkGLcall("glGetTexImage"); + + 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 + { + memcpy(data->addr, src_data, sub_resource->size); + } + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + HeapFree(GetProcessHeap(), 0, temporary_mem); +} + +/* 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) @@ -1706,7 +2166,6 @@ static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture) 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; @@ -1729,24 +2188,15 @@ static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture) 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); + heap_free(entry); } if (surface->dc) texture2d_destroy_dc(surface); - - if (surface->overlay_dest) - list_remove(&surface->overlay_entry); - - LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &surface->overlays, struct wined3d_surface, overlay_entry) - { - list_remove(&overlay->overlay_entry); - overlay->overlay_dest = NULL; - } } if (context) context_release(context); - HeapFree(GetProcessHeap(), 0, texture->sub_resources[0].u.surface); + heap_free(texture->sub_resources[0].u.surface); } static const struct wined3d_texture_ops texture2d_ops = @@ -1800,7 +2250,7 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) { 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); @@ -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. */ - 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); } +#if !defined(STAGING_CSMT) 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) { @@ -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); - HeapFree(GetProcessHeap(), 0, entry); + heap_free(entry); } 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 (((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; } - 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"); @@ -1915,7 +2365,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour 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); @@ -1980,6 +2430,36 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour 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; @@ -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_sub_resource_map_info, 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) @@ -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; - unsigned int i, j; + unsigned int i, j, sub_count; 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; } - 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)) - 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; @@ -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) { - 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; @@ -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. */ - 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; @@ -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); } - /* 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))) { @@ -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->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 - 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; @@ -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 (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; } + 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) { - 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; - 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); - list_init(&surface->overlays); 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; - 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; @@ -2342,7 +2948,7 @@ static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int checkGLcall("glBindBuffer"); } - HeapFree(GetProcessHeap(), 0, converted_mem); + heap_free(converted_mem); } /* 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; - 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); @@ -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); - HeapFree(GetProcessHeap(), 0, data.addr); + heap_free(data.addr); } /* 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) { +#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); @@ -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)) { +#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); @@ -2576,45 +3190,19 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct 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]) { - 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"); } @@ -2646,7 +3234,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct 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; @@ -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 !defined(STAGING_CSMT) 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)) @@ -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) { - 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); - 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; } - 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; @@ -2746,8 +3345,8 @@ HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture 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); @@ -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) { - 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); - 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; } - 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; } @@ -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_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", @@ -2804,42 +3403,44 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un return WINED3DERR_INVALIDCALL; } + overlay = &texture->overlay_info[sub_resource_idx]; + surface = sub_resource->u.surface; if (src_rect) - surface->overlay_srcrect = *src_rect; + overlay->src_rect = *src_rect; 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) - surface->overlay_destrect = *dst_rect; + overlay->dst_rect = *dst_rect; 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)); - 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 (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. */ - 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; @@ -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->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); @@ -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) { + 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; @@ -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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return E_INVALIDARG; } } diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c index 6b97c634fc7..b48293eabb3 100644 --- a/dll/directx/wine/wined3d/utils.c +++ b/dll/directx/wine/wined3d/utils.c @@ -24,6 +24,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include + #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}, + {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, @@ -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; - 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"); @@ -1917,7 +1926,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) return TRUE; fail: - HeapFree(GetProcessHeap(), 0, gl_info->formats); + heap_free(gl_info->formats); 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; + GLenum target; 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]) { + target = gl_info->supported[ARB_TEXTURE_MULTISAMPLE] ? GL_TEXTURE_2D_MULTISAMPLE : GL_RENDERBUFFER; count = 0; - GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal, + GL_EXTCALL(glGetInternalformativ(target, format->glInternal, GL_NUM_SAMPLE_COUNTS, 1, &count)); - checkGLcall("glGetInternalformativ(GL_NUM_SAMPLE_COUNTS)"); count = min(count, MAX_MULTISAMPLE_TYPES); - GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal, + GL_EXTCALL(glGetInternalformativ(target, format->glInternal, GL_SAMPLES, count, multisample_types)); - checkGLcall("glGetInternalformativ(GL_SAMPLES)"); + checkGLcall("query sample counts"); 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); } @@ -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, - 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__ @@ -3595,6 +3605,23 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) 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}; @@ -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_gen_mipmap_info(gl_info); 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; } @@ -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) { - 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); @@ -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_AUTOGENMIPMAP); 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 - 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_GENMIPMAP); 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 - 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) @@ -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); + 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 @@ -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_COLORWRITEENABLE); 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_COLORWRITEENABLE); 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_DEPTHBIASCLAMP); 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_DEPTHCLIP); #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"; + if (STATE_IS_BLEND(state)) + return "STATE_BLEND"; 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) @@ -5348,6 +5420,293 @@ void multiply_matrix(struct wined3d_matrix *dst, const struct wined3d_matrix *sr *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; @@ -5734,7 +6093,27 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st { 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: + 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]) @@ -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: + 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); @@ -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_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_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); @@ -5796,6 +6181,8 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st } 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); @@ -5896,6 +6283,14 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, 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)); @@ -5991,21 +6386,11 @@ int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb 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) { + struct debug_buffer buffer; const char *prefix = ""; const char *suffix = ""; - char buf[294]; if (wined3d_popcount(location) > 16) { @@ -6014,8 +6399,8 @@ const char *wined3d_debug_location(DWORD location) 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); @@ -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 - 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 @@ -6149,7 +6535,7 @@ BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE 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) diff --git a/dll/directx/wine/wined3d/vertexdeclaration.c b/dll/directx/wine/wined3d/vertexdeclaration.c index 990aab00498..82348b40876 100644 --- a/dll/directx/wine/wined3d/vertexdeclaration.c +++ b/dll/directx/wine/wined3d/vertexdeclaration.c @@ -22,6 +22,8 @@ * 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); @@ -52,8 +54,8 @@ static void wined3d_vertex_declaration_destroy_object(void *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) @@ -117,6 +119,15 @@ static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *e 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) { @@ -186,7 +197,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara 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; @@ -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)); - HeapFree(GetProcessHeap(), 0, declaration->elements); + heap_free(declaration->elements); 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); - HeapFree(GetProcessHeap(), 0, declaration->elements); + heap_free(declaration->elements); 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); - 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); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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; - 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; @@ -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); - HeapFree(GetProcessHeap(), 0, elements); + heap_free(elements); return hr; } diff --git a/dll/directx/wine/wined3d/view.c b/dll/directx/wine/wined3d/view.c index 909467cea38..bed39dbc5fc 100644 --- a/dll/directx/wine/wined3d/view.c +++ b/dll/directx/wine/wined3d/view.c @@ -17,6 +17,9 @@ * */ +#include "config.h" +#include "wine/port.h" + #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[] = { - {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; @@ -328,7 +342,7 @@ static void wined3d_rendertarget_view_destroy_object(void *object) context_release(context); } - HeapFree(GetProcessHeap(), 0, view); + heap_free(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); - 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))) { - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); } - HeapFree(GetProcessHeap(), 0, view); + heap_free(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)); } } +#if defined(STAGING_CSMT) + + wined3d_resource_release(resource); +#endif /* STAGING_CSMT */ } 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); +#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; @@ -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); - 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))) { - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); 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); } - HeapFree(GetProcessHeap(), 0, view); + heap_free(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); } } +#if defined(STAGING_CSMT) + + wined3d_resource_release(resource); +#endif /* STAGING_CSMT */ } 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); +#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; @@ -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); - 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))) { - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); WARN("Failed to initialise view, hr %#x.\n", hr); return hr; } diff --git a/dll/directx/wine/wined3d/wined3d.spec b/dll/directx/wine/wined3d/wined3d.spec index 74e61eab39e..3022e20edbe 100644 --- a/dll/directx/wine/wined3d/wined3d.spec +++ b/dll/directx/wine/wined3d/wined3d.spec @@ -22,9 +22,12 @@ @ 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_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) @@ -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_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) @@ -125,8 +129,10 @@ @ 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_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) @@ -221,10 +227,12 @@ @ 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_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) @@ -264,6 +272,8 @@ @ 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) @@ -275,7 +285,7 @@ @ 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) @@ -288,7 +298,6 @@ @ 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) @@ -300,7 +309,6 @@ @ 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) @@ -318,3 +326,11 @@ @ 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) diff --git a/dll/directx/wine/wined3d/wined3d_gl.h b/dll/directx/wine/wined3d/wined3d_gl.h index 0894c946db8..87283c850e1 100644 --- a/dll/directx/wine/wined3d/wined3d_gl.h +++ b/dll/directx/wine/wined3d/wined3d_gl.h @@ -55,6 +55,7 @@ enum wined3d_gl_extension ARB_CULL_DISTANCE, ARB_DEBUG_OUTPUT, ARB_DEPTH_BUFFER_FLOAT, + ARB_DEPTH_CLAMP, 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_FRAMEBUFFER_NO_ATTACHMENTS, 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_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_STORAGE_MULTISAMPLE, 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_POLYGON_OFFSET_CLAMP, 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, - /* SGI */ - SGIS_GENERATE_MIPMAP, + NVX_GPU_MEMORY_INFO, /* WGL extensions */ WGL_ARB_PIXEL_FORMAT, WGL_EXT_SWAP_CONTROL, diff --git a/dll/directx/wine/wined3d/wined3d_main.c b/dll/directx/wine/wined3d/wined3d_main.c index a60764d0538..28e6fe60cfe 100644 --- a/dll/directx/wine/wined3d/wined3d_main.c +++ b/dll/directx/wine/wined3d/wined3d_main.c @@ -22,9 +22,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wined3d_private.h" +#include "config.h" +#include "wine/port.h" -#include +#include "initguid.h" +#include "wined3d_private.h" 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 = { - 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 */ @@ -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 */ + 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. */ @@ -96,8 +99,7 @@ struct wined3d * CDECL wined3d_create(DWORD flags) 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; @@ -110,7 +112,7 @@ struct wined3d * CDECL wined3d_create(DWORD flags) if (FAILED(hr)) { WARN("Failed to initialize wined3d object, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return NULL; } @@ -278,10 +280,13 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) { 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); @@ -321,6 +326,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) if (appkey) RegCloseKey( appkey ); if (hkey) RegCloseKey( hkey ); + wined3d_dxtn_init(); + 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]); } - 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); + + wined3d_dxtn_free(); + return TRUE; } @@ -506,6 +516,11 @@ void wined3d_unregister_window(HWND window) 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) { diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h index dd2967ac9da..878a4d084c9 100644 --- a/dll/directx/wine/wined3d/wined3d_private.h +++ b/dll/directx/wine/wined3d/wined3d_private.h @@ -25,48 +25,38 @@ #ifndef __WINE_WINED3D_PRIVATE_H #define __WINE_WINED3D_PRIVATE_H -#include -#include - #ifdef USE_WIN32_OPENGL #define WINE_GLAPI __stdcall #else #define WINE_GLAPI #endif -#ifdef HAVE_FLOAT_H -# include -#endif - #include -#include - -#include +#include +#include +#include +#include "ntstatus.h" #define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H - #define NONAMELESSUNION #define NONAMELESSSTRUCT #define COBJMACROS +#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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - +#include "objbase.h" +#include "wine/wined3d.h" #include "wined3d_gl.h" -#include - -#include +#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])) @@ -204,6 +194,7 @@ struct wined3d_d3d_info BOOL vs_clipping; BOOL shader_color_key; DWORD valid_rt_mask; + DWORD valid_dual_rt_mask; 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_RENDER_TARGET_VIEWS 8 #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_RENDER_TARGETS 8 struct min_lookup { @@ -402,6 +396,7 @@ struct wined3d_settings /* 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; @@ -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_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_VERTEXBLEND 0xff000000 +#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i) (0x01000000 << ((i) - 1)) 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 padding : 26; + DWORD dual_source_blend : 1; + DWORD padding : 25; }; 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_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) @@ -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 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 */ @@ -1950,9 +1951,7 @@ struct wined3d_context 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 */ @@ -1999,7 +1998,7 @@ struct wined3d_context 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; }; @@ -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_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, @@ -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_GTX560M = 0x1251, 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; + UINT dual_buffers; UINT lights; UINT textures; UINT texture_coords; @@ -2544,6 +2541,9 @@ struct wined3d_gl_limits 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; @@ -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; -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; @@ -2748,7 +2747,8 @@ struct wined3d_ffp_vs_settings 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]; }; @@ -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; +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; @@ -2852,9 +2863,51 @@ struct wined3d_state 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; }; +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 @@ -2928,16 +2981,7 @@ struct wined3d_device 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; @@ -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; +#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) { @@ -2972,8 +3022,12 @@ static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD sta 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 { @@ -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); + 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); }; @@ -3000,8 +3056,7 @@ struct wined3d_resource 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; @@ -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, - 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; @@ -3109,7 +3164,6 @@ struct wined3d_texture unsigned int sysmem_count; float pow2_matrix[16]; UINT lod; - enum wined3d_texture_filter_type filter_type; DWORD sampler; DWORD flags; GLenum target; @@ -3136,6 +3190,15 @@ struct wined3d_texture 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; @@ -3150,7 +3213,11 @@ struct wined3d_texture unsigned int map_count; DWORD locations; +#if !defined(STAGING_CSMT) GLuint buffer_object; +#else /* STAGING_CSMT */ + struct wined3d_gl_bo *buffer; +#endif /* STAGING_CSMT */ } 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); } +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) { @@ -3265,7 +3349,7 @@ struct fbo_entry 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; }; @@ -3273,7 +3357,6 @@ struct wined3d_surface { struct wined3d_texture *container; - GLenum texture_target; 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; - - /* 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) @@ -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; -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 { @@ -3465,6 +3542,9 @@ struct wined3d_cs_queue 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); @@ -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_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_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, @@ -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_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; @@ -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; +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; @@ -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_GEN_MIPMAP 0x00400000 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; } -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) @@ -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; } +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) { @@ -4419,6 +4531,9 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs) 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" diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 6b33d671de7..083be5fd7d7 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -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 -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/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 @@ -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/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 diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h index 4b50c51b5e6..1f8171d9c6b 100644 --- a/sdk/include/reactos/wine/wined3d.h +++ b/sdk/include/reactos/wine/wined3d.h @@ -30,13 +30,15 @@ # error You must include config.h to use this header #endif -#include +#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 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) @@ -50,6 +52,11 @@ #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, @@ -381,8 +388,22 @@ enum wined3d_render_state 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 { @@ -501,10 +522,13 @@ enum wined3d_patch_edge_style 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 @@ -672,16 +696,9 @@ enum wined3d_resource_type { 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 @@ -888,14 +905,14 @@ enum wined3d_shader_byte_code_format #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_MASK 0x10007fff +#define WINED3DUSAGE_MASK 0x10007bff +#define WINED3DUSAGE_SCRATCH 0x00200000 #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_QUERY_GENMIPMAP 0x00000400 #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_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 @@ -1166,7 +1185,7 @@ enum wined3d_shader_byte_code_format #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 @@ -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_REQUEST_D3D10 0x00004000 +#define WINED3D_LIMIT_VIEWPORT 0x00008000 #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; + DWORD backbuffer_usage; 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; - 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; - 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 @@ -1798,6 +1820,13 @@ struct wined3d_map_desc void *data; }; +struct wined3d_map_info +{ + UINT row_pitch; + UINT slice_pitch; + UINT size; +}; + struct wined3d_sub_resource_data { const void *data; @@ -1964,13 +1993,18 @@ struct wined3d_blt_fx struct wined3d_buffer_desc { unsigned int byte_width; - DWORD usage; + unsigned int usage; unsigned int bind_flags; - unsigned int cpu_access_flags; + unsigned int access; 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; @@ -2081,6 +2115,7 @@ struct wined3d_buffer; struct wined3d_device; struct wined3d_palette; struct wined3d_query; +struct wined3d_blend_state; 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_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); @@ -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); +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, @@ -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); +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_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, @@ -2548,6 +2583,13 @@ static inline HRESULT wined3d_private_store_set_private_data(struct wined3d_priv 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); @@ -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); +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); +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, @@ -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, - 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); @@ -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); -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); @@ -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); -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); @@ -2754,4 +2797,18 @@ static inline void wined3d_box_set(struct wined3d_box *box, unsigned int left, u 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 */