diff --git a/reactos/dll/directx/wine/d3d8/d3d8_main.c b/reactos/dll/directx/wine/d3d8/d3d8_main.c index 13e3d354e0e..51e59915d40 100644 --- a/reactos/dll/directx/wine/d3d8/d3d8_main.c +++ b/reactos/dll/directx/wine/d3d8/d3d8_main.c @@ -52,11 +52,10 @@ IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version) } /* At process attach */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { - TRACE("fdwReason=%d\n", fdwReason); - if (fdwReason == DLL_PROCESS_ATTACH) - DisableThreadLibraryCalls(hInstDLL); + if (reason == DLL_PROCESS_ATTACH) + DisableThreadLibraryCalls(inst); return TRUE; } diff --git a/reactos/dll/directx/wine/d3d8/d3d8_private.h b/reactos/dll/directx/wine/d3d8/d3d8_private.h index 6fb7296b9ec..9f4c224ab93 100644 --- a/reactos/dll/directx/wine/d3d8/d3d8_private.h +++ b/reactos/dll/directx/wine/d3d8/d3d8_private.h @@ -35,7 +35,6 @@ #define NONAMELESSUNION #define NONAMELESSSTRUCT #define COBJMACROS - #include #include #include @@ -193,9 +192,8 @@ struct d3d8_volume IUnknown *forwardReference; }; -HRESULT volume_init(struct d3d8_volume *volume, struct d3d8_device *device, UINT width, UINT height, - UINT depth, UINT level, DWORD usage, enum wined3d_format_id format, - enum wined3d_pool pool) DECLSPEC_HIDDEN; +void volume_init(struct d3d8_volume *volume, struct wined3d_volume *wined3d_volume, + const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct d3d8_swapchain { @@ -222,9 +220,8 @@ struct d3d8_surface IUnknown *forwardReference; }; -HRESULT surface_init(struct d3d8_surface *surface, struct d3d8_device *device, UINT width, UINT height, - D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, - DWORD multisample_quality) DECLSPEC_HIDDEN; +void surface_init(struct d3d8_surface *surface, struct wined3d_surface *wined3d_surface, + struct d3d8_device *device, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN; struct d3d8_vertexbuffer diff --git a/reactos/dll/directx/wine/d3d8/device.c b/reactos/dll/directx/wine/d3d8/device.c index fd0661f8c27..3737a74b2df 100644 --- a/reactos/dll/directx/wine/d3d8/device.c +++ b/reactos/dll/directx/wine/d3d8/device.c @@ -728,6 +728,7 @@ static HRESULT WINAPI d3d8_device_CreateTexture(IDirect3DDevice8 *iface, TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", iface, width, height, levels, usage, format, pool, texture); + *texture = NULL; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) return D3DERR_OUTOFVIDEOMEMORY; @@ -757,6 +758,7 @@ static HRESULT WINAPI d3d8_device_CreateVolumeTexture(IDirect3DDevice8 *iface, TRACE("iface %p, width %u, height %u, depth %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", iface, width, height, depth, levels, usage, format, pool, texture); + *texture = NULL; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) return D3DERR_OUTOFVIDEOMEMORY; @@ -785,6 +787,7 @@ static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UIN TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", iface, edge_length, levels, usage, format, pool, texture); + *texture = NULL; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) return D3DERR_OUTOFVIDEOMEMORY; @@ -887,7 +890,7 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width wined3d_mutex_lock(); - if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &desc, + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, 1, flags, NULL, &d3d8_null_wined3d_parent_ops, &texture))) { wined3d_mutex_unlock(); @@ -918,6 +921,7 @@ static HRESULT WINAPI d3d8_device_CreateRenderTarget(IDirect3DDevice8 *iface, UI TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, lockable %#x, surface %p.\n", iface, width, height, format, multisample_type, lockable, surface); + *surface = NULL; if (lockable) flags |= WINED3D_SURFACE_MAPPABLE; @@ -934,6 +938,8 @@ static HRESULT WINAPI d3d8_device_CreateDepthStencilSurface(IDirect3DDevice8 *if TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, surface %p.\n", iface, width, height, format, multisample_type, surface); + *surface = NULL; + /* TODO: Verify that Discard is false */ return d3d8_device_create_surface(device, width, height, format, WINED3D_SURFACE_MAPPABLE, surface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, 0); @@ -948,6 +954,8 @@ static HRESULT WINAPI d3d8_device_CreateImageSurface(IDirect3DDevice8 *iface, UI TRACE("iface %p, width %u, height %u, format %#x, surface %p.\n", iface, width, height, format, surface); + *surface = NULL; + return d3d8_device_create_surface(device, width, height, format, WINED3D_SURFACE_MAPPABLE, surface, 0, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0); } @@ -1005,7 +1013,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, { TRACE("Converting destination surface from WINED3DFMT_UNKNOWN to the source format.\n"); if (FAILED(hr = wined3d_surface_update_desc(dst->wined3d_surface, wined3d_desc.width, wined3d_desc.height, - src_format, wined3d_desc.multisample_type, wined3d_desc.multisample_quality))) + src_format, wined3d_desc.multisample_type, wined3d_desc.multisample_quality, NULL, 0))) { WARN("Failed to update surface desc, hr %#x.\n", hr); wined3d_mutex_unlock(); @@ -2898,16 +2906,15 @@ static void CDECL device_parent_mode_changed(struct wined3d_device_parent *devic TRACE("device_parent %p.\n", device_parent); } -static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_parent *device_parent, - void *container_parent, const struct wined3d_resource_desc *desc, UINT sub_resource_idx, - DWORD flags, struct wined3d_surface **surface) +static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, + void *container_parent, struct wined3d_surface *surface, void **parent, + const struct wined3d_parent_ops **parent_ops) { struct d3d8_device *device = device_from_device_parent(device_parent); struct d3d8_surface *d3d_surface; - HRESULT hr; - TRACE("device_parent %p, container_parent %p, desc %p, sub_resource_idx %u, flags %#x, surface %p.\n", - device_parent, container_parent, desc, sub_resource_idx, flags, surface); + TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n", + device_parent, container_parent, surface, parent, parent_ops); if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface)))) { @@ -2915,20 +2922,10 @@ static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_ return D3DERR_OUTOFVIDEOMEMORY; } - if (FAILED(hr = surface_init(d3d_surface, device, desc->width, desc->height, - d3dformat_from_wined3dformat(desc->format), flags, desc->usage, desc->pool, - desc->multisample_type, desc->multisample_quality))) - { - WARN("Failed to initialize surface, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, d3d_surface); - return hr; - } - + surface_init(d3d_surface, surface, device, parent_ops); + *parent = d3d_surface; TRACE("Created surface %p.\n", d3d_surface); - *surface = d3d_surface->wined3d_surface; - wined3d_surface_incref(*surface); - d3d_surface->container = container_parent; IDirect3DDevice8_Release(d3d_surface->parent_device); d3d_surface->parent_device = NULL; @@ -2936,7 +2933,31 @@ static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_ IDirect3DSurface8_Release(&d3d_surface->IDirect3DSurface8_iface); d3d_surface->forwardReference = container_parent; - return hr; + return D3D_OK; +} + +static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, + void *container_parent, struct wined3d_volume *volume, void **parent, + const struct wined3d_parent_ops **parent_ops) +{ + struct d3d8_volume *d3d_volume; + + TRACE("device_parent %p, container_parent %p, volume %p, parent %p, parent_ops %p.\n", + device_parent, container_parent, volume, parent, parent_ops); + + if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume)))) + return E_OUTOFMEMORY; + + volume_init(d3d_volume, volume, parent_ops); + *parent = d3d_volume; + TRACE("Created volume %p.\n", d3d_volume); + + d3d_volume->container = container_parent; + + IDirect3DVolume8_Release(&d3d_volume->IDirect3DVolume8_iface); + d3d_volume->forwardReference = container_parent; + + return D3D_OK; } static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent, @@ -2953,7 +2974,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic texture_desc = *desc; texture_desc.resource_type = WINED3D_RTYPE_TEXTURE; - if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &texture_desc, 1, + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1, WINED3D_SURFACE_MAPPABLE, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture))) { WARN("Failed to create texture, hr %#x.\n", hr); @@ -2971,48 +2992,6 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic return hr; } -static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent, - void *container_parent, UINT width, UINT height, UINT depth, UINT level, - enum wined3d_format_id format, enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume) -{ - struct d3d8_device *device = device_from_device_parent(device_parent); - struct d3d8_volume *object; - HRESULT hr; - - TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, " - "format %#x, pool %#x, usage %#x, volume %p.\n", - device_parent, container_parent, width, height, depth, - format, pool, usage, volume); - - /* Allocate the storage for the device */ - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) - { - FIXME("Allocation of memory failed\n"); - *volume = NULL; - return D3DERR_OUTOFVIDEOMEMORY; - } - - hr = volume_init(object, device, width, height, depth, level, usage, format, pool); - if (FAILED(hr)) - { - WARN("Failed to initialize volume, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, object); - return hr; - } - - *volume = object->wined3d_volume; - wined3d_volume_incref(*volume); - IDirect3DVolume8_Release(&object->IDirect3DVolume8_iface); - - object->container = container_parent; - object->forwardReference = container_parent; - - TRACE("Created volume %p.\n", object); - - return hr; -} - static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) { @@ -3040,9 +3019,9 @@ static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops = { device_parent_wined3d_device_created, device_parent_mode_changed, + device_parent_surface_created, + device_parent_volume_created, device_parent_create_swapchain_surface, - device_parent_create_texture_surface, - device_parent_create_volume, device_parent_create_swapchain, }; diff --git a/reactos/dll/directx/wine/d3d8/shader.c b/reactos/dll/directx/wine/d3d8/shader.c index 540a4c08014..7453e01799c 100644 --- a/reactos/dll/directx/wine/d3d8/shader.c +++ b/reactos/dll/directx/wine/d3d8/shader.c @@ -92,7 +92,7 @@ HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_d if (reg == D3DVSDE_NORMAL && type != D3DVSDT_FLOAT3 && !byte_code) { - WARN("Attempt to use a non-FLOAT3 normal with the fixed function function\n"); + WARN("Attempt to use a non-FLOAT3 normal with the fixed-function function\n"); return D3DERR_INVALIDCALL; } } diff --git a/reactos/dll/directx/wine/d3d8/surface.c b/reactos/dll/directx/wine/d3d8/surface.c index 8295a36ceee..10abee875b0 100644 --- a/reactos/dll/directx/wine/d3d8/surface.c +++ b/reactos/dll/directx/wine/d3d8/surface.c @@ -270,8 +270,16 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface, hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags); wined3d_mutex_unlock(); - locked_rect->Pitch = map_desc.row_pitch; - locked_rect->pBits = map_desc.data; + if (SUCCEEDED(hr)) + { + locked_rect->Pitch = map_desc.row_pitch; + locked_rect->pBits = map_desc.data; + } + else + { + locked_rect->Pitch = 0; + locked_rect->pBits = NULL; + } return hr; } @@ -322,37 +330,17 @@ static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops = surface_wined3d_object_destroyed, }; -HRESULT surface_init(struct d3d8_surface *surface, struct d3d8_device *device, UINT width, UINT height, - D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, - DWORD multisample_quality) +void surface_init(struct d3d8_surface *surface, struct wined3d_surface *wined3d_surface, + struct d3d8_device *device, const struct wined3d_parent_ops **parent_ops) { - HRESULT hr; - surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl; surface->refcount = 1; - - /* FIXME: Check MAX bounds of MultisampleQuality. */ - if (multisample_quality > 0) - { - FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality); - multisample_quality = 0; - } - - wined3d_mutex_lock(); - hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format), - usage & WINED3DUSAGE_MASK, (enum wined3d_pool)pool, multisample_type, multisample_quality, - flags, surface, &d3d8_surface_wined3d_parent_ops, &surface->wined3d_surface); - wined3d_mutex_unlock(); - if (FAILED(hr)) - { - WARN("Failed to create wined3d surface, hr %#x.\n", hr); - return hr; - } - + wined3d_surface_incref(wined3d_surface); + surface->wined3d_surface = wined3d_surface; surface->parent_device = &device->IDirect3DDevice8_iface; IDirect3DDevice8_AddRef(surface->parent_device); - return D3D_OK; + *parent_ops = &d3d8_surface_wined3d_parent_ops; } struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) diff --git a/reactos/dll/directx/wine/d3d8/texture.c b/reactos/dll/directx/wine/d3d8/texture.c index e954ddc3587..9ea83e7d938 100644 --- a/reactos/dll/directx/wine/d3d8/texture.c +++ b/reactos/dll/directx/wine/d3d8/texture.c @@ -1194,6 +1194,7 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device, desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage |= WINED3DUSAGE_TEXTURE; desc.pool = pool; desc.width = width; desc.height = height; @@ -1204,7 +1205,7 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device, surface_flags |= WINED3D_SURFACE_MAPPABLE; wined3d_mutex_lock(); - hr = wined3d_texture_create_2d(device->wined3d_device, &desc, levels, surface_flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1234,6 +1235,7 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage |= WINED3DUSAGE_TEXTURE; desc.pool = pool; desc.width = edge_length; desc.height = edge_length; @@ -1244,7 +1246,7 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic surface_flags |= WINED3D_SURFACE_MAPPABLE; wined3d_mutex_lock(); - hr = wined3d_texture_create_cube(device->wined3d_device, &desc, levels, surface_flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1273,6 +1275,7 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage |= WINED3DUSAGE_TEXTURE; desc.pool = pool; desc.width = width; desc.height = height; @@ -1280,7 +1283,7 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev desc.size = 0; wined3d_mutex_lock(); - hr = wined3d_texture_create_3d(device->wined3d_device, &desc, levels, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) diff --git a/reactos/dll/directx/wine/d3d8/volume.c b/reactos/dll/directx/wine/d3d8/volume.c index 5e3a8a485a0..d2399d51e4b 100644 --- a/reactos/dll/directx/wine/d3d8/volume.c +++ b/reactos/dll/directx/wine/d3d8/volume.c @@ -280,21 +280,13 @@ static const struct wined3d_parent_ops d3d8_volume_wined3d_parent_ops = volume_wined3d_object_destroyed, }; -HRESULT volume_init(struct d3d8_volume *volume, struct d3d8_device *device, UINT width, UINT height, - UINT depth, UINT level, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool) +void volume_init(struct d3d8_volume *volume, struct wined3d_volume *wined3d_volume, + const struct wined3d_parent_ops **parent_ops) { - HRESULT hr; - volume->IDirect3DVolume8_iface.lpVtbl = &d3d8_volume_vtbl; volume->refcount = 1; + wined3d_volume_incref(wined3d_volume); + volume->wined3d_volume = wined3d_volume; - hr = wined3d_volume_create(device->wined3d_device, width, height, depth, level, usage, - format, pool, volume, &d3d8_volume_wined3d_parent_ops, &volume->wined3d_volume); - if (FAILED(hr)) - { - WARN("Failed to create wined3d volume, hr %#x.\n", hr); - return hr; - } - - return D3D_OK; + *parent_ops = &d3d8_volume_wined3d_parent_ops; } diff --git a/reactos/dll/directx/wine/d3d9/d3d9_main.c b/reactos/dll/directx/wine/d3d9/d3d9_main.c index 01d6b216236..b2a1c68a7f6 100644 --- a/reactos/dll/directx/wine/d3d9/d3d9_main.c +++ b/reactos/dll/directx/wine/d3d9/d3d9_main.c @@ -89,12 +89,10 @@ void* WINAPI Direct3DShaderValidatorCreate9(void) /******************************************************************* * DllMain */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { - /* At process attach */ - TRACE("fdwReason=%d\n", fdwReason); - if (fdwReason == DLL_PROCESS_ATTACH) - DisableThreadLibraryCalls(hInstDLL); + if (reason == DLL_PROCESS_ATTACH) + DisableThreadLibraryCalls(inst); return TRUE; } @@ -102,8 +100,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) /*********************************************************************** * D3DPERF_BeginEvent (D3D9.@) */ -int WINAPI D3DPERF_BeginEvent(D3DCOLOR color, LPCWSTR name) { - TRACE("(color %#x, name %s) : stub\n", color, debugstr_w(name)); +int WINAPI D3DPERF_BeginEvent(D3DCOLOR color, const WCHAR *name) +{ + TRACE("color 0x%08x, name %s.\n", color, debugstr_w(name)); return D3DPERF_event_level++; } @@ -147,13 +146,15 @@ BOOL WINAPI D3DPERF_QueryRepeatFrame(void) { /*********************************************************************** * D3DPERF_SetMarker (D3D9.@) */ -void WINAPI D3DPERF_SetMarker(D3DCOLOR color, LPCWSTR name) { - FIXME("(color %#x, name %s) : stub\n", color, debugstr_w(name)); +void WINAPI D3DPERF_SetMarker(D3DCOLOR color, const WCHAR *name) +{ + FIXME("color 0x%08x, name %s stub!\n", color, debugstr_w(name)); } /*********************************************************************** * D3DPERF_SetRegion (D3D9.@) */ -void WINAPI D3DPERF_SetRegion(D3DCOLOR color, LPCWSTR name) { - FIXME("(color %#x, name %s) : stub\n", color, debugstr_w(name)); +void WINAPI D3DPERF_SetRegion(D3DCOLOR color, const WCHAR *name) +{ + FIXME("color 0x%08x, name %s stub!\n", color, debugstr_w(name)); } diff --git a/reactos/dll/directx/wine/d3d9/d3d9_private.h b/reactos/dll/directx/wine/d3d9/d3d9_private.h index 6ae0c4d56ae..e896c280c41 100644 --- a/reactos/dll/directx/wine/d3d9/d3d9_private.h +++ b/reactos/dll/directx/wine/d3d9/d3d9_private.h @@ -35,7 +35,6 @@ #define NONAMELESSUNION #define NONAMELESSSTRUCT #define COBJMACROS - #include #include #include @@ -182,13 +181,12 @@ struct d3d9_volume IUnknown *forwardReference; }; -HRESULT volume_init(struct d3d9_volume *volume, struct d3d9_device *device, UINT width, UINT height, - UINT depth, UINT level, DWORD usage, enum wined3d_format_id format, - enum wined3d_pool pool) DECLSPEC_HIDDEN; +void volume_init(struct d3d9_volume *volume, struct wined3d_volume *wined3d_volume, + const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct d3d9_swapchain { - IDirect3DSwapChain9 IDirect3DSwapChain9_iface; + IDirect3DSwapChain9Ex IDirect3DSwapChain9Ex_iface; LONG refcount; struct wined3d_swapchain *wined3d_swapchain; IDirect3DDevice9Ex *parent_device; @@ -208,9 +206,8 @@ struct d3d9_surface BOOL getdc_supported; }; -HRESULT surface_init(struct d3d9_surface *surface, struct d3d9_device *device, UINT width, UINT height, - D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, - DWORD multisample_quality) DECLSPEC_HIDDEN; +void surface_init(struct d3d9_surface *surface, struct wined3d_surface *wined3d_surface, + struct d3d9_device *device, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) DECLSPEC_HIDDEN; struct d3d9_vertexbuffer @@ -319,4 +316,9 @@ struct d3d9_query HRESULT query_init(struct d3d9_query *query, struct d3d9_device *device, D3DQUERYTYPE type) DECLSPEC_HIDDEN; +static inline struct d3d9_device *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9Ex *iface) +{ + return CONTAINING_RECORD(iface, struct d3d9_device, IDirect3DDevice9Ex_iface); +} + #endif /* __WINE_D3D9_PRIVATE_H */ diff --git a/reactos/dll/directx/wine/d3d9/device.c b/reactos/dll/directx/wine/d3d9/device.c index 6bcc65bc03b..efff993cfac 100644 --- a/reactos/dll/directx/wine/d3d9/device.c +++ b/reactos/dll/directx/wine/d3d9/device.c @@ -226,11 +226,6 @@ static void wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch swapchain_desc->auto_restore_display_mode = TRUE; } -static inline struct d3d9_device *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9Ex *iface) -{ - return CONTAINING_RECORD(iface, struct d3d9_device, IDirect3DDevice9Ex_iface); -} - static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); @@ -504,7 +499,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters); if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object))) - *swapchain = &object->IDirect3DSwapChain9_iface; + *swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface; present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc); return hr; @@ -524,8 +519,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_GetSwapChain(IDirect3DDevice if ((wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, swapchain_idx))) { swapchain_impl = wined3d_swapchain_get_parent(wined3d_swapchain); - *swapchain = &swapchain_impl->IDirect3DSwapChain9_iface; - IDirect3DSwapChain9_AddRef(*swapchain); + *swapchain = (IDirect3DSwapChain9 *)&swapchain_impl->IDirect3DSwapChain9Ex_iface; + IDirect3DSwapChain9Ex_AddRef(*swapchain); hr = D3D_OK; } else @@ -739,8 +734,15 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n", iface, width, height, levels, usage, format, pool, texture, shared_handle); + *texture = NULL; if (shared_handle) { + if (!device->d3d_parent->extended) + { + WARN("Trying to create a shared or user memory texture on a non-ex device.\n"); + return E_NOTIMPL; + } + if (pool == D3DPOOL_SYSTEMMEM) { if (levels != 1) @@ -748,7 +750,14 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, set_mem = TRUE; } else + { + if (pool != D3DPOOL_DEFAULT) + { + WARN("Trying to create a shared texture in pool %#x.\n", pool); + return D3DERR_INVALIDCALL; + } FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } } object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); @@ -770,7 +779,9 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, resource = wined3d_texture_get_sub_resource(object->wined3d_texture, 0); surface = wined3d_resource_get_parent(resource); - wined3d_surface_set_mem(surface->wined3d_surface, *shared_handle, 0); + wined3d_surface_update_desc(surface->wined3d_surface, width, height, + wined3dformat_from_d3dformat(format), WINED3D_MULTISAMPLE_NONE, 0, + *shared_handle, 0); } TRACE("Created texture %p.\n", object); @@ -792,8 +803,22 @@ static HRESULT WINAPI d3d9_device_CreateVolumeTexture(IDirect3DDevice9Ex *iface, TRACE("usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n", usage, format, pool, texture, shared_handle); + *texture = NULL; if (shared_handle) + { + if (!device->d3d_parent->extended) + { + WARN("Trying to create a shared volume texture on a non-ex device.\n"); + return E_NOTIMPL; + } + + if (pool != D3DPOOL_DEFAULT) + { + WARN("Trying to create a shared volume texture in pool %#x.\n", pool); + return D3DERR_INVALIDCALL; + } FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) @@ -824,8 +849,22 @@ static HRESULT WINAPI d3d9_device_CreateCubeTexture(IDirect3DDevice9Ex *iface, TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n", iface, edge_length, levels, usage, format, pool, texture, shared_handle); + *texture = NULL; if (shared_handle) + { + if (!device->d3d_parent->extended) + { + WARN("Trying to create a shared cube texture on a non-ex device.\n"); + return E_NOTIMPL; + } + + if (pool != D3DPOOL_DEFAULT) + { + WARN("Trying to create a shared cube texture in pool %#x.\n", pool); + return D3DERR_INVALIDCALL; + } FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) @@ -857,7 +896,20 @@ static HRESULT WINAPI d3d9_device_CreateVertexBuffer(IDirect3DDevice9Ex *iface, iface, size, usage, fvf, pool, buffer, shared_handle); if (shared_handle) + { + if (!device->d3d_parent->extended) + { + WARN("Trying to create a shared vertex buffer on a non-ex device.\n"); + return E_NOTIMPL; + } + + if (pool != D3DPOOL_DEFAULT) + { + WARN("Trying to create a shared vertex buffer in pool %#x.\n", pool); + return D3DERR_NOTAVAILABLE; + } FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) @@ -889,7 +941,20 @@ static HRESULT WINAPI d3d9_device_CreateIndexBuffer(IDirect3DDevice9Ex *iface, U iface, size, usage, format, pool, buffer, shared_handle); if (shared_handle) + { + if (!device->d3d_parent->extended) + { + WARN("Trying to create a shared index buffer on a non-ex device.\n"); + return E_NOTIMPL; + } + + if (pool != D3DPOOL_DEFAULT) + { + WARN("Trying to create a shared index buffer in pool %#x.\n", pool); + return D3DERR_NOTAVAILABLE; + } FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) @@ -911,7 +976,7 @@ static HRESULT WINAPI d3d9_device_CreateIndexBuffer(IDirect3DDevice9Ex *iface, U static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width, UINT height, D3DFORMAT format, DWORD flags, IDirect3DSurface9 **surface, UINT usage, D3DPOOL pool, - D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) + D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, void *user_mem) { struct wined3d_resource *sub_resource; struct wined3d_resource_desc desc; @@ -937,7 +1002,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width wined3d_mutex_lock(); - if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &desc, + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, 1, flags, NULL, &d3d9_null_wined3d_parent_ops, &texture))) { wined3d_mutex_unlock(); @@ -953,6 +1018,10 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width IDirect3DSurface9_AddRef(*surface); wined3d_texture_decref(texture); + if (user_mem) + wined3d_surface_update_desc(surface_impl->wined3d_surface, width, height, + desc.format, multisample_type, multisample_quality, user_mem, 0); + wined3d_mutex_unlock(); return D3D_OK; @@ -970,14 +1039,23 @@ static HRESULT WINAPI d3d9_device_CreateRenderTarget(IDirect3DDevice9Ex *iface, iface, width, height, format, multisample_type, multisample_quality, lockable, surface, shared_handle); + *surface = NULL; if (shared_handle) + { + if (!device->d3d_parent->extended) + { + WARN("Trying to create a shared render target on a non-ex device.\n"); + return E_NOTIMPL; + } + FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } if (lockable) flags |= WINED3D_SURFACE_MAPPABLE; return d3d9_device_create_surface(device, width, height, format, flags, surface, - D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, multisample_quality); + D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); } static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex *iface, UINT width, UINT height, @@ -992,14 +1070,23 @@ static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex * iface, width, height, format, multisample_type, multisample_quality, discard, surface, shared_handle); + *surface = NULL; if (shared_handle) + { + if (!device->d3d_parent->extended) + { + WARN("Trying to create a shared depth stencil on a non-ex device.\n"); + return E_NOTIMPL; + } + FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } if (discard) flags |= WINED3D_SURFACE_DISCARD; return d3d9_device_create_surface(device, width, height, format, flags, surface, - D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, multisample_quality); + D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); } @@ -1184,23 +1271,44 @@ static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurface(IDirect3DDevice9Ex HANDLE *shared_handle) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + void *user_mem = NULL; TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n", iface, width, height, format, pool, surface, shared_handle); - if (shared_handle) - FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); - + *surface = NULL; if (pool == D3DPOOL_MANAGED) { WARN("Attempting to create a managed offscreen plain surface.\n"); return D3DERR_INVALIDCALL; } + + if (shared_handle) + { + if (!device->d3d_parent->extended) + { + WARN("Trying to create a shared or user memory surface on a non-ex device.\n"); + return E_NOTIMPL; + } + + if (pool == D3DPOOL_SYSTEMMEM) + user_mem = *shared_handle; + else + { + if (pool != D3DPOOL_DEFAULT) + { + WARN("Trying to create a shared surface in pool %#x.\n", pool); + return D3DERR_INVALIDCALL; + } + FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } + } + /* FIXME: Offscreen surfaces are supposed to be always lockable, * regardless of the pool they're created in. Should we set dynamic usage * here? */ return d3d9_device_create_surface(device, width, height, format, - WINED3D_SURFACE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0); + WINED3D_SURFACE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0, user_mem); } static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 *surface) @@ -1217,6 +1325,12 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO return D3DERR_INVALIDCALL; } + if (!idx && !surface_impl) + { + WARN("Trying to set render target 0 to NULL.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); hr = wined3d_device_set_render_target(device->wined3d_device, idx, surface_impl ? surface_impl->wined3d_surface : NULL, TRUE); @@ -2363,7 +2477,7 @@ static struct wined3d_vertex_declaration *device_get_fvf_declaration(struct d3d9 fvf_decls[low].fvf = fvf; ++device->fvf_decl_count; - TRACE("Returning %p. %u declatations in array.\n", wined3d_declaration, device->fvf_decl_count); + TRACE("Returning %p. %u declarations in array.\n", wined3d_declaration, device->fvf_decl_count); return wined3d_declaration; } @@ -3035,6 +3149,7 @@ static HRESULT WINAPI d3d9_device_CreateRenderTargetEx(IDirect3DDevice9Ex *iface iface, width, height, format, multisample_type, multisample_quality, lockable, surface, shared_handle, usage); + *surface = NULL; if (shared_handle) FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); @@ -3060,6 +3175,7 @@ static HRESULT WINAPI d3d9_device_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex iface, width, height, format, multisample_type, multisample_quality, discard, surface, shared_handle, usage); + *surface = NULL; if (shared_handle) FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); @@ -3295,16 +3411,15 @@ static void CDECL device_parent_mode_changed(struct wined3d_device_parent *devic TRACE("device_parent %p.\n", device_parent); } -static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_parent *device_parent, - void *container_parent, const struct wined3d_resource_desc *desc, UINT sub_resource_idx, - DWORD flags, struct wined3d_surface **surface) +static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, + void *container_parent, struct wined3d_surface *surface, void **parent, + const struct wined3d_parent_ops **parent_ops) { struct d3d9_device *device = device_from_device_parent(device_parent); struct d3d9_surface *d3d_surface; - HRESULT hr; - TRACE("device_parent %p, container_parent %p, desc %p, sub_resource_idx %u, flags %#x, surface %p.\n", - device_parent, container_parent, desc, sub_resource_idx, flags, surface); + TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n", + device_parent, container_parent, surface, parent, parent_ops); if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface)))) { @@ -3312,20 +3427,10 @@ static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_ return D3DERR_OUTOFVIDEOMEMORY; } - if (FAILED(hr = surface_init(d3d_surface, device, desc->width, desc->height, - d3dformat_from_wined3dformat(desc->format), flags, desc->usage, desc->pool, - desc->multisample_type, desc->multisample_quality))) - { - WARN("Failed to initialize surface, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, d3d_surface); - return hr; - } - + surface_init(d3d_surface, surface, device, parent_ops); + *parent = d3d_surface; TRACE("Created surface %p.\n", d3d_surface); - *surface = d3d_surface->wined3d_surface; - wined3d_surface_incref(*surface); - d3d_surface->container = container_parent; IDirect3DDevice9Ex_Release(d3d_surface->parent_device); d3d_surface->parent_device = NULL; @@ -3333,7 +3438,31 @@ static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_ IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface); d3d_surface->forwardReference = container_parent; - return hr; + return D3D_OK; +} + +static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, + void *container_parent, struct wined3d_volume *volume, void **parent, + const struct wined3d_parent_ops **parent_ops) +{ + struct d3d9_volume *d3d_volume; + + TRACE("device_parent %p, container_parent %p, volume %p, parent %p, parent_ops %p.\n", + device_parent, container_parent, volume, parent, parent_ops); + + if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume)))) + return E_OUTOFMEMORY; + + volume_init(d3d_volume, volume, parent_ops); + *parent = d3d_volume; + TRACE("Created volume %p.\n", d3d_volume); + + d3d_volume->container = container_parent; + + IDirect3DVolume9_Release(&d3d_volume->IDirect3DVolume9_iface); + d3d_volume->forwardReference = container_parent; + + return D3D_OK; } static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent, @@ -3353,7 +3482,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic texture_desc = *desc; texture_desc.resource_type = WINED3D_RTYPE_TEXTURE; - if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &texture_desc, 1, + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1, WINED3D_SURFACE_MAPPABLE, container_parent, &d3d9_null_wined3d_parent_ops, &texture))) { WARN("Failed to create texture, hr %#x.\n", hr); @@ -3371,48 +3500,6 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic return hr; } -static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent, - void *container_parent, UINT width, UINT height, UINT depth, UINT level, - enum wined3d_format_id format, enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume) -{ - struct d3d9_device *device = device_from_device_parent(device_parent); - struct d3d9_volume *object; - HRESULT hr; - - TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, " - "format %#x, pool %#x, usage %#x, volume %p\n", - device_parent, container_parent, width, height, depth, - format, pool, usage, volume); - - /* Allocate the storage for the device */ - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) - { - FIXME("Allocation of memory failed\n"); - *volume = NULL; - return D3DERR_OUTOFVIDEOMEMORY; - } - - hr = volume_init(object, device, width, height, depth, level, usage, format, pool); - if (FAILED(hr)) - { - WARN("Failed to initialize volume, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, object); - return hr; - } - - *volume = object->wined3d_volume; - wined3d_volume_incref(*volume); - IDirect3DVolume9_Release(&object->IDirect3DVolume9_iface); - - object->container = container_parent; - object->forwardReference = container_parent; - - TRACE("Created volume %p.\n", object); - - return hr; -} - static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) { @@ -3432,7 +3519,7 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *swapchain = d3d_swapchain->wined3d_swapchain; wined3d_swapchain_incref(*swapchain); - IDirect3DSwapChain9_Release(&d3d_swapchain->IDirect3DSwapChain9_iface); + IDirect3DSwapChain9Ex_Release(&d3d_swapchain->IDirect3DSwapChain9Ex_iface); return hr; } @@ -3441,9 +3528,9 @@ static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops = { device_parent_wined3d_device_created, device_parent_mode_changed, + device_parent_surface_created, + device_parent_volume_created, device_parent_create_swapchain_surface, - device_parent_create_texture_surface, - device_parent_create_volume, device_parent_create_swapchain, }; diff --git a/reactos/dll/directx/wine/d3d9/surface.c b/reactos/dll/directx/wine/d3d9/surface.c index c86d05d093f..27e6744c80f 100644 --- a/reactos/dll/directx/wine/d3d9/surface.c +++ b/reactos/dll/directx/wine/d3d9/surface.c @@ -290,8 +290,11 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface, hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags); wined3d_mutex_unlock(); - locked_rect->Pitch = map_desc.row_pitch; - locked_rect->pBits = map_desc.data; + if (SUCCEEDED(hr)) + { + locked_rect->Pitch = map_desc.row_pitch; + locked_rect->pBits = map_desc.data; + } return hr; } @@ -387,16 +390,16 @@ static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops = surface_wined3d_object_destroyed, }; -HRESULT surface_init(struct d3d9_surface *surface, struct d3d9_device *device, UINT width, UINT height, - D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, - DWORD multisample_quality) +void surface_init(struct d3d9_surface *surface, struct wined3d_surface *wined3d_surface, + struct d3d9_device *device, const struct wined3d_parent_ops **parent_ops) { - HRESULT hr; + struct wined3d_resource_desc desc; surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl; surface->refcount = 1; - switch (format) + wined3d_resource_get_desc(wined3d_surface_get_resource(wined3d_surface), &desc); + switch (d3dformat_from_wined3dformat(desc.format)) { case D3DFMT_A8R8G8B8: case D3DFMT_X8R8G8B8: @@ -412,28 +415,12 @@ HRESULT surface_init(struct d3d9_surface *surface, struct d3d9_device *device, U break; } - /* FIXME: Check MAX bounds of MultisampleQuality. */ - if (multisample_quality > 0) - { - FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality); - multisample_quality = 0; - } - - wined3d_mutex_lock(); - hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format), - usage & WINED3DUSAGE_MASK, (enum wined3d_pool)pool, multisample_type, multisample_quality, - flags, surface, &d3d9_surface_wined3d_parent_ops, &surface->wined3d_surface); - wined3d_mutex_unlock(); - if (FAILED(hr)) - { - WARN("Failed to create wined3d surface, hr %#x.\n", hr); - return hr; - } - + wined3d_surface_incref(wined3d_surface); + surface->wined3d_surface = wined3d_surface; surface->parent_device = &device->IDirect3DDevice9Ex_iface; IDirect3DDevice9Ex_AddRef(surface->parent_device); - return D3D_OK; + *parent_ops = &d3d9_surface_wined3d_parent_ops; } struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) diff --git a/reactos/dll/directx/wine/d3d9/swapchain.c b/reactos/dll/directx/wine/d3d9/swapchain.c index c1be78f44b9..f5ec38307aa 100644 --- a/reactos/dll/directx/wine/d3d9/swapchain.c +++ b/reactos/dll/directx/wine/d3d9/swapchain.c @@ -22,19 +22,38 @@ #include "d3d9_private.h" -static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9(IDirect3DSwapChain9 *iface) +static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9Ex(IDirect3DSwapChain9Ex *iface) { - return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9_iface); + return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9Ex_iface); } -static HRESULT WINAPI d3d9_swapchain_QueryInterface(IDirect3DSwapChain9 *iface, REFIID riid, void **out) +static HRESULT WINAPI d3d9_swapchain_QueryInterface(IDirect3DSwapChain9Ex *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); if (IsEqualGUID(riid, &IID_IDirect3DSwapChain9) || IsEqualGUID(riid, &IID_IUnknown)) { - IDirect3DSwapChain9_AddRef(iface); + IDirect3DSwapChain9Ex_AddRef(iface); + *out = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_IDirect3DSwapChain9Ex)) + { + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(swapchain->parent_device); + + /* Find out if the creating d3d9 interface was created with Direct3DCreate9Ex. + * It doesn't matter with which function the device was created. */ + if (!device->d3d_parent->extended) + { + WARN("IDirect3D9 instance wasn't created with CreateDirect3D9Ex, returning E_NOINTERFACE.\n"); + *out = NULL; + return E_NOINTERFACE; + } + + IDirect3DSwapChain9Ex_AddRef(iface); *out = iface; return S_OK; } @@ -45,9 +64,9 @@ static HRESULT WINAPI d3d9_swapchain_QueryInterface(IDirect3DSwapChain9 *iface, return E_NOINTERFACE; } -static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9 *iface) +static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9Ex *iface) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); ULONG refcount = InterlockedIncrement(&swapchain->refcount); TRACE("%p increasing refcount to %u.\n", iface, refcount); @@ -65,9 +84,9 @@ static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9 *iface) return refcount; } -static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9 *iface) +static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9Ex *iface) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); ULONG refcount = InterlockedDecrement(&swapchain->refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount); @@ -88,11 +107,11 @@ static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9 *iface) return refcount; } -static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChain9 *iface, +static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChain9Ex *iface, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region, DWORD flags) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); HRESULT hr; TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n", @@ -107,9 +126,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai return hr; } -static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9 *iface, IDirect3DSurface9 *surface) +static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9Ex *iface, IDirect3DSurface9 *surface) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(surface); HRESULT hr; @@ -122,10 +141,10 @@ static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9 *ifa return hr; } -static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9 *iface, +static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9Ex *iface, UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); struct wined3d_surface *wined3d_surface = NULL; struct d3d9_surface *surface_impl; HRESULT hr = D3D_OK; @@ -150,9 +169,9 @@ static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9 *iface, return hr; } -static HRESULT WINAPI d3d9_swapchain_GetRasterStatus(IDirect3DSwapChain9 *iface, D3DRASTER_STATUS *raster_status) +static HRESULT WINAPI d3d9_swapchain_GetRasterStatus(IDirect3DSwapChain9Ex *iface, D3DRASTER_STATUS *raster_status) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); HRESULT hr; TRACE("iface %p, raster_status %p.\n", iface, raster_status); @@ -165,9 +184,9 @@ static HRESULT WINAPI d3d9_swapchain_GetRasterStatus(IDirect3DSwapChain9 *iface, return hr; } -static HRESULT WINAPI d3d9_swapchain_GetDisplayMode(IDirect3DSwapChain9 *iface, D3DDISPLAYMODE *mode) +static HRESULT WINAPI d3d9_swapchain_GetDisplayMode(IDirect3DSwapChain9Ex *iface, D3DDISPLAYMODE *mode) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); struct wined3d_display_mode wined3d_mode; HRESULT hr; @@ -188,9 +207,9 @@ static HRESULT WINAPI d3d9_swapchain_GetDisplayMode(IDirect3DSwapChain9 *iface, return hr; } -static HRESULT WINAPI d3d9_swapchain_GetDevice(IDirect3DSwapChain9 *iface, IDirect3DDevice9 **device) +static HRESULT WINAPI d3d9_swapchain_GetDevice(IDirect3DSwapChain9Ex *iface, IDirect3DDevice9 **device) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); TRACE("iface %p, device %p.\n", iface, device); @@ -202,10 +221,10 @@ static HRESULT WINAPI d3d9_swapchain_GetDevice(IDirect3DSwapChain9 *iface, IDire return D3D_OK; } -static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9 *iface, +static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9Ex *iface, D3DPRESENT_PARAMETERS *parameters) { - struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); struct wined3d_swapchain_desc desc; TRACE("iface %p, parameters %p.\n", iface, parameters); @@ -218,12 +237,64 @@ static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9 *i return D3D_OK; } - -static const struct IDirect3DSwapChain9Vtbl d3d9_swapchain_vtbl = +static HRESULT WINAPI d3d9_swapchain_GetLastPresentCount(IDirect3DSwapChain9Ex *iface, + UINT *last_present_count) { + FIXME("iface %p, last_present_count %p, stub!\n", iface, last_present_count); + + if (last_present_count) + *last_present_count = 0; + + return D3D_OK; +} + +static HRESULT WINAPI d3d9_swapchain_GetPresentStatistics(IDirect3DSwapChain9Ex *iface, + D3DPRESENTSTATS *present_stats) +{ + FIXME("iface %p, present_stats %p, stub!\n", iface, present_stats); + + if (present_stats) + memset(present_stats, 0, sizeof(*present_stats)); + + return D3D_OK; +} + +static HRESULT WINAPI d3d9_swapchain_GetDisplayModeEx(IDirect3DSwapChain9Ex *iface, + D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation) +{ + struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); + struct wined3d_display_mode wined3d_mode; + HRESULT hr; + + TRACE("iface %p, mode %p, rotation %p.\n", iface, mode, rotation); + + if (mode->Size != sizeof(*mode)) + return D3DERR_INVALIDCALL; + + wined3d_mutex_lock(); + hr = wined3d_swapchain_get_display_mode(swapchain->wined3d_swapchain, &wined3d_mode, + (enum wined3d_display_rotation *)rotation); + wined3d_mutex_unlock(); + + if (SUCCEEDED(hr)) + { + mode->Width = wined3d_mode.width; + mode->Height = wined3d_mode.height; + mode->RefreshRate = wined3d_mode.refresh_rate; + mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id); + mode->ScanLineOrdering = wined3d_mode.scanline_ordering; + } + + return hr; +} + +static const struct IDirect3DSwapChain9ExVtbl d3d9_swapchain_vtbl = +{ + /* IUnknown */ d3d9_swapchain_QueryInterface, d3d9_swapchain_AddRef, d3d9_swapchain_Release, + /* IDirect3DSwapChain9 */ d3d9_swapchain_Present, d3d9_swapchain_GetFrontBufferData, d3d9_swapchain_GetBackBuffer, @@ -231,6 +302,10 @@ static const struct IDirect3DSwapChain9Vtbl d3d9_swapchain_vtbl = d3d9_swapchain_GetDisplayMode, d3d9_swapchain_GetDevice, d3d9_swapchain_GetPresentParameters, + /* IDirect3DSwapChain9Ex */ + d3d9_swapchain_GetLastPresentCount, + d3d9_swapchain_GetPresentStatistics, + d3d9_swapchain_GetDisplayModeEx }; static void STDMETHODCALLTYPE d3d9_swapchain_wined3d_object_released(void *parent) @@ -249,7 +324,7 @@ static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_devi HRESULT hr; swapchain->refcount = 1; - swapchain->IDirect3DSwapChain9_iface.lpVtbl = &d3d9_swapchain_vtbl; + swapchain->IDirect3DSwapChain9Ex_iface.lpVtbl = &d3d9_swapchain_vtbl; wined3d_mutex_lock(); hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, diff --git a/reactos/dll/directx/wine/d3d9/texture.c b/reactos/dll/directx/wine/d3d9/texture.c index 74ff5d9261a..2cddc57e09a 100644 --- a/reactos/dll/directx/wine/d3d9/texture.c +++ b/reactos/dll/directx/wine/d3d9/texture.c @@ -1318,6 +1318,7 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage |= WINED3DUSAGE_TEXTURE; desc.pool = pool; desc.width = width; desc.height = height; @@ -1328,7 +1329,7 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, surface_flags |= WINED3D_SURFACE_MAPPABLE; wined3d_mutex_lock(); - hr = wined3d_texture_create_2d(device->wined3d_device, &desc, levels, surface_flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1358,6 +1359,7 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage |= WINED3DUSAGE_TEXTURE; desc.pool = pool; desc.width = edge_length; desc.height = edge_length; @@ -1368,7 +1370,7 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic surface_flags |= WINED3D_SURFACE_MAPPABLE; wined3d_mutex_lock(); - hr = wined3d_texture_create_cube(device->wined3d_device, &desc, levels, surface_flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1397,6 +1399,7 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage |= WINED3DUSAGE_TEXTURE; desc.pool = pool; desc.width = width; desc.height = height; @@ -1404,7 +1407,7 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev desc.size = 0; wined3d_mutex_lock(); - hr = wined3d_texture_create_3d(device->wined3d_device, &desc, levels, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) diff --git a/reactos/dll/directx/wine/d3d9/volume.c b/reactos/dll/directx/wine/d3d9/volume.c index ef54a56b680..b0a629080bc 100644 --- a/reactos/dll/directx/wine/d3d9/volume.c +++ b/reactos/dll/directx/wine/d3d9/volume.c @@ -271,22 +271,13 @@ static const struct wined3d_parent_ops d3d9_volume_wined3d_parent_ops = volume_wined3d_object_destroyed, }; -HRESULT volume_init(struct d3d9_volume *volume, struct d3d9_device *device, UINT width, UINT height, - UINT depth, UINT level, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool) +void volume_init(struct d3d9_volume *volume, struct wined3d_volume *wined3d_volume, + const struct wined3d_parent_ops **parent_ops) { - HRESULT hr; - volume->IDirect3DVolume9_iface.lpVtbl = &d3d9_volume_vtbl; volume->refcount = 1; + wined3d_volume_incref(wined3d_volume); + volume->wined3d_volume = wined3d_volume; - hr = wined3d_volume_create(device->wined3d_device, width, height, depth, level, - usage & WINED3DUSAGE_MASK, format, pool, volume, &d3d9_volume_wined3d_parent_ops, - &volume->wined3d_volume); - if (FAILED(hr)) - { - WARN("Failed to create wined3d volume, hr %#x.\n", hr); - return hr; - } - - return D3D_OK; + *parent_ops = &d3d9_volume_wined3d_parent_ops; } diff --git a/reactos/dll/directx/wine/ddraw/CMakeLists.txt b/reactos/dll/directx/wine/ddraw/CMakeLists.txt index 19f87562fbd..5872db063de 100644 --- a/reactos/dll/directx/wine/ddraw/CMakeLists.txt +++ b/reactos/dll/directx/wine/ddraw/CMakeLists.txt @@ -32,7 +32,7 @@ endif() add_library(ddraw SHARED ${SOURCE} ddraw.rc) set_module_type(ddraw win32dll) target_link_libraries(ddraw wine uuid dxguid ${PSEH_LIB}) -add_importlibs(ddraw advapi32 gdi32 ole32 user32 wined3d msvcrt kernel32 ntdll) +add_importlibs(ddraw advapi32 gdi32 user32 wined3d msvcrt kernel32 ntdll) add_dependencies(ddraw wineheaders) add_pch(ddraw ddraw_private.h) add_cd_file(TARGET ddraw DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/directx/wine/ddraw/ddraw.c b/reactos/dll/directx/wine/ddraw/ddraw.c index e1587a4e23a..272e10969a9 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw.c +++ b/reactos/dll/directx/wine/ddraw/ddraw.c @@ -773,21 +773,29 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, wined3d_mutex_lock(); + if (ddraw->flags & DDRAW_SCL_RECURSIVE) + { + WARN("Recursive call, returning DD_OK.\n"); + hr = DD_OK; + goto done; + } + ddraw->flags |= DDRAW_SCL_RECURSIVE; + /* Tests suggest that we need one of them: */ if(!(cooplevel & (DDSCL_SETFOCUSWINDOW | DDSCL_NORMAL | DDSCL_EXCLUSIVE ))) { TRACE("Incorrect cooplevel flags, returning DDERR_INVALIDPARAMS\n"); - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; + hr = DDERR_INVALIDPARAMS; + goto done; } if ((cooplevel & DDSCL_CREATEDEVICEWINDOW) && !(cooplevel & DDSCL_EXCLUSIVE)) { WARN("DDSCL_CREATEDEVICEWINDOW requires DDSCL_EXCLUSIVE.\n"); - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; + hr = DDERR_INVALIDPARAMS; + goto done; } /* Handle those levels first which set various hwnds */ @@ -805,13 +813,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, | DDSCL_FULLSCREEN)) { WARN("Called with incompatible flags, returning DDERR_INVALIDPARAMS.\n"); - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; + hr = DDERR_INVALIDPARAMS; + goto done; } hr = ddraw_set_focus_window(ddraw, window); - wined3d_mutex_unlock(); - return hr; + goto done; } if (cooplevel & DDSCL_EXCLUSIVE) @@ -819,8 +826,8 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, if (!(cooplevel & DDSCL_FULLSCREEN) || !(window || (cooplevel & DDSCL_CREATEDEVICEWINDOW))) { WARN("DDSCL_EXCLUSIVE requires DDSCL_FULLSCREEN and a window.\n"); - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; + hr = DDERR_INVALIDPARAMS; + goto done; } if (cooplevel & DDSCL_CREATEDEVICEWINDOW) @@ -830,8 +837,8 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, if (!ddraw->focuswindow && !(cooplevel & DDSCL_SETFOCUSWINDOW)) { WARN("No focus window set.\n"); - wined3d_mutex_unlock(); - return DDERR_NOFOCUSWINDOW; + hr = DDERR_NOFOCUSWINDOW; + goto done; } device_window = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "DirectDrawDeviceWnd", @@ -840,8 +847,8 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, if (!device_window) { ERR("Failed to create window, last error %#x.\n", GetLastError()); - wined3d_mutex_unlock(); - return E_FAIL; + hr = E_FAIL; + goto done; } ShowWindow(device_window, SW_SHOW); @@ -856,15 +863,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, { if (!window) { - wined3d_mutex_unlock(); - return DDERR_NOHWND; + hr = DDERR_NOHWND; + goto done; } if (FAILED(hr = ddraw_set_focus_window(ddraw, window))) - { - wined3d_mutex_unlock(); - return hr; - } + goto done; } window = device_window; @@ -905,8 +909,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, WINED3D_SBT_ALL, &stateblock))) { ERR("Failed to create stateblock, hr %#x.\n", hr); - wined3d_mutex_unlock(); - return hr; + goto done; } wined3d_stateblock_capture(stateblock); @@ -963,8 +966,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, if (FAILED(hr)) { ERR("Failed to acquire focus window, hr %#x.\n", hr); - wined3d_mutex_unlock(); - return hr; + goto done; } } @@ -986,9 +988,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ddraw->dest_window = window; TRACE("SetCooperativeLevel retuning DD_OK\n"); + hr = DD_OK; +done: + ddraw->flags &= ~DDRAW_SCL_RECURSIVE; wined3d_mutex_unlock(); - return DD_OK; + return hr; } static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND window, DWORD flags) @@ -1155,6 +1160,269 @@ static HRESULT WINAPI ddraw1_SetDisplayMode(IDirectDraw *iface, DWORD width, DWO return ddraw7_SetDisplayMode(&ddraw->IDirectDraw7_iface, width, height, bpp, 0, 0); } +void ddraw_d3dcaps1_from_7(D3DDEVICEDESC *caps1, D3DDEVICEDESC7 *caps7) +{ + memset(caps1, 0, sizeof(*caps1)); + caps1->dwSize = sizeof(*caps1); + caps1->dwFlags = D3DDD_COLORMODEL + | D3DDD_DEVCAPS + | D3DDD_TRANSFORMCAPS + | D3DDD_BCLIPPING + | D3DDD_LIGHTINGCAPS + | D3DDD_LINECAPS + | D3DDD_TRICAPS + | D3DDD_DEVICERENDERBITDEPTH + | D3DDD_DEVICEZBUFFERBITDEPTH + | D3DDD_MAXBUFFERSIZE + | D3DDD_MAXVERTEXCOUNT; + caps1->dcmColorModel = D3DCOLOR_RGB; + caps1->dwDevCaps = caps7->dwDevCaps; + caps1->dtcTransformCaps.dwSize = sizeof(caps1->dtcTransformCaps); + caps1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP; + caps1->bClipping = TRUE; + caps1->dlcLightingCaps.dwSize = sizeof(caps1->dlcLightingCaps); + caps1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL + | D3DLIGHTCAPS_PARALLELPOINT + | D3DLIGHTCAPS_POINT + | D3DLIGHTCAPS_SPOT; + caps1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB; + caps1->dlcLightingCaps.dwNumLights = caps7->dwMaxActiveLights; + caps1->dpcLineCaps = caps7->dpcLineCaps; + caps1->dpcTriCaps = caps7->dpcTriCaps; + caps1->dwDeviceRenderBitDepth = caps7->dwDeviceRenderBitDepth; + caps1->dwDeviceZBufferBitDepth = caps7->dwDeviceZBufferBitDepth; + caps1->dwMaxBufferSize = 0; + caps1->dwMaxVertexCount = 65536; + caps1->dwMinTextureWidth = caps7->dwMinTextureWidth; + caps1->dwMinTextureHeight = caps7->dwMinTextureHeight; + caps1->dwMaxTextureWidth = caps7->dwMaxTextureWidth; + caps1->dwMaxTextureHeight = caps7->dwMaxTextureHeight; + caps1->dwMinStippleWidth = 1; + caps1->dwMinStippleHeight = 1; + caps1->dwMaxStippleWidth = 32; + caps1->dwMaxStippleHeight = 32; + caps1->dwMaxTextureRepeat = caps7->dwMaxTextureRepeat; + caps1->dwMaxTextureAspectRatio = caps7->dwMaxTextureAspectRatio; + caps1->dwMaxAnisotropy = caps7->dwMaxAnisotropy; + caps1->dvGuardBandLeft = caps7->dvGuardBandLeft; + caps1->dvGuardBandTop = caps7->dvGuardBandTop; + caps1->dvGuardBandRight = caps7->dvGuardBandRight; + caps1->dvGuardBandBottom = caps7->dvGuardBandBottom; + caps1->dvExtentsAdjust = caps7->dvExtentsAdjust; + caps1->dwStencilCaps = caps7->dwStencilCaps; + caps1->dwFVFCaps = caps7->dwFVFCaps; + caps1->dwTextureOpCaps = caps7->dwTextureOpCaps; + caps1->wMaxTextureBlendStages = caps7->wMaxTextureBlendStages; + caps1->wMaxSimultaneousTextures = caps7->wMaxSimultaneousTextures; +} + +HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) +{ + WINED3DCAPS wined3d_caps; + HRESULT hr; + + TRACE("ddraw %p, caps %p.\n", ddraw, caps); + + memset(&wined3d_caps, 0, sizeof(wined3d_caps)); + + wined3d_mutex_lock(); + hr = wined3d_get_device_caps(ddraw->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, &wined3d_caps); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + WARN("Failed to get device caps, hr %#x.\n", hr); + return hr; + } + + caps->dwDevCaps = wined3d_caps.DevCaps; + caps->dpcLineCaps.dwMiscCaps = wined3d_caps.PrimitiveMiscCaps; + caps->dpcLineCaps.dwRasterCaps = wined3d_caps.RasterCaps; + caps->dpcLineCaps.dwZCmpCaps = wined3d_caps.ZCmpCaps; + caps->dpcLineCaps.dwSrcBlendCaps = wined3d_caps.SrcBlendCaps; + caps->dpcLineCaps.dwDestBlendCaps = wined3d_caps.DestBlendCaps; + caps->dpcLineCaps.dwAlphaCmpCaps = wined3d_caps.AlphaCmpCaps; + caps->dpcLineCaps.dwShadeCaps = wined3d_caps.ShadeCaps; + caps->dpcLineCaps.dwTextureCaps = wined3d_caps.TextureCaps; + caps->dpcLineCaps.dwTextureFilterCaps = wined3d_caps.TextureFilterCaps; + caps->dpcLineCaps.dwTextureAddressCaps = wined3d_caps.TextureAddressCaps; + + caps->dwMaxTextureWidth = wined3d_caps.MaxTextureWidth; + caps->dwMaxTextureHeight = wined3d_caps.MaxTextureHeight; + + caps->dwMaxTextureRepeat = wined3d_caps.MaxTextureRepeat; + caps->dwMaxTextureAspectRatio = wined3d_caps.MaxTextureAspectRatio; + caps->dwMaxAnisotropy = wined3d_caps.MaxAnisotropy; + caps->dvMaxVertexW = wined3d_caps.MaxVertexW; + + caps->dvGuardBandLeft = wined3d_caps.GuardBandLeft; + caps->dvGuardBandTop = wined3d_caps.GuardBandTop; + caps->dvGuardBandRight = wined3d_caps.GuardBandRight; + caps->dvGuardBandBottom = wined3d_caps.GuardBandBottom; + + caps->dvExtentsAdjust = wined3d_caps.ExtentsAdjust; + caps->dwStencilCaps = wined3d_caps.StencilCaps; + + caps->dwFVFCaps = wined3d_caps.FVFCaps; + caps->dwTextureOpCaps = wined3d_caps.TextureOpCaps; + + caps->dwVertexProcessingCaps = wined3d_caps.VertexProcessingCaps; + caps->dwMaxActiveLights = wined3d_caps.MaxActiveLights; + + /* Remove all non-d3d7 caps */ + caps->dwDevCaps &= ( + D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_SORTINCREASINGZ | D3DDEVCAPS_SORTDECREASINGZ | + D3DDEVCAPS_SORTEXACT | D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_EXECUTEVIDEOMEMORY | + D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY | + D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_CANRENDERAFTERFLIP | + D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_SEPARATETEXTUREMEMORIES | + D3DDEVCAPS_DRAWPRIMITIVES2EX | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_CANBLTSYSTONONLOCAL | + D3DDEVCAPS_HWRASTERIZATION); + + caps->dwStencilCaps &= ( + D3DSTENCILCAPS_KEEP | D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | + D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INVERT | + D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR); + + /* FVF caps ?*/ + + caps->dwTextureOpCaps &= ( + D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2 | + D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_MODULATE2X | D3DTEXOPCAPS_MODULATE4X | + D3DTEXOPCAPS_ADD | D3DTEXOPCAPS_ADDSIGNED | D3DTEXOPCAPS_ADDSIGNED2X | + D3DTEXOPCAPS_SUBTRACT | D3DTEXOPCAPS_ADDSMOOTH | D3DTEXOPCAPS_BLENDTEXTUREALPHA | + D3DTEXOPCAPS_BLENDFACTORALPHA | D3DTEXOPCAPS_BLENDTEXTUREALPHAPM | D3DTEXOPCAPS_BLENDCURRENTALPHA | + D3DTEXOPCAPS_PREMODULATE | D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR | D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA | + D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR | D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA | D3DTEXOPCAPS_BUMPENVMAP | + D3DTEXOPCAPS_BUMPENVMAPLUMINANCE | D3DTEXOPCAPS_DOTPRODUCT3); + + caps->dwVertexProcessingCaps &= ( + D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | + D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER); + + caps->dpcLineCaps.dwMiscCaps &= ( + D3DPMISCCAPS_MASKPLANES | D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP | + D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | + D3DPMISCCAPS_CULLCCW); + + caps->dpcLineCaps.dwRasterCaps &= ( + D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ROP2 | D3DPRASTERCAPS_XOR | + D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL | + D3DPRASTERCAPS_SUBPIXELX | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | + D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT | D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT | + D3DPRASTERCAPS_ANTIALIASEDGES | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBIAS | + D3DPRASTERCAPS_ZBUFFERLESSHSR | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | + D3DPRASTERCAPS_WBUFFER | D3DPRASTERCAPS_TRANSLUCENTSORTINDEPENDENT | D3DPRASTERCAPS_WFOG | + D3DPRASTERCAPS_ZFOG); + + caps->dpcLineCaps.dwZCmpCaps &= ( + D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | + D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | + D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS); + + caps->dpcLineCaps.dwSrcBlendCaps &= ( + D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | + D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | + D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR | + D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA | + D3DPBLENDCAPS_BOTHINVSRCALPHA); + + caps->dpcLineCaps.dwDestBlendCaps &= ( + D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | + D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | + D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR | + D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA | + D3DPBLENDCAPS_BOTHINVSRCALPHA); + + caps->dpcLineCaps.dwAlphaCmpCaps &= ( + D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | + D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | + D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS); + + caps->dpcLineCaps.dwShadeCaps &= ( + D3DPSHADECAPS_COLORFLATMONO | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDMONO | + D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_COLORPHONGMONO | D3DPSHADECAPS_COLORPHONGRGB | + D3DPSHADECAPS_SPECULARFLATMONO | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDMONO | + D3DPSHADECAPS_SPECULARGOURAUDRGB | D3DPSHADECAPS_SPECULARPHONGMONO | D3DPSHADECAPS_SPECULARPHONGRGB | + D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAFLATSTIPPLED | D3DPSHADECAPS_ALPHAGOURAUDBLEND | + D3DPSHADECAPS_ALPHAGOURAUDSTIPPLED | D3DPSHADECAPS_ALPHAPHONGBLEND | D3DPSHADECAPS_ALPHAPHONGSTIPPLED | + D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_FOGPHONG); + + caps->dpcLineCaps.dwTextureCaps &= ( + D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA | + D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_SQUAREONLY | + D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE| D3DPTEXTURECAPS_NONPOW2CONDITIONAL | + D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_COLORKEYBLEND); + + caps->dpcLineCaps.dwTextureFilterCaps &= ( + D3DPTFILTERCAPS_NEAREST | D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_MIPNEAREST | + D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST | D3DPTFILTERCAPS_LINEARMIPLINEAR | + D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFANISOTROPIC | + D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | + D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC | + D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC); + + caps->dpcLineCaps.dwTextureAddressCaps &= ( + D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | + D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV); + + if (!(caps->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2)) + { + /* DirectX7 always has the np2 flag set, no matter what the card + * supports. Some old games (Rollcage) check the caps incorrectly. + * If wined3d supports nonpow2 textures it also has np2 conditional + * support. */ + caps->dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL; + } + + /* Fill the missing members, and do some fixup */ + caps->dpcLineCaps.dwSize = sizeof(caps->dpcLineCaps); + caps->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD + | D3DPTBLENDCAPS_MODULATEMASK + | D3DPTBLENDCAPS_COPY + | D3DPTBLENDCAPS_DECAL + | D3DPTBLENDCAPS_DECALALPHA + | D3DPTBLENDCAPS_DECALMASK + | D3DPTBLENDCAPS_MODULATE + | D3DPTBLENDCAPS_MODULATEALPHA; + caps->dpcLineCaps.dwStippleWidth = 32; + caps->dpcLineCaps.dwStippleHeight = 32; + /* Use the same for the TriCaps */ + caps->dpcTriCaps = caps->dpcLineCaps; + + caps->dwDeviceRenderBitDepth = DDBD_16 | DDBD_24 | DDBD_32; + caps->dwDeviceZBufferBitDepth = DDBD_16 | DDBD_24; + caps->dwMinTextureWidth = 1; + caps->dwMinTextureHeight = 1; + + /* Convert DWORDs safely to WORDs */ + if (wined3d_caps.MaxTextureBlendStages > 0xffff) + caps->wMaxTextureBlendStages = 0xffff; + else + caps->wMaxTextureBlendStages = (WORD)wined3d_caps.MaxTextureBlendStages; + if (wined3d_caps.MaxSimultaneousTextures > 0xffff) + caps->wMaxSimultaneousTextures = 0xffff; + else + caps->wMaxSimultaneousTextures = (WORD)wined3d_caps.MaxSimultaneousTextures; + + if (wined3d_caps.MaxUserClipPlanes > 0xffff) + caps->wMaxUserClipPlanes = 0xffff; + else + caps->wMaxUserClipPlanes = (WORD)wined3d_caps.MaxUserClipPlanes; + if (wined3d_caps.MaxVertexBlendMatrices > 0xffff) + caps->wMaxVertexBlendMatrices = 0xffff; + else + caps->wMaxVertexBlendMatrices = (WORD)wined3d_caps.MaxVertexBlendMatrices; + + caps->deviceGUID = IID_IDirect3DTnLHalDevice; + + caps->dwReserved1 = 0; + caps->dwReserved2 = 0; + caps->dwReserved3 = 0; + caps->dwReserved4 = 0; + + return DD_OK; +} + /***************************************************************************** * IDirectDraw7::GetCaps * @@ -1201,9 +1469,18 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD } hr = IDirectDraw7_GetAvailableVidMem(iface, &ddscaps, &caps.dwVidMemTotal, &caps.dwVidMemFree); - wined3d_mutex_unlock(); - if(FAILED(hr)) { + if (FAILED(hr)) + { WARN("IDirectDraw7::GetAvailableVidMem failed\n"); + wined3d_mutex_unlock(); + return hr; + } + + hr = IDirectDraw7_GetFourCCCodes(iface, &caps.dwNumFourCCCodes, NULL); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + WARN("IDirectDraw7::GetFourCCCodes failed\n"); return hr; } @@ -1211,7 +1488,7 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD caps.dwCaps2 = winecaps.ddraw_caps.caps2; caps.dwCKeyCaps = winecaps.ddraw_caps.color_key_caps; caps.dwFXCaps = winecaps.ddraw_caps.fx_caps; - caps.dwPalCaps = winecaps.ddraw_caps.pal_caps; + caps.dwPalCaps = DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE; caps.ddsCaps.dwCaps = winecaps.ddraw_caps.dds_caps; caps.dwSVBCaps = winecaps.ddraw_caps.svb_caps; caps.dwSVBCKeyCaps = winecaps.ddraw_caps.svb_color_key_caps; @@ -2449,420 +2726,6 @@ static HRESULT WINAPI ddraw7_StartModeTest(IDirectDraw7 *iface, SIZE *Modes, DWO return DD_OK; } -/***************************************************************************** - * ddraw_create_surface - * - * A helper function for IDirectDraw7::CreateSurface. It creates a new surface - * with the passed parameters. - * - * Params: - * DDSD: Description of the surface to create - * Surf: Address to store the interface pointer at - * - * Returns: - * DD_OK on success - * - *****************************************************************************/ -static HRESULT ddraw_create_surface(struct ddraw *ddraw, DDSURFACEDESC2 *desc, - DWORD flags, struct ddraw_surface **surface, UINT version) -{ - HRESULT hr; - - TRACE("ddraw %p, desc %p, flags %#x, surface %p.\n", ddraw, desc, flags, surface); - - if (TRACE_ON(ddraw)) - { - TRACE("Requesting surface desc:\n"); - DDRAW_dump_surface_desc(desc); - } - - if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && (ddraw->flags & DDRAW_NO3D)) - { - WARN("The application requests a 3D capable surface, but the ddraw object was created without 3D support.\n"); - /* Do not fail surface creation, only fail 3D device creation. */ - } - - /* Create the Surface object */ - *surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**surface)); - if (!*surface) - { - ERR("Failed to allocate surface memory.\n"); - return DDERR_OUTOFVIDEOMEMORY; - } - - if (FAILED(hr = ddraw_surface_init(*surface, ddraw, desc, flags, version))) - { - WARN("Failed to initialize surface, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, *surface); - return hr; - } - - /* Increase the surface counter, and attach the surface */ - list_add_head(&ddraw->surface_list, &(*surface)->surface_list_entry); - - TRACE("Created surface %p.\n", *surface); - - return DD_OK; -} - -static HRESULT CDECL ddraw_reset_enum_callback(struct wined3d_resource *resource) -{ - return DD_OK; -} - -/***************************************************************************** - * IDirectDraw7::CreateSurface - * - * Creates a new IDirectDrawSurface object and returns its interface. - * - * The surface connections with wined3d are a bit tricky. Basically it works - * like this: - * - * |------------------------| |-----------------| - * | DDraw surface | | WineD3DSurface | - * | | | | - * | WineD3DSurface |-------------->| | - * | Child |<------------->| Parent | - * |------------------------| |-----------------| - * - * The DDraw surface is the parent of the wined3d surface, and it releases - * the WineD3DSurface when the ddraw surface is destroyed. - * - * However, for all surfaces which can be in a container in WineD3D, - * we have to do this. These surfaces are usually complex surfaces, - * so this concerns primary surfaces with a front and a back buffer, - * and textures. - * - * |------------------------| |-----------------| - * | DDraw surface | | Container | - * | | | | - * | Child |<------------->| Parent | - * | Texture |<------------->| | - * | WineD3DSurface |<----| | Levels |<--| - * | Complex connection | | | | | - * |------------------------| | |-----------------| | - * ^ | | - * | | | - * | | | - * | |------------------| | |-----------------| | - * | | IParent | |-------->| WineD3DSurface | | - * | | | | | | - * | | Child |<------------->| Parent | | - * | | | | Container |<--| - * | |------------------| |-----------------| | - * | | - * | |----------------------| | - * | | DDraw surface 2 | | - * | | | | - * |<->| Complex root Child | | - * | | Texture | | - * | | WineD3DSurface |<----| | - * | |----------------------| | | - * | | | - * | |---------------------| | |-----------------| | - * | | IParent | |----->| WineD3DSurface | | - * | | | | | | - * | | Child |<---------->| Parent | | - * | |---------------------| | Container |<--| - * | |-----------------| | - * | | - * | ---More surfaces can follow--- | - * - * The reason is that the IWineD3DSwapchain(render target container) - * and the IWineD3DTexure(Texture container) release the parents - * of their surface's children, but by releasing the complex root - * the surfaces which are complexly attached to it are destroyed - * too. See IDirectDrawSurface::Release for a more detailed - * explanation. - * - * Params: - * DDSD: Description of the surface to create - * Surf: Address to store the interface pointer at - * UnkOuter: Basically for aggregation support, but ddraw doesn't support - * aggregation, so it has to be NULL - * - * Returns: - * DD_OK on success - * CLASS_E_NOAGGREGATION if UnkOuter != NULL - * DDERR_* if an error occurs - * - *****************************************************************************/ -static HRESULT CreateSurface(struct ddraw *ddraw, DDSURFACEDESC2 *DDSD, - struct ddraw_surface **surface, IUnknown *UnkOuter, UINT version) -{ - struct ddraw_surface *object = NULL; - struct wined3d_display_mode mode; - HRESULT hr; - DDSURFACEDESC2 desc2; - const DWORD sysvidmem = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY; - /* Some applications assume surfaces will always be mapped at the same - * address. Some of those also assume that this address is valid even when - * the surface isn't mapped, and that updates done this way will be - * visible on the screen. The game Nox is such an application, - * Commandos: Behind Enemy Lines is another. */ - const DWORD flags = WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_PIN_SYSMEM; - - TRACE("ddraw %p, surface_desc %p, surface %p, outer_unknown %p.\n", ddraw, DDSD, surface, UnkOuter); - - /* Some checks before we start */ - if (TRACE_ON(ddraw)) - { - TRACE(" (%p) Requesting surface desc :\n", ddraw); - DDRAW_dump_surface_desc(DDSD); - } - - if (UnkOuter != NULL) - { - FIXME("(%p) : outer != NULL?\n", ddraw); - return CLASS_E_NOAGGREGATION; /* unchecked */ - } - - if (!surface) - { - FIXME("(%p) You want to get back a surface? Don't give NULL ptrs!\n", ddraw); - return E_POINTER; /* unchecked */ - } - - if (!(DDSD->dwFlags & DDSD_CAPS)) - { - /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */ - DDSD->dwFlags |= DDSD_CAPS; - } - - if (DDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) - { - /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */ - DDSD->dwFlags &= ~DDSD_LPSURFACE; - } - - if ((DDSD->dwFlags & DDSD_LPSURFACE) && (DDSD->lpSurface == NULL)) - { - /* Frank Herbert's Dune specifies a null pointer for the surface, ignore the LPSURFACE field */ - WARN("(%p) Null surface pointer specified, ignore it!\n", ddraw); - DDSD->dwFlags &= ~DDSD_LPSURFACE; - } - - if((DDSD->ddsCaps.dwCaps & (DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE)) == (DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE) && - !(ddraw->cooperative_level & DDSCL_EXCLUSIVE)) - { - TRACE("(%p): Attempt to create a flipable primary surface without DDSCL_EXCLUSIVE set\n", - ddraw); - *surface = NULL; - return DDERR_NOEXCLUSIVEMODE; - } - - if((DDSD->ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER | DDSCAPS_PRIMARYSURFACE)) == (DDSCAPS_BACKBUFFER | DDSCAPS_PRIMARYSURFACE)) - { - WARN("Application wanted to create back buffer primary surface\n"); - return DDERR_INVALIDCAPS; - } - - if((DDSD->ddsCaps.dwCaps & sysvidmem) == sysvidmem) - { - /* This is a special switch in ddrawex.dll, but not allowed in ddraw.dll */ - WARN("Application tries to put the surface in both system and video memory\n"); - *surface = NULL; - return DDERR_INVALIDCAPS; - } - - /* Check cube maps but only if the size includes them */ - if (DDSD->dwSize >= sizeof(DDSURFACEDESC2)) - { - if(DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES && - !(DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)) - { - WARN("Cube map faces requested without cube map flag\n"); - return DDERR_INVALIDCAPS; - } - if(DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP && - (DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) == 0) - { - WARN("Cube map without faces requested\n"); - return DDERR_INVALIDPARAMS; - } - - /* Quick tests confirm those can be created, but we don't do that yet */ - if(DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP && - (DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) != DDSCAPS2_CUBEMAP_ALLFACES) - { - FIXME("Partial cube maps not supported yet\n"); - } - } - - /* According to the msdn this flag is ignored by CreateSurface */ - if (DDSD->dwSize >= sizeof(DDSURFACEDESC2)) - DDSD->ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL; - - /* Modify some flags */ - copy_to_surfacedesc2(&desc2, DDSD); - desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); /* Just to be sure */ - - if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL))) - { - ERR("Failed to get display mode, hr %#x.\n", hr); - return hr; - } - - /* No pixelformat given? Use the current screen format */ - if(!(desc2.dwFlags & DDSD_PIXELFORMAT)) - { - desc2.dwFlags |= DDSD_PIXELFORMAT; - desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); - - ddrawformat_from_wined3dformat(&desc2.u4.ddpfPixelFormat, mode.format_id); - } - - /* No Width or no Height? Use the original screen size - */ - if(!(desc2.dwFlags & DDSD_WIDTH) || - !(desc2.dwFlags & DDSD_HEIGHT) ) - { - /* Invalid for non-render targets */ - if(!(desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) - { - WARN("Creating a non-Primary surface without Width or Height info, returning DDERR_INVALIDPARAMS\n"); - *surface = NULL; - return DDERR_INVALIDPARAMS; - } - - desc2.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT; - desc2.dwWidth = mode.width; - desc2.dwHeight = mode.height; - } - - if (!desc2.dwWidth || !desc2.dwHeight) - return DDERR_INVALIDPARAMS; - - /* Mipmap count fixes */ - if(desc2.ddsCaps.dwCaps & DDSCAPS_MIPMAP) - { - if(desc2.ddsCaps.dwCaps & DDSCAPS_COMPLEX) - { - if(desc2.dwFlags & DDSD_MIPMAPCOUNT) - { - /* Mipmap count is given, should not be 0 */ - if( desc2.u2.dwMipMapCount == 0 ) - return DDERR_INVALIDPARAMS; - } - else - { - /* Undocumented feature: Create sublevels until - * either the width or the height is 1 - */ - DWORD min = desc2.dwWidth < desc2.dwHeight ? - desc2.dwWidth : desc2.dwHeight; - desc2.u2.dwMipMapCount = 0; - while( min ) - { - desc2.u2.dwMipMapCount += 1; - min >>= 1; - } - } - } - else - { - /* Not-complex mipmap -> Mipmapcount = 1 */ - desc2.u2.dwMipMapCount = 1; - } - - /* There's a mipmap count in the created surface in any case */ - desc2.dwFlags |= DDSD_MIPMAPCOUNT; - } - /* If no mipmap is given, the texture has only one level */ - - /* The first surface is a front buffer, the back buffer is created afterwards */ - if( (desc2.dwFlags & DDSD_CAPS) && (desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) ) - { - desc2.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; - } - - /* The root surface in a cube map is positive x */ - if(desc2.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) - { - desc2.ddsCaps.dwCaps2 &= ~DDSCAPS2_CUBEMAP_ALLFACES; - desc2.ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP_POSITIVEX; - } - - if ((desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE)) - { - struct wined3d_swapchain_desc swapchain_desc; - - wined3d_swapchain_get_desc(ddraw->wined3d_swapchain, &swapchain_desc); - swapchain_desc.backbuffer_width = mode.width; - swapchain_desc.backbuffer_height = mode.height; - swapchain_desc.backbuffer_format = mode.format_id; - - hr = wined3d_device_reset(ddraw->wined3d_device, - &swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE); - if (FAILED(hr)) - { - ERR("Failed to reset device.\n"); - return hr; - } - } - - /* Create the first surface */ - if (FAILED(hr = ddraw_create_surface(ddraw, &desc2, flags, &object, version))) - { - WARN("ddraw_create_surface failed, hr %#x.\n", hr); - return hr; - } - object->is_complex_root = TRUE; - - *surface = object; - - /* Create Additional surfaces if necessary - * This applies to Primary surfaces which have a back buffer count - * set, but not to mipmap textures. In case of Mipmap textures, - * wineD3D takes care of the creation of additional surfaces - */ - if(DDSD->dwFlags & DDSD_BACKBUFFERCOUNT) - { - struct ddraw_surface *last = object; - UINT i; - - desc2.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER; /* It's not a front buffer */ - desc2.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; - desc2.u5.dwBackBufferCount = 0; - - for (i = 0; i < DDSD->u5.dwBackBufferCount; ++i) - { - struct ddraw_surface *object2 = NULL; - - if (FAILED(hr = ddraw_create_surface(ddraw, &desc2, flags, &object2, version))) - { - if (version == 7) - IDirectDrawSurface7_Release(&object->IDirectDrawSurface7_iface); - else if (version == 4) - IDirectDrawSurface4_Release(&object->IDirectDrawSurface4_iface); - else - IDirectDrawSurface_Release(&object->IDirectDrawSurface_iface); - - return hr; - } - - /* Add the new surface to the complex attachment array. */ - last->complex_array[0] = object2; - last = object2; - - /* Remove the (possible) back buffer cap from the new surface - * description, because only one surface in the flipping chain is a - * back buffer, one is a front buffer, the others are just primary - * surfaces. */ - desc2.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; - } - } - - if (desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - ddraw->primary = object; - - /* Create a WineD3DTexture if a texture was requested */ - if (desc2.ddsCaps.dwCaps & DDSCAPS_TEXTURE) - ddraw_surface_create_texture(object, flags); - - return hr; -} - static HRESULT WINAPI ddraw7_CreateSurface(IDirectDraw7 *iface, DDSURFACEDESC2 *surface_desc, IDirectDrawSurface7 **surface, IUnknown *outer_unknown) { @@ -2902,7 +2765,7 @@ static HRESULT WINAPI ddraw7_CreateSurface(IDirectDraw7 *iface, DDSURFACEDESC2 * return DDERR_INVALIDCAPS; } - hr = CreateSurface(ddraw, surface_desc, &impl, outer_unknown, 7); + hr = ddraw_surface_create(ddraw, surface_desc, &impl, outer_unknown, 7); wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -2956,7 +2819,7 @@ static HRESULT WINAPI ddraw4_CreateSurface(IDirectDraw4 *iface, return DDERR_INVALIDCAPS; } - hr = CreateSurface(ddraw, surface_desc, &impl, outer_unknown, 4); + hr = ddraw_surface_create(ddraw, surface_desc, &impl, outer_unknown, 4); wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -3012,7 +2875,7 @@ static HRESULT WINAPI ddraw2_CreateSurface(IDirectDraw2 *iface, return DDERR_INVALIDCAPS; } - hr = CreateSurface(ddraw, &surface_desc2, &impl, outer_unknown, 2); + hr = ddraw_surface_create(ddraw, &surface_desc2, &impl, outer_unknown, 2); wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -3053,11 +2916,18 @@ static HRESULT WINAPI ddraw1_CreateSurface(IDirectDraw *iface, return DDERR_INVALIDPARAMS; } - /* Remove front buffer flag, this causes failure in v7, and its added to normal - * primaries anyway. */ - surface_desc->ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER; + if ((surface_desc->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER)) + == (DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER) + || (surface_desc->ddsCaps.dwCaps & (DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER)) + == ((DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER))) + { + WARN("Application tried to create an explicit front or back buffer.\n"); + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + DDSD_to_DDSD2(surface_desc, &surface_desc2); - hr = CreateSurface(ddraw, &surface_desc2, &impl, outer_unknown, 1); + hr = ddraw_surface_create(ddraw, &surface_desc2, &impl, outer_unknown, 1); wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -3682,7 +3552,6 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA { struct ddraw *ddraw = impl_from_IDirect3D7(iface); D3DDEVICEDESC7 device_desc7; - D3DDEVICEDESC device_desc1; HRESULT hr; size_t i; @@ -3693,8 +3562,7 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA wined3d_mutex_lock(); - hr = IDirect3DImpl_GetCaps(ddraw->wined3d, &device_desc1, &device_desc7); - if (hr != D3D_OK) + if (FAILED(hr = ddraw_get_d3dcaps(ddraw, &device_desc7))) { wined3d_mutex_unlock(); return hr; @@ -3760,12 +3628,12 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA wined3d_mutex_lock(); - hr = IDirect3DImpl_GetCaps(ddraw->wined3d, &device_desc1, &device_desc7); - if (hr != D3D_OK) + if (FAILED(hr = ddraw_get_d3dcaps(ddraw, &device_desc7))) { wined3d_mutex_unlock(); return hr; } + ddraw_d3dcaps1_from_7(&device_desc1, &device_desc7); /* Do I have to enumerate the reference id? Note from old d3d7: * "It seems that enumerating the reference IID on Direct3D 1 games @@ -4124,10 +3992,11 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd } /* Get the caps */ - hr = IDirect3DImpl_GetCaps(ddraw->wined3d, &desc1, &desc7); - if (hr != D3D_OK) return hr; + if (FAILED(hr = ddraw_get_d3dcaps(ddraw, &desc7))) + return hr; /* Now return our own GUID */ + ddraw_d3dcaps1_from_7(&desc1, &desc7); fdr->guid = IID_D3DDEVICE_WineD3D; fdr->ddHwDesc = desc1; fdr->ddSwDesc = desc1; @@ -4187,9 +4056,10 @@ 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(); - hr = d3d_device_create(ddraw, target, 7, &object, NULL); - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr = d3d_device_create(ddraw, target, (IUnknown *)surface, 7, &object, NULL))) + { *device = &object->IDirect3DDevice7_iface; + } else { WARN("Failed to create device, hr %#x.\n", hr); @@ -4215,9 +4085,10 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid, return CLASS_E_NOAGGREGATION; wined3d_mutex_lock(); - hr = d3d_device_create(ddraw, surface_impl, 3, &device_impl, NULL); - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) + { *device = &device_impl->IDirect3DDevice3_iface; + } else { WARN("Failed to create device, hr %#x.\n", hr); @@ -4240,9 +4111,10 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid, iface, debugstr_guid(riid), surface, device); wined3d_mutex_lock(); - hr = d3d_device_create(ddraw, surface_impl, 2, &device_impl, NULL); - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) + { *device = &device_impl->IDirect3DDevice2_iface; + } else { WARN("Failed to create device, hr %#x.\n", hr); @@ -4502,301 +4374,6 @@ static HRESULT WINAPI d3d3_EvictManagedTextures(IDirect3D3 *iface) return d3d7_EvictManagedTextures(&ddraw->IDirect3D7_iface); } -/***************************************************************************** - * IDirect3DImpl_GetCaps - * - * This function retrieves the device caps from wined3d - * and converts it into a D3D7 and D3D - D3D3 structure - * This is a helper function called from various places in ddraw - * - * Params: - * wined3d: The interface to get the caps from - * desc1: Old D3D <3 structure to fill (needed) - * desc7: D3D7 device desc structure to fill (needed) - * - * Returns - * D3D_OK on success, or the return value of IWineD3D::GetCaps - * - *****************************************************************************/ -HRESULT IDirect3DImpl_GetCaps(const struct wined3d *wined3d, D3DDEVICEDESC *desc1, D3DDEVICEDESC7 *desc7) -{ - WINED3DCAPS wined3d_caps; - HRESULT hr; - - TRACE("wined3d %p, desc1 %p, desc7 %p.\n", wined3d, desc1, desc7); - - memset(&wined3d_caps, 0, sizeof(wined3d_caps)); - - wined3d_mutex_lock(); - hr = wined3d_get_device_caps(wined3d, 0, WINED3D_DEVICE_TYPE_HAL, &wined3d_caps); - wined3d_mutex_unlock(); - if (FAILED(hr)) - { - WARN("Failed to get device caps, hr %#x.\n", hr); - return hr; - } - - /* Copy the results into the d3d7 and d3d3 structures */ - desc7->dwDevCaps = wined3d_caps.DevCaps; - desc7->dpcLineCaps.dwMiscCaps = wined3d_caps.PrimitiveMiscCaps; - desc7->dpcLineCaps.dwRasterCaps = wined3d_caps.RasterCaps; - desc7->dpcLineCaps.dwZCmpCaps = wined3d_caps.ZCmpCaps; - desc7->dpcLineCaps.dwSrcBlendCaps = wined3d_caps.SrcBlendCaps; - desc7->dpcLineCaps.dwDestBlendCaps = wined3d_caps.DestBlendCaps; - desc7->dpcLineCaps.dwAlphaCmpCaps = wined3d_caps.AlphaCmpCaps; - desc7->dpcLineCaps.dwShadeCaps = wined3d_caps.ShadeCaps; - desc7->dpcLineCaps.dwTextureCaps = wined3d_caps.TextureCaps; - desc7->dpcLineCaps.dwTextureFilterCaps = wined3d_caps.TextureFilterCaps; - desc7->dpcLineCaps.dwTextureAddressCaps = wined3d_caps.TextureAddressCaps; - - desc7->dwMaxTextureWidth = wined3d_caps.MaxTextureWidth; - desc7->dwMaxTextureHeight = wined3d_caps.MaxTextureHeight; - - desc7->dwMaxTextureRepeat = wined3d_caps.MaxTextureRepeat; - desc7->dwMaxTextureAspectRatio = wined3d_caps.MaxTextureAspectRatio; - desc7->dwMaxAnisotropy = wined3d_caps.MaxAnisotropy; - desc7->dvMaxVertexW = wined3d_caps.MaxVertexW; - - desc7->dvGuardBandLeft = wined3d_caps.GuardBandLeft; - desc7->dvGuardBandTop = wined3d_caps.GuardBandTop; - desc7->dvGuardBandRight = wined3d_caps.GuardBandRight; - desc7->dvGuardBandBottom = wined3d_caps.GuardBandBottom; - - desc7->dvExtentsAdjust = wined3d_caps.ExtentsAdjust; - desc7->dwStencilCaps = wined3d_caps.StencilCaps; - - desc7->dwFVFCaps = wined3d_caps.FVFCaps; - desc7->dwTextureOpCaps = wined3d_caps.TextureOpCaps; - - desc7->dwVertexProcessingCaps = wined3d_caps.VertexProcessingCaps; - desc7->dwMaxActiveLights = wined3d_caps.MaxActiveLights; - - /* Remove all non-d3d7 caps */ - desc7->dwDevCaps &= ( - D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_SORTINCREASINGZ | D3DDEVCAPS_SORTDECREASINGZ | - D3DDEVCAPS_SORTEXACT | D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_EXECUTEVIDEOMEMORY | - D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY | - D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_CANRENDERAFTERFLIP | - D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_SEPARATETEXTUREMEMORIES | - D3DDEVCAPS_DRAWPRIMITIVES2EX | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_CANBLTSYSTONONLOCAL | - D3DDEVCAPS_HWRASTERIZATION); - - desc7->dwStencilCaps &= ( - D3DSTENCILCAPS_KEEP | D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | - D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INVERT | - D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR); - - /* FVF caps ?*/ - - desc7->dwTextureOpCaps &= ( - D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2 | - D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_MODULATE2X | D3DTEXOPCAPS_MODULATE4X | - D3DTEXOPCAPS_ADD | D3DTEXOPCAPS_ADDSIGNED | D3DTEXOPCAPS_ADDSIGNED2X | - D3DTEXOPCAPS_SUBTRACT | D3DTEXOPCAPS_ADDSMOOTH | D3DTEXOPCAPS_BLENDTEXTUREALPHA | - D3DTEXOPCAPS_BLENDFACTORALPHA | D3DTEXOPCAPS_BLENDTEXTUREALPHAPM | D3DTEXOPCAPS_BLENDCURRENTALPHA | - D3DTEXOPCAPS_PREMODULATE | D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR | D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA | - D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR | D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA | D3DTEXOPCAPS_BUMPENVMAP | - D3DTEXOPCAPS_BUMPENVMAPLUMINANCE | D3DTEXOPCAPS_DOTPRODUCT3); - - desc7->dwVertexProcessingCaps &= ( - D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | - D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER); - - desc7->dpcLineCaps.dwMiscCaps &= ( - D3DPMISCCAPS_MASKPLANES | D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP | - D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | - D3DPMISCCAPS_CULLCCW); - - desc7->dpcLineCaps.dwRasterCaps &= ( - D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ROP2 | D3DPRASTERCAPS_XOR | - D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL | - D3DPRASTERCAPS_SUBPIXELX | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | - D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT | D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT | - D3DPRASTERCAPS_ANTIALIASEDGES | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBIAS | - D3DPRASTERCAPS_ZBUFFERLESSHSR | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | - D3DPRASTERCAPS_WBUFFER | D3DPRASTERCAPS_TRANSLUCENTSORTINDEPENDENT | D3DPRASTERCAPS_WFOG | - D3DPRASTERCAPS_ZFOG); - - desc7->dpcLineCaps.dwZCmpCaps &= ( - D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | - D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | - D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS); - - desc7->dpcLineCaps.dwSrcBlendCaps &= ( - D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | - D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | - D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR | - D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA | - D3DPBLENDCAPS_BOTHINVSRCALPHA); - - desc7->dpcLineCaps.dwDestBlendCaps &= ( - D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | - D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | - D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR | - D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA | - D3DPBLENDCAPS_BOTHINVSRCALPHA); - - desc7->dpcLineCaps.dwAlphaCmpCaps &= ( - D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | - D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | - D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS); - - desc7->dpcLineCaps.dwShadeCaps &= ( - D3DPSHADECAPS_COLORFLATMONO | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDMONO | - D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_COLORPHONGMONO | D3DPSHADECAPS_COLORPHONGRGB | - D3DPSHADECAPS_SPECULARFLATMONO | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDMONO | - D3DPSHADECAPS_SPECULARGOURAUDRGB | D3DPSHADECAPS_SPECULARPHONGMONO | D3DPSHADECAPS_SPECULARPHONGRGB | - D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAFLATSTIPPLED | D3DPSHADECAPS_ALPHAGOURAUDBLEND | - D3DPSHADECAPS_ALPHAGOURAUDSTIPPLED | D3DPSHADECAPS_ALPHAPHONGBLEND | D3DPSHADECAPS_ALPHAPHONGSTIPPLED | - D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_FOGPHONG); - - desc7->dpcLineCaps.dwTextureCaps &= ( - D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA | - D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_SQUAREONLY | - D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE| D3DPTEXTURECAPS_NONPOW2CONDITIONAL | - D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_COLORKEYBLEND); - - desc7->dpcLineCaps.dwTextureFilterCaps &= ( - D3DPTFILTERCAPS_NEAREST | D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_MIPNEAREST | - D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST | D3DPTFILTERCAPS_LINEARMIPLINEAR | - D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFANISOTROPIC | - D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | - D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC | - D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC); - - desc7->dpcLineCaps.dwTextureAddressCaps &= ( - D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | - D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV); - - if (!(desc7->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2)) - { - /* DirectX7 always has the np2 flag set, no matter what the card - * supports. Some old games (Rollcage) check the caps incorrectly. - * If wined3d supports nonpow2 textures it also has np2 conditional - * support. */ - desc7->dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL; - } - - /* Fill the missing members, and do some fixup */ - desc7->dpcLineCaps.dwSize = sizeof(desc7->dpcLineCaps); - desc7->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_MODULATEMASK | - D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | - D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK | - D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA; - desc7->dpcLineCaps.dwStippleWidth = 32; - desc7->dpcLineCaps.dwStippleHeight = 32; - /* Use the same for the TriCaps */ - desc7->dpcTriCaps = desc7->dpcLineCaps; - - desc7->dwDeviceRenderBitDepth = DDBD_16 | DDBD_24 | DDBD_32; - desc7->dwDeviceZBufferBitDepth = DDBD_16 | DDBD_24; - desc7->dwMinTextureWidth = 1; - desc7->dwMinTextureHeight = 1; - - /* Convert DWORDs safely to WORDs */ - if (wined3d_caps.MaxTextureBlendStages > 0xffff) desc7->wMaxTextureBlendStages = 0xffff; - else desc7->wMaxTextureBlendStages = (WORD)wined3d_caps.MaxTextureBlendStages; - if (wined3d_caps.MaxSimultaneousTextures > 0xffff) desc7->wMaxSimultaneousTextures = 0xffff; - else desc7->wMaxSimultaneousTextures = (WORD)wined3d_caps.MaxSimultaneousTextures; - - if (wined3d_caps.MaxUserClipPlanes > 0xffff) desc7->wMaxUserClipPlanes = 0xffff; - else desc7->wMaxUserClipPlanes = (WORD)wined3d_caps.MaxUserClipPlanes; - if (wined3d_caps.MaxVertexBlendMatrices > 0xffff) desc7->wMaxVertexBlendMatrices = 0xffff; - else desc7->wMaxVertexBlendMatrices = (WORD)wined3d_caps.MaxVertexBlendMatrices; - - desc7->deviceGUID = IID_IDirect3DTnLHalDevice; - - desc7->dwReserved1 = 0; - desc7->dwReserved2 = 0; - desc7->dwReserved3 = 0; - desc7->dwReserved4 = 0; - - /* Fill the old structure */ - memset(desc1, 0, sizeof(*desc1)); - desc1->dwSize = sizeof(D3DDEVICEDESC); - desc1->dwFlags = D3DDD_COLORMODEL - | D3DDD_DEVCAPS - | D3DDD_TRANSFORMCAPS - | D3DDD_BCLIPPING - | D3DDD_LIGHTINGCAPS - | D3DDD_LINECAPS - | D3DDD_TRICAPS - | D3DDD_DEVICERENDERBITDEPTH - | D3DDD_DEVICEZBUFFERBITDEPTH - | D3DDD_MAXBUFFERSIZE - | D3DDD_MAXVERTEXCOUNT; - - desc1->dcmColorModel = D3DCOLOR_RGB; - desc1->dwDevCaps = desc7->dwDevCaps; - desc1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS); - desc1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP; - desc1->bClipping = TRUE; - desc1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS); - desc1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL - | D3DLIGHTCAPS_PARALLELPOINT - | D3DLIGHTCAPS_POINT - | D3DLIGHTCAPS_SPOT; - - desc1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB; - desc1->dlcLightingCaps.dwNumLights = desc7->dwMaxActiveLights; - - desc1->dpcLineCaps.dwSize = sizeof(D3DPRIMCAPS); - desc1->dpcLineCaps.dwMiscCaps = desc7->dpcLineCaps.dwMiscCaps; - desc1->dpcLineCaps.dwRasterCaps = desc7->dpcLineCaps.dwRasterCaps; - desc1->dpcLineCaps.dwZCmpCaps = desc7->dpcLineCaps.dwZCmpCaps; - desc1->dpcLineCaps.dwSrcBlendCaps = desc7->dpcLineCaps.dwSrcBlendCaps; - desc1->dpcLineCaps.dwDestBlendCaps = desc7->dpcLineCaps.dwDestBlendCaps; - desc1->dpcLineCaps.dwShadeCaps = desc7->dpcLineCaps.dwShadeCaps; - desc1->dpcLineCaps.dwTextureCaps = desc7->dpcLineCaps.dwTextureCaps; - desc1->dpcLineCaps.dwTextureFilterCaps = desc7->dpcLineCaps.dwTextureFilterCaps; - desc1->dpcLineCaps.dwTextureBlendCaps = desc7->dpcLineCaps.dwTextureBlendCaps; - desc1->dpcLineCaps.dwTextureAddressCaps = desc7->dpcLineCaps.dwTextureAddressCaps; - desc1->dpcLineCaps.dwStippleWidth = desc7->dpcLineCaps.dwStippleWidth; - desc1->dpcLineCaps.dwAlphaCmpCaps = desc7->dpcLineCaps.dwAlphaCmpCaps; - - desc1->dpcTriCaps.dwSize = sizeof(D3DPRIMCAPS); - desc1->dpcTriCaps.dwMiscCaps = desc7->dpcTriCaps.dwMiscCaps; - desc1->dpcTriCaps.dwRasterCaps = desc7->dpcTriCaps.dwRasterCaps; - desc1->dpcTriCaps.dwZCmpCaps = desc7->dpcTriCaps.dwZCmpCaps; - desc1->dpcTriCaps.dwSrcBlendCaps = desc7->dpcTriCaps.dwSrcBlendCaps; - desc1->dpcTriCaps.dwDestBlendCaps = desc7->dpcTriCaps.dwDestBlendCaps; - desc1->dpcTriCaps.dwShadeCaps = desc7->dpcTriCaps.dwShadeCaps; - desc1->dpcTriCaps.dwTextureCaps = desc7->dpcTriCaps.dwTextureCaps; - desc1->dpcTriCaps.dwTextureFilterCaps = desc7->dpcTriCaps.dwTextureFilterCaps; - desc1->dpcTriCaps.dwTextureBlendCaps = desc7->dpcTriCaps.dwTextureBlendCaps; - desc1->dpcTriCaps.dwTextureAddressCaps = desc7->dpcTriCaps.dwTextureAddressCaps; - desc1->dpcTriCaps.dwStippleWidth = desc7->dpcTriCaps.dwStippleWidth; - desc1->dpcTriCaps.dwAlphaCmpCaps = desc7->dpcTriCaps.dwAlphaCmpCaps; - - desc1->dwDeviceRenderBitDepth = desc7->dwDeviceRenderBitDepth; - desc1->dwDeviceZBufferBitDepth = desc7->dwDeviceZBufferBitDepth; - desc1->dwMaxBufferSize = 0; - desc1->dwMaxVertexCount = 65536; - desc1->dwMinTextureWidth = desc7->dwMinTextureWidth; - desc1->dwMinTextureHeight = desc7->dwMinTextureHeight; - desc1->dwMaxTextureWidth = desc7->dwMaxTextureWidth; - desc1->dwMaxTextureHeight = desc7->dwMaxTextureHeight; - desc1->dwMinStippleWidth = 1; - desc1->dwMinStippleHeight = 1; - desc1->dwMaxStippleWidth = 32; - desc1->dwMaxStippleHeight = 32; - desc1->dwMaxTextureRepeat = desc7->dwMaxTextureRepeat; - desc1->dwMaxTextureAspectRatio = desc7->dwMaxTextureAspectRatio; - desc1->dwMaxAnisotropy = desc7->dwMaxAnisotropy; - desc1->dvGuardBandLeft = desc7->dvGuardBandLeft; - desc1->dvGuardBandRight = desc7->dvGuardBandRight; - desc1->dvGuardBandTop = desc7->dvGuardBandTop; - desc1->dvGuardBandBottom = desc7->dvGuardBandBottom; - desc1->dvExtentsAdjust = desc7->dvExtentsAdjust; - desc1->dwStencilCaps = desc7->dwStencilCaps; - desc1->dwFVFCaps = desc7->dwFVFCaps; - desc1->dwTextureOpCaps = desc7->dwTextureOpCaps; - desc1->wMaxTextureBlendStages = desc7->wMaxTextureBlendStages; - desc1->wMaxSimultaneousTextures = desc7->wMaxSimultaneousTextures; - - return DD_OK; -} - /***************************************************************************** * IDirectDraw7 VTable *****************************************************************************/ @@ -5113,36 +4690,56 @@ static void CDECL device_parent_mode_changed(struct wined3d_device_parent *devic ERR("Failed to resize window.\n"); } -static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_parent *device_parent, - void *container_parent, const struct wined3d_resource_desc *wined3d_desc, UINT sub_resource_idx, - DWORD flags, struct wined3d_surface **surface) +static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, + void *container_parent, struct wined3d_surface *surface, + void **parent, const struct wined3d_parent_ops **parent_ops) { struct ddraw *ddraw = ddraw_from_device_parent(device_parent); - struct ddraw_surface *tex_root = container_parent; - DDSURFACEDESC2 desc = tex_root->surface_desc; struct ddraw_surface *ddraw_surface; HRESULT hr; - TRACE("device_parent %p, container_parent %p, wined3d_desc %p, sub_resource_idx %u, flags %#x, surface %p.\n", - device_parent, container_parent, wined3d_desc, sub_resource_idx, flags, surface); + TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n", + device_parent, container_parent, surface, parent, parent_ops); - /* The ddraw root surface is created before the wined3d texture. */ - if (!sub_resource_idx) + /* We have a swapchain texture. */ + if (container_parent == ddraw) { - ddraw_surface = tex_root; - goto done; + *parent = NULL; + *parent_ops = &ddraw_null_wined3d_parent_ops; + + return DD_OK; } - desc.dwWidth = wined3d_desc->width; - desc.dwHeight = wined3d_desc->height; + if (!(ddraw_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ddraw_surface)))) + { + ERR("Failed to allocate surface memory.\n"); + return DDERR_OUTOFVIDEOMEMORY; + } - /* FIXME: Validate that format, usage, pool, etc. really make sense. */ - if (FAILED(hr = ddraw_create_surface(ddraw, &desc, flags, &ddraw_surface, tex_root->version))) + if (FAILED(hr = ddraw_surface_init(ddraw_surface, ddraw, container_parent, surface, parent_ops))) + { + WARN("Failed to initialize surface, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, ddraw_surface); return hr; + } -done: - *surface = ddraw_surface->wined3d_surface; - wined3d_surface_incref(*surface); + *parent = ddraw_surface; + list_add_head(&ddraw->surface_list, &ddraw_surface->surface_list_entry); + + TRACE("Created ddraw surface %p.\n", ddraw_surface); + + return DD_OK; +} + +static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, + void *container_parent, struct wined3d_volume *volume, + void **parent, const struct wined3d_parent_ops **parent_ops) +{ + TRACE("device_parent %p, container_parent %p, volume %p, parent %p, parent_ops %p.\n", + device_parent, container_parent, volume, parent, parent_ops); + + *parent = NULL; + *parent_ops = &ddraw_null_wined3d_parent_ops; return DD_OK; } @@ -5162,6 +4759,8 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface) { struct ddraw *ddraw = ddraw_from_device_parent(device_parent); + struct wined3d_resource_desc texture_desc; + struct wined3d_texture *texture; HRESULT hr; TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n", @@ -5173,29 +4772,23 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic return E_FAIL; } - if (SUCCEEDED(hr = wined3d_surface_create(ddraw->wined3d_device, desc->width, desc->height, desc->format, - desc->usage, desc->pool, desc->multisample_type, desc->multisample_quality, WINED3D_SURFACE_MAPPABLE, - ddraw, &ddraw_frontbuffer_parent_ops, surface))) - ddraw->wined3d_frontbuffer = *surface; + texture_desc = *desc; + texture_desc.resource_type = WINED3D_RTYPE_TEXTURE; + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &texture_desc, 1, + WINED3D_SURFACE_MAPPABLE, ddraw, &ddraw_frontbuffer_parent_ops, &texture))) + { + WARN("Failed to create texture, hr %#x.\n", hr); + return hr; + } + + *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0)); + ddraw->wined3d_frontbuffer = *surface; + wined3d_surface_incref(*surface); + wined3d_texture_decref(texture); return hr; } -static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent, - void *container_parent, UINT width, UINT height, UINT depth, UINT level, - enum wined3d_format_id format, enum wined3d_pool pool, DWORD usage, - struct wined3d_volume **volume) -{ - TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, " - "format %#x, pool %#x, usage %#x, volume %p.\n", - device_parent, container_parent, width, height, depth, - format, pool, usage, volume); - - ERR("Not implemented!\n"); - - return E_NOTIMPL; -} - static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) { @@ -5221,9 +4814,9 @@ static const struct wined3d_device_parent_ops ddraw_wined3d_device_parent_ops = { device_parent_wined3d_device_created, device_parent_mode_changed, + device_parent_surface_created, + device_parent_volume_created, device_parent_create_swapchain_surface, - device_parent_create_texture_surface, - device_parent_create_volume, device_parent_create_swapchain, }; diff --git a/reactos/dll/directx/wine/ddraw/ddraw_classes.idl b/reactos/dll/directx/wine/ddraw/ddraw_classes.idl index d8247003441..6e33253ad4e 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw_classes.idl +++ b/reactos/dll/directx/wine/ddraw/ddraw_classes.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("DirectDraw Object"), threading(both), diff --git a/reactos/dll/directx/wine/ddraw/ddraw_private.h b/reactos/dll/directx/wine/ddraw/ddraw_private.h index 6fb960894ea..a312ed7dad2 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw_private.h +++ b/reactos/dll/directx/wine/ddraw/ddraw_private.h @@ -26,7 +26,7 @@ #include #define _INC_WINDOWS -#define COM_NO_WINDOWS_H +#define COM_NO_WINDOW_H #define COBJMACROS #define NONAMELESSSTRUCT @@ -61,6 +61,7 @@ struct FvfToDecl #define DDRAW_RESTORE_MODE 0x00000004 #define DDRAW_NO3D 0x00000008 #define DDRAW_SCL_DDRAW1 0x00000010 +#define DDRAW_SCL_RECURSIVE 0x00000020 #define DDRAW_STRIDE_ALIGNMENT 8 @@ -118,7 +119,9 @@ struct ddraw #define DDRAW_WINDOW_CLASS_NAME "DirectDrawDeviceWnd" HRESULT ddraw_init(struct ddraw *ddraw, enum wined3d_device_type device_type) DECLSPEC_HIDDEN; +void ddraw_d3dcaps1_from_7(D3DDEVICEDESC *caps1, D3DDEVICEDESC7 *caps7) DECLSPEC_HIDDEN; void ddraw_destroy_swapchain(struct ddraw *ddraw) DECLSPEC_HIDDEN; +HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) DECLSPEC_HIDDEN; static inline void ddraw_set_swapchain_window(struct ddraw *ddraw, HWND window) { @@ -182,6 +185,7 @@ struct ddraw_surface /* Clipper objects */ struct ddraw_clipper *clipper; + struct ddraw_palette *palette; /* For the ddraw surface list */ struct list surface_list_entry; @@ -189,9 +193,18 @@ struct ddraw_surface DWORD Handle; }; -HRESULT ddraw_surface_create_texture(struct ddraw_surface *surface, DWORD surface_flags) DECLSPEC_HIDDEN; -HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, - DDSURFACEDESC2 *desc, DWORD flags, UINT version) DECLSPEC_HIDDEN; +struct ddraw_texture +{ + unsigned int version; + DDSURFACEDESC2 surface_desc; + + struct ddraw_surface *root; +}; + +HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, + struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) DECLSPEC_HIDDEN; +HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture, + struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN; static inline struct ddraw_surface *impl_from_IDirect3DTexture(IDirect3DTexture *iface) @@ -281,7 +294,7 @@ struct d3d_device IUnknown *outer_unknown; struct wined3d_device *wined3d_device; struct ddraw *ddraw; - struct ddraw_surface *target; + IUnknown *rt_iface; struct wined3d_buffer *index_buffer; UINT index_buffer_size; @@ -310,7 +323,7 @@ struct d3d_device DWORD vertex_type; DWORD render_flags; DWORD nb_vertices; - LPBYTE sysmem_vertex_buffer; + BYTE *sysmem_vertex_buffer; DWORD vertex_size; DWORD buffer_size; @@ -319,17 +332,13 @@ struct d3d_device D3DMATRIXHANDLE world, proj, view; }; -HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, +HRESULT d3d_device_create(struct ddraw *ddraw, 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; /* The IID */ extern const GUID IID_D3DDEVICE_WineD3D DECLSPEC_HIDDEN; -/* Helper functions */ -HRESULT IDirect3DImpl_GetCaps(const struct wined3d *wined3d, - D3DDEVICEDESC *Desc123, D3DDEVICEDESC7 *Desc7) DECLSPEC_HIDDEN; - static inline struct d3d_device *impl_from_IDirect3DDevice(IDirect3DDevice *iface) { return CONTAINING_RECORD(iface, struct d3d_device, IDirect3DDevice_iface); @@ -377,9 +386,9 @@ struct ddraw_palette LONG ref; struct wined3d_palette *wineD3DPalette; - - /* IDirectDrawPalette fields */ - IUnknown *ifaceToRelease; + struct ddraw *ddraw; + IUnknown *ifaceToRelease; + DWORD flags; }; static inline struct ddraw_palette *impl_from_IDirectDrawPalette(IDirectDrawPalette *iface) @@ -607,18 +616,6 @@ struct member_info #define DD_STRUCT_COPY_BYSIZE(to,from) DD_STRUCT_COPY_BYSIZE_(to,from,(from)->dwSize) -#define SIZEOF_END_PADDING(type, last_field) \ - (sizeof(type) - offsetof(type, last_field) - sizeof(((type *)0)->last_field)) - -static inline void copy_to_surfacedesc2(DDSURFACEDESC2 *to, DDSURFACEDESC2 *from) -{ - DWORD from_size = from->dwSize; - if (from_size == sizeof(DDSURFACEDESC)) - from_size -= SIZEOF_END_PADDING(DDSURFACEDESC, ddsCaps); - to->dwSize = sizeof(DDSURFACEDESC2); /* for struct copy */ - DD_STRUCT_COPY_BYSIZE_(to, from, from_size); -} - HRESULT hr_ddraw_from_wined3d(HRESULT hr) DECLSPEC_HIDDEN; -#endif /* __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H */ +#endif diff --git a/reactos/dll/directx/wine/ddraw/device.c b/reactos/dll/directx/wine/ddraw/device.c index baa0b774ada..cfad802e46d 100644 --- a/reactos/dll/directx/wine/ddraw/device.c +++ b/reactos/dll/directx/wine/ddraw/device.c @@ -220,6 +220,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) { struct d3d_device *This = impl_from_IUnknown(iface); ULONG ref = InterlockedDecrement(&This->ref); + IUnknown *rt_iface; TRACE("%p decreasing refcount to %u.\n", This, ref); @@ -241,10 +242,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) if (This->vertex_buffer) wined3d_buffer_decref(This->vertex_buffer); - /* Set the device up to render to the front buffer since the back - * buffer will vanish soon. */ - wined3d_device_set_render_target(This->wined3d_device, 0, - This->ddraw->wined3d_frontbuffer, TRUE); + wined3d_device_set_render_target(This->wined3d_device, 0, NULL, FALSE); /* Release the wined3d device. This won't destroy it. */ if (!wined3d_device_decref(This->wined3d_device)) @@ -307,11 +305,12 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) IDirect3DDevice3_DeleteViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface); } - TRACE("Releasing target %p.\n", This->target); - /* Release the render target. */ + TRACE("Releasing render target %p.\n", This->rt_iface); + rt_iface = This->rt_iface; + This->rt_iface = NULL; if (This->version != 1) - IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface); - TRACE("Target release done\n"); + IUnknown_Release(rt_iface); + TRACE("Render target release done.\n"); This->ddraw->d3ddevice = NULL; @@ -389,37 +388,20 @@ static HRESULT WINAPI d3d_device1_Initialize(IDirect3DDevice *iface, return D3D_OK; } -/***************************************************************************** - * IDirect3DDevice7::GetCaps - * - * Retrieves the device's capabilities - * - * This implementation is used for Version 7 only, the older versions have - * their own implementation. - * - * Parameters: - * Desc: Pointer to a D3DDEVICEDESC7 structure to fill - * - * Returns: - * D3D_OK on success - * D3DERR_* if a problem occurs. See WineD3D - * - *****************************************************************************/ -static HRESULT d3d_device7_GetCaps(IDirect3DDevice7 *iface, D3DDEVICEDESC7 *Desc) +static HRESULT d3d_device7_GetCaps(IDirect3DDevice7 *iface, D3DDEVICEDESC7 *device_desc) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); - D3DDEVICEDESC OldDesc; - TRACE("iface %p, device_desc %p.\n", iface, Desc); + TRACE("iface %p, device_desc %p.\n", iface, device_desc); - if (!Desc) + if (!device_desc) { - WARN("Desc is NULL, returning DDERR_INVALIDPARAMS.\n"); + WARN("device_desc is NULL, returning DDERR_INVALIDPARAMS.\n"); return DDERR_INVALIDPARAMS; } /* Call the same function used by IDirect3D, this saves code */ - return IDirect3DImpl_GetCaps(device->ddraw->wined3d, &OldDesc, Desc); + return ddraw_get_d3dcaps(device->ddraw, device_desc); } static HRESULT WINAPI d3d_device7_GetCaps_FPUSetup(IDirect3DDevice7 *iface, D3DDEVICEDESC7 *desc) @@ -481,8 +463,8 @@ static HRESULT WINAPI d3d_device3_GetCaps(IDirect3DDevice3 *iface, D3DDEVICEDESC *HWDesc, D3DDEVICEDESC *HelDesc) { struct d3d_device *device = impl_from_IDirect3DDevice3(iface); - D3DDEVICEDESC oldDesc; - D3DDEVICEDESC7 newDesc; + D3DDEVICEDESC7 desc7; + D3DDEVICEDESC desc1; HRESULT hr; TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, HWDesc, HelDesc); @@ -508,12 +490,12 @@ static HRESULT WINAPI d3d_device3_GetCaps(IDirect3DDevice3 *iface, return DDERR_INVALIDPARAMS; } - hr = IDirect3DImpl_GetCaps(device->ddraw->wined3d, &oldDesc, &newDesc); - if (hr != D3D_OK) + if (FAILED(hr = ddraw_get_d3dcaps(device->ddraw, &desc7))) return hr; - DD_STRUCT_COPY_BYSIZE(HWDesc, &oldDesc); - DD_STRUCT_COPY_BYSIZE(HelDesc, &oldDesc); + ddraw_d3dcaps1_from_7(&desc1, &desc7); + DD_STRUCT_COPY_BYSIZE(HWDesc, &desc1); + DD_STRUCT_COPY_BYSIZE(HelDesc, &desc1); return D3D_OK; } @@ -1069,7 +1051,9 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface, WINED3DFMT_P8_UINT, /* FOURCC codes */ WINED3DFMT_DXT1, + WINED3DFMT_DXT2, WINED3DFMT_DXT3, + WINED3DFMT_DXT4, WINED3DFMT_DXT5, }; @@ -1808,62 +1792,88 @@ static HRESULT WINAPI d3d_device2_GetCurrentViewport(IDirect3DDevice2 *iface, ID (IDirect3DViewport3 **)viewport); } -/***************************************************************************** - * IDirect3DDevice7::SetRenderTarget - * - * Sets the render target for the Direct3DDevice. - * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and - * IDirectDrawSurface3 == IDirectDrawSurface - * - * Version 2, 3 and 7 - * - * Params: - * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new - * render target - * Flags: Some flags - * - * Returns: - * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget - * - *****************************************************************************/ -static HRESULT d3d_device_set_render_target(struct d3d_device *device, struct ddraw_surface *target) +static BOOL validate_surface_palette(struct ddraw_surface *surface) +{ + return !(surface->surface_desc.u4.ddpfPixelFormat.dwFlags + & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 + | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 + | DDPF_PALETTEINDEXEDTO8)) + || wined3d_surface_get_palette(surface->wined3d_surface); +} + +static HRESULT d3d_device_set_render_target(struct d3d_device *device, + struct ddraw_surface *target, IUnknown *rt_iface) { HRESULT hr; - wined3d_mutex_lock(); - - if (device->target == target) + if (device->rt_iface == rt_iface) { TRACE("No-op SetRenderTarget operation, not doing anything\n"); - wined3d_mutex_unlock(); return D3D_OK; } - device->target = target; - hr = wined3d_device_set_render_target(device->wined3d_device, 0, - target ? target->wined3d_surface : NULL, FALSE); - if(hr != D3D_OK) + if (!target) { - wined3d_mutex_unlock(); - return hr; + WARN("Trying to set render target to NULL.\n"); + return DDERR_INVALIDPARAMS; } - d3d_device_update_depth_stencil(device); - wined3d_mutex_unlock(); + if (FAILED(hr = wined3d_device_set_render_target(device->wined3d_device, + 0, target->wined3d_surface, FALSE))) + return hr; + + IUnknown_AddRef(rt_iface); + IUnknown_Release(device->rt_iface); + device->rt_iface = rt_iface; + d3d_device_update_depth_stencil(device); return D3D_OK; } static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface, - IDirectDrawSurface7 *NewTarget, DWORD flags) + IDirectDrawSurface7 *target, DWORD flags) { + struct ddraw_surface *target_impl = unsafe_impl_from_IDirectDrawSurface7(target); struct d3d_device *device = impl_from_IDirect3DDevice7(iface); - struct ddraw_surface *target = unsafe_impl_from_IDirectDrawSurface7(NewTarget); + HRESULT hr; - TRACE("iface %p, target %p, flags %#x.\n", iface, NewTarget, flags); + TRACE("iface %p, target %p, flags %#x.\n", iface, target, flags); - IDirectDrawSurface7_AddRef(NewTarget); - IDirectDrawSurface7_Release(&device->target->IDirectDrawSurface7_iface); - return d3d_device_set_render_target(device, target); + wined3d_mutex_lock(); + + if (!validate_surface_palette(target_impl)) + { + WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl); + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) + { + WARN("Surface %p is not a render target.\n", target_impl); + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target_impl); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + + if (target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) + { + WARN("Surface %p is a depth buffer.\n", target_impl); + IDirectDrawSurface7_AddRef(target); + IUnknown_Release(device->rt_iface); + device->rt_iface = (IUnknown *)target; + wined3d_mutex_unlock(); + return DDERR_INVALIDPIXELFORMAT; + } + + hr = d3d_device_set_render_target(device, target_impl, (IUnknown *)target); + wined3d_mutex_unlock(); + return hr; } static HRESULT WINAPI d3d_device7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface, @@ -1886,29 +1896,102 @@ static HRESULT WINAPI d3d_device7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 * } static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, - IDirectDrawSurface4 *NewRenderTarget, DWORD flags) + IDirectDrawSurface4 *target, DWORD flags) { + struct ddraw_surface *target_impl = unsafe_impl_from_IDirectDrawSurface4(target); struct d3d_device *device = impl_from_IDirect3DDevice3(iface); - struct ddraw_surface *target = unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget); + HRESULT hr; - TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, flags); + TRACE("iface %p, target %p, flags %#x.\n", iface, target, flags); - IDirectDrawSurface4_AddRef(NewRenderTarget); - IDirectDrawSurface4_Release(&device->target->IDirectDrawSurface4_iface); - return d3d_device_set_render_target(device, target); + wined3d_mutex_lock(); + + if (!validate_surface_palette(target_impl)) + { + WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl); + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) + { + WARN("Surface %p is not a render target.\n", target_impl); + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + + if (target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) + { + WARN("Surface %p is a depth buffer.\n", target_impl); + IDirectDrawSurface4_AddRef(target); + IUnknown_Release(device->rt_iface); + device->rt_iface = (IUnknown *)target; + wined3d_mutex_unlock(); + return DDERR_INVALIDPIXELFORMAT; + } + + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target_impl); + IDirectDrawSurface4_AddRef(target); + IUnknown_Release(device->rt_iface); + device->rt_iface = (IUnknown *)target; + wined3d_mutex_unlock(); + return D3D_OK; + } + + hr = d3d_device_set_render_target(device, target_impl, (IUnknown *)target); + wined3d_mutex_unlock(); + return hr; } static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, - IDirectDrawSurface *NewRenderTarget, DWORD flags) + IDirectDrawSurface *target, DWORD flags) { + struct ddraw_surface *target_impl = unsafe_impl_from_IDirectDrawSurface(target); struct d3d_device *device = impl_from_IDirect3DDevice2(iface); - struct ddraw_surface *target = unsafe_impl_from_IDirectDrawSurface(NewRenderTarget); + HRESULT hr; - TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, flags); + TRACE("iface %p, target %p, flags %#x.\n", iface, target, flags); - IDirectDrawSurface_AddRef(NewRenderTarget); - IDirectDrawSurface_Release(&device->target->IDirectDrawSurface_iface); - return d3d_device_set_render_target(device, target); + wined3d_mutex_lock(); + + if (!validate_surface_palette(target_impl)) + { + WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl); + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) + { + WARN("Surface %p is not a render target.\n", target_impl); + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + + if (target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) + { + WARN("Surface %p is a depth buffer.\n", target_impl); + IUnknown_Release(device->rt_iface); + device->rt_iface = (IUnknown *)target; + wined3d_mutex_unlock(); + return DDERR_INVALIDPIXELFORMAT; + } + + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target_impl); + IDirectDrawSurface_AddRef(target); + IUnknown_Release(device->rt_iface); + device->rt_iface = (IUnknown *)target; + wined3d_mutex_unlock(); + return D3D_OK; + } + + hr = d3d_device_set_render_target(device, target_impl, (IUnknown *)target); + wined3d_mutex_unlock(); + return hr; } /***************************************************************************** @@ -1931,6 +2014,7 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, static HRESULT WINAPI d3d_device7_GetRenderTarget(IDirect3DDevice7 *iface, IDirectDrawSurface7 **RenderTarget) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + HRESULT hr; TRACE("iface %p, target %p.\n", iface, RenderTarget); @@ -1938,11 +2022,10 @@ static HRESULT WINAPI d3d_device7_GetRenderTarget(IDirect3DDevice7 *iface, IDire return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - *RenderTarget = &device->target->IDirectDrawSurface7_iface; - IDirectDrawSurface7_AddRef(*RenderTarget); + hr = IUnknown_QueryInterface(device->rt_iface, &IID_IDirectDrawSurface7, (void **)RenderTarget); wined3d_mutex_unlock(); - return D3D_OK; + return hr; } static HRESULT WINAPI d3d_device3_GetRenderTarget(IDirect3DDevice3 *iface, IDirectDrawSurface4 **RenderTarget) @@ -2367,9 +2450,9 @@ static HRESULT WINAPI d3d_device3_GetRenderState(IDirect3DDevice3 *iface, { /* The parent of the texture is the IDirectDrawSurface7 * interface of the ddraw surface. */ - struct ddraw_surface *parent = wined3d_texture_get_parent(tex); + struct ddraw_texture *parent = wined3d_texture_get_parent(tex); if (parent) - *value = parent->Handle; + *value = parent->root->Handle; } wined3d_mutex_unlock(); @@ -4499,7 +4582,7 @@ static HRESULT d3d_device7_GetTexture(IDirect3DDevice7 *iface, { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); struct wined3d_texture *wined3d_texture; - struct ddraw_surface *surface; + struct ddraw_texture *ddraw_texture; TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); @@ -4514,8 +4597,8 @@ static HRESULT d3d_device7_GetTexture(IDirect3DDevice7 *iface, return D3D_OK; } - surface = wined3d_texture_get_parent(wined3d_texture); - *texture = &surface->IDirectDrawSurface7_iface; + ddraw_texture = wined3d_texture_get_parent(wined3d_texture); + *texture = &ddraw_texture->root->IDirectDrawSurface7_iface; IDirectDrawSurface7_AddRef(*texture); wined3d_mutex_unlock(); @@ -4581,14 +4664,16 @@ static HRESULT d3d_device7_SetTexture(IDirect3DDevice7 *iface, { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); struct ddraw_surface *surf = unsafe_impl_from_IDirectDrawSurface7(texture); + struct wined3d_texture *wined3d_texture = NULL; HRESULT hr; TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); - /* Texture may be NULL here */ + if (surf && (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + wined3d_texture = surf->wined3d_texture; + wined3d_mutex_lock(); - hr = wined3d_device_set_texture(device->wined3d_device, - stage, surf ? surf->wined3d_texture : NULL); + hr = wined3d_device_set_texture(device->wined3d_device, stage, wined3d_texture); wined3d_mutex_unlock(); return hr; @@ -6667,10 +6752,16 @@ struct d3d_device *unsafe_impl_from_IDirect3DDevice(IDirect3DDevice *iface) enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device *device) { IDirectDrawSurface7 *depthStencil = NULL; + IDirectDrawSurface7 *render_target; static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, {0} }; struct ddraw_surface *dsi; - IDirectDrawSurface7_GetAttachedSurface(&device->target->IDirectDrawSurface7_iface, &depthcaps, &depthStencil); + if (device->rt_iface && SUCCEEDED(IUnknown_QueryInterface(device->rt_iface, + &IID_IDirectDrawSurface7, (void **)&render_target))) + { + IDirectDrawSurface7_GetAttachedSurface(render_target, &depthcaps, &depthStencil); + IDirectDrawSurface7_Release(render_target); + } if (!depthStencil) { TRACE("Setting wined3d depth stencil to NULL\n"); @@ -6687,7 +6778,7 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device } static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, - struct ddraw_surface *target, UINT version, IUnknown *outer_unknown) + struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown) { static const D3DMATRIX ident = { @@ -6716,7 +6807,6 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, device->outer_unknown = &device->IUnknown_inner; device->ddraw = ddraw; - device->target = target; list_init(&device->viewport_list); if (!ddraw_handle_table_init(&device->handle_table, 64)) @@ -6742,17 +6832,9 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, return hr; } - /* FIXME: This is broken. The target AddRef() makes some sense, because - * we store a pointer during initialization, but then that's also where - * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */ - /* AddRef the render target. Also AddRef the render target from ddraw, - * because if it is released before the app releases the D3D device, the - * D3D capabilities of wined3d will be uninitialized, which has bad effects. - * - * In most cases, those surfaces are the same anyway, but this will simply - * add another ref which is released when the device is destroyed. */ + device->rt_iface = rt_iface; if (version != 1) - IDirectDrawSurface7_AddRef(&target->IDirectDrawSurface7_iface); + IUnknown_AddRef(device->rt_iface); ddraw->d3ddevice = device; @@ -6766,7 +6848,7 @@ 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, +HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, struct d3d_device **device, IUnknown *outer_unknown) { struct d3d_device *object; @@ -6775,6 +6857,25 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n", ddraw, target, version, device, outer_unknown); + if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) + || (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) + { + WARN("Surface %p is not a render target.\n", target); + return DDERR_INVALIDCAPS; + } + + if (!validate_surface_palette(target)) + { + WARN("Surface %p has an indexed pixel format, but no palette.\n", target); + return DDERR_NOPALETTEATTACHED; + } + + if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target); + return D3DERR_SURFACENOTINVIDMEM; + } + if (ddraw->flags & DDRAW_NO3D) { ERR_(winediag)("The application wants to create a Direct3D device, " @@ -6796,8 +6897,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, return DDERR_OUTOFMEMORY; } - hr = d3d_device_init(object, ddraw, target, version, outer_unknown); - if (FAILED(hr)) + if (FAILED(hr = d3d_device_init(object, ddraw, target, rt_iface, version, outer_unknown))) { WARN("Failed to initialize device, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); diff --git a/reactos/dll/directx/wine/ddraw/main.c b/reactos/dll/directx/wine/ddraw/main.c index 8a9801185cf..d9665d008f7 100644 --- a/reactos/dll/directx/wine/ddraw/main.c +++ b/reactos/dll/directx/wine/ddraw/main.c @@ -25,11 +25,10 @@ */ #include "ddraw_private.h" - #include #include -#include +#include "wine/exception.h" static struct list global_ddraw_list = LIST_INIT(global_ddraw_list); @@ -54,6 +53,37 @@ static HRESULT CALLBACK enum_callback(GUID *guid, char *description, char *drive return info->callback(guid, description, driver_name, info->context); } +static void ddraw_enumerate_secondary_devices(struct wined3d *wined3d, LPDDENUMCALLBACKEXA callback, + void *context) +{ + struct wined3d_adapter_identifier adapter_id; + BOOL cont_enum = TRUE; + HRESULT hr = S_OK; + UINT adapter = 0; + + for (adapter = 0; SUCCEEDED(hr) && cont_enum; adapter++) + { + char DriverName[512] = "", DriverDescription[512] = ""; + + /* The Battle.net System Checker expects the GetAdapterIdentifier DeviceName to match the + * Driver Name, so obtain the DeviceName and GUID from D3D. */ + memset(&adapter_id, 0x0, sizeof(adapter_id)); + adapter_id.device_name = DriverName; + adapter_id.device_name_size = sizeof(DriverName); + adapter_id.description = DriverDescription; + adapter_id.description_size = sizeof(DriverDescription); + wined3d_mutex_lock(); + hr = wined3d_get_adapter_identifier(wined3d, adapter, 0x0, &adapter_id); + wined3d_mutex_unlock(); + if (SUCCEEDED(hr)) + { + TRACE("Interface %d: %s\n", adapter, wine_dbgstr_guid(&adapter_id.device_identifier)); + cont_enum = callback(&adapter_id.device_identifier, adapter_id.description, + adapter_id.device_name, context, wined3d_get_adapter_monitor(wined3d, adapter)); + } + } +} + /* Handle table functions */ BOOL ddraw_handle_table_init(struct ddraw_handle_table *t, UINT initial_size) { @@ -291,28 +321,25 @@ HRESULT WINAPI DECLSPEC_HOTPATCH DirectDrawCreate(GUID *driver_guid, IDirectDraw * Arguments, return values: See DDRAW_Create * ***********************************************************************/ -HRESULT WINAPI DECLSPEC_HOTPATCH -DirectDrawCreateEx(GUID *guid, - LPVOID *dd, - REFIID iid, - IUnknown *UnkOuter) +HRESULT WINAPI DECLSPEC_HOTPATCH DirectDrawCreateEx(GUID *driver_guid, + void **ddraw, REFIID interface_iid, IUnknown *outer) { HRESULT hr; - TRACE("driver_guid %s, ddraw %p, interface_iid %s, outer_unknown %p.\n", - debugstr_guid(guid), dd, debugstr_guid(iid), UnkOuter); + TRACE("driver_guid %s, ddraw %p, interface_iid %s, outer %p.\n", + debugstr_guid(driver_guid), ddraw, debugstr_guid(interface_iid), outer); - if (!IsEqualGUID(iid, &IID_IDirectDraw7)) + if (!IsEqualGUID(interface_iid, &IID_IDirectDraw7)) return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - hr = DDRAW_Create(guid, dd, UnkOuter, iid); + hr = DDRAW_Create(driver_guid, ddraw, outer, interface_iid); wined3d_mutex_unlock(); if (SUCCEEDED(hr)) { - IDirectDraw7 *ddraw7 = *(IDirectDraw7 **)dd; - hr = IDirectDraw7_Initialize(ddraw7, guid); + IDirectDraw7 *ddraw7 = *(IDirectDraw7 **)ddraw; + hr = IDirectDraw7_Initialize(ddraw7, driver_guid); if (FAILED(hr)) IDirectDraw7_Release(ddraw7); } @@ -371,8 +398,8 @@ HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA callback, void *contex DDENUM_NONDISPLAYDEVICES)) return DDERR_INVALIDPARAMS; - if (flags) - FIXME("flags 0x%08x not handled\n", flags); + if (flags & ~DDENUM_ATTACHEDSECONDARYDEVICES) + FIXME("flags 0x%08x not handled\n", flags & ~DDENUM_ATTACHEDSECONDARYDEVICES); TRACE("Enumerating ddraw interfaces\n"); if (!(wined3d = wined3d_create(7, WINED3D_LEGACY_DEPTH_BIAS))) @@ -391,33 +418,14 @@ HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA callback, void *contex /* QuickTime expects the description "DirectDraw HAL" */ static CHAR driver_desc[] = "DirectDraw HAL", driver_name[] = "display"; - struct wined3d_adapter_identifier adapter_id; - HRESULT hr = S_OK; - UINT adapter = 0; BOOL cont_enum; - /* The Battle.net System Checker expects both a NULL device and a GUID-based device */ TRACE("Default interface: DirectDraw HAL\n"); cont_enum = callback(NULL, driver_desc, driver_name, context, 0); - for (adapter = 0; SUCCEEDED(hr) && cont_enum; adapter++) - { - char DriverName[512] = ""; - /* The Battle.net System Checker expects the GetAdapterIdentifier DeviceName to match the - * Driver Name, so obtain the DeviceName and GUID from D3D. */ - memset(&adapter_id, 0x0, sizeof(adapter_id)); - adapter_id.device_name = DriverName; - adapter_id.device_name_size = sizeof(DriverName); - wined3d_mutex_lock(); - hr = wined3d_get_adapter_identifier(wined3d, adapter, 0x0, &adapter_id); - wined3d_mutex_unlock(); - if (SUCCEEDED(hr)) - { - TRACE("Interface %d: %s\n", adapter, wine_dbgstr_guid(&adapter_id.device_identifier)); - cont_enum = callback(&adapter_id.device_identifier, driver_desc, - adapter_id.device_name, context, 0); - } - } + /* The Battle.net System Checker expects both a NULL device and a GUID-based device */ + if (cont_enum && (flags & ~DDENUM_ATTACHEDSECONDARYDEVICES)) + ddraw_enumerate_secondary_devices(wined3d, callback, context); } __EXCEPT_PAGE_FAULT { @@ -546,7 +554,7 @@ struct ddraw_class_factory IClassFactory IClassFactory_iface; LONG ref; - HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID iid, LPVOID *ppObj); + HRESULT (*pfnCreateInstance)(IUnknown *outer, REFIID iid, void **out); }; static inline struct ddraw_class_factory *impl_from_IClassFactory(IClassFactory *iface) @@ -682,30 +690,13 @@ static const IClassFactoryVtbl IClassFactory_Vtbl = ddraw_class_factory_LockServer }; -/******************************************************************************* - * DllGetClassObject [DDRAW.@] - * Retrieves class object from a DLL object - * - * NOTES - * Docs say returns STDAPI - * - * PARAMS - * rclsid [I] CLSID for the class object - * riid [I] Reference to identifier of interface for class object - * ppv [O] Address of variable to receive interface pointer for riid - * - * RETURNS - * Success: S_OK - * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG, - * E_UNEXPECTED - */ -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **out) { struct ddraw_class_factory *factory; unsigned int i; - TRACE("rclsid %s, riid %s, object %p.\n", - debugstr_guid(rclsid), debugstr_guid(riid), ppv); + TRACE("rclsid %s, riid %s, out %p.\n", + debugstr_guid(rclsid), debugstr_guid(riid), out); if (!IsEqualGUID(&IID_IClassFactory, riid) && !IsEqualGUID(&IID_IUnknown, riid)) @@ -731,7 +722,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; - *ppv = factory; + *out = factory; return S_OK; } @@ -813,19 +804,6 @@ DestroyCallback(IDirectDrawSurface7 *surf, return DDENUMRET_OK; } -/*********************************************************************** - * get_config_key - * - * Reads a config key from the registry. Taken from WineD3D - * - ***********************************************************************/ -static inline DWORD get_config_key(HKEY defkey, HKEY appkey, const char* name, char* buffer, DWORD size) -{ - if (0 != appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0; - if (0 != defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0; - return ERROR_FILE_NOT_FOUND; -} - /*********************************************************************** * DllMain (DDRAW.0) * @@ -834,9 +812,8 @@ static inline DWORD get_config_key(HKEY defkey, HKEY appkey, const char* name, c * app didn't release them properly(Gothic 2, Diablo 2, Moto racer, ...) * ***********************************************************************/ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID reserved) +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { - TRACE("(%p,%x,%p)\n", hInstDLL, reason, reserved); switch (reason) { case DLL_PROCESS_ATTACH: @@ -852,7 +829,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID reserved) wc.lpfnWndProc = DefWindowProcA; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = hInstDLL; + wc.hInstance = inst; wc.hIcon = 0; wc.hCursor = 0; wc.hbrBackground = GetStockObject(BLACK_BRUSH); @@ -889,7 +866,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID reserved) DWORD type, data, size; size = sizeof(data); - if (!RegQueryValueExA( hkey, "ForceRefreshRate", NULL, &type, (LPBYTE)&data, &size ) && type == REG_DWORD) + if (!RegQueryValueExA(hkey, "ForceRefreshRate", NULL, &type, (BYTE *)&data, &size) && type == REG_DWORD) { TRACE("ForceRefreshRate set; overriding refresh rate to %d Hz\n", data); force_refresh_rate = data; @@ -901,14 +878,13 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID reserved) * exclusive mode, we replace the window proc of the ddraw window. If * an application would unload ddraw from the WM_DESTROY handler for * that window, it would return to unmapped memory and die. Apparently - * this is supposed to work on Windows. We should probably use - * GET_MODULE_HANDLE_EX_FLAG_PIN for this, but that's not currently - * implemented. */ - if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const WCHAR *)&ddraw_self, &ddraw_self)) + * this is supposed to work on Windows. */ + if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, + (const WCHAR *)&ddraw_self, &ddraw_self)) ERR("Failed to get own module handle.\n"); - instance = hInstDLL; - DisableThreadLibraryCalls(hInstDLL); + instance = inst; + DisableThreadLibraryCalls(inst); break; } @@ -977,7 +953,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID reserved) } if (reserved) break; - UnregisterClassA(DDRAW_WINDOW_CLASS_NAME, hInstDLL); + UnregisterClassA(DDRAW_WINDOW_CLASS_NAME, inst); } return TRUE; diff --git a/reactos/dll/directx/wine/ddraw/palette.c b/reactos/dll/directx/wine/ddraw/palette.c index cd43e82812a..fca27068547 100644 --- a/reactos/dll/directx/wine/ddraw/palette.c +++ b/reactos/dll/directx/wine/ddraw/palette.c @@ -89,10 +89,10 @@ static ULONG WINAPI ddraw_palette_Release(IDirectDrawPalette *iface) { wined3d_mutex_lock(); wined3d_palette_decref(This->wineD3DPalette); - if(This->ifaceToRelease) - { + if ((This->flags & DDPCAPS_PRIMARYSURFACE) && This->ddraw->primary) + This->ddraw->primary->palette = NULL; + if (This->ifaceToRelease) IUnknown_Release(This->ifaceToRelease); - } wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, This); @@ -125,20 +125,6 @@ static HRESULT WINAPI ddraw_palette_Initialize(IDirectDrawPalette *iface, return DDERR_ALREADYINITIALIZED; } -/***************************************************************************** - * IDirectDrawPalette::GetCaps - * - * Returns the palette description - * - * Params: - * Caps: Address to store the caps at - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if Caps is NULL - * For more details, see IWineD3DPalette::GetCaps - * - *****************************************************************************/ static HRESULT WINAPI ddraw_palette_GetCaps(IDirectDrawPalette *iface, DWORD *caps) { struct ddraw_palette *palette = impl_from_IDirectDrawPalette(iface); @@ -146,7 +132,7 @@ static HRESULT WINAPI ddraw_palette_GetCaps(IDirectDrawPalette *iface, DWORD *ca TRACE("iface %p, caps %p.\n", iface, caps); wined3d_mutex_lock(); - *caps = wined3d_palette_get_flags(palette->wineD3DPalette); + *caps = palette->flags; wined3d_mutex_unlock(); return D3D_OK; @@ -245,22 +231,55 @@ struct ddraw_palette *unsafe_impl_from_IDirectDrawPalette(IDirectDrawPalette *if return CONTAINING_RECORD(iface, struct ddraw_palette, IDirectDrawPalette_iface); } +static unsigned int palette_size(DWORD flags) +{ + switch (flags & (DDPCAPS_1BIT | DDPCAPS_2BIT | DDPCAPS_4BIT | DDPCAPS_8BIT)) + { + case DDPCAPS_1BIT: + return 2; + case DDPCAPS_2BIT: + return 4; + case DDPCAPS_4BIT: + return 16; + case DDPCAPS_8BIT: + return 256; + default: + return ~0u; + } +} + HRESULT ddraw_palette_init(struct ddraw_palette *palette, struct ddraw *ddraw, DWORD flags, PALETTEENTRY *entries) { + unsigned int entry_count; + DWORD wined3d_flags = 0; HRESULT hr; + if ((entry_count = palette_size(flags)) == ~0u) + { + WARN("Invalid flags %#x.\n", flags); + return DDERR_INVALIDPARAMS; + } + + if (flags & DDPCAPS_8BITENTRIES) + wined3d_flags |= WINED3D_PALETTE_8BIT_ENTRIES; + if (flags & DDPCAPS_ALLOW256) + wined3d_flags |= WINED3D_PALETTE_ALLOW_256; + if (flags & DDPCAPS_ALPHA) + wined3d_flags |= WINED3D_PALETTE_ALPHA; + palette->IDirectDrawPalette_iface.lpVtbl = &ddraw_palette_vtbl; palette->ref = 1; + palette->flags = flags; - hr = wined3d_palette_create(ddraw->wined3d_device, flags, - entries, palette, &palette->wineD3DPalette); - if (FAILED(hr)) + if (FAILED(hr = wined3d_palette_create(ddraw->wined3d_device, + wined3d_flags, entry_count, entries, &palette->wineD3DPalette))) { WARN("Failed to create wined3d palette, hr %#x.\n", hr); return hr; } + palette->ddraw = ddraw; palette->ifaceToRelease = (IUnknown *)&ddraw->IDirectDraw7_iface; IUnknown_AddRef(palette->ifaceToRelease); diff --git a/reactos/dll/directx/wine/ddraw/surface.c b/reactos/dll/directx/wine/ddraw/surface.c index b13708d8d19..9a35b1ad452 100644 --- a/reactos/dll/directx/wine/ddraw/surface.c +++ b/reactos/dll/directx/wine/ddraw/surface.c @@ -202,9 +202,10 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, wined3d_mutex_lock(); if (!This->device1) { - HRESULT hr = d3d_device_create(This->ddraw, This, 1, &This->device1, - (IUnknown *)&This->IDirectDrawSurface_iface); - if (FAILED(hr)) + HRESULT hr; + + if (FAILED(hr = d3d_device_create(This->ddraw, This, (IUnknown *)&This->IDirectDrawSurface_iface, + 1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface))) { This->device1 = NULL; wined3d_mutex_unlock(); @@ -463,7 +464,8 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface) surf = surface->complex_array[i]; surface->complex_array[i] = NULL; - ddraw_surface_cleanup(surf); + if (!surf->is_complex_root) + ddraw_surface_cleanup(surf); } if (surface->device1) @@ -478,6 +480,8 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface) surface, surface->ref7, surface->ref4, surface->ref3, surface->ref2, surface->ref1); } + if (surface->wined3d_texture) + wined3d_texture_decref(surface->wined3d_texture); if (surface->wined3d_surface) wined3d_surface_decref(surface->wined3d_surface); } @@ -499,10 +503,7 @@ ULONG ddraw_surface_release_iface(struct ddraw_surface *This) wined3d_mutex_unlock(); return iface_count; } - if (This->wined3d_texture) /* If it's a texture, destroy the wined3d texture. */ - wined3d_texture_decref(This->wined3d_texture); - else - ddraw_surface_cleanup(This); + ddraw_surface_cleanup(This); wined3d_mutex_unlock(); if (release_iface) @@ -934,7 +935,7 @@ static HRESULT surface_lock(struct ddraw_surface *This, } } - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(This, Rect, TRUE); if (SUCCEEDED(hr)) hr = wined3d_surface_map(This->wined3d_surface, &map_desc, Rect, Flags); @@ -954,7 +955,7 @@ static HRESULT surface_lock(struct ddraw_surface *This, } } - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { if (Flags & DDLOCK_READONLY) memset(&This->ddraw->primary_lock, 0, sizeof(This->ddraw->primary_lock)); @@ -1116,7 +1117,7 @@ static HRESULT WINAPI ddraw_surface7_Unlock(IDirectDrawSurface7 *iface, RECT *pR hr = wined3d_surface_unmap(surface->wined3d_surface); if (SUCCEEDED(hr)) { - if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE); surface->surface_desc.lpSurface = NULL; } @@ -1164,64 +1165,109 @@ static HRESULT WINAPI ddraw_surface1_Unlock(IDirectDrawSurface *iface, void *dat return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL); } -/***************************************************************************** - * IDirectDrawSurface7::Flip - * - * Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to - * IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces, - * the flip target is passed to WineD3D, even if the app didn't specify one - * - * Params: - * DestOverride: Specifies the surface that will become the new front - * buffer. If NULL, the current back buffer is used - * Flags: some DirectDraw flags, see include/ddraw.h - * - * Returns: - * DD_OK on success - * DDERR_NOTFLIPPABLE if no flip target could be found - * DDERR_INVALIDOBJECT if the surface isn't a front buffer - * For more details, see IWineD3DSurface::Flip - * - *****************************************************************************/ -static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *DestOverride, DWORD Flags) +static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *src, DWORD flags) { - struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); - struct ddraw_surface *Override = unsafe_impl_from_IDirectDrawSurface7(DestOverride); - IDirectDrawSurface7 *Override7; + struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface); + struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src); + struct ddraw_texture *ddraw_texture, *prev_ddraw_texture; + DDSCAPS2 caps = {DDSCAPS_FLIP, 0, 0, {0}}; + struct wined3d_surface *tmp, *rt; + struct wined3d_texture *texture; + IDirectDrawSurface7 *current; HRESULT hr; - TRACE("iface %p, dst %p, flags %#x.\n", iface, DestOverride, Flags); + TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags); - /* Flip has to be called from a front buffer - * What about overlay surfaces, AFAIK they can flip too? */ - if (!(surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY))) - return DDERR_INVALIDOBJECT; /* Unchecked */ + if (src == iface || !(dst_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY))) + return DDERR_NOTFLIPPABLE; wined3d_mutex_lock(); - /* WineD3D doesn't keep track of attached surface, so find the target */ - if(!Override) + tmp = dst_impl->wined3d_surface; + texture = dst_impl->wined3d_texture; + rt = wined3d_device_get_render_target(dst_impl->ddraw->wined3d_device, 0); + ddraw_texture = wined3d_texture_get_parent(dst_impl->wined3d_texture); + + if (src_impl) { - DDSCAPS2 Caps; - - memset(&Caps, 0, sizeof(Caps)); - Caps.dwCaps |= DDSCAPS_BACKBUFFER; - hr = ddraw_surface7_GetAttachedSurface(iface, &Caps, &Override7); - if(hr != DD_OK) + for (current = iface; current != src;) { - ERR("Can't find a flip target\n"); - wined3d_mutex_unlock(); - return DDERR_NOTFLIPPABLE; /* Unchecked */ + if (FAILED(hr = ddraw_surface7_GetAttachedSurface(current, &caps, ¤t))) + { + WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface); + wined3d_mutex_unlock(); + return DDERR_NOTFLIPPABLE; + } + ddraw_surface7_Release(current); + if (current == iface) + { + WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface); + wined3d_mutex_unlock(); + return DDERR_NOTFLIPPABLE; + } } - Override = impl_from_IDirectDrawSurface7(Override7); - /* For the GetAttachedSurface */ - ddraw_surface7_Release(Override7); + if (rt == dst_impl->wined3d_surface) + wined3d_device_set_render_target(dst_impl->ddraw->wined3d_device, 0, src_impl->wined3d_surface, FALSE); + wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl); + dst_impl->wined3d_surface = src_impl->wined3d_surface; + prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); + wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), ddraw_texture); + dst_impl->wined3d_texture = src_impl->wined3d_texture; + ddraw_texture = prev_ddraw_texture; + } + else + { + for (current = iface;;) + { + if (FAILED(hr = ddraw_surface7_GetAttachedSurface(current, &caps, ¤t))) + { + ERR("Can't find a flip target\n"); + wined3d_mutex_unlock(); + return DDERR_NOTFLIPPABLE; /* Unchecked */ + } + ddraw_surface7_Release(current); + if (current == iface) + { + dst_impl = impl_from_IDirectDrawSurface7(iface); + break; + } + + src_impl = impl_from_IDirectDrawSurface7(current); + if (rt == dst_impl->wined3d_surface) + wined3d_device_set_render_target(dst_impl->ddraw->wined3d_device, 0, src_impl->wined3d_surface, FALSE); + wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl); + dst_impl->wined3d_surface = src_impl->wined3d_surface; + prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); + wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), ddraw_texture); + ddraw_texture = prev_ddraw_texture; + dst_impl->wined3d_texture = src_impl->wined3d_texture; + dst_impl = src_impl; + } } - hr = wined3d_surface_flip(surface->wined3d_surface, Override->wined3d_surface, Flags); - if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) - hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE); + /* We don't have to worry about potential texture bindings, since + * flippable surfaces can never be textures. */ + if (rt == src_impl->wined3d_surface) + wined3d_device_set_render_target(dst_impl->ddraw->wined3d_device, 0, tmp, FALSE); + wined3d_resource_set_parent(wined3d_surface_get_resource(tmp), src_impl); + src_impl->wined3d_surface = tmp; + wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture); + src_impl->wined3d_texture = texture; + + if (flags) + { + static UINT once; + if (!once++) + FIXME("Ignoring flags %#x.\n", flags); + else + WARN("Ignoring flags %#x.\n", flags); + } + + if (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE); + else + hr = DD_OK; wined3d_mutex_unlock(); @@ -1287,12 +1333,12 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (!dst_surface->clipper) { - if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(src_surface, src_rect_in, TRUE); if (SUCCEEDED(hr)) hr = wined3d_surface_blt(dst_surface->wined3d_surface, dst_rect_in, wined3d_src_surface, src_rect_in, flags, fx, filter); - if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) + if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) hr = ddraw_surface_update_frontbuffer(dst_surface, dst_rect_in, FALSE); return hr; @@ -1371,7 +1417,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons src_rect_clipped.right -= (LONG)((dst_rect.right - clip_rect[i].right) * scale_x); src_rect_clipped.bottom -= (LONG)((dst_rect.bottom - clip_rect[i].bottom) * scale_y); - if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE))) break; @@ -1382,7 +1428,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons wined3d_src_surface, &src_rect_clipped, flags, fx, filter))) break; - if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE))) break; @@ -1930,7 +1976,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *hdc) return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE); if (SUCCEEDED(hr)) hr = wined3d_surface_getdc(surface->wined3d_surface, hdc); @@ -2006,7 +2052,7 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h wined3d_mutex_lock(); hr = wined3d_surface_releasedc(surface->wined3d_surface, hdc); - if (SUCCEEDED(hr) && (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) + if (SUCCEEDED(hr) && (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE); wined3d_mutex_unlock(); @@ -3965,12 +4011,12 @@ static HRESULT WINAPI ddraw_surface7_BltFast(IDirectDrawSurface7 *iface, DWORD d return DDERR_BLTFASTCANTCLIP; } - if (src->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + if (src->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(src, rsrc, TRUE); if (SUCCEEDED(hr)) hr = wined3d_surface_blt(This->wined3d_surface, &dst_rect, src->wined3d_surface, rsrc, flags, NULL, WINED3D_TEXF_POINT); - if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) + if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) hr = ddraw_surface_update_frontbuffer(This, &dst_rect, FALSE); wined3d_mutex_unlock(); @@ -4227,7 +4273,6 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, const DWORD allowed_flags = DDSD_LPSURFACE | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_CAPS; enum wined3d_format_id format_id; - BOOL update_wined3d = FALSE; UINT pitch, width, height; TRACE("iface %p, surface_desc %p, flags %#x.\n", iface, DDSD, Flags); @@ -4242,7 +4287,9 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, WARN("Flags is %x, returning DDERR_INVALIDPARAMS\n", Flags); return DDERR_INVALIDPARAMS; } - if (!(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) + if (!(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) + || This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE + || This->surface_desc.ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE)) { WARN("Surface is not in system memory, returning DDERR_INVALIDSURFACETYPE.\n"); return DDERR_INVALIDSURFACETYPE; @@ -4255,12 +4302,12 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, WARN("Invalid flags (0x%08x) set, returning DDERR_INVALIDPARAMS\n", DDSD->dwFlags); return DDERR_INVALIDPARAMS; } - if (!(DDSD->dwFlags & DDSD_LPSURFACE)) + if (!(DDSD->dwFlags & DDSD_LPSURFACE) || !DDSD->lpSurface) { - WARN("DDSD_LPSURFACE is not set, returning DDERR_INVALIDPARAMS\n"); + WARN("DDSD_LPSURFACE is not set or lpSurface is NULL, returning DDERR_INVALIDPARAMS\n"); return DDERR_INVALIDPARAMS; } - if (DDSD->dwFlags & DDSD_CAPS) + if ((DDSD->dwFlags & DDSD_CAPS) && DDSD->ddsCaps.dwCaps) { WARN("DDSD_CAPS is set, returning DDERR_INVALIDCAPS.\n"); return DDERR_INVALIDCAPS; @@ -4279,15 +4326,9 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, return DDERR_INVALIDPARAMS; } if (DDSD->dwWidth != This->surface_desc.dwWidth) - { TRACE("Surface width changed from %u to %u.\n", This->surface_desc.dwWidth, DDSD->dwWidth); - update_wined3d = TRUE; - } if (DDSD->u1.lPitch != This->surface_desc.u1.lPitch) - { TRACE("Surface pitch changed from %u to %u.\n", This->surface_desc.u1.lPitch, DDSD->u1.lPitch); - update_wined3d = TRUE; - } pitch = DDSD->u1.lPitch; width = DDSD->dwWidth; } @@ -4310,10 +4351,7 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, return DDERR_INVALIDPARAMS; } if (DDSD->dwHeight != This->surface_desc.dwHeight) - { TRACE("Surface height changed from %u to %u.\n", This->surface_desc.dwHeight, DDSD->dwHeight); - update_wined3d = TRUE; - } height = DDSD->dwHeight; } else @@ -4335,52 +4373,29 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, } current_format_id = wined3dformat_from_ddrawformat(&This->surface_desc.u4.ddpfPixelFormat); if (format_id != current_format_id) - { TRACE("Surface format changed from %#x to %#x.\n", current_format_id, format_id); - update_wined3d = TRUE; - } } else { format_id = wined3dformat_from_ddrawformat(&This->surface_desc.u4.ddpfPixelFormat); } - if (update_wined3d) + if (FAILED(hr = wined3d_surface_update_desc(This->wined3d_surface, width, height, + format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch))) { - if (FAILED(hr = wined3d_surface_update_desc(This->wined3d_surface, width, height, - format_id, WINED3D_MULTISAMPLE_NONE, 0))) - { - WARN("Failed to update surface desc, hr %#x.\n", hr); - wined3d_mutex_unlock(); - return hr; - } - - if (DDSD->dwFlags & DDSD_WIDTH) - This->surface_desc.dwWidth = width; - if (DDSD->dwFlags & DDSD_PITCH) - This->surface_desc.u1.lPitch = DDSD->u1.lPitch; - if (DDSD->dwFlags & DDSD_HEIGHT) - This->surface_desc.dwHeight = height; - if (DDSD->dwFlags & DDSD_PIXELFORMAT) - This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat; + WARN("Failed to update surface desc, hr %#x.\n", hr); + wined3d_mutex_unlock(); + return hr_ddraw_from_wined3d(hr); } - if (DDSD->dwFlags & DDSD_LPSURFACE && DDSD->lpSurface) - { - if (FAILED(hr = wined3d_surface_set_mem(This->wined3d_surface, DDSD->lpSurface, pitch))) - { - /* No need for a trace here, wined3d does that for us */ - switch(hr) - { - case WINED3DERR_INVALIDCALL: - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; - default: - break; /* Go on */ - } - } - /* DDSD->lpSurface is set by Lock() */ - } + if (DDSD->dwFlags & DDSD_WIDTH) + This->surface_desc.dwWidth = width; + if (DDSD->dwFlags & DDSD_PITCH) + This->surface_desc.u1.lPitch = DDSD->u1.lPitch; + if (DDSD->dwFlags & DDSD_HEIGHT) + This->surface_desc.dwHeight = height; + if (DDSD->dwFlags & DDSD_PIXELFORMAT) + This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat; wined3d_mutex_unlock(); @@ -4411,46 +4426,28 @@ static HRESULT WINAPI ddraw_surface3_SetSurfaceDesc(IDirectDrawSurface3 *iface, surface_desc ? &surface_desc2 : NULL, flags); } -/***************************************************************************** - * IDirectDrawSurface7::GetPalette - * - * Returns the IDirectDrawPalette interface of the palette currently assigned - * to the surface - * - * Params: - * Pal: Address to write the interface pointer to - * - * Returns: - * DD_OK on success - * DDERR_INVALIDPARAMS if Pal is NULL - * - *****************************************************************************/ -static HRESULT WINAPI ddraw_surface7_GetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette **Pal) +static HRESULT WINAPI ddraw_surface7_GetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette **palette) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); - struct wined3d_palette *wined3d_palette; struct ddraw_palette *palette_impl; HRESULT hr = DD_OK; - TRACE("iface %p, palette %p.\n", iface, Pal); + TRACE("iface %p, palette %p.\n", iface, palette); - if(!Pal) + if (!palette) return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - wined3d_palette = wined3d_surface_get_palette(surface->wined3d_surface); - if (wined3d_palette) + if ((palette_impl = surface->palette)) { - palette_impl = wined3d_palette_get_parent(wined3d_palette); - *Pal = &palette_impl->IDirectDrawPalette_iface; - IDirectDrawPalette_AddRef(*Pal); + *palette = &palette_impl->IDirectDrawPalette_iface; + IDirectDrawPalette_AddRef(*palette); } else { - *Pal = NULL; + *palette = NULL; hr = DDERR_NOPALETTEATTACHED; } - wined3d_mutex_unlock(); return hr; @@ -4492,132 +4489,97 @@ static HRESULT WINAPI ddraw_surface1_GetPalette(IDirectDrawSurface *iface, IDire return ddraw_surface7_GetPalette(&surface->IDirectDrawSurface7_iface, palette); } -/***************************************************************************** - * SetColorKeyEnum - * - * EnumAttachedSurface callback for SetColorKey. Used to set color keys - * recursively in the surface tree - * - *****************************************************************************/ -struct SCKContext +static HRESULT ddraw_surface_set_color_key(struct ddraw_surface *surface, DWORD flags, DDCOLORKEY *color_key) { - HRESULT ret; - struct wined3d_color_key *color_key; - DWORD Flags; -}; - -static HRESULT WINAPI SetColorKeyEnum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context) -{ - struct ddraw_surface *surface_impl = impl_from_IDirectDrawSurface7(surface); - struct SCKContext *ctx = context; - HRESULT hr; - - hr = wined3d_surface_set_color_key(surface_impl->wined3d_surface, ctx->Flags, ctx->color_key); - if (FAILED(hr)) - { - WARN("IWineD3DSurface_SetColorKey failed, hr = %08x\n", hr); - ctx->ret = hr; - } - - ddraw_surface7_EnumAttachedSurfaces(surface, context, SetColorKeyEnum); - ddraw_surface7_Release(surface); - - return DDENUMRET_OK; -} - -/***************************************************************************** - * IDirectDrawSurface7::SetColorKey - * - * Sets the color keying options for the surface. Observations showed that - * in case of complex surfaces the color key has to be assigned to all - * sublevels. - * - * Params: - * Flags: DDCKEY_* - * CKey: The new color key - * - * Returns: - * DD_OK on success - * See IWineD3DSurface::SetColorKey for details - * - *****************************************************************************/ -static HRESULT WINAPI ddraw_surface7_SetColorKey(IDirectDrawSurface7 *iface, DWORD Flags, DDCOLORKEY *CKey) -{ - struct ddraw_surface *This = impl_from_IDirectDrawSurface7(iface); - DDCOLORKEY FixedCKey; - struct SCKContext ctx = { DD_OK, (struct wined3d_color_key *)(CKey ? &FixedCKey : NULL), Flags }; - - TRACE("iface %p, flags %#x, color_key %p.\n", iface, Flags, CKey); + DDCOLORKEY fixed_color_key; + HRESULT hr = WINED3D_OK; wined3d_mutex_lock(); - if (CKey) + + if (color_key) { - FixedCKey = *CKey; + fixed_color_key = *color_key; /* Handle case where dwColorSpaceHighValue < dwColorSpaceLowValue */ - if (FixedCKey.dwColorSpaceHighValue < FixedCKey.dwColorSpaceLowValue) - FixedCKey.dwColorSpaceHighValue = FixedCKey.dwColorSpaceLowValue; + if (fixed_color_key.dwColorSpaceHighValue < fixed_color_key.dwColorSpaceLowValue) + fixed_color_key.dwColorSpaceHighValue = fixed_color_key.dwColorSpaceLowValue; - switch (Flags & ~DDCKEY_COLORSPACE) + switch (flags & ~DDCKEY_COLORSPACE) { - case DDCKEY_DESTBLT: - This->surface_desc.ddckCKDestBlt = FixedCKey; - This->surface_desc.dwFlags |= DDSD_CKDESTBLT; - break; + case DDCKEY_DESTBLT: + surface->surface_desc.ddckCKDestBlt = fixed_color_key; + surface->surface_desc.dwFlags |= DDSD_CKDESTBLT; + break; - case DDCKEY_DESTOVERLAY: - This->surface_desc.u3.ddckCKDestOverlay = FixedCKey; - This->surface_desc.dwFlags |= DDSD_CKDESTOVERLAY; - break; + case DDCKEY_DESTOVERLAY: + surface->surface_desc.u3.ddckCKDestOverlay = fixed_color_key; + surface->surface_desc.dwFlags |= DDSD_CKDESTOVERLAY; + break; - case DDCKEY_SRCOVERLAY: - This->surface_desc.ddckCKSrcOverlay = FixedCKey; - This->surface_desc.dwFlags |= DDSD_CKSRCOVERLAY; - break; + case DDCKEY_SRCOVERLAY: + surface->surface_desc.ddckCKSrcOverlay = fixed_color_key; + surface->surface_desc.dwFlags |= DDSD_CKSRCOVERLAY; + break; - case DDCKEY_SRCBLT: - This->surface_desc.ddckCKSrcBlt = FixedCKey; - This->surface_desc.dwFlags |= DDSD_CKSRCBLT; - break; + case DDCKEY_SRCBLT: + surface->surface_desc.ddckCKSrcBlt = fixed_color_key; + surface->surface_desc.dwFlags |= DDSD_CKSRCBLT; + break; - default: - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; + default: + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; } } else { - switch (Flags & ~DDCKEY_COLORSPACE) + switch (flags & ~DDCKEY_COLORSPACE) { - case DDCKEY_DESTBLT: - This->surface_desc.dwFlags &= ~DDSD_CKDESTBLT; - break; + case DDCKEY_DESTBLT: + surface->surface_desc.dwFlags &= ~DDSD_CKDESTBLT; + break; - case DDCKEY_DESTOVERLAY: - This->surface_desc.dwFlags &= ~DDSD_CKDESTOVERLAY; - break; + case DDCKEY_DESTOVERLAY: + surface->surface_desc.dwFlags &= ~DDSD_CKDESTOVERLAY; + break; - case DDCKEY_SRCOVERLAY: - This->surface_desc.dwFlags &= ~DDSD_CKSRCOVERLAY; - break; + case DDCKEY_SRCOVERLAY: + surface->surface_desc.dwFlags &= ~DDSD_CKSRCOVERLAY; + break; - case DDCKEY_SRCBLT: - This->surface_desc.dwFlags &= ~DDSD_CKSRCBLT; - break; + case DDCKEY_SRCBLT: + surface->surface_desc.dwFlags &= ~DDSD_CKSRCBLT; + break; - default: - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; + default: + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; } } - ctx.ret = wined3d_surface_set_color_key(This->wined3d_surface, Flags, ctx.color_key); - ddraw_surface7_EnumAttachedSurfaces(iface, &ctx, SetColorKeyEnum); + + if (surface->wined3d_texture) + hr = wined3d_texture_set_color_key(surface->wined3d_texture, flags, + color_key ? (struct wined3d_color_key *)&fixed_color_key : NULL); + wined3d_mutex_unlock(); - switch(ctx.ret) + return hr_ddraw_from_wined3d(hr); +} + +static HRESULT WINAPI ddraw_surface7_SetColorKey(IDirectDrawSurface7 *iface, DWORD flags, DDCOLORKEY *color_key) +{ + struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); + + TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); + + wined3d_mutex_lock(); + if (!surface->wined3d_texture) { - case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; - default: return ctx.ret; + wined3d_mutex_unlock(); + return DDERR_NOTONMIPMAPSUBLEVEL; } + wined3d_mutex_unlock(); + + return ddraw_surface_set_color_key(surface, flags, color_key); } static HRESULT WINAPI ddraw_surface4_SetColorKey(IDirectDrawSurface4 *iface, DWORD flags, DDCOLORKEY *color_key) @@ -4626,7 +4588,7 @@ static HRESULT WINAPI ddraw_surface4_SetColorKey(IDirectDrawSurface4 *iface, DWO TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); - return ddraw_surface7_SetColorKey(&surface->IDirectDrawSurface7_iface, flags, color_key); + return ddraw_surface_set_color_key(surface, flags, color_key); } static HRESULT WINAPI ddraw_surface3_SetColorKey(IDirectDrawSurface3 *iface, DWORD flags, DDCOLORKEY *color_key) @@ -4635,7 +4597,7 @@ static HRESULT WINAPI ddraw_surface3_SetColorKey(IDirectDrawSurface3 *iface, DWO TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); - return ddraw_surface7_SetColorKey(&surface->IDirectDrawSurface7_iface, flags, color_key); + return ddraw_surface_set_color_key(surface, flags, color_key); } static HRESULT WINAPI ddraw_surface2_SetColorKey(IDirectDrawSurface2 *iface, DWORD flags, DDCOLORKEY *color_key) @@ -4644,7 +4606,7 @@ static HRESULT WINAPI ddraw_surface2_SetColorKey(IDirectDrawSurface2 *iface, DWO TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); - return ddraw_surface7_SetColorKey(&surface->IDirectDrawSurface7_iface, flags, color_key); + return ddraw_surface_set_color_key(surface, flags, color_key); } static HRESULT WINAPI ddraw_surface1_SetColorKey(IDirectDrawSurface *iface, DWORD flags, DDCOLORKEY *color_key) @@ -4653,89 +4615,44 @@ static HRESULT WINAPI ddraw_surface1_SetColorKey(IDirectDrawSurface *iface, DWOR TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); - return ddraw_surface7_SetColorKey(&surface->IDirectDrawSurface7_iface, flags, color_key); + return ddraw_surface_set_color_key(surface, flags, color_key); } -/***************************************************************************** - * IDirectDrawSurface7::SetPalette - * - * Assigns a DirectDrawPalette object to the surface - * - * Params: - * Pal: Interface to the palette to set - * - * Returns: - * DD_OK on success - * - *****************************************************************************/ -static HRESULT WINAPI ddraw_surface7_SetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette *Pal) +static HRESULT WINAPI ddraw_surface7_SetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette *palette) { - struct ddraw_surface *This = impl_from_IDirectDrawSurface7(iface); - struct ddraw_palette *palette_impl = unsafe_impl_from_IDirectDrawPalette(Pal); - IDirectDrawPalette *oldPal; - struct ddraw_surface *surf; - HRESULT hr; + struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); + struct ddraw_palette *palette_impl = unsafe_impl_from_IDirectDrawPalette(palette); + struct ddraw_palette *prev; - TRACE("iface %p, palette %p.\n", iface, Pal); + TRACE("iface %p, palette %p.\n", iface, palette); - if (!(This->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | - DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8))) { + if (!(surface->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 + | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8))) return DDERR_INVALIDPIXELFORMAT; - } - if (This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL) - { + if (surface->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL) return DDERR_NOTONMIPMAPSUBLEVEL; - } - /* Find the old palette */ wined3d_mutex_lock(); - hr = IDirectDrawSurface_GetPalette(iface, &oldPal); - if(hr != DD_OK && hr != DDERR_NOPALETTEATTACHED) + + prev = surface->palette; + if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - wined3d_mutex_unlock(); - return hr; - } - if(oldPal) IDirectDrawPalette_Release(oldPal); /* For the GetPalette */ - - /* Set the new Palette */ - wined3d_surface_set_palette(This->wined3d_surface, palette_impl ? palette_impl->wineD3DPalette : NULL); - /* AddRef the Palette */ - if(Pal) IDirectDrawPalette_AddRef(Pal); - - /* Release the old palette */ - if(oldPal) IDirectDrawPalette_Release(oldPal); - - /* Update the wined3d frontbuffer if this is the frontbuffer. */ - if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) && This->ddraw->wined3d_frontbuffer) - wined3d_surface_set_palette(This->ddraw->wined3d_frontbuffer, - palette_impl ? palette_impl->wineD3DPalette : NULL); - - /* If this is a front buffer, also update the back buffers - * TODO: How do things work for palettized cube textures? - */ - if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) - { - /* For primary surfaces the tree is just a list, so the simpler scheme fits too */ - DDSCAPS2 caps2 = { DDSCAPS_PRIMARYSURFACE, 0, 0, {0} }; - - surf = This; - while(1) - { - IDirectDrawSurface7 *attach; - HRESULT hr; - hr = ddraw_surface7_GetAttachedSurface(&surf->IDirectDrawSurface7_iface, &caps2, &attach); - if(hr != DD_OK) - { - break; - } - - TRACE("Setting palette on %p\n", attach); - ddraw_surface7_SetPalette(attach, Pal); - surf = impl_from_IDirectDrawSurface7(attach); - ddraw_surface7_Release(attach); - } + if (prev) + prev->flags &= ~DDPCAPS_PRIMARYSURFACE; + if (palette_impl) + palette_impl->flags |= DDPCAPS_PRIMARYSURFACE; + /* Update the wined3d frontbuffer if this is the primary. */ + if (surface->ddraw->wined3d_frontbuffer) + wined3d_surface_set_palette(surface->ddraw->wined3d_frontbuffer, + palette_impl ? palette_impl->wineD3DPalette : NULL); } + if (palette_impl) + IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface); + if (prev) + IDirectDrawPalette_Release(&prev->IDirectDrawPalette_iface); + surface->palette = palette_impl; + wined3d_surface_set_palette(surface->wined3d_surface, palette_impl ? palette_impl->wineD3DPalette : NULL); wined3d_mutex_unlock(); @@ -4995,7 +4912,7 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface) * Loads a texture created with the DDSCAPS_ALLOCONLOAD * * This function isn't relayed to WineD3D because the whole interface is - * implemented in DDraw only. For speed improvements a implementation which + * implemented in DDraw only. For speed improvements an implementation which * takes OpenGL more into account could be placed into WineD3D. * * Params: @@ -5569,11 +5486,9 @@ static const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops = static void STDMETHODCALLTYPE ddraw_texture_wined3d_object_destroyed(void *parent) { - struct ddraw_surface *surface = parent; + TRACE("parent %p.\n", parent); - TRACE("surface %p.\n", surface); - - ddraw_surface_cleanup(surface); + HeapFree(GetProcessHeap(), 0, parent); } static const struct wined3d_parent_ops ddraw_texture_wined3d_parent_ops = @@ -5581,75 +5496,388 @@ static const struct wined3d_parent_ops ddraw_texture_wined3d_parent_ops = ddraw_texture_wined3d_object_destroyed, }; -HRESULT ddraw_surface_create_texture(struct ddraw_surface *surface, DWORD surface_flags) +static HRESULT CDECL ddraw_reset_enum_callback(struct wined3d_resource *resource) { - const DDSURFACEDESC2 *desc = &surface->surface_desc; + return DD_OK; +} + +HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, + struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) +{ + struct ddraw_surface *root, *mip, **attach; struct wined3d_resource_desc wined3d_desc; - struct ddraw_surface *mip, **attach; + struct wined3d_texture *wined3d_texture; struct wined3d_resource *resource; + struct wined3d_display_mode mode; + DDSURFACEDESC2 *desc, *mip_desc; + struct ddraw_texture *texture; UINT layers, levels, i, j; - DDSURFACEDESC2 *mip_desc; - enum wined3d_pool pool; HRESULT hr; - if (desc->ddsCaps.dwCaps & DDSCAPS_MIPMAP) - levels = desc->u2.dwMipMapCount; - else - levels = 1; + TRACE("ddraw %p, surface_desc %p, surface %p, outer_unknown %p, version %u.\n", + ddraw, surface_desc, surface, outer_unknown, version); + if (TRACE_ON(ddraw)) + { + TRACE("Requesting surface desc:\n"); + DDRAW_dump_surface_desc(surface_desc); + } - if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) - layers = 6; - else - layers = 1; + if (outer_unknown) + return CLASS_E_NOAGGREGATION; - /* DDSCAPS_SYSTEMMEMORY textures are in WINED3D_POOL_SYSTEM_MEM. - * Should I forward the MANAGED cap to the managed pool? */ - if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) - pool = WINED3D_POOL_SYSTEM_MEM; - else - pool = WINED3D_POOL_DEFAULT; + if (!surface) + return E_POINTER; + + if (!(texture = HeapAlloc(GetProcessHeap(), 0, sizeof(*texture)))) + return E_OUTOFMEMORY; + + texture->version = version; + texture->surface_desc = *surface_desc; + desc = &texture->surface_desc; + + /* Ensure DDSD_CAPS is always set. */ + desc->dwFlags |= DDSD_CAPS; + + /* If the surface is of the 'ALLOCONLOAD' type, ignore the LPSURFACE + * field. Frank Herbert's Dune specifies a NULL pointer for lpSurface. */ + if ((desc->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) || !desc->lpSurface) + desc->dwFlags &= ~DDSD_LPSURFACE; + + if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + DWORD flippable = desc->ddsCaps.dwCaps & (DDSCAPS_FLIP | DDSCAPS_COMPLEX); + + if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) + { + WARN("Tried to create a primary surface with DDSCAPS_TEXTURE.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + + if (flippable) + { + if (flippable != (DDSCAPS_FLIP | DDSCAPS_COMPLEX)) + { + WARN("Tried to create a flippable primary surface without both DDSCAPS_FLIP and DDSCAPS_COMPLEX.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + + if (!(desc->dwFlags & DDSD_BACKBUFFERCOUNT) || !desc->u5.dwBackBufferCount) + { + WARN("Tried to create a flippable primary surface without any back buffers.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + + if (!(ddraw->cooperative_level & DDSCL_EXCLUSIVE)) + { + WARN("Tried to create a flippable primary surface without DDSCL_EXCLUSIVE.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_NOEXCLUSIVEMODE; + } + } + } + + /* This is a special case in ddrawex, but not allowed in ddraw. */ + if ((desc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY)) + == (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY)) + { + WARN("Tried to create a surface in both system and video memory.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + + if ((desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) + && !(desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)) + { + WARN("Cube map faces requested without cube map flag.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + + if ((desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) + && !(desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES)) + { + WARN("Cube map without faces requested.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDPARAMS; + } + + if ((desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) + && (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) != DDSCAPS2_CUBEMAP_ALLFACES) + FIXME("Partial cube maps not implemented.\n"); + + if (desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE)) + { + if (!(desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + { + WARN("DDSCAPS2_TEXTUREMANAGE used without DDSCAPS_TEXTURE, returning DDERR_INVALIDCAPS.\n"); + HeapFree(GetProcessHeap(), 0, 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); + return DDERR_INVALIDCAPS; + } + } + + 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); + return hr_ddraw_from_wined3d(hr); + } + + /* No pixelformat given? Use the current screen format. */ + if (!(desc->dwFlags & DDSD_PIXELFORMAT)) + { + desc->dwFlags |= DDSD_PIXELFORMAT; + desc->u4.ddpfPixelFormat.dwSize = sizeof(desc->u4.ddpfPixelFormat); + ddrawformat_from_wined3dformat(&desc->u4.ddpfPixelFormat, mode.format_id); + } + + wined3d_desc.format = wined3dformat_from_ddrawformat(&desc->u4.ddpfPixelFormat); + if (wined3d_desc.format == WINED3DFMT_UNKNOWN) + { + WARN("Unsupported / unknown pixelformat.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDPIXELFORMAT; + } + + /* No width or no height? Use the screen size. */ + if (!(desc->dwFlags & DDSD_WIDTH) || !(desc->dwFlags & DDSD_HEIGHT)) + { + if (!(desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) + { + WARN("No width / height specified.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDPARAMS; + } + + desc->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT; + desc->dwWidth = mode.width; + desc->dwHeight = mode.height; + } + + if (!desc->dwWidth || !desc->dwHeight) + { + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDPARAMS; + } + + if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + /* The first surface is a front buffer, the back buffers are created + * afterwards. */ + if (desc->ddsCaps.dwCaps & DDSCAPS_FLIP) + desc->ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; + desc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE; + if (ddraw->cooperative_level & DDSCL_EXCLUSIVE) + { + struct wined3d_swapchain_desc swapchain_desc; + + wined3d_swapchain_get_desc(ddraw->wined3d_swapchain, &swapchain_desc); + swapchain_desc.backbuffer_width = mode.width; + swapchain_desc.backbuffer_height = mode.height; + swapchain_desc.backbuffer_format = mode.format_id; + + if (FAILED(hr = wined3d_device_reset(ddraw->wined3d_device, + &swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE))) + { + ERR("Failed to reset device.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return hr_ddraw_from_wined3d(hr); + } + } + } - wined3d_desc.format = wined3dformat_from_ddrawformat(&surface->surface_desc.u4.ddpfPixelFormat); wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = 0; wined3d_desc.usage = 0; - wined3d_desc.pool = pool; + wined3d_desc.pool = WINED3D_POOL_DEFAULT; wined3d_desc.width = desc->dwWidth; wined3d_desc.height = desc->dwHeight; wined3d_desc.depth = 1; wined3d_desc.size = 0; + if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && (ddraw->flags & DDRAW_NO3D)) + { + WARN("The application requests a 3D capable surface, but the ddraw object was created without 3D support.\n"); + /* Do not fail surface creation, only fail 3D device creation. */ + } + + /* Mipmap count fixes */ + if (desc->ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + if (desc->ddsCaps.dwCaps & DDSCAPS_COMPLEX) + { + if (desc->dwFlags & DDSD_MIPMAPCOUNT) + { + /* Mipmap count is given, should not be 0. */ + if (!desc->u2.dwMipMapCount) + { + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDPARAMS; + } + } + else + { + /* Undocumented feature: Create sublevels until either the + * width or the height is 1. */ + DWORD min = desc->dwWidth < desc->dwHeight ? desc->dwWidth : desc->dwHeight; + + desc->u2.dwMipMapCount = 0; + while (min) + { + ++desc->u2.dwMipMapCount; + min >>= 1; + } + } + } + else + { + desc->u2.dwMipMapCount = 1; + } + + desc->dwFlags |= DDSD_MIPMAPCOUNT; + levels = desc->u2.dwMipMapCount; + } + else + { + levels = 1; + } + + if (!(desc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY))) + { + if (!(desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE))) + { + enum wined3d_resource_type rtype; + DWORD usage = 0; + + if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) + rtype = WINED3D_RTYPE_CUBE_TEXTURE; + else if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) + rtype = WINED3D_RTYPE_TEXTURE; + else + rtype = WINED3D_RTYPE_SURFACE; + + if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) + usage = WINED3DUSAGE_DEPTHSTENCIL; + else if (desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) + usage = WINED3DUSAGE_RENDERTARGET; + + if (SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, + WINED3D_DEVICE_TYPE_HAL, mode.format_id, usage, rtype, wined3d_desc.format))) + desc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; + else + desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + } + else if (!(desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + { + /* Tests show surfaces without memory flags get these flags added + * right after creation. */ + desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY; + } + } + + if ((desc->ddsCaps.dwCaps & (DDSCAPS_OVERLAY | DDSCAPS_SYSTEMMEMORY)) + == (DDSCAPS_OVERLAY | DDSCAPS_SYSTEMMEMORY)) + { + WARN("System memory overlays are not allowed.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_NOOVERLAYHW; + } + + if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) + { + wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM; + } + else + { + if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) + wined3d_desc.usage |= WINED3DUSAGE_TEXTURE; + if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) + wined3d_desc.usage |= WINED3DUSAGE_DEPTHSTENCIL; + else if (desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) + wined3d_desc.usage |= WINED3DUSAGE_RENDERTARGET; + + if (desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE)) + { + wined3d_desc.pool = WINED3D_POOL_MANAGED; + /* Managed textures have the system memory flag set. */ + desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + } + else if (desc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) + { + /* Videomemory adds localvidmem. This is mutually exclusive with + * systemmemory and texturemanage. */ + desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM; + wined3d_desc.usage |= WINED3DUSAGE_DYNAMIC; + } + } + + if (desc->ddsCaps.dwCaps & (DDSCAPS_OVERLAY)) + wined3d_desc.usage |= WINED3DUSAGE_OVERLAY; + + if (desc->ddsCaps.dwCaps & DDSCAPS_OWNDC) + wined3d_desc.usage |= WINED3DUSAGE_OWNDC; + if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) { wined3d_desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE; - hr = wined3d_texture_create_cube(surface->ddraw->wined3d_device, &wined3d_desc, levels, - surface_flags, surface, &ddraw_texture_wined3d_parent_ops, &surface->wined3d_texture); + layers = 6; } else { wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE; - hr = wined3d_texture_create_2d(surface->ddraw->wined3d_device, &wined3d_desc, levels, - surface_flags, surface, &ddraw_texture_wined3d_parent_ops, &surface->wined3d_texture); + layers = 1; } - if (FAILED(hr)) + /* Some applications assume surfaces will always be mapped at the same + * address. Some of those also assume that this address is valid even when + * the surface isn't mapped, and that updates done this way will be + * visible on the screen. The game Nox is such an application, + * Commandos: Behind Enemy Lines is another. We set + * WINED3D_SURFACE_PIN_SYSMEM because of this. */ + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, levels, + WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); - return hr; + HeapFree(GetProcessHeap(), 0, texture); + return hr_ddraw_from_wined3d(hr); } + resource = wined3d_texture_get_sub_resource(wined3d_texture, 0); + root = wined3d_resource_get_parent(resource); + root->wined3d_texture = wined3d_texture; + root->is_complex_root = TRUE; + texture->root = root; + + if (desc->dwFlags & DDSD_CKDESTOVERLAY) + wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTOVERLAY, + (struct wined3d_color_key *)&desc->u3.ddckCKDestOverlay); + if (desc->dwFlags & DDSD_CKDESTBLT) + wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTBLT, + (struct wined3d_color_key *)&desc->ddckCKDestBlt); + if (desc->dwFlags & DDSD_CKSRCOVERLAY) + wined3d_texture_set_color_key(wined3d_texture, DDCKEY_SRCOVERLAY, + (struct wined3d_color_key *)&desc->ddckCKSrcOverlay); + if (desc->dwFlags & DDSD_CKSRCBLT) + wined3d_texture_set_color_key(wined3d_texture, DDCKEY_SRCBLT, + (struct wined3d_color_key *)&desc->ddckCKSrcBlt); + for (i = 0; i < layers; ++i) { - attach = &surface->complex_array[layers - 1 - i]; + attach = &root->complex_array[layers - 1 - i]; for (j = 0; j < levels; ++j) { - resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, i * levels + j); + resource = wined3d_texture_get_sub_resource(wined3d_texture, i * levels + j); mip = wined3d_resource_get_parent(resource); - - if (mip == surface) - continue; - mip_desc = &mip->surface_desc; if (j) @@ -5685,77 +5913,97 @@ HRESULT ddraw_surface_create_texture(struct ddraw_surface *surface, DWORD surfac } + if (mip == root) + continue; + *attach = mip; attach = &mip->complex_array[0]; } } + if (desc->dwFlags & DDSD_BACKBUFFERCOUNT) + { + unsigned int count = desc->u5.dwBackBufferCount; + struct ddraw_surface *last = root; + + attach = &last->complex_array[0]; + for (i = 0; i < count; ++i) + { + if (!(texture = HeapAlloc(GetProcessHeap(), 0, sizeof(*texture)))) + { + hr = E_OUTOFMEMORY; + goto fail; + } + + texture->version = version; + texture->surface_desc = root->surface_desc; + desc = &texture->surface_desc; + + /* Only one surface in the flipping chain is a back buffer, one is + * a front buffer, the others are just flippable surfaces. */ + desc->ddsCaps.dwCaps &= ~(DDSCAPS_VISIBLE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER + | DDSCAPS_BACKBUFFER); + if (!i) + desc->ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; + desc->u5.dwBackBufferCount = 0; + + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1, + WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) + { + HeapFree(GetProcessHeap(), 0, texture); + hr = hr_ddraw_from_wined3d(hr); + goto fail; + } + + resource = wined3d_texture_get_sub_resource(wined3d_texture, 0); + last = wined3d_resource_get_parent(resource); + last->wined3d_texture = wined3d_texture; + texture->root = last; + + if (desc->dwFlags & DDSD_CKDESTOVERLAY) + wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTOVERLAY, + (struct wined3d_color_key *)&desc->u3.ddckCKDestOverlay); + if (desc->dwFlags & DDSD_CKDESTBLT) + wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTBLT, + (struct wined3d_color_key *)&desc->ddckCKDestBlt); + if (desc->dwFlags & DDSD_CKSRCOVERLAY) + wined3d_texture_set_color_key(wined3d_texture, DDCKEY_SRCOVERLAY, + (struct wined3d_color_key *)&desc->ddckCKSrcOverlay); + if (desc->dwFlags & DDSD_CKSRCBLT) + wined3d_texture_set_color_key(wined3d_texture, DDCKEY_SRCBLT, + (struct wined3d_color_key *)&desc->ddckCKSrcBlt); + + *attach = last; + attach = &last->complex_array[0]; + } + *attach = root; + } + + if (surface_desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + ddraw->primary = root; + *surface = root; + return DD_OK; + +fail: + if (version == 7) + IDirectDrawSurface7_Release(&root->IDirectDrawSurface7_iface); + else if (version == 4) + IDirectDrawSurface4_Release(&root->IDirectDrawSurface4_iface); + else + IDirectDrawSurface_Release(&root->IDirectDrawSurface_iface); + + return hr; } -HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, - DDSURFACEDESC2 *desc, DWORD flags, UINT version) +HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture, + struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) { - enum wined3d_pool pool = WINED3D_POOL_DEFAULT; - enum wined3d_format_id format; - DWORD usage = 0; + DDSURFACEDESC2 *desc = &surface->surface_desc; + struct wined3d_resource_desc wined3d_desc; + unsigned int version = texture->version; HRESULT hr; - if (!(desc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY)) - && !((desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) - && (desc->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE))) - { - /* Tests show surfaces without memory flags get these flags added - * right after creation. */ - desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY; - } - - if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { - usage |= WINED3DUSAGE_RENDERTARGET; - desc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE; - } - - if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && !(desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) - { - usage |= WINED3DUSAGE_RENDERTARGET; - } - - if (desc->ddsCaps.dwCaps & (DDSCAPS_OVERLAY)) - { - usage |= WINED3DUSAGE_OVERLAY; - } - - if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) - usage |= WINED3DUSAGE_DEPTHSTENCIL; - - if (desc->ddsCaps.dwCaps & DDSCAPS_OWNDC) - usage |= WINED3DUSAGE_OWNDC; - - if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) - { - pool = WINED3D_POOL_SYSTEM_MEM; - } - else if (desc->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE) - { - pool = WINED3D_POOL_MANAGED; - /* Managed textures have the system memory flag set. */ - desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - } - else if (desc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) - { - /* Videomemory adds localvidmem. This is mutually exclusive with - * systemmemory and texturemanage. */ - desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM; - } - - format = wined3dformat_from_ddrawformat(&desc->u4.ddpfPixelFormat); - if (format == WINED3DFMT_UNKNOWN) - { - WARN("Unsupported / unknown pixelformat.\n"); - return DDERR_INVALIDPIXELFORMAT; - } - surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl; surface->IDirectDrawSurface4_iface.lpVtbl = &ddraw_surface4_vtbl; surface->IDirectDrawSurface3_iface.lpVtbl = &ddraw_surface3_vtbl; @@ -5784,59 +6032,30 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, surface->texture_outer = (IUnknown *)&surface->IDirectDrawSurface_iface; } - copy_to_surfacedesc2(&surface->surface_desc, desc); - + *desc = texture->surface_desc; + wined3d_resource_get_desc(wined3d_surface_get_resource(wined3d_surface), &wined3d_desc); + desc->dwWidth = wined3d_desc.width; + desc->dwHeight = wined3d_desc.height; surface->first_attached = surface; - if (FAILED(hr = wined3d_surface_create(ddraw->wined3d_device, desc->dwWidth, desc->dwHeight, format, - usage, pool, WINED3D_MULTISAMPLE_NONE, 0, flags, surface, - &ddraw_surface_wined3d_parent_ops, &surface->wined3d_surface))) - { - WARN("Failed to create wined3d surface, hr %#x.\n", hr); - return hr; - } - /* Anno 1602 stores the pitch right after surface creation, so make sure * it's there. TODO: Test other fourcc formats. */ - if (format == WINED3DFMT_DXT1 || format == WINED3DFMT_DXT2 || format == WINED3DFMT_DXT3 - || format == WINED3DFMT_DXT4 || format == WINED3DFMT_DXT5) + if (wined3d_desc.format == WINED3DFMT_DXT1 || wined3d_desc.format == WINED3DFMT_DXT2 + || wined3d_desc.format == WINED3DFMT_DXT3 || wined3d_desc.format == WINED3DFMT_DXT4 + || wined3d_desc.format == WINED3DFMT_DXT5) { surface->surface_desc.dwFlags |= DDSD_LINEARSIZE; - if (format == WINED3DFMT_DXT1) - { + if (wined3d_desc.format == WINED3DFMT_DXT1) surface->surface_desc.u1.dwLinearSize = max(4, desc->dwWidth) * max(4, desc->dwHeight) / 2; - } else - { surface->surface_desc.u1.dwLinearSize = max(4, desc->dwWidth) * max(4, desc->dwHeight); - } } else { surface->surface_desc.dwFlags |= DDSD_PITCH; - surface->surface_desc.u1.lPitch = wined3d_surface_get_pitch(surface->wined3d_surface); + surface->surface_desc.u1.lPitch = wined3d_surface_get_pitch(wined3d_surface); } - if (desc->dwFlags & DDSD_CKDESTOVERLAY) - { - wined3d_surface_set_color_key(surface->wined3d_surface, DDCKEY_DESTOVERLAY, - (struct wined3d_color_key *)&desc->u3.ddckCKDestOverlay); - } - if (desc->dwFlags & DDSD_CKDESTBLT) - { - wined3d_surface_set_color_key(surface->wined3d_surface, DDCKEY_DESTBLT, - (struct wined3d_color_key *)&desc->ddckCKDestBlt); - } - if (desc->dwFlags & DDSD_CKSRCOVERLAY) - { - wined3d_surface_set_color_key(surface->wined3d_surface, DDCKEY_SRCOVERLAY, - (struct wined3d_color_key *)&desc->ddckCKSrcOverlay); - } - if (desc->dwFlags & DDSD_CKSRCBLT) - { - wined3d_surface_set_color_key(surface->wined3d_surface, DDCKEY_SRCBLT, - (struct wined3d_color_key *)&desc->ddckCKSrcBlt); - } if (desc->dwFlags & DDSD_LPSURFACE) { UINT pitch = 0; @@ -5847,13 +6066,18 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, surface->surface_desc.u1.lPitch = pitch; } - if (FAILED(hr = wined3d_surface_set_mem(surface->wined3d_surface, desc->lpSurface, pitch))) + if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width, + wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0, + desc->lpSurface, pitch))) { ERR("Failed to set surface memory, hr %#x.\n", hr); - wined3d_surface_decref(surface->wined3d_surface); return hr; } } + wined3d_surface_incref(wined3d_surface); + surface->wined3d_surface = wined3d_surface; + *parent_ops = &ddraw_surface_wined3d_parent_ops; + return DD_OK; } diff --git a/reactos/dll/directx/wine/wined3d/CMakeLists.txt b/reactos/dll/directx/wine/wined3d/CMakeLists.txt index ad4913c3db5..a504e2bed86 100644 --- a/reactos/dll/directx/wine/wined3d/CMakeLists.txt +++ b/reactos/dll/directx/wine/wined3d/CMakeLists.txt @@ -9,10 +9,11 @@ include_directories(BEFORE ${REACTOS_SOURCE_DIR}/include/reactos/wine) spec2def(wined3d.dll wined3d.spec ADD_IMPORTLIB) list(APPEND SOURCE - ati_fragment_shader.c arb_program_shader.c + ati_fragment_shader.c buffer.c context.c + cs.c device.c directx.c drawprim.c diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index 66c4640a12c..2d30dd2d5f5 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -33,13 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); WINE_DECLARE_DEBUG_CHANNEL(d3d_constants); WINE_DECLARE_DEBUG_CHANNEL(d3d); -/* sRGB correction constants */ -static const float srgb_cmp = 0.0031308f; -static const float srgb_mul_low = 12.92f; -static const float srgb_pow = 0.41666f; -static const float srgb_mul_high = 1.055f; -static const float srgb_sub_high = 0.055f; - static BOOL shader_is_pshader_version(enum wined3d_shader_type type) { return type == WINED3D_SHADER_TYPE_PIXEL; @@ -145,9 +138,9 @@ static const char *arb_get_helper_value(enum wined3d_shader_type shader, enum ar } } -static inline BOOL ffp_clip_emul(const struct wined3d_state *state) +static inline BOOL ffp_clip_emul(const struct wined3d_context *context) { - return state->lowest_disabled_stage < 7; + return context->lowest_disabled_stage < 7; } /* ARB_program_shader private data */ @@ -176,7 +169,7 @@ struct control_frame struct arb_ps_np2fixup_info { struct ps_np2fixup_info super; - /* For ARB we need a offset value: + /* For ARB we need an offset value: * With both GLSL and ARB mode the NP2 fixup information (the texture dimensions) are stored in a * consecutive way (GLSL uses a uniform array). Since ARB doesn't know the notion of a "standalone" * array we need an offset to the index inside the program local parameter array. */ @@ -658,7 +651,9 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, if (!from_shader_select) { - const struct wined3d_shader *vshader = state->vertex_shader, *pshader = state->pixel_shader; + const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; + const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; + if (vshader && (vshader->reg_maps.boolean_constants || (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION] @@ -692,7 +687,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, if (useVertexShader) { - struct wined3d_shader *vshader = state->vertex_shader; + const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; const struct arb_vs_compiled_shader *gl_shader = priv->compiled_vprog; /* Load DirectX 9 float constants for vertex shader */ @@ -703,7 +698,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, if (usePixelShader) { - struct wined3d_shader *pshader = state->pixel_shader; + const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; UINT rt_height = state->fb->render_targets[0]->resource.height; @@ -764,6 +759,17 @@ static void shader_arb_update_float_pixel_constants(struct wined3d_device *devic priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, start + count); } +static void shader_arb_append_imm_vec4(struct wined3d_shader_buffer *buffer, const float *values) +{ + char str[4][17]; + + wined3d_ftoa(values[0], str[0]); + wined3d_ftoa(values[1], str[1]); + wined3d_ftoa(values[2], str[2]); + wined3d_ftoa(values[3], str[3]); + shader_addline(buffer, "{%s, %s, %s, %s}", str[0], str[1], str[2], str[3]); +} + /* Generate the variable & register declarations for the ARB_vertex_program output target */ static void shader_generate_arb_declarations(const struct wined3d_shader *shader, const struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_buffer *buffer, @@ -868,8 +874,9 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader { const float *value; value = (const float *)lconst->value; - shader_addline(buffer, "PARAM C%u = {%.8e, %.8e, %.8e, %.8e};\n", lconst->idx, - value[0], value[1], value[2], value[3]); + shader_addline(buffer, "PARAM C%u = ", lconst->idx); + shader_arb_append_imm_vec4(buffer, value); + shader_addline(buffer, ";\n"); } } @@ -1106,7 +1113,7 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction if (!pshader && reg->idx[0].rel_addr) { const struct arb_vshader_private *shader_data = shader->backend_data; - UINT rel_offset = shader_data->rel_offset; + UINT rel_offset = ctx->target_version == ARB ? shader_data->rel_offset : 0; BOOL aL = FALSE; char rel_reg[50]; if (reg_maps->shader_version.major < 2) @@ -1493,17 +1500,16 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in const struct wined3d_shader_src_param *src, unsigned int tmpreg, char *outregstr) { /* Generate a line that does the input modifier computation and return the input register to use */ - BOOL is_color = FALSE; + BOOL is_color = FALSE, insert_line; char regstr[256]; char swzstr[20]; - int insert_line; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data; const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); const char *two = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_TWO); /* Assume a new line will be added */ - insert_line = 1; + insert_line = TRUE; /* Get register name */ shader_arb_get_register_name(ins, &src->reg, regstr, &is_color); @@ -1513,11 +1519,11 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in { case WINED3DSPSM_NONE: sprintf(outregstr, "%s%s", regstr, swzstr); - insert_line = 0; + insert_line = FALSE; break; case WINED3DSPSM_NEG: sprintf(outregstr, "-%s%s", regstr, swzstr); - insert_line = 0; + insert_line = FALSE; break; case WINED3DSPSM_BIAS: shader_addline(buffer, "ADD T%c, %s, -coefdiv.x;\n", 'A' + tmpreg, regstr); @@ -1551,7 +1557,7 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in case WINED3DSPSM_ABS: if(ctx->target_version >= NV2) { sprintf(outregstr, "|%s%s|", regstr, swzstr); - insert_line = 0; + insert_line = FALSE; } else { shader_addline(buffer, "ABS T%c, %s;\n", 'A' + tmpreg, regstr); } @@ -1563,11 +1569,11 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in shader_addline(buffer, "ABS T%c, %s;\n", 'A' + tmpreg, regstr); sprintf(outregstr, "-T%c%s", 'A' + tmpreg, swzstr); } - insert_line = 0; + insert_line = FALSE; break; default: sprintf(outregstr, "%s%s", regstr, swzstr); - insert_line = 0; + insert_line = FALSE; } /* Return modified or original register, with swizzle */ @@ -1837,7 +1843,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) const struct arb_vshader_private *shader_data = shader->backend_data; src0_param[0] = '\0'; - if (shader_data->rel_offset) + if (shader_data->rel_offset && ctx->target_version == ARB) { const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET); shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param); @@ -3442,29 +3448,29 @@ static void arbfp_add_sRGB_correction(struct wined3d_shader_buffer *buffer, cons if(condcode) { /* Sigh. MOVC CC doesn't work, so use one of the temps as dummy dest */ - shader_addline(buffer, "SUBC %s, %s.x, srgb_consts1.y;\n", tmp1, fragcolor); + shader_addline(buffer, "SUBC %s, %s.x, srgb_consts1.x;\n", tmp1, fragcolor); /* Calculate the > 0.0031308 case */ - shader_addline(buffer, "POW %s.x (GE), %s.x, srgb_consts1.z;\n", fragcolor, fragcolor); - shader_addline(buffer, "POW %s.y (GE), %s.y, srgb_consts1.z;\n", fragcolor, fragcolor); - shader_addline(buffer, "POW %s.z (GE), %s.z, srgb_consts1.z;\n", fragcolor, fragcolor); - shader_addline(buffer, "MUL %s.xyz (GE), %s, srgb_consts1.w;\n", fragcolor, fragcolor); - shader_addline(buffer, "SUB %s.xyz (GE), %s, srgb_consts2.x;\n", fragcolor, fragcolor); + shader_addline(buffer, "POW %s.x (GE), %s.x, srgb_consts0.x;\n", fragcolor, fragcolor); + shader_addline(buffer, "POW %s.y (GE), %s.y, srgb_consts0.x;\n", fragcolor, fragcolor); + shader_addline(buffer, "POW %s.z (GE), %s.z, srgb_consts0.x;\n", fragcolor, fragcolor); + shader_addline(buffer, "MUL %s.xyz (GE), %s, srgb_consts0.y;\n", fragcolor, fragcolor); + shader_addline(buffer, "SUB %s.xyz (GE), %s, srgb_consts0.z;\n", fragcolor, fragcolor); /* Calculate the < case */ - shader_addline(buffer, "MUL %s.xyz (LT), srgb_consts1.x, %s;\n", fragcolor, fragcolor); + shader_addline(buffer, "MUL %s.xyz (LT), srgb_consts0.w, %s;\n", fragcolor, fragcolor); } else { /* Calculate the > 0.0031308 case */ - shader_addline(buffer, "POW %s.x, %s.x, srgb_consts1.z;\n", tmp1, fragcolor); - shader_addline(buffer, "POW %s.y, %s.y, srgb_consts1.z;\n", tmp1, fragcolor); - shader_addline(buffer, "POW %s.z, %s.z, srgb_consts1.z;\n", tmp1, fragcolor); - shader_addline(buffer, "MUL %s, %s, srgb_consts1.w;\n", tmp1, tmp1); - shader_addline(buffer, "SUB %s, %s, srgb_consts2.x;\n", tmp1, tmp1); + shader_addline(buffer, "POW %s.x, %s.x, srgb_consts0.x;\n", tmp1, fragcolor); + shader_addline(buffer, "POW %s.y, %s.y, srgb_consts0.x;\n", tmp1, fragcolor); + shader_addline(buffer, "POW %s.z, %s.z, srgb_consts0.x;\n", tmp1, fragcolor); + shader_addline(buffer, "MUL %s, %s, srgb_consts0.y;\n", tmp1, tmp1); + shader_addline(buffer, "SUB %s, %s, srgb_consts0.z;\n", tmp1, tmp1); /* Calculate the < case */ - shader_addline(buffer, "MUL %s, srgb_consts1.x, %s;\n", tmp2, fragcolor); + shader_addline(buffer, "MUL %s, srgb_consts0.w, %s;\n", tmp2, fragcolor); /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */ - shader_addline(buffer, "SLT %s, srgb_consts1.y, %s;\n", tmp3, fragcolor); - shader_addline(buffer, "SGE %s, srgb_consts1.y, %s;\n", tmp4, fragcolor); + shader_addline(buffer, "SLT %s, srgb_consts1.x, %s;\n", tmp3, fragcolor); + shader_addline(buffer, "SGE %s, srgb_consts1.x, %s;\n", tmp4, fragcolor); /* Store the components > 0.0031308 in the destination */ shader_addline(buffer, "MUL %s.xyz, %s, %s;\n", fragcolor, tmp1, tmp3); /* Add the components that are < 0.0031308 */ @@ -3593,6 +3599,7 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, BOOL custom_linear_fog = FALSE; char srgbtmp[4][4]; + char ftoa_tmp[17]; unsigned int i, found = 0; for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i) @@ -3718,7 +3725,8 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, if(dcl_td) shader_addline(buffer, "TEMP TD;\n"); /* Used for sRGB writing */ shader_addline(buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n"); shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n"); - shader_addline(buffer, "PARAM ps_helper_const = { 0.0, 1.0, %1.10f, 0.0 };\n", eps); + wined3d_ftoa(eps, ftoa_tmp); + shader_addline(buffer, "PARAM ps_helper_const = { 0.0, 1.0, %s, 0.0 };\n", ftoa_tmp); if (reg_maps->shader_version.major < 2) { @@ -3742,11 +3750,14 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, } } - if(args->super.srgb_correction) { - shader_addline(buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n", - srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high); - shader_addline(buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n", - srgb_sub_high, 0.0, 0.0, 0.0); + if (args->super.srgb_correction) + { + shader_addline(buffer, "PARAM srgb_consts0 = "); + shader_arb_append_imm_vec4(buffer, wined3d_srgb_const0); + shader_addline(buffer, ";\n"); + shader_addline(buffer, "PARAM srgb_consts1 = "); + shader_arb_append_imm_vec4(buffer, wined3d_srgb_const1); + shader_addline(buffer, ";\n"); } /* Base Declarations */ @@ -3972,7 +3983,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(*sig)); + found_sig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*found_sig)); found_sig->sig = clone_sig(sig); found_sig->idx = priv->ps_sig_number++; TRACE("New signature stored and assigned number %u\n", found_sig->idx); @@ -4203,7 +4214,9 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader, shader_addline(buffer, "TEMP TMP_FOGCOORD;\n"); if (need_helper_const(shader_data, reg_maps, gl_info)) { - shader_addline(buffer, "PARAM helper_const = { 0.0, 1.0, 2.0, %1.10f};\n", eps); + char ftoa_tmp[17]; + wined3d_ftoa(eps, ftoa_tmp); + shader_addline(buffer, "PARAM helper_const = { 0.0, 1.0, 2.0, %s};\n", ftoa_tmp); } if (need_rel_addr_const(shader_data, reg_maps, gl_info)) { @@ -4412,12 +4425,9 @@ static inline BOOL vs_args_equal(const struct arb_vs_compile_args *stored, const } static struct arb_vs_compiled_shader *find_arb_vshader(struct wined3d_shader *shader, - const struct arb_vs_compile_args *args, + const struct wined3d_gl_info *gl_info, DWORD use_map, const struct arb_vs_compile_args *args, const struct wined3d_shader_signature_element *ps_input_sig) { - struct wined3d_device *device = shader->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - DWORD use_map = device->stream_info.use_map; UINT i; DWORD new_size; struct arb_vs_compiled_shader *new_array; @@ -4508,7 +4518,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state, int i; WORD int_skip; - find_ps_compile_args(state, shader, &args->super); + find_ps_compile_args(state, shader, context->stream_info.position_transformed, &args->super, gl_info); /* This forces all local boolean constants to 1 to make them stateblock independent */ args->bools = shader->reg_maps.local_bool_consts; @@ -4559,19 +4569,19 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, const struct wined3d_context *context, const struct wined3d_shader *shader, struct arb_vs_compile_args *args) { - struct wined3d_device *device = shader->device; + const struct wined3d_device *device = shader->device; const struct wined3d_adapter *adapter = device->adapter; const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info; int i; WORD int_skip; - find_vs_compile_args(state, shader, &args->super); + find_vs_compile_args(state, shader, context->stream_info.swizzle_map, &args->super); args->clip.boolclip_compare = 0; if (use_ps(state)) { - const struct wined3d_shader *ps = state->pixel_shader; + const struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct arb_pshader_private *shader_priv = ps->backend_data; args->ps_signature = shader_priv->input_signature_idx; @@ -4581,9 +4591,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, { args->ps_signature = ~0; if (!d3d_info->vs_clipping && adapter->fragment_pipe == &arbfp_fragment_pipeline) - { - args->clip.boolclip.clip_texcoord = ffp_clip_emul(state) ? d3d_info->limits.ffp_blend_stages : 0; - } + args->clip.boolclip.clip_texcoord = ffp_clip_emul(context) ? d3d_info->limits.ffp_blend_stages : 0; /* Otherwise: Setting boolclip_compare set clip_texcoord to 0 */ } @@ -4603,9 +4611,9 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, args->clip.boolclip.bools |= ( 1 << i); } - args->vertex.samplers[0] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 0]; - args->vertex.samplers[1] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 1]; - args->vertex.samplers[2] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 2]; + args->vertex.samplers[0] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 0]; + args->vertex.samplers[1] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 1]; + args->vertex.samplers[2] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 2]; args->vertex.samplers[3] = 0; /* Skip if unused or local */ @@ -4645,7 +4653,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context /* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */ if (use_ps(state)) { - struct wined3d_shader *ps = state->pixel_shader; + struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; struct arb_ps_compile_args compile_args; struct arb_ps_compiled_shader *compiled; @@ -4712,7 +4720,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context if (use_vs(state)) { - struct wined3d_shader *vs = state->vertex_shader; + struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; struct arb_vs_compile_args compile_args; struct arb_vs_compiled_shader *compiled; const struct wined3d_shader_signature_element *ps_input_sig; @@ -4726,9 +4734,10 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context if (compile_args.ps_signature == ~0U) ps_input_sig = NULL; else - ps_input_sig = state->pixel_shader->input_signature; + ps_input_sig = state->shader[WINED3D_SHADER_TYPE_PIXEL]->input_signature; - compiled = find_arb_vshader(vs, &compile_args, ps_input_sig); + compiled = find_arb_vshader(vs, context->gl_info, context->stream_info.use_map, + &compile_args, ps_input_sig); priv->current_vprogram_id = compiled->prgId; priv->compiled_vprog = compiled; @@ -5300,7 +5309,7 @@ static BOOL get_bool_const(const struct wined3d_shader_instruction *ins, if (reg_maps->local_bool_consts & flag) { - /* What good is a if(bool) with a hardcoded local constant? I don't know, but handle it */ + /* What good is an if(bool) with a hardcoded local constant? I don't know, but handle it */ LIST_FOR_EACH_ENTRY(constant, &shader->constantsB, struct wined3d_shader_lconst, entry) { if (constant->idx == idx) @@ -6170,7 +6179,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con BOOL luminance_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; UINT lowest_disabled_stage; const char *textype; - const char *instr, *sat; + const char *instr; char colorcor_dst[8]; GLuint ret; DWORD arg0, arg1, arg2; @@ -6285,11 +6294,14 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con } shader_addline(&buffer, "PARAM specular_enable = program.env[%u];\n", ARB_FFP_CONST_SPECULAR_ENABLE); - if(settings->sRGB_write) { - shader_addline(&buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n", - srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high); - shader_addline(&buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n", - srgb_sub_high, 0.0, 0.0, 0.0); + if (settings->sRGB_write) + { + shader_addline(&buffer, "PARAM srgb_consts0 = "); + shader_arb_append_imm_vec4(&buffer, wined3d_srgb_const0); + shader_addline(&buffer, ";\n"); + shader_addline(&buffer, "PARAM srgb_consts1 = "); + shader_arb_append_imm_vec4(&buffer, wined3d_srgb_const1); + shader_addline(&buffer, ";\n"); } if (lowest_disabled_stage < 7 && settings->emul_clipplanes) @@ -6310,12 +6322,6 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con default: textype = "unexpected_textype"; break; } - if (settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP - || settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE) - sat = ""; - else - sat = "_SAT"; - if(settings->op[stage].projected == proj_none) { instr = "TEX"; } else if(settings->op[stage].projected == proj_count4 || @@ -6350,8 +6356,8 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con shader_addline(&buffer, "ADD ret, ret, fragment.texcoord[%u];\n", stage); } - shader_addline(&buffer, "%s%s tex%u, ret, texture[%u], %s;\n", - instr, sat, stage, stage, textype); + shader_addline(&buffer, "%s tex%u, ret, texture[%u], %s;\n", + instr, stage, stage, textype); if (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE) { shader_addline(&buffer, "MAD_SAT ret.x, tex%u.z, luminance%u.x, luminance%u.y;\n", @@ -6361,11 +6367,11 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con } else if(settings->op[stage].projected == proj_count3) { shader_addline(&buffer, "MOV ret, fragment.texcoord[%u];\n", stage); shader_addline(&buffer, "MOV ret.w, ret.z;\n"); - shader_addline(&buffer, "%s%s tex%u, ret, texture[%u], %s;\n", - instr, sat, stage, stage, textype); + shader_addline(&buffer, "%s tex%u, ret, texture[%u], %s;\n", + instr, stage, stage, textype); } else { - shader_addline(&buffer, "%s%s tex%u, fragment.texcoord[%u], texture[%u], %s;\n", - instr, sat, stage, stage, stage, textype); + shader_addline(&buffer, "%s tex%u, fragment.texcoord[%u], texture[%u], %s;\n", + instr, stage, stage, stage, textype); } sprintf(colorcor_dst, "tex%u", stage); @@ -6564,7 +6570,7 @@ static void state_arbfp_fog(struct wined3d_context *context, const struct wined3 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); - if (!isStateDirty(context, STATE_PIXELSHADER)) + if (!isStateDirty(context, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL))) fragment_prog_arbfp(context, state, state_id); if (!state->render_states[WINED3D_RS_FOGENABLE]) @@ -6598,141 +6604,141 @@ static void state_arbfp_fog(struct wined3d_context *context, const struct wined3 static void textransform(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - if (!isStateDirty(context, STATE_PIXELSHADER)) + if (!isStateDirty(context, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL))) fragment_prog_arbfp(context, state, state_id); } static const struct StateEntryTemplate arbfp_fragmentstate_template[] = { {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_PIXELSHADER, { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_srgbwrite }, ARB_FRAMEBUFFER_SRGB }, - {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, @@ -6888,6 +6894,8 @@ static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum compl static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, char *luminance) { const char *tex; + static const float yv12_coef[] + = {2.0f / 3.0f, 1.0f / 6.0f, (2.0f / 3.0f) + (1.0f / 6.0f), 1.0f / 3.0f}; switch(textype) { case GL_TEXTURE_2D: tex = "2D"; break; @@ -6935,8 +6943,9 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, * When reading from rectangle textures, keep in mind that the input y coordinates * go from 0 to d3d_height, whereas the opengl texture height is 1.5 * d3d_height */ - shader_addline(buffer, "PARAM yv12_coef = {%f, %f, %f, %f};\n", - 2.0f / 3.0f, 1.0f / 6.0f, (2.0f / 3.0f) + (1.0f / 6.0f), 1.0f / 3.0f); + shader_addline(buffer, "PARAM yv12_coef = "); + shader_arb_append_imm_vec4(buffer, yv12_coef); + shader_addline(buffer, ";\n"); shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n"); /* the chroma planes have only half the width */ @@ -7101,7 +7110,7 @@ static void upload_palette(const struct wined3d_surface *surface, struct wined3d struct wined3d_device *device = surface->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct arbfp_blit_priv *priv = device->blit_priv; - BOOL colorkey = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) != 0; + BOOL colorkey = !!(surface->container->color_key_flags & WINEDDSD_CKSRCBLT); d3dfmt_p8_init_palette(surface, table, colorkey); @@ -7286,12 +7295,7 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context, struct arbfp_blit_priv *priv = blit_priv; enum complex_fixup fixup; const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum textype; - - if (surface->container) - textype = surface->container->target; - else - textype = surface->texture_target; + GLenum textype = surface->container->target; if (surface->flags & SFLAG_CONVERTED) { @@ -7439,9 +7443,14 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter, RECT src_rect = *src_rect_in; RECT dst_rect = *dst_rect_in; + /* Activate the destination context, set it up for blitting */ + context = context_acquire(device, dst_surface); + /* Now load the surface */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && (src_surface->flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) == SFLAG_INDRAWABLE) + && (src_surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) + == WINED3D_LOCATION_DRAWABLE + && !surface_is_offscreen(src_surface)) { /* Without FBO blits transferring from the drawable to the texture is * expensive, because we have to flip the data in sysmem. Since we can @@ -7454,10 +7463,8 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter, src_rect.bottom = src_surface->resource.height - src_rect.bottom; } else - surface_internal_preload(src_surface, SRGB_RGB); + wined3d_texture_load(src_surface->container, context, FALSE); - /* Activate the destination context, set it up for blitting */ - context = context_acquire(device, dst_surface); context_apply_blit_state(context, device); if (!surface_is_offscreen(dst_surface)) @@ -7477,11 +7484,12 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter, context_release(context); - surface_modify_location(dst_surface, dst_surface->draw_binding, TRUE); + surface_validate_location(dst_surface, dst_surface->draw_binding); + surface_invalidate_location(dst_surface, ~dst_surface->draw_binding); + return WINED3D_OK; } -/* Do not call while under the GL lock. */ static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, const RECT *dst_rect, const struct wined3d_color *color) { @@ -7489,7 +7497,6 @@ static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined return WINED3DERR_INVALIDCALL; } -/* Do not call while under the GL lock. */ static HRESULT arbfp_blit_depth_fill(struct wined3d_device *device, struct wined3d_surface *surface, const RECT *rect, float depth) { diff --git a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c index 0dd577441b1..92c25dbe27b 100644 --- a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -868,7 +868,7 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined */ for (i = 0; i < desc->num_textures_used; ++i) { - mapped_stage = device->texUnitMap[i]; + mapped_stage = context->tex_unit_map[i]; if (mapped_stage != WINED3D_UNMAPPED_STAGE) { context_active_texture(context, gl_info, mapped_stage); @@ -916,7 +916,7 @@ static void set_bumpmat(struct wined3d_context *context, const struct wined3d_st static void textransform(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - if (!isStateDirty(context, STATE_PIXELSHADER)) + if (!isStateDirty(context, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL))) set_tex_op_atifs(context, state, state_id); } @@ -1075,7 +1075,7 @@ static const struct StateEntryTemplate atifs_fragmentstate_template[] = { {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_PIXELSHADER, { STATE_PIXELSHADER, atifs_apply_pixelshader }, WINED3D_GL_EXT_NONE }, + {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), atifs_apply_pixelshader }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; diff --git a/reactos/dll/directx/wine/wined3d/buffer.c b/reactos/dll/directx/wine/wined3d/buffer.c index 5a0f0abc8aa..6a6fbcf2776 100644 --- a/reactos/dll/directx/wine/wined3d/buffer.c +++ b/reactos/dll/directx/wine/wined3d/buffer.c @@ -3,7 +3,7 @@ * Copyright 2002-2005 Raphael Junqueira * Copyright 2004 Christian Costa * Copyright 2005 Oliver Stieber - * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers + * Copyright 2007-2011, 2013-2014 Stefan Dösinger for CodeWeavers * Copyright 2009-2010 Henri Verbeet for CodeWeavers * * This library is free software; you can redistribute it and/or @@ -115,10 +115,11 @@ static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_g } /* Context activation is done by the caller. */ -static void buffer_create_buffer_object(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) +static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) { GLenum gl_usage = GL_STATIC_DRAW_ARB; GLenum error; + const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Creating an OpenGL vertex buffer object for wined3d_buffer %p with usage %s.\n", This, debug_d3dusage(This->resource.usage)); @@ -145,7 +146,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, const struc } if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - device_invalidate_state(This->resource.device, STATE_INDEXBUFFER); + context_invalidate_state(context, STATE_INDEXBUFFER); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); error = gl_info->gl_ops.gl.p_glGetError(); if (error != GL_NO_ERROR) @@ -177,7 +178,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, const struc * calling glBufferSubData on updates. Upload the actual data in case * we're not double buffering, so we can release the heap mem afterwards */ - GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, This->resource.allocatedMemory, gl_usage)); + GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, This->resource.heap_memory, gl_usage)); error = gl_info->gl_ops.gl.p_glGetError(); if (error != GL_NO_ERROR) { @@ -185,19 +186,12 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, const struc goto fail; } - This->buffer_object_size = This->resource.size; This->buffer_object_usage = gl_usage; if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) - { buffer_invalidate_bo_range(This, 0, 0); - } else - { - wined3d_resource_free_sysmem(This->resource.heap_memory); - This->resource.allocatedMemory = NULL; - This->resource.heap_memory = NULL; - } + wined3d_resource_free_sysmem(&This->resource); return; @@ -265,9 +259,11 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, return ret; } +#define WINED3D_BUFFER_FIXUP_D3DCOLOR 0x01 +#define WINED3D_BUFFER_FIXUP_XYZRHW 0x02 + static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si, - UINT attrib_idx, const BOOL check_d3dcolor, const BOOL check_position, const BOOL is_ffp_color, - DWORD *stride_this_run) + UINT attrib_idx, DWORD fixup_flags, DWORD *stride_this_run) { const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx]; enum wined3d_format_id format; @@ -282,13 +278,11 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win format = attrib->format->id; /* Look for newly appeared conversion */ - if (check_d3dcolor && format == WINED3DFMT_B8G8R8A8_UNORM) + if (fixup_flags & WINED3D_BUFFER_FIXUP_D3DCOLOR && format == WINED3DFMT_B8G8R8A8_UNORM) { ret = buffer_process_converted_attribute(This, CONV_D3DCOLOR, attrib, stride_this_run); - - if (!is_ffp_color) FIXME("Test for non-color fixed function WINED3DFMT_B8G8R8A8_UNORM format\n"); } - else if (check_position && si->position_transformed) + else if (fixup_flags & WINED3D_BUFFER_FIXUP_XYZRHW && si->position_transformed) { if (format != WINED3DFMT_R32G32B32A32_FLOAT) { @@ -306,14 +300,9 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win return ret; } -static BOOL buffer_find_decl(struct wined3d_buffer *This) +static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_stream_info *si, + DWORD fixup_flags) { - struct wined3d_device *device = This->resource.device; - const struct wined3d_adapter *adapter = device->adapter; - const struct wined3d_stream_info *si = &device->stream_info; - const struct wined3d_state *state = &device->state; - BOOL support_d3dcolor = adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA]; - BOOL support_xyzrhw = adapter->d3d_info.xyzrhw; UINT stride_this_run = 0; BOOL ret = FALSE; @@ -326,9 +315,9 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) if(This->resource.usage & WINED3DUSAGE_STATICDECL) return FALSE; } - if (use_vs(state)) + if (!fixup_flags) { - TRACE("Vertex shaders used, no VBO conversion is needed\n"); + TRACE("No fixup required.\n"); if(This->conversion_map) { HeapFree(GetProcessHeap(), 0, This->conversion_map); @@ -387,29 +376,31 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) */ ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION, - TRUE, !support_xyzrhw, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; + fixup_flags &= ~WINED3D_BUFFER_FIXUP_XYZRHW; + ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE, - !support_d3dcolor, FALSE, TRUE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_SPECULAR, - !support_d3dcolor, FALSE, TRUE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD0, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD1, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD2, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD3, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD4, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD5, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD6, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD7, - TRUE, FALSE, FALSE, &stride_this_run) || ret; + fixup_flags, &stride_this_run) || ret; if (!stride_this_run && This->conversion_map) { @@ -457,7 +448,7 @@ static inline void fixup_transformed_pos(float *p) } /* Context activation is done by the caller. */ -void buffer_get_memory(struct wined3d_buffer *buffer, const struct wined3d_gl_info *gl_info, +void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo_address *data) { data->buffer_object = buffer->buffer_object; @@ -465,7 +456,7 @@ void buffer_get_memory(struct wined3d_buffer *buffer, const struct wined3d_gl_in { if ((buffer->flags & WINED3D_BUFFER_CREATEBO) && !buffer->resource.map_count) { - buffer_create_buffer_object(buffer, gl_info); + buffer_create_buffer_object(buffer, context); buffer->flags &= ~WINED3D_BUFFER_CREATEBO; if (buffer->buffer_object) { @@ -474,7 +465,7 @@ void buffer_get_memory(struct wined3d_buffer *buffer, const struct wined3d_gl_in return; } } - data->addr = buffer->resource.allocatedMemory; + data->addr = buffer->resource.heap_memory; } else { @@ -492,25 +483,27 @@ ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer) } /* Context activation is done by the caller. */ -BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) +BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) { - /* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */ - if(This->resource.allocatedMemory) return This->resource.allocatedMemory; + const struct wined3d_gl_info *gl_info = context->gl_info; - This->resource.heap_memory = wined3d_resource_allocate_sysmem(This->resource.size); - This->resource.allocatedMemory = This->resource.heap_memory; + /* Heap_memory exists if the buffer is double buffered or has no buffer object at all. */ + if (This->resource.heap_memory) + return This->resource.heap_memory; + + if (!wined3d_resource_allocate_sysmem(&This->resource)) + ERR("Failed to allocate system memory.\n"); if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - device_invalidate_state(This->resource.device, STATE_INDEXBUFFER); + context_invalidate_state(context, STATE_INDEXBUFFER); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); - GL_EXTCALL(glGetBufferSubDataARB(This->buffer_type_hint, 0, This->resource.size, This->resource.allocatedMemory)); + GL_EXTCALL(glGetBufferSubDataARB(This->buffer_type_hint, 0, This->resource.size, This->resource.heap_memory)); This->flags |= WINED3D_BUFFER_DOUBLEBUFFER; - return This->resource.allocatedMemory; + return This->resource.heap_memory; } -/* Do not call while under the GL lock. */ static void buffer_unload(struct wined3d_resource *resource) { struct wined3d_buffer *buffer = buffer_from_resource(resource); @@ -527,7 +520,7 @@ static void buffer_unload(struct wined3d_resource *resource) /* Download the buffer, but don't permanently enable double buffering */ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(buffer, context->gl_info); + buffer_get_sysmem(buffer, context); buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; } @@ -547,7 +540,6 @@ static void buffer_unload(struct wined3d_resource *resource) resource_unload(resource); } -/* Do not call while under the GL lock. */ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) { ULONG refcount = InterlockedDecrement(&buffer->resource.ref); @@ -709,7 +701,7 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined start = This->maps[This->modified_areas].offset; len = This->maps[This->modified_areas].size; - memcpy(map + start, This->resource.allocatedMemory + start, len); + memcpy(map + start, (BYTE *)This->resource.heap_memory + start, len); if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) { @@ -726,14 +718,14 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined checkGLcall("glUnmapBufferARB"); } -/* Do not call while under the GL lock. */ -void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) +/* Context activation is done by the caller. */ +void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct wined3d_state *state) { DWORD flags = buffer->flags & (WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD); struct wined3d_device *device = buffer->resource.device; UINT start = 0, end = 0, len = 0, vertices; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; BOOL decl_changed = FALSE; unsigned int i, j; BYTE *data; @@ -753,9 +745,7 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) /* TODO: Make converting independent from VBOs */ if (buffer->flags & WINED3D_BUFFER_CREATEBO) { - context = context_acquire(device, NULL); - buffer_create_buffer_object(buffer, context->gl_info); - context_release(context); + buffer_create_buffer_object(buffer, context); buffer->flags &= ~WINED3D_BUFFER_CREATEBO; } else @@ -765,10 +755,21 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) } } - /* Reading the declaration makes only sense if the stateblock is finalized and the buffer bound to a stream */ - if (device->isInDraw && buffer->resource.bind_count > 0) + /* Reading the declaration makes only sense if we have valid state information + * (i.e., if this function is called during draws). */ + if (state) { - decl_changed = buffer_find_decl(buffer); + DWORD fixup_flags = 0; + + if (!use_vs(state)) + { + if (!context->gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) + fixup_flags |= WINED3D_BUFFER_FIXUP_D3DCOLOR; + if (!context->d3d_info->xyzrhw) + fixup_flags |= WINED3D_BUFFER_FIXUP_XYZRHW; + } + + decl_changed = buffer_find_decl(buffer, &context->stream_info, fixup_flags); buffer->flags |= WINED3D_BUFFER_HASDESC; } @@ -852,7 +853,7 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) if (!buffer->conversion_map) { /* That means that there is nothing to fixup. Just upload from - * buffer->resource.allocatedMemory directly into the vbo. Do not + * buffer->resource.heap_memory directly into the vbo. Do not * free the system memory copy because drawPrimitive may need it if * the stride is 0, for instancing emulation, vertex blending * emulation or shader emulation. */ @@ -864,19 +865,16 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) return; } - context = context_acquire(device, NULL); buffer_direct_upload(buffer, context->gl_info, flags); - context_release(context); return; } - context = context_acquire(device, NULL); gl_info = context->gl_info; if(!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(buffer, gl_info); + buffer_get_sysmem(buffer, context); } /* Now for each vertex in the buffer that needs conversion */ @@ -891,7 +889,7 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) len = buffer->maps[buffer->modified_areas].size; end = start + len; - memcpy(data + start, buffer->resource.allocatedMemory + start, end - start); + memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start); for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertices); ++i) { for (j = 0; j < buffer->stride; ++j) @@ -924,6 +922,13 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) } HeapFree(GetProcessHeap(), 0, data); +} + +void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) +{ + struct wined3d_context *context; + context = context_acquire(buffer->resource.device, NULL); + buffer_internal_preload(buffer, context, NULL); context_release(context); } @@ -938,6 +943,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN { BOOL dirty = buffer_is_dirty(buffer); LONG count; + BYTE *base; TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); @@ -973,7 +979,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) { GLbitfield mapflags = wined3d_resource_gl_map_flags(flags); - buffer->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint, + buffer->map_ptr = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint, 0, buffer->resource.size, mapflags)); checkGLcall("glMapBufferRange"); } @@ -981,18 +987,18 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN { if (buffer->flags & WINED3D_BUFFER_APPLESYNC) buffer_sync_apple(buffer, flags, gl_info); - buffer->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(buffer->buffer_type_hint, + buffer->map_ptr = GL_EXTCALL(glMapBufferARB(buffer->buffer_type_hint, GL_READ_WRITE_ARB)); checkGLcall("glMapBufferARB"); } - if (((DWORD_PTR)buffer->resource.allocatedMemory) & (RESOURCE_ALIGNMENT - 1)) + if (((DWORD_PTR)buffer->map_ptr) & (RESOURCE_ALIGNMENT - 1)) { - WARN("Pointer %p is not %u byte aligned.\n", buffer->resource.allocatedMemory, RESOURCE_ALIGNMENT); + WARN("Pointer %p is not %u byte aligned.\n", buffer->map_ptr, RESOURCE_ALIGNMENT); GL_EXTCALL(glUnmapBufferARB(buffer->buffer_type_hint)); checkGLcall("glUnmapBufferARB"); - buffer->resource.allocatedMemory = NULL; + buffer->map_ptr = NULL; if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC) { @@ -1009,9 +1015,10 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN else { TRACE("Falling back to doublebuffered operation\n"); - buffer_get_sysmem(buffer, gl_info); + buffer_get_sysmem(buffer, context); } - TRACE("New pointer is %p.\n", buffer->resource.allocatedMemory); + TRACE("New pointer is %p.\n", buffer->resource.heap_memory); + buffer->map_ptr = NULL; } context_release(context); } @@ -1037,9 +1044,10 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN } } - *data = buffer->resource.allocatedMemory + offset; + base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; + *data = base + offset; - TRACE("Returning memory at %p (base %p, offset %u).\n", *data, buffer->resource.allocatedMemory, offset); + TRACE("Returning memory at %p (base %p, offset %u).\n", *data, base, offset); /* TODO: check Flags compatibility with buffer->currentDesc.Usage (see MSDN) */ return WINED3D_OK; @@ -1105,7 +1113,6 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); - buffer->resource.allocatedMemory = NULL; buffer_clear_dirty_areas(buffer); } else if (buffer->flags & WINED3D_BUFFER_HASDESC) @@ -1145,7 +1152,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device buffer->buffer_type_hint = bind_hint; TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, - debug_d3dformat(buffer->resource.format->id), buffer->resource.allocatedMemory, buffer); + debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory, buffer); if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) { diff --git a/reactos/dll/directx/wine/wined3d/context.c b/reactos/dll/directx/wine/wined3d/context.c index cfa5974216c..b9afbe1f8b4 100644 --- a/reactos/dll/directx/wine/wined3d/context.c +++ b/reactos/dll/directx/wine/wined3d/context.c @@ -131,14 +131,14 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context, { switch (location) { - case SFLAG_INTEXTURE: - case SFLAG_INSRGBTEX: + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: surface_prepare_texture(depth_stencil, context, FALSE); if (format_flags & WINED3DFMT_FLAG_DEPTH) { gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, - depth_stencil->texture_target, depth_stencil->texture_name, + depth_stencil->texture_target, depth_stencil->container->texture_rgb.name, depth_stencil->texture_level); checkGLcall("glFramebufferTexture2D()"); } @@ -146,26 +146,26 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context, if (format_flags & WINED3DFMT_FLAG_STENCIL) { gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, - depth_stencil->texture_target, depth_stencil->texture_name, + depth_stencil->texture_target, depth_stencil->container->texture_rgb.name, depth_stencil->texture_level); checkGLcall("glFramebufferTexture2D()"); } break; - case SFLAG_INRB_MULTISAMPLE: + case WINED3D_LOCATION_RB_MULTISAMPLE: surface_prepare_rb(depth_stencil, gl_info, TRUE); context_attach_depth_stencil_rb(gl_info, fbo_target, format_flags, depth_stencil->rb_multisample); break; - case SFLAG_INRB_RESOLVED: + case WINED3D_LOCATION_RB_RESOLVED: surface_prepare_rb(depth_stencil, gl_info, FALSE); context_attach_depth_stencil_rb(gl_info, fbo_target, format_flags, depth_stencil->rb_resolved); break; default: - ERR("Unsupported location %s (%#x).\n", debug_surflocation(location), location); + ERR("Unsupported location %s (%#x).\n", wined3d_debug_location(location), location); break; } } @@ -206,9 +206,9 @@ static void context_attach_surface_fbo(struct wined3d_context *context, switch (location) { - case SFLAG_INTEXTURE: - case SFLAG_INSRGBTEX: - srgb = location == SFLAG_INSRGBTEX; + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: + srgb = location == WINED3D_LOCATION_TEXTURE_SRGB; surface_prepare_texture(surface, context, srgb); gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface->texture_target, surface_get_texture_name(surface, gl_info, srgb), @@ -216,14 +216,14 @@ static void context_attach_surface_fbo(struct wined3d_context *context, checkGLcall("glFramebufferTexture2D()"); break; - case SFLAG_INRB_MULTISAMPLE: + case WINED3D_LOCATION_RB_MULTISAMPLE: surface_prepare_rb(surface, gl_info, TRUE); gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_RENDERBUFFER, surface->rb_multisample); checkGLcall("glFramebufferRenderbuffer()"); break; - case SFLAG_INRB_RESOLVED: + case WINED3D_LOCATION_RB_RESOLVED: surface_prepare_rb(surface, gl_info, FALSE); gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_RENDERBUFFER, surface->rb_resolved); @@ -231,7 +231,7 @@ static void context_attach_surface_fbo(struct wined3d_context *context, break; default: - ERR("Unsupported location %s (%#x).\n", debug_surflocation(location), location); + ERR("Unsupported location %s (%#x).\n", wined3d_debug_location(location), location); break; } } @@ -268,7 +268,7 @@ void context_check_fbo_status(const struct wined3d_context *context, GLenum targ return; } - FIXME("\tLocation %s (%#x).\n", debug_surflocation(context->current_fbo->location), + FIXME("\tLocation %s (%#x).\n", wined3d_debug_location(context->current_fbo->location), context->current_fbo->location); /* Dump the FBO attachments */ @@ -459,7 +459,7 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ context->rebind_fbo = FALSE; } - if (location == SFLAG_INDRAWABLE) + if (location == WINED3D_LOCATION_DRAWABLE) { context->current_fbo = NULL; context_bind_fbo(context, target, 0); @@ -806,6 +806,8 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) context_set_current(NULL); return FALSE; } + + ctx->valid = 1; } return TRUE; } @@ -836,25 +838,9 @@ static void context_update_window(struct wined3d_context *context) context, context->win_handle, context->swapchain->win_handle); if (context->valid) - { - /* You'd figure ReleaseDC() would fail if the DC doesn't match the - * window. However, that's not what actually happens, and there are - * user32 tests that confirm ReleaseDC() with the wrong window is - * supposed to succeed. So explicitly check that the DC belongs to - * the window, since we want to avoid releasing a DC that belongs to - * some other window if the original window was already destroyed. */ - if (WindowFromDC(context->hdc) != context->win_handle) - { - WARN("DC %p does not belong to window %p.\n", - context->hdc, context->win_handle); - } - else if (!ReleaseDC(context->win_handle, context->hdc)) - { - ERR("Failed to release device context %p, last error %#x.\n", - context->hdc, GetLastError()); - } - } - else context->valid = 1; + wined3d_release_dc(context->win_handle, context->hdc); + else + context->valid = 1; context->win_handle = context->swapchain->win_handle; @@ -879,7 +865,6 @@ err: context->valid = 0; } -/* Do not call while under the GL lock. */ static void context_destroy_gl_resources(struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -980,7 +965,7 @@ static void context_destroy_gl_resources(struct wined3d_context *context) ERR("Failed to disable GL context.\n"); } - ReleaseDC(context->win_handle, context->hdc); + wined3d_release_dc(context->win_handle, context->hdc); if (!wglDeleteContext(context->glCtx)) { @@ -1004,7 +989,6 @@ struct wined3d_context *context_get_current(void) return TlsGetValue(wined3d_context_tls_idx); } -/* Do not call while under the GL lock. */ BOOL context_set_current(struct wined3d_context *ctx) { struct wined3d_context *old = context_get_current(); @@ -1289,7 +1273,6 @@ static void WINE_GLAPI wined3d_debug_callback(GLenum source, GLenum type, GLuint } } -/* Do not call while under the GL lock. */ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_surface *target, const struct wined3d_format *ds_format) { @@ -1345,6 +1328,21 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, goto out; } + /* Initialize the texture unit mapping to a 1:1 mapping */ + for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) + { + if (s < gl_info->limits.fragment_samplers) + { + ret->tex_unit_map[s] = s; + ret->rev_tex_unit_map[s] = s; + } + else + { + ret->tex_unit_map[s] = WINED3D_UNMAPPED_STAGE; + ret->rev_tex_unit_map[s] = WINED3D_UNMAPPED_STAGE; + } + } + if (!(hdc = GetDC(swapchain->win_handle))) { WARN("Failed to retireve device context, trying swapchain backup.\n"); @@ -1648,7 +1646,6 @@ out: return NULL; } -/* Do not call while under the GL lock. */ void context_destroy(struct wined3d_device *device, struct wined3d_context *context) { BOOL destroy; @@ -1768,7 +1765,7 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con */ for (i = gl_info->limits.textures - 1; i > 0 ; --i) { - sampler = device->rev_tex_unit_map[i]; + sampler = context->rev_tex_unit_map[i]; context_active_texture(context, gl_info, i); if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) @@ -1798,7 +1795,7 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con } context_active_texture(context, gl_info, 0); - sampler = device->rev_tex_unit_map[0]; + sampler = context->rev_tex_unit_map[0]; if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) { @@ -2091,7 +2088,7 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ - surface_load_location(context->current_rt, SFLAG_INTEXTURE, NULL); + surface_load_location(context->current_rt, WINED3D_LOCATION_TEXTURE_RGB); swapchain->render_to_fbo = TRUE; swapchain_update_draw_bindings(swapchain); context_set_render_offscreen(context, TRUE); @@ -2119,7 +2116,7 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine if (context->render_offscreen) { - surface_internal_preload(rt, SRGB_RGB); + wined3d_texture_load(rt->container, context, FALSE); context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, rt, NULL, rt->draw_binding); if (rt->resource.format->id != WINED3DFMT_NULL) @@ -2206,11 +2203,11 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win ++i; } context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, fb->depth_stencil, - rt_count ? rts[0]->draw_binding : SFLAG_INTEXTURE); + rt_count ? rts[0]->draw_binding : WINED3D_LOCATION_TEXTURE_RGB); } else { - context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, SFLAG_INDRAWABLE); + context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, WINED3D_LOCATION_DRAWABLE); rt_mask = context_generate_rt_mask_from_surface(rts[0]); } @@ -2272,7 +2269,7 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const { const struct wined3d_state *state = &device->state; struct wined3d_surface **rts = state->fb->render_targets; - struct wined3d_shader *ps = state->pixel_shader; + struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; DWORD rt_mask, rt_mask_bits; unsigned int i; @@ -2307,7 +2304,7 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat { if (!context->render_offscreen) { - context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, SFLAG_INDRAWABLE); + context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, WINED3D_LOCATION_DRAWABLE); } else { @@ -2324,6 +2321,238 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat } } +static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) +{ + DWORD i = context->rev_tex_unit_map[unit]; + DWORD j = context->tex_unit_map[stage]; + + context->tex_unit_map[stage] = unit; + if (i != WINED3D_UNMAPPED_STAGE && i != stage) + context->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; + + context->rev_tex_unit_map[unit] = stage; + if (j != WINED3D_UNMAPPED_STAGE && j != unit) + context->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE; +} + +static void context_invalidate_texture_stage(struct wined3d_context *context, DWORD stage) +{ + DWORD i; + + for (i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i) + context_invalidate_state(context, STATE_TEXTURESTAGE(stage, i)); +} + +static void context_update_fixed_function_usage_map(struct wined3d_context *context, + const struct wined3d_state *state) +{ + UINT i, start, end; + + context->fixed_function_usage_map = 0; + for (i = 0; i < MAX_TEXTURES; ++i) + { + enum wined3d_texture_op color_op = state->texture_states[i][WINED3D_TSS_COLOR_OP]; + enum wined3d_texture_op alpha_op = state->texture_states[i][WINED3D_TSS_ALPHA_OP]; + DWORD color_arg1 = state->texture_states[i][WINED3D_TSS_COLOR_ARG1] & WINED3DTA_SELECTMASK; + DWORD color_arg2 = state->texture_states[i][WINED3D_TSS_COLOR_ARG2] & WINED3DTA_SELECTMASK; + DWORD color_arg3 = state->texture_states[i][WINED3D_TSS_COLOR_ARG0] & WINED3DTA_SELECTMASK; + DWORD alpha_arg1 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] & WINED3DTA_SELECTMASK; + DWORD alpha_arg2 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] & WINED3DTA_SELECTMASK; + DWORD alpha_arg3 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] & WINED3DTA_SELECTMASK; + + /* Not used, and disable higher stages. */ + if (color_op == WINED3D_TOP_DISABLE) + break; + + if (((color_arg1 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG2) + || ((color_arg2 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG1) + || ((color_arg3 == WINED3DTA_TEXTURE) + && (color_op == WINED3D_TOP_MULTIPLY_ADD || color_op == WINED3D_TOP_LERP)) + || ((alpha_arg1 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG2) + || ((alpha_arg2 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG1) + || ((alpha_arg3 == WINED3DTA_TEXTURE) + && (alpha_op == WINED3D_TOP_MULTIPLY_ADD || alpha_op == WINED3D_TOP_LERP))) + context->fixed_function_usage_map |= (1 << i); + + if ((color_op == WINED3D_TOP_BUMPENVMAP || color_op == WINED3D_TOP_BUMPENVMAP_LUMINANCE) + && i < MAX_TEXTURES - 1) + context->fixed_function_usage_map |= (1 << (i + 1)); + } + + if (i < context->lowest_disabled_stage) + { + start = i; + end = context->lowest_disabled_stage; + } + else + { + start = context->lowest_disabled_stage; + end = i; + } + + context->lowest_disabled_stage = i; + for (i = start + 1; i < end; ++i) + { + context_invalidate_state(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)); + } +} + +static void context_map_fixed_function_samplers(struct wined3d_context *context, + const struct wined3d_state *state) +{ + unsigned int i, tex; + WORD ffu_map; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + + context_update_fixed_function_usage_map(context, state); + ffu_map = context->fixed_function_usage_map; + + if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages + || context->lowest_disabled_stage <= d3d_info->limits.ffp_textures) + { + for (i = 0; ffu_map; ffu_map >>= 1, ++i) + { + if (!(ffu_map & 1)) + continue; + + if (context->tex_unit_map[i] != i) + { + context_map_stage(context, i, i); + context_invalidate_state(context, STATE_SAMPLER(i)); + context_invalidate_texture_stage(context, i); + } + } + return; + } + + /* Now work out the mapping */ + tex = 0; + for (i = 0; ffu_map; ffu_map >>= 1, ++i) + { + if (!(ffu_map & 1)) + continue; + + if (context->tex_unit_map[i] != tex) + { + context_map_stage(context, i, tex); + context_invalidate_state(context, STATE_SAMPLER(i)); + context_invalidate_texture_stage(context, i); + } + + ++tex; + } +} + +static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state) +{ + const enum wined3d_sampler_texture_type *sampler_type = + state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type; + unsigned int i; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + + for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + { + if (sampler_type[i] && context->tex_unit_map[i] != i) + { + context_map_stage(context, i, i); + context_invalidate_state(context, STATE_SAMPLER(i)); + if (i < d3d_info->limits.ffp_blend_stages) + context_invalidate_texture_stage(context, i); + } + } +} + +static BOOL context_unit_free_for_vs(const struct wined3d_context *context, + const enum wined3d_sampler_texture_type *pshader_sampler_tokens, + const enum wined3d_sampler_texture_type *vshader_sampler_tokens, DWORD unit) +{ + DWORD current_mapping = context->rev_tex_unit_map[unit]; + + /* Not currently used */ + if (current_mapping == WINED3D_UNMAPPED_STAGE) + return TRUE; + + if (current_mapping < MAX_FRAGMENT_SAMPLERS) + { + /* Used by a fragment sampler */ + + if (!pshader_sampler_tokens) + { + /* No pixel shader, check fixed function */ + return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1 << current_mapping)); + } + + /* Pixel shader, check the shader's sampler map */ + return !pshader_sampler_tokens[current_mapping]; + } + + /* Used by a vertex sampler */ + return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS]; +} + +static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state) +{ + const enum wined3d_sampler_texture_type *vshader_sampler_type = + state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.sampler_type; + const enum wined3d_sampler_texture_type *pshader_sampler_type = NULL; + const struct wined3d_gl_info *gl_info = context->gl_info; + int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1; + int i; + + if (ps) + { + /* Note that we only care if a sampler is sampled or not, not the sampler's specific type. + * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */ + pshader_sampler_type = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type; + } + + for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) { + DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS; + if (vshader_sampler_type[i]) + { + if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE) + { + /* Already mapped somewhere */ + continue; + } + + while (start >= 0) + { + if (context_unit_free_for_vs(context, pshader_sampler_type, vshader_sampler_type, start)) + { + context_map_stage(context, vsampler_idx, start); + context_invalidate_state(context, STATE_SAMPLER(vsampler_idx)); + + --start; + break; + } + + --start; + } + } + } +} + +static void context_update_tex_unit_map(struct wined3d_context *context, const struct wined3d_state *state) +{ + BOOL vs = use_vs(state); + BOOL ps = use_ps(state); + /* + * Rules are: + * -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but + * that would be really messy and require shader recompilation + * -> When the mapping of a stage is changed, sampler and ALL texture stage states have + * to be reset. Because of that try to work with a 1:1 mapping as much as possible + */ + if (ps) + context_map_psamplers(context, state); + else + context_map_fixed_function_samplers(context, state); + + if (vs) + context_map_vsamplers(context, ps, state); +} + /* Context activation is done by the caller. */ void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { @@ -2341,6 +2570,260 @@ void context_state_drawbuf(struct wined3d_context *context, const struct wined3d } } +static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum) +{ + if ((usage == WINED3D_DECL_USAGE_POSITION || usage == WINED3D_DECL_USAGE_POSITIONT) && !usage_idx) + *regnum = WINED3D_FFP_POSITION; + else if (usage == WINED3D_DECL_USAGE_BLEND_WEIGHT && !usage_idx) + *regnum = WINED3D_FFP_BLENDWEIGHT; + else if (usage == WINED3D_DECL_USAGE_BLEND_INDICES && !usage_idx) + *regnum = WINED3D_FFP_BLENDINDICES; + else if (usage == WINED3D_DECL_USAGE_NORMAL && !usage_idx) + *regnum = WINED3D_FFP_NORMAL; + else if (usage == WINED3D_DECL_USAGE_PSIZE && !usage_idx) + *regnum = WINED3D_FFP_PSIZE; + else if (usage == WINED3D_DECL_USAGE_COLOR && !usage_idx) + *regnum = WINED3D_FFP_DIFFUSE; + else if (usage == WINED3D_DECL_USAGE_COLOR && usage_idx == 1) + *regnum = WINED3D_FFP_SPECULAR; + else if (usage == WINED3D_DECL_USAGE_TEXCOORD && usage_idx < WINED3DDP_MAXTEXCOORD) + *regnum = WINED3D_FFP_TEXCOORD0 + usage_idx; + else + { + FIXME("Unsupported input stream [usage=%s, usage_idx=%u].\n", debug_d3ddeclusage(usage), usage_idx); + *regnum = ~0U; + return FALSE; + } + + return TRUE; +} + +/* FIXME: Separate buffer loading from declaration decoding */ +/* Context activation is done by the caller. */ +void context_stream_info_from_declaration(struct wined3d_context *context, + const struct wined3d_state *state, struct wined3d_stream_info *stream_info) +{ + /* We need to deal with frequency data! */ + struct wined3d_vertex_declaration *declaration = state->vertex_declaration; + BOOL use_vshader = use_vs(state); + unsigned int i; + WORD map; + + stream_info->use_map = 0; + stream_info->swizzle_map = 0; + stream_info->all_vbo = 1; + stream_info->position_transformed = declaration->position_transformed; + + /* Translate the declaration into strided data. */ + for (i = 0; i < declaration->element_count; ++i) + { + const struct wined3d_vertex_declaration_element *element = &declaration->elements[i]; + const struct wined3d_stream_state *stream = &state->streams[element->input_slot]; + struct wined3d_buffer *buffer = stream->buffer; + struct wined3d_bo_address data; + BOOL stride_used; + unsigned int idx; + DWORD stride; + + TRACE("%p Element %p (%u of %u).\n", declaration->elements, + element, i + 1, declaration->element_count); + + if (!buffer) continue; + + stride = stream->stride; + TRACE("Stream %u in buffer %p.\n", element->input_slot, buffer); + buffer_get_memory(buffer, context, &data); + + /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets + * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory + * sources. In most sane cases the pointer - offset will still be > 0, otherwise it will wrap + * around to some big value. Hope that with the indices, the driver wraps it back internally. If + * not, drawStridedSlow is needed, including a vertex buffer path. */ + if (state->load_base_vertex_index < 0) + { + WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n", + state->load_base_vertex_index); + data.buffer_object = 0; + data.addr = buffer_get_sysmem(buffer, context); + if ((UINT_PTR)data.addr < -state->load_base_vertex_index * stride) + { + FIXME("System memory vertex data load offset is negative!\n"); + } + } + data.addr += element->offset; + + TRACE("offset %u input_slot %u usage_idx %d.\n", element->offset, element->input_slot, element->usage_idx); + + if (use_vshader) + { + if (element->output_slot == ~0U) + { + /* TODO: Assuming vertexdeclarations are usually used with the + * same or a similar shader, it might be worth it to store the + * last used output slot and try that one first. */ + stride_used = vshader_get_input(state->shader[WINED3D_SHADER_TYPE_VERTEX], + element->usage, element->usage_idx, &idx); + } + else + { + idx = element->output_slot; + stride_used = TRUE; + } + } + else + { + if (!element->ffp_valid) + { + WARN("Skipping unsupported fixed function element of format %s and usage %s.\n", + debug_d3dformat(element->format->id), debug_d3ddeclusage(element->usage)); + stride_used = FALSE; + } + else + { + stride_used = fixed_get_input(element->usage, element->usage_idx, &idx); + } + } + + if (stride_used) + { + TRACE("Load %s array %u [usage %s, usage_idx %u, " + "input_slot %u, offset %u, stride %u, format %s, buffer_object %u].\n", + use_vshader ? "shader": "fixed function", idx, + debug_d3ddeclusage(element->usage), element->usage_idx, element->input_slot, + element->offset, stride, debug_d3dformat(element->format->id), data.buffer_object); + + data.addr += stream->offset; + + stream_info->elements[idx].format = element->format; + stream_info->elements[idx].data = data; + stream_info->elements[idx].stride = stride; + stream_info->elements[idx].stream_idx = element->input_slot; + + if (!context->gl_info->supported[ARB_VERTEX_ARRAY_BGRA] + && element->format->id == WINED3DFMT_B8G8R8A8_UNORM) + { + stream_info->swizzle_map |= 1 << idx; + } + stream_info->use_map |= 1 << idx; + } + } + + /* Preload the vertex buffers. */ + context->num_buffer_queries = 0; + for (i = 0, map = stream_info->use_map; map; map >>= 1, ++i) + { + struct wined3d_stream_info_element *element; + struct wined3d_buffer *buffer; + + if (!(map & 1)) + continue; + + element = &stream_info->elements[i]; + buffer = state->streams[element->stream_idx].buffer; + buffer_internal_preload(buffer, context, state); + + /* If the preload dropped the buffer object, update the stream info. */ + if (buffer->buffer_object != element->data.buffer_object) + { + element->data.buffer_object = 0; + element->data.addr = buffer_get_sysmem(buffer, context) + + (ptrdiff_t)element->data.addr; + } + + if (!buffer->buffer_object) + stream_info->all_vbo = 0; + + if (buffer->query) + context->buffer_queries[context->num_buffer_queries++] = buffer->query; + } +} + +/* Context activation is done by the caller. */ +static void context_update_stream_info(struct wined3d_context *context, const struct wined3d_state *state) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + struct wined3d_stream_info *stream_info = &context->stream_info; + DWORD prev_all_vbo = stream_info->all_vbo; + + TRACE("============================= Vertex Declaration =============================\n"); + context_stream_info_from_declaration(context, state, stream_info); + + if (use_vs(state)) + { + if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo) + { + TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n"); + context->use_immediate_mode_draw = TRUE; + } + else + { + context->use_immediate_mode_draw = FALSE; + } + } + else + { + WORD slow_mask = (1 << WINED3D_FFP_PSIZE); + slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] + & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR)); + + if (((stream_info->position_transformed && !d3d_info->xyzrhw) + || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo) + context->use_immediate_mode_draw = TRUE; + else + context->use_immediate_mode_draw = FALSE; + } + + if (prev_all_vbo != stream_info->all_vbo) + context_invalidate_state(context, STATE_INDEXBUFFER); +} + +/* Context activation is done by the caller. */ +static void context_preload_texture(struct wined3d_context *context, + const struct wined3d_state *state, unsigned int idx) +{ + struct wined3d_texture *texture; + + if (!(texture = state->textures[idx])) + return; + + wined3d_texture_load(texture, context, state->sampler_states[idx][WINED3D_SAMP_SRGB_TEXTURE]); +} + +/* Context activation is done by the caller. */ +static void context_preload_textures(struct wined3d_context *context, const struct wined3d_state *state) +{ + unsigned int i; + + if (use_vs(state)) + { + for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) + { + if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.sampler_type[i]) + context_preload_texture(context, state, MAX_FRAGMENT_SAMPLERS + i); + } + } + + if (use_ps(state)) + { + for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + { + if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type[i]) + context_preload_texture(context, state, i); + } + } + else + { + WORD ffu_map = context->fixed_function_usage_map; + + for (i = 0; ffu_map; ffu_map >>= 1, ++i) + { + if (ffu_map & 1) + context_preload_texture(context, state, i); + } + } +} + /* Context activation is done by the caller. */ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) { @@ -2361,16 +2844,16 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de /* Preload resources before FBO setup. Texture preload in particular may * result in changes to the current FBO, due to using e.g. FBO blits for * updating a resource location. */ - device_update_tex_unit_map(device); - device_preload_textures(device); + context_update_tex_unit_map(context, state); + context_preload_textures(context, state); if (isStateDirty(context, STATE_VDECL) || isStateDirty(context, STATE_STREAMSRC)) - device_update_stream_info(device, context->gl_info); + context_update_stream_info(context, state); if (state->index_buffer) { - if (device->stream_info.all_vbo) - wined3d_buffer_preload(state->index_buffer); + if (context->stream_info.all_vbo) + buffer_internal_preload(state->index_buffer, context, state); else - buffer_get_sysmem(state->index_buffer, context->gl_info); + buffer_get_sysmem(state->index_buffer, context); } for (i = 0; i < context->numDirtyEntries; ++i) @@ -2437,19 +2920,21 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d /* When switching away from an offscreen render target, and we're not * using FBOs, we have to read the drawable into the texture. This is - * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There - * are some things that need care though. PreLoad needs a GL context, + * done via PreLoad (and WINED3D_LOCATION_DRAWABLE set on the surface). + * There are some things that need care though. PreLoad needs a GL context, * and FindContext is called before the context is activated. It also * has to be called with the old rendertarget active, otherwise a * wrong drawable is read. */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO && old_render_offscreen && context->current_rt != target) { + struct wined3d_texture *texture = context->current_rt->container; + /* Read the back buffer of the old drawable into the destination texture. */ - if (context->current_rt->texture_name_srgb) - surface_internal_preload(context->current_rt, SRGB_SRGB); - surface_internal_preload(context->current_rt, SRGB_RGB); - surface_modify_location(context->current_rt, SFLAG_INDRAWABLE, FALSE); + if (texture->texture_srgb.name) + wined3d_texture_load(texture, context, TRUE); + wined3d_texture_load(texture, context, FALSE); + surface_invalidate_location(context->current_rt, WINED3D_LOCATION_DRAWABLE); } } @@ -2457,7 +2942,6 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d context_set_render_offscreen(context, render_offscreen); } -/* Do not call while under the GL lock. */ struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_surface *target) { struct wined3d_context *current_context = context_get_current(); diff --git a/reactos/dll/directx/wine/wined3d/cs.c b/reactos/dll/directx/wine/wined3d/cs.c new file mode 100644 index 00000000000..338a3e13971 --- /dev/null +++ b/reactos/dll/directx/wine/wined3d/cs.c @@ -0,0 +1,941 @@ +/* + * Copyright 2013 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); + +#define WINED3D_INITIAL_CS_SIZE 4096 + +enum wined3d_cs_op +{ + WINED3D_CS_OP_PRESENT, + WINED3D_CS_OP_CLEAR, + WINED3D_CS_OP_DRAW, + WINED3D_CS_OP_SET_VIEWPORT, + WINED3D_CS_OP_SET_SCISSOR_RECT, + WINED3D_CS_OP_SET_RENDER_TARGET, + WINED3D_CS_OP_SET_DEPTH_STENCIL, + WINED3D_CS_OP_SET_VERTEX_DECLARATION, + WINED3D_CS_OP_SET_STREAM_SOURCE, + WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ, + WINED3D_CS_OP_SET_STREAM_OUTPUT, + WINED3D_CS_OP_SET_INDEX_BUFFER, + WINED3D_CS_OP_SET_CONSTANT_BUFFER, + WINED3D_CS_OP_SET_TEXTURE, + WINED3D_CS_OP_SET_SAMPLER, + WINED3D_CS_OP_SET_SHADER, + WINED3D_CS_OP_SET_RENDER_STATE, + WINED3D_CS_OP_SET_TEXTURE_STATE, + WINED3D_CS_OP_SET_SAMPLER_STATE, + WINED3D_CS_OP_SET_TRANSFORM, + WINED3D_CS_OP_SET_CLIP_PLANE, + WINED3D_CS_OP_SET_MATERIAL, + WINED3D_CS_OP_RESET_STATE, +}; + +struct wined3d_cs_present +{ + enum wined3d_cs_op opcode; + HWND dst_window_override; + struct wined3d_swapchain *swapchain; + const RECT *src_rect; + const RECT *dst_rect; + const RGNDATA *dirty_region; + DWORD flags; +}; + +struct wined3d_cs_clear +{ + enum wined3d_cs_op opcode; + DWORD rect_count; + const RECT *rects; + DWORD flags; + const struct wined3d_color *color; + float depth; + DWORD stencil; +}; + +struct wined3d_cs_draw +{ + enum wined3d_cs_op opcode; + UINT start_idx; + UINT index_count; + UINT start_instance; + UINT instance_count; + BOOL indexed; +}; + +struct wined3d_cs_set_viewport +{ + enum wined3d_cs_op opcode; + const struct wined3d_viewport *viewport; +}; + +struct wined3d_cs_set_scissor_rect +{ + enum wined3d_cs_op opcode; + const RECT *rect; +}; + +struct wined3d_cs_set_render_target +{ + enum wined3d_cs_op opcode; + UINT render_target_idx; + struct wined3d_surface *render_target; +}; + +struct wined3d_cs_set_depth_stencil +{ + enum wined3d_cs_op opcode; + struct wined3d_surface *depth_stencil; +}; + +struct wined3d_cs_set_vertex_declaration +{ + enum wined3d_cs_op opcode; + struct wined3d_vertex_declaration *declaration; +}; + +struct wined3d_cs_set_stream_source +{ + enum wined3d_cs_op opcode; + UINT stream_idx; + struct wined3d_buffer *buffer; + UINT offset; + UINT stride; +}; + +struct wined3d_cs_set_stream_source_freq +{ + enum wined3d_cs_op opcode; + UINT stream_idx; + UINT frequency; + UINT flags; +}; + +struct wined3d_cs_set_stream_output +{ + enum wined3d_cs_op opcode; + UINT stream_idx; + struct wined3d_buffer *buffer; + UINT offset; +}; + +struct wined3d_cs_set_index_buffer +{ + enum wined3d_cs_op opcode; + struct wined3d_buffer *buffer; + enum wined3d_format_id format_id; +}; + +struct wined3d_cs_set_constant_buffer +{ + enum wined3d_cs_op opcode; + enum wined3d_shader_type type; + UINT cb_idx; + struct wined3d_buffer *buffer; +}; + +struct wined3d_cs_set_texture +{ + enum wined3d_cs_op opcode; + UINT stage; + struct wined3d_texture *texture; +}; + +struct wined3d_cs_set_sampler +{ + enum wined3d_cs_op opcode; + enum wined3d_shader_type type; + UINT sampler_idx; + struct wined3d_sampler *sampler; +}; + +struct wined3d_cs_set_shader +{ + enum wined3d_cs_op opcode; + enum wined3d_shader_type type; + struct wined3d_shader *shader; +}; + +struct wined3d_cs_set_render_state +{ + enum wined3d_cs_op opcode; + enum wined3d_render_state state; + DWORD value; +}; + +struct wined3d_cs_set_texture_state +{ + enum wined3d_cs_op opcode; + UINT stage; + enum wined3d_texture_stage_state state; + DWORD value; +}; + +struct wined3d_cs_set_sampler_state +{ + enum wined3d_cs_op opcode; + UINT sampler_idx; + enum wined3d_sampler_state state; + DWORD value; +}; + +struct wined3d_cs_set_transform +{ + enum wined3d_cs_op opcode; + enum wined3d_transform_state state; + const struct wined3d_matrix *matrix; +}; + +struct wined3d_cs_set_clip_plane +{ + enum wined3d_cs_op opcode; + UINT plane_idx; + const struct wined3d_vec4 *plane; +}; + +struct wined3d_cs_set_material +{ + enum wined3d_cs_op opcode; + const struct wined3d_material *material; +}; + +struct wined3d_cs_reset_state +{ + enum wined3d_cs_op opcode; +}; + +static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_present *op = data; + struct wined3d_swapchain *swapchain; + + swapchain = op->swapchain; + wined3d_swapchain_set_window(swapchain, op->dst_window_override); + + swapchain->swapchain_ops->swapchain_present(swapchain, + op->src_rect, op->dst_rect, op->dirty_region, op->flags); +} + +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, + const RGNDATA *dirty_region, DWORD flags) +{ + struct wined3d_cs_present *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_PRESENT; + op->dst_window_override = dst_window_override; + op->swapchain = swapchain; + op->src_rect = src_rect; + op->dst_rect = dst_rect; + op->dirty_region = dirty_region; + op->flags = flags; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_clear *op = data; + struct wined3d_device *device; + RECT draw_rect; + + device = cs->device; + wined3d_get_draw_rect(&device->state, &draw_rect); + device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, + &device->fb, op->rect_count, op->rects, &draw_rect, op->flags, + op->color, op->depth, op->stencil); +} + +void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, + DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) +{ + struct wined3d_cs_clear *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_CLEAR; + op->rect_count = rect_count; + op->rects = rects; + op->flags = flags; + op->color = color; + op->depth = depth; + op->stencil = stencil; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_draw *op = data; + + draw_primitive(cs->device, op->start_idx, op->index_count, + op->start_instance, op->instance_count, op->indexed); +} + +void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, + UINT start_instance, UINT instance_count, BOOL indexed) +{ + struct wined3d_cs_draw *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_DRAW; + op->start_idx = start_idx; + op->index_count = index_count; + op->start_instance = start_instance; + op->instance_count = instance_count; + op->indexed = indexed; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_viewport *op = data; + + cs->state.viewport = *op->viewport; + device_invalidate_state(cs->device, STATE_VIEWPORT); +} + +void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) +{ + struct wined3d_cs_set_viewport *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_VIEWPORT; + op->viewport = viewport; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_scissor_rect *op = data; + + cs->state.scissor_rect = *op->rect; + device_invalidate_state(cs->device, STATE_SCISSORRECT); +} + +void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) +{ + struct wined3d_cs_set_scissor_rect *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; + op->rect = rect; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_render_target(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_render_target *op = data; + + cs->state.fb->render_targets[op->render_target_idx] = op->render_target; + device_invalidate_state(cs->device, STATE_FRAMEBUFFER); +} + +void wined3d_cs_emit_set_render_target(struct wined3d_cs *cs, UINT render_target_idx, + struct wined3d_surface *render_target) +{ + struct wined3d_cs_set_render_target *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_RENDER_TARGET; + op->render_target_idx = render_target_idx; + op->render_target = render_target; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_depth_stencil(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_depth_stencil *op = data; + struct wined3d_device *device = cs->device; + struct wined3d_surface *prev; + + if ((prev = cs->state.fb->depth_stencil)) + { + if (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL + || prev->flags & SFLAG_DISCARD) + { + surface_modify_ds_location(prev, WINED3D_LOCATION_DISCARDED, + prev->resource.width, prev->resource.height); + if (prev == device->onscreen_depth_stencil) + { + wined3d_surface_decref(device->onscreen_depth_stencil); + device->onscreen_depth_stencil = NULL; + } + } + } + + cs->fb.depth_stencil = op->depth_stencil; + + if (!prev != !op->depth_stencil) + { + /* Swapping NULL / non NULL depth stencil affects the depth and tests */ + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); + 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)); + } + else if (prev && prev->resource.format->depth_size != op->depth_stencil->resource.format->depth_size) + { + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); + } + + device_invalidate_state(device, STATE_FRAMEBUFFER); +} + +void wined3d_cs_emit_set_depth_stencil(struct wined3d_cs *cs, struct wined3d_surface *depth_stencil) +{ + struct wined3d_cs_set_depth_stencil *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL; + op->depth_stencil = depth_stencil; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_vertex_declaration *op = data; + + cs->state.vertex_declaration = op->declaration; + device_invalidate_state(cs->device, STATE_VDECL); +} + +void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) +{ + struct wined3d_cs_set_vertex_declaration *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION; + op->declaration = declaration; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_stream_source *op = data; + struct wined3d_stream_state *stream; + struct wined3d_buffer *prev; + + stream = &cs->state.streams[op->stream_idx]; + prev = stream->buffer; + stream->buffer = op->buffer; + stream->offset = op->offset; + stream->stride = op->stride; + + if (op->buffer) + InterlockedIncrement(&op->buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); + + device_invalidate_state(cs->device, STATE_STREAMSRC); +} + +void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, + struct wined3d_buffer *buffer, UINT offset, UINT stride) +{ + struct wined3d_cs_set_stream_source *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; + op->stream_idx = stream_idx; + op->buffer = buffer; + op->offset = offset; + op->stride = stride; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_stream_source_freq *op = data; + struct wined3d_stream_state *stream; + + stream = &cs->state.streams[op->stream_idx]; + stream->frequency = op->frequency; + stream->flags = op->flags; + + device_invalidate_state(cs->device, STATE_STREAMSRC); +} + +void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags) +{ + struct wined3d_cs_set_stream_source_freq *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ; + op->stream_idx = stream_idx; + op->frequency = frequency; + op->flags = flags; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_stream_output *op = data; + struct wined3d_stream_output *stream; + struct wined3d_buffer *prev; + + stream = &cs->state.stream_output[op->stream_idx]; + prev = stream->buffer; + stream->buffer = op->buffer; + stream->offset = op->offset; + + if (op->buffer) + InterlockedIncrement(&op->buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); +} + +void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, + struct wined3d_buffer *buffer, UINT offset) +{ + struct wined3d_cs_set_stream_output *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; + op->stream_idx = stream_idx; + op->buffer = buffer; + op->offset = offset; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_index_buffer *op = data; + struct wined3d_buffer *prev; + + prev = cs->state.index_buffer; + cs->state.index_buffer = op->buffer; + cs->state.index_format = op->format_id; + + if (op->buffer) + InterlockedIncrement(&op->buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); + + device_invalidate_state(cs->device, STATE_INDEXBUFFER); +} + +void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, + enum wined3d_format_id format_id) +{ + struct wined3d_cs_set_index_buffer *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER; + op->buffer = buffer; + op->format_id = format_id; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_constant_buffer *op = data; + struct wined3d_buffer *prev; + + prev = cs->state.cb[op->type][op->cb_idx]; + cs->state.cb[op->type][op->cb_idx] = op->buffer; + + if (op->buffer) + InterlockedIncrement(&op->buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); +} + +void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, + UINT cb_idx, struct wined3d_buffer *buffer) +{ + struct wined3d_cs_set_constant_buffer *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER; + op->type = type; + op->cb_idx = cb_idx; + op->buffer = buffer; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; + const struct wined3d_cs_set_texture *op = data; + struct wined3d_texture *prev; + + prev = cs->state.textures[op->stage]; + cs->state.textures[op->stage] = op->texture; + + if (op->texture) + { + if (InterlockedIncrement(&op->texture->resource.bind_count) == 1) + op->texture->sampler = op->stage; + + if (!prev || op->texture->target != prev->target) + device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); + + if (!prev && op->stage < d3d_info->limits.ffp_blend_stages) + { + /* The source arguments for color and alpha ops have different + * meanings when a NULL texture is bound, so the COLOR_OP and + * ALPHA_OP have to be dirtified. */ + device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); + device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); + } + } + + if (prev) + { + if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage) + { + unsigned int i; + + /* Search for other stages the texture is bound to. Shouldn't + * happen if applications bind textures to a single stage only. */ + TRACE("Searching for other stages the texture is bound to.\n"); + for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) + { + if (cs->state.textures[i] == prev) + { + TRACE("Texture is also bound to stage %u.\n", i); + prev->sampler = i; + break; + } + } + } + + if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages) + { + device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); + device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); + } + } + + device_invalidate_state(cs->device, STATE_SAMPLER(op->stage)); +} + +void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) +{ + struct wined3d_cs_set_texture *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_TEXTURE; + op->stage = stage; + op->texture = texture; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_sampler *op = data; + + cs->state.sampler[op->type][op->sampler_idx] = op->sampler; +} + +void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type, + UINT sampler_idx, struct wined3d_sampler *sampler) +{ + struct wined3d_cs_set_sampler *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_SAMPLER; + op->type = type; + op->sampler_idx = sampler_idx; + op->sampler = sampler; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_shader *op = data; + + cs->state.shader[op->type] = op->shader; + device_invalidate_state(cs->device, STATE_SHADER(op->type)); +} + +void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) +{ + struct wined3d_cs_set_shader *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_SHADER; + op->type = type; + op->shader = shader; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_render_state *op = data; + + cs->state.render_states[op->state] = op->value; + device_invalidate_state(cs->device, STATE_RENDER(op->state)); +} + +void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) +{ + struct wined3d_cs_set_render_state *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_RENDER_STATE; + op->state = state; + op->value = value; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_texture_state *op = data; + + cs->state.texture_states[op->stage][op->state] = op->value; + device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state)); +} + +void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, + enum wined3d_texture_stage_state state, DWORD value) +{ + struct wined3d_cs_set_texture_state *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE; + op->stage = stage; + op->state = state; + op->value = value; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_sampler_state *op = data; + + cs->state.sampler_states[op->sampler_idx][op->state] = op->value; + device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx)); +} + +void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, + enum wined3d_sampler_state state, DWORD value) +{ + struct wined3d_cs_set_sampler_state *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE; + op->sampler_idx = sampler_idx; + op->state = state; + op->value = value; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_transform *op = data; + + cs->state.transforms[op->state] = *op->matrix; + if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->gl_info.limits.blends)) + device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); +} + +void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state, + const struct wined3d_matrix *matrix) +{ + struct wined3d_cs_set_transform *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_TRANSFORM; + op->state = state; + op->matrix = matrix; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_clip_plane *op = data; + + cs->state.clip_planes[op->plane_idx] = *op->plane; + device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx)); +} + +void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) +{ + struct wined3d_cs_set_clip_plane *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE; + op->plane_idx = plane_idx; + op->plane = plane; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_material *op = data; + + cs->state.material = *op->material; + device_invalidate_state(cs->device, STATE_MATERIAL); +} + +void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) +{ + struct wined3d_cs_set_material *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_MATERIAL; + op->material = material; + + cs->ops->submit(cs); +} + +static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) +{ + struct wined3d_adapter *adapter = cs->device->adapter; + HRESULT hr; + + state_cleanup(&cs->state); + memset(&cs->state, 0, sizeof(cs->state)); + if (FAILED(hr = state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info, + WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) + ERR("Failed to initialize CS state, hr %#x.\n", hr); +} + +void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) +{ + struct wined3d_cs_reset_state *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_RESET_STATE; + + cs->ops->submit(cs); +} + +static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = +{ + /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, + /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, + /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, + /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, + /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, + /* WINED3D_CS_OP_SET_RENDER_TARGET */ wined3d_cs_exec_set_render_target, + /* WINED3D_CS_OP_SET_DEPTH_STENCIL */ wined3d_cs_exec_set_depth_stencil, + /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, + /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, + /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, + /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, + /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, + /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, + /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, + /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, + /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, + /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, + /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, + /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, + /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, + /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, + /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, + /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, +}; + +static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +{ + if (size > cs->data_size) + { + void *new_data; + + size = max( size, cs->data_size * 2 ); + if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size))) + return NULL; + + cs->data_size = size; + cs->data = new_data; + } + + return cs->data; +} + +static void wined3d_cs_st_submit(struct wined3d_cs *cs) +{ + enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data; + + wined3d_cs_op_handlers[opcode](cs, cs->data); +} + +static const struct wined3d_cs_ops wined3d_cs_st_ops = +{ + wined3d_cs_st_require_space, + wined3d_cs_st_submit, +}; + +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)))) + return NULL; + + if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(*cs->fb.render_targets) * gl_info->limits.buffers))) + { + HeapFree(GetProcessHeap(), 0, cs); + return NULL; + } + + if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info, + WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) + { + HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); + HeapFree(GetProcessHeap(), 0, cs); + return NULL; + } + + cs->ops = &wined3d_cs_st_ops; + cs->device = device; + + cs->data_size = WINED3D_INITIAL_CS_SIZE; + if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) + { + HeapFree(GetProcessHeap(), 0, cs); + return NULL; + } + + return cs; +} + +void wined3d_cs_destroy(struct wined3d_cs *cs) +{ + state_cleanup(&cs->state); + HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); + HeapFree(GetProcessHeap(), 0, cs); +} diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index 84c4200dab4..7e60fe3b7ec 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -27,7 +27,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); -WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); /* Define the default light parameters as specified by MSDN. */ const struct wined3d_light WINED3D_default_light = @@ -127,258 +126,6 @@ static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_t } } -static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum) -{ - if ((usage == WINED3D_DECL_USAGE_POSITION || usage == WINED3D_DECL_USAGE_POSITIONT) && !usage_idx) - *regnum = WINED3D_FFP_POSITION; - else if (usage == WINED3D_DECL_USAGE_BLEND_WEIGHT && !usage_idx) - *regnum = WINED3D_FFP_BLENDWEIGHT; - else if (usage == WINED3D_DECL_USAGE_BLEND_INDICES && !usage_idx) - *regnum = WINED3D_FFP_BLENDINDICES; - else if (usage == WINED3D_DECL_USAGE_NORMAL && !usage_idx) - *regnum = WINED3D_FFP_NORMAL; - else if (usage == WINED3D_DECL_USAGE_PSIZE && !usage_idx) - *regnum = WINED3D_FFP_PSIZE; - else if (usage == WINED3D_DECL_USAGE_COLOR && !usage_idx) - *regnum = WINED3D_FFP_DIFFUSE; - else if (usage == WINED3D_DECL_USAGE_COLOR && usage_idx == 1) - *regnum = WINED3D_FFP_SPECULAR; - else if (usage == WINED3D_DECL_USAGE_TEXCOORD && usage_idx < WINED3DDP_MAXTEXCOORD) - *regnum = WINED3D_FFP_TEXCOORD0 + usage_idx; - else - { - FIXME("Unsupported input stream [usage=%s, usage_idx=%u]\n", debug_d3ddeclusage(usage), usage_idx); - *regnum = ~0U; - return FALSE; - } - - return TRUE; -} - -/* Context activation is done by the caller. */ -static void device_stream_info_from_declaration(struct wined3d_device *device, struct wined3d_stream_info *stream_info) -{ - const struct wined3d_state *state = &device->state; - /* We need to deal with frequency data! */ - struct wined3d_vertex_declaration *declaration = state->vertex_declaration; - BOOL use_vshader; - unsigned int i; - WORD map; - - stream_info->use_map = 0; - stream_info->swizzle_map = 0; - stream_info->all_vbo = 1; - - /* Check for transformed vertices, disable vertex shader if present. */ - stream_info->position_transformed = declaration->position_transformed; - use_vshader = state->vertex_shader && !declaration->position_transformed; - - /* Translate the declaration into strided data. */ - for (i = 0; i < declaration->element_count; ++i) - { - const struct wined3d_vertex_declaration_element *element = &declaration->elements[i]; - const struct wined3d_stream_state *stream = &state->streams[element->input_slot]; - struct wined3d_buffer *buffer = stream->buffer; - struct wined3d_bo_address data; - BOOL stride_used; - unsigned int idx; - DWORD stride; - - TRACE("%p Element %p (%u of %u)\n", declaration->elements, - element, i + 1, declaration->element_count); - - if (!buffer) continue; - - stride = stream->stride; - - TRACE("Stream %u, buffer %p.\n", element->input_slot, buffer); - buffer_get_memory(buffer, &device->adapter->gl_info, &data); - - /* We can't use VBOs if the base vertex index is negative. OpenGL - * doesn't accept negative offsets (or rather offsets bigger than the - * VBO, because the pointer is unsigned), so use system memory - * sources. In most sane cases the pointer - offset will still be > 0, - * otherwise it will wrap around to some big value. Hope that with the - * indices, the driver wraps it back internally. If not, - * drawStridedSlow() is needed, including a vertex buffer path. */ - if (state->load_base_vertex_index < 0) - { - WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n", state->load_base_vertex_index); - data.buffer_object = 0; - data.addr = buffer_get_sysmem(buffer, &device->adapter->gl_info); - if ((UINT_PTR)data.addr < -state->load_base_vertex_index * stride) - FIXME("System memory vertex data load offset is negative!\n"); - } - data.addr += element->offset; - - TRACE("offset %u input_slot %u usage_idx %d\n", element->offset, element->input_slot, element->usage_idx); - - if (use_vshader) - { - if (element->output_slot == ~0U) - { - /* TODO: Assuming vertexdeclarations are usually used with the - * same or a similar shader, it might be worth it to store the - * last used output slot and try that one first. */ - stride_used = vshader_get_input(state->vertex_shader, - element->usage, element->usage_idx, &idx); - } - else - { - idx = element->output_slot; - stride_used = TRUE; - } - } - else - { - if (!element->ffp_valid) - { - WARN("Skipping unsupported fixed function element of format %s and usage %s\n", - debug_d3dformat(element->format->id), debug_d3ddeclusage(element->usage)); - stride_used = FALSE; - } - else - { - stride_used = fixed_get_input(element->usage, element->usage_idx, &idx); - } - } - - if (stride_used) - { - TRACE("Load %s array %u [usage %s, usage_idx %u, " - "input_slot %u, offset %u, stride %u, format %s, buffer_object %u]\n", - use_vshader ? "shader": "fixed function", idx, - debug_d3ddeclusage(element->usage), element->usage_idx, element->input_slot, - element->offset, stride, debug_d3dformat(element->format->id), data.buffer_object); - - data.addr += stream->offset; - - stream_info->elements[idx].format = element->format; - stream_info->elements[idx].data = data; - stream_info->elements[idx].stride = stride; - stream_info->elements[idx].stream_idx = element->input_slot; - - if (!device->adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA] - && element->format->id == WINED3DFMT_B8G8R8A8_UNORM) - { - stream_info->swizzle_map |= 1 << idx; - } - stream_info->use_map |= 1 << idx; - } - } - - /* Preload the vertex buffers. */ - device->num_buffer_queries = 0; - for (i = 0, map = stream_info->use_map; map; map >>= 1, ++i) - { - struct wined3d_stream_info_element *element; - struct wined3d_buffer *buffer; - - if (!(map & 1)) - continue; - - element = &stream_info->elements[i]; - buffer = state->streams[element->stream_idx].buffer; - wined3d_buffer_preload(buffer); - - /* If the preload dropped the buffer object, update the stream info. */ - if (buffer->buffer_object != element->data.buffer_object) - { - element->data.buffer_object = 0; - element->data.addr = buffer_get_sysmem(buffer, &device->adapter->gl_info) + (ptrdiff_t)element->data.addr; - } - - if (!buffer->buffer_object) - stream_info->all_vbo = 0; - - if (buffer->query) - device->buffer_queries[device->num_buffer_queries++] = buffer->query; - } -} - -/* Context activation is done by the caller. */ -void device_update_stream_info(struct wined3d_device *device, const struct wined3d_gl_info *gl_info) -{ - struct wined3d_stream_info *stream_info = &device->stream_info; - const struct wined3d_state *state = &device->state; - DWORD prev_all_vbo = stream_info->all_vbo; - - TRACE("============================= Vertex Declaration =============================\n"); - device_stream_info_from_declaration(device, stream_info); - - if (state->vertex_shader && !stream_info->position_transformed) - { - if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo) - { - TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n"); - device->useDrawStridedSlow = TRUE; - } - else - { - device->useDrawStridedSlow = FALSE; - } - } - else - { - WORD slow_mask = (1 << WINED3D_FFP_PSIZE); - slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] - & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR)); - - if (((stream_info->position_transformed && !device->adapter->d3d_info.xyzrhw) - || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo) - device->useDrawStridedSlow = TRUE; - else - device->useDrawStridedSlow = FALSE; - } - - if (prev_all_vbo != stream_info->all_vbo) - device_invalidate_state(device, STATE_INDEXBUFFER); -} - -static void device_preload_texture(const struct wined3d_state *state, unsigned int idx) -{ - struct wined3d_texture *texture; - enum WINED3DSRGB srgb; - - if (!(texture = state->textures[idx])) return; - srgb = state->sampler_states[idx][WINED3D_SAMP_SRGB_TEXTURE] ? SRGB_SRGB : SRGB_RGB; - texture->texture_ops->texture_preload(texture, srgb); -} - -void device_preload_textures(const struct wined3d_device *device) -{ - const struct wined3d_state *state = &device->state; - unsigned int i; - - if (use_vs(state)) - { - for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) - { - if (state->vertex_shader->reg_maps.sampler_type[i]) - device_preload_texture(state, MAX_FRAGMENT_SAMPLERS + i); - } - } - - if (use_ps(state)) - { - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) - { - if (state->pixel_shader->reg_maps.sampler_type[i]) - device_preload_texture(state, i); - } - } - else - { - WORD ffu_map = device->fixed_function_usage_map; - - for (i = 0; ffu_map; ffu_map >>= 1, ++i) - { - if (ffu_map & 1) - device_preload_texture(state, i); - } - } -} - BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *context) { struct wined3d_context **new_array; @@ -441,15 +188,14 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context device->contexts = new_array; } -/* Do not call while under the GL lock. */ void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context, struct wined3d_surface *depth_stencil) { if (device->onscreen_depth_stencil) { - surface_load_ds_location(device->onscreen_depth_stencil, context, SFLAG_INTEXTURE); + surface_load_ds_location(device->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); - surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_INTEXTURE, + surface_modify_ds_location(device->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, device->onscreen_depth_stencil->ds_current_size.cx, device->onscreen_depth_stencil->ds_current_size.cy); wined3d_surface_decref(device->onscreen_depth_stencil); @@ -480,7 +226,7 @@ static void prepare_ds_clear(struct wined3d_surface *ds, struct wined3d_context { RECT current_rect, r; - if (ds->flags & SFLAG_DISCARDED) + if (ds->locations & WINED3D_LOCATION_DISCARDED) { /* Depth buffer was discarded, make it entirely current in its new location since * there is no other place where we would get data anyway. */ @@ -488,7 +234,7 @@ static void prepare_ds_clear(struct wined3d_surface *ds, struct wined3d_context return; } - if (ds->flags & location) + if (ds->locations & location) SetRect(¤t_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); @@ -528,7 +274,6 @@ static void prepare_ds_clear(struct wined3d_surface *ds, struct wined3d_context SetRect(out_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); } -/* Do not call while under the GL lock. */ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb, UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) @@ -557,7 +302,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c { struct wined3d_surface *rt = fb->render_targets[i]; if (rt) - surface_load_location(rt, rt->draw_binding, NULL); + surface_load_location(rt, rt->draw_binding); } } @@ -584,7 +329,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c if (flags & WINED3DCLEAR_ZBUFFER) { - DWORD location = render_offscreen ? fb->depth_stencil->draw_binding : SFLAG_INDRAWABLE; + DWORD location = render_offscreen ? fb->depth_stencil->draw_binding : WINED3D_LOCATION_DRAWABLE; if (!render_offscreen && fb->depth_stencil != device->onscreen_depth_stencil) device_switch_onscreen_ds(device, context, fb->depth_stencil); @@ -616,7 +361,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c if (flags & WINED3DCLEAR_ZBUFFER) { - DWORD location = render_offscreen ? fb->depth_stencil->draw_binding : SFLAG_INDRAWABLE; + DWORD location = render_offscreen ? fb->depth_stencil->draw_binding : WINED3D_LOCATION_DRAWABLE; surface_modify_ds_location(fb->depth_stencil, location, ds_rect.right, ds_rect.bottom); @@ -634,7 +379,10 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c struct wined3d_surface *rt = fb->render_targets[i]; if (rt) - surface_modify_location(rt, rt->draw_binding, TRUE); + { + surface_validate_location(rt, rt->draw_binding); + surface_invalidate_location(rt, ~rt->draw_binding); + } } gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -729,6 +477,8 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device) { UINT i; + wined3d_cs_destroy(device->cs); + if (device->recording && wined3d_stateblock_decref(device->recording)) FIXME("Something's still holding the recording stateblock.\n"); device->recording = NULL; @@ -793,6 +543,8 @@ struct wined3d_swapchain * CDECL wined3d_device_get_swapchain(const struct wined static void device_load_logo(struct wined3d_device *device, const char *filename) { struct wined3d_color_key color_key; + struct wined3d_resource_desc desc; + struct wined3d_surface *surface; HBITMAP hbm; BITMAP bm; HRESULT hr; @@ -816,31 +568,40 @@ static void device_load_logo(struct wined3d_device *device, const char *filename bm.bmHeight = 32; } - hr = wined3d_surface_create(device, bm.bmWidth, bm.bmHeight, WINED3DFMT_B5G6R5_UNORM, 0, - WINED3D_POOL_SYSTEM_MEM, WINED3D_MULTISAMPLE_NONE, 0, WINED3D_SURFACE_MAPPABLE, - NULL, &wined3d_null_parent_ops, &device->logo_surface); - if (FAILED(hr)) + desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.format = WINED3DFMT_B5G6R5_UNORM; + desc.multisample_type = WINED3D_MULTISAMPLE_NONE; + desc.multisample_quality = 0; + desc.usage = WINED3DUSAGE_DYNAMIC; + desc.pool = WINED3D_POOL_DEFAULT; + desc.width = bm.bmWidth; + desc.height = bm.bmHeight; + desc.depth = 1; + desc.size = 0; + if (FAILED(hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE, + NULL, &wined3d_null_parent_ops, &device->logo_texture))) { - ERR("Wine logo requested, but failed to create surface, hr %#x.\n", hr); + ERR("Wine logo requested, but failed to create texture, hr %#x.\n", hr); goto out; } + surface = surface_from_resource(wined3d_texture_get_sub_resource(device->logo_texture, 0)); if (dcb) { - if (FAILED(hr = wined3d_surface_getdc(device->logo_surface, &dcs))) + if (FAILED(hr = wined3d_surface_getdc(surface, &dcs))) goto out; BitBlt(dcs, 0, 0, bm.bmWidth, bm.bmHeight, dcb, 0, 0, SRCCOPY); - wined3d_surface_releasedc(device->logo_surface, dcs); + wined3d_surface_releasedc(surface, dcs); color_key.color_space_low_value = 0; color_key.color_space_high_value = 0; - wined3d_surface_set_color_key(device->logo_surface, WINEDDCKEY_SRCBLT, &color_key); + wined3d_texture_set_color_key(device->logo_texture, WINEDDCKEY_SRCBLT, &color_key); } else { const struct wined3d_color c = {1.0f, 1.0f, 1.0f, 1.0f}; /* Fill the surface with a white color to show that wined3d is there */ - wined3d_device_color_fill(device, device->logo_surface, NULL, &c); + wined3d_device_color_fill(device, surface, NULL, &c); } out: @@ -1071,6 +832,25 @@ void CDECL wined3d_device_release_focus_window(struct wined3d_device *device) InterlockedExchangePointer((void **)&device->focus_window, NULL); } +static void device_init_swapchain_state(struct wined3d_device *device, struct wined3d_swapchain *swapchain) +{ + 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) + { + wined3d_device_set_render_target(device, i, NULL, FALSE); + } + if (swapchain->back_buffers && swapchain->back_buffers[0]) + wined3d_device_set_render_target(device, 0, swapchain->back_buffers[0], TRUE); + } + + wined3d_device_set_depth_stencil(device, ds_enable ? device->auto_depth_stencil : NULL); + wined3d_device_set_render_state(device, WINED3D_RS_ZENABLE, ds_enable); +} + HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc) { @@ -1078,8 +858,8 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_swapchain *swapchain = NULL; struct wined3d_context *context; + DWORD clear_flags = 0; HRESULT hr; - DWORD state; TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc); @@ -1091,21 +871,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*device->fb.render_targets) * gl_info->limits.buffers); - /* Initialize the texture unit mapping to a 1:1 mapping */ - for (state = 0; state < MAX_COMBINED_SAMPLERS; ++state) - { - if (state < gl_info->limits.fragment_samplers) - { - device->texUnitMap[state] = state; - device->rev_tex_unit_map[state] = state; - } - else - { - device->texUnitMap[state] = WINED3D_UNMAPPED_STAGE; - device->rev_tex_unit_map[state] = WINED3D_UNMAPPED_STAGE; - } - } - if (FAILED(hr = device->shader_backend->shader_alloc_private(device, device->adapter->vertex_pipe, device->adapter->fragment_pipe))) { @@ -1136,28 +901,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, goto err_out; } device->swapchains[0] = swapchain; - - if (swapchain->back_buffers && swapchain->back_buffers[0]) - { - TRACE("Setting rendertarget to %p.\n", swapchain->back_buffers); - device->fb.render_targets[0] = swapchain->back_buffers[0]; - } - else - { - TRACE("Setting rendertarget to %p.\n", swapchain->front_buffer); - device->fb.render_targets[0] = swapchain->front_buffer; - } - wined3d_surface_incref(device->fb.render_targets[0]); - - /* Depth Stencil support */ - device->fb.depth_stencil = device->auto_depth_stencil; - if (device->fb.depth_stencil) - wined3d_surface_incref(device->fb.depth_stencil); - - /* Set up some starting GL setup */ - - /* Setup all the devices defaults */ - state_init_default(&device->state, device); + device_init_swapchain_state(device, swapchain); context = context_acquire(device, swapchain->front_buffer); @@ -1191,9 +935,12 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, context_release(context); /* Clear the screen */ - wined3d_device_clear(device, 0, NULL, WINED3DCLEAR_TARGET - | (swapchain_desc->enable_auto_depth_stencil ? WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL : 0), - &black, 1.0f, 0); + if (swapchain->back_buffers && swapchain->back_buffers[0]) + clear_flags |= WINED3DCLEAR_TARGET; + if (swapchain_desc->enable_auto_depth_stencil) + clear_flags |= WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL; + if (clear_flags) + wined3d_device_clear(device, 0, NULL, clear_flags, &black, 1.0f, 0); device->d3d_initialized = TRUE; @@ -1270,8 +1017,10 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) context = context_acquire(device, NULL); gl_info = context->gl_info; - if (device->logo_surface) - wined3d_surface_decref(device->logo_surface); + if (device->logo_texture) + wined3d_texture_decref(device->logo_texture); + if (device->cursor_texture) + wined3d_texture_decref(device->cursor_texture); state_unbind_resources(&device->state); @@ -1283,13 +1032,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) resource->resource_ops->resource_unload(resource); } - /* Delete the mouse cursor texture */ - if (device->cursorTexture) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->cursorTexture); - device->cursorTexture = 0; - } - /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader * private data, it might contain opengl pointers */ @@ -1330,17 +1072,11 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) FIXME("Something's still holding the auto depth stencil buffer (%p).\n", surface); } - for (i = 1; i < gl_info->limits.buffers; ++i) + for (i = 0; i < gl_info->limits.buffers; ++i) { wined3d_device_set_render_target(device, i, NULL, FALSE); } - surface = device->fb.render_targets[0]; - TRACE("Setting rendertarget 0 to NULL\n"); - device->fb.render_targets[0] = NULL; - TRACE("Releasing the render target at %p\n", surface); - wined3d_surface_decref(surface); - context_release(context); for (i = 0; i < device->swapchain_count; ++i) @@ -1407,6 +1143,7 @@ UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer, UINT offset) { + struct wined3d_stream_output *stream; struct wined3d_buffer *prev_buffer; TRACE("device %p, idx %u, buffer %p, offset %u.\n", device, idx, buffer, offset); @@ -1417,32 +1154,17 @@ void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT return; } - prev_buffer = device->update_state->stream_output[idx].buffer; - device->update_state->stream_output[idx].buffer = buffer; - device->update_state->stream_output[idx].offset = offset; + stream = &device->update_state->stream_output[idx]; + prev_buffer = stream->buffer; - if (device->recording) - { - if (buffer) - wined3d_buffer_incref(buffer); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); - return; - } - - if (prev_buffer != buffer) - { - if (buffer) - { - InterlockedIncrement(&buffer->resource.bind_count); - wined3d_buffer_incref(buffer); - } - if (prev_buffer) - { - InterlockedDecrement(&prev_buffer->resource.bind_count); - wined3d_buffer_decref(prev_buffer); - } - } + if (buffer) + wined3d_buffer_incref(buffer); + stream->buffer = buffer; + stream->offset = offset; + if (!device->recording) + wined3d_cs_emit_set_stream_output(device->cs, idx, buffer, offset); + if (prev_buffer) + wined3d_buffer_decref(prev_buffer); } struct wined3d_buffer * CDECL wined3d_device_get_stream_output(struct wined3d_device *device, @@ -1501,29 +1223,12 @@ HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UI stream->offset = offset; } - /* Handle recording of state blocks. */ - if (device->recording) - { - TRACE("Recording... not performing anything.\n"); - if (buffer) - wined3d_buffer_incref(buffer); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); - return WINED3D_OK; - } - if (buffer) - { - InterlockedIncrement(&buffer->resource.bind_count); wined3d_buffer_incref(buffer); - } + if (!device->recording) + wined3d_cs_emit_set_stream_source(device->cs, stream_idx, buffer, offset, stride); if (prev_buffer) - { - InterlockedDecrement(&prev_buffer->resource.bind_count); wined3d_buffer_decref(prev_buffer); - } - - device_invalidate_state(device, STATE_STREAMSRC); return WINED3D_OK; } @@ -1587,7 +1292,7 @@ HRESULT CDECL wined3d_device_set_stream_source_freq(struct wined3d_device *devic if (device->recording) device->recording->changed.streamFreq |= 1 << stream_idx; else if (stream->frequency != old_freq || stream->flags != old_flags) - device_invalidate_state(device, STATE_STREAMSRC); + wined3d_cs_emit_set_stream_source_freq(device->cs, stream_idx, stream->frequency, stream->flags); return WINED3D_OK; } @@ -1639,9 +1344,7 @@ void CDECL wined3d_device_set_transform(struct wined3d_device *device, } device->state.transforms[d3dts] = *matrix; - - if (d3dts < WINED3D_TS_WORLD_MATRIX(device->adapter->gl_info.limits.blends)) - device_invalidate_state(device, STATE_TRANSFORM(d3dts)); + wined3d_cs_emit_set_transform(device->cs, d3dts, matrix); } void CDECL wined3d_device_get_transform(const struct wined3d_device *device, @@ -2015,14 +1718,8 @@ HRESULT CDECL wined3d_device_set_clip_plane(struct wined3d_device *device, device->update_state->clip_planes[plane_idx] = *plane; - /* Handle recording of state blocks. */ - if (device->recording) - { - TRACE("Recording... not performing anything.\n"); - return WINED3D_OK; - } - - device_invalidate_state(device, STATE_CLIPPLANE(plane_idx)); + if (!device->recording) + wined3d_cs_emit_set_clip_plane(device->cs, plane_idx, plane); return WINED3D_OK; } @@ -2072,15 +1769,10 @@ void CDECL wined3d_device_set_material(struct wined3d_device *device, const stru device->update_state->material = *material; - /* Handle recording of state blocks */ if (device->recording) - { device->recording->changed.material = TRUE; - TRACE("Recording... not performing anything.\n"); - return; - } - - device_invalidate_state(device, STATE_MATERIAL); + else + wined3d_cs_emit_set_material(device->cs, material); } void CDECL wined3d_device_get_material(const struct wined3d_device *device, struct wined3d_material *material) @@ -2107,42 +1799,30 @@ void CDECL wined3d_device_get_material(const struct wined3d_device *device, stru void CDECL wined3d_device_set_index_buffer(struct wined3d_device *device, struct wined3d_buffer *buffer, enum wined3d_format_id format_id) { + enum wined3d_format_id prev_format; struct wined3d_buffer *prev_buffer; TRACE("device %p, buffer %p, format %s.\n", device, buffer, debug_d3dformat(format_id)); prev_buffer = device->update_state->index_buffer; + prev_format = device->update_state->index_format; device->update_state->index_buffer = buffer; device->update_state->index_format = format_id; - /* Handle recording of state blocks. */ if (device->recording) - { - TRACE("Recording... not performing anything.\n"); device->recording->changed.indices = TRUE; - if (buffer) - wined3d_buffer_incref(buffer); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); - return; - } - if (prev_buffer != buffer) - { - device_invalidate_state(device, STATE_INDEXBUFFER); - if (buffer) - { - InterlockedIncrement(&buffer->resource.bind_count); - wined3d_buffer_incref(buffer); - } - if (prev_buffer) - { - InterlockedDecrement(&prev_buffer->resource.bind_count); - wined3d_buffer_decref(prev_buffer); - } - } + if (prev_buffer == buffer && prev_format == format_id) + return; + + if (buffer) + wined3d_buffer_incref(buffer); + if (!device->recording) + wined3d_cs_emit_set_index_buffer(device->cs, buffer, format_id); + if (prev_buffer) + wined3d_buffer_decref(prev_buffer); } struct wined3d_buffer * CDECL wined3d_device_get_index_buffer(const struct wined3d_device *device, @@ -2184,7 +1864,7 @@ void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const stru return; } - device_invalidate_state(device, STATE_VIEWPORT); + wined3d_cs_emit_set_viewport(device->cs, viewport); } void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport) @@ -2231,7 +1911,7 @@ void CDECL wined3d_device_set_render_state(struct wined3d_device *device, if (value == old_value) TRACE("Application is setting the old value over, nothing to do.\n"); else - device_invalidate_state(device, STATE_RENDER(state)); + wined3d_cs_emit_set_render_state(device->cs, state, value); if (state == WINED3D_RS_POINTSIZE && value == WINED3D_RESZ_CODE) { @@ -2281,7 +1961,7 @@ void CDECL wined3d_device_set_sampler_state(struct wined3d_device *device, return; } - device_invalidate_state(device, STATE_SAMPLER(sampler_idx)); + wined3d_cs_emit_set_sampler_state(device->cs, sampler_idx, state, value); } DWORD CDECL wined3d_device_get_sampler_state(const struct wined3d_device *device, @@ -2322,7 +2002,7 @@ void CDECL wined3d_device_set_scissor_rect(struct wined3d_device *device, const return; } - device_invalidate_state(device, STATE_SCISSORRECT); + wined3d_cs_emit_set_scissor_rect(device->cs, rect); } void CDECL wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect) @@ -2340,28 +2020,19 @@ void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device, TRACE("device %p, declaration %p.\n", device, declaration); - if (declaration) - wined3d_vertex_declaration_incref(declaration); - if (prev) - wined3d_vertex_declaration_decref(prev); - - device->update_state->vertex_declaration = declaration; - if (device->recording) - { - TRACE("Recording... not performing anything.\n"); device->recording->changed.vertexDecl = TRUE; - return; - } if (declaration == prev) - { - /* Checked after the assignment to allow proper stateblock recording. */ - TRACE("Application is setting the old declaration over, nothing to do.\n"); return; - } - device_invalidate_state(device, STATE_VDECL); + if (declaration) + wined3d_vertex_declaration_incref(declaration); + device->update_state->vertex_declaration = declaration; + if (!device->recording) + wined3d_cs_emit_set_vertex_declaration(device->cs, declaration); + if (prev) + wined3d_vertex_declaration_decref(prev); } struct wined3d_vertex_declaration * CDECL wined3d_device_get_vertex_declaration(const struct wined3d_device *device) @@ -2373,77 +2044,61 @@ struct wined3d_vertex_declaration * CDECL wined3d_device_get_vertex_declaration( void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_shader *prev = device->update_state->vertex_shader; + struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_VERTEX]; TRACE("device %p, shader %p.\n", device, shader); - if (shader) - wined3d_shader_incref(shader); - if (prev) - wined3d_shader_decref(prev); - - device->update_state->vertex_shader = shader; - if (device->recording) - { - TRACE("Recording... not performing anything.\n"); device->recording->changed.vertexShader = TRUE; - return; - } if (shader == prev) - { - TRACE("Application is setting the old shader over, nothing to do.\n"); return; - } - device_invalidate_state(device, STATE_VSHADER); + if (shader) + wined3d_shader_incref(shader); + device->update_state->shader[WINED3D_SHADER_TYPE_VERTEX] = shader; + if (!device->recording) + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_VERTEX, shader); + if (prev) + wined3d_shader_decref(prev); } struct wined3d_shader * CDECL wined3d_device_get_vertex_shader(const struct wined3d_device *device) { TRACE("device %p.\n", device); - return device->state.vertex_shader; + return device->state.shader[WINED3D_SHADER_TYPE_VERTEX]; } -void CDECL wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer) +static void wined3d_device_set_constant_buffer(struct wined3d_device *device, + enum wined3d_shader_type type, UINT idx, struct wined3d_buffer *buffer) { struct wined3d_buffer *prev; - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - if (idx >= MAX_CONSTANT_BUFFERS) { WARN("Invalid constant buffer index %u.\n", idx); return; } - prev = device->update_state->vs_cb[idx]; - device->update_state->vs_cb[idx] = buffer; - - if (device->recording) - { - if (buffer) - wined3d_buffer_incref(buffer); - if (prev) - wined3d_buffer_decref(prev); + prev = device->update_state->cb[type][idx]; + if (buffer == prev) return; - } - if (prev != buffer) - { - if (buffer) - { - InterlockedIncrement(&buffer->resource.bind_count); - wined3d_buffer_incref(buffer); - } - if (prev) - { - InterlockedDecrement(&prev->resource.bind_count); - wined3d_buffer_decref(prev); - } - } + if (buffer) + wined3d_buffer_incref(buffer); + device->update_state->cb[type][idx] = buffer; + if (!device->recording) + wined3d_cs_emit_set_constant_buffer(device->cs, type, idx, buffer); + if (prev) + wined3d_buffer_decref(prev); +} + +void CDECL wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer) +{ + TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); + + wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_VERTEX, idx, buffer); } struct wined3d_buffer * CDECL wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx) @@ -2456,30 +2111,40 @@ struct wined3d_buffer * CDECL wined3d_device_get_vs_cb(const struct wined3d_devi return NULL; } - return device->state.vs_cb[idx]; + return device->state.cb[WINED3D_SHADER_TYPE_VERTEX][idx]; } -void CDECL wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler) +static void wined3d_device_set_sampler(struct wined3d_device *device, + enum wined3d_shader_type type, UINT idx, struct wined3d_sampler *sampler) { struct wined3d_sampler *prev; - TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); - if (idx >= MAX_SAMPLER_OBJECTS) { WARN("Invalid sampler index %u.\n", idx); return; } - prev = device->update_state->vs_sampler[idx]; - device->update_state->vs_sampler[idx] = sampler; + prev = device->update_state->sampler[type][idx]; + if (sampler == prev) + return; if (sampler) wined3d_sampler_incref(sampler); + device->update_state->sampler[type][idx] = sampler; + if (!device->recording) + wined3d_cs_emit_set_sampler(device->cs, type, idx, sampler); if (prev) wined3d_sampler_decref(prev); } +void CDECL wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler) +{ + TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); + + wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_VERTEX, idx, sampler); +} + struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx) { TRACE("device %p, idx %u.\n", device, idx); @@ -2490,10 +2155,10 @@ struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3 return NULL; } - return device->state.vs_sampler[idx]; + return device->state.sampler[WINED3D_SHADER_TYPE_VERTEX][idx]; } -void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) +static void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) { UINT i; @@ -2647,290 +2312,39 @@ HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device return WINED3D_OK; } -static void device_invalidate_texture_stage(const struct wined3d_device *device, DWORD stage) -{ - DWORD i; - - for (i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i) - { - device_invalidate_state(device, STATE_TEXTURESTAGE(stage, i)); - } -} - -static void device_map_stage(struct wined3d_device *device, DWORD stage, DWORD unit) -{ - DWORD i = device->rev_tex_unit_map[unit]; - DWORD j = device->texUnitMap[stage]; - - device->texUnitMap[stage] = unit; - if (i != WINED3D_UNMAPPED_STAGE && i != stage) - device->texUnitMap[i] = WINED3D_UNMAPPED_STAGE; - - device->rev_tex_unit_map[unit] = stage; - if (j != WINED3D_UNMAPPED_STAGE && j != unit) - device->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE; -} - -static void device_update_fixed_function_usage_map(struct wined3d_device *device) -{ - UINT i; - - device->fixed_function_usage_map = 0; - for (i = 0; i < MAX_TEXTURES; ++i) - { - const struct wined3d_state *state = &device->state; - enum wined3d_texture_op color_op = state->texture_states[i][WINED3D_TSS_COLOR_OP]; - enum wined3d_texture_op alpha_op = state->texture_states[i][WINED3D_TSS_ALPHA_OP]; - DWORD color_arg1 = state->texture_states[i][WINED3D_TSS_COLOR_ARG1] & WINED3DTA_SELECTMASK; - DWORD color_arg2 = state->texture_states[i][WINED3D_TSS_COLOR_ARG2] & WINED3DTA_SELECTMASK; - DWORD color_arg3 = state->texture_states[i][WINED3D_TSS_COLOR_ARG0] & WINED3DTA_SELECTMASK; - DWORD alpha_arg1 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] & WINED3DTA_SELECTMASK; - DWORD alpha_arg2 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] & WINED3DTA_SELECTMASK; - DWORD alpha_arg3 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] & WINED3DTA_SELECTMASK; - - /* Not used, and disable higher stages. */ - if (color_op == WINED3D_TOP_DISABLE) - break; - - if (((color_arg1 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG2) - || ((color_arg2 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG1) - || ((color_arg3 == WINED3DTA_TEXTURE) - && (color_op == WINED3D_TOP_MULTIPLY_ADD || color_op == WINED3D_TOP_LERP)) - || ((alpha_arg1 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG2) - || ((alpha_arg2 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG1) - || ((alpha_arg3 == WINED3DTA_TEXTURE) - && (alpha_op == WINED3D_TOP_MULTIPLY_ADD || alpha_op == WINED3D_TOP_LERP))) - device->fixed_function_usage_map |= (1 << i); - - if ((color_op == WINED3D_TOP_BUMPENVMAP || color_op == WINED3D_TOP_BUMPENVMAP_LUMINANCE) - && i < MAX_TEXTURES - 1) - device->fixed_function_usage_map |= (1 << (i + 1)); - } -} - -static void device_map_fixed_function_samplers(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info) -{ - unsigned int i, tex; - WORD ffu_map; - - device_update_fixed_function_usage_map(device); - ffu_map = device->fixed_function_usage_map; - - if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages - || device->state.lowest_disabled_stage <= d3d_info->limits.ffp_textures) - { - for (i = 0; ffu_map; ffu_map >>= 1, ++i) - { - if (!(ffu_map & 1)) continue; - - if (device->texUnitMap[i] != i) - { - device_map_stage(device, i, i); - device_invalidate_state(device, STATE_SAMPLER(i)); - device_invalidate_texture_stage(device, i); - } - } - return; - } - - /* Now work out the mapping */ - tex = 0; - for (i = 0; ffu_map; ffu_map >>= 1, ++i) - { - if (!(ffu_map & 1)) continue; - - if (device->texUnitMap[i] != tex) - { - device_map_stage(device, i, tex); - device_invalidate_state(device, STATE_SAMPLER(i)); - device_invalidate_texture_stage(device, i); - } - - ++tex; - } -} - -static void device_map_psamplers(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info) -{ - const enum wined3d_sampler_texture_type *sampler_type = - device->state.pixel_shader->reg_maps.sampler_type; - unsigned int i; - - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) - { - if (sampler_type[i] && device->texUnitMap[i] != i) - { - device_map_stage(device, i, i); - device_invalidate_state(device, STATE_SAMPLER(i)); - if (i < d3d_info->limits.ffp_blend_stages) - device_invalidate_texture_stage(device, i); - } - } -} - -static BOOL device_unit_free_for_vs(const struct wined3d_device *device, - const enum wined3d_sampler_texture_type *pshader_sampler_tokens, - const enum wined3d_sampler_texture_type *vshader_sampler_tokens, DWORD unit) -{ - DWORD current_mapping = device->rev_tex_unit_map[unit]; - - /* Not currently used */ - if (current_mapping == WINED3D_UNMAPPED_STAGE) return TRUE; - - if (current_mapping < MAX_FRAGMENT_SAMPLERS) { - /* Used by a fragment sampler */ - - if (!pshader_sampler_tokens) { - /* No pixel shader, check fixed function */ - return current_mapping >= MAX_TEXTURES || !(device->fixed_function_usage_map & (1 << current_mapping)); - } - - /* Pixel shader, check the shader's sampler map */ - return !pshader_sampler_tokens[current_mapping]; - } - - /* Used by a vertex sampler */ - return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS]; -} - -static void device_map_vsamplers(struct wined3d_device *device, BOOL ps, const struct wined3d_gl_info *gl_info) -{ - const enum wined3d_sampler_texture_type *vshader_sampler_type = - device->state.vertex_shader->reg_maps.sampler_type; - const enum wined3d_sampler_texture_type *pshader_sampler_type = NULL; - int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1; - int i; - - if (ps) - { - /* Note that we only care if a sampler is sampled or not, not the sampler's specific type. - * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */ - pshader_sampler_type = device->state.pixel_shader->reg_maps.sampler_type; - } - - for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) { - DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS; - if (vshader_sampler_type[i]) - { - if (device->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE) - { - /* Already mapped somewhere */ - continue; - } - - while (start >= 0) - { - if (device_unit_free_for_vs(device, pshader_sampler_type, vshader_sampler_type, start)) - { - device_map_stage(device, vsampler_idx, start); - device_invalidate_state(device, STATE_SAMPLER(vsampler_idx)); - - --start; - break; - } - - --start; - } - } - } -} - -void device_update_tex_unit_map(struct wined3d_device *device) -{ - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - const struct wined3d_state *state = &device->state; - BOOL vs = use_vs(state); - BOOL ps = use_ps(state); - /* - * Rules are: - * -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but - * that would be really messy and require shader recompilation - * -> When the mapping of a stage is changed, sampler and ALL texture stage states have - * to be reset. Because of that try to work with a 1:1 mapping as much as possible - */ - if (ps) - device_map_psamplers(device, d3d_info); - else - device_map_fixed_function_samplers(device, d3d_info); - - if (vs) - device_map_vsamplers(device, ps, gl_info); -} - void CDECL wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_shader *prev = device->update_state->pixel_shader; + struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_PIXEL]; TRACE("device %p, shader %p.\n", device, shader); - if (shader) - wined3d_shader_incref(shader); - if (prev) - wined3d_shader_decref(prev); - - device->update_state->pixel_shader = shader; - if (device->recording) - { - TRACE("Recording... not performing anything.\n"); device->recording->changed.pixelShader = TRUE; - return; - } if (shader == prev) - { - TRACE("Application is setting the old shader over, nothing to do.\n"); return; - } - device_invalidate_state(device, STATE_PIXELSHADER); + if (shader) + wined3d_shader_incref(shader); + device->update_state->shader[WINED3D_SHADER_TYPE_PIXEL] = shader; + if (!device->recording) + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_PIXEL, shader); + if (prev) + wined3d_shader_decref(prev); } struct wined3d_shader * CDECL wined3d_device_get_pixel_shader(const struct wined3d_device *device) { TRACE("device %p.\n", device); - return device->state.pixel_shader; + return device->state.shader[WINED3D_SHADER_TYPE_PIXEL]; } void CDECL wined3d_device_set_ps_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer) { - struct wined3d_buffer *prev; - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - if (idx >= MAX_CONSTANT_BUFFERS) - { - WARN("Invalid constant buffer index %u.\n", idx); - return; - } - - prev = device->update_state->ps_cb[idx]; - device->update_state->ps_cb[idx] = buffer; - - if (device->recording) - { - if (buffer) - wined3d_buffer_incref(buffer); - if (prev) - wined3d_buffer_decref(prev); - return; - } - - if (prev != buffer) - { - if (buffer) - { - InterlockedIncrement(&buffer->resource.bind_count); - wined3d_buffer_incref(buffer); - } - if (prev) - { - InterlockedDecrement(&prev->resource.bind_count); - wined3d_buffer_decref(prev); - } - } + wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_PIXEL, idx, buffer); } struct wined3d_buffer * CDECL wined3d_device_get_ps_cb(const struct wined3d_device *device, UINT idx) @@ -2943,28 +2357,14 @@ struct wined3d_buffer * CDECL wined3d_device_get_ps_cb(const struct wined3d_devi return NULL; } - return device->state.ps_cb[idx]; + return device->state.cb[WINED3D_SHADER_TYPE_PIXEL][idx]; } void CDECL wined3d_device_set_ps_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler) { - struct wined3d_sampler *prev; - TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); - if (idx >= MAX_SAMPLER_OBJECTS) - { - WARN("Invalid sampler index %u.\n", idx); - return; - } - - prev = device->update_state->ps_sampler[idx]; - device->update_state->ps_sampler[idx] = sampler; - - if (sampler) - wined3d_sampler_incref(sampler); - if (prev) - wined3d_sampler_decref(prev); + wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_PIXEL, idx, sampler); } struct wined3d_sampler * CDECL wined3d_device_get_ps_sampler(const struct wined3d_device *device, UINT idx) @@ -2977,7 +2377,7 @@ struct wined3d_sampler * CDECL wined3d_device_get_ps_sampler(const struct wined3 return NULL; } - return device->state.ps_sampler[idx]; + return device->state.sampler[WINED3D_SHADER_TYPE_PIXEL][idx]; } HRESULT CDECL wined3d_device_set_ps_consts_b(struct wined3d_device *device, @@ -3126,67 +2526,32 @@ HRESULT CDECL wined3d_device_get_ps_consts_f(const struct wined3d_device *device void CDECL wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_shader *prev = device->update_state->geometry_shader; + struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; TRACE("device %p, shader %p.\n", device, shader); - if (shader) - wined3d_shader_incref(shader); - if (prev) - wined3d_shader_decref(prev); - - device->update_state->geometry_shader = shader; - if (device->recording || shader == prev) return; - - device_invalidate_state(device, STATE_GEOMETRY_SHADER); + if (shader) + wined3d_shader_incref(shader); + device->update_state->shader[WINED3D_SHADER_TYPE_GEOMETRY] = shader; + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_GEOMETRY, shader); + if (prev) + wined3d_shader_decref(prev); } struct wined3d_shader * CDECL wined3d_device_get_geometry_shader(const struct wined3d_device *device) { TRACE("device %p.\n", device); - return device->state.geometry_shader; + return device->state.shader[WINED3D_SHADER_TYPE_GEOMETRY]; } void CDECL wined3d_device_set_gs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer) { - struct wined3d_buffer *prev; - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - if (idx >= MAX_CONSTANT_BUFFERS) - { - WARN("Invalid constant buffer index %u.\n", idx); - return; - } - - prev = device->update_state->gs_cb[idx]; - device->update_state->gs_cb[idx] = buffer; - - if (device->recording) - { - if (buffer) - wined3d_buffer_incref(buffer); - if (prev) - wined3d_buffer_decref(prev); - return; - } - - if (prev != buffer) - { - if (buffer) - { - InterlockedIncrement(&buffer->resource.bind_count); - wined3d_buffer_incref(buffer); - } - if (prev) - { - InterlockedDecrement(&prev->resource.bind_count); - wined3d_buffer_decref(prev); - } - } + wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_GEOMETRY, idx, buffer); } struct wined3d_buffer * CDECL wined3d_device_get_gs_cb(const struct wined3d_device *device, UINT idx) @@ -3199,28 +2564,14 @@ struct wined3d_buffer * CDECL wined3d_device_get_gs_cb(const struct wined3d_devi return NULL; } - return device->state.gs_cb[idx]; + return device->state.cb[WINED3D_SHADER_TYPE_GEOMETRY][idx]; } void CDECL wined3d_device_set_gs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler) { - struct wined3d_sampler *prev; - TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); - if (idx >= MAX_SAMPLER_OBJECTS) - { - WARN("Invalid sampler index %u.\n", idx); - return; - } - - prev = device->update_state->gs_sampler[idx]; - device->update_state->gs_sampler[idx] = sampler; - - if (sampler) - wined3d_sampler_incref(sampler); - if (prev) - wined3d_sampler_decref(prev); + wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_GEOMETRY, idx, sampler); } struct wined3d_sampler * CDECL wined3d_device_get_gs_sampler(const struct wined3d_device *device, UINT idx) @@ -3233,11 +2584,10 @@ struct wined3d_sampler * CDECL wined3d_device_get_gs_sampler(const struct wined3 return NULL; } - return device->state.gs_sampler[idx]; + return device->state.sampler[WINED3D_SHADER_TYPE_GEOMETRY][idx]; } /* Context activation is done by the caller. */ -/* Do not call while under the GL lock. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount, const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD flags, @@ -3504,7 +2854,6 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO } #undef copy_and_next -/* Do not call while under the GL lock. */ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer, const struct wined3d_vertex_declaration *declaration, DWORD flags, DWORD dst_fvf) @@ -3529,10 +2878,10 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, context = context_acquire(device, NULL); gl_info = context->gl_info; - vs = state->vertex_shader; - state->vertex_shader = NULL; - device_stream_info_from_declaration(device, &stream_info); - state->vertex_shader = vs; + vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; + state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; + context_stream_info_from_declaration(context, state, &stream_info); + state->shader[WINED3D_SHADER_TYPE_VERTEX] = vs; /* We can't convert FROM a VBO, and vertex buffers used to source into * process_vertices() are unlikely to ever be used for drawing. Release @@ -3551,7 +2900,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, { struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer; e->data.buffer_object = 0; - e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, gl_info)); + e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, context)); GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object)); vb->buffer_object = 0; } @@ -3606,57 +2955,7 @@ void CDECL wined3d_device_set_texture_stage_state(struct wined3d_device *device, return; } - if (stage > device->state.lowest_disabled_stage - && device->StateTable[STATE_TEXTURESTAGE(0, state)].representative - == STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP)) - { - /* Colorop change above lowest disabled stage? That won't change - * anything in the GL setup. Changes in other states are important on - * disabled stages too. */ - return; - } - - if (state == WINED3D_TSS_COLOR_OP) - { - unsigned int i; - - if (value == WINED3D_TOP_DISABLE && old_value != WINED3D_TOP_DISABLE) - { - /* Previously enabled stage disabled now. Make sure to dirtify - * all enabled stages above stage, they have to be disabled. - * - * The current stage is dirtified below. */ - for (i = stage + 1; i < device->state.lowest_disabled_stage; ++i) - { - TRACE("Additionally dirtifying stage %u.\n", i); - device_invalidate_state(device, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)); - } - device->state.lowest_disabled_stage = stage; - TRACE("New lowest disabled: %u.\n", stage); - } - else if (value != WINED3D_TOP_DISABLE && old_value == WINED3D_TOP_DISABLE) - { - /* Previously disabled stage enabled. Stages above it may need - * enabling. Stage must be lowest_disabled_stage here, if it's - * bigger success is returned above, and stages below the lowest - * disabled stage can't be enabled (because they are enabled - * already). - * - * Again stage stage doesn't need to be dirtified here, it is - * handled below. */ - for (i = stage + 1; i < d3d_info->limits.ffp_blend_stages; ++i) - { - if (device->update_state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE) - break; - TRACE("Additionally dirtifying stage %u due to enable.\n", i); - device_invalidate_state(device, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)); - } - device->state.lowest_disabled_stage = i; - TRACE("New lowest disabled: %u.\n", i); - } - } - - device_invalidate_state(device, STATE_TEXTURESTAGE(stage, state)); + wined3d_cs_emit_set_texture_state(device->cs, stage, state, value); } DWORD CDECL wined3d_device_get_texture_stage_state(const struct wined3d_device *device, @@ -3677,7 +2976,6 @@ DWORD CDECL wined3d_device_get_texture_stage_state(const struct wined3d_device * HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device, UINT stage, struct wined3d_texture *texture) { - const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct wined3d_texture *prev; TRACE("device %p, stage %u, texture %p.\n", device, stage, texture); @@ -3713,70 +3011,12 @@ HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device, TRACE("Setting new texture to %p.\n", texture); device->update_state->textures[stage] = texture; - if (device->recording) - { - TRACE("Recording... not performing anything\n"); - - if (texture) wined3d_texture_incref(texture); - if (prev) wined3d_texture_decref(prev); - - return WINED3D_OK; - } - if (texture) - { - LONG bind_count = InterlockedIncrement(&texture->resource.bind_count); - wined3d_texture_incref(texture); - - if (!prev || texture->target != prev->target) - device_invalidate_state(device, STATE_PIXELSHADER); - - if (!prev && stage < d3d_info->limits.ffp_blend_stages) - { - /* The source arguments for color and alpha ops have different - * meanings when a NULL texture is bound, so the COLOR_OP and - * ALPHA_OP have to be dirtified. */ - device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP)); - device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP)); - } - - if (bind_count == 1) - texture->sampler = stage; - } - + if (!device->recording) + wined3d_cs_emit_set_texture(device->cs, stage, texture); if (prev) - { - LONG bind_count = InterlockedDecrement(&prev->resource.bind_count); - - if (!texture && stage < d3d_info->limits.ffp_blend_stages) - { - device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP)); - device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP)); - } - - if (bind_count && prev->sampler == stage) - { - unsigned int i; - - /* Search for other stages the texture is bound to. Shouldn't - * happen if applications bind textures to a single stage only. */ - TRACE("Searching for other stages the texture is bound to.\n"); - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) - { - if (device->update_state->textures[i] == prev) - { - TRACE("Texture is also bound to stage %u.\n", i); - prev->sampler = i; - break; - } - } - } - wined3d_texture_decref(prev); - } - - device_invalidate_state(device, STATE_SAMPLER(stage)); return WINED3D_OK; } @@ -3938,12 +3178,9 @@ HRESULT CDECL wined3d_device_present(const struct wined3d_device *device, const return WINED3D_OK; } -/* Do not call while under the GL lock. */ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { - RECT draw_rect; - TRACE("device %p, rect_count %u, rects %p, flags %#x, color {%.8e, %.8e, %.8e, %.8e}, depth %.8e, stencil %u.\n", device, rect_count, rects, flags, color->r, color->g, color->b, color->a, depth, stencil); @@ -3973,9 +3210,7 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou } } - wined3d_get_draw_rect(&device->state, &draw_rect); - device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, - &device->fb, rect_count, rects, &draw_rect, flags, color, depth, stencil); + wined3d_cs_emit_clear(device->cs, rect_count, rects, flags, color, depth, stencil); return WINED3D_OK; } @@ -4022,9 +3257,8 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT device_invalidate_state(device, STATE_BASEVERTEXINDEX); } - /* Account for the loading offset due to index buffers. Instead of - * reloading all sources correct it with the startvertex parameter. */ - draw_primitive(device, start_vertex, vertex_count, 0, 0, FALSE); + wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); + return WINED3D_OK; } @@ -4057,7 +3291,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic device_invalidate_state(device, STATE_BASEVERTEXINDEX); } - draw_primitive(device, start_idx, index_count, 0, 0, TRUE); + wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); return WINED3D_OK; } @@ -4067,7 +3301,7 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device { TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count); - draw_primitive(device, start_idx, index_count, start_instance, instance_count, TRUE); + wined3d_cs_emit_draw(device->cs, start_idx, index_count, start_instance, instance_count, TRUE); } /* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */ @@ -4120,6 +3354,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, enum wined3d_resource_type type; unsigned int level_count, i; HRESULT hr; + struct wined3d_context *context; TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); @@ -4158,7 +3393,9 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, } /* Make sure that the destination texture is loaded. */ - dst_texture->texture_ops->texture_preload(dst_texture, SRGB_RGB); + context = context_acquire(device, NULL); + wined3d_texture_load(dst_texture, context, FALSE); + context_release(context); /* Update every surface level of the texture. */ switch (type) @@ -4396,7 +3633,6 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, return surface_upload_from_surface(dst_surface, dst_point, src_surface, src_rect); } -/* Do not call while under the GL lock. */ HRESULT CDECL wined3d_device_color_fill(struct wined3d_device *device, struct wined3d_surface *surface, const RECT *rect, const struct wined3d_color *color) { @@ -4421,7 +3657,6 @@ HRESULT CDECL wined3d_device_color_fill(struct wined3d_device *device, return surface_color_fill(surface, rect, color); } -/* Do not call while under the GL lock. */ void CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, struct wined3d_rendertarget_view *rendertarget_view, const struct wined3d_color *color) { @@ -4476,16 +3711,9 @@ HRESULT CDECL wined3d_device_set_render_target(struct wined3d_device *device, return WINED3DERR_INVALIDCALL; } - /* Render target 0 can't be set to NULL. */ - if (!render_target && !render_target_idx) - { - WARN("Trying to set render target 0 to NULL.\n"); - return WINED3DERR_INVALIDCALL; - } - if (render_target && !(render_target->resource.usage & WINED3DUSAGE_RENDERTARGET)) { - FIXME("Surface %p doesn't have render target usage.\n", render_target); + WARN("Surface %p doesn't have render target usage.\n", render_target); return WINED3DERR_INVALIDCALL; } @@ -4502,13 +3730,13 @@ HRESULT CDECL wined3d_device_set_render_target(struct wined3d_device *device, state->viewport.height = render_target->resource.height; state->viewport.min_z = 0.0f; state->viewport.max_z = 1.0f; - device_invalidate_state(device, STATE_VIEWPORT); + wined3d_cs_emit_set_viewport(device->cs, &state->viewport); state->scissor_rect.top = 0; state->scissor_rect.left = 0; state->scissor_rect.right = render_target->resource.width; state->scissor_rect.bottom = render_target->resource.height; - device_invalidate_state(device, STATE_SCISSORRECT); + wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); } @@ -4519,13 +3747,12 @@ HRESULT CDECL wined3d_device_set_render_target(struct wined3d_device *device, if (render_target) wined3d_surface_incref(render_target); device->fb.render_targets[render_target_idx] = render_target; + wined3d_cs_emit_set_render_target(device->cs, render_target_idx, render_target); /* Release after the assignment, to prevent device_resource_released() * from seeing the surface as still in use. */ if (prev) wined3d_surface_decref(prev); - device_invalidate_state(device, STATE_FRAMEBUFFER); - return WINED3D_OK; } @@ -4542,43 +3769,71 @@ void CDECL wined3d_device_set_depth_stencil(struct wined3d_device *device, struc return; } - if (prev) - { - if (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || prev->flags & SFLAG_DISCARD) - { - surface_modify_ds_location(prev, SFLAG_DISCARDED, - prev->resource.width, prev->resource.height); - if (prev == device->onscreen_depth_stencil) - { - wined3d_surface_decref(device->onscreen_depth_stencil); - device->onscreen_depth_stencil = NULL; - } - } - } - device->fb.depth_stencil = depth_stencil; if (depth_stencil) wined3d_surface_incref(depth_stencil); - - if (!prev != !depth_stencil) - { - /* Swapping NULL / non NULL depth stencil affects the depth and tests */ - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); - 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)); - } - else if (prev && prev->resource.format->depth_size != depth_stencil->resource.format->depth_size) - { - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); - } + wined3d_cs_emit_set_depth_stencil(device->cs, depth_stencil); if (prev) wined3d_surface_decref(prev); +} - device_invalidate_state(device, STATE_FRAMEBUFFER); +static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device, + struct wined3d_surface *cursor_image) +{ + struct wined3d_resource_desc desc; + struct wined3d_map_desc map_desc; + struct wined3d_texture *texture; + struct wined3d_surface *surface; + BYTE *src_data, *dst_data; + unsigned int src_pitch; + unsigned int i; - return; + if (FAILED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY))) + { + ERR("Failed to map source surface.\n"); + return NULL; + } + + src_pitch = map_desc.row_pitch; + src_data = map_desc.data; + + desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.format = WINED3DFMT_B8G8R8A8_UNORM; + desc.multisample_type = WINED3D_MULTISAMPLE_NONE; + desc.multisample_quality = 0; + desc.usage = WINED3DUSAGE_DYNAMIC; + desc.pool = WINED3D_POOL_DEFAULT; + desc.width = cursor_image->resource.width; + desc.height = cursor_image->resource.height; + desc.depth = 1; + desc.size = 0; + + if (FAILED(wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE, + NULL, &wined3d_null_parent_ops, &texture))) + { + ERR("Failed to create cursor texture.\n"); + wined3d_surface_unmap(cursor_image); + return NULL; + } + + surface = surface_from_resource(wined3d_texture_get_sub_resource(texture, 0)); + if (FAILED(wined3d_surface_map(surface, &map_desc, NULL, WINED3D_MAP_DISCARD))) + { + ERR("Failed to map destination surface.\n"); + wined3d_texture_decref(texture); + wined3d_surface_unmap(cursor_image); + return NULL; + } + + dst_data = map_desc.data; + + for (i = 0; i < desc.height; ++i) + memcpy(&dst_data[map_desc.row_pitch * i], &src_data[src_pitch * i], desc.width * 4); + + wined3d_surface_unmap(surface); + wined3d_surface_unmap(cursor_image); + + return texture; } HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device, @@ -4587,13 +3842,10 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device TRACE("device %p, x_hotspot %u, y_hotspot %u, cursor_image %p.\n", device, x_hotspot, y_hotspot, cursor_image); - /* some basic validation checks */ - if (device->cursorTexture) + if (device->cursor_texture) { - struct wined3d_context *context = context_acquire(device, NULL); - context->gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->cursorTexture); - context_release(context); - device->cursorTexture = 0; + wined3d_texture_decref(device->cursor_texture); + device->cursor_texture = NULL; } if (cursor_image) @@ -4629,50 +3881,15 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device /* Do not store the surface's pointer because the application may * release it after setting the cursor image. Windows doesn't * addref the set surface, so we can't do this either without - * creating circular refcount dependencies. Copy out the gl texture - * instead. */ + * creating circular refcount dependencies. */ + if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, cursor_image))) + { + ERR("Failed to create cursor texture.\n"); + return WINED3DERR_INVALIDCALL; + } + device->cursorWidth = cursor_image->resource.width; device->cursorHeight = cursor_image->resource.height; - if (SUCCEEDED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY))) - { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM); - struct wined3d_context *context; - char *mem, *bits = map_desc.data; - GLint intfmt = format->glInternal; - GLint gl_format = format->glFormat; - GLint type = format->glType; - INT height = device->cursorHeight; - INT width = device->cursorWidth; - INT bpp = format->byte_count; - INT i; - - /* Reformat the texture memory (pitch and width can be - * different) */ - mem = HeapAlloc(GetProcessHeap(), 0, width * height * bpp); - for (i = 0; i < height; ++i) - memcpy(&mem[width * bpp * i], &bits[map_desc.row_pitch * i], width * bpp); - wined3d_surface_unmap(cursor_image); - - context = context_acquire(device, NULL); - - invalidate_active_texture(device, context); - /* Create a new cursor texture */ - gl_info->gl_ops.gl.p_glGenTextures(1, &device->cursorTexture); - checkGLcall("glGenTextures"); - context_bind_texture(context, GL_TEXTURE_2D, device->cursorTexture); - /* Copy the bitmap memory into the cursor texture */ - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, intfmt, width, height, 0, gl_format, type, mem); - checkGLcall("glTexImage2D"); - HeapFree(GetProcessHeap(), 0, mem); - - context_release(context); - } - else - { - FIXME("A cursor texture was not returned.\n"); - device->cursorTexture = 0; - } if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32) { @@ -4769,10 +3986,9 @@ BOOL CDECL wined3d_device_show_cursor(struct wined3d_device *device, BOOL show) else SetCursor(NULL); } - else + else if (device->cursor_texture) { - if (device->cursorTexture) - device->bCursorVisible = show; + device->bCursorVisible = show; } return oldVisible; @@ -4799,7 +4015,6 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) device_invalidate_state(device, STATE_STREAMSRC); } -/* Do not call while under the GL lock. */ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) { struct wined3d_resource *resource, *cursor; @@ -4827,11 +4042,6 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); device->depth_blt_texture = 0; } - if (device->cursorTexture) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->cursorTexture); - device->cursorTexture = 0; - } device->blitter->free_private(device); device->shader_backend->shader_free_private(device); @@ -4848,7 +4058,6 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d swapchain->context = NULL; } -/* Do not call while under the GL lock. */ static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) { struct wined3d_context *context; @@ -4897,7 +4106,6 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru return WINED3D_OK; } -/* Do not call while under the GL lock. */ 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) @@ -4925,14 +4133,12 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, if (device->fb.render_targets) { - if (swapchain->back_buffers && swapchain->back_buffers[0]) - wined3d_device_set_render_target(device, 0, swapchain->back_buffers[0], FALSE); - else - wined3d_device_set_render_target(device, 0, swapchain->front_buffer, FALSE); - for (i = 1; i < device->adapter->gl_info.limits.buffers; ++i) + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) { wined3d_device_set_render_target(device, i, NULL, FALSE); } + if (swapchain->back_buffers && swapchain->back_buffers[0]) + wined3d_device_set_render_target(device, 0, swapchain->back_buffers[0], FALSE); } wined3d_device_set_depth_stencil(device, NULL); @@ -4979,9 +4185,12 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, /* 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; + swapchain->desc.auto_depth_stencil_format = swapchain_desc->auto_depth_stencil_format; swapchain->desc.flags = swapchain_desc->flags; - swapchain->desc.swap_interval = swapchain_desc->swap_interval; swapchain->desc.refresh_rate = swapchain_desc->refresh_rate; + swapchain->desc.swap_interval = swapchain_desc->swap_interval; + swapchain->desc.auto_restore_display_mode = swapchain_desc->auto_restore_display_mode; /* What to do about these? */ if (swapchain_desc->backbuffer_count @@ -5101,21 +4310,21 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, if (FAILED(hr = wined3d_surface_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format, - swapchain->desc.multisample_type, swapchain->desc.multisample_quality))) + swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0))) return hr; for (i = 0; i < swapchain->desc.backbuffer_count; ++i) { if (FAILED(hr = wined3d_surface_update_desc(swapchain->back_buffers[i], swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format, - swapchain->desc.multisample_type, swapchain->desc.multisample_quality))) + swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0))) return hr; } if (device->auto_depth_stencil) { if (FAILED(hr = wined3d_surface_update_desc(device->auto_depth_stencil, swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height, device->auto_depth_stencil->resource.format->id, - swapchain->desc.multisample_type, swapchain->desc.multisample_quality))) + swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0))) return hr; } } @@ -5189,15 +4398,18 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_stateblock_decref(device->recording); device->recording = NULL; } + wined3d_cs_emit_reset_state(device->cs); state_cleanup(&device->state); if (device->d3d_initialized) delete_opengl_contexts(device, swapchain); - if (FAILED(hr = state_init(&device->state, &device->adapter->d3d_info))) + if (FAILED(hr = state_init(&device->state, &device->fb, &device->adapter->gl_info, + &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) ERR("Failed to initialize device state, hr %#x.\n", hr); - state_init_default(&device->state, device); device->update_state = &device->state; + + device_init_swapchain_state(device, swapchain); } else { @@ -5209,13 +4421,13 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, state->viewport.y = 0; state->viewport.width = rt->resource.width; state->viewport.height = rt->resource.height; - device_invalidate_state(device, STATE_VIEWPORT); + wined3d_cs_emit_set_viewport(device->cs, &state->viewport); state->scissor_rect.top = 0; state->scissor_rect.left = 0; state->scissor_rect.right = rt->resource.width; state->scissor_rect.bottom = rt->resource.height; - device_invalidate_state(device, STATE_SCISSORRECT); + wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); } swapchain_update_render_to_fbo(swapchain); @@ -5456,19 +4668,31 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, device->blitter = adapter->blitter; - if (FAILED(hr = state_init(&device->state, &adapter->d3d_info))) + if (FAILED(hr = state_init(&device->state, &device->fb, &adapter->gl_info, + &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) { ERR("Failed to initialize device state, hr %#x.\n", hr); - for (i = 0; i < sizeof(device->multistate_funcs) / sizeof(device->multistate_funcs[0]); ++i) - { - HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]); - } - wined3d_decref(device->wined3d); - return hr; + goto err; } device->update_state = &device->state; + if (!(device->cs = wined3d_cs_create(device))) + { + WARN("Failed to create command stream.\n"); + state_cleanup(&device->state); + hr = E_FAIL; + goto err; + } + return WINED3D_OK; + +err: + for (i = 0; i < sizeof(device->multistate_funcs) / sizeof(device->multistate_funcs[0]); ++i) + { + HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]); + } + wined3d_decref(device->wined3d); + return hr; } diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index 420de71d486..ffdcc664e6d 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -22,6 +22,8 @@ */ #include "wined3d_private.h" +#include +#include #include @@ -130,6 +132,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3 }, {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT }, {"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_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO }, {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE }, {"GL_ARB_texture_rg", ARB_TEXTURE_RG }, @@ -174,6 +177,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3 }, {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC}, {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS }, + {"GL_EXT_texture_mirror_clamp", EXT_TEXTURE_MIRROR_CLAMP }, {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB }, {"GL_EXT_texture_sRGB_decode", EXT_TEXTURE_SRGB_DECODE }, {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA }, @@ -251,7 +255,7 @@ const GLenum magLookup_noFilter[] = GL_NEAREST, GL_NEAREST, GL_NEAREST, }; -struct wined3d_fake_gl_ctx +struct wined3d_caps_gl_ctx { HDC dc; HWND wnd; @@ -260,12 +264,12 @@ struct wined3d_fake_gl_ctx HGLRC restore_gl_ctx; }; -static void WineD3D_ReleaseFakeGLContext(const struct wined3d_fake_gl_ctx *ctx) +static void wined3d_caps_gl_ctx_destroy(const struct wined3d_caps_gl_ctx *ctx) { - TRACE("Destroying fake GL context.\n"); + TRACE("Destroying caps GL context.\n"); if (!wglMakeCurrent(NULL, NULL)) - ERR("Failed to disable fake GL context.\n"); + ERR("Failed to disable caps GL context.\n"); if (!wglDeleteContext(ctx->gl_ctx)) { @@ -273,14 +277,14 @@ static void WineD3D_ReleaseFakeGLContext(const struct wined3d_fake_gl_ctx *ctx) ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err); } - ReleaseDC(ctx->wnd, ctx->dc); + wined3d_release_dc(ctx->wnd, ctx->dc); DestroyWindow(ctx->wnd); if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx)) ERR("Failed to restore previous GL context.\n"); } -static void wined3d_create_fake_gl_context_attribs(struct wined3d_fake_gl_ctx *fake_gl_ctx, +static void wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_gl_ctx, struct wined3d_gl_info *gl_info, const GLint *ctx_attribs) { HGLRC new_ctx; @@ -288,14 +292,14 @@ static void wined3d_create_fake_gl_context_attribs(struct wined3d_fake_gl_ctx *f if (!(gl_info->p_wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB"))) return; - if (!(new_ctx = gl_info->p_wglCreateContextAttribsARB(fake_gl_ctx->dc, NULL, ctx_attribs))) + if (!(new_ctx = gl_info->p_wglCreateContextAttribsARB(caps_gl_ctx->dc, NULL, ctx_attribs))) { ERR("Failed to create a context using wglCreateContextAttribsARB(), last error %#x.\n", GetLastError()); gl_info->p_wglCreateContextAttribsARB = NULL; return; } - if (!wglMakeCurrent(fake_gl_ctx->dc, new_ctx)) + if (!wglMakeCurrent(caps_gl_ctx->dc, new_ctx)) { ERR("Failed to make new context current, last error %#x.\n", GetLastError()); if (!wglDeleteContext(new_ctx)) @@ -304,13 +308,12 @@ static void wined3d_create_fake_gl_context_attribs(struct wined3d_fake_gl_ctx *f return; } - if (!wglDeleteContext(fake_gl_ctx->gl_ctx)) + if (!wglDeleteContext(caps_gl_ctx->gl_ctx)) ERR("Failed to delete old context, last error %#x.\n", GetLastError()); - fake_gl_ctx->gl_ctx = new_ctx; + caps_gl_ctx->gl_ctx = new_ctx; } -/* Do not call while under the GL lock. */ -static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx) +static BOOL wined3d_caps_gl_ctx_create(struct wined3d_caps_gl_ctx *ctx) { PIXELFORMATDESCRIPTOR pfd; int iPixelFormat; @@ -364,7 +367,7 @@ static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx) /* Make it the current GL context. */ if (!wglMakeCurrent(ctx->dc, ctx->gl_ctx)) { - ERR("Failed to make fake GL context current.\n"); + ERR("Failed to make caps GL context current.\n"); goto fail; } @@ -1248,10 +1251,12 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650, "NVIDIA GeForce GTX 650", DRIVER_NVIDIA_GEFORCE6, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650TI, "NVIDIA GeForce GTX 650 Ti", DRIVER_NVIDIA_GEFORCE6, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660, "NVIDIA GeForce GTX 660", DRIVER_NVIDIA_GEFORCE6, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660M, "NVIDIA GeForce GTX 660M", DRIVER_NVIDIA_GEFORCE6, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660TI, "NVIDIA GeForce GTX 660 Ti", DRIVER_NVIDIA_GEFORCE6, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670, "NVIDIA GeForce GTX 670", DRIVER_NVIDIA_GEFORCE6, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670MX, "NVIDIA GeForce GTX 670MX", DRIVER_NVIDIA_GEFORCE6, 3072}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX680, "NVIDIA GeForce GTX 680", DRIVER_NVIDIA_GEFORCE6, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX765M, "NVIDIA GeForce GTX 765M", DRIVER_NVIDIA_GEFORCE6, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770M, "NVIDIA GeForce GTX 770M", DRIVER_NVIDIA_GEFORCE6, 3072}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770, "NVIDIA GeForce GTX 770", DRIVER_NVIDIA_GEFORCE6, 2048}, @@ -1324,6 +1329,7 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_INTEL, CARD_INTEL_IVBD, "Intel(R) Ivybridge Desktop", DRIVER_INTEL_GMA3000, 1024}, {HW_VENDOR_INTEL, CARD_INTEL_IVBM, "Intel(R) Ivybridge Mobile", DRIVER_INTEL_GMA3000, 1024}, {HW_VENDOR_INTEL, CARD_INTEL_IVBS, "Intel(R) Ivybridge Server", DRIVER_INTEL_GMA3000, 1024}, + {HW_VENDOR_INTEL, CARD_INTEL_HWM, "Intel(R) Haswell Mobile", DRIVER_INTEL_GMA3000, 1024}, }; static const struct driver_version_information *get_driver_version_info(enum wined3d_display_driver driver, @@ -1658,10 +1664,12 @@ static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl { {"GTX 770M", CARD_NVIDIA_GEFORCE_GTX770M}, /* Geforce 700 - midend high mobile */ {"GTX 770", CARD_NVIDIA_GEFORCE_GTX770}, /* Geforce 700 - highend */ + {"GTX 765M", CARD_NVIDIA_GEFORCE_GTX765M}, /* Geforce 700 - midend high mobile */ {"GTX 680", CARD_NVIDIA_GEFORCE_GTX680}, /* Geforce 600 - highend */ {"GTX 670MX", CARD_NVIDIA_GEFORCE_GTX670MX}, /* Geforce 600 - highend */ {"GTX 670", CARD_NVIDIA_GEFORCE_GTX670}, /* Geforce 600 - midend high */ {"GTX 660 Ti", CARD_NVIDIA_GEFORCE_GTX660TI}, /* Geforce 600 - midend high */ + {"GTX 660M", CARD_NVIDIA_GEFORCE_GTX660M}, /* Geforce 600 - midend high mobile */ {"GTX 660", CARD_NVIDIA_GEFORCE_GTX660}, /* Geforce 600 - midend high */ {"GTX 650 Ti", CARD_NVIDIA_GEFORCE_GTX650TI}, /* Geforce 600 - lowend */ {"GTX 650", CARD_NVIDIA_GEFORCE_GTX650}, /* Geforce 600 - lowend */ @@ -1984,6 +1992,8 @@ static enum wined3d_pci_device select_card_intel(const struct wined3d_gl_info *g } cards[] = { + /* Haswell */ + {"Haswell Mobile", CARD_INTEL_HWM}, /* Ivybridge */ {"Ivybridge Server", CARD_INTEL_IVBS}, {"Ivybridge Mobile", CARD_INTEL_IVBM}, @@ -2371,7 +2381,7 @@ static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info * * size of the database can be made quite small because when you know what * type of 3d functionality a card has, you know to which GPU family the * GPU must belong. Because of this you only have to check a small part of - * the renderer string to distinguishes between different models from that + * the renderer string to distinguish between different models from that * family. * * The code also selects a default amount of video memory which we will @@ -2927,6 +2937,16 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) if (!counter_bits) gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE; } + if (!gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] && gl_info->supported[EXT_TEXTURE_MIRROR_CLAMP]) + { + TRACE(" IMPLIED: ATI_texture_mirror_once support (by EXT_texture_mirror_clamp).\n"); + gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] = TRUE; + } + if (!gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] && gl_info->supported[ATI_TEXTURE_MIRROR_ONCE]) + { + TRACE(" IMPLIED: ARB_texture_mirror_clamp_to_edge support (by ATI_texture_mirror_once).\n"); + gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] = TRUE; + } wined3d_adapter_init_limits(gl_info); @@ -3044,7 +3064,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) gl_info->wrap_lookup[WINED3D_TADDRESS_BORDER - WINED3D_TADDRESS_WRAP] = gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT; gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP] = - gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT; + gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] ? GL_MIRROR_CLAMP_TO_EDGE : GL_REPEAT; adapter->d3d_info.valid_rt_mask = 0; for (i = 0; i < gl_info->limits.buffers; ++i) @@ -3871,18 +3891,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; } - /* Filter formats that need conversion; For one part, this - * conversion is unimplemented, and volume textures are huge, so - * it would be a big performance hit. Unless we hit an application - * needing one of those formats, don't advertize them to avoid - * leading applications into temptation. The windows drivers don't - * support most of those formats on volumes anyway. */ - if (format->convert) - { - TRACE("[FAILED] - No converted formats on volumes.\n"); - return WINED3DERR_NOTAVAILABLE; - } - /* The GL_EXT_texture_compression_s3tc spec requires that loading * an s3tc compressed texture results in an error. While the D3D * refrast does support s3tc volumes, at least the nvidia Windows @@ -4095,7 +4103,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte struct shader_caps shader_caps; struct fragment_caps fragment_caps; struct wined3d_vertex_caps vertex_caps; - DWORD ckey_caps, blit_caps, fx_caps, pal_caps; + DWORD ckey_caps, blit_caps, fx_caps; TRACE("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n", wined3d, adapter_idx, debug_d3ddevicetype(device_type), caps); @@ -4356,7 +4364,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte { caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR; } - if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE]) + if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE]) { caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE; } @@ -4374,7 +4382,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte { caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR; } - if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE]) + if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE]) { caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE; } @@ -4619,8 +4627,6 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINEDDCAPS_COLORKEY | WINEDDCAPS_COLORKEYHWASSIST | WINEDDCAPS_ALIGNBOUNDARYSRC; - pal_caps = WINEDDPCAPS_8BIT | - WINEDDPCAPS_PRIMARYSURFACE; /* Fill the ddraw caps structure */ caps->ddraw_caps.caps = WINEDDCAPS_GDI | @@ -4633,7 +4639,6 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINEDDCAPS2_CANRENDERWINDOWED; caps->ddraw_caps.color_key_caps = ckey_caps; caps->ddraw_caps.fx_caps = fx_caps; - caps->ddraw_caps.pal_caps = pal_caps; caps->ddraw_caps.svb_caps = blit_caps; caps->ddraw_caps.svb_color_key_caps = ckey_caps; caps->ddraw_caps.svb_fx_caps = fx_caps; @@ -5027,11 +5032,10 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc } } -/* Do not call while under the GL lock. */ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) { struct wined3d_gl_info *gl_info = &adapter->gl_info; - struct wined3d_fake_gl_ctx fake_gl_ctx = {0}; + struct wined3d_caps_gl_ctx caps_gl_ctx = {0}; unsigned int ctx_attrib_idx = 0; DISPLAY_DEVICEW display_device; GLint ctx_attribs[3]; @@ -5074,7 +5078,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) TRACE("Allocated LUID %08x:%08x for adapter %p.\n", adapter->luid.HighPart, adapter->luid.LowPart, adapter); - if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx)) + if (!wined3d_caps_gl_ctx_create(&caps_gl_ctx)) { ERR("Failed to get a GL context for adapter %p.\n", adapter); return FALSE; @@ -5086,22 +5090,22 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_DEBUG_BIT_ARB; } ctx_attribs[ctx_attrib_idx] = 0; - wined3d_create_fake_gl_context_attribs(&fake_gl_ctx, gl_info, ctx_attribs); + wined3d_caps_gl_ctx_create_attribs(&caps_gl_ctx, gl_info, ctx_attribs); if (!wined3d_adapter_init_gl_caps(adapter)) { ERR("Failed to initialize GL caps for adapter %p.\n", adapter); - WineD3D_ReleaseFakeGLContext(&fake_gl_ctx); + wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); return FALSE; } - wined3d_adapter_init_fb_cfgs(adapter, fake_gl_ctx.dc); + wined3d_adapter_init_fb_cfgs(adapter, caps_gl_ctx.dc); /* We haven't found any suitable formats. This should only happen in * case of GDI software rendering, which is pretty useless anyway. */ if (!adapter->cfg_count) { WARN("No suitable pixel formats found.\n"); - WineD3D_ReleaseFakeGLContext(&fake_gl_ctx); + wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); HeapFree(GetProcessHeap(), 0, adapter->cfgs); return FALSE; } @@ -5109,7 +5113,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) if (!wined3d_adapter_init_format_info(adapter)) { ERR("Failed to initialize GL format info.\n"); - WineD3D_ReleaseFakeGLContext(&fake_gl_ctx); + wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); HeapFree(GetProcessHeap(), 0, adapter->cfgs); return FALSE; } @@ -5123,7 +5127,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName)); strcpyW(adapter->DeviceName, display_device.DeviceName); - WineD3D_ReleaseFakeGLContext(&fake_gl_ctx); + wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); wined3d_adapter_init_ffp_attrib_ops(adapter); @@ -5166,7 +5170,6 @@ const struct wined3d_parent_ops wined3d_null_parent_ops = wined3d_null_wined3d_object_destroyed, }; -/* Do not call while under the GL lock. */ HRESULT wined3d_init(struct wined3d *wined3d, UINT version, DWORD flags) { wined3d->dxVersion = version; diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index 4d0f59bd61d..e2f087c8323 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -29,9 +29,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); -//#include -//#include - /* Context activation is done by the caller. */ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count) @@ -41,7 +38,7 @@ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primit GLenum idxtype = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; if (instance_count) { - if (!gl_info->supported[ARB_DRAW_INSTANCED]) + if (!gl_info->supported[ARB_DRAW_INSTANCED] && !gl_info->supported[ARB_INSTANCED_ARRAYS]) { FIXME("Instanced drawing not supported.\n"); } @@ -49,9 +46,18 @@ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primit { if (start_instance) FIXME("Start instance (%u) not supported.\n", start_instance); - GL_EXTCALL(glDrawElementsInstancedBaseVertex(primitive_type, count, idxtype, - (const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_index)); - checkGLcall("glDrawElementsInstancedBaseVertex"); + if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) + { + GL_EXTCALL(glDrawElementsInstancedBaseVertex(primitive_type, count, idxtype, + (const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_index)); + checkGLcall("glDrawElementsInstancedBaseVertex"); + } + else + { + GL_EXTCALL(glDrawElementsInstancedARB(primitive_type, count, idxtype, + (const char *)idx_data + (idx_size * start_idx), instance_count)); + checkGLcall("glDrawElementsInstancedARB"); + } } } else if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) @@ -80,7 +86,7 @@ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primit */ /* Context activation is done by the caller. */ -static void drawStridedSlow(const struct wined3d_device *device, const struct wined3d_context *context, +static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_context *context, const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, const void *idxData, UINT idxSize, UINT startIdx) { @@ -112,7 +118,7 @@ static void drawStridedSlow(const struct wined3d_device *device, const struct wi * supported or other reason), or with user pointer drawing idxData * will be non-NULL. */ if (!idxData) - idxData = buffer_get_sysmem(state->index_buffer, gl_info); + idxData = buffer_get_sysmem(state->index_buffer, context); if (idxSize == 2) pIdxBufS = idxData; else pIdxBufL = idxData; @@ -191,7 +197,7 @@ static void drawStridedSlow(const struct wined3d_device *device, const struct wi for (textureNo = 0; textureNo < texture_stages; ++textureNo) { int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX]; - DWORD texture_idx = device->texUnitMap[textureNo]; + DWORD texture_idx = context->tex_unit_map[textureNo]; if (!gl_info->supported[ARB_MULTITEXTURE] && textureNo > 0) { @@ -263,7 +269,7 @@ static void drawStridedSlow(const struct wined3d_device *device, const struct wi coord_idx = state->texture_states[texture][WINED3D_TSS_TEXCOORD_INDEX]; ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride); - texture_idx = device->texUnitMap[texture]; + texture_idx = context->tex_unit_map[texture]; ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx]( GL_TEXTURE0_ARB + texture_idx, ptr); } @@ -438,10 +444,11 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info, } /* Context activation is done by the caller. */ -static void drawStridedSlowVs(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, +static void drawStridedSlowVs(struct wined3d_context *context, const struct wined3d_state *state, const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT startIdx) { + const struct wined3d_gl_info *gl_info = context->gl_info; LONG SkipnStrides = startIdx + state->load_base_vertex_index; const DWORD *pIdxBufL = NULL; const WORD *pIdxBufS = NULL; @@ -456,7 +463,7 @@ static void drawStridedSlowVs(const struct wined3d_gl_info *gl_info, const struc * supported or other reason), or with user pointer drawing idxData * will be non-NULL. */ if (!idxData) - idxData = buffer_get_sysmem(state->index_buffer, gl_info); + idxData = buffer_get_sysmem(state->index_buffer, context); if (idxSize == 2) pIdxBufS = idxData; else pIdxBufL = idxData; @@ -494,10 +501,11 @@ static void drawStridedSlowVs(const struct wined3d_gl_info *gl_info, const struc } /* Context activation is done by the caller. */ -static void drawStridedInstanced(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, +static void drawStridedInstanced(struct wined3d_context *context, const struct wined3d_state *state, const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT startIdx, UINT base_vertex_index, UINT instance_count) { + const struct wined3d_gl_info *gl_info = context->gl_info; int numInstancedAttribs = 0, j; UINT instancedData[sizeof(si->elements) / sizeof(*si->elements) /* 16 */]; GLenum idxtype = idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; @@ -535,7 +543,7 @@ static void drawStridedInstanced(const struct wined3d_gl_info *gl_info, const st if (si->elements[instancedData[j]].data.buffer_object) { struct wined3d_buffer *vb = state->streams[si->elements[instancedData[j]].stream_idx].buffer; - ptr += (ULONG_PTR)buffer_get_sysmem(vb, gl_info); + ptr += (ULONG_PTR)buffer_get_sysmem(vb, context); } send_attribute(gl_info, si->elements[instancedData[j]].format->id, instancedData[j], ptr); @@ -556,7 +564,7 @@ static void drawStridedInstanced(const struct wined3d_gl_info *gl_info, const st } } -static void remove_vbos(const struct wined3d_gl_info *gl_info, +static void remove_vbos(struct wined3d_context *context, const struct wined3d_state *state, struct wined3d_stream_info *s) { unsigned int i; @@ -572,7 +580,7 @@ static void remove_vbos(const struct wined3d_gl_info *gl_info, { struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer; e->data.buffer_object = 0; - e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, gl_info)); + e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, context)); } } } @@ -602,15 +610,12 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co struct wined3d_surface *target = device->fb.render_targets[i]; if (target) { - surface_load_location(target, target->draw_binding, NULL); - surface_modify_location(target, target->draw_binding, TRUE); + surface_load_location(target, target->draw_binding); + surface_invalidate_location(target, ~target->draw_binding); } } } - /* Signals other modules that a drawing is in progress and the stateblock finalized */ - device->isInDraw = TRUE; - context = context_acquire(device, device->fb.render_targets[0]); if (!context->valid) { @@ -627,7 +632,8 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co * 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 ? device->fb.depth_stencil->draw_binding : SFLAG_INDRAWABLE; + DWORD location = context->render_offscreen ? + device->fb.depth_stencil->draw_binding : WINED3D_LOCATION_DRAWABLE; if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) { struct wined3d_surface *ds = device->fb.depth_stencil; @@ -636,7 +642,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co if (!context->render_offscreen && ds != device->onscreen_depth_stencil) device_switch_onscreen_ds(device, context, ds); - if (ds->flags & location) + if (ds->locations & location) SetRect(¤t_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); else SetRectEmpty(¤t_rect); @@ -659,7 +665,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co if (device->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) { struct wined3d_surface *ds = device->fb.depth_stencil; - DWORD location = context->render_offscreen ? ds->draw_binding : SFLAG_INDRAWABLE; + DWORD location = context->render_offscreen ? ds->draw_binding : WINED3D_LOCATION_DRAWABLE; surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); } @@ -673,15 +679,15 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co FIXME("Point sprite coordinate origin switching not supported.\n"); } - stream_info = &device->stream_info; - if (device->instance_count) - instance_count = device->instance_count; + stream_info = &context->stream_info; + if (context->instance_count) + instance_count = context->instance_count; if (indexed) { struct wined3d_buffer *index_buffer = state->index_buffer; if (!index_buffer->buffer_object || !stream_info->all_vbo) - idx_data = index_buffer->resource.allocatedMemory; + idx_data = index_buffer->resource.heap_memory; else { ib_query = index_buffer->query; @@ -723,13 +729,13 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co if (emulation) { - si_emulated = device->stream_info; - remove_vbos(gl_info, state, &si_emulated); + si_emulated = context->stream_info; + remove_vbos(context, state, &si_emulated); stream_info = &si_emulated; } } - if (device->useDrawStridedSlow || emulation) + if (context->use_immediate_mode_draw || emulation) { /* Immediate mode drawing. */ if (use_vs(state)) @@ -741,7 +747,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co else WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n"); - drawStridedSlowVs(gl_info, state, stream_info, index_count, + drawStridedSlowVs(context, state, stream_info, index_count, state->gl_primitive_type, idx_data, idx_size, start_idx); } else @@ -753,7 +759,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count) { /* Instancing emulation by mixing immediate mode and arrays. */ - drawStridedInstanced(gl_info, state, stream_info, index_count, state->gl_primitive_type, + drawStridedInstanced(context, state, stream_info, index_count, state->gl_primitive_type, idx_data, idx_size, start_idx, state->base_vertex_index, instance_count); } else @@ -764,9 +770,9 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co if (ib_query) wined3d_event_query_issue(ib_query, device); - for (i = 0; i < device->num_buffer_queries; ++i) + for (i = 0; i < context->num_buffer_queries; ++i) { - wined3d_event_query_issue(device->buffer_queries[i], device); + wined3d_event_query_issue(context->buffer_queries[i], device); } if (wined3d_settings.strict_draw_ordering) @@ -775,7 +781,4 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co context_release(context); TRACE("Done all gl drawing\n"); - - /* Control goes back to the device, stateblock values may change again */ - device->isInDraw = FALSE; } diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index f2ec1d797ae..2a18b8fa0bf 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -36,18 +36,11 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_constants); WINE_DECLARE_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(winediag); -#ifdef _MSC_VER -#define copysignf(x, y) ((x) < 0.0f ? -fabsf(y) : fabsf(y)) -#endif - #define WINED3D_GLSL_SAMPLE_PROJECTED 0x1 #define WINED3D_GLSL_SAMPLE_NPOT 0x2 #define WINED3D_GLSL_SAMPLE_LOD 0x4 #define WINED3D_GLSL_SAMPLE_GRAD 0x8 -static const float srgb_const0[] = {0.41666f, 1.055f, 0.055f, 12.92f}; /* pow, mul_high, sub_high, mul_low */ -static const float srgb_const1[] = {0.0031308f, 0.0f, 0.0f, 0.0f}; /* cmp */ - struct glsl_dst_param { char reg_name[150]; @@ -249,61 +242,14 @@ static const char *shader_glsl_get_prefix(enum wined3d_shader_type type) } } -/* This should be equivalent to using the %.8e format specifier, but always - * using '.' as decimal separator. This doesn't handle +/-INF or NAN, since - * the GLSL parser wouldn't be able to handle those anyway. */ -static void shader_glsl_ftoa(float value, char *s) -{ - int x, frac, exponent; - const char *sign = ""; - double d; - - d = value; - if (copysignf(1.0f, value) < 0.0f) - { - d = -d; - sign = "-"; - } - - if (d == 0.0f) - { - x = 0; - frac = 0; - exponent = 0; - } - else - { - double t, diff; - - exponent = floorf(log10f(d)); - d /= pow(10.0, exponent); - - x = d; - t = (d - x) * 100000000; - frac = t; - diff = t - frac; - - if ((diff > 0.5) || (diff == 0.5 && (frac & 1))) - { - if (++frac >= 100000000) - { - frac = 0; - ++x; - } - } - } - - sprintf(s, "%s%d.%08de%+03d", sign, x, frac, exponent); -} - static void shader_glsl_append_imm_vec4(struct wined3d_shader_buffer *buffer, const float *values) { - char str[4][16]; + char str[4][17]; - shader_glsl_ftoa(values[0], str[0]); - shader_glsl_ftoa(values[1], str[1]); - shader_glsl_ftoa(values[2], str[2]); - shader_glsl_ftoa(values[3], str[3]); + wined3d_ftoa(values[0], str[0]); + wined3d_ftoa(values[1], str[1]); + wined3d_ftoa(values[2], str[2]); + wined3d_ftoa(values[3], str[3]); shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]); } @@ -809,8 +755,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context const struct wined3d_state *state) { const struct glsl_context_data *ctx_data = context->shader_backend_data; - const struct wined3d_shader *vshader = state->vertex_shader; - const struct wined3d_shader *pshader = state->pixel_shader; + const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; + const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_priv *priv = shader_priv; float position_fixup[4]; @@ -1273,10 +1219,10 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont if (ps_args->srgb_correction) { shader_addline(buffer, "const vec4 srgb_const0 = "); - shader_glsl_append_imm_vec4(buffer, srgb_const0); + shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const0); shader_addline(buffer, ";\n"); shader_addline(buffer, "const vec4 srgb_const1 = "); - shader_glsl_append_imm_vec4(buffer, srgb_const1); + shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const1); shader_addline(buffer, ";\n"); } if (reg_maps->vpos || reg_maps->usesdsy) @@ -1463,7 +1409,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; const char *prefix = shader_glsl_get_prefix(version->type); struct glsl_src_param rel_param0, rel_param1; - char imm_str[4][16]; + char imm_str[4][17]; if (reg->idx[0].offset != ~0U && reg->idx[0].rel_addr) shader_glsl_add_src_param(ins, reg->idx[0].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param0); @@ -1659,7 +1605,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * switch (reg->data_type) { case WINED3D_DATA_FLOAT: - shader_glsl_ftoa(*(const float *)reg->immconst_data, register_name); + wined3d_ftoa(*(const float *)reg->immconst_data, register_name); break; case WINED3D_DATA_INT: sprintf(register_name, "%#x", reg->immconst_data[0]); @@ -1679,10 +1625,10 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * switch (reg->data_type) { case WINED3D_DATA_FLOAT: - shader_glsl_ftoa(*(const float *)®->immconst_data[0], imm_str[0]); - shader_glsl_ftoa(*(const float *)®->immconst_data[1], imm_str[1]); - shader_glsl_ftoa(*(const float *)®->immconst_data[2], imm_str[2]); - shader_glsl_ftoa(*(const float *)®->immconst_data[3], imm_str[3]); + wined3d_ftoa(*(const float *)®->immconst_data[0], imm_str[0]); + wined3d_ftoa(*(const float *)®->immconst_data[1], imm_str[1]); + wined3d_ftoa(*(const float *)®->immconst_data[2], imm_str[2]); + wined3d_ftoa(*(const float *)®->immconst_data[3], imm_str[3]); sprintf(register_name, "vec4(%s, %s, %s, %s)", imm_str[0], imm_str[1], imm_str[2], imm_str[3]); break; @@ -2636,33 +2582,6 @@ static void shader_glsl_pow(const struct wined3d_shader_instruction *ins) } } -/* Process the WINED3DSIO_LOG instruction in GLSL (dst = log2(|src0|)) - * Src0 is a scalar. Note that D3D uses the absolute of src0, while - * GLSL uses the value as-is. */ -static void shader_glsl_log(const struct wined3d_shader_instruction *ins) -{ - struct wined3d_shader_buffer *buffer = ins->ctx->buffer; - struct glsl_src_param src0_param; - DWORD dst_write_mask; - unsigned int dst_size; - - dst_write_mask = shader_glsl_append_dst(buffer, ins); - dst_size = shader_glsl_get_write_mask_size(dst_write_mask); - - shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param); - - if (dst_size > 1) - { - shader_addline(buffer, "vec%u(log2(abs(%s))));\n", - dst_size, src0_param.param_str); - } - else - { - shader_addline(buffer, "log2(abs(%s)));\n", - src0_param.param_str); - } -} - /* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins) { @@ -2680,7 +2599,6 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins) case WINED3DSIH_MAX: instruction = "max"; break; case WINED3DSIH_ABS: instruction = "abs"; break; case WINED3DSIH_FRC: instruction = "fract"; break; - case WINED3DSIH_EXP: instruction = "exp2"; break; case WINED3DSIH_DSX: instruction = "dFdx"; break; case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break; case WINED3DSIH_ROUND_NI: instruction = "floor"; break; @@ -2737,6 +2655,56 @@ static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins) } } +static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) +{ + struct wined3d_shader_buffer *buffer = ins->ctx->buffer; + struct glsl_src_param src0_param; + const char *prefix, *suffix; + unsigned int dst_size; + DWORD dst_write_mask; + + dst_write_mask = shader_glsl_append_dst(buffer, ins); + dst_size = shader_glsl_get_write_mask_size(dst_write_mask); + + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src0_param); + + switch (ins->handler_idx) + { + case WINED3DSIH_EXP: + case WINED3DSIH_EXPP: + prefix = "exp2("; + suffix = ")"; + break; + + case WINED3DSIH_LOG: + case WINED3DSIH_LOGP: + prefix = "log2(abs("; + suffix = "))"; + break; + + case WINED3DSIH_RCP: + prefix = "1.0 / "; + suffix = ""; + break; + + case WINED3DSIH_RSQ: + prefix = "inversesqrt(abs("; + suffix = "))"; + break; + + default: + prefix = ""; + suffix = ""; + FIXME("Unhandled instruction %#x.\n", ins->handler_idx); + break; + } + + if (dst_size > 1) + shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix); + else + shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix); +} + /** Process the WINED3DSIO_EXPP instruction in GLSL: * For shader model 1.x, do the following (and honor the writemask, so use a temporary variable): * dst.x = 2^(floor(src)) @@ -2748,14 +2716,13 @@ static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins) */ static void shader_glsl_expp(const struct wined3d_shader_instruction *ins) { - struct glsl_src_param src_param; - - shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param); - if (ins->ctx->reg_maps->shader_version.major < 2) { + struct glsl_src_param src_param; char dst_mask[6]; + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param); + shader_addline(ins->ctx->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str); shader_addline(ins->ctx->buffer, "tmp0.y = %s - floor(%s);\n", src_param.param_str, src_param.param_str); shader_addline(ins->ctx->buffer, "tmp0.z = exp2(%s);\n", src_param.param_str); @@ -2764,19 +2731,10 @@ static void shader_glsl_expp(const struct wined3d_shader_instruction *ins) shader_glsl_append_dst(ins->ctx->buffer, ins); shader_glsl_get_write_mask(&ins->dst[0], dst_mask); shader_addline(ins->ctx->buffer, "tmp0%s);\n", dst_mask); - } else { - DWORD write_mask; - unsigned int mask_size; - - write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins); - mask_size = shader_glsl_get_write_mask_size(write_mask); - - if (mask_size > 1) { - shader_addline(ins->ctx->buffer, "vec%d(exp2(%s)));\n", mask_size, src_param.param_str); - } else { - shader_addline(ins->ctx->buffer, "exp2(%s));\n", src_param.param_str); - } + return; } + + shader_glsl_scalar_op(ins); } static void shader_glsl_to_int(const struct wined3d_shader_instruction *ins) @@ -2813,53 +2771,6 @@ static void shader_glsl_to_float(const struct wined3d_shader_instruction *ins) shader_addline(buffer, "float(%s));\n", src_param.param_str); } -/** Process the RCP (reciprocal or inverse) opcode in GLSL (dst = 1 / src) */ -static void shader_glsl_rcp(const struct wined3d_shader_instruction *ins) -{ - struct glsl_src_param src_param; - DWORD write_mask; - unsigned int mask_size; - - write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins); - mask_size = shader_glsl_get_write_mask_size(write_mask); - shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param); - - if (mask_size > 1) - { - shader_addline(ins->ctx->buffer, "vec%u(1.0 / %s));\n", - mask_size, src_param.param_str); - } - else - { - shader_addline(ins->ctx->buffer, "1.0 / %s);\n", - src_param.param_str); - } -} - -static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins) -{ - struct wined3d_shader_buffer *buffer = ins->ctx->buffer; - struct glsl_src_param src_param; - DWORD write_mask; - unsigned int mask_size; - - write_mask = shader_glsl_append_dst(buffer, ins); - mask_size = shader_glsl_get_write_mask_size(write_mask); - - shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param); - - if (mask_size > 1) - { - shader_addline(buffer, "vec%u(inversesqrt(abs(%s))));\n", - mask_size, src_param.param_str); - } - else - { - shader_addline(buffer, "inversesqrt(abs(%s)));\n", - src_param.param_str); - } -} - /** Process signed comparison opcodes in GLSL. */ static void shader_glsl_compare(const struct wined3d_shader_instruction *ins) { @@ -4783,7 +4694,7 @@ static GLhandleARB find_glsl_vshader(const struct wined3d_context *context, { UINT i; DWORD new_size; - DWORD use_map = shader->device->stream_info.use_map; + DWORD use_map = context->stream_info.use_map; struct glsl_vs_compiled_shader *gl_shaders, *new_array; struct glsl_shader_private *shader_data; GLhandleARB ret; @@ -4938,7 +4849,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_shader_buffer *buffer if (!settings->normal) break; shader_addline(buffer, "dir = normalize(dir);\n"); - shader_addline(buffer, "diffuse += (max(0.0, dot(dir, normal))" + shader_addline(buffer, "diffuse += (clamp(dot(dir, normal), 0.0, 1.0)" " * gl_LightSource[%u].diffuse.xyz) / att;\n", i); if (settings->localviewer) shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); @@ -4963,7 +4874,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_shader_buffer *buffer shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz * att;\n", i); if (!settings->normal) break; - shader_addline(buffer, "diffuse += (max(0.0, dot(dir, normal))" + shader_addline(buffer, "diffuse += (clamp(dot(dir, normal), 0.0, 1.0)" " * gl_LightSource[%u].diffuse.xyz) * att;\n", i); if (settings->localviewer) shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); @@ -4978,7 +4889,8 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_shader_buffer *buffer if (!settings->normal) break; shader_addline(buffer, "dir = normalize(gl_LightSource[%u].position.xyz);\n", i); - shader_addline(buffer, "diffuse += max(0.0, dot(dir, normal)) * gl_LightSource[%u].diffuse.xyz;\n", i); + shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)" + " * gl_LightSource[%u].diffuse.xyz;\n", i); shader_addline(buffer, "t = dot(normal, gl_LightSource[%u].halfVector.xyz);\n", i); shader_addline(buffer, "if (t > 0.0) specular += pow(t, gl_FrontMaterial.shininess)" " * gl_LightSource[%u].specular;\n", i); @@ -5488,10 +5400,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf if (settings->sRGB_write) { shader_addline(buffer, "const vec4 srgb_const0 = "); - shader_glsl_append_imm_vec4(buffer, srgb_const0); + shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const0); shader_addline(buffer, ";\n"); shader_addline(buffer, "const vec4 srgb_const1 = "); - shader_glsl_append_imm_vec4(buffer, srgb_const1); + shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const1); shader_addline(buffer, ";\n"); } @@ -5505,7 +5417,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf { const char *texture_function, *coord_mask; char tex_reg_name[8]; - BOOL proj, clamp; + BOOL proj; if (!(tex_map & (1 << stage))) continue; @@ -5525,12 +5437,6 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf proj = TRUE; } - if (settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP - || settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE) - clamp = FALSE; - else - clamp = TRUE; - switch (settings->op[stage].tex_type) { case tex_1d: @@ -5622,12 +5528,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf shader_addline(buffer, "ret = gl_TexCoord[%u] + ret.xyxy;\n", stage); } - if (clamp) - shader_addline(buffer, "tex%u = clamp(%s(ps_sampler%u, ret.%s), 0.0, 1.0);\n", - stage, texture_function, stage, coord_mask); - else - shader_addline(buffer, "tex%u = %s(ps_sampler%u, ret.%s);\n", - stage, texture_function, stage, coord_mask); + shader_addline(buffer, "tex%u = %s(ps_sampler%u, ret.%s);\n", + stage, texture_function, stage, coord_mask); if (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE) shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n", @@ -5635,21 +5537,13 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf } else if (settings->op[stage].projected == proj_count3) { - if (clamp) - shader_addline(buffer, "tex%u = clamp(%s(ps_sampler%u, gl_TexCoord[%u].xyz), 0.0, 1.0);\n", - stage, texture_function, stage, stage); - else - shader_addline(buffer, "tex%u = %s(ps_sampler%u, gl_TexCoord[%u].xyz);\n", - stage, texture_function, stage, stage); + shader_addline(buffer, "tex%u = %s(ps_sampler%u, gl_TexCoord[%u].xyz);\n", + stage, texture_function, stage, stage); } else { - if (clamp) - shader_addline(buffer, "tex%u = clamp(%s(ps_sampler%u, gl_TexCoord[%u].%s), 0.0, 1.0);\n", - stage, texture_function, stage, stage, coord_mask); - else - shader_addline(buffer, "tex%u = %s(ps_sampler%u, gl_TexCoord[%u].%s);\n", - stage, texture_function, stage, stage, coord_mask); + shader_addline(buffer, "tex%u = %s(ps_sampler%u, gl_TexCoord[%u].%s);\n", + stage, texture_function, stage, stage, coord_mask); } sprintf(tex_reg_name, "tex%u", stage); @@ -5769,18 +5663,20 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info, - GLhandleARB program_id, struct glsl_vs_program *vs) + GLhandleARB program_id, struct glsl_vs_program *vs, unsigned int vs_c_count) { unsigned int i; char name[32]; vs->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * gl_info->limits.glsl_vs_float_constants); - for (i = 0; i < gl_info->limits.glsl_vs_float_constants; ++i) + for (i = 0; i < vs_c_count; ++i) { snprintf(name, sizeof(name), "vs_c[%u]", i); vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); } + memset(&vs->uniform_f_locations[vs_c_count], 0xff, + (gl_info->limits.glsl_vs_float_constants - vs_c_count) * sizeof(GLhandleARB)); for (i = 0; i < MAX_CONST_I; ++i) { @@ -5792,18 +5688,20 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * } static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info, - GLhandleARB program_id, struct glsl_ps_program *ps) + GLhandleARB program_id, struct glsl_ps_program *ps, unsigned int ps_c_count) { unsigned int i; char name[32]; ps->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * gl_info->limits.glsl_ps_float_constants); - for (i = 0; i < gl_info->limits.glsl_ps_float_constants; ++i) + for (i = 0; i < ps_c_count; ++i) { snprintf(name, sizeof(name), "ps_c[%u]", i); ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); } + memset(&ps->uniform_f_locations[ps_c_count], 0xff, + (gl_info->limits.glsl_ps_float_constants - ps_c_count) * sizeof(GLhandleARB)); for (i = 0; i < MAX_CONST_I; ++i) { @@ -5844,7 +5742,6 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const GLhandleARB gs_id = 0; GLhandleARB ps_id = 0; struct list *ps_list, *vs_list; - struct wined3d_device *device = context->swapchain->device; if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_VERTEX))) { @@ -5853,8 +5750,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (use_vs(state)) { - vshader = state->vertex_shader; - gshader = state->geometry_shader; + vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; + gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_GEOMETRY)) && ctx_data->glsl_program->gs.id) @@ -5866,13 +5763,13 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const else if (use_vs(state)) { struct vs_compile_args vs_compile_args; - vshader = state->vertex_shader; + vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; - find_vs_compile_args(state, vshader, &vs_compile_args); + find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args); vs_id = find_glsl_vshader(context, &priv->shader_buffer, vshader, &vs_compile_args); vs_list = &vshader->linked_programs; - if ((gshader = state->geometry_shader)) + if ((gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY])) gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, gshader); } else if (priv->vertex_pipe == &glsl_vertex_pipe) @@ -5880,7 +5777,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const struct glsl_ffp_vertex_shader *ffp_shader; struct wined3d_ffp_vs_settings settings; - wined3d_ffp_get_vs_settings(state, &device->stream_info, &settings); + wined3d_ffp_get_vs_settings(state, &context->stream_info, &settings); ffp_shader = shader_glsl_find_ffp_vertex_shader(priv, gl_info, &settings); vs_id = ffp_shader->id; vs_list = &ffp_shader->linked_programs; @@ -5892,13 +5789,13 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const ps_list = &ctx_data->glsl_program->ps.shader_entry; if (use_ps(state)) - pshader = state->pixel_shader; + pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; } else if (use_ps(state)) { struct ps_compile_args ps_compile_args; - pshader = state->pixel_shader; - find_ps_compile_args(state, pshader, &ps_compile_args); + pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; + find_ps_compile_args(state, pshader, context->stream_info.position_transformed, &ps_compile_args, gl_info); ps_id = find_glsl_pshader(context, &priv->shader_buffer, pshader, &ps_compile_args, &np2fixup_info); ps_list = &pshader->linked_programs; @@ -6017,8 +5914,10 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const GL_EXTCALL(glLinkProgramARB(programId)); shader_glsl_validate_link(gl_info, programId); - shader_glsl_init_vs_uniform_locations(gl_info, programId, &entry->vs); - shader_glsl_init_ps_uniform_locations(gl_info, programId, &entry->ps); + shader_glsl_init_vs_uniform_locations(gl_info, programId, &entry->vs, + vshader ? vshader->limits.constant_float : 0); + shader_glsl_init_ps_uniform_locations(gl_info, programId, &entry->ps, + pshader ? pshader->limits.constant_float : 0); checkGLcall("Find glsl program uniform locations"); if (pshader && pshader->reg_maps.shader_version.major >= 3 @@ -6044,8 +5943,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const * fixed function fragment processing setups. So once the program is linked these samplers * won't change. */ - shader_glsl_load_vsamplers(gl_info, device->texUnitMap, programId); - shader_glsl_load_psamplers(gl_info, device->texUnitMap, programId); + shader_glsl_load_vsamplers(gl_info, context->tex_unit_map, programId); + shader_glsl_load_psamplers(gl_info, context->tex_unit_map, programId); entry->constant_update_mask = 0; if (vshader) @@ -6731,7 +6630,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_ENDLOOP */ shader_glsl_end, /* WINED3DSIH_ENDREP */ shader_glsl_end, /* WINED3DSIH_EQ */ shader_glsl_relop, - /* WINED3DSIH_EXP */ shader_glsl_map2gl, + /* WINED3DSIH_EXP */ shader_glsl_scalar_op, /* WINED3DSIH_EXPP */ shader_glsl_expp, /* WINED3DSIH_FRC */ shader_glsl_map2gl, /* WINED3DSIH_FTOI */ shader_glsl_to_int, @@ -6746,8 +6645,8 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_LABEL */ shader_glsl_label, /* WINED3DSIH_LD */ NULL, /* WINED3DSIH_LIT */ shader_glsl_lit, - /* WINED3DSIH_LOG */ shader_glsl_log, - /* WINED3DSIH_LOGP */ shader_glsl_log, + /* WINED3DSIH_LOG */ shader_glsl_scalar_op, + /* WINED3DSIH_LOGP */ shader_glsl_scalar_op, /* WINED3DSIH_LOOP */ shader_glsl_loop, /* WINED3DSIH_LRP */ shader_glsl_lrp, /* WINED3DSIH_LT */ shader_glsl_relop, @@ -6767,11 +6666,11 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_NRM */ shader_glsl_nrm, /* WINED3DSIH_PHASE */ shader_glsl_nop, /* WINED3DSIH_POW */ shader_glsl_pow, - /* WINED3DSIH_RCP */ shader_glsl_rcp, + /* WINED3DSIH_RCP */ shader_glsl_scalar_op, /* WINED3DSIH_REP */ shader_glsl_rep, /* WINED3DSIH_RET */ shader_glsl_ret, /* WINED3DSIH_ROUND_NI */ shader_glsl_map2gl, - /* WINED3DSIH_RSQ */ shader_glsl_rsq, + /* WINED3DSIH_RSQ */ shader_glsl_scalar_op, /* WINED3DSIH_SAMPLE */ NULL, /* WINED3DSIH_SAMPLE_GRAD */ NULL, /* WINED3DSIH_SAMPLE_LOD */ NULL, @@ -6867,7 +6766,7 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, { caps->xyzrhw = TRUE; caps->max_active_lights = gl_info->limits.lights; - caps->max_vertex_blend_matrices = 0; + caps->max_vertex_blend_matrices = 1; caps->max_vertex_blend_matrix_index = 0; caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN | WINED3DVTXPCAPS_MATERIALSOURCE7 @@ -6949,7 +6848,7 @@ static void glsl_vertex_pipe_projection(struct wined3d_context *context, static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = { {STATE_VDECL, {STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, - {STATE_VSHADER, {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, {STATE_MATERIAL, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable }, WINED3D_GL_EXT_NONE }, /* Clip planes */ @@ -7258,86 +7157,86 @@ static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *cont static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = { {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, - {STATE_PIXELSHADER, {STATE_PIXELSHADER, glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_srgbwrite }, ARB_FRAMEBUFFER_SRGB}, - {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, diff --git a/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c b/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c index 7028c44921d..05c2d461c6a 100644 --- a/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c +++ b/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c @@ -167,7 +167,6 @@ void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d output = GL_SPARE0_NV; } - /* This is called by a state handler which has the gl lock held and a context for the thread */ switch (op) { case WINED3D_TOP_DISABLE: @@ -473,9 +472,8 @@ void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_device *device = context->swapchain->device; - BOOL tex_used = device->fixed_function_usage_map & (1 << stage); - DWORD mapped_stage = device->texUnitMap[stage]; + BOOL tex_used = context->fixed_function_usage_map & (1 << stage); + DWORD mapped_stage = context->tex_unit_map[stage]; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Setting color op for stage %u.\n", stage); @@ -495,16 +493,16 @@ static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_s context_active_texture(context, gl_info, mapped_stage); } - if (state->lowest_disabled_stage > 0) + if (context->lowest_disabled_stage > 0) { gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV); - GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, state->lowest_disabled_stage)); + GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, context->lowest_disabled_stage)); } else { gl_info->gl_ops.gl.p_glDisable(GL_REGISTER_COMBINERS_NV); } - if (stage >= state->lowest_disabled_stage) + if (stage >= context->lowest_disabled_stage) { TRACE("Stage disabled\n"); if (mapped_stage != WINED3D_UNMAPPED_STAGE) @@ -577,17 +575,33 @@ static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_s } } +static void nvrc_resultarg(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + + TRACE("Setting result arg for stage %u.\n", stage); + + if (!isStateDirty(context, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP))) + { + context_apply_state(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP)); + } + if (!isStateDirty(context, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP))) + { + context_apply_state(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP)); + } +} + static void nvts_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD sampler = state_id - STATE_SAMPLER(0); - DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler]; + DWORD mapped_stage = context->tex_unit_map[sampler]; /* No need to enable / disable anything here for unused samplers. The tex_colorop * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop * will take care of this business. */ if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return; - if (sampler >= state->lowest_disabled_stage) + if (sampler >= context->lowest_disabled_stage) return; if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) return; @@ -598,7 +612,7 @@ static void nvts_texdim(struct wined3d_context *context, const struct wined3d_st static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - DWORD mapped_stage = context->swapchain->device->texUnitMap[stage + 1]; + DWORD mapped_stage = context->tex_unit_map[stage + 1]; const struct wined3d_gl_info *gl_info = context->gl_info; float mat[2][2]; @@ -766,7 +780,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 }, { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), nvrc_resultarg }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -779,7 +793,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 }, { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), nvrc_resultarg }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -792,7 +806,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 }, { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), nvrc_resultarg }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -805,7 +819,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 }, { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), nvrc_resultarg }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -818,7 +832,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 }, { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), nvrc_resultarg }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -831,7 +845,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 }, { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), nvrc_resultarg }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -844,7 +858,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 }, { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), nvrc_resultarg }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -857,9 +871,9 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), nvrc_resultarg }, WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), apply_pixelshader }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), nvrc_texfactor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, diff --git a/reactos/dll/directx/wine/wined3d/palette.c b/reactos/dll/directx/wine/wined3d/palette.c index 1239b15ca3b..b78249a6aff 100644 --- a/reactos/dll/directx/wine/wined3d/palette.c +++ b/reactos/dll/directx/wine/wined3d/palette.c @@ -23,8 +23,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define SIZE_BITS (WINEDDPCAPS_1BIT | WINEDDPCAPS_2BIT | WINEDDPCAPS_4BIT | WINEDDPCAPS_8BIT) - ULONG CDECL wined3d_palette_incref(struct wined3d_palette *palette) { ULONG refcount = InterlockedIncrement(&palette->ref); @@ -49,31 +47,18 @@ ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette) return refcount; } -static WORD wined3d_palette_size(DWORD flags) -{ - switch (flags & SIZE_BITS) - { - case WINEDDPCAPS_1BIT: return 2; - case WINEDDPCAPS_2BIT: return 4; - case WINEDDPCAPS_4BIT: return 16; - case WINEDDPCAPS_8BIT: return 256; - default: - FIXME("Unhandled size bits %#x.\n", flags & SIZE_BITS); - return 256; - } -} - HRESULT CDECL wined3d_palette_get_entries(const struct wined3d_palette *palette, DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries) { TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n", palette, flags, start, count, entries); - if (flags) return WINED3DERR_INVALIDCALL; /* unchecked */ - if (start + count > wined3d_palette_size(palette->flags)) + if (flags) + return WINED3DERR_INVALIDCALL; /* unchecked */ + if (start > palette->palNumEntries || count > palette->palNumEntries - start) return WINED3DERR_INVALIDCALL; - if (palette->flags & WINEDDPCAPS_8BITENTRIES) + if (palette->flags & WINED3D_PALETTE_8BIT_ENTRIES) { BYTE *entry = (BYTE *)entries; unsigned int i; @@ -96,7 +81,7 @@ HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette, palette, flags, start, count, entries); TRACE("Palette flags: %#x.\n", palette->flags); - if (palette->flags & WINEDDPCAPS_8BITENTRIES) + if (palette->flags & WINED3D_PALETTE_8BIT_ENTRIES) { const BYTE *entry = (const BYTE *)entries; unsigned int i; @@ -109,9 +94,9 @@ HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette, memcpy(palette->palents + start, entries, count * sizeof(*palette->palents)); /* When WINEDDCAPS_ALLOW256 isn't set we need to override entry 0 with black and 255 with white */ - if (!(palette->flags & WINEDDPCAPS_ALLOW256)) + if (!(palette->flags & WINED3D_PALETTE_ALLOW_256)) { - TRACE("WINEDDPCAPS_ALLOW256 set, overriding palette entry 0 with black and 255 with white\n"); + TRACE("WINED3D_PALETTE_ALLOW_256 not set, overriding palette entry 0 with black and 255 with white.\n"); palette->palents[0].peRed = 0; palette->palents[0].peGreen = 0; palette->palents[0].peBlue = 0; @@ -139,31 +124,16 @@ HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette, return WINED3D_OK; } -DWORD CDECL wined3d_palette_get_flags(const struct wined3d_palette *palette) -{ - TRACE("palette %p.\n", palette); - - return palette->flags; -} - -void * CDECL wined3d_palette_get_parent(const struct wined3d_palette *palette) -{ - TRACE("palette %p.\n", palette); - - return palette->parent; -} - static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wined3d_device *device, - DWORD flags, const PALETTEENTRY *entries, void *parent) + DWORD flags, unsigned int entry_count, const PALETTEENTRY *entries) { HRESULT hr; palette->ref = 1; - palette->parent = parent; palette->device = device; palette->flags = flags; - palette->palNumEntries = wined3d_palette_size(flags); + palette->palNumEntries = entry_count; palette->hpal = CreatePalette((const LOGPALETTE *)&palette->palVersion); if (!palette->hpal) { @@ -171,8 +141,7 @@ static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wine return E_FAIL; } - hr = wined3d_palette_set_entries(palette, 0, 0, wined3d_palette_size(flags), entries); - if (FAILED(hr)) + if (FAILED(hr = wined3d_palette_set_entries(palette, 0, 0, entry_count, entries))) { WARN("Failed to set palette entries, hr %#x.\n", hr); DeleteObject(palette->hpal); @@ -183,20 +152,19 @@ static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wine } HRESULT CDECL wined3d_palette_create(struct wined3d_device *device, DWORD flags, - const PALETTEENTRY *entries, void *parent, struct wined3d_palette **palette) + unsigned int entry_count, const PALETTEENTRY *entries, struct wined3d_palette **palette) { struct wined3d_palette *object; HRESULT hr; - TRACE("device %p, flags %#x, entries %p, palette %p, parent %p.\n", - device, flags, entries, palette, parent); + TRACE("device %p, flags %#x, entries %p, palette %p.\n", + device, flags, entries, palette); object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) return E_OUTOFMEMORY; - hr = wined3d_palette_init(object, device, flags, entries, parent); - if (FAILED(hr)) + 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); diff --git a/reactos/dll/directx/wine/wined3d/query.c b/reactos/dll/directx/wine/wined3d/query.c index 8806c9a4e9d..becea1b76f8 100644 --- a/reactos/dll/directx/wine/wined3d/query.c +++ b/reactos/dll/directx/wine/wined3d/query.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); diff --git a/reactos/dll/directx/wine/wined3d/resource.c b/reactos/dll/directx/wine/wined3d/resource.c index a3fc9d00638..5c7bc8178e9 100644 --- a/reactos/dll/directx/wine/wined3d/resource.c +++ b/reactos/dll/directx/wine/wined3d/resource.c @@ -68,7 +68,8 @@ static void resource_check_usage(DWORD usage) | WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_AUTOGENMIPMAP | WINED3DUSAGE_STATICDECL - | WINED3DUSAGE_OVERLAY; + | WINED3DUSAGE_OVERLAY + | WINED3DUSAGE_TEXTURE; if (usage & ~handled) FIXME("Unhandled usage flags %#x.\n", usage & ~handled); @@ -83,6 +84,17 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * { const struct wined3d *d3d = device->wined3d; + resource_check_usage(usage); + if (pool != WINED3D_POOL_SCRATCH) + { + if ((usage & WINED3DUSAGE_RENDERTARGET) && !(format->flags & WINED3DFMT_FLAG_RENDERTARGET)) + return WINED3DERR_INVALIDCALL; + if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && !(format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) + return WINED3DERR_INVALIDCALL; + if ((usage & WINED3DUSAGE_TEXTURE) && !(format->flags & WINED3DFMT_FLAG_TEXTURE)) + return WINED3DERR_INVALIDCALL; + } + resource->ref = 1; resource->device = device; resource->type = type; @@ -104,22 +116,18 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource->resource_ops = resource_ops; list_init(&resource->privateData); - resource_check_usage(usage); - if (size) { - resource->heap_memory = wined3d_resource_allocate_sysmem(size); - if (!resource->heap_memory) + if (!wined3d_resource_allocate_sysmem(resource)) { - ERR("Out of memory!\n"); - return WINED3DERR_OUTOFVIDEOMEMORY; + ERR("Failed to allocate system memory.\n"); + return E_OUTOFMEMORY; } } else { resource->heap_memory = NULL; } - resource->allocatedMemory = resource->heap_memory; /* Check that we have enough video ram left */ if (pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) @@ -127,7 +135,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * if (size > wined3d_device_get_available_texture_mem(device)) { ERR("Out of adapter memory\n"); - wined3d_resource_free_sysmem(resource->heap_memory); + wined3d_resource_free_sysmem(resource); return WINED3DERR_OUTOFVIDEOMEMORY; } adapter_adjust_memory(device->adapter, size); @@ -161,9 +169,7 @@ void resource_cleanup(struct wined3d_resource *resource) ERR("Failed to free private data when destroying resource %p, hr = %#x.\n", resource, hr); } - wined3d_resource_free_sysmem(resource->heap_memory); - resource->allocatedMemory = NULL; - resource->heap_memory = NULL; + wined3d_resource_free_sysmem(resource); device_resource_released(resource->device, resource); } @@ -318,6 +324,11 @@ void * CDECL wined3d_resource_get_parent(const struct wined3d_resource *resource return resource->parent; } +void CDECL wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent) +{ + resource->parent = parent; +} + void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, struct wined3d_resource_desc *desc) { desc->resource_type = resource->type; @@ -332,29 +343,32 @@ void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, st desc->size = resource->size; } -void *wined3d_resource_allocate_sysmem(SIZE_T size) +BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) { void **p; SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p); void *mem; - if (!(mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + align))) - return NULL; + if (!(mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, resource->size + align))) + return FALSE; p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; *p = mem; - return ++p; + resource->heap_memory = ++p; + + return TRUE; } -void wined3d_resource_free_sysmem(void *mem) +void wined3d_resource_free_sysmem(struct wined3d_resource *resource) { - void **p = mem; + void **p = resource->heap_memory; - if (!mem) + if (!p) return; HeapFree(GetProcessHeap(), 0, *(--p)); + resource->heap_memory = NULL; } DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) @@ -406,3 +420,12 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) return ret; } + +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; +} diff --git a/reactos/dll/directx/wine/wined3d/shader.c b/reactos/dll/directx/wine/wined3d/shader.c index de86bc1f138..eb6264a15b1 100644 --- a/reactos/dll/directx/wine/wined3d/shader.c +++ b/reactos/dll/directx/wine/wined3d/shader.c @@ -26,6 +26,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); +/* pow, mul_high, sub_high, mul_low */ +const float wined3d_srgb_const0[] = {0.41666f, 1.055f, 0.055f, 12.92f}; +/* cmp */ +const float wined3d_srgb_const1[] = {0.0031308f, 0.0f, 0.0f, 0.0f}; + static const char * const shader_opcode_names[] = { /* WINED3DSIH_ABS */ "abs", @@ -1720,7 +1725,6 @@ ULONG CDECL wined3d_shader_incref(struct wined3d_shader *shader) return refcount; } -/* Do not call while under the GL lock. */ ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader) { ULONG refcount = InterlockedDecrement(&shader->ref); @@ -1806,14 +1810,14 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh return WINED3D_OK; } -void find_vs_compile_args(const struct wined3d_state *state, - const struct wined3d_shader *shader, struct vs_compile_args *args) +void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, + WORD swizzle_map, struct vs_compile_args *args) { args->fog_src = state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE ? VS_FOG_COORD : VS_FOG_Z; args->clip_enabled = state->render_states[WINED3D_RS_CLIPPING] && state->render_states[WINED3D_RS_CLIPPLANEENABLE]; - args->swizzle_map = shader->device->stream_info.swizzle_map; + args->swizzle_map = swizzle_map; } static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) @@ -2014,11 +2018,9 @@ static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d return WINED3D_OK; } -void find_ps_compile_args(const struct wined3d_state *state, - const struct wined3d_shader *shader, struct ps_compile_args *args) +void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, + BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_gl_info *gl_info) { - struct wined3d_device *device = shader->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_texture *texture; UINT i; @@ -2048,7 +2050,7 @@ void find_ps_compile_args(const struct wined3d_state *state, { DWORD tex_transform = flags & ~WINED3D_TTFF_PROJECTED; - if (!state->vertex_shader) + if (!state->shader[WINED3D_SHADER_TYPE_VERTEX]) { unsigned int j; unsigned int index = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; @@ -2147,7 +2149,7 @@ void find_ps_compile_args(const struct wined3d_state *state, } if (shader->reg_maps.shader_version.major >= 3) { - if (device->stream_info.position_transformed) + if (position_transformed) args->vp_mode = pretransformed; else if (use_vs(state)) args->vp_mode = vertexshader; @@ -2163,7 +2165,7 @@ void find_ps_compile_args(const struct wined3d_state *state, switch (state->render_states[WINED3D_RS_FOGTABLEMODE]) { case WINED3D_FOG_NONE: - if (device->stream_info.position_transformed || use_vs(state)) + if (position_transformed || use_vs(state)) { args->fog = WINED3D_FFP_PS_FOG_LINEAR; break; diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index 784907a72f9..327f153bb2b 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -79,7 +79,7 @@ static void state_lighting(struct wined3d_context *context, const struct wined3d return; if (state->render_states[WINED3D_RS_LIGHTING] - && !context->swapchain->device->stream_info.position_transformed) + && !context->stream_info.position_transformed) { gl_info->gl_ops.gl.p_glEnable(GL_LIGHTING); checkGLcall("glEnable GL_LIGHTING"); @@ -126,7 +126,7 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_ if (context->gl_info->supported[ARB_DEPTH_CLAMP]) { - if (!zenable && context->swapchain->device->stream_info.position_transformed) + if (!zenable && context->stream_info.position_transformed) { gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP); checkGLcall("glEnable(GL_DEPTH_CLAMP)"); @@ -523,19 +523,15 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); - /* Find out if the texture on the first stage has a ckey set - * The alpha state func reads the texture settings, even though alpha and texture are not grouped - * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly - * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha - * in case it finds some texture+colorkeyenable combination which needs extra care. - */ - if (state->textures[0]) - { - struct wined3d_surface *surface = surface_from_resource(state->textures[0]->sub_resources[0]); - - if (surface->CKeyFlags & WINEDDSD_CKSRCBLT) - enable_ckey = TRUE; - } + /* Find out if the texture on the first stage has a ckey set. The alpha + * state func reads the texture settings, even though alpha and texture + * are not grouped together. This is to avoid making a huge alpha + + * texture + texture stage + ckey block due to the hardly used + * WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture + * function will call alpha in case it finds some texture + colorkeyenable + * combination which needs extra care. */ + if (state->textures[0] && (state->textures[0]->color_key_flags & WINEDDSD_CKSRCBLT)) + enable_ckey = TRUE; if (enable_ckey || context->last_was_ckey) context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP)); @@ -811,18 +807,18 @@ static GLenum gl_stencil_op(enum wined3d_stencil_op op) static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD onesided_enable = FALSE; - DWORD twosided_enable = FALSE; - GLint func = GL_ALWAYS; - GLint func_ccw = GL_ALWAYS; - GLint ref = 0; - GLuint mask = 0; - GLint stencilFail = GL_KEEP; - GLint depthFail = GL_KEEP; - GLint stencilPass = GL_KEEP; - GLint stencilFail_ccw = GL_KEEP; - GLint depthFail_ccw = GL_KEEP; - GLint stencilPass_ccw = GL_KEEP; + DWORD onesided_enable; + DWORD twosided_enable; + GLint func; + GLint func_ccw; + GLint ref; + GLuint mask; + GLint stencilFail; + GLint stencilFail_ccw; + GLint stencilPass; + GLint stencilPass_ccw; + GLint depthFail; + GLint depthFail_ccw; /* No stencil test without a stencil buffer. */ if (!state->fb->depth_stencil) @@ -1242,7 +1238,6 @@ void state_fogdensity(struct wined3d_context *context, const struct wined3d_stat static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; GLenum Parm = 0; @@ -1255,7 +1250,7 @@ static void state_colormat(struct wined3d_context *context, const struct wined3d } context->num_untracked_materials = 0; - if ((device->stream_info.use_map & (1 << WINED3D_FFP_DIFFUSE)) + if ((context->stream_info.use_map & (1 << WINED3D_FFP_DIFFUSE)) && state->render_states[WINED3D_RS_COLORVERTEX]) { TRACE("diff %d, amb %d, emis %d, spec %d\n", @@ -1408,7 +1403,7 @@ static void state_normalize(struct wined3d_context *context, const struct wined3 * by zero and is not properly defined in opengl, so avoid it */ if (state->render_states[WINED3D_RS_NORMALIZENORMALS] - && (context->swapchain->device->stream_info.use_map & (1 << WINED3D_FFP_NORMAL))) + && (context->stream_info.use_map & (1 << WINED3D_FFP_NORMAL))) { gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE); checkGLcall("glEnable(GL_NORMALIZE);"); @@ -2083,18 +2078,17 @@ static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3); - /* This is called by a state handler which has the gl lock held and a context for the thread */ - - /* Note: Operations usually involve two ars, src0 and src1 and are operations of - the form (a1 a2). However, some of the more complex operations - take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added - in a third parameter called a0. Therefore these are operations of the form - a0 a1 a2, i.e., the new parameter goes to the front. - - However, below we treat the new (a0) parameter as src2/opr2, so in the actual - functions below, expect their syntax to differ slightly to those listed in the - manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2 - This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */ + /* Operations usually involve two args, src0 and src1 and are operations + * of the form (a1 a2). However, some of the more complex + * operations take 3 parameters. Instead of the (sensible) addition of a3, + * Microsoft added in a third parameter called a0. Therefore these are + * operations of the form a0 a1 a2. I.e., the new + * parameter goes to the front. + * + * However, below we treat the new (a0) parameter as src2/opr2, so in the + * actual functions below, expect their syntax to differ slightly to those + * listed in the manuals. I.e., replace arg1 with arg3, arg2 with arg1 and + * arg3 with arg2. This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP. */ if (isAlpha) { @@ -3124,9 +3118,8 @@ static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_device *device = context->swapchain->device; - BOOL tex_used = device->fixed_function_usage_map & (1 << stage); - DWORD mapped_stage = device->texUnitMap[stage]; + BOOL tex_used = context->fixed_function_usage_map & (1 << stage); + DWORD mapped_stage = context->tex_unit_map[stage]; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Setting color op for stage %d\n", stage); @@ -3146,7 +3139,7 @@ static void tex_colorop(struct wined3d_context *context, const struct wined3d_st context_active_texture(context, gl_info, mapped_stage); } - if (stage >= state->lowest_disabled_stage) + if (stage >= context->lowest_disabled_stage) { TRACE("Stage disabled\n"); if (mapped_stage != WINED3D_UNMAPPED_STAGE) @@ -3186,9 +3179,8 @@ static void tex_colorop(struct wined3d_context *context, const struct wined3d_st void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_device *device = context->swapchain->device; - BOOL tex_used = device->fixed_function_usage_map & (1 << stage); - DWORD mapped_stage = device->texUnitMap[stage]; + BOOL tex_used = context->fixed_function_usage_map & (1 << stage); + DWORD mapped_stage = context->tex_unit_map[stage]; const struct wined3d_gl_info *gl_info = context->gl_info; DWORD op, arg1, arg2, arg0; @@ -3216,9 +3208,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]); - - if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size) + if (texture->color_key_flags & WINEDDSD_CKSRCBLT && !texture->resource.format->alpha_size) { /* Color keying needs to pass alpha values from the texture through to have the alpha test work * properly. On the other hand applications can still use texture combiners apparently. This code @@ -3289,7 +3279,7 @@ void transform_texture(struct wined3d_context *context, const struct wined3d_sta DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); const struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD mapped_stage = device->texUnitMap[texUnit]; + DWORD mapped_stage = context->tex_unit_map[texUnit]; BOOL generated; int coordIdx; @@ -3310,8 +3300,8 @@ void transform_texture(struct wined3d_context *context, const struct wined3d_sta set_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0], state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS], generated, context->last_was_rhw, - device->stream_info.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)) - ? device->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id + context->stream_info.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)) + ? context->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id : WINED3DFMT_UNKNOWN, device->shader_backend->shader_has_ffp_proj_control(device->shader_priv)); @@ -3345,7 +3335,6 @@ static void unload_tex_coords(const struct wined3d_gl_info *gl_info) static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si, GLuint *curVBO, const struct wined3d_state *state) { - const struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int mapped_stage = 0; unsigned int textureNo = 0; @@ -3354,7 +3343,7 @@ static void load_tex_coords(const struct wined3d_context *context, const struct { int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX]; - mapped_stage = device->texUnitMap[textureNo]; + mapped_stage = context->tex_unit_map[textureNo]; if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue; if (mapped_stage >= gl_info->limits.texture_coords) @@ -3405,13 +3394,12 @@ static void load_tex_coords(const struct wined3d_context *context, const struct static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_device *device = context->swapchain->device; static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f }; static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f }; static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f }; static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f }; const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD mapped_stage = device->texUnitMap[stage]; + DWORD mapped_stage = context->tex_unit_map[stage]; if (mapped_stage == WINED3D_UNMAPPED_STAGE) { @@ -3574,7 +3562,7 @@ static void tex_coordindex(struct wined3d_context *context, const struct wined3d GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; unload_tex_coords(gl_info); - load_tex_coords(context, &device->stream_info, &curVBO, state); + load_tex_coords(context, &context->stream_info, &curVBO, state); } } @@ -3599,24 +3587,21 @@ void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_sta if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler))) { - const struct wined3d_device *device = context->swapchain->device; - if (texIsPow2) context->lastWasPow2Texture |= 1 << sampler; else context->lastWasPow2Texture &= ~(1 << sampler); transform_texture(context, state, - STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS)); + STATE_TEXTURESTAGE(context->tex_unit_map[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS)); } } } static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->swapchain->device; DWORD sampler = state_id - STATE_SAMPLER(0); - DWORD mapped_stage = device->texUnitMap[sampler]; + DWORD mapped_stage = context->tex_unit_map[sampler]; const struct wined3d_gl_info *gl_info = context->gl_info; union { float f; @@ -3645,7 +3630,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state struct wined3d_texture *texture = state->textures[sampler]; BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE]; - texture->texture_ops->texture_bind(texture, context, srgb); + wined3d_texture_bind(texture, context, srgb); wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info); if (gl_info->supported[EXT_TEXTURE_LOD_BIAS]) @@ -3656,7 +3641,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)"); } - if (!use_ps(state) && sampler < state->lowest_disabled_stage) + if (!use_ps(state) && sampler < context->lowest_disabled_stage) { if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler) { @@ -3672,7 +3657,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state } else { - if (sampler < state->lowest_disabled_stage) + if (sampler < context->lowest_disabled_stage) { /* TODO: What should I do with pixel shaders here ??? */ if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler) @@ -4061,13 +4046,12 @@ static void unload_numbered_arrays(struct wined3d_context *context) static void load_numbered_arrays(struct wined3d_context *context, const struct wined3d_stream_info *stream_info, const struct wined3d_state *state) { - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; int i; /* Default to no instancing */ - device->instance_count = 0; + context->instance_count = 0; for (i = 0; i < MAX_ATTRIBS; i++) { @@ -4077,7 +4061,7 @@ static void load_numbered_arrays(struct wined3d_context *context, { if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); - if (state->vertex_shader->reg_maps.input_registers & (1 << i)) + if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.input_registers & (1 << i)) GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f)); continue; } @@ -4086,8 +4070,8 @@ static void load_numbered_arrays(struct wined3d_context *context, if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) { - if (!device->instance_count) - device->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1; + if (!context->instance_count) + context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1; if (!gl_info->supported[ARB_INSTANCED_ARRAYS]) { @@ -4140,7 +4124,7 @@ static void load_numbered_arrays(struct wined3d_context *context, const BYTE *ptr = stream_info->elements[i].data.addr; if (stream_info->elements[i].data.buffer_object) { - ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info); + ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, context); } if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); @@ -4233,10 +4217,9 @@ static void load_numbered_arrays(struct wined3d_context *context, checkGLcall("Loading numbered arrays"); } -static void load_vertex_data(const struct wined3d_context *context, +static void load_vertex_data(struct wined3d_context *context, const struct wined3d_stream_info *si, const struct wined3d_state *state) { - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; const struct wined3d_stream_info_element *e; @@ -4244,7 +4227,7 @@ static void load_vertex_data(const struct wined3d_context *context, TRACE("Using fast vertex array code\n"); /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */ - device->instance_count = 0; + context->instance_count = 0; /* Blend Data ---------------------------------------------- */ if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT)) @@ -4471,9 +4454,8 @@ static void load_vertex_data(const struct wined3d_context *context, static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->swapchain->device; - BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow; - BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow; + BOOL load_numbered = use_vs(state) && !context->use_immediate_mode_draw; + BOOL load_named = !use_vs(state) && !context->use_immediate_mode_draw; if (isStateDirty(context, STATE_VDECL)) return; if (context->numberedArraysLoaded && !load_numbered) @@ -4491,13 +4473,13 @@ static void streamsrc(struct wined3d_context *context, const struct wined3d_stat if (load_numbered) { TRACE("Loading numbered arrays\n"); - load_numbered_arrays(context, &device->stream_info, state); + load_numbered_arrays(context, &context->stream_info, state); context->numberedArraysLoaded = TRUE; } else if (load_named) { TRACE("Loading vertex data\n"); - load_vertex_data(context, &device->stream_info, state); + load_vertex_data(context, &context->stream_info, state); context->namedArraysLoaded = TRUE; } } @@ -4511,7 +4493,6 @@ static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; BOOL useVertexShaderFunction = use_vs(state); BOOL updateFog = FALSE; @@ -4519,7 +4500,7 @@ void vertexdeclaration(struct wined3d_context *context, const struct wined3d_sta BOOL wasrhw = context->last_was_rhw; unsigned int i; - transformed = device->stream_info.position_transformed; + transformed = context->stream_info.position_transformed; if (transformed != context->last_was_rhw && !useVertexShaderFunction) updateFog = TRUE; @@ -4637,8 +4618,8 @@ void vertexdeclaration(struct wined3d_context *context, const struct wined3d_sta transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS)); } - if (use_ps(state) && state->pixel_shader->reg_maps.shader_version.major == 1 - && state->pixel_shader->reg_maps.shader_version.minor <= 3) + if (use_ps(state) && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.major == 1 + && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.minor <= 3) context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL; } @@ -4840,7 +4821,7 @@ static void scissorrect(struct wined3d_context *context, const struct wined3d_st static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_stream_info *stream_info = &context->swapchain->device->stream_info; + const struct wined3d_stream_info *stream_info = &context->stream_info; const struct wined3d_gl_info *gl_info = context->gl_info; if (!state->index_buffer || !stream_info->all_vbo) @@ -5097,15 +5078,15 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX }, { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE }, { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE }, - { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE }, - { STATE_GEOMETRY_SHADER, { STATE_GEOMETRY_SHADER, state_geometry_shader}, WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), context_state_drawbuf},WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), { STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), state_geometry_shader}, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; const struct StateEntryTemplate vp_ffp_states[] = { { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, - { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE }, /* Clip planes */ @@ -5583,8 +5564,8 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, - { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), apply_pixelshader }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, @@ -5833,9 +5814,9 @@ static void validate_state_table(struct StateEntry *state_table) STATE_VDECL, STATE_STREAMSRC, STATE_INDEXBUFFER, - STATE_VSHADER, - STATE_GEOMETRY_SHADER, - STATE_PIXELSHADER, + STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), + STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), + STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), STATE_VIEWPORT, STATE_LIGHT_TYPE, STATE_SCISSORRECT, diff --git a/reactos/dll/directx/wine/wined3d/stateblock.c b/reactos/dll/directx/wine/wined3d/stateblock.c index 9cb336d5f1e..d76f6d6d6b7 100644 --- a/reactos/dll/directx/wine/wined3d/stateblock.c +++ b/reactos/dll/directx/wine/wined3d/stateblock.c @@ -461,7 +461,7 @@ void state_unbind_resources(struct wined3d_state *state) struct wined3d_texture *texture; struct wined3d_buffer *buffer; struct wined3d_shader *shader; - unsigned int i; + unsigned int i, j; if ((decl = state->vertex_declaration)) { @@ -502,75 +502,30 @@ void state_unbind_resources(struct wined3d_state *state) wined3d_buffer_decref(buffer); } - if ((shader = state->vertex_shader)) + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) { - state->vertex_shader = NULL; - wined3d_shader_decref(shader); - } - - for (i = 0; i < MAX_CONSTANT_BUFFERS; ++i) - { - if ((buffer = state->vs_cb[i])) + if ((shader = state->shader[i])) { - state->vs_cb[i] = NULL; - wined3d_buffer_decref(buffer); + state->shader[i] = NULL; + wined3d_shader_decref(shader); } - } - for (i = 0; i < MAX_SAMPLER_OBJECTS; ++i) - { - if ((sampler = state->vs_sampler[i])) + for (j = 0; j < MAX_CONSTANT_BUFFERS; ++j) { - state->vs_sampler[i] = NULL; - wined3d_sampler_decref(sampler); + if ((buffer = state->cb[i][j])) + { + state->cb[i][j] = NULL; + wined3d_buffer_decref(buffer); + } } - } - if ((shader = state->geometry_shader)) - { - state->geometry_shader = NULL; - wined3d_shader_decref(shader); - } - - for (i = 0; i < MAX_CONSTANT_BUFFERS; ++i) - { - if ((buffer = state->gs_cb[i])) + for (j = 0; j < MAX_SAMPLER_OBJECTS; ++j) { - state->gs_cb[i] = NULL; - wined3d_buffer_decref(buffer); - } - } - - for (i = 0; i < MAX_SAMPLER_OBJECTS; ++i) - { - if ((sampler = state->gs_sampler[i])) - { - state->gs_sampler[i] = NULL; - wined3d_sampler_decref(sampler); - } - } - - if ((shader = state->pixel_shader)) - { - state->pixel_shader = NULL; - wined3d_shader_decref(shader); - } - - for (i = 0; i < MAX_SAMPLER_OBJECTS; ++i) - { - if ((sampler = state->ps_sampler[i])) - { - state->ps_sampler[i] = NULL; - wined3d_sampler_decref(sampler); - } - } - - for (i = 0; i < MAX_CONSTANT_BUFFERS; ++i) - { - if ((buffer = state->ps_cb[i])) - { - state->ps_cb[i] = NULL; - wined3d_buffer_decref(buffer); + if ((sampler = state->sampler[i][j])) + { + state->sampler[i][j] = NULL; + wined3d_sampler_decref(sampler); + } } } } @@ -579,7 +534,8 @@ void state_cleanup(struct wined3d_state *state) { unsigned int counter; - state_unbind_resources(state); + if (!(state->flags & WINED3D_STATE_NO_REF)) + state_unbind_resources(state); for (counter = 0; counter < LIGHTMAP_SIZE; ++counter) { @@ -596,29 +552,6 @@ void state_cleanup(struct wined3d_state *state) HeapFree(GetProcessHeap(), 0, state->ps_consts_f); } -HRESULT state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) -{ - unsigned int i; - - for (i = 0; i < LIGHTMAP_SIZE; i++) - { - list_init(&state->light_map[i]); - } - - if (!(state->vs_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - 4 * sizeof(float) * d3d_info->limits.vs_uniform_count))) - return E_OUTOFMEMORY; - - if (!(state->ps_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - 4 * sizeof(float) * d3d_info->limits.ps_uniform_count))) - { - HeapFree(GetProcessHeap(), 0, state->vs_consts_f); - return E_OUTOFMEMORY; - } - - return WINED3D_OK; -} - ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) { ULONG refcount = InterlockedDecrement(&stateblock->ref); @@ -706,16 +639,18 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) TRACE("Capturing state %p.\n", src_state); - if (stateblock->changed.vertexShader && stateblock->state.vertex_shader != src_state->vertex_shader) + if (stateblock->changed.vertexShader && stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX] + != src_state->shader[WINED3D_SHADER_TYPE_VERTEX]) { TRACE("Updating vertex shader from %p to %p\n", - stateblock->state.vertex_shader, src_state->vertex_shader); + stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX], + src_state->shader[WINED3D_SHADER_TYPE_VERTEX]); - if (src_state->vertex_shader) - wined3d_shader_incref(src_state->vertex_shader); - if (stateblock->state.vertex_shader) - wined3d_shader_decref(stateblock->state.vertex_shader); - stateblock->state.vertex_shader = src_state->vertex_shader; + if (src_state->shader[WINED3D_SHADER_TYPE_VERTEX]) + wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_VERTEX]); + if (stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]) + wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]); + stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX] = src_state->shader[WINED3D_SHADER_TYPE_VERTEX]; } /* Vertex shader float constants. */ @@ -970,13 +905,14 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) stateblock->state.sampler_states[stage][state] = src_state->sampler_states[stage][state]; } - if (stateblock->changed.pixelShader && stateblock->state.pixel_shader != src_state->pixel_shader) + if (stateblock->changed.pixelShader && stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL] + != src_state->shader[WINED3D_SHADER_TYPE_PIXEL]) { - if (src_state->pixel_shader) - wined3d_shader_incref(src_state->pixel_shader); - if (stateblock->state.pixel_shader) - wined3d_shader_decref(stateblock->state.pixel_shader); - stateblock->state.pixel_shader = src_state->pixel_shader; + if (src_state->shader[WINED3D_SHADER_TYPE_PIXEL]) + wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_PIXEL]); + if (stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]) + wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]); + stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL] = src_state->shader[WINED3D_SHADER_TYPE_PIXEL]; } wined3d_state_record_lights(&stateblock->state, src_state); @@ -1011,7 +947,7 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) TRACE("Applying stateblock %p to device %p.\n", stateblock, device); if (stateblock->changed.vertexShader) - wined3d_device_set_vertex_shader(device, stateblock->state.vertex_shader); + wined3d_device_set_vertex_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]); /* Vertex Shader Constants. */ for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i) @@ -1033,7 +969,7 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) apply_lights(device, &stateblock->state); if (stateblock->changed.pixelShader) - wined3d_device_set_pixel_shader(device, stateblock->state.pixel_shader); + wined3d_device_set_pixel_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]); /* Pixel Shader Constants. */ for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i) @@ -1153,22 +1089,11 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) wined3d_device_set_clip_plane(device, i, &stateblock->state.clip_planes[i]); } - stateblock->device->state.lowest_disabled_stage = MAX_TEXTURES - 1; - for (i = 0; i < MAX_TEXTURES - 1; ++i) - { - if (stateblock->device->state.texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE) - { - stateblock->device->state.lowest_disabled_stage = i; - break; - } - } - TRACE("Applied stateblock %p.\n", stateblock); } -void state_init_default(struct wined3d_state *state, struct wined3d_device *device) +static void state_init_default(struct wined3d_state *state, const struct wined3d_gl_info *gl_info) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; union { struct wined3d_line_pattern lp; @@ -1179,8 +1104,6 @@ void state_init_default(struct wined3d_state *state, struct wined3d_device *devi DWORD d; } tmpfloat; unsigned int i; - struct wined3d_swapchain *swapchain; - struct wined3d_surface *backbuffer; static const struct wined3d_matrix identity = {{{ 1.0f, 0.0f, 0.0f, 0.0f, @@ -1189,7 +1112,7 @@ void state_init_default(struct wined3d_state *state, struct wined3d_device *devi 0.0f, 0.0f, 0.0f, 1.0f, }}}; - TRACE("state %p, device %p.\n", state, device); + TRACE("state %p, gl_info %p.\n", state, gl_info); /* Set some of the defaults for lights, transforms etc */ state->transforms[WINED3D_TS_PROJECTION] = identity; @@ -1199,14 +1122,9 @@ void state_init_default(struct wined3d_state *state, struct wined3d_device *devi state->transforms[WINED3D_TS_WORLD_MATRIX(i)] = identity; } - state->fb = &device->fb; - TRACE("Render states\n"); /* Render states: */ - if (device->auto_depth_stencil) - state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_TRUE; - else - state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_FALSE; + state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_TRUE; state->render_states[WINED3D_RS_FILLMODE] = WINED3D_FILL_SOLID; state->render_states[WINED3D_RS_SHADEMODE] = WINED3D_SHADE_GOURAUD; lp.lp.repeat_factor = 0; @@ -1356,9 +1274,7 @@ void state_init_default(struct wined3d_state *state, struct wined3d_device *devi state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] = WINED3DTA_CURRENT; state->texture_states[i][WINED3D_TSS_RESULT_ARG] = WINED3DTA_CURRENT; } - state->lowest_disabled_stage = 1; - /* Sampler states*/ for (i = 0 ; i < MAX_COMBINED_SAMPLERS; ++i) { TRACE("Setting up default samplers states for sampler %u.\n", i); @@ -1378,38 +1294,37 @@ void state_init_default(struct wined3d_state *state, struct wined3d_device *devi /* TODO: Vertex offset in the presampled displacement map. */ state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0; } +} - for (i = 0; i < gl_info->limits.textures; ++i) +HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, + const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, + DWORD flags) +{ + unsigned int i; + + state->flags = flags; + state->fb = fb; + + for (i = 0; i < LIGHTMAP_SIZE; i++) { - state->textures[i] = NULL; + list_init(&state->light_map[i]); } - /* check the return values, because the GetBackBuffer call isn't valid for ddraw */ - if ((swapchain = wined3d_device_get_swapchain(device, 0))) + if (!(state->vs_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + 4 * sizeof(float) * d3d_info->limits.vs_uniform_count))) + return E_OUTOFMEMORY; + + if (!(state->ps_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + 4 * sizeof(float) * d3d_info->limits.ps_uniform_count))) { - if ((backbuffer = wined3d_swapchain_get_back_buffer(swapchain, 0, WINED3D_BACKBUFFER_TYPE_MONO))) - { - struct wined3d_resource_desc desc; - - wined3d_resource_get_desc(&backbuffer->resource, &desc); - - /* Set the default scissor rect values */ - state->scissor_rect.left = 0; - state->scissor_rect.right = desc.width; - state->scissor_rect.top = 0; - state->scissor_rect.bottom = desc.height; - } - - /* Set the default viewport */ - state->viewport.x = 0; - state->viewport.y = 0; - state->viewport.width = swapchain->desc.backbuffer_width; - state->viewport.height = swapchain->desc.backbuffer_height; - state->viewport.min_z = 0.0f; - state->viewport.max_z = 1.0f; + HeapFree(GetProcessHeap(), 0, state->vs_consts_f); + return E_OUTOFMEMORY; } - TRACE("Done.\n"); + if (flags & WINED3D_STATE_INIT_DEFAULT) + state_init_default(state, gl_info); + + return WINED3D_OK; } static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, @@ -1421,7 +1336,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, stateblock->ref = 1; stateblock->device = device; - if (FAILED(hr = state_init(&stateblock->state, d3d_info))) + if (FAILED(hr = state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0))) return hr; if (FAILED(hr = stateblock_allocate_shader_constants(stateblock))) diff --git a/reactos/dll/directx/wine/wined3d/surface.c b/reactos/dll/directx/wine/wined3d/surface.c index ddf4cbf74f0..aea626d7c1c 100644 --- a/reactos/dll/directx/wine/wined3d/surface.c +++ b/reactos/dll/directx/wine/wined3d/surface.c @@ -6,7 +6,7 @@ * Copyright 2002-2003 Raphael Junqueira * Copyright 2004 Christian Costa * Copyright 2005 Oliver Stieber - * Copyright 2006-2011, 2013 Stefan Dösinger for CodeWeavers + * Copyright 2006-2011, 2013-2014 Stefan Dösinger for CodeWeavers * Copyright 2007-2008 Henri Verbeet * Copyright 2006-2008 Roderick Colenbrander * Copyright 2009-2011 Henri Verbeet for CodeWeavers @@ -32,12 +32,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(d3d); -static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter); -static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, - enum wined3d_texture_filter_type filter); +#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ + +static const DWORD surface_simple_locations = + WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY + | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; static void surface_cleanup(struct wined3d_surface *surface) { @@ -45,9 +44,8 @@ static void surface_cleanup(struct wined3d_surface *surface) TRACE("surface %p.\n", surface); - if (surface->texture_name || (surface->flags & SFLAG_PBO) - || surface->rb_multisample || surface->rb_resolved - || !list_empty(&surface->renderbuffers)) + if (surface->pbo || surface->rb_multisample + || surface->rb_resolved || !list_empty(&surface->renderbuffers)) { struct wined3d_renderbuffer_entry *entry, *entry2; const struct wined3d_gl_info *gl_info; @@ -56,13 +54,7 @@ static void surface_cleanup(struct wined3d_surface *surface) context = context_acquire(surface->resource.device, NULL); gl_info = context->gl_info; - if (surface->texture_name) - { - TRACE("Deleting texture %u.\n", surface->texture_name); - gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name); - } - - if (surface->flags & SFLAG_PBO) + if (surface->pbo) { TRACE("Deleting PBO %u.\n", surface->pbo); GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo)); @@ -95,11 +87,8 @@ static void surface_cleanup(struct wined3d_surface *surface) DeleteDC(surface->hDC); DeleteObject(surface->dib.DIBsection); surface->dib.bitmap_data = NULL; - surface->resource.allocatedMemory = NULL; } - if (surface->flags & SFLAG_USERPTR) - wined3d_surface_set_mem(surface, NULL, 0); if (surface->overlay_dest) list_remove(&surface->overlay_entry); @@ -115,11 +104,11 @@ static void surface_cleanup(struct wined3d_surface *surface) void surface_update_draw_binding(struct wined3d_surface *surface) { if (!surface_is_offscreen(surface) || wined3d_settings.offscreen_rendering_mode != ORM_FBO) - surface->draw_binding = SFLAG_INDRAWABLE; + surface->draw_binding = WINED3D_LOCATION_DRAWABLE; else if (surface->resource.multisample_type) - surface->draw_binding = SFLAG_INRB_MULTISAMPLE; + surface->draw_binding = WINED3D_LOCATION_RB_MULTISAMPLE; else - surface->draw_binding = SFLAG_INTEXTURE; + surface->draw_binding = WINED3D_LOCATION_TEXTURE_RGB; } void surface_set_swapchain(struct wined3d_surface *surface, struct wined3d_swapchain *swapchain) @@ -335,6 +324,7 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3 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, src_surface->pow2Width, src_surface->pow2Height, &info); @@ -342,7 +332,7 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3 gl_info->gl_ops.gl.p_glEnable(info.bind_target); checkGLcall("glEnable(bind_target)"); - context_bind_texture(context, info.bind_target, src_surface->texture_name); + context_bind_texture(context, info.bind_target, texture->texture_rgb.name); /* Filtering for StretchRect */ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, @@ -378,14 +368,10 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3 /* We changed the filtering settings on the texture. Inform the * container about this to get the filters reset properly next draw. */ - if (src_surface->container) - { - struct wined3d_texture *texture = src_surface->container; - texture->texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT; - texture->texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; - texture->texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE; - texture->texture_rgb.states[WINED3DTEXSTA_SRGBTEXTURE] = FALSE; - } + texture->texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT; + texture->texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; + texture->texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE; + texture->texture_rgb.states[WINED3DTEXSTA_SRGBTEXTURE] = FALSE; } /* Works correctly only for <= 4 bpp formats. */ @@ -503,17 +489,6 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface) } TRACE("DIBSection at %p.\n", surface->dib.bitmap_data); - /* Copy the existing surface to the dib section. */ - if (surface->resource.allocatedMemory) - { - memcpy(surface->dib.bitmap_data, surface->resource.allocatedMemory, - surface->resource.height * wined3d_surface_get_pitch(surface)); - } - else - { - /* This is to make maps read the GL texture although memory is allocated. */ - surface->flags &= ~SFLAG_INSYSMEM; - } surface->dib.bitmap_size = b_info->bmiHeader.biSizeImage; HeapFree(GetProcessHeap(), 0, b_info); @@ -529,26 +504,50 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface) return WINED3D_OK; } -static BOOL surface_need_pbo(const struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) +static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data, + DWORD location) { - if (surface->resource.pool == WINED3D_POOL_SYSTEM_MEM) - return FALSE; - if (!(surface->flags & SFLAG_DYNLOCK)) - return FALSE; - if (surface->flags & (SFLAG_CONVERTED | SFLAG_NONPOW2 | SFLAG_PIN_SYSMEM)) - return FALSE; - if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) - return FALSE; + if (location & WINED3D_LOCATION_BUFFER) + { + data->addr = NULL; + data->buffer_object = surface->pbo; + return; + } + if (location & WINED3D_LOCATION_USER_MEMORY) + { + data->addr = surface->user_memory; + data->buffer_object = 0; + return; + } + if (location & WINED3D_LOCATION_DIB) + { + data->addr = surface->dib.bitmap_data; + data->buffer_object = 0; + return; + } + if (location & WINED3D_LOCATION_SYSMEM) + { + data->addr = surface->resource.heap_memory; + data->buffer_object = 0; + return; + } - return TRUE; + ERR("Unexpected locations %s.\n", wined3d_debug_location(location)); + data->addr = NULL; + data->buffer_object = 0; } -static void surface_load_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) +static void surface_prepare_buffer(struct wined3d_surface *surface) { struct wined3d_context *context; GLenum error; + const struct wined3d_gl_info *gl_info; + + if (surface->pbo) + return; context = context_acquire(surface->resource.device, NULL); + gl_info = context->gl_info; GL_EXTCALL(glGenBuffersARB(1, &surface->pbo)); error = gl_info->gl_ops.gl.p_glGetError(); @@ -561,124 +560,65 @@ static void surface_load_pbo(struct wined3d_surface *surface, const struct wined checkGLcall("glBindBufferARB"); GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->resource.size + 4, - surface->resource.allocatedMemory, GL_STREAM_DRAW_ARB)); + NULL, GL_STREAM_DRAW_ARB)); checkGLcall("glBufferDataARB"); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); checkGLcall("glBindBufferARB"); - /* We don't need the system memory anymore and we can't even use it for PBOs. */ - if (!(surface->flags & SFLAG_CLIENT)) - { - wined3d_resource_free_sysmem(surface->resource.heap_memory); - surface->resource.heap_memory = NULL; - } - surface->resource.allocatedMemory = NULL; - surface->flags |= SFLAG_PBO; context_release(context); } static void surface_prepare_system_memory(struct wined3d_surface *surface) { - const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; - TRACE("surface %p.\n", surface); - if (!(surface->flags & SFLAG_PBO) && surface_need_pbo(surface, gl_info)) - surface_load_pbo(surface, gl_info); - else if (!(surface->resource.allocatedMemory || surface->flags & SFLAG_PBO)) + if (surface->resource.heap_memory) + return; + + /* Whatever surface we have, make sure that there is memory allocated + * for the downloaded copy, or a PBO to map. */ + if (!wined3d_resource_allocate_sysmem(&surface->resource)) + ERR("Failed to allocate system memory.\n"); + + if (surface->locations & WINED3D_LOCATION_SYSMEM) + ERR("Surface without system memory has WINED3D_LOCATION_SYSMEM set.\n"); +} + +void surface_prepare_map_memory(struct wined3d_surface *surface) +{ + switch (surface->map_binding) { - /* Whatever surface we have, make sure that there is memory allocated - * for the downloaded copy, or a PBO to map. */ - if (!surface->resource.heap_memory) - surface->resource.heap_memory = wined3d_resource_allocate_sysmem(surface->resource.size); + case WINED3D_LOCATION_SYSMEM: + surface_prepare_system_memory(surface); + break; - surface->resource.allocatedMemory = surface->resource.heap_memory; + case WINED3D_LOCATION_USER_MEMORY: + if (!surface->user_memory) + ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n"); + break; - if (surface->flags & SFLAG_INSYSMEM) - ERR("Surface without memory or PBO has SFLAG_INSYSMEM set.\n"); + case WINED3D_LOCATION_DIB: + if (!surface->dib.bitmap_data) + ERR("Map binding is set to WINED3D_LOCATION_DIB but surface->dib.bitmap_data is NULL.\n"); + break; + + case WINED3D_LOCATION_BUFFER: + surface_prepare_buffer(surface); + break; + + default: + ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->map_binding)); } } static void surface_evict_sysmem(struct wined3d_surface *surface) { - if (surface->resource.map_count || (surface->flags & SFLAG_DONOTFREE)) + if (surface->resource.map_count || surface->flags & SFLAG_DONOTFREE) return; - wined3d_resource_free_sysmem(surface->resource.heap_memory); - surface->resource.allocatedMemory = NULL; - surface->resource.heap_memory = NULL; - surface_modify_location(surface, SFLAG_INSYSMEM, FALSE); -} - -/* Context activation is done by the caller. */ -static void surface_bind(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) -{ - TRACE("surface %p, context %p, srgb %#x.\n", surface, context, srgb); - - if (surface->container) - { - struct wined3d_texture *texture = surface->container; - - TRACE("Passing to container (%p).\n", texture); - texture->texture_ops->texture_bind(texture, context, srgb); - } - else - { - const struct wined3d_gl_info *gl_info = context->gl_info; - - if (surface->texture_level) - { - ERR("Standalone surface %p is non-zero texture level %u.\n", - surface, surface->texture_level); - } - - if (srgb) - ERR("Trying to bind standalone surface %p as sRGB.\n", surface); - - if (!surface->texture_name) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &surface->texture_name); - checkGLcall("glGenTextures"); - - TRACE("Surface %p given name %u.\n", surface, surface->texture_name); - - context_bind_texture(context, surface->texture_target, surface->texture_name); - gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); - } - else - { - context_bind_texture(context, surface->texture_target, surface->texture_name); - } - } -} - -/* Context activation is done by the caller. */ -static void surface_bind_and_dirtify(struct wined3d_surface *surface, - struct wined3d_context *context, BOOL srgb) -{ - struct wined3d_device *device = surface->resource.device; - DWORD active_sampler; - - /* We don't need a specific texture unit, but after binding the texture - * the current unit is dirty. Read the unit back instead of switching to - * 0, this avoids messing around with the state manager's GL states. The - * current texture unit should always be a valid one. - * - * To be more specific, this is tricky because we can implicitly be - * called from sampler() in state.c. This means we can't touch anything - * other than whatever happens to be the currently active texture, or we - * would risk marking already applied sampler states dirty again. */ - active_sampler = device->rev_tex_unit_map[context->active_texture]; - - if (active_sampler != WINED3D_UNMAPPED_STAGE) - device_invalidate_state(device, STATE_SAMPLER(active_sampler)); - surface_bind(surface, context, srgb); + wined3d_resource_free_sysmem(&surface->resource); + surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); } static void surface_force_reload(struct wined3d_surface *surface) @@ -691,26 +631,36 @@ static void surface_release_client_storage(struct wined3d_surface *surface) struct wined3d_context *context = context_acquire(surface->resource.device, NULL); const struct wined3d_gl_info *gl_info = context->gl_info; - if (surface->texture_name) + if (surface->container->texture_rgb.name) { - surface_bind_and_dirtify(surface, context, FALSE); + wined3d_texture_bind_and_dirtify(surface->container, context, FALSE); gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); } - if (surface->texture_name_srgb) + if (surface->container->texture_srgb.name) { - surface_bind_and_dirtify(surface, context, TRUE); + wined3d_texture_bind_and_dirtify(surface->container, context, TRUE); gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); } context_release(context); - surface_modify_location(surface, SFLAG_INSRGBTEX, FALSE); - surface_modify_location(surface, SFLAG_INTEXTURE, FALSE); + surface_invalidate_location(surface, WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB); surface_force_reload(surface); } +static BOOL surface_use_pbo(const struct wined3d_surface *surface) +{ + const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; + + return surface->resource.pool == WINED3D_POOL_DEFAULT + && surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU + && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] + && !surface->resource.format->convert + && !(surface->flags & (SFLAG_NONPOW2 | SFLAG_PIN_SYSMEM)); +} + static HRESULT surface_private_setup(struct wined3d_surface *surface) { /* TODO: Check against the maximum texture sizes supported by the video card. */ @@ -719,7 +669,6 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) TRACE("surface %p.\n", surface); - surface->texture_name = 0; surface->texture_target = GL_TEXTURE_2D; /* Non-power2 support */ @@ -797,7 +746,10 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) } if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) - surface->flags |= SFLAG_DISCARDED; + surface->locations = WINED3D_LOCATION_DISCARDED; + + if (surface_use_pbo(surface)) + surface->map_binding = WINED3D_LOCATION_BUFFER; return WINED3D_OK; } @@ -817,20 +769,21 @@ static void surface_realize_palette(struct wined3d_surface *surface) { /* Make sure the texture is up to date. This call doesn't do * anything if the texture is already up to date. */ - surface_load_location(surface, SFLAG_INTEXTURE, NULL); + surface_load_location(surface, WINED3D_LOCATION_TEXTURE_RGB); /* We want to force a palette refresh, so mark the drawable as not being up to date */ if (!surface_is_offscreen(surface)) - surface_modify_location(surface, SFLAG_INDRAWABLE, FALSE); + surface_invalidate_location(surface, WINED3D_LOCATION_DRAWABLE); } else { - if (!(surface->flags & SFLAG_INSYSMEM)) + if (!(surface->locations & surface->map_binding)) { TRACE("Palette changed with surface that does not have an up to date system memory copy.\n"); - surface_load_location(surface, SFLAG_INSYSMEM, NULL); + surface_prepare_map_memory(surface); + surface_load_location(surface, surface->map_binding); } - surface_modify_location(surface, SFLAG_INSYSMEM, TRUE); + surface_invalidate_location(surface, ~surface->map_binding); } } @@ -853,184 +806,51 @@ static void surface_realize_palette(struct wined3d_surface *surface) /* Propagate the changes to the drawable when we have a palette. */ if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET) - surface_load_location(surface, surface->draw_binding, NULL); -} - -static HRESULT surface_draw_overlay(struct wined3d_surface *surface) -{ - HRESULT hr; - - /* If there's no destination surface there is nothing to do. */ - if (!surface->overlay_dest) - return WINED3D_OK; - - /* Blt calls ModifyLocation on the dest surface, which in turn calls - * DrawOverlay to update the overlay. Prevent an endless recursion. */ - if (surface->overlay_dest->flags & SFLAG_INOVERLAYDRAW) - return WINED3D_OK; - - surface->overlay_dest->flags |= SFLAG_INOVERLAYDRAW; - hr = wined3d_surface_blt(surface->overlay_dest, &surface->overlay_destrect, surface, - &surface->overlay_srcrect, WINEDDBLT_WAIT, NULL, WINED3D_TEXF_LINEAR); - surface->overlay_dest->flags &= ~SFLAG_INOVERLAYDRAW; - - return hr; -} - -static void surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD flags) -{ - struct wined3d_device *device = surface->resource.device; - const RECT *pass_rect = rect; - - TRACE("surface %p, rect %s, flags %#x.\n", - surface, wine_dbgstr_rect(rect), flags); - - if (flags & WINED3D_MAP_DISCARD) - { - TRACE("WINED3D_MAP_DISCARD flag passed, marking SYSMEM as up to date.\n"); - surface_prepare_system_memory(surface); - surface_modify_location(surface, SFLAG_INSYSMEM, TRUE); - } - else - { - if (surface->resource.usage & WINED3DUSAGE_DYNAMIC) - WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n"); - - /* surface_load_location() does not check if the rectangle specifies - * the full surface. Most callers don't need that, so do it here. */ - if (rect && !rect->top && !rect->left - && rect->right == surface->resource.width - && rect->bottom == surface->resource.height) - pass_rect = NULL; - surface_load_location(surface, SFLAG_INSYSMEM, pass_rect); - } - - if (surface->flags & SFLAG_PBO) - { - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - context = context_acquire(device, NULL); - gl_info = context->gl_info; - - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); - checkGLcall("glBindBufferARB"); - - /* This shouldn't happen but could occur if some other function - * didn't handle the PBO properly. */ - if (surface->resource.allocatedMemory) - ERR("The surface already has PBO memory allocated.\n"); - - surface->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB)); - checkGLcall("glMapBufferARB"); - - /* Make sure the PBO isn't set anymore in order not to break non-PBO - * calls. */ - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); - checkGLcall("glBindBufferARB"); - - context_release(context); - } - - if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) - { - if (!rect) - surface_add_dirty_rect(surface, NULL); - else - { - struct wined3d_box b; - - b.left = rect->left; - b.top = rect->top; - b.right = rect->right; - b.bottom = rect->bottom; - b.front = 0; - b.back = 1; - surface_add_dirty_rect(surface, &b); - } - } + surface_load_location(surface, surface->draw_binding); } static void surface_unmap(struct wined3d_surface *surface) { struct wined3d_device *device = surface->resource.device; - BOOL fullsurface; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; TRACE("surface %p.\n", surface); memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); - if (surface->flags & SFLAG_PBO) + switch (surface->map_binding) { - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + case WINED3D_LOCATION_SYSMEM: + case WINED3D_LOCATION_USER_MEMORY: + case WINED3D_LOCATION_DIB: + break; - TRACE("Freeing PBO memory.\n"); + case WINED3D_LOCATION_BUFFER: + context = context_acquire(device, NULL); + gl_info = context->gl_info; - context = context_acquire(device, NULL); - gl_info = context->gl_info; + GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); + GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + checkGLcall("glUnmapBufferARB"); + context_release(context); + break; - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); - GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); - checkGLcall("glUnmapBufferARB"); - context_release(context); - - surface->resource.allocatedMemory = NULL; + default: + ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->map_binding)); } - TRACE("dirtyfied %u.\n", surface->flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1); - - if (surface->flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE)) + if (surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)) { TRACE("Not dirtified, nothing to do.\n"); - goto done; + return; } if (surface->swapchain && surface->swapchain->front_buffer == surface) - { - if (!surface->dirtyRect.left && !surface->dirtyRect.top - && surface->dirtyRect.right == surface->resource.width - && surface->dirtyRect.bottom == surface->resource.height) - { - fullsurface = TRUE; - } - else - { - /* TODO: Proper partial rectangle tracking. */ - fullsurface = FALSE; - surface->flags |= SFLAG_INSYSMEM; - } - - surface_load_location(surface, surface->draw_binding, fullsurface ? NULL : &surface->dirtyRect); - - /* Partial rectangle tracking is not commonly implemented, it is only - * done for render targets. INSYSMEM was set before to tell - * surface_load_location() where to read the rectangle from. - * Indrawable is set because all modifications from the partial - * sysmem copy are written back to the drawable, thus the surface is - * merged again in the drawable. The sysmem copy is not fully up to - * date because only a subrectangle was read in Map(). */ - if (!fullsurface) - { - surface_modify_location(surface, surface->draw_binding, TRUE); - surface_evict_sysmem(surface); - } - - surface->dirtyRect.left = surface->resource.width; - surface->dirtyRect.top = surface->resource.height; - surface->dirtyRect.right = 0; - surface->dirtyRect.bottom = 0; - } + surface_load_location(surface, surface->draw_binding); else if (surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) - { FIXME("Depth / stencil buffer locking is not implemented.\n"); - } - -done: - /* Overlays have to be redrawn manually after changes with the GL implementation */ - if (surface->overlay_dest) - surface_draw_overlay(surface); } static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r) @@ -1053,9 +873,9 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, TRACE("device %p\n", device); TRACE("src_surface %p, src_location %s, src_rect %s,\n", - src_surface, debug_surflocation(src_location), wine_dbgstr_rect(src_rect)); + src_surface, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect)); TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n", - dst_surface, debug_surflocation(dst_location), wine_dbgstr_rect(dst_rect)); + dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); src_mask = src_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); dst_mask = dst_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); @@ -1083,9 +903,9 @@ 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. */ - surface_load_location(src_surface, src_location, NULL); + surface_load_location(src_surface, src_location); if (!surface_is_full_rect(dst_surface, dst_rect)) - surface_load_location(dst_surface, dst_location, NULL); + surface_load_location(dst_surface, dst_location); context = context_acquire(device, NULL); if (!context->valid) @@ -1148,9 +968,9 @@ static void surface_blt_fbo(const struct wined3d_device *device, enum wined3d_te TRACE("device %p, filter %s,\n", device, debug_d3dtexturefiltertype(filter)); TRACE("src_surface %p, src_location %s, src_rect %s,\n", - src_surface, debug_surflocation(src_location), wine_dbgstr_rect(src_rect_in)); + src_surface, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect_in)); TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n", - dst_surface, debug_surflocation(dst_location), wine_dbgstr_rect(dst_rect_in)); + dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect_in)); src_rect = *src_rect_in; dst_rect = *dst_rect_in; @@ -1170,22 +990,22 @@ static void surface_blt_fbo(const struct wined3d_device *device, enum wined3d_te } /* Resolve the source surface first if needed. */ - if (src_location == SFLAG_INRB_MULTISAMPLE + if (src_location == WINED3D_LOCATION_RB_MULTISAMPLE && (src_surface->resource.format->id != dst_surface->resource.format->id || abs(src_rect.bottom - src_rect.top) != abs(dst_rect.bottom - dst_rect.top) || abs(src_rect.right - src_rect.left) != abs(dst_rect.right - dst_rect.left))) - src_location = SFLAG_INRB_RESOLVED; + src_location = WINED3D_LOCATION_RB_RESOLVED; /* Make sure the locations are up-to-date. Loading the destination * surface isn't required if the entire surface is overwritten. (And is * in fact harmful if we're being called by surface_load_location() with * the purpose of loading the destination surface.) */ - surface_load_location(src_surface, src_location, NULL); + surface_load_location(src_surface, src_location); if (!surface_is_full_rect(dst_surface, &dst_rect)) - surface_load_location(dst_surface, dst_location, NULL); + surface_load_location(dst_surface, dst_location); - if (src_location == SFLAG_INDRAWABLE) context = context_acquire(device, src_surface); - else if (dst_location == SFLAG_INDRAWABLE) context = context_acquire(device, dst_surface); + if (src_location == WINED3D_LOCATION_DRAWABLE) context = context_acquire(device, src_surface); + else if (dst_location == WINED3D_LOCATION_DRAWABLE) context = context_acquire(device, dst_surface); else context = context_acquire(device, NULL); if (!context->valid) @@ -1197,7 +1017,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, enum wined3d_te gl_info = context->gl_info; - if (src_location == SFLAG_INDRAWABLE) + if (src_location == WINED3D_LOCATION_DRAWABLE) { TRACE("Source surface %p is onscreen.\n", src_surface); buffer = surface_get_gl_buffer(src_surface); @@ -1214,7 +1034,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, enum wined3d_te checkGLcall("glReadBuffer()"); context_check_fbo_status(context, GL_READ_FRAMEBUFFER); - if (dst_location == SFLAG_INDRAWABLE) + if (dst_location == WINED3D_LOCATION_DRAWABLE) { TRACE("Destination surface %p is onscreen.\n", dst_surface); buffer = surface_get_gl_buffer(dst_surface); @@ -1245,7 +1065,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, enum wined3d_te checkGLcall("glBlitFramebuffer()"); if (wined3d_settings.strict_draw_ordering - || (dst_location == SFLAG_INDRAWABLE + || (dst_location == WINED3D_LOCATION_DRAWABLE && dst_surface->swapchain->front_buffer == dst_surface)) gl_info->gl_ops.gl.p_glFlush(); @@ -1291,19 +1111,6 @@ static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum wined return TRUE; } -/* This function checks if the primary render target uses the 8bit paletted format. */ -static BOOL primary_render_target_is_p8(const struct wined3d_device *device) -{ - if (device->fb.render_targets && device->fb.render_targets[0]) - { - const struct wined3d_surface *render_target = device->fb.render_targets[0]; - if ((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET) - && (render_target->resource.format->id == WINED3DFMT_P8_UINT)) - return TRUE; - } - return FALSE; -} - static BOOL surface_convert_color_to_float(const struct wined3d_surface *surface, DWORD color, struct wined3d_color *float_color) { @@ -1325,7 +1132,7 @@ static BOOL surface_convert_color_to_float(const struct wined3d_surface *surface float_color->g = 0.0f; float_color->b = 0.0f; } - float_color->a = primary_render_target_is_p8(device) ? color / 255.0f : 1.0f; + float_color->a = swapchain_is_p8(device->swapchains[0]) ? color / 255.0f : 1.0f; break; case WINED3DFMT_B5G6R5_UNORM: @@ -1389,7 +1196,6 @@ static BOOL surface_convert_depth_to_float(const struct wined3d_surface *surface return TRUE; } -/* Do not call while under the GL lock. */ static HRESULT wined3d_surface_depth_fill(struct wined3d_surface *surface, const RECT *rect, float depth) { const struct wined3d_resource *resource = &surface->resource; @@ -1425,316 +1231,6 @@ static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DW return WINED3D_OK; } -/* Do not call while under the GL lock. */ -HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, - struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) -{ - struct wined3d_swapchain *src_swapchain, *dst_swapchain; - struct wined3d_device *device = dst_surface->resource.device; - DWORD src_ds_flags, dst_ds_flags; - RECT src_rect, dst_rect; - BOOL scale, convert; - - static const DWORD simple_blit = WINEDDBLT_ASYNC - | WINEDDBLT_COLORFILL - | WINEDDBLT_WAIT - | WINEDDBLT_DEPTHFILL - | WINEDDBLT_DONOTWAIT; - - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in), - flags, fx, debug_d3dtexturefiltertype(filter)); - TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); - - if (fx) - { - TRACE("dwSize %#x.\n", fx->dwSize); - TRACE("dwDDFX %#x.\n", fx->dwDDFX); - TRACE("dwROP %#x.\n", fx->dwROP); - TRACE("dwDDROP %#x.\n", fx->dwDDROP); - TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle); - TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode); - TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow); - TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh); - TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest); - TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth); - TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest); - TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth); - TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc); - TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth); - TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend); - TRACE("dwReserved %#x.\n", fx->dwReserved); - TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth); - TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest); - TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth); - TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc); - TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern); - TRACE("ddckDestColorkey {%#x, %#x}.\n", - fx->ddckDestColorkey.color_space_low_value, - fx->ddckDestColorkey.color_space_high_value); - TRACE("ddckSrcColorkey {%#x, %#x}.\n", - fx->ddckSrcColorkey.color_space_low_value, - fx->ddckSrcColorkey.color_space_high_value); - } - - if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) - { - WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); - return WINEDDERR_SURFACEBUSY; - } - - surface_get_rect(dst_surface, dst_rect_in, &dst_rect); - - if (dst_rect.left >= dst_rect.right || dst_rect.top >= dst_rect.bottom - || dst_rect.left > dst_surface->resource.width || dst_rect.left < 0 - || dst_rect.top > dst_surface->resource.height || dst_rect.top < 0 - || dst_rect.right > dst_surface->resource.width || dst_rect.right < 0 - || dst_rect.bottom > dst_surface->resource.height || dst_rect.bottom < 0) - { - WARN("The application gave us a bad destination rectangle.\n"); - return WINEDDERR_INVALIDRECT; - } - - if (src_surface) - { - surface_get_rect(src_surface, src_rect_in, &src_rect); - - if (src_rect.left >= src_rect.right || src_rect.top >= src_rect.bottom - || src_rect.left > src_surface->resource.width || src_rect.left < 0 - || src_rect.top > src_surface->resource.height || src_rect.top < 0 - || src_rect.right > src_surface->resource.width || src_rect.right < 0 - || src_rect.bottom > src_surface->resource.height || src_rect.bottom < 0) - { - WARN("Application gave us bad source rectangle for Blt.\n"); - return WINEDDERR_INVALIDRECT; - } - } - else - { - memset(&src_rect, 0, sizeof(src_rect)); - } - - if (!fx || !(fx->dwDDFX)) - flags &= ~WINEDDBLT_DDFX; - - if (flags & WINEDDBLT_WAIT) - flags &= ~WINEDDBLT_WAIT; - - if (flags & WINEDDBLT_ASYNC) - { - static unsigned int once; - - if (!once++) - FIXME("Can't handle WINEDDBLT_ASYNC flag.\n"); - flags &= ~WINEDDBLT_ASYNC; - } - - /* WINEDDBLT_DONOTWAIT appeared in DX7. */ - if (flags & WINEDDBLT_DONOTWAIT) - { - static unsigned int once; - - if (!once++) - FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n"); - flags &= ~WINEDDBLT_DONOTWAIT; - } - - if (!device->d3d_initialized) - { - WARN("D3D not initialized, using fallback.\n"); - 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_surface->flags & SFLAG_CONVERTED) - { - WARN_(d3d_perf)("Converted surface, using CPU blit.\n"); - return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter); - } - - if (flags & ~simple_blit) - { - WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags); - goto fallback; - } - - if (src_surface) - src_swapchain = src_surface->swapchain; - else - src_swapchain = NULL; - - dst_swapchain = dst_surface->swapchain; - - /* This isn't strictly needed. FBO blits for example could deal with - * cross-swapchain blits by first downloading the source to a texture - * before switching to the destination context. We just have this here to - * not have to deal with the issue, since cross-swapchain blits should be - * rare. */ - if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain) - { - FIXME("Using fallback for cross-swapchain blit.\n"); - goto fallback; - } - - scale = src_surface - && (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_surface && src_surface->resource.format->id != dst_surface->resource.format->id; - - dst_ds_flags = dst_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); - if (src_surface) - src_ds_flags = src_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); - else - src_ds_flags = 0; - - if (src_ds_flags || dst_ds_flags) - { - if (flags & WINEDDBLT_DEPTHFILL) - { - float depth; - - TRACE("Depth fill.\n"); - - if (!surface_convert_depth_to_float(dst_surface, fx->u5.dwFillDepth, &depth)) - return WINED3DERR_INVALIDCALL; - - if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, &dst_rect, depth))) - return WINED3D_OK; - } - else - { - if (src_ds_flags != dst_ds_flags) - { - WARN("Rejecting depth / stencil blit between incompatible formats.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->draw_binding, &src_rect, - dst_surface, dst_surface->draw_binding, &dst_rect))) - return WINED3D_OK; - } - } - else - { - /* In principle this would apply to depth blits as well, but we don't - * implement those in the CPU blitter at the moment. */ - if ((dst_surface->flags & SFLAG_INSYSMEM) - && (!src_surface || (src_surface->flags & SFLAG_INSYSMEM))) - { - if (scale) - TRACE("Not doing sysmem blit because of scaling.\n"); - else if (convert) - TRACE("Not doing sysmem blit because of format conversion.\n"); - else - return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter); - } - - if (flags & WINEDDBLT_COLORFILL) - { - struct wined3d_color color; - - TRACE("Color fill.\n"); - - if (!surface_convert_color_to_float(dst_surface, fx->u5.dwFillColor, &color)) - goto fallback; - - if (SUCCEEDED(surface_color_fill(dst_surface, &dst_rect, &color))) - return WINED3D_OK; - } - else - { - TRACE("Color blit.\n"); - - /* Upload */ - if ((src_surface->flags & SFLAG_INSYSMEM) && !(dst_surface->flags & SFLAG_INSYSMEM)) - { - if (scale) - TRACE("Not doing upload because of scaling.\n"); - else if (convert) - TRACE("Not doing upload because of format conversion.\n"); - else - { - POINT dst_point = {dst_rect.left, dst_rect.top}; - - if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, &src_rect))) - { - if (!surface_is_offscreen(dst_surface)) - surface_load_location(dst_surface, dst_surface->draw_binding, NULL); - return WINED3D_OK; - } - } - } - - /* Use present for back -> front blits. The idea behind this is - * that present is potentially faster than a blit, in particular - * when FBO blits aren't available. Some ddraw applications like - * Half-Life and Prince of Persia 3D use Blt() from the backbuffer - * to the frontbuffer instead of doing a Flip(). D3D8 and D3D9 - * applications can't blit directly to the frontbuffer. */ - if (dst_swapchain && dst_swapchain->back_buffers - && dst_surface == dst_swapchain->front_buffer - && src_surface == dst_swapchain->back_buffers[0]) - { - enum wined3d_swap_effect swap_effect = dst_swapchain->desc.swap_effect; - - TRACE("Using present for backbuffer -> frontbuffer blit.\n"); - - /* 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, NULL, 0); - dst_swapchain->desc.swap_effect = swap_effect; - - return WINED3D_OK; - } - - if (fbo_blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT, - &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, - &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) - { - TRACE("Using FBO blit.\n"); - - surface_blt_fbo(device, filter, - src_surface, src_surface->draw_binding, &src_rect, - dst_surface, dst_surface->draw_binding, &dst_rect); - surface_modify_location(dst_surface, dst_surface->draw_binding, TRUE); - return WINED3D_OK; - } - - if (arbfp_blit.blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT, - &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, - &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) - { - TRACE("Using arbfp blit.\n"); - - if (SUCCEEDED(arbfp_blit_surface(device, filter, src_surface, &src_rect, dst_surface, &dst_rect))) - return WINED3D_OK; - } - } - } - -fallback: - - /* Special cases for render targets. */ - if ((dst_surface->resource.usage & WINED3DUSAGE_RENDERTARGET) - || (src_surface && (src_surface->resource.usage & WINED3DUSAGE_RENDERTARGET))) - { - if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(dst_surface, &dst_rect, - src_surface, &src_rect, flags, fx, filter))) - return WINED3D_OK; - } - -cpu: - - /* For the rest call the X11 surface implementation. For render targets - * this should be implemented OpenGL accelerated in BltOverride, other - * blits are rather rare. */ - return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter); -} - HRESULT CDECL wined3d_surface_get_render_target_data(struct wined3d_surface *surface, struct wined3d_surface *render_target) { @@ -1751,65 +1247,13 @@ HRESULT CDECL wined3d_surface_get_render_target_data(struct wined3d_surface *sur /* Context activation is done by the caller. */ static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) { - if (surface->flags & SFLAG_DIBSECTION) - { - surface->resource.allocatedMemory = surface->dib.bitmap_data; - } - else - { - if (!surface->resource.heap_memory) - surface->resource.heap_memory = wined3d_resource_allocate_sysmem(surface->resource.size); - else if (!(surface->flags & SFLAG_CLIENT)) - ERR("Surface %p has heap_memory %p and flags %#x.\n", - surface, surface->resource.heap_memory, surface->flags); - - surface->resource.allocatedMemory = surface->resource.heap_memory; - } - - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); - checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, surface->pbo)"); - GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, - surface->resource.size, surface->resource.allocatedMemory)); - checkGLcall("glGetBufferSubDataARB"); GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo)); - checkGLcall("glDeleteBuffersARB"); + checkGLcall("glDeleteBuffersARB(1, &surface->pbo)"); surface->pbo = 0; - surface->flags &= ~SFLAG_PBO; + surface_invalidate_location(surface, WINED3D_LOCATION_BUFFER); } -static BOOL surface_init_sysmem(struct wined3d_surface *surface) -{ - if (!surface->resource.allocatedMemory) - { - if (!surface->resource.heap_memory) - { - surface->resource.heap_memory = wined3d_resource_allocate_sysmem(surface->resource.size); - if (!surface->resource.heap_memory) - { - ERR("Failed to allocate memory.\n"); - return FALSE; - } - } - else if (!(surface->flags & SFLAG_CLIENT)) - { - ERR("Surface %p has heap_memory %p and flags %#x.\n", - surface, surface->resource.heap_memory, surface->flags); - } - - surface->resource.allocatedMemory = surface->resource.heap_memory; - } - else - { - memset(surface->resource.allocatedMemory, 0, surface->resource.size); - } - - surface_modify_location(surface, SFLAG_INSYSMEM, TRUE); - - return TRUE; -} - -/* Do not call while under the GL lock. */ static void surface_unload(struct wined3d_resource *resource) { struct wined3d_surface *surface = surface_from_resource(resource); @@ -1830,10 +1274,12 @@ static void surface_unload(struct wined3d_resource *resource) * Put the surfaces into sysmem, and reset the content. The D3D content is undefined, * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain * or the depth stencil into an FBO the texture or render buffer will be removed - * and all flags get lost - */ - if (!(surface->flags & SFLAG_PBO)) - surface_init_sysmem(surface); + * and all flags get lost */ + surface_prepare_system_memory(surface); + memset(surface->resource.heap_memory, 0, surface->resource.size); + surface_validate_location(surface, WINED3D_LOCATION_SYSMEM); + surface_invalidate_location(surface, ~WINED3D_LOCATION_SYSMEM); + /* We also get here when the ddraw swapchain is destroyed, for example * for a mode switch. In this case this surface won't necessarily be * an implicit surface. We have to mark it lost so that the @@ -1842,19 +1288,17 @@ static void surface_unload(struct wined3d_resource *resource) } else { - /* Load the surface into system memory */ - surface_load_location(surface, SFLAG_INSYSMEM, NULL); - surface_modify_location(surface, surface->draw_binding, FALSE); + surface_prepare_map_memory(surface); + surface_load_location(surface, surface->map_binding); + surface_invalidate_location(surface, ~surface->map_binding); } - surface_modify_location(surface, SFLAG_INTEXTURE, FALSE); - surface_modify_location(surface, SFLAG_INSRGBTEX, FALSE); surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); context = context_acquire(device, NULL); gl_info = context->gl_info; /* Destroy PBOs, but load them into real sysmem before */ - if (surface->flags & SFLAG_PBO) + if (surface->pbo) surface_remove_pbo(surface, gl_info); /* Destroy fbo render buffers. This is needed for implicit render targets, for @@ -1870,15 +1314,6 @@ static void surface_unload(struct wined3d_resource *resource) list_init(&surface->renderbuffers); surface->current_renderbuffer = NULL; - /* If we're in a texture, the texture name belongs to the texture. - * Otherwise, destroy it. */ - if (!surface->container) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name); - surface->texture_name = 0; - gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name_srgb); - surface->texture_name_srgb = 0; - } if (surface->rb_multisample) { gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample); @@ -1904,7 +1339,6 @@ static const struct wined3d_surface_ops surface_ops = { surface_private_setup, surface_realize_palette, - surface_map, surface_unmap, }; @@ -1938,12 +1372,9 @@ static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface) /* Sysmem textures have memory already allocated - release it, * this avoids an unnecessary memcpy. */ hr = surface_create_dib_section(surface); - if (SUCCEEDED(hr)) - { - wined3d_resource_free_sysmem(surface->resource.heap_memory); - surface->resource.heap_memory = NULL; - surface->resource.allocatedMemory = surface->dib.bitmap_data; - } + if (FAILED(hr)) + return hr; + surface->map_binding = WINED3D_LOCATION_DIB; /* We don't mind the nonpow2 stuff in GDI. */ surface->pow2Width = surface->resource.width; @@ -1984,28 +1415,6 @@ static void gdi_surface_realize_palette(struct wined3d_surface *surface) x11_copy_to_screen(surface->swapchain, NULL); } -static void gdi_surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD flags) -{ - TRACE("surface %p, rect %s, flags %#x.\n", - surface, wine_dbgstr_rect(rect), flags); - - if (!(surface->flags & SFLAG_DIBSECTION)) - { - HRESULT hr; - - /* This happens on gdi surfaces if the application set a user pointer - * and resets it. Recreate the DIB section. */ - if (FAILED(hr = surface_create_dib_section(surface))) - { - ERR("Failed to create dib section, hr %#x.\n", hr); - return; - } - wined3d_resource_free_sysmem(surface->resource.heap_memory); - surface->resource.heap_memory = NULL; - surface->resource.allocatedMemory = surface->dib.bitmap_data; - } -} - static void gdi_surface_unmap(struct wined3d_surface *surface) { TRACE("surface %p.\n", surface); @@ -2021,43 +1430,9 @@ static const struct wined3d_surface_ops gdi_surface_ops = { gdi_surface_private_setup, gdi_surface_realize_palette, - gdi_surface_map, gdi_surface_unmap, }; -void surface_set_texture_name(struct wined3d_surface *surface, GLuint new_name, BOOL srgb) -{ - GLuint *name; - DWORD flag; - - TRACE("surface %p, new_name %u, srgb %#x.\n", surface, new_name, srgb); - - if(srgb) - { - name = &surface->texture_name_srgb; - flag = SFLAG_INSRGBTEX; - } - else - { - name = &surface->texture_name; - flag = SFLAG_INTEXTURE; - } - - if (!*name && new_name) - { - /* FIXME: We shouldn't need to remove SFLAG_INTEXTURE if the - * surface has no texture name yet. See if we can get rid of this. */ - if (surface->flags & flag) - { - ERR("Surface has %s set, but no texture name.\n", debug_surflocation(flag)); - surface_modify_location(surface, flag, FALSE); - } - } - - *name = new_name; - surface_force_reload(surface); -} - void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) { TRACE("surface %p, target %#x.\n", surface, target); @@ -2081,9 +1456,11 @@ void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, /* This call just downloads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) +static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, + DWORD dst_location) { const struct wined3d_format *format = surface->resource.format; + struct wined3d_bo_address data; /* Only support read back of converted P8 surfaces. */ if (surface->flags & SFLAG_CONVERTED && format->id != WINED3DFMT_P8_UINT) @@ -2092,15 +1469,16 @@ static void surface_download_data(struct wined3d_surface *surface, const struct return; } + surface_get_memory(surface, &data, dst_location); + if (format->flags & WINED3DFMT_FLAG_COMPRESSED) { TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p.\n", - surface, surface->texture_level, format->glFormat, format->glType, - surface->resource.allocatedMemory); + surface, surface->texture_level, format->glFormat, format->glType, data.addr); - if (surface->flags & SFLAG_PBO) + if (data.buffer_object) { - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data.buffer_object)); checkGLcall("glBindBufferARB"); GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target, surface->texture_level, NULL)); checkGLcall("glGetCompressedTexImageARB"); @@ -2110,7 +1488,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct else { GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target, - surface->texture_level, surface->resource.allocatedMemory)); + surface->texture_level, data.addr)); checkGLcall("glGetCompressedTexImageARB"); } } @@ -2123,7 +1501,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct int dst_pitch = 0; /* In case of P8 the index is stored in the alpha component if the primary render target uses P8. */ - if (format->id == WINED3DFMT_P8_UINT && primary_render_target_is_p8(surface->resource.device)) + if (format->id == WINED3DFMT_P8_UINT && swapchain_is_p8(surface->resource.device->swapchains[0])) { gl_format = GL_ALPHA; gl_type = GL_UNSIGNED_BYTE; @@ -2139,15 +1517,15 @@ static void surface_download_data(struct wined3d_surface *surface, const struct } else { - mem = surface->resource.allocatedMemory; + mem = data.addr; } TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n", surface, surface->texture_level, gl_format, gl_type, mem); - if (surface->flags & SFLAG_PBO) + if (data.buffer_object) { - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data.buffer_object)); checkGLcall("glBindBufferARB"); gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level, @@ -2209,8 +1587,8 @@ static void surface_download_data(struct wined3d_surface *surface, const struct * |444444444444444444| \/ * -------------------- * - * this also means that any references to allocatedMemory should work with the data as if were a - * standard texture with a non-power2 width instead of texture boxed up to be a power2 texture. + * This also means that any references to surface memory should work with the data as if it were a + * standard texture with a non-power2 width instead of a texture boxed up to be a power2 texture. * * internally the texture is still stored in a boxed format so any references to textureName will * get a boxed texture with width pow2width and not a texture of width resource.width. @@ -2219,7 +1597,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct * rendering. If an app does, the SFLAG_DYNLOCK flag will kick in and the memory copy won't be released, * and doesn't have to be re-read. */ src_data = mem; - dst_data = surface->resource.allocatedMemory; + dst_data = data.addr; TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch); for (y = 0; y < surface->resource.height; ++y) { @@ -2231,9 +1609,6 @@ static void surface_download_data(struct wined3d_surface *surface, const struct HeapFree(GetProcessHeap(), 0, mem); } } - - /* Surface has now been downloaded */ - surface->flags |= SFLAG_INSYSMEM; } /* This call just uploads data, the caller is responsible for binding the @@ -2352,7 +1727,7 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi static HRESULT d3dfmt_get_conv(const struct wined3d_surface *surface, BOOL need_alpha_ck, BOOL use_texturing, struct wined3d_format *format, enum wined3d_conversion_type *conversion_type) { - BOOL colorkey_active = need_alpha_ck && (surface->CKeyFlags & WINEDDSD_CKSRCBLT); + BOOL colorkey_active = need_alpha_ck && (surface->container->color_key_flags & WINEDDSD_CKSRCBLT); const struct wined3d_device *device = surface->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; BOOL blit_supported = FALSE; @@ -2387,7 +1762,7 @@ static HRESULT d3dfmt_get_conv(const struct wined3d_surface *surface, BOOL need_ * in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which * conflicts with this. */ - if (!((blit_supported && device->fb.render_targets && surface == device->fb.render_targets[0])) + if (!((blit_supported && surface->swapchain && surface == surface->swapchain->front_buffer)) || colorkey_active || !use_texturing) { format->glFormat = GL_RGBA; @@ -2594,20 +1969,21 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P if (update_w == dst_w && update_h == dst_h) surface_prepare_texture(dst_surface, context, FALSE); else - surface_load_location(dst_surface, SFLAG_INTEXTURE, NULL); - surface_bind(dst_surface, context, FALSE); + surface_load_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_bind(dst_surface->container, context, FALSE); - data.buffer_object = src_surface->pbo; - data.addr = src_surface->resource.allocatedMemory; + surface_get_memory(src_surface, &data, src_surface->locations); src_pitch = wined3d_surface_get_pitch(src_surface); surface_upload_data(dst_surface, gl_info, src_format, src_rect, src_pitch, dst_point, FALSE, &data); - invalidate_active_texture(dst_surface->resource.device, context); + context_invalidate_active_texture(context); context_release(context); - surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE); + surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); + surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); + return WINED3D_OK; } @@ -2652,23 +2028,19 @@ static void surface_allocate_surface(struct wined3d_surface *surface, const stru if (gl_info->supported[APPLE_CLIENT_STORAGE]) { if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_CONVERTED) - || !surface->resource.allocatedMemory) + || !surface->resource.heap_memory) { /* In some cases we want to disable client storage. * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues... * SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface - * allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively + * heap_memory == NULL: Not defined in the extension. Seems to disable client storage effectively */ surface->flags &= ~SFLAG_CLIENT; } else { surface->flags |= SFLAG_CLIENT; - - /* Point OpenGL to our allocated texture memory. Do not use - * resource.allocatedMemory here because it might point into a - * PBO. Instead use heap_memory. */ mem = surface->resource.heap_memory; gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); @@ -2796,88 +2168,49 @@ GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) return GL_BACK; } -/* Slightly inefficient way to handle multiple dirty rects but it works :) */ -void surface_add_dirty_rect(struct wined3d_surface *surface, const struct wined3d_box *dirty_rect) +void surface_load(struct wined3d_surface *surface, BOOL srgb) { - TRACE("surface %p, dirty_rect %p.\n", surface, dirty_rect); - - if (!(surface->flags & SFLAG_INSYSMEM) && (surface->flags & SFLAG_INTEXTURE)) - /* No partial locking for textures yet. */ - surface_load_location(surface, SFLAG_INSYSMEM, NULL); - - surface_modify_location(surface, SFLAG_INSYSMEM, TRUE); - if (dirty_rect) - { - surface->dirtyRect.left = min(surface->dirtyRect.left, dirty_rect->left); - surface->dirtyRect.top = min(surface->dirtyRect.top, dirty_rect->top); - surface->dirtyRect.right = max(surface->dirtyRect.right, dirty_rect->right); - surface->dirtyRect.bottom = max(surface->dirtyRect.bottom, dirty_rect->bottom); - } - else - { - surface->dirtyRect.left = 0; - surface->dirtyRect.top = 0; - surface->dirtyRect.right = surface->resource.width; - surface->dirtyRect.bottom = surface->resource.height; - } - - /* if the container is a texture then mark it dirty. */ - if (surface->container) - { - TRACE("Passing to container.\n"); - wined3d_texture_set_dirty(surface->container, TRUE); - } -} - -HRESULT surface_load(struct wined3d_surface *surface, BOOL srgb) -{ - DWORD flag = srgb ? SFLAG_INSRGBTEX : SFLAG_INTEXTURE; + DWORD location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; BOOL ck_changed; TRACE("surface %p, srgb %#x.\n", surface, srgb); if (surface->resource.pool == WINED3D_POOL_SCRATCH) - { ERR("Not supported on scratch surfaces.\n"); - return WINED3DERR_INVALIDCALL; - } - ck_changed = !(surface->flags & SFLAG_GLCKEY) != !(surface->CKeyFlags & WINEDDSD_CKSRCBLT); + ck_changed = !(surface->flags & SFLAG_GLCKEY) != !(surface->container->color_key_flags & WINEDDSD_CKSRCBLT); /* Reload if either the texture and sysmem have different ideas about the * color key, or the actual key values changed. */ - if (ck_changed || ((surface->CKeyFlags & WINEDDSD_CKSRCBLT) - && (surface->gl_color_key.color_space_low_value != surface->src_blt_color_key.color_space_low_value - || surface->gl_color_key.color_space_high_value != surface->src_blt_color_key.color_space_high_value))) + if (ck_changed || ((surface->container->color_key_flags & WINEDDSD_CKSRCBLT) + && (surface->gl_color_key.color_space_low_value + != surface->container->src_blt_color_key.color_space_low_value + || surface->gl_color_key.color_space_high_value + != surface->container->src_blt_color_key.color_space_high_value))) { TRACE("Reloading because of color keying\n"); /* To perform the color key conversion we need a sysmem copy of * the surface. Make sure we have it. */ - surface_load_location(surface, SFLAG_INSYSMEM, NULL); - /* Make sure the texture is reloaded because of the color key change, - * this kills performance though :( */ - /* TODO: This is not necessarily needed with hw palettized texture support. */ - surface_modify_location(surface, SFLAG_INSYSMEM, TRUE); + surface_prepare_map_memory(surface); + surface_load_location(surface, surface->map_binding); + surface_invalidate_location(surface, ~surface->map_binding); /* Switching color keying on / off may change the internal format. */ if (ck_changed) surface_force_reload(surface); } - else if (!(surface->flags & flag)) + else if (!(surface->locations & location)) { TRACE("Reloading because surface is dirty.\n"); } else { TRACE("surface is already in texture\n"); - return WINED3D_OK; + return; } - /* No partial locking for textures yet. */ - surface_load_location(surface, flag, NULL); + surface_load_location(surface, location); surface_evict_sysmem(surface); - - return WINED3D_OK; } /* See also float_16_to_32() in wined3d_private.h */ @@ -2962,7 +2295,6 @@ ULONG CDECL wined3d_surface_incref(struct wined3d_surface *surface) return refcount; } -/* Do not call while under the GL lock. */ ULONG CDECL wined3d_surface_decref(struct wined3d_surface *surface) { ULONG refcount; @@ -3011,7 +2343,7 @@ void CDECL wined3d_surface_preload(struct wined3d_surface *surface) return; } - surface_internal_preload(surface, SRGB_ANY); + wined3d_texture_preload(surface->container); } void * CDECL wined3d_surface_get_parent(const struct wined3d_surface *surface) @@ -3086,80 +2418,9 @@ void CDECL wined3d_surface_set_palette(struct wined3d_surface *surface, struct w return; } - if (surface->palette && (surface->resource.usage & WINED3DUSAGE_RENDERTARGET)) - surface->palette->flags &= ~WINEDDPCAPS_PRIMARYSURFACE; - surface->palette = palette; - if (palette) - { - if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET) - palette->flags |= WINEDDPCAPS_PRIMARYSURFACE; - surface->surface_ops->surface_realize_palette(surface); - } -} - -HRESULT CDECL wined3d_surface_set_color_key(struct wined3d_surface *surface, - DWORD flags, const struct wined3d_color_key *color_key) -{ - TRACE("surface %p, flags %#x, color_key %p.\n", surface, flags, color_key); - - if (flags & WINEDDCKEY_COLORSPACE) - { - FIXME(" colorkey value not supported (%08x) !\n", flags); - return WINED3DERR_INVALIDCALL; - } - - /* Dirtify the surface, but only if a key was changed. */ - if (color_key) - { - switch (flags & ~WINEDDCKEY_COLORSPACE) - { - case WINEDDCKEY_DESTBLT: - surface->dst_blt_color_key = *color_key; - surface->CKeyFlags |= WINEDDSD_CKDESTBLT; - break; - - case WINEDDCKEY_DESTOVERLAY: - surface->dst_overlay_color_key = *color_key; - surface->CKeyFlags |= WINEDDSD_CKDESTOVERLAY; - break; - - case WINEDDCKEY_SRCOVERLAY: - surface->src_overlay_color_key = *color_key; - surface->CKeyFlags |= WINEDDSD_CKSRCOVERLAY; - break; - - case WINEDDCKEY_SRCBLT: - surface->src_blt_color_key = *color_key; - surface->CKeyFlags |= WINEDDSD_CKSRCBLT; - break; - } - } - else - { - switch (flags & ~WINEDDCKEY_COLORSPACE) - { - case WINEDDCKEY_DESTBLT: - surface->CKeyFlags &= ~WINEDDSD_CKDESTBLT; - break; - - case WINEDDCKEY_DESTOVERLAY: - surface->CKeyFlags &= ~WINEDDSD_CKDESTOVERLAY; - break; - - case WINEDDCKEY_SRCOVERLAY: - surface->CKeyFlags &= ~WINEDDSD_CKSRCOVERLAY; - break; - - case WINEDDCKEY_SRCBLT: - surface->CKeyFlags &= ~WINEDDSD_CKSRCBLT; - break; - } - } - - return WINED3D_OK; } struct wined3d_palette * CDECL wined3d_surface_get_palette(const struct wined3d_surface *surface) @@ -3198,80 +2459,6 @@ DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface) return pitch; } -HRESULT CDECL wined3d_surface_set_mem(struct wined3d_surface *surface, void *mem, UINT pitch) -{ - TRACE("surface %p, mem %p.\n", surface, mem); - - if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE)) - { - WARN("Surface is mapped or the DC is in use.\n"); - return WINED3DERR_INVALIDCALL; - } - - /* Render targets depend on their hdc, and we can't create an hdc on a user pointer. */ - if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET) - { - ERR("Not supported on render targets.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (mem && mem != surface->resource.allocatedMemory) - { - void *release = NULL; - - /* Do I have to copy the old surface content? */ - if (surface->flags & SFLAG_DIBSECTION) - { - DeleteDC(surface->hDC); - DeleteObject(surface->dib.DIBsection); - surface->dib.bitmap_data = NULL; - surface->resource.allocatedMemory = NULL; - surface->hDC = NULL; - surface->flags &= ~SFLAG_DIBSECTION; - } - else if (!(surface->flags & SFLAG_USERPTR)) - { - release = surface->resource.heap_memory; - surface->resource.heap_memory = NULL; - } - surface->resource.allocatedMemory = mem; - surface->flags |= SFLAG_USERPTR; - - /* Now the surface memory is most up do date. Invalidate drawable and texture. */ - surface_modify_location(surface, SFLAG_INSYSMEM, TRUE); - - /* For client textures OpenGL has to be notified. */ - if (surface->flags & SFLAG_CLIENT) - surface_release_client_storage(surface); - - /* Now free the old memory if any. */ - wined3d_resource_free_sysmem(release); - } - else if (surface->flags & SFLAG_USERPTR) - { - /* heap_memory should be NULL already. */ - if (surface->resource.heap_memory) - ERR("User pointer surface has heap memory allocated.\n"); - - if (!mem) - { - surface->resource.allocatedMemory = NULL; - surface->flags &= ~(SFLAG_USERPTR | SFLAG_INSYSMEM); - - if (surface->flags & SFLAG_CLIENT) - surface_release_client_storage(surface); - - surface_prepare_system_memory(surface); - } - - surface_modify_location(surface, SFLAG_INSYSMEM, TRUE); - } - - surface->pitch = pitch; - - return WINED3D_OK; -} - HRESULT CDECL wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y) { LONG w, h; @@ -3291,8 +2478,6 @@ HRESULT CDECL wined3d_surface_set_overlay_position(struct wined3d_surface *surfa surface->overlay_destrect.right = x + w; surface->overlay_destrect.bottom = y + h; - surface_draw_overlay(surface); - return WINED3D_OK; } @@ -3401,19 +2586,21 @@ HRESULT CDECL wined3d_surface_update_overlay(struct wined3d_surface *surface, co surface->overlay_dest = NULL; } - surface_draw_overlay(surface); - return WINED3D_OK; } HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface, UINT width, UINT height, enum wined3d_format_id format_id, - enum wined3d_multisample_type multisample_type, UINT multisample_quality) + enum wined3d_multisample_type multisample_type, UINT multisample_quality, + void *mem, UINT pitch) { struct wined3d_device *device = surface->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_format *format = wined3d_get_format(gl_info, format_id); UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1); + BOOL create_dib = FALSE; + HRESULT hr; + DWORD valid_location = 0; TRACE("surface %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u.\n", surface, width, height, debug_d3dformat(format_id), multisample_type, multisample_type); @@ -3421,6 +2608,12 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface, if (!resource_size) return WINED3DERR_INVALIDCALL; + if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE)) + { + WARN("Surface is mapped or the DC is in use.\n"); + return WINED3DERR_INVALIDCALL; + } + if (device->d3d_initialized) surface->resource.resource_ops->resource_unload(&surface->resource); @@ -3430,12 +2623,11 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface, DeleteObject(surface->dib.DIBsection); surface->dib.bitmap_data = NULL; surface->flags &= ~SFLAG_DIBSECTION; + create_dib = TRUE; } - surface->flags &= ~(SFLAG_LOCATIONS | SFLAG_USERPTR); - surface->resource.allocatedMemory = NULL; - wined3d_resource_free_sysmem(surface->resource.heap_memory); - surface->resource.heap_memory = NULL; + surface->locations = 0; + wined3d_resource_free_sysmem(&surface->resource); surface->resource.width = width; surface->resource.height = height; @@ -3459,13 +2651,46 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface, else surface->flags &= ~SFLAG_NONPOW2; + surface->user_memory = mem; + if (surface->user_memory) + { + surface->map_binding = WINED3D_LOCATION_USER_MEMORY; + valid_location = WINED3D_LOCATION_USER_MEMORY; + } + surface->pitch = pitch; surface->resource.format = format; surface->resource.multisample_type = multisample_type; surface->resource.multisample_quality = multisample_quality; - surface->resource.size = resource_size; + if (surface->pitch) + surface->resource.size = height * surface->pitch; + else + surface->resource.size = resource_size; - if (!surface_init_sysmem(surface)) - return E_OUTOFMEMORY; + /* The format might be changed to a format that needs conversion. + * If the surface didn't use PBOs previously but could now, don't + * change it - whatever made us not use PBOs might come back, e.g. + * color keys. */ + if (surface->map_binding == WINED3D_LOCATION_BUFFER && !surface_use_pbo(surface)) + surface->map_binding = create_dib ? WINED3D_LOCATION_DIB : WINED3D_LOCATION_SYSMEM; + + if (create_dib) + { + if (FAILED(hr = surface_create_dib_section(surface))) + { + ERR("Failed to create dib section, hr %#x.\n", hr); + return hr; + } + if (!valid_location) + valid_location = WINED3D_LOCATION_DIB; + } + + if (!valid_location) + { + surface_prepare_system_memory(surface); + valid_location = WINED3D_LOCATION_SYSMEM; + } + + surface_validate_location(surface, valid_location); return WINED3D_OK; } @@ -3669,23 +2894,13 @@ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_fo return NULL; } -/***************************************************************************** - * surface_convert_format - * - * Creates a duplicate of a surface in a different format. Is used by Blt to - * blit between surfaces with different formats. - * - * Parameters - * source: Source surface - * fmt: Requested destination format - * - *****************************************************************************/ -static struct wined3d_surface *surface_convert_format(struct wined3d_surface *source, enum wined3d_format_id to_fmt) +static struct wined3d_texture *surface_convert_format(struct wined3d_surface *source, enum wined3d_format_id to_fmt) { struct wined3d_map_desc src_map, dst_map; const struct d3dfmt_converter_desc *conv; - struct wined3d_surface *ret = NULL; - HRESULT hr; + struct wined3d_texture *ret = NULL; + struct wined3d_resource_desc desc; + struct wined3d_surface *dst; conv = find_converter(source->resource.format->id, to_fmt); if (!conv) @@ -3696,35 +2911,40 @@ static struct wined3d_surface *surface_convert_format(struct wined3d_surface *so } /* FIXME: Multisampled conversion? */ - if (FAILED(hr = wined3d_surface_create(source->resource.device, source->resource.width, source->resource.height, - to_fmt, 0, WINED3D_POOL_SCRATCH, WINED3D_MULTISAMPLE_NONE, 0, + wined3d_resource_get_desc(&source->resource, &desc); + desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.format = to_fmt; + desc.usage = 0; + desc.pool = WINED3D_POOL_SCRATCH; + if (FAILED(wined3d_texture_create(source->resource.device, &desc, 1, WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, &wined3d_null_parent_ops, &ret))) { ERR("Failed to create a destination surface for conversion.\n"); return NULL; } + dst = surface_from_resource(wined3d_texture_get_sub_resource(ret, 0)); memset(&src_map, 0, sizeof(src_map)); memset(&dst_map, 0, sizeof(dst_map)); - if (FAILED(hr = wined3d_surface_map(source, &src_map, NULL, WINED3D_MAP_READONLY))) + if (FAILED(wined3d_surface_map(source, &src_map, NULL, WINED3D_MAP_READONLY))) { ERR("Failed to lock the source surface.\n"); - wined3d_surface_decref(ret); + wined3d_texture_decref(ret); return NULL; } - if (FAILED(hr = wined3d_surface_map(ret, &dst_map, NULL, WINED3D_MAP_READONLY))) + if (FAILED(wined3d_surface_map(dst, &dst_map, NULL, 0))) { ERR("Failed to lock the destination surface.\n"); wined3d_surface_unmap(source); - wined3d_surface_decref(ret); + wined3d_texture_decref(ret); return NULL; } conv->convert(src_map.data, dst_map.data, src_map.row_pitch, dst_map.row_pitch, source->resource.width, source->resource.height); - wined3d_surface_unmap(ret); + wined3d_surface_unmap(dst); wined3d_surface_unmap(source); return ret; @@ -3813,6 +3033,10 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, const RECT *rect, DWORD flags) { const struct wined3d_format *format = surface->resource.format; + struct wined3d_device *device = surface->resource.device; + struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + BYTE *base_memory; TRACE("surface %p, map_desc %p, rect %s, flags %#x.\n", surface, map_desc, wine_dbgstr_rect(rect), flags); @@ -3835,14 +3059,14 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, ++surface->resource.map_count; - if (!(surface->flags & SFLAG_LOCKABLE)) + if (!(surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) WARN("Trying to lock unlockable surface.\n"); /* Performance optimization: Count how often a surface is mapped, if it is * mapped regularly do not throw away the system memory copy. This avoids * the need to download the surface from OpenGL all the time. The surface * is still downloaded if the OpenGL texture is changed. */ - if (!(surface->flags & SFLAG_DYNLOCK)) + if (!(surface->flags & SFLAG_DYNLOCK) && surface->map_binding == WINED3D_LOCATION_SYSMEM) { if (++surface->lockCount > MAXLOCKCOUNT) { @@ -3851,7 +3075,54 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, } } - surface->surface_ops->surface_map(surface, rect, flags); + surface_prepare_map_memory(surface); + if (flags & WINED3D_MAP_DISCARD) + { + TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", + wined3d_debug_location(surface->map_binding)); + surface_validate_location(surface, surface->map_binding); + } + else + { + if (surface->resource.usage & WINED3DUSAGE_DYNAMIC) + WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n"); + + surface_load_location(surface, surface->map_binding); + } + + if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) + surface_invalidate_location(surface, ~surface->map_binding); + + switch (surface->map_binding) + { + case WINED3D_LOCATION_SYSMEM: + base_memory = surface->resource.heap_memory; + break; + + case WINED3D_LOCATION_USER_MEMORY: + base_memory = surface->user_memory; + break; + + case WINED3D_LOCATION_DIB: + base_memory = surface->dib.bitmap_data; + break; + + case WINED3D_LOCATION_BUFFER: + context = context_acquire(device, NULL); + gl_info = context->gl_info; + + GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); + base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + checkGLcall("map PBO"); + + context_release(context); + break; + + default: + ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->map_binding)); + base_memory = NULL; + } if (format->flags & WINED3DFMT_FLAG_BROKEN_PITCH) map_desc->row_pitch = surface->resource.width * format->byte_count; @@ -3861,7 +3132,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, if (!rect) { - map_desc->data = surface->resource.allocatedMemory; + map_desc->data = base_memory; surface->lockedRect.left = 0; surface->lockedRect.top = 0; surface->lockedRect.right = surface->resource.width; @@ -3873,13 +3144,13 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, { /* Compressed textures are block based, so calculate the offset of * the block that contains the top-left pixel of the locked rectangle. */ - map_desc->data = surface->resource.allocatedMemory + map_desc->data = base_memory + ((rect->top / format->block_height) * map_desc->row_pitch) + ((rect->left / format->block_width) * format->block_byte_count); } else { - map_desc->data = surface->resource.allocatedMemory + map_desc->data = base_memory + (map_desc->row_pitch * rect->top) + (rect->left * format->byte_count); } @@ -3897,17 +3168,10 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) { - struct wined3d_map_desc map; HRESULT hr; TRACE("surface %p, dc %p.\n", surface, dc); - if (surface->flags & SFLAG_USERPTR) - { - ERR("Not supported on surfaces with application-provided memory.\n"); - return WINEDDERR_NODC; - } - /* Give more detailed info for ddraw. */ if (surface->flags & SFLAG_DCINUSE) return WINEDDERR_DCALREADYCREATED; @@ -3921,34 +3185,20 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) { if (surface->flags & SFLAG_CLIENT) { - surface_load_location(surface, SFLAG_INSYSMEM, NULL); + surface_load_location(surface, WINED3D_LOCATION_SYSMEM); surface_release_client_storage(surface); } hr = surface_create_dib_section(surface); if (FAILED(hr)) return WINED3DERR_INVALIDCALL; - - /* Use the DIB section from now on if we are not using a PBO. */ - if (!(surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM))) - { - wined3d_resource_free_sysmem(surface->resource.heap_memory); - surface->resource.heap_memory = NULL; - surface->resource.allocatedMemory = surface->dib.bitmap_data; - } + if (!(surface->map_binding == WINED3D_LOCATION_USER_MEMORY + || surface->flags & SFLAG_PIN_SYSMEM + || surface->pbo)) + surface->map_binding = WINED3D_LOCATION_DIB; } - /* Map the surface. */ - hr = wined3d_surface_map(surface, &map, NULL, 0); - if (FAILED(hr)) - { - ERR("Map failed, hr %#x.\n", hr); - return hr; - } - - /* Sync the DIB with the PBO. This can't be done earlier because Map() - * activates the allocatedMemory. */ - if (surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)) - memcpy(surface->dib.bitmap_data, surface->resource.allocatedMemory, surface->resource.size); + surface_load_location(surface, WINED3D_LOCATION_DIB); + surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); if (surface->resource.format->id == WINED3DFMT_P8_UINT || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM) @@ -3988,6 +3238,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) } surface->flags |= SFLAG_DCINUSE; + surface->resource.map_count++; *dc = surface->hDC; TRACE("Returning dc %p.\n", *dc); @@ -4009,92 +3260,16 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) return WINEDDERR_NODC; } - /* Copy the contents of the DIB over to the PBO. */ - if ((surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)) && surface->resource.allocatedMemory) - memcpy(surface->resource.allocatedMemory, surface->dib.bitmap_data, surface->resource.size); - - /* We locked first, so unlock now. */ - wined3d_surface_unmap(surface); - + surface->resource.map_count--; surface->flags &= ~SFLAG_DCINUSE; - return WINED3D_OK; -} - -HRESULT CDECL wined3d_surface_flip(struct wined3d_surface *surface, struct wined3d_surface *override, DWORD flags) -{ - TRACE("surface %p, override %p, flags %#x.\n", surface, override, flags); - - if (flags) - { - static UINT once; - if (!once++) - FIXME("Ignoring flags %#x.\n", flags); - else - WARN("Ignoring flags %#x.\n", flags); - } - - if (surface->swapchain) - { - ERR("Not supported on swapchain surfaces.\n"); - return WINEDDERR_NOTFLIPPABLE; - } - - /* Flipping is only supported on render targets and overlays. */ - if (!(surface->resource.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_OVERLAY))) - { - WARN("Tried to flip a non-render target, non-overlay surface.\n"); - return WINEDDERR_NOTFLIPPABLE; - } - - flip_surface(surface, override); - - /* Update overlays if they're visible. */ - if ((surface->resource.usage & WINED3DUSAGE_OVERLAY) && surface->overlay_dest) - return surface_draw_overlay(surface); + if (surface->map_binding == WINED3D_LOCATION_USER_MEMORY) + surface_load_location(surface, WINED3D_LOCATION_USER_MEMORY); return WINED3D_OK; } -/* Do not call while under the GL lock. */ -void surface_internal_preload(struct wined3d_surface *surface, enum WINED3DSRGB srgb) -{ - struct wined3d_device *device = surface->resource.device; - - TRACE("iface %p, srgb %#x.\n", surface, srgb); - - if (surface->container) - { - struct wined3d_texture *texture = surface->container; - - TRACE("Passing to container (%p).\n", texture); - texture->texture_ops->texture_preload(texture, srgb); - } - else - { - struct wined3d_context *context; - - TRACE("(%p) : About to load surface\n", surface); - - /* TODO: Use already acquired context when possible. */ - context = context_acquire(device, NULL); - - surface_load(surface, srgb == SRGB_SRGB); - - if (surface->resource.pool == WINED3D_POOL_DEFAULT) - { - /* Tell opengl to try and keep this texture in video ram (well mostly) */ - GLclampf tmp; - tmp = 0.9f; - context->gl_info->gl_ops.gl.p_glPrioritizeTextures(1, &surface->texture_name, &tmp); - } - - context_release(context); - } -} - -/* Read the framebuffer back into the surface */ -static void read_from_framebuffer(struct wined3d_surface *surface, const RECT *rect, void *dest, UINT pitch) +static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_location) { struct wined3d_device *device = surface->resource.device; const struct wined3d_gl_info *gl_info; @@ -4105,11 +3280,11 @@ static void read_from_framebuffer(struct wined3d_surface *surface, const RECT *r BYTE *row, *top, *bottom; int i; BOOL bpp; - RECT local_rect; BOOL srcIsUpsideDown; - GLint rowLen = 0; - GLint skipPix = 0; - GLint skipRow = 0; + struct wined3d_bo_address data; + UINT pitch = wined3d_surface_get_pitch(surface); + + surface_get_memory(surface, &data, dst_location); context = context_acquire(device, surface); context_apply_blit_state(context, device); @@ -4137,30 +3312,16 @@ static void read_from_framebuffer(struct wined3d_surface *surface, const RECT *r srcIsUpsideDown = FALSE; } - /* TODO: Get rid of the extra rectangle comparison and construction of a full surface rectangle */ - if (!rect) - { - local_rect.left = 0; - local_rect.top = 0; - local_rect.right = surface->resource.width; - local_rect.bottom = surface->resource.height; - } - else - { - local_rect = *rect; - } - /* TODO: Get rid of the extra GetPitch call, LockRect does that too. Cache the pitch */ - switch (surface->resource.format->id) { case WINED3DFMT_P8_UINT: { - if (primary_render_target_is_p8(device)) + if (swapchain_is_p8(context->swapchain)) { /* In case of P8 render targets the index is stored in the alpha component */ fmt = GL_ALPHA; type = GL_UNSIGNED_BYTE; - mem = dest; + mem = data.addr; bpp = surface->resource.format->byte_count; } else @@ -4189,106 +3350,80 @@ static void read_from_framebuffer(struct wined3d_surface *surface, const RECT *r break; default: - mem = dest; + mem = data.addr; fmt = surface->resource.format->glFormat; type = surface->resource.format->glType; bpp = surface->resource.format->byte_count; } - if (surface->flags & SFLAG_PBO) + if (data.buffer_object) { - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data.buffer_object)); checkGLcall("glBindBufferARB"); if (mem) - { ERR("mem not null for pbo -- unexpected\n"); - mem = NULL; - } } - /* Save old pixel store pack state */ - gl_info->gl_ops.gl.p_glGetIntegerv(GL_PACK_ROW_LENGTH, &rowLen); - checkGLcall("glGetIntegerv"); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_PACK_SKIP_PIXELS, &skipPix); - checkGLcall("glGetIntegerv"); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_PACK_SKIP_ROWS, &skipRow); - checkGLcall("glGetIntegerv"); - /* Setup pixel store pack state -- to glReadPixels into the correct place */ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, surface->resource.width); checkGLcall("glPixelStorei"); - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_PIXELS, local_rect.left); - checkGLcall("glPixelStorei"); - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_ROWS, local_rect.top); - checkGLcall("glPixelStorei"); - gl_info->gl_ops.gl.p_glReadPixels(local_rect.left, - !srcIsUpsideDown ? (surface->resource.height - local_rect.bottom) : local_rect.top, - local_rect.right - local_rect.left, - local_rect.bottom - local_rect.top, + gl_info->gl_ops.gl.p_glReadPixels(0, 0, + surface->resource.width, surface->resource.height, fmt, type, mem); checkGLcall("glReadPixels"); /* Reset previous pixel store pack state */ - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, rowLen); - checkGLcall("glPixelStorei"); - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_PIXELS, skipPix); - checkGLcall("glPixelStorei"); - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_ROWS, skipRow); + gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, 0); checkGLcall("glPixelStorei"); - if (surface->flags & SFLAG_PBO) + if (data.buffer_object && !srcIsUpsideDown) { - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); - checkGLcall("glBindBufferARB"); - /* Check if we need to flip the image. If we need to flip use glMapBufferARB * to get a pointer to it and perform the flipping in software. This is a lot * faster than calling glReadPixels for each line. In case we want more speed * we should rerender it flipped in a FBO and read the data back from the FBO. */ - if (!srcIsUpsideDown) - { - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); - checkGLcall("glBindBufferARB"); - - mem = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB)); - checkGLcall("glMapBufferARB"); - } + mem = GL_EXTCALL(glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_WRITE_ARB)); + checkGLcall("glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_WRITE_ARB)"); } /* TODO: Merge this with the palettization loop below for P8 targets */ - if(!srcIsUpsideDown) { - UINT len, off; + if (!srcIsUpsideDown) + { + UINT len; /* glReadPixels returns the image upside down, and there is no way to prevent this. Flip the lines in software */ - len = (local_rect.right - local_rect.left) * bpp; - off = local_rect.left * bpp; + len = surface->resource.width * bpp; row = HeapAlloc(GetProcessHeap(), 0, len); - if(!row) { + if (!row) + { ERR("Out of memory\n"); if (surface->resource.format->id == WINED3DFMT_P8_UINT) HeapFree(GetProcessHeap(), 0, mem); return; } - top = mem + pitch * local_rect.top; - bottom = mem + pitch * (local_rect.bottom - 1); - for(i = 0; i < (local_rect.bottom - local_rect.top) / 2; i++) { - memcpy(row, top + off, len); - memcpy(top + off, bottom + off, len); - memcpy(bottom + off, row, len); + top = mem; + bottom = mem + pitch * (surface->resource.height - 1); + for (i = 0; i < surface->resource.height / 2; i++) + { + memcpy(row, top, len); + memcpy(top, bottom, len); + memcpy(bottom, row, len); top += pitch; bottom -= pitch; } HeapFree(GetProcessHeap(), 0, row); + } - /* Unmap the temp PBO buffer */ - if (surface->flags & SFLAG_PBO) - { - GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); - } + if (data.buffer_object) + { + if (!srcIsUpsideDown) + GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB)); + + GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); + checkGLcall("glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)"); } context_release(context); @@ -4298,7 +3433,7 @@ static void read_from_framebuffer(struct wined3d_surface *surface, const RECT *r * Note this isn't guaranteed to work when there are multiple entries for * the same color but we have no choice. In case of P8 render targets, * the index is stored in the alpha component so no conversion is needed. */ - if (surface->resource.format->id == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(device)) + if (surface->resource.format->id == WINED3DFMT_P8_UINT && !swapchain_is_p8(context->swapchain)) { const PALETTEENTRY *pal = NULL; DWORD width = pitch / 3; @@ -4315,19 +3450,22 @@ static void read_from_framebuffer(struct wined3d_surface *surface, const RECT *r return; } - for(y = local_rect.top; y < local_rect.bottom; y++) { - for(x = local_rect.left; x < local_rect.right; x++) { + for (y = 0; y < surface->resource.height; y++) + { + for (x = 0; x < surface->resource.width; x++) + { /* start lines pixels */ const BYTE *blue = mem + y * pitch + x * (sizeof(BYTE) * 3); const BYTE *green = blue + 1; const BYTE *red = green + 1; - for(c = 0; c < 256; c++) { - if(*red == pal[c].peRed && - *green == pal[c].peGreen && - *blue == pal[c].peBlue) + for (c = 0; c < 256; c++) + { + if (*red == pal[c].peRed + && *green == pal[c].peGreen + && *blue == pal[c].peBlue) { - *((BYTE *) dest + y * width + x) = c; + *((BYTE *)data.addr + y * width + x) = c; break; } } @@ -4351,7 +3489,7 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb) device_invalidate_state(device, STATE_FRAMEBUFFER); surface_prepare_texture(surface, context, srgb); - surface_bind_and_dirtify(surface, context, srgb); + wined3d_texture_bind_and_dirtify(surface->container, context, srgb); TRACE("Reading back offscreen render target %p.\n", surface); @@ -4383,7 +3521,7 @@ static void surface_prepare_texture_internal(struct wined3d_surface *surface, surface->flags |= SFLAG_CONVERTED; else surface->flags &= ~SFLAG_CONVERTED; - surface_bind_and_dirtify(surface, context, srgb); + wined3d_texture_bind_and_dirtify(surface->container, context, srgb); surface_allocate_surface(surface, context->gl_info, &format, srgb); surface->flags |= alloc_flag; } @@ -4391,24 +3529,19 @@ static void surface_prepare_texture_internal(struct wined3d_surface *surface, /* Context activation is done by the caller. */ void surface_prepare_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) { - if (surface->container) + struct wined3d_texture *texture = surface->container; + UINT sub_count = texture->level_count * texture->layer_count; + UINT i; + + TRACE("surface %p is a subresource of texture %p.\n", surface, texture); + + for (i = 0; i < sub_count; ++i) { - struct wined3d_texture *texture = surface->container; - UINT sub_count = texture->level_count * texture->layer_count; - UINT i; - - TRACE("surface %p is a subresource of texture %p.\n", surface, texture); - - for (i = 0; i < sub_count; ++i) - { - struct wined3d_surface *s = surface_from_resource(texture->sub_resources[i]); - surface_prepare_texture_internal(s, context, srgb); - } - - return; + struct wined3d_surface *s = surface_from_resource(texture->sub_resources[i]); + surface_prepare_texture_internal(s, context, srgb); } - surface_prepare_texture_internal(surface, context, srgb); + return; } void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample) @@ -4457,7 +3590,7 @@ void d3dfmt_p8_init_palette(const struct wined3d_surface *surface, BYTE table[25 * is slow. Further RGB->P8 conversion is not possible because palettes can have * duplicate entries. Store the color key in the unused alpha component to speed the * download up and to make conversion unneeded. */ - index_in_alpha = primary_render_target_is_p8(device); + index_in_alpha = swapchain_is_p8(device->swapchains[0]); if (!pal) { @@ -4481,15 +3614,15 @@ void d3dfmt_p8_init_palette(const struct wined3d_surface *surface, BYTE table[25 /* When index_in_alpha is set the palette index is stored in the * alpha component. In case of a readback we can then read - * GL_ALPHA. Color keying is handled in BltOverride using a + * GL_ALPHA. Color keying is handled in surface_blt_special() using a * GL_ALPHA_TEST using GL_NOT_EQUAL. In case of index_in_alpha the * color key itself is passed to glAlphaFunc in other cases the * alpha component of pixels that should be masked away is set to 0. */ if (index_in_alpha) table[i][3] = i; - else if (colorkey && color_in_range(&surface->src_blt_color_key, i)) + else if (colorkey && color_in_range(&surface->container->src_blt_color_key, i)) table[i][3] = 0x00; - else if (pal->flags & WINEDDPCAPS_ALPHA) + else if (pal->flags & WINED3D_PALETTE_ALPHA) table[i][3] = pal->palents[i].peFlags; else table[i][3] = 0xff; @@ -4562,7 +3695,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI for (x = 0; x < width; x++ ) { WORD color = *Source++; *Dest = ((color & 0xffc0) | ((color & 0x1f) << 1)); - if (!color_in_range(&surface->src_blt_color_key, color)) + if (!color_in_range(&surface->container->src_blt_color_key, color)) *Dest |= 0x0001; Dest++; } @@ -4583,7 +3716,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI for (x = 0; x < width; x++ ) { WORD color = *Source++; *Dest = color; - if (!color_in_range(&surface->src_blt_color_key, color)) + if (!color_in_range(&surface->container->src_blt_color_key, color)) *Dest |= (1 << 15); else *Dest &= ~(1 << 15); @@ -4604,7 +3737,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI for (x = 0; x < width; x++) { DWORD color = ((DWORD)source[0] << 16) + ((DWORD)source[1] << 8) + (DWORD)source[2] ; DWORD dstcolor = color << 8; - if (!color_in_range(&surface->src_blt_color_key, color)) + if (!color_in_range(&surface->container->src_blt_color_key, color)) dstcolor |= 0xff; *(DWORD*)dest = dstcolor; source += 3; @@ -4625,7 +3758,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI for (x = 0; x < width; x++) { DWORD color = 0xffffff & *(const DWORD*)source; DWORD dstcolor = color << 8; - if (!color_in_range(&surface->src_blt_color_key, color)) + if (!color_in_range(&surface->container->src_blt_color_key, color)) dstcolor |= 0xff; *(DWORD*)dest = dstcolor; source += 4; @@ -4645,7 +3778,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI for (x = 0; x < width; ++x) { DWORD color = *(const DWORD *)source; - if (color_in_range(&surface->src_blt_color_key, color)) + if (color_in_range(&surface->container->src_blt_color_key, color)) color &= ~0xff000000; *(DWORD*)dest = color; source += 4; @@ -4663,6 +3796,10 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) { + if (front->container->level_count != 1 || front->container->layer_count != 1 + || back->container->level_count != 1 || back->container->layer_count != 1) + ERR("Flip between surfaces %p and %p not supported.\n", front, back); + /* Flip the surface contents */ /* Flip the DC */ { @@ -4687,10 +3824,6 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) front->dib.bitmap_data = back->dib.bitmap_data; back->dib.bitmap_data = tmp; - tmp = front->resource.allocatedMemory; - front->resource.allocatedMemory = back->resource.allocatedMemory; - back->resource.allocatedMemory = tmp; - tmp = front->resource.heap_memory; front->resource.heap_memory = back->resource.heap_memory; back->resource.heap_memory = tmp; @@ -4707,13 +3840,13 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) { GLuint tmp; - tmp = back->texture_name; - back->texture_name = front->texture_name; - front->texture_name = tmp; + tmp = back->container->texture_rgb.name; + back->container->texture_rgb.name = front->container->texture_rgb.name; + front->container->texture_rgb.name = tmp; - tmp = back->texture_name_srgb; - back->texture_name_srgb = front->texture_name_srgb; - front->texture_name_srgb = tmp; + tmp = back->container->texture_srgb.name; + back->container->texture_srgb.name = front->container->texture_srgb.name; + front->container->texture_srgb.name = tmp; tmp = back->rb_multisample; back->rb_multisample = front->rb_multisample; @@ -4731,6 +3864,10 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) DWORD tmp_flags = back->flags; back->flags = front->flags; front->flags = tmp_flags; + + tmp_flags = back->locations; + back->locations = front->locations; + front->locations = tmp_flags; } } @@ -4745,12 +3882,6 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc struct wined3d_context *context; BOOL upsidedown = FALSE; RECT dst_rect = *dst_rect_in; - GLenum dst_target; - - if (dst_surface->container) - dst_target = dst_surface->container->target; - else - dst_target = dst_surface->texture_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 @@ -4765,10 +3896,10 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc context = context_acquire(device, src_surface); gl_info = context->gl_info; context_apply_blit_state(context, device); - surface_internal_preload(dst_surface, SRGB_RGB); + wined3d_texture_load(dst_surface->container, context, FALSE); /* Bind the target texture */ - context_bind_texture(context, dst_target, dst_surface->texture_name); + context_bind_texture(context, dst_surface->container->target, dst_surface->container->texture_rgb.name); if (surface_is_offscreen(src_surface)) { TRACE("Reading from an offscreen target\n"); @@ -4844,10 +3975,10 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc context_release(context); - /* The texture is now most up to date - If the surface is a render target and has a drawable, this - * path is never entered - */ - surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE); + /* The texture is now most up to date - If the surface is a render target + * and has a drawable, this path is never entered. */ + surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); + surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); } /* Uses the hardware to stretch and flip the image */ @@ -4873,14 +4004,14 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st context = context_acquire(device, src_surface); gl_info = context->gl_info; context_apply_blit_state(context, device); - surface_internal_preload(dst_surface, SRGB_RGB); + wined3d_texture_load(dst_surface->container, context, FALSE); src_offscreen = surface_is_offscreen(src_surface); noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO; - if (!noBackBufferBackup && !src_surface->texture_name) + if (!noBackBufferBackup && !src_surface->container->texture_rgb.name) { /* Get it a description */ - surface_internal_preload(src_surface, SRGB_RGB); + wined3d_texture_load(src_surface->container, context, FALSE); } /* Try to use an aux buffer for drawing the rectangle. This way it doesn't need restoring. @@ -4910,12 +4041,12 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st * we are reading from the back buffer, the backup can be used as source texture */ texture_target = src_surface->texture_target; - context_bind_texture(context, texture_target, src_surface->texture_name); + context_bind_texture(context, texture_target, src_surface->container->texture_rgb.name); gl_info->gl_ops.gl.p_glEnable(texture_target); checkGLcall("glEnable(texture_target)"); /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ - src_surface->flags &= ~SFLAG_INTEXTURE; + src_surface->locations &= ~WINED3D_LOCATION_TEXTURE_RGB; } /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag @@ -4954,7 +4085,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st if (!src_surface->swapchain || src_surface == src_surface->swapchain->back_buffers[0]) { - src = backup ? backup : src_surface->texture_name; + src = backup ? backup : src_surface->container->texture_rgb.name; } else { @@ -5046,7 +4177,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st } /* Now read the stretched and upside down image into the destination texture */ - context_bind_texture(context, texture_target, dst_surface->texture_name); + context_bind_texture(context, texture_target, dst_surface->container->texture_rgb.name); gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, 0, dst_rect.left, dst_rect.top, /* xoffset, yoffset */ @@ -5075,7 +4206,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st gl_info->gl_ops.gl.p_glEnable(src_surface->texture_target); texture_target = src_surface->texture_target; } - context_bind_texture(context, src_surface->texture_target, src_surface->texture_name); + context_bind_texture(context, src_surface->texture_target, src_surface->container->texture_rgb.name); } gl_info->gl_ops.gl.p_glBegin(GL_QUADS); @@ -5101,7 +4232,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st checkGLcall("glDisable(texture_target)"); /* Cleanup */ - if (src != src_surface->texture_name && src != backup) + if (src != src_surface->container->texture_rgb.name && src != backup) { gl_info->gl_ops.gl.p_glDeleteTextures(1, &src); checkGLcall("glDeleteTextures(1, &src)"); @@ -5117,10 +4248,10 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st context_release(context); - /* The texture is now most up to date - If the surface is a render target and has a drawable, this - * path is never entered - */ - surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE); + /* The texture is now most up to date - If the surface is a render target + * and has a drawable, this path is never entered. */ + surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); + surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); } /* Front buffer coordinates are always full screen coordinates, but our GL @@ -5152,7 +4283,7 @@ void surface_translate_drawable_coords(const struct wined3d_surface *surface, HW } static void surface_blt_to_drawable(const struct wined3d_device *device, - enum wined3d_texture_filter_type filter, BOOL color_key, + enum wined3d_texture_filter_type filter, BOOL alpha_test, struct wined3d_surface *src_surface, const RECT *src_rect_in, struct wined3d_surface *dst_surface, const RECT *dst_rect_in) { @@ -5163,14 +4294,15 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, src_rect = *src_rect_in; dst_rect = *dst_rect_in; + context = context_acquire(device, dst_surface); + gl_info = context->gl_info; + /* Make sure the surface is up-to-date. This should probably use * surface_load_location() and worry about the destination surface too, * unless we're overwriting it completely. */ - surface_internal_preload(src_surface, SRGB_RGB); + wined3d_texture_load(src_surface->container, context, FALSE); /* Activate the destination context, set it up for blitting */ - context = context_acquire(device, dst_surface); - gl_info = context->gl_info; context_apply_blit_state(context, device); if (!surface_is_offscreen(dst_surface)) @@ -5178,7 +4310,7 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, device->blitter->set_shader(device->blit_priv, context, src_surface); - if (color_key) + if (alpha_test) { gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST); checkGLcall("glEnable(GL_ALPHA_TEST)"); @@ -5187,9 +4319,9 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, * contains the palette index. Which means that the colorkey is one of * the palette entries. In other cases pixels that should be masked * away have alpha set to 0. */ - if (primary_render_target_is_p8(device)) + if (swapchain_is_p8(context->swapchain)) gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, - (float)src_surface->src_blt_color_key.color_space_low_value / 256.0f); + (float)src_surface->container->src_blt_color_key.color_space_low_value / 256.0f); else gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f); checkGLcall("glAlphaFunc"); @@ -5202,7 +4334,7 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, draw_textured_quad(src_surface, context, &src_rect, &dst_rect, filter); - if (color_key) + if (alpha_test) { gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); checkGLcall("glDisable(GL_ALPHA_TEST)"); @@ -5218,7 +4350,6 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, context_release(context); } -/* Do not call while under the GL lock. */ HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const struct wined3d_color *color) { struct wined3d_device *device = s->resource.device; @@ -5235,8 +4366,7 @@ HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const st return blitter->color_fill(device, s, rect, color); } -/* Do not call while under the GL lock. */ -static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surface, const RECT *dst_rect, +static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RECT *dst_rect, struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const WINEDDBLTFX *DDBltFx, enum wined3d_texture_filter_type filter) { @@ -5341,9 +4471,9 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surfa /* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot * flip the image nor scale it. * - * -> If the app asks for a unscaled, upside down copy, just perform one glCopyTexSubImage2D call - * -> If the app wants a image width an unscaled width, copy it line per line - * -> If the app wants a image that is scaled on the x axis, and the destination rectangle is smaller + * -> If the app asks for an unscaled, upside down copy, just perform one glCopyTexSubImage2D call + * -> If the app wants an image width an unscaled width, copy it line per line + * -> If the app wants an image that is scaled on the x axis, and the destination rectangle is smaller * than the frame buffer, draw an upside down scaled image onto the fb, read it back and restore the * 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 @@ -5360,24 +4490,15 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surfa fb_copy_to_texture_hwstretch(dst_surface, src_surface, src_rect, dst_rect, filter); } - if (!dst_surface->resource.map_count && !(dst_surface->flags & SFLAG_DONOTFREE)) - { - wined3d_resource_free_sysmem(dst_surface->resource.heap_memory); - dst_surface->resource.allocatedMemory = NULL; - dst_surface->resource.heap_memory = NULL; - } - else - { - dst_surface->flags &= ~SFLAG_INSYSMEM; - } + surface_evict_sysmem(dst_surface); return WINED3D_OK; } else if (src_surface) { /* Blit from offscreen surface to render target */ - struct wined3d_color_key old_blt_key = src_surface->src_blt_color_key; - DWORD oldCKeyFlags = src_surface->CKeyFlags; + struct wined3d_color_key old_blt_key = src_surface->container->src_blt_color_key; + DWORD old_color_key_flags = src_surface->container->color_key_flags; TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface); @@ -5403,23 +4524,25 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surfa else if (flags & WINEDDBLT_KEYSRCOVERRIDE) { /* Use color key from DDBltFx */ - src_surface->CKeyFlags |= WINEDDSD_CKSRCBLT; - src_surface->src_blt_color_key = DDBltFx->ddckSrcColorkey; + src_surface->container->color_key_flags |= WINEDDSD_CKSRCBLT; + src_surface->container->src_blt_color_key = DDBltFx->ddckSrcColorkey; } else { /* Do not use color key */ - src_surface->CKeyFlags &= ~WINEDDSD_CKSRCBLT; + src_surface->container->color_key_flags &= ~WINEDDSD_CKSRCBLT; } - surface_blt_to_drawable(device, filter, flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE), + surface_blt_to_drawable(device, filter, + flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_ALPHATEST), src_surface, src_rect, dst_surface, dst_rect); /* Restore the color key parameters */ - src_surface->CKeyFlags = oldCKeyFlags; - src_surface->src_blt_color_key = old_blt_key; + src_surface->container->color_key_flags = old_color_key_flags; + src_surface->container->src_blt_color_key = old_blt_key; - surface_modify_location(dst_surface, dst_surface->draw_binding, TRUE); + surface_validate_location(dst_surface, dst_surface->draw_binding); + surface_invalidate_location(dst_surface, ~dst_surface->draw_binding); return WINED3D_OK; } @@ -5494,23 +4617,13 @@ void surface_modify_ds_location(struct wined3d_surface *surface, { TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h); - if (location & ~(SFLAG_LOCATIONS | SFLAG_DISCARDED)) - FIXME("Invalid location (%#x) specified.\n", location); - - if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE)) - || (!(surface->flags & SFLAG_INTEXTURE) && (location & SFLAG_INTEXTURE))) - { - if (surface->container) - { - TRACE("Passing to container.\n"); - wined3d_texture_set_dirty(surface->container, TRUE); - } - } + if (((surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB)) + || (!(surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && (location & WINED3D_LOCATION_TEXTURE_RGB))) + wined3d_texture_set_dirty(surface->container); surface->ds_current_size.cx = w; surface->ds_current_size.cy = h; - surface->flags &= ~(SFLAG_LOCATIONS | SFLAG_DISCARDED); - surface->flags |= location; + surface->locations = location; } /* Context activation is done by the caller. */ @@ -5525,7 +4638,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co /* TODO: Make this work for modes other than FBO */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; - if (!(surface->flags & location)) + if (!(surface->locations & location)) { w = surface->ds_current_size.cx; h = surface->ds_current_size.cy; @@ -5551,40 +4664,40 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co return; } - if (surface->flags & SFLAG_DISCARDED) + if (surface->locations & WINED3D_LOCATION_DISCARDED) { TRACE("Surface was discarded, no need copy data.\n"); switch (location) { - case SFLAG_INTEXTURE: + case WINED3D_LOCATION_TEXTURE_RGB: surface_prepare_texture(surface, context, FALSE); break; - case SFLAG_INRB_MULTISAMPLE: + case WINED3D_LOCATION_RB_MULTISAMPLE: surface_prepare_rb(surface, gl_info, TRUE); break; - case SFLAG_INDRAWABLE: + case WINED3D_LOCATION_DRAWABLE: /* Nothing to do */ break; default: FIXME("Unhandled location %#x\n", location); } - surface->flags &= ~SFLAG_DISCARDED; - surface->flags |= location; + surface->locations &= ~WINED3D_LOCATION_DISCARDED; + surface->locations |= location; surface->ds_current_size.cx = surface->resource.width; surface->ds_current_size.cy = surface->resource.height; return; } - if (!(surface->flags & SFLAG_LOCATIONS)) + if (!surface->locations) { FIXME("No up to date depth stencil location.\n"); - surface->flags |= location; + surface->locations |= location; surface->ds_current_size.cx = surface->resource.width; surface->ds_current_size.cy = surface->resource.height; return; } - if (location == SFLAG_INTEXTURE) + if (location == WINED3D_LOCATION_TEXTURE_RGB) { GLint old_binding = 0; GLenum bind_target; @@ -5604,7 +4717,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co /* Note that we use depth_blt here as well, rather than glCopyTexImage2D * directly on the FBO texture. That's because we need to flip. */ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, - context->swapchain->front_buffer, NULL, SFLAG_INDRAWABLE); + context->swapchain->front_buffer, NULL, WINED3D_LOCATION_DRAWABLE); if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB) { gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); @@ -5633,7 +4746,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co gl_info->gl_ops.gl.p_glBindTexture(bind_target, old_binding); context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, - NULL, surface, SFLAG_INTEXTURE); + NULL, surface, WINED3D_LOCATION_TEXTURE_RGB); context_set_draw_buffer(context, GL_NONE); /* Do the actual blit */ @@ -5645,13 +4758,13 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co if (wined3d_settings.strict_draw_ordering) gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ } - else if (location == SFLAG_INDRAWABLE) + else if (location == WINED3D_LOCATION_DRAWABLE) { TRACE("Copying depth texture to onscreen depth buffer.\n"); context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, - context->swapchain->front_buffer, NULL, SFLAG_INDRAWABLE); - surface_depth_blt(surface, context, surface->texture_name, + context->swapchain->front_buffer, NULL, WINED3D_LOCATION_DRAWABLE); + surface_depth_blt(surface, context, surface->container->texture_rgb.name, 0, surface->pow2Height - h, w, h, surface->texture_target); checkGLcall("depth_blt"); @@ -5665,82 +4778,45 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co ERR("Invalid location (%#x) specified.\n", location); } - surface->flags |= location; + surface->locations |= location; surface->ds_current_size.cx = surface->resource.width; surface->ds_current_size.cy = surface->resource.height; } -void surface_modify_location(struct wined3d_surface *surface, DWORD location, BOOL persistent) +void surface_validate_location(struct wined3d_surface *surface, DWORD location) { - const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; - struct wined3d_surface *overlay; + TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); - TRACE("surface %p, location %s, persistent %#x.\n", - surface, debug_surflocation(location), persistent); + surface->locations |= location; +} - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && surface_is_offscreen(surface) - && !(surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) - && (location & SFLAG_INDRAWABLE)) - ERR("Trying to invalidate the SFLAG_INDRAWABLE location of an offscreen surface.\n"); +void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) +{ + TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); - if (location & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX) - && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - location |= (SFLAG_INTEXTURE | SFLAG_INSRGBTEX); + if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + wined3d_texture_set_dirty(surface->container); + surface->locations &= ~location; - if (persistent) - { - if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE)) - || ((surface->flags & SFLAG_INSRGBTEX) && !(location & SFLAG_INSRGBTEX))) - { - if (surface->container) - { - TRACE("Passing to container.\n"); - wined3d_texture_set_dirty(surface->container, TRUE); - } - } - surface->flags &= ~SFLAG_LOCATIONS; - surface->flags |= location; - - /* Redraw emulated overlays, if any */ - if (location & SFLAG_INDRAWABLE && !list_empty(&surface->overlays)) - { - LIST_FOR_EACH_ENTRY(overlay, &surface->overlays, struct wined3d_surface, overlay_entry) - { - surface_draw_overlay(overlay); - } - } - } - else - { - if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (location & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX))) - { - if (surface->container) - { - TRACE("Passing to container\n"); - wined3d_texture_set_dirty(surface->container, TRUE); - } - } - surface->flags &= ~location; - } - - if (!(surface->flags & SFLAG_LOCATIONS)) - { + if (!surface->locations) ERR("Surface %p does not have any up to date location.\n", surface); - } } static DWORD resource_access_from_location(DWORD location) { switch (location) { - case SFLAG_INSYSMEM: + case WINED3D_LOCATION_SYSMEM: + case WINED3D_LOCATION_USER_MEMORY: + case WINED3D_LOCATION_DIB: + case WINED3D_LOCATION_BUFFER: return WINED3D_RESOURCE_ACCESS_CPU; - case SFLAG_INDRAWABLE: - case SFLAG_INSRGBTEX: - case SFLAG_INTEXTURE: - case SFLAG_INRB_MULTISAMPLE: - case SFLAG_INRB_RESOLVED: + case WINED3D_LOCATION_DRAWABLE: + case WINED3D_LOCATION_TEXTURE_SRGB: + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_RB_MULTISAMPLE: + case WINED3D_LOCATION_RB_RESOLVED: return WINED3D_RESOURCE_ACCESS_GPU; default: @@ -5749,16 +4825,56 @@ static DWORD resource_access_from_location(DWORD location) } } -static void surface_load_sysmem(struct wined3d_surface *surface, - const struct wined3d_gl_info *gl_info, const RECT *rect) +static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) { - surface_prepare_system_memory(surface); + struct wined3d_device *device = surface->resource.device; + struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + struct wined3d_bo_address dst, src; + UINT size = surface->resource.size; - if (surface->flags & (SFLAG_INRB_MULTISAMPLE | SFLAG_INRB_RESOLVED)) - surface_load_location(surface, SFLAG_INTEXTURE, NULL); + surface_get_memory(surface, &dst, location); + surface_get_memory(surface, &src, surface->locations); + + if (dst.buffer_object) + { + context = context_acquire(device, NULL); + gl_info = context->gl_info; + GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, dst.buffer_object)); + GL_EXTCALL(glBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, size, src.addr)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + checkGLcall("Upload PBO"); + context_release(context); + return; + } + if (src.buffer_object) + { + context = context_acquire(device, NULL); + gl_info = context->gl_info; + GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, src.buffer_object)); + GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_PACK_BUFFER_ARB, 0, size, dst.addr)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); + checkGLcall("Download PBO"); + context_release(context); + return; + } + memcpy(dst.addr, src.addr, size); +} + +static void surface_load_sysmem(struct wined3d_surface *surface, + const struct wined3d_gl_info *gl_info, DWORD dst_location) +{ + if (surface->locations & surface_simple_locations) + { + surface_copy_simple_location(surface, dst_location); + return; + } + + if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) + surface_load_location(surface, WINED3D_LOCATION_TEXTURE_RGB); /* Download the surface to system memory. */ - if (surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) + if (surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { struct wined3d_device *device = surface->resource.device; struct wined3d_context *context; @@ -5766,38 +4882,38 @@ static void surface_load_sysmem(struct wined3d_surface *surface, /* TODO: Use already acquired context when possible. */ context = context_acquire(device, NULL); - surface_bind_and_dirtify(surface, context, !(surface->flags & SFLAG_INTEXTURE)); - surface_download_data(surface, gl_info); + wined3d_texture_bind_and_dirtify(surface->container, context, + !(surface->locations & WINED3D_LOCATION_TEXTURE_RGB)); + surface_download_data(surface, gl_info, dst_location); context_release(context); return; } - if (surface->flags & SFLAG_INDRAWABLE) + if (surface->locations & WINED3D_LOCATION_DRAWABLE) { - read_from_framebuffer(surface, rect, surface->resource.allocatedMemory, - wined3d_surface_get_pitch(surface)); + read_from_framebuffer(surface, dst_location); return; } - FIXME("Can't load surface %p with location flags %#x into sysmem.\n", - surface, surface->flags & SFLAG_LOCATIONS); + FIXME("Can't load surface %p with location flags %s into sysmem.\n", + surface, wined3d_debug_location(surface->locations)); } static HRESULT surface_load_drawable(struct wined3d_surface *surface, - const struct wined3d_gl_info *gl_info, const RECT *rect) + const struct wined3d_gl_info *gl_info) { RECT r; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && surface_is_offscreen(surface)) { - ERR("Trying to load offscreen surface into SFLAG_INDRAWABLE.\n"); + ERR("Trying to load offscreen surface into WINED3D_LOCATION_DRAWABLE.\n"); return WINED3DERR_INVALIDCALL; } - surface_get_rect(surface, rect, &r); - surface_load_location(surface, SFLAG_INTEXTURE, NULL); + surface_get_rect(surface, NULL, &r); + surface_load_location(surface, WINED3D_LOCATION_TEXTURE_RGB); surface_blt_to_drawable(surface->resource.device, WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r); @@ -5805,7 +4921,7 @@ static HRESULT surface_load_drawable(struct wined3d_surface *surface, } static HRESULT surface_load_texture(struct wined3d_surface *surface, - const struct wined3d_gl_info *gl_info, const RECT *rect, BOOL srgb) + const struct wined3d_gl_info *gl_info, BOOL srgb) { RECT src_rect = {0, 0, surface->resource.width, surface->resource.height}; struct wined3d_device *device = surface->resource.device; @@ -5815,41 +4931,42 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, struct wined3d_bo_address data; struct wined3d_format format; POINT dst_point = {0, 0}; - BYTE *mem; + BYTE *mem = NULL; if (wined3d_settings.offscreen_rendering_mode != ORM_FBO && surface_is_offscreen(surface) - && (surface->flags & SFLAG_INDRAWABLE)) + && (surface->locations & WINED3D_LOCATION_DRAWABLE)) { surface_load_fb_texture(surface, srgb); return WINED3D_OK; } - if (surface->flags & (SFLAG_INSRGBTEX | SFLAG_INTEXTURE) + if (surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) && (surface->resource.format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) { if (srgb) - surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, SFLAG_INTEXTURE, - &src_rect, surface, SFLAG_INSRGBTEX, &src_rect); + surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB, + &src_rect, surface, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect); else - surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, SFLAG_INSRGBTEX, - &src_rect, surface, SFLAG_INTEXTURE, &src_rect); + surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_SRGB, + &src_rect, surface, WINED3D_LOCATION_TEXTURE_RGB, &src_rect); return WINED3D_OK; } - if (surface->flags & (SFLAG_INRB_MULTISAMPLE | SFLAG_INRB_RESOLVED) + if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) && (!srgb || (surface->resource.format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)) && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) { - DWORD src_location = surface->flags & SFLAG_INRB_RESOLVED ? SFLAG_INRB_RESOLVED : SFLAG_INRB_MULTISAMPLE; - DWORD dst_location = srgb ? SFLAG_INSRGBTEX : SFLAG_INTEXTURE; + DWORD src_location = surface->locations & WINED3D_LOCATION_RB_RESOLVED ? + WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE; + DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; RECT rect = {0, 0, surface->resource.width, surface->resource.height}; surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, src_location, @@ -5865,40 +4982,45 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, if (srgb) { - if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE) + if ((surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->map_binding)) + == WINED3D_LOCATION_TEXTURE_RGB) { /* Performance warning... */ FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface); - surface_load_location(surface, SFLAG_INSYSMEM, rect); + surface_prepare_map_memory(surface); + surface_load_location(surface, surface->map_binding); } } else { - if ((surface->flags & (SFLAG_INSRGBTEX | SFLAG_INSYSMEM)) == SFLAG_INSRGBTEX) + if ((surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | surface->map_binding)) + == WINED3D_LOCATION_TEXTURE_SRGB) { /* Performance warning... */ FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface); - surface_load_location(surface, SFLAG_INSYSMEM, rect); + surface_prepare_map_memory(surface); + surface_load_location(surface, surface->map_binding); } } - if (!(surface->flags & SFLAG_INSYSMEM)) + if (!(surface->locations & surface_simple_locations)) { - WARN("Trying to load a texture from sysmem, but SFLAG_INSYSMEM is not set.\n"); + WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); /* Lets hope we get it from somewhere... */ - surface_load_location(surface, SFLAG_INSYSMEM, rect); + surface_prepare_system_memory(surface); + surface_load_location(surface, WINED3D_LOCATION_SYSMEM); } /* TODO: Use already acquired context when possible. */ context = context_acquire(device, NULL); surface_prepare_texture(surface, context, srgb); - surface_bind_and_dirtify(surface, context, srgb); + wined3d_texture_bind_and_dirtify(surface->container, context, srgb); - if (surface->CKeyFlags & WINEDDSD_CKSRCBLT) + if (surface->container->color_key_flags & WINEDDSD_CKSRCBLT) { surface->flags |= SFLAG_GLCKEY; - surface->gl_color_key = surface->src_blt_color_key; + surface->gl_color_key = surface->container->src_blt_color_key; } else surface->flags &= ~SFLAG_GLCKEY; @@ -5908,12 +5030,21 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, /* Don't use PBOs for converted surfaces. During PBO conversion we look at * SFLAG_CONVERTED but it isn't set (yet) in all cases it is getting * called. */ - if ((convert != WINED3D_CT_NONE || format.convert) && (surface->flags & SFLAG_PBO)) + if ((convert != WINED3D_CT_NONE || format.convert) && surface->pbo) { TRACE("Removing the pbo attached to surface %p.\n", surface); + + if (surface->flags & SFLAG_DIBSECTION) + surface->map_binding = WINED3D_LOCATION_DIB; + else + surface->map_binding = WINED3D_LOCATION_SYSMEM; + + surface_prepare_map_memory(surface); + surface_load_location(surface, surface->map_binding); surface_remove_pbo(surface, gl_info); } + surface_get_memory(surface, &data, surface->locations); if (format.convert) { /* This code is entered for texture formats which need a fixup. */ @@ -5929,11 +5060,13 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, context_release(context); return E_OUTOFMEMORY; } - format.convert(surface->resource.allocatedMemory, mem, src_pitch, width, height); + format.convert(data.addr, mem, src_pitch, src_pitch * height, + dst_pitch, dst_pitch * height, width, height, 1); format.byte_count = format.conv_byte_count; src_pitch = dst_pitch; + data.addr = mem; } - else if (convert != WINED3D_CT_NONE && surface->resource.allocatedMemory) + else if (convert != WINED3D_CT_NONE) { /* This code is only entered for color keying fixups */ UINT height = surface->resource.height; @@ -5948,25 +5081,18 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, context_release(context); return E_OUTOFMEMORY; } - d3dfmt_convert_surface(surface->resource.allocatedMemory, mem, src_pitch, + d3dfmt_convert_surface(data.addr, mem, src_pitch, width, height, dst_pitch, convert, surface); format.byte_count = format.conv_byte_count; src_pitch = dst_pitch; - } - else - { - mem = surface->resource.allocatedMemory; + data.addr = mem; } - data.buffer_object = surface->pbo; - data.addr = mem; surface_upload_data(surface, gl_info, &format, &src_rect, src_pitch, &dst_point, srgb, &data); context_release(context); - /* Don't delete PBO memory. */ - if ((mem != surface->resource.allocatedMemory) && !(surface->flags & SFLAG_PBO)) - HeapFree(GetProcessHeap(), 0, mem); + HeapFree(GetProcessHeap(), 0, mem); return WINED3D_OK; } @@ -5975,31 +5101,32 @@ static void surface_multisample_resolve(struct wined3d_surface *surface) { RECT rect = {0, 0, surface->resource.width, surface->resource.height}; - if (!(surface->flags & SFLAG_INRB_MULTISAMPLE)) - ERR("Trying to resolve multisampled surface %p, but location SFLAG_INRB_MULTISAMPLE not current.\n", surface); + if (!(surface->locations & WINED3D_LOCATION_RB_MULTISAMPLE)) + ERR("Trying to resolve multisampled surface %p, but location WINED3D_LOCATION_RB_MULTISAMPLE not current.\n", + surface); surface_blt_fbo(surface->resource.device, WINED3D_TEXF_POINT, - surface, SFLAG_INRB_MULTISAMPLE, &rect, surface, SFLAG_INRB_RESOLVED, &rect); + surface, WINED3D_LOCATION_RB_MULTISAMPLE, &rect, surface, WINED3D_LOCATION_RB_RESOLVED, &rect); } -HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, const RECT *rect) +HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location) { struct wined3d_device *device = surface->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; HRESULT hr; - TRACE("surface %p, location %s, rect %s.\n", surface, debug_surflocation(location), wine_dbgstr_rect(rect)); + TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) { - if (location == SFLAG_INTEXTURE && surface->flags & SFLAG_INDRAWABLE) + if (location == WINED3D_LOCATION_TEXTURE_RGB && surface->locations & WINED3D_LOCATION_DRAWABLE) { struct wined3d_context *context = context_acquire(device, NULL); surface_load_ds_location(surface, context, location); context_release(context); return WINED3D_OK; } - else if (location & surface->flags && surface->draw_binding != SFLAG_INDRAWABLE) + else if (location & surface->locations && surface->draw_binding != WINED3D_LOCATION_DRAWABLE) { /* Already up to date, nothing to do. */ return WINED3D_OK; @@ -6007,22 +5134,14 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, c else { FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n", - debug_surflocation(surface->flags & SFLAG_LOCATIONS), debug_surflocation(location)); + wined3d_debug_location(surface->locations), wined3d_debug_location(location)); return WINED3DERR_INVALIDCALL; } } - if (location == SFLAG_INSRGBTEX && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - location = SFLAG_INTEXTURE; - - if (surface->flags & location) + if (surface->locations & location) { TRACE("Location already up to date.\n"); - - if (location == SFLAG_INSYSMEM && !(surface->flags & SFLAG_PBO) - && surface_need_pbo(surface, gl_info)) - surface_load_pbo(surface, gl_info); - return WINED3D_OK; } @@ -6034,7 +5153,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, c required_access, surface->resource.access_flags); } - if (!(surface->flags & SFLAG_LOCATIONS)) + if (!surface->locations) { ERR("Surface %p does not have any up to date location.\n", surface); surface->flags |= SFLAG_LOST; @@ -6043,22 +5162,25 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, c switch (location) { - case SFLAG_INSYSMEM: - surface_load_sysmem(surface, gl_info, rect); + case WINED3D_LOCATION_DIB: + case WINED3D_LOCATION_USER_MEMORY: + case WINED3D_LOCATION_SYSMEM: + case WINED3D_LOCATION_BUFFER: + surface_load_sysmem(surface, gl_info, location); break; - case SFLAG_INDRAWABLE: - if (FAILED(hr = surface_load_drawable(surface, gl_info, rect))) + case WINED3D_LOCATION_DRAWABLE: + if (FAILED(hr = surface_load_drawable(surface, gl_info))) return hr; break; - case SFLAG_INRB_RESOLVED: + case WINED3D_LOCATION_RB_RESOLVED: surface_multisample_resolve(surface); break; - case SFLAG_INTEXTURE: - case SFLAG_INSRGBTEX: - if (FAILED(hr = surface_load_texture(surface, gl_info, rect, location == SFLAG_INSRGBTEX))) + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: + if (FAILED(hr = surface_load_texture(surface, gl_info, location == WINED3D_LOCATION_TEXTURE_SRGB))) return hr; break; @@ -6067,19 +5189,10 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, c break; } - if (!rect) - { - surface->flags |= location; + surface_validate_location(surface, location); - if (location != SFLAG_INSYSMEM && (surface->flags & SFLAG_INSYSMEM)) - surface_evict_sysmem(surface); - } - - if (surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX) - && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - { - surface->flags |= (SFLAG_INTEXTURE | SFLAG_INSRGBTEX); - } + if (location != WINED3D_LOCATION_SYSMEM && (surface->locations & WINED3D_LOCATION_SYSMEM)) + surface_evict_sysmem(surface); return WINED3D_OK; } @@ -6108,14 +5221,8 @@ static void ffp_blit_free(struct wined3d_device *device) { } static HRESULT ffp_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface) { const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum target; - if (surface->container) - target = surface->container->target; - else - target = surface->texture_target; - - gl_info->gl_ops.gl.p_glEnable(target); + gl_info->gl_ops.gl.p_glEnable(surface->container->target); checkGLcall("glEnable(target)"); return WINED3D_OK; @@ -6193,7 +5300,6 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, enum wined } } -/* Do not call while under the GL lock. */ static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, const RECT *dst_rect, const struct wined3d_color *color) { @@ -6205,7 +5311,6 @@ static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d return WINED3D_OK; } -/* Do not call while under the GL lock. */ static HRESULT ffp_blit_depth_fill(struct wined3d_device *device, struct wined3d_surface *surface, const RECT *rect, float depth) { @@ -6368,7 +5473,7 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * { int bpp, srcheight, srcwidth, dstheight, dstwidth, width; const struct wined3d_format *src_format, *dst_format; - struct wined3d_surface *orig_src = src_surface; + struct wined3d_texture *src_texture = NULL; struct wined3d_map_desc dst_map, src_map; const BYTE *sbase = NULL; HRESULT hr = WINED3D_OK; @@ -6394,13 +5499,13 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * { if (dst_surface->resource.format->id != src_surface->resource.format->id) { - src_surface = surface_convert_format(src_surface, dst_format->id); - if (!src_surface) + if (!(src_texture = surface_convert_format(src_surface, dst_format->id))) { /* The conv function writes a FIXME */ WARN("Cannot convert source surface format to dest format.\n"); goto release; } + src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, 0)); } wined3d_surface_map(src_surface, &src_map, NULL, WINED3D_MAP_READONLY); src_format = src_surface->resource.format; @@ -6654,8 +5759,8 @@ do { \ /* The color keying flags are checked for correctness in ddraw */ if (flags & WINEDDBLT_KEYSRC) { - keylow = src_surface->src_blt_color_key.color_space_low_value; - keyhigh = src_surface->src_blt_color_key.color_space_high_value; + keylow = src_surface->container->src_blt_color_key.color_space_low_value; + keyhigh = src_surface->container->src_blt_color_key.color_space_high_value; } else if (flags & WINEDDBLT_KEYSRCOVERRIDE) { @@ -6666,8 +5771,8 @@ do { \ if (flags & WINEDDBLT_KEYDEST) { /* Destination color keys are taken from the source surface! */ - destkeylow = src_surface->dst_blt_color_key.color_space_low_value; - destkeyhigh = src_surface->dst_blt_color_key.color_space_high_value; + destkeylow = src_surface->container->dst_blt_color_key.color_space_low_value; + destkeyhigh = src_surface->container->dst_blt_color_key.color_space_high_value; } else if (flags & WINEDDBLT_KEYDESTOVERRIDE) { @@ -6854,13 +5959,12 @@ release: if (src_surface && src_surface != dst_surface) wined3d_surface_unmap(src_surface); /* Release the converted surface, if any. */ - if (src_surface && src_surface != orig_src) - wined3d_surface_decref(src_surface); + if (src_texture) + wined3d_texture_decref(src_texture); return hr; } -/* Do not call while under the GL lock. */ static HRESULT cpu_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, const RECT *dst_rect, const struct wined3d_color *color) { @@ -6874,7 +5978,6 @@ static HRESULT cpu_blit_color_fill(struct wined3d_device *device, struct wined3d WINEDDBLT_COLORFILL, &BltFx, WINED3D_TEXF_POINT); } -/* Do not call while under the GL lock. */ static HRESULT cpu_blit_depth_fill(struct wined3d_device *device, struct wined3d_surface *surface, const RECT *rect, float depth) { @@ -6892,13 +5995,322 @@ const struct blit_shader cpu_blit = { cpu_blit_depth_fill, }; -static HRESULT surface_init(struct wined3d_surface *surface, UINT alignment, UINT width, UINT height, - enum wined3d_multisample_type multisample_type, UINT multisample_quality, - struct wined3d_device *device, DWORD usage, enum wined3d_format_id format_id, - enum wined3d_pool pool, DWORD flags, void *parent, const struct wined3d_parent_ops *parent_ops) +HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, + struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, + const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) { + struct wined3d_swapchain *src_swapchain, *dst_swapchain; + struct wined3d_device *device = dst_surface->resource.device; + DWORD src_ds_flags, dst_ds_flags; + RECT src_rect, dst_rect; + BOOL scale, convert; + enum wined3d_conversion_type dst_convert_type; + struct wined3d_format dst_conv_fmt; + + static const DWORD simple_blit = WINEDDBLT_ASYNC + | WINEDDBLT_COLORFILL + | WINEDDBLT_WAIT + | WINEDDBLT_DEPTHFILL + | WINEDDBLT_DONOTWAIT; + + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in), + flags, fx, debug_d3dtexturefiltertype(filter)); + TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); + + if (fx) + { + TRACE("dwSize %#x.\n", fx->dwSize); + TRACE("dwDDFX %#x.\n", fx->dwDDFX); + TRACE("dwROP %#x.\n", fx->dwROP); + TRACE("dwDDROP %#x.\n", fx->dwDDROP); + TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle); + TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode); + TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow); + TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh); + TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest); + TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth); + TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest); + TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth); + TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc); + TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth); + TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend); + TRACE("dwReserved %#x.\n", fx->dwReserved); + TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth); + TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest); + TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth); + TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc); + TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern); + TRACE("ddckDestColorkey {%#x, %#x}.\n", + fx->ddckDestColorkey.color_space_low_value, + fx->ddckDestColorkey.color_space_high_value); + TRACE("ddckSrcColorkey {%#x, %#x}.\n", + fx->ddckSrcColorkey.color_space_low_value, + fx->ddckSrcColorkey.color_space_high_value); + } + + if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) + { + WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); + return WINEDDERR_SURFACEBUSY; + } + + surface_get_rect(dst_surface, dst_rect_in, &dst_rect); + + if (dst_rect.left >= dst_rect.right || dst_rect.top >= dst_rect.bottom + || dst_rect.left > dst_surface->resource.width || dst_rect.left < 0 + || dst_rect.top > dst_surface->resource.height || dst_rect.top < 0 + || dst_rect.right > dst_surface->resource.width || dst_rect.right < 0 + || dst_rect.bottom > dst_surface->resource.height || dst_rect.bottom < 0) + { + WARN("The application gave us a bad destination rectangle.\n"); + return WINEDDERR_INVALIDRECT; + } + + if (src_surface) + { + surface_get_rect(src_surface, src_rect_in, &src_rect); + + if (src_rect.left >= src_rect.right || src_rect.top >= src_rect.bottom + || src_rect.left > src_surface->resource.width || src_rect.left < 0 + || src_rect.top > src_surface->resource.height || src_rect.top < 0 + || src_rect.right > src_surface->resource.width || src_rect.right < 0 + || src_rect.bottom > src_surface->resource.height || src_rect.bottom < 0) + { + WARN("Application gave us bad source rectangle for Blt.\n"); + return WINEDDERR_INVALIDRECT; + } + } + else + { + memset(&src_rect, 0, sizeof(src_rect)); + } + + if (!fx || !(fx->dwDDFX)) + flags &= ~WINEDDBLT_DDFX; + + if (flags & WINEDDBLT_WAIT) + flags &= ~WINEDDBLT_WAIT; + + if (flags & WINEDDBLT_ASYNC) + { + static unsigned int once; + + if (!once++) + FIXME("Can't handle WINEDDBLT_ASYNC flag.\n"); + flags &= ~WINEDDBLT_ASYNC; + } + + /* WINEDDBLT_DONOTWAIT appeared in DX7. */ + if (flags & WINEDDBLT_DONOTWAIT) + { + static unsigned int once; + + if (!once++) + FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n"); + flags &= ~WINEDDBLT_DONOTWAIT; + } + + if (!device->d3d_initialized) + { + WARN("D3D not initialized, using fallback.\n"); + 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. */ + d3dfmt_get_conv(dst_surface, TRUE, TRUE, &dst_conv_fmt, &dst_convert_type); + if (dst_convert_type != WINED3D_CT_NONE || dst_conv_fmt.convert || dst_surface->flags & SFLAG_CONVERTED) + { + 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); + goto fallback; + } + + if (src_surface) + src_swapchain = src_surface->swapchain; + else + src_swapchain = NULL; + + dst_swapchain = dst_surface->swapchain; + + /* This isn't strictly needed. FBO blits for example could deal with + * cross-swapchain blits by first downloading the source to a texture + * before switching to the destination context. We just have this here to + * not have to deal with the issue, since cross-swapchain blits should be + * rare. */ + if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain) + { + FIXME("Using fallback for cross-swapchain blit.\n"); + goto fallback; + } + + scale = src_surface + && (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_surface && src_surface->resource.format->id != dst_surface->resource.format->id; + + dst_ds_flags = dst_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); + if (src_surface) + src_ds_flags = src_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); + else + src_ds_flags = 0; + + if (src_ds_flags || dst_ds_flags) + { + if (flags & WINEDDBLT_DEPTHFILL) + { + float depth; + + TRACE("Depth fill.\n"); + + if (!surface_convert_depth_to_float(dst_surface, fx->u5.dwFillDepth, &depth)) + return WINED3DERR_INVALIDCALL; + + if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, &dst_rect, depth))) + return WINED3D_OK; + } + else + { + if (src_ds_flags != dst_ds_flags) + { + WARN("Rejecting depth / stencil blit between incompatible formats.\n"); + return WINED3DERR_INVALIDCALL; + } + + if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->draw_binding, &src_rect, + dst_surface, dst_surface->draw_binding, &dst_rect))) + return WINED3D_OK; + } + } + else + { + /* In principle this would apply to depth blits as well, but we don't + * implement those in the CPU blitter at the moment. */ + if ((dst_surface->locations & dst_surface->map_binding) + && (!src_surface || (src_surface->locations & src_surface->map_binding))) + { + if (scale) + TRACE("Not doing sysmem blit because of scaling.\n"); + else if (convert) + TRACE("Not doing sysmem blit because of format conversion.\n"); + else + goto cpu; + } + + if (flags & WINEDDBLT_COLORFILL) + { + struct wined3d_color color; + + TRACE("Color fill.\n"); + + if (!surface_convert_color_to_float(dst_surface, fx->u5.dwFillColor, &color)) + goto fallback; + + if (SUCCEEDED(surface_color_fill(dst_surface, &dst_rect, &color))) + return WINED3D_OK; + } + else + { + TRACE("Color blit.\n"); + + /* Upload */ + if ((src_surface->locations & WINED3D_LOCATION_SYSMEM) + && !(dst_surface->locations & WINED3D_LOCATION_SYSMEM)) + { + if (scale) + TRACE("Not doing upload because of scaling.\n"); + else if (convert) + TRACE("Not doing upload because of format conversion.\n"); + else + { + POINT dst_point = {dst_rect.left, dst_rect.top}; + + if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, &src_rect))) + { + if (!surface_is_offscreen(dst_surface)) + surface_load_location(dst_surface, dst_surface->draw_binding); + return WINED3D_OK; + } + } + } + + /* Use present for back -> front blits. The idea behind this is + * that present is potentially faster than a blit, in particular + * when FBO blits aren't available. Some ddraw applications like + * Half-Life and Prince of Persia 3D use Blt() from the backbuffer + * to the frontbuffer instead of doing a Flip(). D3D8 and D3D9 + * applications can't blit directly to the frontbuffer. */ + if (dst_swapchain && dst_swapchain->back_buffers + && dst_surface == dst_swapchain->front_buffer + && src_surface == dst_swapchain->back_buffers[0]) + { + enum wined3d_swap_effect swap_effect = dst_swapchain->desc.swap_effect; + + TRACE("Using present for backbuffer -> frontbuffer blit.\n"); + + /* 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, NULL, 0); + dst_swapchain->desc.swap_effect = swap_effect; + + return WINED3D_OK; + } + + if (fbo_blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) + { + TRACE("Using FBO blit.\n"); + + surface_blt_fbo(device, filter, + src_surface, src_surface->draw_binding, &src_rect, + dst_surface, dst_surface->draw_binding, &dst_rect); + surface_validate_location(dst_surface, dst_surface->draw_binding); + surface_invalidate_location(dst_surface, ~dst_surface->draw_binding); + + return WINED3D_OK; + } + + if (arbfp_blit.blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) + { + TRACE("Using arbfp blit.\n"); + + if (SUCCEEDED(arbfp_blit_surface(device, filter, src_surface, &src_rect, dst_surface, &dst_rect))) + return WINED3D_OK; + } + } + } + +fallback: + /* Special cases for render targets. */ + if (SUCCEEDED(surface_blt_special(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter))) + return WINED3D_OK; + +cpu: + + /* For the rest call the X11 surface implementation. For render targets + * this should be implemented OpenGL accelerated in surface_blt_special(), + * other blits are rather rare. */ + return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter); +} + +static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_texture *container, + const struct wined3d_resource_desc *desc, DWORD flags) +{ + struct wined3d_device *device = container->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, format_id); + const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format); + UINT multisample_quality = desc->multisample_quality; BOOL lockable = flags & WINED3D_SURFACE_MAPPABLE; unsigned int resource_size; HRESULT hr; @@ -6913,43 +6325,34 @@ static HRESULT surface_init(struct wined3d_surface *surface, UINT alignment, UIN * TODO: remove this after surfaces, usage and lockability have been debugged properly * this function is too deep to need to care about things like this. * Levels need to be checked too, since they all affect what can be done. */ - switch (pool) + switch (desc->pool) { - case WINED3D_POOL_SCRATCH: - if (!lockable) - { - FIXME("Called with a pool of SCRATCH and a lockable of FALSE " - "which are mutually exclusive, setting lockable to TRUE.\n"); - lockable = TRUE; - } - break; - - case WINED3D_POOL_SYSTEM_MEM: - if (!lockable) - FIXME("Called with a pool of SYSTEMMEM and a lockable of FALSE, this is acceptable but unexpected.\n"); - break; - case WINED3D_POOL_MANAGED: - if (usage & WINED3DUSAGE_DYNAMIC) + if (desc->usage & WINED3DUSAGE_DYNAMIC) FIXME("Called with a pool of MANAGED and a usage of DYNAMIC which are mutually exclusive.\n"); break; case WINED3D_POOL_DEFAULT: - if (lockable && !(usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))) + if (lockable && !(desc->usage & (WINED3DUSAGE_DYNAMIC + | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))) WARN("Creating a lockable surface with a POOL of DEFAULT, that doesn't specify DYNAMIC usage.\n"); break; + case WINED3D_POOL_SCRATCH: + case WINED3D_POOL_SYSTEM_MEM: + break; + default: - FIXME("Unknown pool %#x.\n", pool); + FIXME("Unknown pool %#x.\n", desc->pool); break; }; - if (usage & WINED3DUSAGE_RENDERTARGET && pool != WINED3D_POOL_DEFAULT) + 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"); /* FIXME: Check that the format is supported by the device. */ - resource_size = wined3d_format_calculate_size(format, alignment, width, height, 1); + resource_size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, 1); if (!resource_size) return WINED3DERR_INVALIDCALL; @@ -6958,50 +6361,36 @@ static HRESULT surface_init(struct wined3d_surface *surface, UINT alignment, UIN else surface->surface_ops = &surface_ops; - hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE, format, - multisample_type, multisample_quality, usage, pool, width, height, 1, - resource_size, parent, parent_ops, &surface_resource_ops); - if (FAILED(hr)) + if (FAILED(hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE, format, + desc->multisample_type, multisample_quality, desc->usage, desc->pool, desc->width, desc->height, 1, + resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops))) { WARN("Failed to initialize resource, returning %#x.\n", hr); return hr; } - /* "Standalone" surface. */ - surface_set_container(surface, NULL); - + surface_set_container(surface, container); + surface_validate_location(surface, WINED3D_LOCATION_SYSMEM); + list_init(&surface->renderbuffers); list_init(&surface->overlays); /* Flags */ - surface->flags = SFLAG_NORMCOORD; /* Default to normalized coords. */ + surface->flags |= SFLAG_NORMCOORD; /* Default to normalized coords. */ if (flags & WINED3D_SURFACE_DISCARD) surface->flags |= SFLAG_DISCARD; if (flags & WINED3D_SURFACE_PIN_SYSMEM) surface->flags |= SFLAG_PIN_SYSMEM; - if (lockable || format_id == WINED3DFMT_D16_LOCKABLE) - surface->flags |= SFLAG_LOCKABLE; - /* I'm not sure if this qualifies as a hack or as an optimization. It - * seems reasonable to assume that lockable render targets will get - * locked, so we might as well set SFLAG_DYNLOCK right at surface - * creation. However, the other reason we want to do this is that several - * ddraw applications access surface memory while the surface isn't - * mapped. The SFLAG_DYNLOCK behaviour of keeping SYSMEM around for - * future locks prevents these from crashing. */ - if (lockable && (usage & WINED3DUSAGE_RENDERTARGET)) - surface->flags |= SFLAG_DYNLOCK; + if (lockable || desc->format == WINED3DFMT_D16_LOCKABLE) + surface->resource.access_flags |= WINED3D_RESOURCE_ACCESS_CPU; - /* Mark the texture as dirty so that it gets loaded first time around. */ - surface_add_dirty_rect(surface, NULL); - list_init(&surface->renderbuffers); - - TRACE("surface %p, memory %p, size %u\n", - surface, surface->resource.allocatedMemory, surface->resource.size); + surface->map_binding = WINED3D_LOCATION_SYSMEM; /* Call the private setup routine */ hr = surface->surface_ops->surface_private_setup(surface); if (FAILED(hr)) { ERR("Private setup failed, returning %#x\n", hr); + surface_set_container(surface, NULL); surface_cleanup(surface); return hr; } @@ -7009,44 +6398,58 @@ static HRESULT surface_init(struct wined3d_surface *surface, UINT alignment, UIN /* Similar to lockable rendertargets above, creating the DIB section * during surface initialization prevents the sysmem pointer from changing * after a wined3d_surface_getdc() call. */ - if ((usage & WINED3DUSAGE_OWNDC) && !surface->hDC + if ((desc->usage & WINED3DUSAGE_OWNDC) && !surface->hDC && SUCCEEDED(surface_create_dib_section(surface))) + surface->map_binding = WINED3D_LOCATION_DIB; + + if (surface->map_binding == WINED3D_LOCATION_DIB) { - wined3d_resource_free_sysmem(surface->resource.heap_memory); - surface->resource.heap_memory = NULL; - surface->resource.allocatedMemory = surface->dib.bitmap_data; + wined3d_resource_free_sysmem(&surface->resource); + surface_validate_location(surface, WINED3D_LOCATION_DIB); + surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); } return hr; } -HRESULT CDECL wined3d_surface_create(struct wined3d_device *device, UINT width, UINT height, - enum wined3d_format_id format_id, DWORD usage, enum wined3d_pool pool, - enum wined3d_multisample_type multisample_type, DWORD multisample_quality, DWORD flags, - void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_surface **surface) +HRESULT CDECL wined3d_surface_create(struct wined3d_texture *container, + const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface) { + struct wined3d_device_parent *device_parent = container->resource.device->device_parent; + const struct wined3d_parent_ops *parent_ops; struct wined3d_surface *object; + void *parent; HRESULT hr; - TRACE("device %p, width %u, height %u, format %s\n", - device, width, height, debug_d3dformat(format_id)); - TRACE("surface %p, usage %s (%#x), pool %s, multisample_type %#x, multisample_quality %u\n", - surface, debug_d3dusage(usage), usage, debug_d3dpool(pool), multisample_type, multisample_quality); - TRACE("flags %#x, parent %p, parent_ops %p.\n", flags, parent, parent_ops); + TRACE("container %p, width %u, height %u, format %s, usage %s (%#x), " + "pool %s, multisample_type %#x, multisample_quality %u, flags %#x, surface %p.\n", + container, desc->width, desc->height, debug_d3dformat(desc->format), + debug_d3dusage(desc->usage), desc->usage, debug_d3dpool(desc->pool), + desc->multisample_type, desc->multisample_quality, flags, surface); - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) - return WINED3DERR_OUTOFVIDEOMEMORY; + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; - if (FAILED(hr = surface_init(object, device->surface_alignment, width, height, multisample_type, - multisample_quality, device, usage, format_id, pool, flags, parent, parent_ops))) + if (FAILED(hr = surface_init(object, container, desc, flags))) { WARN("Failed to initialize surface, returning %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); return hr; } - TRACE("Created surface %p.\n", object); + if (FAILED(hr = device_parent->ops->surface_created(device_parent, + wined3d_texture_get_parent(container), object, &parent, &parent_ops))) + { + WARN("Failed to create surface parent, hr %#x.\n", hr); + surface_set_container(object, NULL); + wined3d_surface_decref(object); + return hr; + } + + TRACE("Created surface %p, parent %p, parent_ops %p.\n", object, parent, parent_ops); + + object->resource.parent = parent; + object->resource.parent_ops = parent_ops; *surface = object; return hr; diff --git a/reactos/dll/directx/wine/wined3d/swapchain.c b/reactos/dll/directx/wine/wined3d/swapchain.c index f0d7fbee297..6dbcf804c30 100644 --- a/reactos/dll/directx/wine/wined3d/swapchain.c +++ b/reactos/dll/directx/wine/wined3d/swapchain.c @@ -25,7 +25,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(fps); -/* Do not call while under the GL lock. */ static void swapchain_cleanup(struct wined3d_swapchain *swapchain) { HRESULT hr; @@ -82,7 +81,7 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain) { TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain->backup_wnd, swapchain->backup_dc); - ReleaseDC(swapchain->backup_wnd, swapchain->backup_dc); + wined3d_release_dc(swapchain->backup_wnd, swapchain->backup_dc); DestroyWindow(swapchain->backup_wnd); } } @@ -96,7 +95,6 @@ ULONG CDECL wined3d_swapchain_incref(struct wined3d_swapchain *swapchain) return refcount; } -/* Do not call while under the GL lock. */ ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain) { ULONG refcount = InterlockedDecrement(&swapchain->ref); @@ -149,9 +147,8 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, return WINED3DERR_INVALIDCALL; } - wined3d_swapchain_set_window(swapchain, dst_window_override); - - swapchain->swapchain_ops->swapchain_present(swapchain, src_rect, dst_rect, dirty_region, flags); + wined3d_cs_emit_present(swapchain->device->cs, swapchain, src_rect, + dst_rect, dst_window_override, dirty_region, flags); return WINED3D_OK; } @@ -298,19 +295,20 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, if (gl_info->fbo_ops.glBlitFramebuffer && is_identity_fixup(backbuffer->resource.format->color_fixup)) { - DWORD location = SFLAG_INTEXTURE; + DWORD location = WINED3D_LOCATION_TEXTURE_RGB; if (backbuffer->resource.multisample_type) { - location = SFLAG_INRB_RESOLVED; - surface_load_location(backbuffer, location, NULL); + location = WINED3D_LOCATION_RB_RESOLVED; + surface_load_location(backbuffer, location); } context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL, location); gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0); context_check_fbo_status(context, GL_READ_FRAMEBUFFER); - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, swapchain->front_buffer, NULL, SFLAG_INDRAWABLE); + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, swapchain->front_buffer, + NULL, WINED3D_LOCATION_DRAWABLE); context_set_draw_buffer(context, GL_BACK); context_invalidate_state(context, STATE_FRAMEBUFFER); @@ -352,8 +350,9 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, if (is_complex_fixup(backbuffer->resource.format->color_fixup)) gl_filter = GL_NEAREST; - context_apply_fbo_state_blit(context2, GL_FRAMEBUFFER, swapchain->front_buffer, NULL, SFLAG_INDRAWABLE); - context_bind_texture(context2, backbuffer->texture_target, backbuffer->texture_name); + context_apply_fbo_state_blit(context2, GL_FRAMEBUFFER, swapchain->front_buffer, + NULL, WINED3D_LOCATION_DRAWABLE); + context_bind_texture(context2, backbuffer->texture_target, backbuffer->container->texture_rgb.name); /* Set up the texture. The surface is not in a wined3d_texture * container, so there are no D3D texture settings to dirtify. */ @@ -426,12 +425,22 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT gl_info = context->gl_info; - /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */ - if (swapchain->device->bCursorVisible && - swapchain->device->cursorTexture && - !swapchain->device->hardwareCursor) + if (swapchain->device->logo_texture) { - struct wined3d_surface cursor; + struct wined3d_surface *src_surface = surface_from_resource( + wined3d_texture_get_sub_resource(swapchain->device->logo_texture, 0)); + RECT rect = {0, 0, src_surface->resource.width, src_surface->resource.height}; + + /* Blit the logo into the upper left corner of the drawable. */ + wined3d_surface_blt(back_buffer, &rect, src_surface, &rect, WINEDDBLT_ALPHATEST, + NULL, WINED3D_TEXF_POINT); + } + + if (swapchain->device->bCursorVisible && swapchain->device->cursor_texture + && !swapchain->device->hardwareCursor) + { + struct wined3d_surface *cursor = surface_from_resource( + wined3d_texture_get_sub_resource(swapchain->device->cursor_texture, 0)); RECT destRect = { swapchain->device->xScreenSpace - swapchain->device->xHotSpot, @@ -439,43 +448,12 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot, swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot, }; - TRACE("Rendering the cursor. Creating fake surface at %p\n", &cursor); - /* Build a fake surface to call the Blitting code. It is not possible to use the interface passed by - * the application because we are only supposed to copy the information out. Using a fake surface - * allows us to use the Blitting engine and avoid copying the whole texture -> render target blitting code. - */ - memset(&cursor, 0, sizeof(cursor)); - cursor.resource.ref = 1; - cursor.resource.device = swapchain->device; - cursor.resource.pool = WINED3D_POOL_SCRATCH; - cursor.resource.format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM); - cursor.resource.type = WINED3D_RTYPE_SURFACE; - cursor.texture_name = swapchain->device->cursorTexture; - cursor.texture_target = GL_TEXTURE_2D; - cursor.texture_level = 0; - cursor.resource.width = swapchain->device->cursorWidth; - cursor.resource.height = swapchain->device->cursorHeight; - /* The cursor must have pow2 sizes */ - cursor.pow2Width = cursor.resource.width; - cursor.pow2Height = cursor.resource.height; - /* The surface is in the texture */ - cursor.flags |= SFLAG_INTEXTURE; - /* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0, - * which is exactly what we want :-) - */ + + TRACE("Rendering the software cursor.\n"); + if (swapchain->desc.windowed) MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&destRect, 2); - wined3d_surface_blt(back_buffer, &destRect, &cursor, NULL, WINEDDBLT_KEYSRC, - NULL, WINED3D_TEXF_POINT); - } - - if (swapchain->device->logo_surface) - { - struct wined3d_surface *src_surface = swapchain->device->logo_surface; - RECT rect = {0, 0, src_surface->resource.width, src_surface->resource.height}; - - /* Blit the logo into the upper left corner of the drawable. */ - wined3d_surface_blt(back_buffer, &rect, src_surface, &rect, WINEDDBLT_KEYSRC, + wined3d_surface_blt(back_buffer, &destRect, cursor, NULL, WINEDDBLT_ALPHATEST, NULL, WINED3D_TEXF_POINT); } @@ -520,26 +498,22 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT */ if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - surface_load_location(back_buffer, SFLAG_INTEXTURE, NULL); - surface_modify_location(back_buffer, SFLAG_INDRAWABLE, FALSE); + surface_load_location(back_buffer, WINED3D_LOCATION_TEXTURE_RGB); + surface_invalidate_location(back_buffer, WINED3D_LOCATION_DRAWABLE); swapchain->render_to_fbo = TRUE; swapchain_update_draw_bindings(swapchain); } else { - surface_load_location(back_buffer, back_buffer->draw_binding, NULL); + surface_load_location(back_buffer, back_buffer->draw_binding); } if (swapchain->render_to_fbo) { - /* This codepath should only be hit with the COPY swapeffect. Otherwise a backbuffer- - * window size mismatch is impossible(fullscreen) and src and dst rectangles are - * not allowed(they need the COPY swapeffect) - * - * The DISCARD swap effect is ok as well since any backbuffer content is allowed after - * the swap. */ - if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP) - FIXME("Render-to-fbo with WINED3D_SWAP_EFFECT_FLIP\n"); + 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); } @@ -567,33 +541,8 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT } } - /* This is disabled, but the code left in for debug purposes. - * - * Since we're allowed to modify the new back buffer on a D3DSWAPEFFECT_DISCARD flip, - * we can clear it with some ugly color to make bad drawing visible and ease debugging. - * The Debug runtime does the same on Windows. However, a few games do not redraw the - * screen properly, like Max Payne 2, which leaves a few pixels undefined. - * - * Tests show that the content of the back buffer after a discard flip is indeed not - * reliable, so no game can depend on the exact content. However, it resembles the - * old contents in some way, for example by showing fragments at other locations. In - * general, the color theme is still intact. So Max payne, which draws rather dark scenes - * gets a dark background image. If we clear it with a bright ugly color, the game's - * bug shows up much more than it does on Windows, and the players see single pixels - * with wrong colors. - * (The Max Payne bug has been confirmed on Windows with the debug runtime) */ - if (FALSE && swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_DISCARD) - { - static const struct wined3d_color cyan = {0.0f, 1.0f, 1.0f, 1.0f}; - - TRACE("Clearing the color buffer with cyan color\n"); - - wined3d_device_clear(swapchain->device, 0, NULL, - WINED3DCLEAR_TARGET, &cyan, 1.0f, 0); - } - - if (!swapchain->render_to_fbo && ((swapchain->front_buffer->flags & SFLAG_INSYSMEM) - || (back_buffer->flags & SFLAG_INSYSMEM))) + if (!swapchain->render_to_fbo && ((swapchain->front_buffer->locations & WINED3D_LOCATION_SYSMEM) + || (back_buffer->locations & WINED3D_LOCATION_SYSMEM))) { /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying * Doesn't work with render_to_fbo because we're not flipping @@ -602,32 +551,35 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT if (front->resource.size == back_buffer->resource.size) { - DWORD fbflags; flip_surface(front, back_buffer); /* Tell the front buffer surface that is has been modified. However, * the other locations were preserved during that, so keep the flags. * This serves to update the emulated overlay, if any. */ - fbflags = front->flags; - surface_modify_location(front, SFLAG_INDRAWABLE, TRUE); - front->flags = fbflags; + surface_validate_location(front, WINED3D_LOCATION_DRAWABLE); } else { - surface_modify_location(front, SFLAG_INDRAWABLE, TRUE); - surface_modify_location(back_buffer, SFLAG_INDRAWABLE, TRUE); + surface_validate_location(front, WINED3D_LOCATION_DRAWABLE); + surface_invalidate_location(front, ~WINED3D_LOCATION_DRAWABLE); + surface_validate_location(back_buffer, WINED3D_LOCATION_DRAWABLE); + surface_invalidate_location(back_buffer, ~WINED3D_LOCATION_DRAWABLE); } } else { - surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE); + surface_validate_location(swapchain->front_buffer, WINED3D_LOCATION_DRAWABLE); + surface_invalidate_location(swapchain->front_buffer, ~WINED3D_LOCATION_DRAWABLE); /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM * and INTEXTURE copies can keep their old content if they have any defined content. * If the swapeffect is COPY, the content remains the same. If it is FLIP however, * the texture / sysmem copy needs to be reloaded from the drawable */ if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP) - surface_modify_location(back_buffer, back_buffer->draw_binding, TRUE); + { + surface_validate_location(back_buffer, back_buffer->draw_binding); + surface_invalidate_location(back_buffer, ~back_buffer->draw_binding); + } } if (fb->depth_stencil) @@ -635,7 +587,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT if (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL || fb->depth_stencil->flags & SFLAG_DISCARD) { - surface_modify_ds_location(fb->depth_stencil, SFLAG_DISCARDED, + surface_modify_ds_location(fb->depth_stencil, WINED3D_LOCATION_DISCARDED, fb->depth_stencil->resource.width, fb->depth_stencil->resource.height); if (fb->depth_stencil == swapchain->device->onscreen_depth_stencil) @@ -657,7 +609,7 @@ static const struct wined3d_swapchain_ops swapchain_gl_ops = /* Helper function that blits the front buffer contents to the target window. */ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) { - const struct wined3d_surface *front; + struct wined3d_surface *front; POINT offset = {0, 0}; HDC src_dc, dst_dc; RECT draw_rect; @@ -666,14 +618,13 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r TRACE("swapchain %p, rect %s.\n", swapchain, wine_dbgstr_rect(rect)); front = swapchain->front_buffer; - if (!(front->resource.usage & WINED3DUSAGE_RENDERTARGET)) - return; - if (front->resource.map_count) ERR("Trying to blit a mapped surface.\n"); TRACE("Copying surface %p to screen.\n", front); + surface_load_location(front, WINED3D_LOCATION_DIB); + src_dc = front->hDC; window = swapchain->win_handle; dst_dc = GetDCEx(window, 0, DCX_CLIPSIBLINGS | DCX_CACHE); @@ -731,10 +682,6 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const REC front->dib.bitmap_data = back->dib.bitmap_data; back->dib.bitmap_data = tmp; - tmp = front->resource.allocatedMemory; - front->resource.allocatedMemory = back->resource.allocatedMemory; - back->resource.allocatedMemory = tmp; - if (front->resource.heap_memory) ERR("GDI Surface %p has heap memory allocated.\n", front); @@ -804,7 +751,6 @@ void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) swapchain->render_to_fbo = TRUE; } -/* Do not call while under the GL lock. */ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { @@ -883,7 +829,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 surface_desc.format = swapchain->desc.backbuffer_format; surface_desc.multisample_type = swapchain->desc.multisample_type; surface_desc.multisample_quality = swapchain->desc.multisample_quality; - surface_desc.usage = WINED3DUSAGE_RENDERTARGET; + surface_desc.usage = 0; surface_desc.pool = WINED3D_POOL_DEFAULT; surface_desc.width = swapchain->desc.backbuffer_width; surface_desc.height = swapchain->desc.backbuffer_height; @@ -899,7 +845,10 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 surface_set_swapchain(swapchain->front_buffer, swapchain); if (!(device->wined3d->flags & WINED3D_NO3D)) - surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE); + { + surface_validate_location(swapchain->front_buffer, WINED3D_LOCATION_DRAWABLE); + surface_invalidate_location(swapchain->front_buffer, ~WINED3D_LOCATION_DRAWABLE); + } /* MSDN says we're only allowed a single fullscreen swapchain per device, * so we should really check to see if there is a fullscreen swapchain @@ -993,6 +942,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 goto err; } + surface_desc.usage |= WINED3DUSAGE_RENDERTARGET; for (i = 0; i < swapchain->desc.backbuffer_count; ++i) { TRACE("Creating back buffer %u.\n", i); @@ -1000,6 +950,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 parent, &surface_desc, &swapchain->back_buffers[i]))) { WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); + swapchain->desc.backbuffer_count = i; goto err; } surface_set_swapchain(swapchain->back_buffers[i], swapchain); @@ -1070,7 +1021,6 @@ err: return hr; } -/* Do not call while under the GL lock. */ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) { @@ -1098,7 +1048,6 @@ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct win return WINED3D_OK; } -/* Do not call while under the GL lock. */ static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain *swapchain) { struct wined3d_context **newArray; diff --git a/reactos/dll/directx/wine/wined3d/texture.c b/reactos/dll/directx/wine/wined3d/texture.c index d670ce8ac86..3aba595da70 100644 --- a/reactos/dll/directx/wine/wined3d/texture.c +++ b/reactos/dll/directx/wine/wined3d/texture.c @@ -39,6 +39,14 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth, device, parent, parent_ops, resource_ops); + if ((format->flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BLOCKS_NO_VERIFY)) == WINED3DFMT_FLAG_BLOCKS) + { + UINT width_mask = format->block_width - 1; + UINT height_mask = format->block_height - 1; + if (desc->width & width_mask || desc->height & height_mask) + 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->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops))) @@ -61,8 +69,6 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc texture->level_count = level_count; texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE; texture->lod = 0; - texture->texture_rgb.dirty = TRUE; - texture->texture_srgb.dirty = TRUE; texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT; if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING) @@ -86,7 +92,7 @@ static void gltexture_delete(const struct wined3d_gl_info *gl_info, struct gl_te tex->name = 0; } -static void wined3d_texture_unload(struct wined3d_texture *texture) +static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture) { struct wined3d_device *device = texture->resource.device; struct wined3d_context *context = NULL; @@ -104,7 +110,7 @@ static void wined3d_texture_unload(struct wined3d_texture *texture) if (context) context_release(context); - wined3d_texture_set_dirty(texture, TRUE); + wined3d_texture_set_dirty(texture); resource_unload(&texture->resource); } @@ -124,28 +130,28 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) texture->texture_ops->texture_sub_resource_cleanup(sub_resource); } - wined3d_texture_unload(texture); + wined3d_texture_unload_gl_texture(texture); HeapFree(GetProcessHeap(), 0, texture->sub_resources); resource_cleanup(&texture->resource); } -void wined3d_texture_set_dirty(struct wined3d_texture *texture, BOOL dirty) +void wined3d_texture_set_dirty(struct wined3d_texture *texture) { - texture->texture_rgb.dirty = dirty; - texture->texture_srgb.dirty = dirty; + texture->flags &= ~(WINED3D_TEXTURE_RGB_VALID | WINED3D_TEXTURE_SRGB_VALID); } /* Context activation is done by the caller. */ -static HRESULT wined3d_texture_bind(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb, BOOL *set_surface_desc) +void wined3d_texture_bind(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb) { const struct wined3d_gl_info *gl_info = context->gl_info; struct gl_texture *gl_tex; - BOOL new_texture = FALSE; - HRESULT hr = WINED3D_OK; GLenum target; - TRACE("texture %p, context %p, srgb %#x, set_surface_desc %p.\n", texture, context, srgb, set_surface_desc); + TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb); + + if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + srgb = FALSE; /* sRGB mode cache for preload() calls outside drawprim. */ if (srgb) @@ -153,89 +159,122 @@ static HRESULT wined3d_texture_bind(struct wined3d_texture *texture, else texture->flags &= ~WINED3D_TEXTURE_IS_SRGB; - gl_tex = wined3d_texture_get_gl_texture(texture, context->gl_info, srgb); + gl_tex = wined3d_texture_get_gl_texture(texture, srgb); target = texture->target; - /* Generate a texture name if we don't already have one. */ - if (!gl_tex->name) - { - *set_surface_desc = TRUE; - gl_info->gl_ops.gl.p_glGenTextures(1, &gl_tex->name); - checkGLcall("glGenTextures"); - TRACE("Generated texture %d.\n", gl_tex->name); - if (texture->resource.pool == WINED3D_POOL_DEFAULT) - { - /* Tell OpenGL to try and keep this texture in video ram (well mostly). */ - GLclampf tmp = 0.9f; - gl_info->gl_ops.gl.p_glPrioritizeTextures(1, &gl_tex->name, &tmp); - } - /* Initialise the state of the texture object to the OpenGL defaults, - * not the D3D defaults. */ - gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_WRAP; - gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_WRAP; - gl_tex->states[WINED3DTEXSTA_ADDRESSW] = WINED3D_TADDRESS_WRAP; - gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = 0; - gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_LINEAR; - gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */ - gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */ - gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0; - gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1; - if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = TRUE; - else - gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = srgb; - gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE; - wined3d_texture_set_dirty(texture, TRUE); - new_texture = TRUE; - - if (texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP) - { - /* This means double binding the texture at creation, but keeps - * the code simpler all in all, and the run-time path free from - * additional checks. */ - context_bind_texture(context, target, gl_tex->name); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - checkGLcall("glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)"); - } - } - else - { - *set_surface_desc = FALSE; - } - if (gl_tex->name) { context_bind_texture(context, target, gl_tex->name); - if (new_texture) - { - /* 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 GL_ARB_texture_non_power_of_two emulation with - * texture rectangles. (I.e., do not care about cond_np2 here, - * just look for GL_TEXTURE_RECTANGLE_ARB.) */ - if (target != GL_TEXTURE_RECTANGLE_ARB) - { - TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", texture->level_count - 1); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1); - checkGLcall("glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count)"); - } - if (target == GL_TEXTURE_CUBE_MAP_ARB) - { - /* Cubemaps are always set to clamp, regardless of the sampler state. */ - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - } - } - } - else - { - ERR("This texture doesn't have an OpenGL texture assigned to it.\n"); - hr = WINED3DERR_INVALIDCALL; + return; } - return hr; + gl_info->gl_ops.gl.p_glGenTextures(1, &gl_tex->name); + checkGLcall("glGenTextures"); + TRACE("Generated texture %d.\n", gl_tex->name); + + if (!gl_tex->name) + { + ERR("Failed to generate a texture name.\n"); + return; + } + + if (texture->resource.pool == WINED3D_POOL_DEFAULT) + { + /* Tell OpenGL to try and keep this texture in video ram (well mostly). */ + GLclampf tmp = 0.9f; + gl_info->gl_ops.gl.p_glPrioritizeTextures(1, &gl_tex->name, &tmp); + } + + /* Initialise the state of the texture object to the OpenGL defaults, not + * the wined3d defaults. */ + gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_WRAP; + gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_WRAP; + gl_tex->states[WINED3DTEXSTA_ADDRESSW] = WINED3D_TADDRESS_WRAP; + gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = 0; + gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_LINEAR; + gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */ + gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */ + gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0; + gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1; + if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = TRUE; + else + gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = srgb; + gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE; + wined3d_texture_set_dirty(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 + * GL_ARB_texture_non_power_of_two emulation with texture rectangles. + * (I.e., do not care about cond_np2 here, just look for + * GL_TEXTURE_RECTANGLE_ARB.) */ + if (target != GL_TEXTURE_RECTANGLE_ARB) + { + TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", texture->level_count - 1); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1); + checkGLcall("glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count)"); + } + + if (target == GL_TEXTURE_CUBE_MAP_ARB) + { + /* Cubemaps are always set to clamp, regardless of the sampler state. */ + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + } + + if (texture->flags & WINED3D_TEXTURE_COND_NP2) + { + /* Conditinal non power of two textures use a different clamping + * default. If we're using the GL_WINE_normalized_texrect partial + * driver emulation, we're dealing with a GL_TEXTURE_2D texture which + * has the address mode set to repeat - something that prevents us + * from hitting the accelerated codepath. Thus manually set the GL + * state. The same applies to filtering. Even if the texture has only + * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW + * fallback on macos. */ + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + checkGLcall("glTexParameteri"); + gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_CLAMP; + gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_CLAMP; + gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT; + gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; + gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE; + } +} + +/* Context activation is done by the caller. */ +void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb) +{ + DWORD active_sampler; + + /* We don't need a specific texture unit, but after binding the texture + * the current unit is dirty. Read the unit back instead of switching to + * 0, this avoids messing around with the state manager's GL states. The + * current texture unit should always be a valid one. + * + * To be more specific, this is tricky because we can implicitly be + * called from sampler() in state.c. This means we can't touch anything + * other than whatever happens to be the currently active texture, or we + * would risk marking already applied sampler states dirty again. */ + active_sampler = context->rev_tex_unit_map[context->active_texture]; + if (active_sampler != WINED3D_UNMAPPED_STAGE) + context_invalidate_state(context, STATE_SAMPLER(active_sampler)); + + wined3d_texture_bind(texture, context, srgb); } /* Context activation is done by the caller. */ @@ -275,8 +314,7 @@ void wined3d_texture_apply_state_changes(struct wined3d_texture *texture, TRACE("texture %p, sampler_states %p.\n", texture, sampler_states); - gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, - texture->flags & WINED3D_TEXTURE_IS_SRGB); + gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB); /* This function relies on the correct texture being bound and loaded. */ @@ -435,7 +473,6 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture) return refcount; } -/* Do not call while under the GL lock. */ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) { ULONG refcount = InterlockedDecrement(&texture->resource.ref); @@ -469,10 +506,45 @@ DWORD CDECL wined3d_texture_get_priority(const struct wined3d_texture *texture) return resource_get_priority(&texture->resource); } -/* Do not call while under the GL lock. */ +/* Context activation is done by the caller */ +void wined3d_texture_load(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb) +{ + UINT sub_count = texture->level_count * texture->layer_count; + const struct wined3d_gl_info *gl_info = context->gl_info; + DWORD flag; + UINT i; + + TRACE("texture %p, srgb %#x.\n", texture, srgb); + + if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + srgb = FALSE; + + if (srgb) + flag = WINED3D_TEXTURE_SRGB_VALID; + else + flag = WINED3D_TEXTURE_RGB_VALID; + + if (texture->flags & flag) + { + TRACE("Texture %p not dirty, nothing to do.\n", texture); + return; + } + + /* Reload the surfaces if the texture is marked dirty. */ + for (i = 0; i < sub_count; ++i) + { + texture->texture_ops->texture_sub_resource_load(texture->sub_resources[i], context, srgb); + } + texture->flags |= flag; +} + void CDECL wined3d_texture_preload(struct wined3d_texture *texture) { - texture->texture_ops->texture_preload(texture, SRGB_ANY); + struct wined3d_context *context; + context = context_acquire(texture->resource.device, NULL); + wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); + context_release(context); } void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture) @@ -549,6 +621,67 @@ enum wined3d_texture_filter_type CDECL wined3d_texture_get_autogen_filter_type(c return texture->filter_type; } +HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture, + DWORD flags, const struct wined3d_color_key *color_key) +{ + TRACE("texture %p, flags %#x, color_key %p.\n", texture, flags, color_key); + + if (flags & WINEDDCKEY_COLORSPACE) + { + FIXME("Unhandled flags %#x.\n", flags); + return WINED3DERR_INVALIDCALL; + } + + if (color_key) + { + switch (flags & ~WINEDDCKEY_COLORSPACE) + { + case WINEDDCKEY_DESTBLT: + texture->dst_blt_color_key = *color_key; + texture->color_key_flags |= WINEDDSD_CKDESTBLT; + break; + + case WINEDDCKEY_DESTOVERLAY: + texture->dst_overlay_color_key = *color_key; + texture->color_key_flags |= WINEDDSD_CKDESTOVERLAY; + break; + + case WINEDDCKEY_SRCOVERLAY: + texture->src_overlay_color_key = *color_key; + texture->color_key_flags |= WINEDDSD_CKSRCOVERLAY; + break; + + case WINEDDCKEY_SRCBLT: + texture->src_blt_color_key = *color_key; + texture->color_key_flags |= WINEDDSD_CKSRCBLT; + break; + } + } + else + { + switch (flags & ~WINEDDCKEY_COLORSPACE) + { + case WINEDDCKEY_DESTBLT: + texture->color_key_flags &= ~WINEDDSD_CKDESTBLT; + break; + + case WINEDDCKEY_DESTOVERLAY: + texture->color_key_flags &= ~WINEDDSD_CKDESTOVERLAY; + break; + + case WINEDDCKEY_SRCOVERLAY: + texture->color_key_flags &= ~WINEDDSD_CKSRCOVERLAY; + break; + + case WINEDDCKEY_SRCBLT: + texture->color_key_flags &= ~WINEDDSD_CKSRCBLT; + break; + } + } + + return WINED3D_OK; +} + void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture) { /* TODO: Implement filters using GL_SGI_generate_mipmaps. */ @@ -584,148 +717,44 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, return WINED3DERR_INVALIDCALL; } - wined3d_texture_set_dirty(texture, TRUE); texture->texture_ops->texture_sub_resource_add_dirty_region(sub_resource, dirty_region); return WINED3D_OK; } -/* Context activation is done by the caller. */ -static HRESULT texture2d_bind(struct wined3d_texture *texture, +static void texture2d_sub_resource_load(struct wined3d_resource *sub_resource, struct wined3d_context *context, BOOL srgb) { - const struct wined3d_gl_info *gl_info = context->gl_info; - BOOL set_gl_texture_desc; - HRESULT hr; - - TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb); - - hr = wined3d_texture_bind(texture, context, srgb, &set_gl_texture_desc); - if (set_gl_texture_desc && SUCCEEDED(hr)) - { - UINT sub_count = texture->level_count * texture->layer_count; - BOOL srgb_tex = !context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE] - && (texture->flags & WINED3D_TEXTURE_IS_SRGB); - struct gl_texture *gl_tex; - UINT i; - - gl_tex = wined3d_texture_get_gl_texture(texture, context->gl_info, srgb_tex); - - for (i = 0; i < sub_count; ++i) - { - struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]); - surface_set_texture_name(surface, gl_tex->name, srgb_tex); - } - - /* Conditinal non power of two textures use a different clamping - * default. If we're using the GL_WINE_normalized_texrect partial - * driver emulation, we're dealing with a GL_TEXTURE_2D texture which - * has the address mode set to repeat - something that prevents us - * from hitting the accelerated codepath. Thus manually set the GL - * state. The same applies to filtering. Even if the texture has only - * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW - * fallback on macos. */ - if (texture->flags & WINED3D_TEXTURE_COND_NP2) - { - GLenum target = texture->target; - - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)"); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)"); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)"); - gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_CLAMP; - gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_CLAMP; - gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT; - gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; - gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE; - } - } - - return hr; -} - -static BOOL texture_srgb_mode(const struct wined3d_texture *texture, enum WINED3DSRGB srgb) -{ - switch (srgb) - { - case SRGB_RGB: - return FALSE; - - case SRGB_SRGB: - return TRUE; - - default: - return texture->flags & WINED3D_TEXTURE_IS_SRGB; - } -} - -/* Do not call while under the GL lock. */ -static void texture2d_preload(struct wined3d_texture *texture, enum WINED3DSRGB srgb) -{ - UINT sub_count = texture->level_count * texture->layer_count; - struct wined3d_device *device = texture->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_context *context = NULL; - struct gl_texture *gl_tex; - BOOL srgb_mode; - UINT i; - - TRACE("texture %p, srgb %#x.\n", texture, srgb); - - srgb_mode = texture_srgb_mode(texture, srgb); - gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, srgb_mode); - - if (!device->isInDraw) - { - /* No danger of recursive calls, context_acquire() sets isInDraw to TRUE - * when loading offscreen render targets into the texture. */ - context = context_acquire(device, NULL); - } - - if (gl_tex->dirty) - { - /* Reload the surfaces if the texture is marked dirty. */ - for (i = 0; i < sub_count; ++i) - { - surface_load(surface_from_resource(texture->sub_resources[i]), srgb_mode); - } - } - else - { - TRACE("Texture %p not dirty, nothing to do.\n", texture); - } - - /* No longer dirty. */ - gl_tex->dirty = FALSE; - - if (context) context_release(context); + surface_load(surface_from_resource(sub_resource), srgb); } static void texture2d_sub_resource_add_dirty_region(struct wined3d_resource *sub_resource, const struct wined3d_box *dirty_region) { - surface_add_dirty_rect(surface_from_resource(sub_resource), dirty_region); + struct wined3d_surface *surface = surface_from_resource(sub_resource); + + surface_prepare_map_memory(surface); + surface_load_location(surface, surface->map_binding); + surface_invalidate_location(surface, ~surface->map_binding); } static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource) { struct wined3d_surface *surface = surface_from_resource(sub_resource); - /* Clean out the texture name we gave to the surface so that the - * surface doesn't try and release it. */ - surface_set_texture_name(surface, 0, TRUE); - surface_set_texture_name(surface, 0, FALSE); surface_set_texture_target(surface, 0, 0); surface_set_container(surface, NULL); wined3d_surface_decref(surface); } -/* Do not call while under the GL lock. */ -static void texture2d_unload(struct wined3d_resource *resource) +static const struct wined3d_texture_ops texture2d_ops = +{ + texture2d_sub_resource_load, + texture2d_sub_resource_add_dirty_region, + texture2d_sub_resource_cleanup, +}; + +static void wined3d_texture_unload(struct wined3d_resource *resource) { struct wined3d_texture *texture = wined3d_texture_from_resource(resource); UINT sub_count = texture->level_count * texture->layer_count; @@ -736,27 +765,16 @@ static void texture2d_unload(struct wined3d_resource *resource) for (i = 0; i < sub_count; ++i) { struct wined3d_resource *sub_resource = texture->sub_resources[i]; - struct wined3d_surface *surface = surface_from_resource(sub_resource); sub_resource->resource_ops->resource_unload(sub_resource); - surface_set_texture_name(surface, 0, FALSE); /* Delete RGB name */ - surface_set_texture_name(surface, 0, TRUE); /* Delete sRGB name */ } - wined3d_texture_unload(texture); + wined3d_texture_unload_gl_texture(texture); } -static const struct wined3d_texture_ops texture2d_ops = +static const struct wined3d_resource_ops texture_resource_ops = { - texture2d_bind, - texture2d_preload, - texture2d_sub_resource_add_dirty_region, - texture2d_sub_resource_cleanup, -}; - -static const struct wined3d_resource_ops texture2d_resource_ops = -{ - texture2d_unload, + wined3d_texture_unload, }; static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, @@ -827,7 +845,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi } if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels, - desc, device, parent, parent_ops, &texture2d_resource_ops))) + desc, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x\n", hr); return hr; @@ -859,15 +877,13 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi UINT idx = j * texture->level_count + i; struct wined3d_surface *surface; - if (FAILED(hr = device->device_parent->ops->create_texture_surface(device->device_parent, - parent, &surface_desc, idx, surface_flags, &surface))) + if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface))) { - FIXME("(%p) Failed to create surface, hr %#x.\n", texture, hr); + WARN("Failed to create surface, hr %#x.\n", hr); wined3d_texture_cleanup(texture); return hr; } - surface_set_container(surface, texture); surface_set_texture_target(surface, cube_targets[j], i); texture->sub_resources[idx] = &surface->resource; TRACE("Created surface level %u @ %p.\n", i, surface); @@ -954,7 +970,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 } if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels, - desc, device, parent, parent_ops, &texture2d_resource_ops))) + desc, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x.\n", hr); return hr; @@ -1015,16 +1031,13 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 { struct wined3d_surface *surface; - /* Use the callback to create the texture surface. */ - if (FAILED(hr = device->device_parent->ops->create_texture_surface(device->device_parent, - parent, &surface_desc, i, surface_flags, &surface))) + if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface))) { - FIXME("Failed to create surface %p, hr %#x\n", texture, hr); + WARN("Failed to create surface, hr %#x.\n", hr); wined3d_texture_cleanup(texture); return hr; } - surface_set_container(surface, texture); surface_set_texture_target(surface, texture->target, i); texture->sub_resources[i] = &surface->resource; TRACE("Created surface level %u @ %p.\n", i, surface); @@ -1036,58 +1049,16 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 return WINED3D_OK; } -/* Context activation is done by the caller. */ -static HRESULT texture3d_bind(struct wined3d_texture *texture, +static void texture3d_sub_resource_load(struct wined3d_resource *sub_resource, struct wined3d_context *context, BOOL srgb) { - BOOL dummy; - - TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb); - - return wined3d_texture_bind(texture, context, srgb, &dummy); -} - -/* Do not call while under the GL lock. */ -static void texture3d_preload(struct wined3d_texture *texture, enum WINED3DSRGB srgb) -{ - UINT sub_count = texture->level_count * texture->layer_count; - struct wined3d_device *device = texture->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_context *context = NULL; - struct gl_texture *gl_tex; - BOOL srgb_mode; - UINT i; - - TRACE("texture %p, srgb %#x.\n", texture, srgb); - - srgb_mode = texture_srgb_mode(texture, srgb); - gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, srgb_mode); - - if (gl_tex->dirty) - { - context = context_acquire(device, NULL); - - /* Reload the surfaces if the texture is marked dirty. */ - for (i = 0; i < sub_count; ++i) - { - wined3d_volume_load(volume_from_resource(texture->sub_resources[i]), context, - srgb_mode); - } - - context_release(context); - } - else - { - TRACE("Texture %p not dirty, nothing to do.\n", texture); - } - - /* No longer dirty. */ - gl_tex->dirty = FALSE; + wined3d_volume_load(volume_from_resource(sub_resource), context, srgb); } static void texture3d_sub_resource_add_dirty_region(struct wined3d_resource *sub_resource, const struct wined3d_box *dirty_region) { + wined3d_texture_set_dirty(volume_from_resource(sub_resource)->container); } static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource) @@ -1099,41 +1070,18 @@ static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource wined3d_volume_decref(volume); } -/* Do not call while under the GL lock. */ -static void texture3d_unload(struct wined3d_resource *resource) -{ - struct wined3d_texture *texture = wined3d_texture_from_resource(resource); - UINT i; - - TRACE("texture %p.\n", texture); - - for (i = 0; i < texture->level_count; ++i) - { - struct wined3d_resource *sub_resource = texture->sub_resources[i]; - sub_resource->resource_ops->resource_unload(sub_resource); - } - - wined3d_texture_unload(texture); -} - static const struct wined3d_texture_ops texture3d_ops = { - texture3d_bind, - texture3d_preload, + texture3d_sub_resource_load, texture3d_sub_resource_add_dirty_region, texture3d_sub_resource_cleanup, }; -static const struct wined3d_resource_ops texture3d_resource_ops = -{ - texture3d_unload, -}; - static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, UINT levels, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - UINT tmp_w, tmp_h, tmp_d; + struct wined3d_resource_desc volume_desc; unsigned int i; HRESULT hr; @@ -1203,7 +1151,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct } if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels, - desc, device, parent, parent_ops, &texture3d_resource_ops))) + desc, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x.\n", hr); return hr; @@ -1216,38 +1164,31 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct texture->target = GL_TEXTURE_3D; /* Generate all the surfaces. */ - tmp_w = desc->width; - tmp_h = desc->height; - tmp_d = desc->depth; - + volume_desc = *desc; + volume_desc.resource_type = WINED3D_RTYPE_VOLUME; for (i = 0; i < texture->level_count; ++i) { struct wined3d_volume *volume; - /* Create the volume. */ - hr = device->device_parent->ops->create_volume(device->device_parent, parent, - tmp_w, tmp_h, tmp_d, i, desc->format, desc->pool, desc->usage, &volume); - if (FAILED(hr)) + if (FAILED(hr = wined3d_volume_create(texture, &volume_desc, i, &volume))) { ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr); wined3d_texture_cleanup(texture); return hr; } - /* Set its container to this texture. */ - volume_set_container(volume, texture); texture->sub_resources[i] = &volume->resource; /* Calculate the next mipmap level. */ - tmp_w = max(1, tmp_w >> 1); - tmp_h = max(1, tmp_h >> 1); - tmp_d = max(1, tmp_d >> 1); + volume_desc.width = max(1, volume_desc.width >> 1); + volume_desc.height = max(1, volume_desc.height >> 1); + volume_desc.depth = max(1, volume_desc.depth >> 1); } return WINED3D_OK; } -HRESULT CDECL wined3d_texture_create_2d(struct wined3d_device *device, const struct wined3d_resource_desc *desc, +HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) { @@ -1257,79 +1198,33 @@ HRESULT CDECL wined3d_texture_create_2d(struct wined3d_device *device, const str TRACE("device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.\n", device, desc, level_count, surface_flags, parent, parent_ops, texture); - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + switch (desc->resource_type) { - *texture = NULL; - return WINED3DERR_OUTOFVIDEOMEMORY; + case WINED3D_RTYPE_TEXTURE: + hr = texture_init(object, desc, level_count, surface_flags, device, parent, parent_ops); + break; + + case WINED3D_RTYPE_VOLUME_TEXTURE: + hr = volumetexture_init(object, desc, level_count, device, parent, parent_ops); + break; + + case WINED3D_RTYPE_CUBE_TEXTURE: + hr = cubetexture_init(object, desc, level_count, surface_flags, device, parent, parent_ops); + break; + + default: + ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type)); + hr = WINED3DERR_INVALIDCALL; + break; } - if (FAILED(hr = texture_init(object, desc, level_count, surface_flags, device, parent, parent_ops))) + if (FAILED(hr)) { WARN("Failed to initialize texture, returning %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); - *texture = NULL; - return hr; - } - - TRACE("Created texture %p.\n", object); - *texture = object; - - return WINED3D_OK; -} - -HRESULT CDECL wined3d_texture_create_3d(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) -{ - struct wined3d_texture *object; - HRESULT hr; - - TRACE("device %p, desc %p, level_count %u, parent %p, parent_ops %p, texture %p.\n", - device, desc, level_count, parent, parent_ops, texture); - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) - { - *texture = NULL; - return WINED3DERR_OUTOFVIDEOMEMORY; - } - - if (FAILED(hr = volumetexture_init(object, desc, level_count, device, parent, parent_ops))) - { - WARN("Failed to initialize volumetexture, returning %#x\n", hr); - HeapFree(GetProcessHeap(), 0, object); - *texture = NULL; - return hr; - } - - TRACE("Created texture %p.\n", object); - *texture = object; - - return WINED3D_OK; -} - -HRESULT CDECL wined3d_texture_create_cube(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_texture **texture) -{ - struct wined3d_texture *object; - HRESULT hr; - - TRACE("device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.\n", - device, desc, level_count, surface_flags, parent, parent_ops, texture); - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) - { - *texture = NULL; - return WINED3DERR_OUTOFVIDEOMEMORY; - } - - if (FAILED(hr = cubetexture_init(object, desc, level_count, surface_flags, device, parent, parent_ops))) - { - WARN("Failed to initialize cubetexture, returning %#x\n", hr); - HeapFree(GetProcessHeap(), 0, object); - *texture = NULL; return hr; } diff --git a/reactos/dll/directx/wine/wined3d/utils.c b/reactos/dll/directx/wine/wined3d/utils.c index 52580dcf545..a0df9aec991 100644 --- a/reactos/dll/directx/wine/wined3d/utils.c +++ b/reactos/dll/directx/wine/wined3d/utils.c @@ -186,18 +186,19 @@ struct wined3d_format_block_info UINT block_width; UINT block_height; UINT block_byte_count; + BOOL verify; }; static const struct wined3d_format_block_info format_block_info[] = { - {WINED3DFMT_DXT1, 4, 4, 8}, - {WINED3DFMT_DXT2, 4, 4, 16}, - {WINED3DFMT_DXT3, 4, 4, 16}, - {WINED3DFMT_DXT4, 4, 4, 16}, - {WINED3DFMT_DXT5, 4, 4, 16}, - {WINED3DFMT_ATI2N, 4, 4, 16}, - {WINED3DFMT_YUY2, 2, 1, 4}, - {WINED3DFMT_UYVY, 2, 1, 4}, + {WINED3DFMT_DXT1, 4, 4, 8, TRUE}, + {WINED3DFMT_DXT2, 4, 4, 16, TRUE}, + {WINED3DFMT_DXT3, 4, 4, 16, TRUE}, + {WINED3DFMT_DXT4, 4, 4, 16, TRUE}, + {WINED3DFMT_DXT5, 4, 4, 16, TRUE}, + {WINED3DFMT_ATI2N, 4, 4, 16, FALSE}, + {WINED3DFMT_YUY2, 2, 1, 4, FALSE}, + {WINED3DFMT_UYVY, 2, 1, 4, FALSE}, }; struct wined3d_format_vertex_info @@ -247,117 +248,136 @@ struct wined3d_format_texture_info unsigned int conv_byte_count; unsigned int flags; enum wined3d_gl_extension extension; - void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height); + void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth); }; -static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not * format+type combination to load it. Thus convert it to A8L8, then load it * with A4L4 internal, but A8L8 format+type */ - unsigned int x, y; + unsigned int x, y, z; const unsigned char *Source; unsigned char *Dest; - UINT outpitch = pitch * 2; - for(y = 0; y < height; y++) { - Source = src + y * pitch; - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - unsigned char color = (*Source++); - /* A */ Dest[1] = (color & 0xf0) << 0; - /* L */ Dest[0] = (color & 0x0f) << 4; - Dest += 2; + for (z = 0; z < depth; z++) + { + for (y = 0; y < height; y++) + { + Source = src + z * src_slice_pitch + y * src_row_pitch; + Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; + for (x = 0; x < width; x++ ) + { + unsigned char color = (*Source++); + /* A */ Dest[1] = (color & 0xf0) << 0; + /* L */ Dest[0] = (color & 0x0f) << 4; + Dest += 2; + } } } } -static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const WORD *Source; - for(y = 0; y < height; y++) + for (z = 0; z < depth; z++) { - unsigned short *Dest_s = (unsigned short *) (dst + y * pitch); - Source = (const WORD *)(src + y * pitch); - for (x = 0; x < width; x++ ) + for (y = 0; y < height; y++) { - short color = (*Source++); - unsigned char l = ((color >> 10) & 0xfc); - short v = ((color >> 5) & 0x3e); - short u = ((color ) & 0x1f); - short v_conv = v + 16; - short u_conv = u + 16; + unsigned short *Dest_s = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch); + Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch); + for (x = 0; x < width; x++ ) + { + short color = (*Source++); + unsigned char l = ((color >> 10) & 0xfc); + short v = ((color >> 5) & 0x3e); + short u = ((color ) & 0x1f); + short v_conv = v + 16; + short u_conv = u + 16; - *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f); - Dest_s += 1; + *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f); + Dest_s += 1; + } } } } -static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const WORD *Source; unsigned char *Dest; - UINT outpitch = (pitch * 3)/2; /* This makes the gl surface bigger(24 bit instead of 16), but it works with * fixed function and shaders without further conversion once the surface is * loaded */ - for(y = 0; y < height; y++) { - Source = (const WORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - short color = (*Source++); - unsigned char l = ((color >> 10) & 0xfc); - char v = ((color >> 5) & 0x3e); - char u = ((color ) & 0x1f); + for (z = 0; z < depth; z++) + { + for (y = 0; y < height; y++) + { + Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch); + Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; + for (x = 0; x < width; x++ ) + { + short color = (*Source++); + unsigned char l = ((color >> 10) & 0xfc); + char v = ((color >> 5) & 0x3e); + char u = ((color ) & 0x1f); - /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign - * and doubles the positive range. Thus shift left only once, gl does the 2nd - * shift. GL reads a signed value and converts it into an unsigned value. - */ - /* M */ Dest[2] = l << 1; + /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign + * and doubles the positive range. Thus shift left only once, gl does the 2nd + * shift. GL reads a signed value and converts it into an unsigned value. + */ + /* M */ Dest[2] = l << 1; - /* Those are read as signed, but kept signed. Just left-shift 3 times to scale - * from 5 bit values to 8 bit values. - */ - /* V */ Dest[1] = v << 3; - /* U */ Dest[0] = u << 3; - Dest += 3; + /* Those are read as signed, but kept signed. Just left-shift 3 times to scale + * from 5 bit values to 8 bit values. + */ + /* V */ Dest[1] = v << 3; + /* U */ Dest[0] = u << 3; + Dest += 3; + } } } } -static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const short *Source; unsigned char *Dest; - UINT outpitch = (pitch * 3)/2; - for(y = 0; y < height; y++) + for (z = 0; z < depth; z++) { - Source = (const short *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) + for (y = 0; y < height; y++) { - const short color = (*Source++); - /* B */ Dest[0] = 0xff; - /* G */ Dest[1] = (color >> 8) + 128; /* V */ - /* R */ Dest[2] = (color & 0xff) + 128; /* U */ - Dest += 3; + Source = (const short *)(src + z * src_slice_pitch + y * src_row_pitch); + Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; + for (x = 0; x < width; x++ ) + { + const short color = (*Source++); + /* B */ Dest[0] = 0xff; + /* G */ Dest[1] = (color >> 8) + 128; /* V */ + /* R */ Dest[2] = (color & 0xff) + 128; /* U */ + Dest += 3; + } } } } -static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const DWORD *Source; unsigned char *Dest; @@ -365,193 +385,222 @@ static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch * shaders if the shader is adjusted. (There's no use for this format in gl's * standard fixed function pipeline anyway). */ - for(y = 0; y < height; y++) + for (z = 0; z < depth; z++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * pitch; - for (x = 0; x < width; x++ ) + for (y = 0; y < height; y++) { - LONG color = (*Source++); - /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */ - /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ - /* R */ Dest[2] = (color & 0xff) + 128; /* U */ - Dest += 4; + Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); + Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */ + /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ + /* R */ Dest[2] = (color & 0xff) + 128; /* U */ + Dest += 4; + } } } } -static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const DWORD *Source; unsigned char *Dest; /* This implementation works with the fixed function pipeline and shaders * without further modification after converting the surface. */ - for(y = 0; y < height; y++) + for (z = 0; z < depth; z++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * pitch; - for (x = 0; x < width; x++ ) + for (y = 0; y < height; y++) { - LONG color = (*Source++); - /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */ - /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */ - /* U */ Dest[0] = (color & 0xff); /* U */ - /* I */ Dest[3] = 255; /* X */ - Dest += 4; + Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); + Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */ + /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */ + /* U */ Dest[0] = (color & 0xff); /* U */ + /* I */ Dest[3] = 255; /* X */ + Dest += 4; + } } } } -static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const DWORD *Source; unsigned char *Dest; - for(y = 0; y < height; y++) + for (z = 0; z < depth; z++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * pitch; - for (x = 0; x < width; x++ ) + for (y = 0; y < height; y++) { - LONG color = (*Source++); - /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */ - /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ - /* R */ Dest[2] = (color & 0xff) + 128; /* U */ - /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */ - Dest += 4; + Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); + Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */ + /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ + /* R */ Dest[2] = (color & 0xff) + 128; /* U */ + /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */ + Dest += 4; + } } } } -static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const DWORD *Source; unsigned short *Dest; - UINT outpitch = (pitch * 3)/2; - for(y = 0; y < height; y++) + for (z = 0; z < depth; z++) { - Source = (const DWORD *)(src + y * pitch); - Dest = (unsigned short *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) + for (y = 0; y < height; y++) { - const DWORD color = (*Source++); - /* B */ Dest[0] = 0xffff; - /* G */ Dest[1] = (color >> 16) + 32768; /* V */ - /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */ - Dest += 3; + Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); + Dest = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch); + for (x = 0; x < width; x++ ) + { + const DWORD color = (*Source++); + /* B */ Dest[0] = 0xffff; + /* G */ Dest[1] = (color >> 16) + 32768; /* V */ + /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */ + Dest += 3; + } } } } -static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r16g16(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const WORD *Source; WORD *Dest; - UINT outpitch = (pitch * 3)/2; - for(y = 0; y < height; y++) + for (z = 0; z < depth; z++) { - Source = (const WORD *)(src + y * pitch); - Dest = (WORD *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) + for (y = 0; y < height; y++) { - WORD green = (*Source++); - WORD red = (*Source++); - Dest[0] = green; - Dest[1] = red; - /* Strictly speaking not correct for R16G16F, but it doesn't matter because the - * shader overwrites it anyway - */ - Dest[2] = 0xffff; - Dest += 3; + Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch); + Dest = (WORD *) (dst + z * dst_slice_pitch + y * dst_row_pitch); + for (x = 0; x < width; x++ ) + { + WORD green = (*Source++); + WORD red = (*Source++); + Dest[0] = green; + Dest[1] = red; + /* Strictly speaking not correct for R16G16F, but it doesn't matter because the + * shader overwrites it anyway */ + Dest[2] = 0xffff; + Dest += 3; + } } } } -static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; const float *Source; float *Dest; - UINT outpitch = (pitch * 3)/2; - for(y = 0; y < height; y++) + for (z = 0; z < depth; z++) { - Source = (const float *)(src + y * pitch); - Dest = (float *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) + for (y = 0; y < height; y++) { - float green = (*Source++); - float red = (*Source++); - Dest[0] = green; - Dest[1] = red; - Dest[2] = 1.0f; - Dest += 3; + Source = (const float *)(src + z * src_slice_pitch + y * src_row_pitch); + Dest = (float *) (dst + z * dst_slice_pitch + y * dst_row_pitch); + for (x = 0; x < width; x++ ) + { + float green = (*Source++); + float red = (*Source++); + Dest[0] = green; + Dest[1] = red; + Dest[2] = 1.0f; + Dest += 3; + } } } } -static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; - UINT outpitch = pitch * 2; + unsigned int x, y, z; - for (y = 0; y < height; ++y) + for (z = 0; z < depth; z++) { - const WORD *source = (const WORD *)(src + y * pitch); - DWORD *dest = (DWORD *)(dst + y * outpitch); - - for (x = 0; x < width; ++x) + for (y = 0; y < height; ++y) { - /* The depth data is normalized, so needs to be scaled, - * the stencil data isn't. Scale depth data by - * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */ - WORD d15 = source[x] >> 1; - DWORD d24 = (d15 << 9) + (d15 >> 6); - dest[x] = (d24 << 8) | (source[x] & 0x1); + const WORD *source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch); + DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch); + + for (x = 0; x < width; ++x) + { + /* The depth data is normalized, so needs to be scaled, + * the stencil data isn't. Scale depth data by + * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */ + WORD d15 = source[x] >> 1; + DWORD d24 = (d15 << 9) + (d15 >> 6); + dest[x] = (d24 << 8) | (source[x] & 0x1); + } } } } -static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; + unsigned int x, y, z; - for (y = 0; y < height; ++y) + for (z = 0; z < depth; z++) { - const DWORD *source = (const DWORD *)(src + y * pitch); - DWORD *dest = (DWORD *)(dst + y * pitch); - - for (x = 0; x < width; ++x) + for (y = 0; y < height; ++y) { - /* Just need to clear out the X4 part. */ - dest[x] = source[x] & ~0xf0; + const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); + DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch); + + for (x = 0; x < width; ++x) + { + /* Just need to clear out the X4 part. */ + dest[x] = source[x] & ~0xf0; + } } } } -static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) { - unsigned int x, y; - UINT outpitch = pitch * 2; + unsigned int x, y, z; - for (y = 0; y < height; ++y) + for (z = 0; z < depth; z++) { - const DWORD *source = (const DWORD *)(src + y * pitch); - float *dest_f = (float *)(dst + y * outpitch); - DWORD *dest_s = (DWORD *)(dst + y * outpitch); - - for (x = 0; x < width; ++x) + for (y = 0; y < height; ++y) { - dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8); - dest_s[x * 2 + 1] = source[x] & 0xff; + const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); + float *dest_f = (float *)(dst + z * dst_slice_pitch + y * dst_row_pitch); + DWORD *dest_s = (DWORD *)dest_f; + + for (x = 0; x < width; ++x) + { + dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8); + dest_s[x * 2 + 1] = source[x] & 0xff; + } } } } @@ -738,7 +787,8 @@ static const struct wined3d_format_texture_info format_texture_info[] = WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, @@ -830,10 +880,18 @@ static const struct wined3d_format_texture_info format_texture_info[] = | WINED3DFMT_FLAG_BUMPMAP, NV_TEXTURE_SHADER, NULL}, /* Depth stencil formats */ + {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_DEPTH, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, ARB_DEPTH_TEXTURE, NULL}, + {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_DEPTH, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, @@ -865,6 +923,10 @@ static const struct wined3d_format_texture_info format_texture_info[] = WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, ARB_FRAMEBUFFER_OBJECT, NULL}, + {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_DEPTH, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING @@ -882,6 +944,10 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm}, + {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_DEPTH, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING @@ -1018,6 +1084,8 @@ static BOOL init_format_block_info(struct wined3d_gl_info *gl_info) format->block_height = format_block_info[i].block_height; format->block_byte_count = format_block_info[i].block_byte_count; format->flags |= WINED3DFMT_FLAG_BLOCKS; + if (!format_block_info[i].verify) + format->flags |= WINED3DFMT_FLAG_BLOCKS_NO_VERIFY; } return TRUE; @@ -2553,6 +2621,21 @@ const char *debug_d3dtstype(enum wined3d_transform_state tstype) } } +static const char *debug_shader_type(enum wined3d_shader_type type) +{ + switch(type) + { +#define WINED3D_TO_STR(type) case type: return #type + WINED3D_TO_STR(WINED3D_SHADER_TYPE_PIXEL); + WINED3D_TO_STR(WINED3D_SHADER_TYPE_VERTEX); + WINED3D_TO_STR(WINED3D_SHADER_TYPE_GEOMETRY); +#undef WINED3D_TO_STR + default: + FIXME("Unrecognized shader type %#x.\n", type); + return "unrecognized"; + } +} + const char *debug_d3dstate(DWORD state) { if (STATE_IS_RENDER(state)) @@ -2566,8 +2649,8 @@ const char *debug_d3dstate(DWORD state) } if (STATE_IS_SAMPLER(state)) return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0)); - if (STATE_IS_PIXELSHADER(state)) - return "STATE_PIXELSHADER"; + if (STATE_IS_SHADER(state)) + return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(state - STATE_SHADER(0))); if (STATE_IS_TRANSFORM(state)) return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0))); if (STATE_IS_STREAMSRC(state)) @@ -2576,10 +2659,6 @@ const char *debug_d3dstate(DWORD state) return "STATE_INDEXBUFFER"; if (STATE_IS_VDECL(state)) return "STATE_VDECL"; - if (STATE_IS_VSHADER(state)) - return "STATE_VSHADER"; - if (STATE_IS_GEOMETRY_SHADER(state)) - return "STATE_GEOMETRY_SHADER"; if (STATE_IS_VIEWPORT(state)) return "STATE_VIEWPORT"; if (STATE_IS_LIGHT_TYPE(state)) @@ -2710,19 +2789,6 @@ void dump_color_fixup_desc(struct color_fixup_desc fixup) TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : ""); } -const char *debug_surflocation(DWORD flag) { - char buf[128]; - - buf[0] = 0; - if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */ - if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */ - if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */ - if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */ - if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */ - if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */ - return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0"); -} - BOOL is_invalid_op(const struct wined3d_state *state, int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3) { @@ -3240,9 +3306,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]); - - if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size) + if (texture->color_key_flags & WINEDDSD_CKSRCBLT && !texture->resource.format->alpha_size) { if (aop == WINED3D_TOP_DISABLE) { @@ -3489,14 +3553,14 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD sampler = state_id - STATE_SAMPLER(0); - DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler]; + DWORD mapped_stage = context->tex_unit_map[sampler]; /* No need to enable / disable anything here for unused samplers. The * tex_colorop handler takes care. Also no action is needed with pixel * shaders, or if tex_colorop will take care of this business. */ if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return; - if (sampler >= state->lowest_disabled_stage) + if (sampler >= context->lowest_disabled_stage) return; if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) return; @@ -3707,17 +3771,53 @@ void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) const char *wined3d_debug_location(DWORD location) { - char buf[200]; + char buf[294]; buf[0] = '\0'; #define LOCATION_TO_STR(u) if (location & u) { strcat(buf, " | "#u); location &= ~u; } LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED); LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM); + LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY); + LOCATION_TO_STR(WINED3D_LOCATION_DIB); LOCATION_TO_STR(WINED3D_LOCATION_BUFFER); LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB); LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB); + LOCATION_TO_STR(WINED3D_LOCATION_DRAWABLE); + 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); return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0"; } + +/* Print a floating point value with the %.8e format specifier, always using + * '.' as decimal separator. */ +void wined3d_ftoa(float value, char *s) +{ + int idx = 1; + + if (copysignf(1.0f, value) < 0.0f) + ++idx; + + /* Be sure to allocate a buffer of at least 17 characters for the result + as sprintf may return a 3 digit exponent when using the MSVC runtime + instead of a 2 digit exponent. */ + sprintf(s, "%.8e", value); + if (isfinite(value)) + s[idx] = '.'; +} + +void wined3d_release_dc(HWND window, HDC dc) +{ + /* You'd figure ReleaseDC() would fail if the DC doesn't match the window. + * However, that's not what actually happens, and there are user32 tests + * that confirm ReleaseDC() with the wrong window is supposed to succeed. + * So explicitly check that the DC belongs to the window, since we want to + * avoid releasing a DC that belongs to some other window if the original + * window was already destroyed. */ + if (WindowFromDC(dc) != window) + WARN("DC %p does not belong to window %p.\n", dc, window); + else if (!ReleaseDC(window, dc)) + ERR("Failed to release device context %p, last error %#x.\n", dc, GetLastError()); +} diff --git a/reactos/dll/directx/wine/wined3d/volume.c b/reactos/dll/directx/wine/wined3d/volume.c index df8e5e49b4b..bd0420066ce 100644 --- a/reactos/dll/directx/wine/wined3d/volume.c +++ b/reactos/dll/directx/wine/wined3d/volume.c @@ -25,29 +25,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); -/* Context activation is done by the caller. */ -static void volume_bind_and_dirtify(const struct wined3d_volume *volume, - struct wined3d_context *context, BOOL srgb) -{ - struct wined3d_texture *container = volume->container; - DWORD active_sampler; - - /* We don't need a specific texture unit, but after binding the texture the current unit is dirty. - * Read the unit back instead of switching to 0, this avoids messing around with the state manager's - * gl states. The current texture unit should always be a valid one. - * - * To be more specific, this is tricky because we can implicitly be called - * from sampler() in state.c. This means we can't touch anything other than - * whatever happens to be the currently active texture, or we would risk - * marking already applied sampler states dirty again. */ - active_sampler = volume->resource.device->rev_tex_unit_map[context->active_texture]; - - if (active_sampler != WINED3D_UNMAPPED_STAGE) - device_invalidate_state(volume->resource.device, STATE_SAMPLER(active_sampler)); - - container->texture_ops->texture_bind(container, context, srgb); -} - void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container) { TRACE("volume %p, container %p.\n", volume, container); @@ -55,18 +32,73 @@ void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture volume->container = container; } +static BOOL volume_prepare_system_memory(struct wined3d_volume *volume) +{ + if (volume->resource.heap_memory) + return TRUE; + + if (!wined3d_resource_allocate_sysmem(&volume->resource)) + { + ERR("Failed to allocate system memory.\n"); + return FALSE; + } + return TRUE; +} + /* Context activation is done by the caller. */ -static void wined3d_volume_allocate_texture(const struct wined3d_volume *volume, +static void wined3d_volume_allocate_texture(struct wined3d_volume *volume, const struct wined3d_context *context, BOOL srgb) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; + void *mem = NULL; + + if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert + && volume_prepare_system_memory(volume)) + { + TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume); + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); + checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)"); + mem = volume->resource.heap_memory; + volume->flags |= WINED3D_VFLAG_CLIENT_STORAGE; + } GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, volume->texture_level, srgb ? format->glGammaInternal : format->glInternal, volume->resource.width, volume->resource.height, volume->resource.depth, - 0, format->glFormat, format->glType, NULL)); + 0, format->glFormat, format->glType, mem)); checkGLcall("glTexImage3D"); + + if (mem) + { + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); + checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)"); + } +} + +static void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, + UINT *slice_pitch) +{ + const struct wined3d_format *format = volume->resource.format; + + if (format->flags & WINED3DFMT_FLAG_BLOCKS) + { + /* Since compressed formats are block based, pitch means the amount of + * bytes to the next row of block rather than the next row of pixels. */ + UINT row_block_count = (volume->resource.width + format->block_width - 1) / format->block_width; + UINT slice_block_count = (volume->resource.height + format->block_height - 1) / format->block_height; + *row_pitch = row_block_count * format->block_byte_count; + *slice_pitch = *row_pitch * slice_block_count; + } + else + { + unsigned char alignment = volume->resource.device->surface_alignment; + *row_pitch = format->byte_count * volume->resource.width; /* Bytes / row */ + *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1); + *slice_pitch = *row_pitch * volume->resource.height; + } + + TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch); } /* Context activation is done by the caller. */ @@ -75,11 +107,36 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; + UINT width = volume->resource.width; + UINT height = volume->resource.height; + UINT depth = volume->resource.depth; + BYTE *mem = data->addr; TRACE("volume %p, context %p, level %u, format %s (%#x).\n", volume, context, volume->texture_level, debug_d3dformat(format->id), format->id); + if (format->convert) + { + UINT dst_row_pitch, dst_slice_pitch; + UINT src_row_pitch, src_slice_pitch; + UINT alignment = volume->resource.device->surface_alignment; + + if (data->buffer_object) + ERR("Loading a converted volume from a PBO.\n"); + if (format->flags & WINED3DFMT_FLAG_BLOCKS) + ERR("Converting a block-based format.\n"); + + dst_row_pitch = width * format->conv_byte_count; + dst_row_pitch = (dst_row_pitch + alignment - 1) & ~(alignment - 1); + dst_slice_pitch = dst_row_pitch * height; + + wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch); + + mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); + format->convert(data->addr, mem, src_row_pitch, src_slice_pitch, + dst_row_pitch, dst_slice_pitch, width, height, depth); + } if (data->buffer_object) { @@ -88,8 +145,8 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine } GL_EXTCALL(glTexSubImage3DEXT(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0, - volume->resource.width, volume->resource.height, volume->resource.depth, - format->glFormat, format->glType, data->addr)); + width, height, depth, + format->glFormat, format->glType, mem)); checkGLcall("glTexSubImage3D"); if (data->buffer_object) @@ -97,6 +154,9 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); checkGLcall("glBindBufferARB"); } + + if (mem != data->addr) + HeapFree(GetProcessHeap(), 0, mem); } static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) @@ -120,6 +180,13 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume, const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; + if (format->convert) + { + FIXME("Attempting to download a converted volume, format %s.\n", + debug_d3dformat(format->id)); + return; + } + if (data->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data->buffer_object)); @@ -140,9 +207,7 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume, static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) { - wined3d_resource_free_sysmem(volume->resource.heap_memory); - volume->resource.heap_memory = NULL; - volume->resource.allocatedMemory = NULL; + wined3d_resource_free_sysmem(&volume->resource); wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM); } @@ -176,7 +241,7 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume, * implementing EXT_SRGB_DECODE in the driver or finding out why we * picked the wrong copy for the original upload and fixing that. * - * Also keep in mind that we want to avoid using resource.allocatedMemory + * Also keep in mind that we want to avoid using resource.heap_memory * for DEFAULT pool surfaces. */ WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n"); @@ -185,14 +250,27 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume, if (!data.addr) return; - volume_bind_and_dirtify(volume, context, !dest_is_srgb); + wined3d_texture_bind_and_dirtify(volume->container, context, !dest_is_srgb); wined3d_volume_download_data(volume, context, &data); - volume_bind_and_dirtify(volume, context, dest_is_srgb); + wined3d_texture_bind_and_dirtify(volume->container, context, dest_is_srgb); wined3d_volume_upload_data(volume, context, &data); HeapFree(GetProcessHeap(), 0, data.addr); } +static BOOL wined3d_volume_can_evict(const struct wined3d_volume *volume) +{ + if (volume->resource.pool != WINED3D_POOL_MANAGED) + return FALSE; + if (volume->download_count >= 10) + return FALSE; + if (volume->resource.format->convert) + return FALSE; + if (volume->flags & WINED3D_VFLAG_CLIENT_STORAGE) + return FALSE; + + return TRUE; +} /* Context activation is done by the caller. */ static void wined3d_volume_load_location(struct wined3d_volume *volume, struct wined3d_context *context, DWORD location) @@ -232,7 +310,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, } else if (volume->locations & WINED3D_LOCATION_SYSMEM) { - struct wined3d_bo_address data = {0, volume->resource.allocatedMemory}; + struct wined3d_bo_address data = {0, volume->resource.heap_memory}; wined3d_volume_upload_data(volume, context, &data); } else if (volume->locations & WINED3D_LOCATION_BUFFER) @@ -255,17 +333,14 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, } wined3d_volume_validate_location(volume, location); - if (volume->resource.pool == WINED3D_POOL_MANAGED && volume->download_count < 10) + if (wined3d_volume_can_evict(volume)) wined3d_volume_evict_sysmem(volume); break; case WINED3D_LOCATION_SYSMEM: - if (!volume->resource.allocatedMemory || !volume->resource.heap_memory) - { + if (!volume->resource.heap_memory) ERR("Trying to load WINED3D_LOCATION_SYSMEM without setting it up first.\n"); - return; - } if (volume->locations & WINED3D_LOCATION_DISCARDED) { @@ -274,12 +349,12 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, } else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { - struct wined3d_bo_address data = {0, volume->resource.allocatedMemory}; + struct wined3d_bo_address data = {0, volume->resource.heap_memory}; if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) - volume_bind_and_dirtify(volume, context, FALSE); + wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); else - volume_bind_and_dirtify(volume, context, TRUE); + wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); volume->download_count++; wined3d_volume_download_data(volume, context, &data); @@ -307,9 +382,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, struct wined3d_bo_address data = {volume->pbo, NULL}; if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) - volume_bind_and_dirtify(volume, context, FALSE); + wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); else - volume_bind_and_dirtify(volume, context, TRUE); + wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); wined3d_volume_download_data(volume, context, &data); } @@ -331,7 +406,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, /* Context activation is done by the caller. */ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) { - volume_bind_and_dirtify(volume, context, srgb_mode); + wined3d_texture_bind_and_dirtify(volume->container, context, srgb_mode); if (srgb_mode) { @@ -384,19 +459,6 @@ static void wined3d_volume_free_pbo(struct wined3d_volume *volume) context_release(context); } -static BOOL volume_prepare_system_memory(struct wined3d_volume *volume) -{ - if (volume->resource.allocatedMemory) - return TRUE; - - volume->resource.heap_memory = wined3d_resource_allocate_sysmem(volume->resource.size); - if (!volume->resource.heap_memory) - return FALSE; - volume->resource.allocatedMemory = volume->resource.heap_memory; - return TRUE; -} - - static void volume_unload(struct wined3d_resource *resource) { struct wined3d_volume *volume = volume_from_resource(resource); @@ -432,7 +494,8 @@ static void volume_unload(struct wined3d_resource *resource) } /* The texture name is managed by the container. */ - volume->flags &= ~(WINED3D_VFLAG_ALLOCATED | WINED3D_VFLAG_SRGB_ALLOCATED); + volume->flags &= ~(WINED3D_VFLAG_ALLOCATED | WINED3D_VFLAG_SRGB_ALLOCATED + | WINED3D_VFLAG_CLIENT_STORAGE); resource_unload(resource); } @@ -454,7 +517,6 @@ ULONG CDECL wined3d_volume_incref(struct wined3d_volume *volume) return refcount; } -/* Do not call while under the GL lock. */ ULONG CDECL wined3d_volume_decref(struct wined3d_volume *volume) { ULONG refcount; @@ -499,7 +561,6 @@ DWORD CDECL wined3d_volume_get_priority(const struct wined3d_volume *volume) return resource_get_priority(&volume->resource); } -/* Do not call while under the GL lock. */ void CDECL wined3d_volume_preload(struct wined3d_volume *volume) { FIXME("volume %p stub!\n", volume); @@ -512,6 +573,56 @@ struct wined3d_resource * CDECL wined3d_volume_get_resource(struct wined3d_volum return &volume->resource; } +static BOOL volume_check_block_align(const struct wined3d_volume *volume, + const struct wined3d_box *box) +{ + UINT width_mask, height_mask; + const struct wined3d_format *format = volume->resource.format; + + if (!box) + return TRUE; + + /* This assumes power of two block sizes, but NPOT block sizes would be + * silly anyway. + * + * This also assumes that the format's block depth is 1. */ + width_mask = format->block_width - 1; + height_mask = format->block_height - 1; + + if (box->left & width_mask) + return FALSE; + if (box->top & height_mask) + return FALSE; + if (box->right & width_mask && box->right != volume->resource.width) + return FALSE; + if (box->bottom & height_mask && box->bottom != volume->resource.height) + return FALSE; + + return TRUE; +} + +static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *volume, + const struct wined3d_box *box) +{ + if (!box) + return TRUE; + + if (box->left >= box->right) + return FALSE; + if (box->top >= box->bottom) + return FALSE; + if (box->front >= box->back) + return FALSE; + if (box->right > volume->resource.width) + return FALSE; + if (box->bottom > volume->resource.height) + return FALSE; + if (box->back > volume->resource.depth) + return FALSE; + + return TRUE; +} + HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) { @@ -519,16 +630,34 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume, struct wined3d_context *context; const struct wined3d_gl_info *gl_info; BYTE *base_memory; + const struct wined3d_format *format = volume->resource.format; TRACE("volume %p, map_desc %p, box %p, flags %#x.\n", volume, map_desc, box, flags); + map_desc->data = NULL; if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) { WARN("Volume %p is not CPU accessible.\n", volume); - map_desc->data = NULL; return WINED3DERR_INVALIDCALL; } + if (volume->resource.map_count) + { + WARN("Volume is already mapped.\n"); + return WINED3DERR_INVALIDCALL; + } + if (!wined3d_volume_check_box_dimensions(volume, box)) + { + WARN("Map box is invalid.\n"); + return WINED3DERR_INVALIDCALL; + } + if ((format->flags & WINED3DFMT_FLAG_BLOCKS) && !volume_check_block_align(volume, box)) + { + WARN("Map box is misaligned for %ux%u blocks.\n", + format->block_width, format->block_height); + return WINED3DERR_INVALIDCALL; + } + flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags); if (volume->flags & WINED3D_VFLAG_PBO) @@ -553,7 +682,8 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume, } else { - base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + GLenum access = wined3d_resource_gl_legacy_map_flags(flags); + base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, access)); } GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); @@ -580,14 +710,21 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume, wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM); context_release(context); } - base_memory = volume->resource.allocatedMemory; + base_memory = volume->resource.heap_memory; } TRACE("Base memory pointer %p.\n", base_memory); - map_desc->row_pitch = volume->resource.format->byte_count * volume->resource.width; /* Bytes / row */ - map_desc->slice_pitch = volume->resource.format->byte_count - * volume->resource.width * volume->resource.height; /* Bytes / slice */ + if (format->flags & WINED3DFMT_FLAG_BROKEN_PITCH) + { + map_desc->row_pitch = volume->resource.width * format->byte_count; + map_desc->slice_pitch = map_desc->row_pitch * volume->resource.height; + } + else + { + wined3d_volume_get_pitch(volume, &map_desc->row_pitch, &map_desc->slice_pitch); + } + if (!box) { TRACE("No box supplied - all is ok\n"); @@ -597,15 +734,28 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume, { TRACE("Lock Box (%p) = l %u, t %u, r %u, b %u, fr %u, ba %u\n", box, box->left, box->top, box->right, box->bottom, box->front, box->back); - map_desc->data = base_memory - + (map_desc->slice_pitch * box->front) /* FIXME: is front < back or vica versa? */ - + (map_desc->row_pitch * box->top) - + (box->left * volume->resource.format->byte_count); + + if ((format->flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) + { + /* Compressed textures are block based, so calculate the offset of + * the block that contains the top-left pixel of the locked rectangle. */ + map_desc->data = base_memory + + (box->front * map_desc->slice_pitch) + + ((box->top / format->block_height) * map_desc->row_pitch) + + ((box->left / format->block_width) * format->block_byte_count); + } + else + { + map_desc->data = base_memory + + (map_desc->slice_pitch * box->front) + + (map_desc->row_pitch * box->top) + + (box->left * volume->resource.format->byte_count); + } } if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) { - wined3d_texture_set_dirty(volume->container, TRUE); + wined3d_texture_set_dirty(volume->container); if (volume->flags & WINED3D_VFLAG_PBO) wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_BUFFER); @@ -613,7 +763,7 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume, wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_SYSMEM); } - volume->flags |= WINED3D_VFLAG_LOCKED; + volume->resource.map_count++; TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); @@ -630,9 +780,9 @@ HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume) { TRACE("volume %p.\n", volume); - if (!(volume->flags & WINED3D_VFLAG_LOCKED)) + if (!volume->resource.map_count) { - WARN("Trying to unlock unlocked volume %p.\n", volume); + WARN("Trying to unlock an unlocked volume %p.\n", volume); return WINED3DERR_INVALIDCALL; } @@ -650,7 +800,7 @@ HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume) context_release(context); } - volume->flags &= ~WINED3D_VFLAG_LOCKED; + volume->resource.map_count--; return WINED3D_OK; } @@ -660,12 +810,12 @@ static const struct wined3d_resource_ops volume_resource_ops = volume_unload, }; -static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device *device, UINT width, - UINT height, UINT depth, UINT level, DWORD usage, enum wined3d_format_id format_id, - enum wined3d_pool pool, void *parent, const struct wined3d_parent_ops *parent_ops) +static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture *container, + const struct wined3d_resource_desc *desc, UINT level) { + struct wined3d_device *device = container->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, format_id); + const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format); HRESULT hr; UINT size; @@ -676,19 +826,18 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device } /* TODO: Write tests for other resources and move this check * to resource_init, if applicable. */ - if (usage & WINED3DUSAGE_DYNAMIC - && (pool == WINED3D_POOL_MANAGED || pool == WINED3D_POOL_SCRATCH)) + if (desc->usage & WINED3DUSAGE_DYNAMIC + && (desc->pool == WINED3D_POOL_MANAGED || desc->pool == WINED3D_POOL_SCRATCH)) { - WARN("Attempted to create a DYNAMIC texture in pool %u.\n", pool); + WARN("Attempted to create a DYNAMIC texture in pool %s.\n", debug_d3dpool(desc->pool)); return WINED3DERR_INVALIDCALL; } - size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, depth); + size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, desc->depth); - hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format, - WINED3D_MULTISAMPLE_NONE, 0, usage, pool, width, height, depth, - size, parent, parent_ops, &volume_resource_ops); - if (FAILED(hr)) + if (FAILED(hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format, + WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->pool, desc->width, desc->height, desc->depth, + size, NULL, &wined3d_null_parent_ops, &volume_resource_ops))) { WARN("Failed to initialize resource, returning %#x.\n", hr); return hr; @@ -697,46 +846,56 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device volume->texture_level = level; volume->locations = WINED3D_LOCATION_DISCARDED; - if (pool == WINED3D_POOL_DEFAULT && usage & WINED3DUSAGE_DYNAMIC - && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) + if (desc->pool == WINED3D_POOL_DEFAULT && desc->usage & WINED3DUSAGE_DYNAMIC + && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] + && !format->convert) { - wined3d_resource_free_sysmem(volume->resource.heap_memory); - volume->resource.heap_memory = NULL; - volume->resource.allocatedMemory = NULL; + wined3d_resource_free_sysmem(&volume->resource); volume->flags |= WINED3D_VFLAG_PBO; } + volume_set_container(volume, container); + return WINED3D_OK; } -HRESULT CDECL wined3d_volume_create(struct wined3d_device *device, UINT width, UINT height, - UINT depth, UINT level, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, - void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_volume **volume) +HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, + unsigned int level, struct wined3d_volume **volume) { + struct wined3d_device_parent *device_parent = container->resource.device->device_parent; + const struct wined3d_parent_ops *parent_ops; struct wined3d_volume *object; + void *parent; HRESULT hr; - TRACE("device %p, width %u, height %u, depth %u, usage %#x, format %s, pool %s\n", - device, width, height, depth, usage, debug_d3dformat(format_id), debug_d3dpool(pool)); - TRACE("parent %p, parent_ops %p, volume %p.\n", parent, parent_ops, volume); + TRACE("container %p, width %u, height %u, depth %u, level %u, format %s, " + "usage %#x, pool %s, volume %p.\n", + container, desc->width, desc->height, desc->depth, level, debug_d3dformat(desc->format), + desc->usage, debug_d3dpool(desc->pool), volume); - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) - { - *volume = NULL; - return WINED3DERR_OUTOFVIDEOMEMORY; - } + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; - hr = volume_init(object, device, width, height, depth, level, - usage, format_id, pool, parent, parent_ops); - if (FAILED(hr)) + if (FAILED(hr = volume_init(object, container, desc, level))) { WARN("Failed to initialize volume, returning %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); return hr; } - TRACE("Created volume %p.\n", object); + if (FAILED(hr = device_parent->ops->volume_created(device_parent, + wined3d_texture_get_parent(container), object, &parent, &parent_ops))) + { + WARN("Failed to create volume parent, hr %#x.\n", hr); + volume_set_container(object, NULL); + wined3d_volume_decref(object); + return hr; + } + + TRACE("Created volume %p, parent %p, parent_ops %p.\n", object, parent, parent_ops); + + object->resource.parent = parent; + object->resource.parent_ops = parent_ops; *volume = object; return WINED3D_OK; diff --git a/reactos/dll/directx/wine/wined3d/wined3d.spec b/reactos/dll/directx/wine/wined3d/wined3d.spec index f451b7a35ac..3a6dd333081 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d.spec +++ b/reactos/dll/directx/wine/wined3d/wined3d.spec @@ -156,11 +156,9 @@ @ cdecl wined3d_device_update_texture(ptr ptr ptr) @ cdecl wined3d_device_validate_device(ptr ptr) -@ cdecl wined3d_palette_create(ptr long ptr ptr ptr) +@ cdecl wined3d_palette_create(ptr long long ptr ptr) @ cdecl wined3d_palette_decref(ptr) @ cdecl wined3d_palette_get_entries(ptr long long long ptr) -@ cdecl wined3d_palette_get_flags(ptr) -@ cdecl wined3d_palette_get_parent(ptr) @ cdecl wined3d_palette_incref(ptr) @ cdecl wined3d_palette_set_entries(ptr long long long ptr) @@ -176,6 +174,7 @@ @ cdecl wined3d_resource_get_desc(ptr ptr) @ cdecl wined3d_resource_get_parent(ptr) @ cdecl wined3d_resource_get_private_data(ptr ptr ptr ptr) +@ cdecl wined3d_resource_set_parent(ptr ptr) @ cdecl wined3d_resource_set_private_data(ptr ptr ptr long long) @ cdecl wined3d_rendertarget_view_create(ptr ptr ptr) @@ -205,9 +204,7 @@ @ cdecl wined3d_stateblock_incref(ptr) @ cdecl wined3d_surface_blt(ptr ptr ptr ptr long ptr long) -@ cdecl wined3d_surface_create(ptr long long long long long long long long ptr ptr ptr) @ cdecl wined3d_surface_decref(ptr) -@ cdecl wined3d_surface_flip(ptr ptr long) @ cdecl wined3d_surface_from_resource(ptr) @ cdecl wined3d_surface_get_blt_status(ptr long) @ cdecl wined3d_surface_get_flip_status(ptr long) @@ -225,13 +222,11 @@ @ cdecl wined3d_surface_preload(ptr) @ cdecl wined3d_surface_releasedc(ptr ptr) @ cdecl wined3d_surface_restore(ptr) -@ cdecl wined3d_surface_set_color_key(ptr long ptr) -@ cdecl wined3d_surface_set_mem(ptr ptr long) @ cdecl wined3d_surface_set_overlay_position(ptr long long) @ cdecl wined3d_surface_set_palette(ptr ptr) @ cdecl wined3d_surface_set_priority(ptr long) @ cdecl wined3d_surface_unmap(ptr) -@ cdecl wined3d_surface_update_desc(ptr long long long long long) +@ cdecl wined3d_surface_update_desc(ptr long long long long long ptr long) @ cdecl wined3d_surface_update_overlay(ptr ptr ptr ptr long ptr) @ cdecl wined3d_surface_update_overlay_z_order(ptr long ptr) @@ -251,9 +246,7 @@ @ cdecl wined3d_swapchain_set_window(ptr ptr) @ cdecl wined3d_texture_add_dirty_region(ptr long ptr) -@ cdecl wined3d_texture_create_2d(ptr ptr long long ptr ptr ptr) -@ cdecl wined3d_texture_create_3d(ptr ptr long ptr ptr ptr) -@ cdecl wined3d_texture_create_cube(ptr ptr long long ptr ptr ptr) +@ cdecl wined3d_texture_create(ptr ptr long long ptr ptr ptr) @ cdecl wined3d_texture_decref(ptr) @ cdecl wined3d_texture_generate_mipmaps(ptr) @ cdecl wined3d_texture_get_autogen_filter_type(ptr) @@ -266,6 +259,7 @@ @ cdecl wined3d_texture_incref(ptr) @ cdecl wined3d_texture_preload(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_priority(ptr long) @@ -275,7 +269,6 @@ @ cdecl wined3d_vertex_declaration_get_parent(ptr) @ cdecl wined3d_vertex_declaration_incref(ptr) -@ cdecl wined3d_volume_create(ptr long long long long long long ptr ptr ptr) @ cdecl wined3d_volume_decref(ptr) @ cdecl wined3d_volume_from_resource(ptr) @ cdecl wined3d_volume_get_parent(ptr) diff --git a/reactos/dll/directx/wine/wined3d/wined3d_gl.h b/reactos/dll/directx/wine/wined3d/wined3d_gl.h index 8ad865e4d3c..b357bb180db 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_gl.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_gl.h @@ -84,6 +84,7 @@ enum wined3d_gl_extension ARB_TEXTURE_ENV_DOT3, ARB_TEXTURE_FLOAT, ARB_TEXTURE_MIRRORED_REPEAT, + ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE, ARB_TEXTURE_NON_POWER_OF_TWO, ARB_TEXTURE_RECTANGLE, ARB_TEXTURE_RG, @@ -126,6 +127,7 @@ enum wined3d_gl_extension EXT_TEXTURE_ENV_DOT3, EXT_TEXTURE_FILTER_ANISOTROPIC, EXT_TEXTURE_LOD_BIAS, + EXT_TEXTURE_MIRROR_CLAMP, EXT_TEXTURE_SRGB, EXT_TEXTURE_SRGB_DECODE, EXT_VERTEX_ARRAY_BGRA, diff --git a/reactos/dll/directx/wine/wined3d/wined3d_main.c b/reactos/dll/directx/wine/wined3d/wined3d_main.c index 6eab4aec14f..d290a6f362a 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_main.c +++ b/reactos/dll/directx/wine/wined3d/wined3d_main.c @@ -85,7 +85,6 @@ struct wined3d_settings wined3d_settings = FALSE, /* 3D support enabled by default. */ }; -/* Do not call while under the GL lock. */ struct wined3d * CDECL wined3d_create(UINT version, DWORD flags) { struct wined3d *object; @@ -157,8 +156,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstDLL; - wc.hIcon = LoadIconA(NULL, (LPCSTR)IDI_WINLOGO); - wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW); + wc.hIcon = LoadIconA(NULL, (const char *)IDI_WINLOGO); + wc.hCursor = LoadCursorA(NULL, (const char *)IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = WINED3D_OPENGL_WINDOW_CLASS_NAME; @@ -505,18 +504,17 @@ void wined3d_unregister_window(HWND window) } /* At process attach */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { - TRACE("WineD3D DLLMain Reason=%u\n", fdwReason); - - switch (fdwReason) + switch (reason) { case DLL_PROCESS_ATTACH: - return wined3d_dll_init(hInstDLL); + return wined3d_dll_init(inst); case DLL_PROCESS_DETACH: - if (lpv) break; - return wined3d_dll_destroy(hInstDLL); + if (!reserved) + return wined3d_dll_destroy(inst); + break; case DLL_THREAD_DETACH: if (!context_set_current(NULL)) diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 17988f76ad7..abfcb7a1dc9 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -551,6 +551,7 @@ enum wined3d_shader_type WINED3D_SHADER_TYPE_PIXEL, WINED3D_SHADER_TYPE_VERTEX, WINED3D_SHADER_TYPE_GEOMETRY, + WINED3D_SHADER_TYPE_COUNT, }; struct wined3d_shader_version @@ -946,7 +947,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN; DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; -#define eps 1e-8 +#define eps 1e-8f #define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \ (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1) @@ -963,10 +964,10 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define STATE_SAMPLER(num) (STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE) + 1 + (num)) #define STATE_IS_SAMPLER(num) ((num) >= STATE_SAMPLER(0) && (num) <= STATE_SAMPLER(MAX_COMBINED_SAMPLERS - 1)) -#define STATE_PIXELSHADER (STATE_SAMPLER(MAX_COMBINED_SAMPLERS - 1) + 1) -#define STATE_IS_PIXELSHADER(a) ((a) == STATE_PIXELSHADER) +#define STATE_SHADER(a) (STATE_SAMPLER(MAX_COMBINED_SAMPLERS) + (a)) +#define STATE_IS_SHADER(a) ((a) >= STATE_SHADER(0) && (a) < STATE_SHADER(WINED3D_SHADER_TYPE_COUNT)) -#define STATE_TRANSFORM(a) (STATE_PIXELSHADER + (a)) +#define STATE_TRANSFORM(a) (STATE_SHADER(WINED3D_SHADER_TYPE_COUNT) + (a) - 1) #define STATE_IS_TRANSFORM(a) ((a) >= STATE_TRANSFORM(1) && (a) <= STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255))) #define STATE_STREAMSRC (STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)) + 1) @@ -977,13 +978,7 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define STATE_VDECL (STATE_INDEXBUFFER + 1) #define STATE_IS_VDECL(a) ((a) == STATE_VDECL) -#define STATE_VSHADER (STATE_VDECL + 1) -#define STATE_IS_VSHADER(a) ((a) == STATE_VSHADER) - -#define STATE_GEOMETRY_SHADER (STATE_VSHADER + 1) -#define STATE_IS_GEOMETRY_SHADER(a) ((a) == STATE_GEOMETRY_SHADER) - -#define STATE_VIEWPORT (STATE_GEOMETRY_SHADER + 1) +#define STATE_VIEWPORT (STATE_VDECL + 1) #define STATE_IS_VIEWPORT(a) ((a) == STATE_VIEWPORT) #define STATE_LIGHT_TYPE (STATE_VIEWPORT + 1) @@ -1092,9 +1087,13 @@ struct wined3d_context DWORD current : 1; DWORD destroyed : 1; DWORD valid : 1; - DWORD padding : 1; + DWORD use_immediate_mode_draw : 1; DWORD texShaderBumpMap : 8; /* MAX_TEXTURES, 8 */ DWORD lastWasPow2Texture : 8; /* MAX_TEXTURES, 8 */ + DWORD fixed_function_usage_map : 8; /* MAX_TEXTURES, 8 */ + DWORD lowest_disabled_stage : 4; /* Max MAX_TEXTURES, 8 */ + DWORD rebind_fbo : 1; + DWORD padding : 19; DWORD shader_update_mask; DWORD constant_update_mask; DWORD numbered_array_mask; @@ -1105,6 +1104,8 @@ struct wined3d_context DWORD active_texture; DWORD texture_type[MAX_COMBINED_SAMPLERS]; + UINT instance_count; + /* The actual opengl context */ UINT level; HGLRC restore_ctx; @@ -1125,7 +1126,6 @@ struct wined3d_context struct fbo_entry *current_fbo; GLuint fbo_read_binding; GLuint fbo_draw_binding; - BOOL rebind_fbo; struct wined3d_surface **blit_targets; GLenum *draw_buffers; DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */ @@ -1141,6 +1141,15 @@ struct wined3d_context UINT free_event_query_count; struct list event_queries; + struct wined3d_stream_info stream_info; + + /* Fences for GL_APPLE_flush_buffer_range */ + struct wined3d_event_query *buffer_queries[MAX_ATTRIBS]; + unsigned int num_buffer_queries; + + DWORD tex_unit_map[MAX_COMBINED_SAMPLERS]; + DWORD rev_tex_unit_map[MAX_COMBINED_SAMPLERS]; + /* Extension emulation */ GLint gl_fog_source; GLfloat fog_coord_value; @@ -1308,6 +1317,8 @@ void context_state_drawbuf(struct wined3d_context *context, void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) DECLSPEC_HIDDEN; +void context_stream_info_from_declaration(struct wined3d_context *context, + const struct wined3d_state *state, struct wined3d_stream_info *stream_info) DECLSPEC_HIDDEN; /***************************************************************************** * Internal representation of a light @@ -1461,10 +1472,12 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_GTX650 = 0x0fc6, CARD_NVIDIA_GEFORCE_GTX650TI = 0x11c6, CARD_NVIDIA_GEFORCE_GTX660 = 0x11c0, + CARD_NVIDIA_GEFORCE_GTX660M = 0x0fd4, CARD_NVIDIA_GEFORCE_GTX660TI = 0x1183, CARD_NVIDIA_GEFORCE_GTX670 = 0x1189, CARD_NVIDIA_GEFORCE_GTX670MX = 0x11a1, CARD_NVIDIA_GEFORCE_GTX680 = 0x1180, + CARD_NVIDIA_GEFORCE_GTX765M = 0x11e2, CARD_NVIDIA_GEFORCE_GTX770M = 0x11e0, CARD_NVIDIA_GEFORCE_GTX770 = 0x1184, @@ -1502,6 +1515,7 @@ enum wined3d_pci_device CARD_INTEL_IVBD = 0x0162, CARD_INTEL_IVBM = 0x0166, CARD_INTEL_IVBS = 0x015a, + CARD_INTEL_HWM = 0x0416, }; struct wined3d_fbo_ops @@ -1719,6 +1733,10 @@ const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *frag 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; +extern const float wined3d_srgb_const1[] DECLSPEC_HIDDEN; enum wined3d_ffp_vs_fog_mode { @@ -1794,8 +1812,12 @@ struct wined3d_stream_state UINT flags; }; +#define WINED3D_STATE_NO_REF 0x00000001 +#define WINED3D_STATE_INIT_DEFAULT 0x00000002 + struct wined3d_state { + DWORD flags; const struct wined3d_fb_state *fb; struct wined3d_vertex_declaration *vertex_declaration; @@ -1807,20 +1829,14 @@ struct wined3d_state INT load_base_vertex_index; /* Non-indexed drawing needs 0 here, indexed needs base_vertex_index. */ GLenum gl_primitive_type; - struct wined3d_shader *vertex_shader; - struct wined3d_buffer *vs_cb[MAX_CONSTANT_BUFFERS]; - struct wined3d_sampler *vs_sampler[MAX_SAMPLER_OBJECTS]; + struct wined3d_shader *shader[WINED3D_SHADER_TYPE_COUNT]; + struct wined3d_buffer *cb[WINED3D_SHADER_TYPE_COUNT][MAX_CONSTANT_BUFFERS]; + struct wined3d_sampler *sampler[WINED3D_SHADER_TYPE_COUNT][MAX_SAMPLER_OBJECTS]; + BOOL vs_consts_b[MAX_CONST_B]; INT vs_consts_i[MAX_CONST_I * 4]; float *vs_consts_f; - struct wined3d_shader *geometry_shader; - struct wined3d_buffer *gs_cb[MAX_CONSTANT_BUFFERS]; - struct wined3d_sampler *gs_sampler[MAX_SAMPLER_OBJECTS]; - - struct wined3d_shader *pixel_shader; - struct wined3d_buffer *ps_cb[MAX_CONSTANT_BUFFERS]; - struct wined3d_sampler *ps_sampler[MAX_SAMPLER_OBJECTS]; BOOL ps_consts_b[MAX_CONST_B]; INT ps_consts_i[MAX_CONST_I * 4]; float *ps_consts_f; @@ -1828,7 +1844,6 @@ struct wined3d_state struct wined3d_texture *textures[MAX_COMBINED_SAMPLERS]; DWORD sampler_states[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1]; DWORD texture_states[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1]; - DWORD lowest_disabled_stage; struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1]; struct wined3d_vec4 clip_planes[MAX_CLIPPLANES]; @@ -1845,12 +1860,10 @@ struct wined3d_state DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; }; -/***************************************************************************** - * IWineD3DDevice implementation structure - */ #define WINED3D_UNMAPPED_STAGE ~0U -/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */ +/* Multithreaded flag. Removed from the public header to signal that + * wined3d_device_create() ignores it. */ #define WINED3DCREATE_MULTITHREADED 0x00000004 struct wined3d_device @@ -1879,22 +1892,18 @@ struct wined3d_device APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1]; const struct blit_shader *blitter; - UINT instance_count; - - WORD vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */ - WORD isInDraw : 1; - WORD bCursorVisible : 1; - WORD d3d_initialized : 1; - WORD inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */ - WORD softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */ - WORD useDrawStridedSlow : 1; - WORD filter_messages : 1; - WORD padding : 8; - - BYTE fixed_function_usage_map; /* MAX_TEXTURES, 8 */ + BYTE vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */ + BYTE bCursorVisible : 1; + BYTE d3d_initialized : 1; + BYTE inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */ + BYTE softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */ + BYTE filter_messages : 1; + BYTE padding : 2; unsigned char surface_alignment; /* Line Alignment of surfaces */ + WORD padding2 : 16; + struct wined3d_state state; struct wined3d_state *update_state; struct wined3d_stateblock *recording; @@ -1923,11 +1932,11 @@ struct wined3d_device UINT xScreenSpace; UINT yScreenSpace; UINT cursorWidth, cursorHeight; - GLuint cursorTexture; + struct wined3d_texture *cursor_texture; HCURSOR hardwareCursor; - /* The Wine logo surface */ - struct wined3d_surface *logo_surface; + /* The Wine logo texture */ + struct wined3d_texture *logo_texture; /* Textures for when no other textures are mapped */ UINT dummy_texture_2d[MAX_COMBINED_SAMPLERS]; @@ -1935,14 +1944,8 @@ struct wined3d_device UINT dummy_texture_3d[MAX_COMBINED_SAMPLERS]; UINT dummy_texture_cube[MAX_COMBINED_SAMPLERS]; - /* With register combiners we can skip junk texture stages */ - DWORD texUnitMap[MAX_COMBINED_SAMPLERS]; - DWORD rev_tex_unit_map[MAX_COMBINED_SAMPLERS]; - - /* Stream source management */ - struct wined3d_stream_info stream_info; - struct wined3d_event_query *buffer_queries[MAX_ATTRIBS]; - unsigned int num_buffer_queries; + /* Command stream */ + struct wined3d_cs *cs; /* Context management */ struct wined3d_context **contexts; @@ -1957,15 +1960,12 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN; -void device_preload_textures(const struct wined3d_device *device) DECLSPEC_HIDDEN; LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode, UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN; void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context, struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; -void device_update_stream_info(struct wined3d_device *device, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -void device_update_tex_unit_map(struct wined3d_device *device) DECLSPEC_HIDDEN; void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) @@ -1975,9 +1975,9 @@ static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD sta return context->isStateDirty[idx] & (1 << shift); } -static inline void invalidate_active_texture(const struct wined3d_device *device, struct wined3d_context *context) +static inline void context_invalidate_active_texture(struct wined3d_context *context) { - DWORD sampler = device->rev_tex_unit_map[context->active_texture]; + DWORD sampler = context->rev_tex_unit_map[context->active_texture]; if (sampler != WINED3D_UNMAPPED_STAGE) context_invalidate_state(context, STATE_SAMPLER(sampler)); } @@ -1990,9 +1990,6 @@ struct wined3d_resource_ops void (*resource_unload)(struct wined3d_resource *resource); }; -void *wined3d_resource_allocate_sysmem(SIZE_T size) DECLSPEC_HIDDEN; -void wined3d_resource_free_sysmem(void *mem) DECLSPEC_HIDDEN; - struct wined3d_resource { LONG ref; @@ -2011,7 +2008,6 @@ struct wined3d_resource UINT depth; UINT size; DWORD priority; - BYTE *allocatedMemory; /* Pointer to the real data location */ void *heap_memory; struct list privateData; struct list resource_list_entry; @@ -2031,9 +2027,12 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN; DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN; void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; +GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; /* Tests show that the start address of resources is 32 byte aligned */ #define RESOURCE_ALIGNMENT 16 @@ -2054,33 +2053,26 @@ enum wined3d_texture_state MAX_WINETEXTURESTATES = 11, }; -enum WINED3DSRGB -{ - SRGB_ANY = 0, /* Uses the cached value(e.g. external calls) */ - SRGB_RGB = 1, /* Loads the rgb texture */ - SRGB_SRGB = 2, /* Loads the srgb texture */ -}; - struct gl_texture { DWORD states[MAX_WINETEXTURESTATES]; - BOOL dirty; GLuint name; }; struct wined3d_texture_ops { - HRESULT (*texture_bind)(struct wined3d_texture *texture, + void (*texture_sub_resource_load)(struct wined3d_resource *sub_resource, struct wined3d_context *context, BOOL srgb); - void (*texture_preload)(struct wined3d_texture *texture, enum WINED3DSRGB srgb); void (*texture_sub_resource_add_dirty_region)(struct wined3d_resource *sub_resource, const struct wined3d_box *dirty_region); void (*texture_sub_resource_cleanup)(struct wined3d_resource *sub_resource); }; -#define WINED3D_TEXTURE_COND_NP2 0x1 -#define WINED3D_TEXTURE_POW2_MAT_IDENT 0x2 -#define WINED3D_TEXTURE_IS_SRGB 0x4 +#define WINED3D_TEXTURE_COND_NP2 0x00000001 +#define WINED3D_TEXTURE_POW2_MAT_IDENT 0x00000002 +#define WINED3D_TEXTURE_IS_SRGB 0x00000004 +#define WINED3D_TEXTURE_RGB_VALID 0x00000008 +#define WINED3D_TEXTURE_SRGB_VALID 0x00000010 struct wined3d_texture { @@ -2098,6 +2090,13 @@ struct wined3d_texture const struct min_lookup *min_mip_lookup; const GLenum *mag_lookup; GLenum target; + + /* Color keys for DDraw */ + struct wined3d_color_key dst_blt_color_key; + struct wined3d_color_key src_blt_color_key; + struct wined3d_color_key dst_overlay_color_key; + struct wined3d_color_key src_overlay_color_key; + DWORD color_key_flags; }; static inline struct wined3d_texture *wined3d_texture_from_resource(struct wined3d_resource *resource) @@ -2106,27 +2105,37 @@ static inline struct wined3d_texture *wined3d_texture_from_resource(struct wined } static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_texture *texture, - const struct wined3d_gl_info *gl_info, BOOL srgb) + BOOL srgb) { - return srgb && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE] - ? &texture->texture_srgb : &texture->texture_rgb; + return srgb ? &texture->texture_srgb : &texture->texture_rgb; } void wined3d_texture_apply_state_changes(struct wined3d_texture *texture, const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1], const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -void wined3d_texture_set_dirty(struct wined3d_texture *texture, BOOL dirty) DECLSPEC_HIDDEN; +void wined3d_texture_bind(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; +void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; +void wined3d_texture_load(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; +void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN; -#define WINED3D_VFLAG_LOCKED 0x00000001 -#define WINED3D_VFLAG_ALLOCATED 0x00000002 -#define WINED3D_VFLAG_SRGB_ALLOCATED 0x00000004 -#define WINED3D_VFLAG_PBO 0x00000008 +#define WINED3D_VFLAG_ALLOCATED 0x00000001 +#define WINED3D_VFLAG_SRGB_ALLOCATED 0x00000002 +#define WINED3D_VFLAG_PBO 0x00000004 +#define WINED3D_VFLAG_CLIENT_STORAGE 0x00000008 #define WINED3D_LOCATION_DISCARDED 0x00000001 #define WINED3D_LOCATION_SYSMEM 0x00000002 -#define WINED3D_LOCATION_BUFFER 0x00000004 -#define WINED3D_LOCATION_TEXTURE_RGB 0x00000008 -#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000010 +#define WINED3D_LOCATION_USER_MEMORY 0x00000004 +#define WINED3D_LOCATION_DIB 0x00000008 +#define WINED3D_LOCATION_BUFFER 0x00000010 +#define WINED3D_LOCATION_TEXTURE_RGB 0x00000020 +#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000040 +#define WINED3D_LOCATION_DRAWABLE 0x00000080 +#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000100 +#define WINED3D_LOCATION_RB_RESOLVED 0x00000200 const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN; @@ -2146,7 +2155,10 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc return CONTAINING_RECORD(resource, struct wined3d_volume, resource); } -void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) DECLSPEC_HIDDEN; +HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, + unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; +void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, + BOOL srgb_mode) DECLSPEC_HIDDEN; void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container) DECLSPEC_HIDDEN; void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, @@ -2182,7 +2194,6 @@ struct wined3d_surface_ops { HRESULT (*surface_private_setup)(struct wined3d_surface *surface); void (*surface_realize_palette)(struct wined3d_surface *surface); - void (*surface_map)(struct wined3d_surface *surface, const RECT *rect, DWORD flags); void (*surface_unmap)(struct wined3d_surface *surface); }; @@ -2193,7 +2204,9 @@ struct wined3d_surface struct wined3d_texture *container; struct wined3d_swapchain *swapchain; struct wined3d_palette *palette; /* D3D7 style palette handling */ - DWORD draw_binding; + DWORD draw_binding, map_binding; + void *user_memory; + DWORD locations; DWORD flags; @@ -2208,27 +2221,16 @@ struct wined3d_surface GLuint pbo; GLuint rb_multisample; GLuint rb_resolved; - GLuint texture_name; - GLuint texture_name_srgb; GLint texture_level; GLenum texture_target; RECT lockedRect; - RECT dirtyRect; int lockCount; -#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy */ /* For GetDC */ struct wined3d_surface_dib dib; HDC hDC; - /* Color keys for DDraw */ - struct wined3d_color_key dst_blt_color_key; - struct wined3d_color_key src_blt_color_key; - struct wined3d_color_key dst_overlay_color_key; - struct wined3d_color_key src_overlay_color_key; - DWORD CKeyFlags; - struct wined3d_color_key gl_color_key; struct list renderbuffers; @@ -2252,22 +2254,21 @@ static inline GLuint surface_get_texture_name(const struct wined3d_surface *surf const struct wined3d_gl_info *gl_info, BOOL srgb) { return srgb && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE] - ? surface->texture_name_srgb : surface->texture_name; + ? surface->container->texture_srgb.name : surface->container->texture_rgb.name; } -void surface_add_dirty_rect(struct wined3d_surface *surface, const struct wined3d_box *dirty_rect) DECLSPEC_HIDDEN; +void surface_set_dirty(struct wined3d_surface *surface) DECLSPEC_HIDDEN; HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void surface_internal_preload(struct wined3d_surface *surface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN; +void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; BOOL surface_is_offscreen(const struct wined3d_surface *surface) DECLSPEC_HIDDEN; -HRESULT surface_load(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN; +void surface_load(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN; void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN; -HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, const RECT *rect) DECLSPEC_HIDDEN; +HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; -void surface_modify_location(struct wined3d_surface *surface, DWORD location, BOOL persistent) DECLSPEC_HIDDEN; void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample) DECLSPEC_HIDDEN; void surface_prepare_texture(struct wined3d_surface *surface, @@ -2276,12 +2277,15 @@ void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_surface *rt) DECLSPEC_HIDDEN; void surface_set_container(struct wined3d_surface *surface, struct wined3d_texture *container) DECLSPEC_HIDDEN; void surface_set_swapchain(struct wined3d_surface *surface, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void surface_set_texture_name(struct wined3d_surface *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN; void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) DECLSPEC_HIDDEN; void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; void surface_update_draw_binding(struct wined3d_surface *surface) DECLSPEC_HIDDEN; HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN; +void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; +HRESULT CDECL wined3d_surface_create(struct wined3d_texture *container, + const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface) DECLSPEC_HIDDEN; +void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN; void get_drawable_size_swapchain(const struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; void get_drawable_size_backbuffer(const struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; @@ -2296,49 +2300,26 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D #define SFLAG_DISCARD 0x00000002 /* ??? */ #define SFLAG_NONPOW2 0x00000004 /* Surface sizes are not a power of 2 */ #define SFLAG_NORMCOORD 0x00000008 /* Set if GL texture coordinates are normalized (non-texture rectangle). */ -#define SFLAG_LOCKABLE 0x00000010 /* Surface can be locked. */ -#define SFLAG_DYNLOCK 0x00000020 /* Surface is often locked by the application. */ -#define SFLAG_PIN_SYSMEM 0x00000040 /* Keep the surface in sysmem, at the same address. */ -#define SFLAG_DCINUSE 0x00000080 /* Set between GetDC and ReleaseDC calls. */ -#define SFLAG_LOST 0x00000100 /* Surface lost flag for ddraw. */ -#define SFLAG_GLCKEY 0x00000200 /* The GL texture was created with a color key. */ -#define SFLAG_CLIENT 0x00000400 /* GL_APPLE_client_storage is used with this surface. */ -#define SFLAG_INOVERLAYDRAW 0x00000800 /* Overlay drawing is in progress. Recursion prevention. */ -#define SFLAG_DIBSECTION 0x00001000 /* Has a DIB section attached for GetDC. */ -#define SFLAG_USERPTR 0x00002000 /* The application allocated the memory for this surface. */ -#define SFLAG_ALLOCATED 0x00004000 /* A GL texture is allocated for this surface. */ -#define SFLAG_SRGBALLOCATED 0x00008000 /* A sRGB GL texture is allocated for this surface. */ -#define SFLAG_PBO 0x00010000 /* The surface has a PBO. */ -#define SFLAG_INSYSMEM 0x00020000 /* The system memory copy is current. */ -#define SFLAG_INTEXTURE 0x00040000 /* The GL texture is current. */ -#define SFLAG_INSRGBTEX 0x00080000 /* The GL sRGB texture is current. */ -#define SFLAG_INDRAWABLE 0x00100000 /* The GL drawable is current. */ -#define SFLAG_INRB_MULTISAMPLE 0x00200000 /* The multisample renderbuffer is current. */ -#define SFLAG_INRB_RESOLVED 0x00400000 /* The resolved renderbuffer is current. */ -#define SFLAG_DISCARDED 0x00800000 /* Surface was discarded, allocating new location is enough. */ +#define SFLAG_DYNLOCK 0x00000010 /* Surface is often locked by the application. */ +#define SFLAG_PIN_SYSMEM 0x00000020 /* Keep the surface in sysmem, at the same address. */ +#define SFLAG_DCINUSE 0x00000040 /* Set between GetDC and ReleaseDC calls. */ +#define SFLAG_LOST 0x00000080 /* Surface lost flag for ddraw. */ +#define SFLAG_GLCKEY 0x00000100 /* The GL texture was created with a color key. */ +#define SFLAG_CLIENT 0x00000200 /* GL_APPLE_client_storage is used with this surface. */ +#define SFLAG_DIBSECTION 0x00000400 /* Has a DIB section attached for GetDC. */ +#define SFLAG_ALLOCATED 0x00000800 /* A GL texture is allocated for this surface. */ +#define SFLAG_SRGBALLOCATED 0x00001000 /* A sRGB GL texture is allocated for this surface. */ /* In some conditions the surface memory must not be freed: * SFLAG_CONVERTED: Converting the data back would take too long - * SFLAG_DIBSECTION: The dib code manages the memory * SFLAG_DYNLOCK: Avoid freeing the data for performance - * SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL. * SFLAG_CLIENT: OpenGL uses our memory as backup */ #define SFLAG_DONOTFREE (SFLAG_CONVERTED | \ SFLAG_DYNLOCK | \ SFLAG_CLIENT | \ - SFLAG_DIBSECTION | \ - SFLAG_USERPTR | \ - SFLAG_PBO | \ SFLAG_PIN_SYSMEM) -#define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \ - SFLAG_INTEXTURE | \ - SFLAG_INSRGBTEX | \ - SFLAG_INDRAWABLE | \ - SFLAG_INRB_MULTISAMPLE | \ - SFLAG_INRB_RESOLVED) - enum wined3d_conversion_type { WINED3D_CT_NONE, @@ -2452,10 +2433,73 @@ struct wined3d_stateblock void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; -HRESULT state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN; -void state_init_default(struct wined3d_state *state, struct wined3d_device *device) DECLSPEC_HIDDEN; +HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, + const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, + DWORD flags) DECLSPEC_HIDDEN; void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; +struct wined3d_cs_ops +{ + void *(*require_space)(struct wined3d_cs *cs, size_t size); + void (*submit)(struct wined3d_cs *cs); +}; + +struct wined3d_cs +{ + const struct wined3d_cs_ops *ops; + struct wined3d_device *device; + struct wined3d_fb_state fb; + struct wined3d_state state; + + size_t data_size; + void *data; +}; + +struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; +void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; + +void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, + DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; +void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, + UINT start_instance, UINT instance_count, BOOL indexed) 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, + const RGNDATA *dirty_region, DWORD flags) DECLSPEC_HIDDEN; +void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) 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_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, + UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_depth_stencil(struct wined3d_cs *cs, struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, + enum wined3d_format_id format_id) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, + enum wined3d_render_state state, DWORD value) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_render_target(struct wined3d_cs *cs, UINT render_target_idx, + struct wined3d_surface *render_target) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type, + UINT sampler_idx, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, + enum wined3d_sampler_state state, DWORD value) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, + struct wined3d_shader *shader) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, + struct wined3d_buffer *buffer, UINT offset) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, + struct wined3d_buffer *buffer, UINT offset, UINT stride) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, + UINT frequency, UINT flags) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, + enum wined3d_texture_stage_state state, DWORD value) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state, + const struct wined3d_matrix *matrix) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, + struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; + /* Direct3D terminology with little modifications. We do not have an issued state * because only the driver knows about it, but we have a created state because d3d * allows GetData on a created issue, but opengl doesn't @@ -2507,8 +2551,8 @@ struct wined3d_buffer GLuint buffer_object; GLenum buffer_object_usage; GLenum buffer_type_hint; - UINT buffer_object_size; DWORD flags; + void *map_ptr; struct wined3d_map_range *maps; ULONG maps_size, modified_areas; @@ -2527,9 +2571,11 @@ static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resourc return CONTAINING_RECORD(resource, struct wined3d_buffer, resource); } -void buffer_get_memory(struct wined3d_buffer *buffer, const struct wined3d_gl_info *gl_info, +void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo_address *data) DECLSPEC_HIDDEN; -BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; +BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; +void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct wined3d_state *state) DECLSPEC_HIDDEN; struct wined3d_rendertarget_view { @@ -2573,6 +2619,11 @@ struct wined3d_swapchain HWND backup_wnd; }; +static inline BOOL swapchain_is_p8(const struct wined3d_swapchain *swapchain) +{ + return swapchain->desc.backbuffer_format == WINED3DFMT_P8_UINT; +} + void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) DECLSPEC_HIDDEN; struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; @@ -2605,7 +2656,6 @@ const char *debug_fbostatus(GLenum status) DECLSPEC_HIDDEN; const char *debug_glerror(GLenum error) DECLSPEC_HIDDEN; const char *debug_d3dtop(enum wined3d_texture_op d3dtop) DECLSPEC_HIDDEN; void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN; -const char *debug_surflocation(DWORD flag) DECLSPEC_HIDDEN; BOOL is_invalid_op(const struct wined3d_state *state, int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3) DECLSPEC_HIDDEN; @@ -2683,6 +2733,8 @@ void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *s UINT wined3d_log2i(UINT32 x) DECLSPEC_HIDDEN; unsigned int count_bits(unsigned int mask) DECLSPEC_HIDDEN; +void wined3d_release_dc(HWND window, HDC dc) DECLSPEC_HIDDEN; + struct wined3d_shader_lconst { struct list entry; @@ -2778,11 +2830,12 @@ struct wined3d_shader }; void pixelshader_update_samplers(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN; -void find_ps_compile_args(const struct wined3d_state *state, - const struct wined3d_shader *shader, struct ps_compile_args *args) DECLSPEC_HIDDEN; +void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, + BOOL position_transformed, struct ps_compile_args *args, + const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -void find_vs_compile_args(const struct wined3d_state *state, - const struct wined3d_shader *shader, struct vs_compile_args *args) DECLSPEC_HIDDEN; +void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, + WORD swizzle_map, struct vs_compile_args *args) DECLSPEC_HIDDEN; void shader_buffer_clear(struct wined3d_shader_buffer *buffer) DECLSPEC_HIDDEN; BOOL shader_buffer_init(struct wined3d_shader_buffer *buffer) DECLSPEC_HIDDEN; @@ -2885,15 +2938,12 @@ struct ps_np2fixup_info { struct wined3d_palette { LONG ref; - void *parent; struct wined3d_device *device; HPALETTE hpal; WORD palVersion; /*| */ WORD palNumEntries; /*| LOGPALETTE */ PALETTEENTRY palents[256]; /*| */ - /* This is to store the palette in 'screen format' */ - int screen_palents[256]; DWORD flags; }; @@ -2924,6 +2974,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN #define WINED3DFMT_FLAG_BLOCKS 0x00020000 #define WINED3DFMT_FLAG_HEIGHT_SCALE 0x00040000 #define WINED3DFMT_FLAG_TEXTURE 0x00080000 +#define WINED3DFMT_FLAG_BLOCKS_NO_VERIFY 0x00100000 struct wined3d_rational { @@ -2967,7 +3018,8 @@ struct wined3d_format unsigned int flags; struct wined3d_rational height_scale; struct color_fixup_desc color_fixup; - void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height); + void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth); }; const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info, @@ -2979,16 +3031,14 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, static inline BOOL use_vs(const struct wined3d_state *state) { - /* Check stateblock->vertexDecl to allow this to be used from - * IWineD3DDeviceImpl_FindTexUnitMap(). This is safe because - * stateblock->vertexShader implies a vertex declaration instead of ddraw - * style strided data. */ - return state->vertex_shader && !state->vertex_declaration->position_transformed; + /* Check state->vertex_declaration to allow this to be used before the + * stream info is validated, for example in device_update_tex_unit_map(). */ + return state->shader[WINED3D_SHADER_TYPE_VERTEX] && !state->vertex_declaration->position_transformed; } static inline BOOL use_ps(const struct wined3d_state *state) { - return !!state->pixel_shader; + return !!state->shader[WINED3D_SHADER_TYPE_PIXEL]; } static inline void context_apply_state(struct wined3d_context *context, @@ -3004,4 +3054,4 @@ static inline void context_apply_state(struct wined3d_context *context, #define MAKEDWORD_VERSION(maj, min) (((maj & 0xffff) << 16) | (min & 0xffff)) -#endif /* __WINE_WINED3D_PRIVATE_H */ +#endif diff --git a/reactos/include/psdk/d3d9.h b/reactos/include/psdk/d3d9.h index 8758e282b00..c538cd7ea42 100644 --- a/reactos/include/psdk/d3d9.h +++ b/reactos/include/psdk/d3d9.h @@ -132,6 +132,9 @@ typedef struct IDirect3DVolume9 *LPDIRECT3DVOLUME9, *PDIRECT3DVOLUME9; DEFINE_GUID(IID_IDirect3DSwapChain9, 0x794950f2, 0xadfc, 0x458a, 0x90, 0x5e, 0x10, 0xa1, 0xb, 0xb, 0x50, 0x3b); typedef struct IDirect3DSwapChain9 *LPDIRECT3DSWAPCHAIN9, *PDIRECT3DSWAPCHAIN9; +DEFINE_GUID(IID_IDirect3DSwapChain9Ex, 0x91886caf, 0x1c3d, 0x4d2e, 0xa0, 0xab, 0x3e, 0x4c, 0x7d, 0x8d, 0x33, 0x3); +typedef struct IDirect3DSwapChain9Ex *LPDIRECT3DSWAPCHAIN9EX, *PDIRECT3DSWAPCHAIN9EX; + DEFINE_GUID(IID_IDirect3DSurface9, 0xcfbaf3a, 0x9ff6, 0x429a, 0x99, 0xb3, 0xa2, 0x79, 0x6a, 0xf8, 0xb8, 0x9b); typedef struct IDirect3DSurface9 *LPDIRECT3DSURFACE9, *PDIRECT3DSURFACE9; @@ -423,6 +426,68 @@ DECLARE_INTERFACE_(IDirect3DSwapChain9,IUnknown) #define IDirect3DSwapChain9_GetPresentParameters(p,a) (p)->GetPresentParameters(a) #endif +/***************************************************************************** + * IDirect3DSwapChain9Ex interface + */ +#define INTERFACE IDirect3DSwapChain9Ex +DECLARE_INTERFACE_(IDirect3DSwapChain9Ex,IDirect3DSwapChain9) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IDirect3DSwapChain9 methods ***/ + STDMETHOD(Present)(THIS_ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, + const RGNDATA *dirty_region, DWORD flags) PURE; + STDMETHOD(GetFrontBufferData)(THIS_ struct IDirect3DSurface9 *pDestSurface) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, struct IDirect3DSurface9 **ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS *pRasterStatus) PURE; + STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE *pMode) PURE; + STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9 **ppDevice) PURE; + STDMETHOD(GetPresentParameters)(THIS_ D3DPRESENT_PARAMETERS *pPresentationParameters) PURE; + /*** IDirect3DSwapChain9Ex methods ***/ + STDMETHOD(GetLastPresentCount)(THIS_ UINT *pLastPresentCount) PURE; + STDMETHOD(GetPresentStats)(THIS_ D3DPRESENTSTATS *pPresentationStatistics) PURE; + STDMETHOD(GetDisplayModeEx)(THIS_ D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) +/*** IUnknown methods ***/ +#define IDirect3DSwapChain9Ex_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSwapChain9Ex_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSwapChain9Ex_Release(p) (p)->lpVtbl->Release(p) +/*** IDirect3DSwapChain9 methods ***/ +#define IDirect3DSwapChain9Ex_Present(p,a,b,c,d,e) (p)->lpVtbl->Present(p,a,b,c,d,e) +#define IDirect3DSwapChain9Ex_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a) +#define IDirect3DSwapChain9EX_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#define IDirect3DSwapChain9EX_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a) +#define IDirect3DSwapChain9Ex_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a) +#define IDirect3DSwapChain9Ex_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DSwapChain9Ex_GetPresentParameters(p,a) (p)->lpVtbl->GetPresentParameters(p,a) +/*** IDirect3DSwapChain9Ex methods ***/ +#define IDirect3DSwapChain9Ex_GetLastPresentCount(p,a) (p)->lpVtbl->GetLastPresentCount(p,a) +#define IDirect3DSwapChain9Ex_GetPresentStats(p,a) (p)->lpVtbl->GetPresentStats(p,a) +#define IDirect3DSwapChain9Ex_GetDisplayModeEx(p,a,b) (p)->lpVtbl->GetDisplayModeEx(p,a,b) +#else +/*** IUnknown methods ***/ +#define IDirect3DSwapChain9Ex_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSwapChain9Ex_AddRef(p) (p)->AddRef() +#define IDirect3DSwapChain9Ex_Release(p) (p)->Release() +/*** IDirect3DSwapChain9 methods ***/ +#define IDirect3DSwapChain9Ex_Present(p,a,b,c,d,e) (p)->Present(a,b,c,d,e) +#define IDirect3DSwapChain9Ex_GetFrontBufferData(p,a) (p)->GetFrontBufferData(a) +#define IDirect3DSwapChain9Ex_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#define IDirect3DSwapChain9Ex_GetRasterStatus(p,a) (p)->GetRasterStatus(a) +#define IDirect3DSwapChain9Ex_GetDisplayMode(p,a) (p)->GetDisplayMode(a) +#define IDirect3DSwapChain9Ex_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DSwapChain9Ex_GetPresentParameters(p,a) (p)->GetPresentParameters(a) +/*** IDirect3DSwapChain9Ex methods ***/ +#define IDirect3DSwapChain9Ex_GetLastPresentCount(p,a) (p)->GetLastPresentCount(a) +#define IDirect3DSwapChain9Ex_GetPresentStats(p,a) (p)->GetPresentStats(a) +#define IDirect3DSwapChain9Ex_GetDisplayModeEx(p,a,b) (p)->GetDisplayModeEx(a,b) +#endif + /***************************************************************************** * IDirect3DResource9 interface */ diff --git a/reactos/include/psdk/d3d9types.h b/reactos/include/psdk/d3d9types.h index 9c7c57cc170..26b259a93bf 100644 --- a/reactos/include/psdk/d3d9types.h +++ b/reactos/include/psdk/d3d9types.h @@ -1587,6 +1587,16 @@ typedef enum _D3DCOMPOSERECTSOP{ D3DCOMPOSERECTS_NEG, D3DCOMPOSERECTS_FORCE_DWORD = 0x7fffffff } D3DCOMPOSERECTSOP; + +typedef struct _D3DPRESENTSTATS +{ + UINT PresentCount; + UINT PresentRefreshCount; + UINT SyncRefreshCount; + LARGE_INTEGER SyncQPCTime; + LARGE_INTEGER SyncGPUTime; +} D3DPRESENTSTATS; + #endif /* D3D_DISABLE_9EX */ typedef enum _D3DSHADER_COMPARISON diff --git a/reactos/include/reactos/wine/wgl.h b/reactos/include/reactos/wine/wgl.h index d3cfc7e2428..f11f19ccfc3 100644 --- a/reactos/include/reactos/wine/wgl.h +++ b/reactos/include/reactos/wine/wgl.h @@ -1,4 +1,4 @@ -/* Automatically generated from http://www.opengl.org/registry/api files; DO NOT EDIT! */ +/* Automatically generated from http://www.opengl.org/registry files; DO NOT EDIT! */ #ifndef __WINE_WGL_H #define __WINE_WGL_H @@ -14,13 +14,16 @@ typedef char GLchar; typedef char GLcharARB; typedef double GLclampd; typedef float GLclampf; +typedef int GLclampx; typedef double GLdouble; typedef unsigned int GLenum; +typedef int GLfixed; typedef float GLfloat; typedef unsigned short GLhalfNV; typedef unsigned int GLhandleARB; typedef int GLint; typedef INT64 GLint64; +typedef INT64 GLint64EXT; typedef INT_PTR GLintptr; typedef INT_PTR GLintptrARB; typedef short GLshort; @@ -32,6 +35,7 @@ typedef struct __GLsync * GLsync; typedef unsigned char GLubyte; typedef unsigned int GLuint; typedef UINT64 GLuint64; +typedef UINT64 GLuint64EXT; typedef unsigned short GLushort; typedef INT_PTR GLvdpauSurfaceNV; typedef void GLvoid; @@ -119,16 +123,19 @@ typedef void GLvoid; #define GL_ALL_COMPLETED_NV 0x84F2 #define GL_ALL_SHADER_BITS 0xFFFFFFFF #define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_ALL_STATIC_DATA_IBM 103060 #define GL_ALPHA 0x1906 #define GL_ALPHA12 0x803D #define GL_ALPHA12_EXT 0x803D #define GL_ALPHA16 0x803E #define GL_ALPHA16F_ARB 0x881C +#define GL_ALPHA16F_EXT 0x881C #define GL_ALPHA16I_EXT 0x8D8A #define GL_ALPHA16UI_EXT 0x8D78 #define GL_ALPHA16_EXT 0x803E #define GL_ALPHA16_SNORM 0x9018 #define GL_ALPHA32F_ARB 0x8816 +#define GL_ALPHA32F_EXT 0x8816 #define GL_ALPHA32I_EXT 0x8D84 #define GL_ALPHA32UI_EXT 0x8D72 #define GL_ALPHA4 0x803B @@ -137,6 +144,7 @@ typedef void GLvoid; #define GL_ALPHA8I_EXT 0x8D90 #define GL_ALPHA8UI_EXT 0x8D7E #define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA8_OES 0x803C #define GL_ALPHA8_SNORM 0x9014 #define GL_ALPHA_BIAS 0x0D1D #define GL_ALPHA_BITS 0x0D55 @@ -233,7 +241,9 @@ typedef void GLvoid; #define GL_BEVEL_NV 0x90A6 #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 +#define GL_BGRA8_EXT 0x93A1 #define GL_BGRA_EXT 0x80E1 +#define GL_BGRA_IMG 0x80E1 #define GL_BGRA_INTEGER 0x8D9B #define GL_BGRA_INTEGER_EXT 0x8D9B #define GL_BGR_EXT 0x80E0 @@ -249,6 +259,7 @@ typedef void GLvoid; #define GL_BITMAP 0x1A00 #define GL_BITMAP_TOKEN 0x0704 #define GL_BLEND 0x0BE2 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 #define GL_BLEND_COLOR 0x8005 #define GL_BLEND_COLOR_EXT 0x8005 #define GL_BLEND_DST 0x0BE0 @@ -267,6 +278,8 @@ typedef void GLvoid; #define GL_BLEND_EQUATION_RGB 0x8009 #define GL_BLEND_EQUATION_RGB_EXT 0x8009 #define GL_BLEND_EQUATION_RGB_OES 0x8009 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 #define GL_BLEND_SRC 0x0BE1 #define GL_BLEND_SRC_ALPHA 0x80CB #define GL_BLEND_SRC_ALPHA_EXT 0x80CB @@ -283,6 +296,7 @@ typedef void GLvoid; #define GL_BLUE_INTEGER_EXT 0x8D96 #define GL_BLUE_MAX_CLAMP_INGR 0x8566 #define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_BLUE_NV 0x1905 #define GL_BLUE_SCALE 0x0D1A #define GL_BOLD_BIT_NV 0x01 #define GL_BOOL 0x8B56 @@ -295,6 +309,7 @@ typedef void GLvoid; #define GL_BOOL_VEC4_ARB 0x8B59 #define GL_BOUNDING_BOX_NV 0x908D #define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_BROWSER_DEFAULT_WEBGL 0x9244 #define GL_BUFFER 0x82E0 #define GL_BUFFER_ACCESS 0x88BB #define GL_BUFFER_ACCESS_ARB 0x88BB @@ -304,6 +319,8 @@ typedef void GLvoid; #define GL_BUFFER_DATA_SIZE 0x9303 #define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 #define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_KHR 0x82E0 #define GL_BUFFER_MAPPED 0x88BC #define GL_BUFFER_MAPPED_ARB 0x88BC #define GL_BUFFER_MAPPED_OES 0x88BC @@ -317,6 +334,7 @@ typedef void GLvoid; #define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_STORAGE_FLAGS 0x8220 #define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 #define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 #define GL_BUFFER_USAGE 0x8765 @@ -346,6 +364,7 @@ typedef void GLvoid; #define GL_CLAMP_READ_COLOR_ARB 0x891C #define GL_CLAMP_TO_BORDER 0x812D #define GL_CLAMP_TO_BORDER_ARB 0x812D +#define GL_CLAMP_TO_BORDER_NV 0x812D #define GL_CLAMP_TO_BORDER_SGIS 0x812D #define GL_CLAMP_TO_EDGE 0x812F #define GL_CLAMP_TO_EDGE_SGIS 0x812F @@ -353,11 +372,14 @@ typedef void GLvoid; #define GL_CLAMP_VERTEX_COLOR_ARB 0x891A #define GL_CLEAR 0x1500 #define GL_CLEAR_BUFFER 0x82B4 +#define GL_CLEAR_TEXTURE 0x9365 #define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 #define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF #define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 #define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_STORAGE_BIT 0x0200 #define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 #define GL_CLIP_DISTANCE0 0x3000 #define GL_CLIP_DISTANCE1 0x3001 @@ -371,11 +393,17 @@ typedef void GLvoid; #define GL_CLIP_FAR_HINT_PGI 0x1A221 #define GL_CLIP_NEAR_HINT_PGI 0x1A220 #define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE0_IMG 0x3000 #define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE1_IMG 0x3001 #define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE2_IMG 0x3002 #define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE3_IMG 0x3003 #define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE4_IMG 0x3004 #define GL_CLIP_PLANE5 0x3005 +#define GL_CLIP_PLANE5_IMG 0x3005 #define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 #define GL_CLOSE_PATH_NV 0x00 #define GL_CMYKA_EXT 0x800D @@ -386,6 +414,8 @@ typedef void GLvoid; #define GL_COLOR 0x1800 #define GL_COLOR3_BIT_PGI 0x00010000 #define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 #define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 #define GL_COLOR_ARRAY 0x8076 #define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 @@ -456,6 +486,14 @@ typedef void GLvoid; #define GL_COLOR_ATTACHMENT9_NV 0x8CE9 #define GL_COLOR_ATTACHMENT_EXT 0x90F0 #define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 #define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 #define GL_COLOR_CLEAR_VALUE 0x0C22 #define GL_COLOR_COMPONENTS 0x8283 @@ -558,22 +596,43 @@ typedef void GLvoid; #define GL_COMPRESSED_LUMINANCE_ARB 0x84EA #define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 #define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_R11_EAC_OES 0x9270 #define GL_COMPRESSED_RED 0x8225 #define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD #define GL_COMPRESSED_RED_RGTC1 0x8DBB #define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB #define GL_COMPRESSED_RG 0x8226 #define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_RG11_EAC_OES 0x9272 #define GL_COMPRESSED_RGB 0x84ED #define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_ETC2_OES 0x9274 #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9276 #define GL_COMPRESSED_RGBA 0x84EE #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_RGBA8_ETC2_EAC_OES 0x9278 #define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 #define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C #define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 #define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 @@ -590,38 +649,68 @@ typedef void GLvoid; #define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 #define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 #define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_SIGNED_R11_EAC_OES 0x9271 #define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC #define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_SIGNED_RG11_EAC_OES 0x9273 #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE #define GL_COMPRESSED_SLUMINANCE 0x8C4A #define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A #define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 #define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_OES 0x9279 #define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_SRGB8_ETC2_OES 0x9275 #define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9277 #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F #define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 +#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -#define GL_COMPUTE_LOCAL_WORK_SIZE 0x8267 +#define GL_COMPUTE_PROGRAM_NV 0x90FB +#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC #define GL_COMPUTE_SHADER 0x91B9 #define GL_COMPUTE_SHADER_BIT 0x00000020 #define GL_COMPUTE_SUBROUTINE 0x92ED #define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 #define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 #define GL_COMP_BIT_ATI 0x00000002 #define GL_CONDITION_SATISFIED 0x911C #define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_CONJOINT_NV 0x9284 #define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD #define GL_CONSTANT 0x8576 #define GL_CONSTANT_ALPHA 0x8003 @@ -640,10 +729,14 @@ typedef void GLvoid; #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 #define GL_CONTEXT_FLAGS 0x821E #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 #define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_CONTEXT_LOST_WEBGL 0x9242 #define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 #define GL_CONTINUOUS_AMD 0x9007 +#define GL_CONTRAST_NV 0x92A1 #define GL_CONVEX_HULL_NV 0x908B #define GL_CONVOLUTION_1D 0x8010 #define GL_CONVOLUTION_1D_EXT 0x8010 @@ -699,11 +792,16 @@ typedef void GLvoid; #define GL_COORD_REPLACE 0x8862 #define GL_COORD_REPLACE_ARB 0x8862 #define GL_COORD_REPLACE_NV 0x8862 +#define GL_COORD_REPLACE_OES 0x8862 #define GL_COPY 0x1503 #define GL_COPY_INVERTED 0x150C #define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_COPY_READ_BUFFER 0x8F36 #define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_READ_BUFFER_NV 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 #define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_COPY_WRITE_BUFFER_NV 0x8F37 #define GL_COUNTER_RANGE_AMD 0x8BC1 #define GL_COUNTER_TYPE_AMD 0x8BC0 #define GL_COUNT_DOWN_NV 0x9089 @@ -716,7 +814,7 @@ typedef void GLvoid; #define GL_COVERAGE_COMPONENT4_NV 0x8ED1 #define GL_COVERAGE_COMPONENT_NV 0x8ED0 #define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 -#define GL_COVERAGE_SAMPLES_NV 0x80A9 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 #define GL_CPU_OPTIMIZED_QCOM 0x8FB1 #define GL_CUBIC_CURVE_TO_NV 0x0C #define GL_CUBIC_EXT 0x8334 @@ -769,12 +867,15 @@ typedef void GLvoid; #define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B #define GL_CURRENT_WEIGHT_ARB 0x86A8 #define GL_CW 0x0900 +#define GL_DARKEN_NV 0x9297 #define GL_DATA_BUFFER_AMD 0x9151 #define GL_DEBUG_ASSERT_MESA 0x875B #define GL_DEBUG_CALLBACK_FUNCTION 0x8244 #define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 #define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 #define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 #define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 #define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F #define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B @@ -784,53 +885,77 @@ typedef void GLvoid; #define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C #define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A #define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D #define GL_DEBUG_LOGGED_MESSAGES 0x9145 #define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 #define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 #define GL_DEBUG_OBJECT_MESA 0x8759 #define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 #define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 #define GL_DEBUG_PRINT_MESA 0x875A #define GL_DEBUG_SEVERITY_HIGH 0x9146 #define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 #define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 #define GL_DEBUG_SEVERITY_LOW 0x9148 #define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 #define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 #define GL_DEBUG_SEVERITY_MEDIUM 0x9147 #define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 #define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 #define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B #define GL_DEBUG_SOURCE_API 0x8246 #define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 #define GL_DEBUG_SOURCE_APPLICATION 0x824A #define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A #define GL_DEBUG_SOURCE_OTHER 0x824B #define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B #define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 #define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 #define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 #define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 #define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 #define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D #define GL_DEBUG_TYPE_ERROR 0x824C #define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C #define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 #define GL_DEBUG_TYPE_OTHER 0x8251 #define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 #define GL_DEBUG_TYPE_PERFORMANCE 0x8250 #define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 #define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A #define GL_DEBUG_TYPE_PORTABILITY 0x824F #define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F #define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E #define GL_DECAL 0x2101 #define GL_DECODE_EXT 0x8A49 #define GL_DECR 0x1E03 @@ -858,6 +983,14 @@ typedef void GLvoid; #define GL_DEPTH_BOUNDS_EXT 0x8891 #define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 #define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 #define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF #define GL_DEPTH_CLAMP 0x864F #define GL_DEPTH_CLAMP_FAR_AMD 0x901F @@ -907,10 +1040,12 @@ typedef void GLvoid; #define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C #define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A #define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DIFFERENCE_NV 0x929E #define GL_DIFFUSE 0x1201 #define GL_DISCARD_ATI 0x8763 #define GL_DISCARD_NV 0x8530 #define GL_DISCRETE_AMD 0x9006 +#define GL_DISJOINT_NV 0x9283 #define GL_DISPATCH_INDIRECT_BUFFER 0x90EE #define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF #define GL_DISPLAY_LIST 0x82E7 @@ -946,10 +1081,22 @@ typedef void GLvoid; #define GL_DOUBLE_EXT 0x140A #define GL_DOUBLE_MAT2 0x8F46 #define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x3_EXT 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT2x4_EXT 0x8F4A #define GL_DOUBLE_MAT3 0x8F47 #define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x2_EXT 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT3x4_EXT 0x8F4C #define GL_DOUBLE_MAT4 0x8F48 #define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x2_EXT 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_DOUBLE_MAT4x3_EXT 0x8F4E #define GL_DOUBLE_VEC2 0x8FFC #define GL_DOUBLE_VEC2_EXT 0x8FFC #define GL_DOUBLE_VEC3 0x8FFD @@ -960,73 +1107,94 @@ typedef void GLvoid; #define GL_DRAW_BUFFER0 0x8825 #define GL_DRAW_BUFFER0_ARB 0x8825 #define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER0_EXT 0x8825 #define GL_DRAW_BUFFER0_NV 0x8825 #define GL_DRAW_BUFFER1 0x8826 #define GL_DRAW_BUFFER10 0x882F #define GL_DRAW_BUFFER10_ARB 0x882F #define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER10_EXT 0x882F #define GL_DRAW_BUFFER10_NV 0x882F #define GL_DRAW_BUFFER11 0x8830 #define GL_DRAW_BUFFER11_ARB 0x8830 #define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER11_EXT 0x8830 #define GL_DRAW_BUFFER11_NV 0x8830 #define GL_DRAW_BUFFER12 0x8831 #define GL_DRAW_BUFFER12_ARB 0x8831 #define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER12_EXT 0x8831 #define GL_DRAW_BUFFER12_NV 0x8831 #define GL_DRAW_BUFFER13 0x8832 #define GL_DRAW_BUFFER13_ARB 0x8832 #define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER13_EXT 0x8832 #define GL_DRAW_BUFFER13_NV 0x8832 #define GL_DRAW_BUFFER14 0x8833 #define GL_DRAW_BUFFER14_ARB 0x8833 #define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER14_EXT 0x8833 #define GL_DRAW_BUFFER14_NV 0x8833 #define GL_DRAW_BUFFER15 0x8834 #define GL_DRAW_BUFFER15_ARB 0x8834 #define GL_DRAW_BUFFER15_ATI 0x8834 +#define GL_DRAW_BUFFER15_EXT 0x8834 #define GL_DRAW_BUFFER15_NV 0x8834 #define GL_DRAW_BUFFER1_ARB 0x8826 #define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER1_EXT 0x8826 #define GL_DRAW_BUFFER1_NV 0x8826 #define GL_DRAW_BUFFER2 0x8827 #define GL_DRAW_BUFFER2_ARB 0x8827 #define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER2_EXT 0x8827 #define GL_DRAW_BUFFER2_NV 0x8827 #define GL_DRAW_BUFFER3 0x8828 #define GL_DRAW_BUFFER3_ARB 0x8828 #define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER3_EXT 0x8828 #define GL_DRAW_BUFFER3_NV 0x8828 #define GL_DRAW_BUFFER4 0x8829 #define GL_DRAW_BUFFER4_ARB 0x8829 #define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER4_EXT 0x8829 #define GL_DRAW_BUFFER4_NV 0x8829 #define GL_DRAW_BUFFER5 0x882A #define GL_DRAW_BUFFER5_ARB 0x882A #define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER5_EXT 0x882A #define GL_DRAW_BUFFER5_NV 0x882A #define GL_DRAW_BUFFER6 0x882B #define GL_DRAW_BUFFER6_ARB 0x882B #define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER6_EXT 0x882B #define GL_DRAW_BUFFER6_NV 0x882B #define GL_DRAW_BUFFER7 0x882C #define GL_DRAW_BUFFER7_ARB 0x882C #define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER7_EXT 0x882C #define GL_DRAW_BUFFER7_NV 0x882C #define GL_DRAW_BUFFER8 0x882D #define GL_DRAW_BUFFER8_ARB 0x882D #define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER8_EXT 0x882D #define GL_DRAW_BUFFER8_NV 0x882D #define GL_DRAW_BUFFER9 0x882E #define GL_DRAW_BUFFER9_ARB 0x882E #define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER9_EXT 0x882E #define GL_DRAW_BUFFER9_NV 0x882E #define GL_DRAW_BUFFER_EXT 0x0C01 #define GL_DRAW_FRAMEBUFFER 0x8CA9 #define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 #define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 #define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 #define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 #define GL_DRAW_INDIRECT_BUFFER 0x8F3F #define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 @@ -1042,7 +1210,12 @@ typedef void GLvoid; #define GL_DSDT_MAG_VIB_NV 0x86F7 #define GL_DSDT_NV 0x86F5 #define GL_DST_ALPHA 0x0304 +#define GL_DST_ATOP_NV 0x928F #define GL_DST_COLOR 0x0306 +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 #define GL_DS_BIAS_NV 0x8716 #define GL_DS_SCALE_NV 0x8710 #define GL_DT_BIAS_NV 0x8717 @@ -1073,6 +1246,7 @@ typedef void GLvoid; #define GL_DYNAMIC_DRAW_ARB 0x88E8 #define GL_DYNAMIC_READ 0x88E9 #define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 #define GL_EDGEFLAG_BIT_PGI 0x00040000 #define GL_EDGE_FLAG 0x0B43 #define GL_EDGE_FLAG_ARRAY 0x8079 @@ -1112,26 +1286,11 @@ typedef void GLvoid; #define GL_EQUAL 0x0202 #define GL_EQUIV 0x1509 #define GL_ETC1_RGB8_OES 0x8D64 +#define GL_ETC1_SRGB8_NV 0x88EE #define GL_EVAL_2D_NV 0x86C0 #define GL_EVAL_BIT 0x00010000 #define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 #define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_EVAL_VERTEX_ATRRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATRRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATRRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATRRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATRRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATRRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATRRIB15_NV 0x86D5 -#define GL_EVAL_VERTEX_ATRRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATRRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATRRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATRRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATRRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATRRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATRRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATRRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATRRIB9_NV 0x86CF #define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 #define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 #define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 @@ -1148,6 +1307,7 @@ typedef void GLvoid; #define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD #define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE #define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EXCLUSION_NV 0x92A0 #define GL_EXP 0x0800 #define GL_EXP2 0x0801 #define GL_EXPAND_NEGATE_NV 0x8539 @@ -1201,10 +1361,22 @@ typedef void GLvoid; #define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D #define GL_FLOAT_MAT2 0x8B5A #define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x3_NV 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT2x4_NV 0x8B66 #define GL_FLOAT_MAT3 0x8B5B #define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x2_NV 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT3x4_NV 0x8B68 #define GL_FLOAT_MAT4 0x8B5C #define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x2_NV 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_FLOAT_MAT4x3_NV 0x8B6A #define GL_FLOAT_R16_NV 0x8884 #define GL_FLOAT_R32_NV 0x8885 #define GL_FLOAT_RG16_NV 0x8886 @@ -1255,32 +1427,28 @@ typedef void GLvoid; #define GL_FOG_DENSITY 0x0B62 #define GL_FOG_DISTANCE_MODE_NV 0x855A #define GL_FOG_END 0x0B64 -#define GL_FOG_FACTOR_TO_ALPHA_SGIX 0x836F #define GL_FOG_FUNC_POINTS_SGIS 0x812B #define GL_FOG_FUNC_SGIS 0x812A -#define GL_FOG_GEN_MODE_NV 0x855A #define GL_FOG_HINT 0x0C54 #define GL_FOG_INDEX 0x0B61 #define GL_FOG_MODE 0x0B65 #define GL_FOG_OFFSET_SGIX 0x8198 #define GL_FOG_OFFSET_VALUE_SGIX 0x8199 -#define GL_FOG_SCALE_SGIX 0x81FC -#define GL_FOG_SCALE_VALUE_SGIX 0x81FD #define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC #define GL_FOG_START 0x0B63 -#define GL_FONT_ASCENDER_NV 0x00200000 -#define GL_FONT_DESCENDER_NV 0x00400000 -#define GL_FONT_HAS_KERNING_NV 0x10000000 -#define GL_FONT_HEIGHT_NV 0x00800000 -#define GL_FONT_MAX_ADVANCE_HEIGHT_NV 0x02000000 -#define GL_FONT_MAX_ADVANCE_WIDTH_NV 0x01000000 -#define GL_FONT_UNDERLINE_POSITION_NV 0x04000000 -#define GL_FONT_UNDERLINE_THICKNESS_NV 0x08000000 -#define GL_FONT_UNITS_PER_EM_NV 0x00100000 -#define GL_FONT_X_MAX_BOUNDS_NV 0x00040000 -#define GL_FONT_X_MIN_BOUNDS_NV 0x00010000 -#define GL_FONT_Y_MAX_BOUNDS_NV 0x00080000 -#define GL_FONT_Y_MIN_BOUNDS_NV 0x00020000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 #define GL_FORCE_BLUE_TO_ONE_NV 0x8860 #define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 #define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 @@ -1338,6 +1506,7 @@ typedef void GLvoid; #define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 #define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 #define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 #define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 @@ -1384,6 +1553,7 @@ typedef void GLvoid; #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9 #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB @@ -1401,8 +1571,10 @@ typedef void GLvoid; #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES 0x8CDC @@ -1469,7 +1641,7 @@ typedef void GLvoid; #define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 #define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA #define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLYPH_HAS_KERNING_NV 0x100 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 #define GL_GLYPH_HEIGHT_BIT_NV 0x02 #define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 #define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 @@ -1479,6 +1651,7 @@ typedef void GLvoid; #define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 #define GL_GLYPH_WIDTH_BIT_NV 0x01 #define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_GPU_DISJOINT_EXT 0x8FBB #define GL_GPU_OPTIMIZED_QCOM 0x8FB2 #define GL_GREATER 0x0204 #define GL_GREEN 0x1904 @@ -1489,8 +1662,10 @@ typedef void GLvoid; #define GL_GREEN_INTEGER_EXT 0x8D95 #define GL_GREEN_MAX_CLAMP_INGR 0x8565 #define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_GREEN_NV 0x1904 #define GL_GREEN_SCALE 0x0D18 #define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 #define GL_HALF_APPLE 0x140B #define GL_HALF_BIAS_NEGATE_NV 0x853B #define GL_HALF_BIAS_NORMAL_NV 0x853A @@ -1499,6 +1674,8 @@ typedef void GLvoid; #define GL_HALF_FLOAT_ARB 0x140B #define GL_HALF_FLOAT_NV 0x140B #define GL_HALF_FLOAT_OES 0x8D61 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 #define GL_HIGH_FLOAT 0x8DF2 #define GL_HIGH_INT 0x8DF5 #define GL_HILO16_NV 0x86F8 @@ -1526,6 +1703,10 @@ typedef void GLvoid; #define GL_HI_BIAS_NV 0x8714 #define GL_HI_SCALE_NV 0x870E #define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE #define GL_IDENTITY_NV 0x862A #define GL_IGNORE_BORDER_HP 0x8150 #define GL_IMAGE_1D 0x904C @@ -1631,6 +1812,7 @@ typedef void GLvoid; #define GL_INDEX_WRITEMASK 0x0C21 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 #define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 #define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 #define GL_INT 0x1404 @@ -1752,7 +1934,7 @@ typedef void GLvoid; #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 #define GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506 -#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_INVALID_INDEX 0xFFFFFFFF #define GL_INVALID_OPERATION 0x0502 #define GL_INVALID_VALUE 0x0501 #define GL_INVARIANT_DATATYPE_EXT 0x87EB @@ -1762,6 +1944,8 @@ typedef void GLvoid; #define GL_INVERSE_TRANSPOSE_NV 0x862D #define GL_INVERT 0x150A #define GL_INVERTED_SCREEN_W_REND 0x8491 +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 #define GL_IR_INSTRUMENT1_SGIX 0x817F #define GL_ISOLINES 0x8E7A #define GL_IS_PER_PATCH 0x92E7 @@ -1779,6 +1963,9 @@ typedef void GLvoid; #define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 #define GL_LAYER_NV 0x8DAA #define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_LAYOUT_DEFAULT_INTEL 0 +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 +#define GL_LAYOUT_LINEAR_INTEL 1 #define GL_LEFT 0x0406 #define GL_LEQUAL 0x0203 #define GL_LERP_ATI 0x8969 @@ -1791,6 +1978,7 @@ typedef void GLvoid; #define GL_LIGHT5 0x4005 #define GL_LIGHT6 0x4006 #define GL_LIGHT7 0x4007 +#define GL_LIGHTEN_NV 0x9298 #define GL_LIGHTING 0x0B50 #define GL_LIGHTING_BIT 0x00000040 #define GL_LIGHT_ENV_MODE_SGIX 0x8407 @@ -1802,6 +1990,9 @@ typedef void GLvoid; #define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 #define GL_LINE 0x1B01 #define GL_LINEAR 0x2601 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 #define GL_LINEAR_ATTENUATION 0x1208 #define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 #define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F @@ -1847,10 +2038,12 @@ typedef void GLvoid; #define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC #define GL_LOCAL_EXT 0x87C4 #define GL_LOCATION 0x930E +#define GL_LOCATION_COMPONENT 0x934A #define GL_LOCATION_INDEX 0x930F #define GL_LOGIC_OP 0x0BF1 #define GL_LOGIC_OP_MODE 0x0BF0 #define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 #define GL_LOWER_LEFT 0x8CA1 #define GL_LOW_FLOAT 0x8DF0 #define GL_LOW_INT 0x8DF3 @@ -1865,6 +2058,7 @@ typedef void GLvoid; #define GL_LUMINANCE12_EXT 0x8041 #define GL_LUMINANCE16 0x8042 #define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE16F_EXT 0x881E #define GL_LUMINANCE16I_EXT 0x8D8C #define GL_LUMINANCE16UI_EXT 0x8D7A #define GL_LUMINANCE16_ALPHA16 0x8048 @@ -1873,11 +2067,13 @@ typedef void GLvoid; #define GL_LUMINANCE16_EXT 0x8042 #define GL_LUMINANCE16_SNORM 0x9019 #define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE32F_EXT 0x8818 #define GL_LUMINANCE32I_EXT 0x8D86 #define GL_LUMINANCE32UI_EXT 0x8D74 #define GL_LUMINANCE4 0x803F #define GL_LUMINANCE4_ALPHA4 0x8043 #define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 #define GL_LUMINANCE4_EXT 0x803F #define GL_LUMINANCE6_ALPHA2 0x8044 #define GL_LUMINANCE6_ALPHA2_EXT 0x8044 @@ -1886,14 +2082,18 @@ typedef void GLvoid; #define GL_LUMINANCE8UI_EXT 0x8D80 #define GL_LUMINANCE8_ALPHA8 0x8045 #define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 #define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 #define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_OES 0x8040 #define GL_LUMINANCE8_SNORM 0x9015 #define GL_LUMINANCE_ALPHA 0x190A #define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F #define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D #define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B #define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 #define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 #define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 #define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 @@ -1914,6 +2114,7 @@ typedef void GLvoid; #define GL_MAGNITUDE_BIAS_NV 0x8718 #define GL_MAGNITUDE_SCALE_NV 0x8712 #define GL_MAJOR_VERSION 0x821B +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 #define GL_MALI_SHADER_BINARY_ARM 0x8F60 #define GL_MANUAL_GENERATE_MIPMAP 0x8294 #define GL_MAP1_BINORMAL_EXT 0x8446 @@ -1976,6 +2177,7 @@ typedef void GLvoid; #define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 #define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 #define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_MAP_COHERENT_BIT 0x0080 #define GL_MAP_COLOR 0x0D10 #define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 #define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 @@ -1983,6 +2185,7 @@ typedef void GLvoid; #define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 #define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 #define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_PERSISTENT_BIT 0x0040 #define GL_MAP_READ_BIT 0x0001 #define GL_MAP_READ_BIT_EXT 0x0001 #define GL_MAP_STENCIL 0x0D11 @@ -2076,6 +2279,7 @@ typedef void GLvoid; #define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 #define GL_MAX_CLIP_DISTANCES 0x0D32 #define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_CLIP_PLANES_IMG 0x0D32 #define GL_MAX_COLOR_ATTACHMENTS 0x8CDF #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF #define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF @@ -2091,6 +2295,7 @@ typedef void GLvoid; #define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF #define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 #define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 #define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC #define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E #define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F @@ -2100,14 +2305,18 @@ typedef void GLvoid; #define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 #define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 #define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB +#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF #define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD -#define GL_MAX_COMPUTE_LOCAL_INVOCATIONS 0x90EB #define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB #define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 #define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC #define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB #define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 #define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB #define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF #define GL_MAX_CONVOLUTION_HEIGHT 0x801B #define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B @@ -2118,18 +2327,24 @@ typedef void GLvoid; #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES 0x851C #define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C #define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 #define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 #define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 #define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 #define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 #define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 +#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 #define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 #define GL_MAX_DEPTH 0x8280 #define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F #define GL_MAX_DRAW_BUFFERS 0x8824 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824 #define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 #define GL_MAX_DRAW_BUFFERS_NV 0x8824 #define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC #define GL_MAX_ELEMENTS_INDICES 0x80E9 @@ -2191,6 +2406,7 @@ typedef void GLvoid; #define GL_MAX_IMAGE_UNITS_EXT 0x8F38 #define GL_MAX_INTEGER_SAMPLES 0x9110 #define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 #define GL_MAX_LAYERS 0x8281 #define GL_MAX_LIGHTS 0x0D31 #define GL_MAX_LIST_NESTING 0x0B31 @@ -2248,8 +2464,8 @@ typedef void GLvoid; #define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 #define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 #define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 #define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F #define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F @@ -2267,8 +2483,10 @@ typedef void GLvoid; #define GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8 #define GL_MAX_SAMPLES 0x8D57 #define GL_MAX_SAMPLES_ANGLE 0x8D57 +#define GL_MAX_SAMPLES_APPLE 0x8D57 #define GL_MAX_SAMPLES_EXT 0x8D57 #define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_MAX_SAMPLES_NV 0x8D57 #define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 #define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 #define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 @@ -2278,8 +2496,11 @@ typedef void GLvoid; #define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD #define GL_MAX_SHININESS_NV 0x8504 #define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 #define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A #define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 +#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 #define GL_MAX_SPOT_EXPONENT_NV 0x8505 #define GL_MAX_SUBROUTINES 0x8DE7 #define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 @@ -2347,6 +2568,7 @@ typedef void GLvoid; #define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 #define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA #define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 #define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 #define GL_MAX_VERTEX_HINT_PGI 0x1A22D #define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA @@ -2382,12 +2604,15 @@ typedef void GLvoid; #define GL_MINMAX_SINK 0x8030 #define GL_MINMAX_SINK_EXT 0x8030 #define GL_MINOR_VERSION 0x821C +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F #define GL_MIN_EXT 0x8007 #define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B #define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B #define GL_MIN_LOD_WARNING_AMD 0x919C #define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC #define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 #define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E @@ -2395,6 +2620,7 @@ typedef void GLvoid; #define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 #define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 #define GL_MIN_SPARSE_LEVEL_AMD 0x919B +#define GL_MIN_SPARSE_LEVEL_ARB 0x919B #define GL_MIPMAP 0x8293 #define GL_MIRRORED_REPEAT 0x8370 #define GL_MIRRORED_REPEAT_ARB 0x8370 @@ -2403,12 +2629,16 @@ typedef void GLvoid; #define GL_MIRROR_CLAMP_ATI 0x8742 #define GL_MIRROR_CLAMP_EXT 0x8742 #define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 #define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 #define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 #define GL_MITER_REVERT_NV 0x90A7 #define GL_MITER_TRUNCATE_NV 0x90A8 #define GL_MODELVIEW 0x1700 #define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 #define GL_MODELVIEW10_ARB 0x872A #define GL_MODELVIEW11_ARB 0x872B #define GL_MODELVIEW12_ARB 0x872C @@ -2444,7 +2674,6 @@ typedef void GLvoid; #define GL_MODELVIEW8_ARB 0x8728 #define GL_MODELVIEW9_ARB 0x8729 #define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_MODELVIEW_MATRIX1_EXT 0x8506 #define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898D #define GL_MODELVIEW_PROJECTION_NV 0x8629 #define GL_MODELVIEW_STACK_DEPTH 0x0BA3 @@ -2458,6 +2687,7 @@ typedef void GLvoid; #define GL_MOVE_TO_RESETS_NV 0x90B5 #define GL_MOV_ATI 0x8961 #define GL_MULT 0x0103 +#define GL_MULTIPLY_NV 0x9294 #define GL_MULTISAMPLE 0x809D #define GL_MULTISAMPLE_3DFX 0x86B2 #define GL_MULTISAMPLE_ARB 0x809D @@ -2465,12 +2695,19 @@ typedef void GLvoid; #define GL_MULTISAMPLE_BIT_3DFX 0x20000000 #define GL_MULTISAMPLE_BIT_ARB 0x20000000 #define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 #define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 #define GL_MULTISAMPLE_EXT 0x809D #define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 #define GL_MULTISAMPLE_SGIS 0x809D #define GL_MULTIVIEW_EXT 0x90F1 -#define GL_MULTI_HULLS_NV 0x908C #define GL_MUL_ATI 0x8964 #define GL_MVP_MATRIX_EXT 0x87E3 #define GL_N3F_V3F 0x2A25 @@ -2494,9 +2731,11 @@ typedef void GLvoid; #define GL_NEGATIVE_Y_EXT 0x87DA #define GL_NEGATIVE_Z_EXT 0x87DB #define GL_NEVER 0x0200 +#define GL_NEXT_BUFFER_NV -2 #define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 #define GL_NICEST 0x1102 #define GL_NONE 0 +#define GL_NONE_OES 0 #define GL_NOOP 0x1505 #define GL_NOR 0x1508 #define GL_NORMALIZE 0x0BA1 @@ -2526,6 +2765,7 @@ typedef void GLvoid; #define GL_NOTEQUAL 0x0205 #define GL_NO_ERROR 0 #define GL_NO_RESET_NOTIFICATION_ARB 0x8261 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 #define GL_NUM_ACTIVE_VARIABLES 0x9304 #define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 @@ -2546,6 +2786,7 @@ typedef void GLvoid; #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 #define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 #define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 #define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 #define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A #define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 @@ -2580,7 +2821,10 @@ typedef void GLvoid; #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 #define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 #define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 #define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 #define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C @@ -2683,6 +2927,7 @@ typedef void GLvoid; #define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 #define GL_OUTPUT_VERTEX_EXT 0x879A #define GL_OUT_OF_MEMORY 0x0505 +#define GL_OVERLAY_NV 0x9296 #define GL_PACK_ALIGNMENT 0x0D05 #define GL_PACK_CMYK_HINT_EXT 0x800E #define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D @@ -2719,6 +2964,8 @@ typedef void GLvoid; #define GL_PALETTE8_RGBA4_OES 0x8B98 #define GL_PALETTE8_RGBA8_OES 0x8B96 #define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_PARAMETER_BUFFER_ARB 0x80EE +#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF #define GL_PARTIAL_SUCCESS_NV 0x902E #define GL_PASS_THROUGH_NV 0x86E6 #define GL_PASS_THROUGH_TOKEN 0x0700 @@ -2753,17 +3000,14 @@ typedef void GLvoid; #define GL_PATH_JOIN_STYLE_NV 0x9079 #define GL_PATH_MITER_LIMIT_NV 0x907A #define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A -#define GL_PATH_SAMPLE_QUALITY_NV 0x9085 #define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD #define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE #define GL_PATH_STENCIL_FUNC_NV 0x90B7 #define GL_PATH_STENCIL_REF_NV 0x90B8 #define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 #define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 -#define GL_PATH_STROKE_BOUND_NV 0x9086 #define GL_PATH_STROKE_COVER_MODE_NV 0x9083 #define GL_PATH_STROKE_MASK_NV 0x9084 -#define GL_PATH_STROKE_OVERSAMPLE_COUNT_NV 0x9087 #define GL_PATH_STROKE_WIDTH_NV 0x9075 #define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D #define GL_PATH_TERMINAL_END_CAP_NV 0x9078 @@ -2778,6 +3022,7 @@ typedef void GLvoid; #define GL_PER_STAGE_CONSTANTS_NV 0x8535 #define GL_PHONG_HINT_WIN 0x80EB #define GL_PHONG_WIN 0x80EA +#define GL_PINLIGHT_NV 0x92A8 #define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 #define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 #define GL_PIXEL_COUNTER_BITS_NV 0x8864 @@ -2846,6 +3091,10 @@ typedef void GLvoid; #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF #define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF #define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 #define GL_PN_TRIANGLES_ATI 0x87F0 #define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 @@ -2885,6 +3134,7 @@ typedef void GLvoid; #define GL_POINT_SPRITE_ARB 0x8861 #define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 #define GL_POINT_SPRITE_NV 0x8861 +#define GL_POINT_SPRITE_OES 0x8861 #define GL_POINT_SPRITE_R_MODE_NV 0x8863 #define GL_POINT_TOKEN 0x0701 #define GL_POLYGON 0x0009 @@ -2963,6 +3213,7 @@ typedef void GLvoid; #define GL_PRIMITIVE_ID_NV 0x8C7C #define GL_PRIMITIVE_RESTART 0x8F9D #define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 #define GL_PRIMITIVE_RESTART_INDEX 0x8F9E #define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 #define GL_PRIMITIVE_RESTART_NV 0x8558 @@ -2971,6 +3222,7 @@ typedef void GLvoid; #define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 #define GL_PROGRAM_ATTRIBS_ARB 0x88AC #define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 #define GL_PROGRAM_BINARY_FORMATS 0x87FF #define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF #define GL_PROGRAM_BINARY_LENGTH 0x8741 @@ -2985,6 +3237,7 @@ typedef void GLvoid; #define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 #define GL_PROGRAM_INPUT 0x92E3 #define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_PROGRAM_KHR 0x82E2 #define GL_PROGRAM_LENGTH_ARB 0x8627 #define GL_PROGRAM_LENGTH_NV 0x8627 #define GL_PROGRAM_MATRIX_EXT 0x8E2D @@ -3024,8 +3277,6 @@ typedef void GLvoid; #define GL_PROJECTION_MATRIX 0x0BA7 #define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898E #define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_PROJECTIVE_2D_NV 0x9093 -#define GL_PROJECTIVE_3D_NV 0x9095 #define GL_PROVOKING_VERTEX 0x8E4F #define GL_PROVOKING_VERTEX_EXT 0x8E4F #define GL_PROXY_COLOR_TABLE 0x80D3 @@ -3079,7 +3330,10 @@ typedef void GLvoid; #define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 #define GL_QUARTER_BIT_ATI 0x00000010 #define GL_QUERY 0x82E3 +#define GL_QUERY_BUFFER 0x9192 #define GL_QUERY_BUFFER_AMD 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 #define GL_QUERY_BUFFER_BINDING_AMD 0x9193 #define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 #define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 @@ -3087,6 +3341,8 @@ typedef void GLvoid; #define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 #define GL_QUERY_COUNTER_BITS 0x8864 #define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_QUERY_KHR 0x82E3 #define GL_QUERY_NO_WAIT 0x8E14 #define GL_QUERY_NO_WAIT_NV 0x8E14 #define GL_QUERY_OBJECT_AMD 0x9153 @@ -3097,6 +3353,7 @@ typedef void GLvoid; #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 #define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 #define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 #define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 #define GL_QUERY_WAIT 0x8E13 #define GL_QUERY_WAIT_NV 0x8E13 @@ -3118,6 +3375,7 @@ typedef void GLvoid; #define GL_R1UI_T2F_V3F_SUN 0x85C9 #define GL_R1UI_V3F_SUN 0x85C4 #define GL_R32F 0x822E +#define GL_R32F_EXT 0x822E #define GL_R32I 0x8235 #define GL_R32UI 0x8236 #define GL_R3_G3_B2 0x2A10 @@ -3135,9 +3393,14 @@ typedef void GLvoid; #define GL_READ_BUFFER_NV 0x0C02 #define GL_READ_FRAMEBUFFER 0x8CA8 #define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 #define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA #define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA #define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 #define GL_READ_ONLY 0x88B8 #define GL_READ_ONLY_ARB 0x88B8 #define GL_READ_PIXELS 0x828C @@ -3162,6 +3425,7 @@ typedef void GLvoid; #define GL_RED_INTEGER_EXT 0x8D94 #define GL_RED_MAX_CLAMP_INGR 0x8564 #define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_RED_NV 0x1903 #define GL_RED_SCALE 0x0D14 #define GL_RED_SNORM 0x8F90 #define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B @@ -3258,8 +3522,10 @@ typedef void GLvoid; #define GL_RENDERBUFFER_RED_SIZE_OES 0x8D50 #define GL_RENDERBUFFER_SAMPLES 0x8CAB #define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB #define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 #define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 #define GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55 @@ -3293,6 +3559,7 @@ typedef void GLvoid; #define GL_RESCALE_NORMAL 0x803A #define GL_RESCALE_NORMAL_EXT 0x803A #define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 #define GL_RESTART_PATH_NV 0xF0 #define GL_RESTART_SUN 0x0001 #define GL_RETAINED_APPLE 0x8A1B @@ -3305,6 +3572,7 @@ typedef void GLvoid; #define GL_RG16UI 0x823A #define GL_RG16_SNORM 0x8F99 #define GL_RG32F 0x8230 +#define GL_RG32F_EXT 0x8230 #define GL_RG32I 0x823B #define GL_RG32UI 0x823C #define GL_RG8 0x822B @@ -3333,6 +3601,7 @@ typedef void GLvoid; #define GL_RGB2_EXT 0x804E #define GL_RGB32F 0x8815 #define GL_RGB32F_ARB 0x8815 +#define GL_RGB32F_EXT 0x8815 #define GL_RGB32I 0x8D83 #define GL_RGB32I_EXT 0x8D83 #define GL_RGB32UI 0x8D71 @@ -3353,6 +3622,7 @@ typedef void GLvoid; #define GL_RGB8UI 0x8D7D #define GL_RGB8UI_EXT 0x8D7D #define GL_RGB8_EXT 0x8051 +#define GL_RGB8_OES 0x8051 #define GL_RGB8_SNORM 0x8F96 #define GL_RGB9_E5 0x8C3D #define GL_RGB9_E5_EXT 0x8C3D @@ -3373,6 +3643,7 @@ typedef void GLvoid; #define GL_RGBA2_EXT 0x8055 #define GL_RGBA32F 0x8814 #define GL_RGBA32F_ARB 0x8814 +#define GL_RGBA32F_EXT 0x8814 #define GL_RGBA32I 0x8D82 #define GL_RGBA32I_EXT 0x8D82 #define GL_RGBA32UI 0x8D70 @@ -3388,6 +3659,7 @@ typedef void GLvoid; #define GL_RGBA8UI 0x8D7C #define GL_RGBA8UI_EXT 0x8D7C #define GL_RGBA8_EXT 0x8058 +#define GL_RGBA8_OES 0x8058 #define GL_RGBA8_SNORM 0x8F97 #define GL_RGBA_DXT5_S3TC 0x83A4 #define GL_RGBA_FLOAT16_APPLE 0x881A @@ -3411,6 +3683,7 @@ typedef void GLvoid; #define GL_RGB_FLOAT32_ATI 0x8815 #define GL_RGB_INTEGER 0x8D98 #define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGB_RAW_422_APPLE 0x8A51 #define GL_RGB_S3TC 0x83A0 #define GL_RGB_SCALE 0x8573 #define GL_RGB_SCALE_ARB 0x8573 @@ -3437,6 +3710,7 @@ typedef void GLvoid; #define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 #define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 #define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 #define GL_SAMPLER_2D_MULTISAMPLE 0x9108 #define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B #define GL_SAMPLER_2D_RECT 0x8B63 @@ -3461,7 +3735,9 @@ typedef void GLvoid; #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D #define GL_SAMPLER_CUBE_SHADOW 0x8DC5 #define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 #define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_SAMPLER_KHR 0x82E6 #define GL_SAMPLER_OBJECT_AMD 0x9155 #define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 #define GL_SAMPLES 0x80A9 @@ -3518,6 +3794,7 @@ typedef void GLvoid; #define GL_SCISSOR_BOX 0x0C10 #define GL_SCISSOR_TEST 0x0C11 #define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_SCREEN_NV 0x9295 #define GL_SECONDARY_COLOR_ARRAY 0x845E #define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C @@ -3563,11 +3840,12 @@ typedef void GLvoid; #define GL_SHADER_IMAGE_LOAD 0x82A4 #define GL_SHADER_IMAGE_STORE 0x82A5 #define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_SHADER_KHR 0x82E1 #define GL_SHADER_OBJECT_ARB 0x8B48 #define GL_SHADER_OBJECT_EXT 0x8B48 #define GL_SHADER_OPERATION_NV 0x86DF #define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000 +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 #define GL_SHADER_STORAGE_BLOCK 0x92E6 #define GL_SHADER_STORAGE_BUFFER 0x90D2 #define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 @@ -3612,6 +3890,10 @@ typedef void GLvoid; #define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF #define GL_SINGLE_COLOR 0x81F9 #define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SKIP_COMPONENTS1_NV -6 +#define GL_SKIP_COMPONENTS2_NV -5 +#define GL_SKIP_COMPONENTS3_NV -4 +#define GL_SKIP_COMPONENTS4_NV -3 #define GL_SKIP_DECODE_EXT 0x8A4A #define GL_SKIP_MISSING_GLYPH_NV 0x90A9 #define GL_SLICE_ACCUM_SUN 0x85CC @@ -3622,10 +3904,14 @@ typedef void GLvoid; #define GL_SLUMINANCE8 0x8C47 #define GL_SLUMINANCE8_ALPHA8 0x8C45 #define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 #define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_SLUMINANCE8_NV 0x8C47 #define GL_SLUMINANCE_ALPHA 0x8C44 #define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 #define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE_NV 0x8C46 #define GL_SMALL_CCW_ARC_TO_NV 0x12 #define GL_SMALL_CW_ARC_TO_NV 0x14 #define GL_SMOOTH 0x1D01 @@ -3635,6 +3921,7 @@ typedef void GLvoid; #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_SOFTLIGHT_NV 0x929C #define GL_SOURCE0_ALPHA 0x8588 #define GL_SOURCE0_ALPHA_ARB 0x8588 #define GL_SOURCE0_ALPHA_EXT 0x8588 @@ -3658,6 +3945,7 @@ typedef void GLvoid; #define GL_SPARE0_NV 0x852E #define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 #define GL_SPARE1_NV 0x852F +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 #define GL_SPECULAR 0x1202 #define GL_SPHERE_MAP 0x2402 #define GL_SPOT_CUTOFF 0x1206 @@ -3680,12 +3968,18 @@ typedef void GLvoid; #define GL_SRC2_RGB 0x8582 #define GL_SRC_ALPHA 0x0302 #define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_ATOP_NV 0x928E #define GL_SRC_COLOR 0x0300 +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 #define GL_SRGB 0x8C40 #define GL_SRGB8 0x8C41 #define GL_SRGB8_ALPHA8 0x8C43 #define GL_SRGB8_ALPHA8_EXT 0x8C43 #define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB8_NV 0x8C41 #define GL_SRGB_ALPHA 0x8C42 #define GL_SRGB_ALPHA_EXT 0x8C42 #define GL_SRGB_DECODE_ARB 0x8299 @@ -3693,7 +3987,9 @@ typedef void GLvoid; #define GL_SRGB_READ 0x8297 #define GL_SRGB_WRITE 0x8298 #define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_OVERFLOW_KHR 0x0503 #define GL_STACK_UNDERFLOW 0x0504 +#define GL_STACK_UNDERFLOW_KHR 0x0504 #define GL_STANDARD_FONT_NAME_NV 0x9072 #define GL_STATE_RESTORE 0x8BDC #define GL_STATIC_ATI 0x8760 @@ -3703,6 +3999,7 @@ typedef void GLvoid; #define GL_STATIC_DRAW_ARB 0x88E4 #define GL_STATIC_READ 0x88E5 #define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 #define GL_STENCIL 0x1802 #define GL_STENCIL_ATTACHMENT 0x8D20 #define GL_STENCIL_ATTACHMENT_EXT 0x8D20 @@ -3721,6 +4018,14 @@ typedef void GLvoid; #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 #define GL_STENCIL_BITS 0x0D57 #define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 #define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 #define GL_STENCIL_CLEAR_VALUE 0x0B91 #define GL_STENCIL_COMPONENTS 0x8285 @@ -3942,6 +4247,7 @@ typedef void GLvoid; #define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 #define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_BINDING_3D_OES 0x806A #define GL_TEXTURE_BINDING_BUFFER 0x8C2C #define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C #define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C @@ -3963,9 +4269,11 @@ typedef void GLvoid; #define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 #define GL_TEXTURE_BORDER 0x1005 #define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 #define GL_TEXTURE_BORDER_VALUES_NV 0x871A #define GL_TEXTURE_BUFFER 0x8C2A #define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D @@ -4084,6 +4392,7 @@ typedef void GLvoid; #define GL_TEXTURE_GATHER 0x82A2 #define GL_TEXTURE_GATHER_SHADOW 0x82A3 #define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_GEN_MODE_OES 0x2500 #define GL_TEXTURE_GEN_Q 0x0C63 #define GL_TEXTURE_GEN_R 0x0C62 #define GL_TEXTURE_GEN_S 0x0C60 @@ -4101,6 +4410,7 @@ typedef void GLvoid; #define GL_TEXTURE_IMAGE_TYPE 0x8290 #define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 #define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F #define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF #define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED #define GL_TEXTURE_INTENSITY_SIZE 0x8061 @@ -4133,9 +4443,11 @@ typedef void GLvoid; #define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 #define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A #define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D #define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D #define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF #define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_TEXTURE_MIN_LOD 0x813A #define GL_TEXTURE_MIN_LOD_SGIS 0x813A @@ -4166,6 +4478,7 @@ typedef void GLvoid; #define GL_TEXTURE_SHADOW 0x82A1 #define GL_TEXTURE_SHARED_SIZE 0x8C3F #define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#define GL_TEXTURE_SPARSE_ARB 0x91A6 #define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 #define GL_TEXTURE_STACK_DEPTH 0x0BA5 #define GL_TEXTURE_STENCIL_SIZE 0x88F1 @@ -4205,9 +4518,10 @@ typedef void GLvoid; #define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 #define GL_TIMEOUT_EXPIRED 0x911B #define GL_TIMEOUT_EXPIRED_APPLE 0x911B -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull -#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFF #define GL_TIMESTAMP 0x8E28 +#define GL_TIMESTAMP_EXT 0x8E28 #define GL_TIME_ELAPSED 0x88BF #define GL_TIME_ELAPSED_EXT 0x88BF #define GL_TOP_LEVEL_ARRAY_SIZE 0x930C @@ -4232,15 +4546,18 @@ typedef void GLvoid; #define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 #define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 #define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 #define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F #define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F #define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 #define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 @@ -4248,6 +4565,7 @@ typedef void GLvoid; #define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C #define GL_TRANSFORM_FEEDBACK_NV 0x8E22 #define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 @@ -4277,8 +4595,6 @@ typedef void GLvoid; #define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E #define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 #define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_PROJECTIVE_2D_NV 0x9097 -#define GL_TRANSPOSE_PROJECTIVE_3D_NV 0x9099 #define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 #define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 #define GL_TRIANGLES 0x0004 @@ -4295,7 +4611,7 @@ typedef void GLvoid; #define GL_TRIANGULAR_NV 0x90A5 #define GL_TRUE 1 #define GL_TYPE 0x92FA -#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 +#define GL_UNCORRELATED_NV 0x9282 #define GL_UNDEFINED_APPLE 0x8A1C #define GL_UNDEFINED_VERTEX 0x8260 #define GL_UNIFORM 0x92E1 @@ -4330,27 +4646,34 @@ typedef void GLvoid; #define GL_UNIFORM_SIZE 0x8A38 #define GL_UNIFORM_TYPE 0x8A37 #define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 #define GL_UNPACK_ALIGNMENT 0x0CF5 #define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 #define GL_UNPACK_CMYK_HINT_EXT 0x800F +#define GL_UNPACK_COLORSPACE_CONVERSION_WEBGL 0x9243 #define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 #define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 #define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A #define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 #define GL_UNPACK_COMPRESSED_SIZE_SGIX 0x831A #define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_UNPACK_FLIP_Y_WEBGL 0x9240 #define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 #define GL_UNPACK_IMAGE_HEIGHT 0x806E #define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E #define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241 #define GL_UNPACK_RESAMPLE_OML 0x8985 #define GL_UNPACK_RESAMPLE_SGIX 0x842D #define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 #define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 #define GL_UNPACK_SKIP_IMAGES 0x806D #define GL_UNPACK_SKIP_IMAGES_EXT 0x806D #define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 #define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 #define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 #define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 #define GL_UNPACK_SWAP_BYTES 0x0CF0 @@ -4368,6 +4691,7 @@ typedef void GLvoid; #define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 #define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 #define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_UNSIGNED_INT64_ARB 0x140F #define GL_UNSIGNED_INT64_NV 0x140F #define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 #define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 @@ -4449,7 +4773,6 @@ typedef void GLvoid; #define GL_UNSIGNED_INT_VEC4 0x8DC8 #define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 #define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_UNSIGNED_NEGATE_NV 0x853D #define GL_UNSIGNED_NORMALIZED 0x8C17 #define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 #define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 @@ -4462,6 +4785,7 @@ typedef void GLvoid; #define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 @@ -4497,26 +4821,21 @@ typedef void GLvoid; #define GL_VECTOR_EXT 0x87BF #define GL_VENDOR 0x1F00 #define GL_VERSION 0x1F02 -#define GL_VERSION_1_1 1 -#define GL_VERSION_1_2 1 -#define GL_VERSION_1_3 1 -#define GL_VERSION_1_4 1 -#define GL_VERSION_1_5 1 -#define GL_VERSION_2_0 1 -#define GL_VERSION_2_1 1 -#define GL_VERSION_3_0 1 -#define GL_VERSION_3_1 1 -#define GL_VERSION_3_2 1 +#define GL_VERSION_ES_CL_1_0 1 +#define GL_VERSION_ES_CL_1_1 1 +#define GL_VERSION_ES_CM_1_1 1 #define GL_VERTEX23_BIT_PGI 0x00000004 #define GL_VERTEX4_BIT_PGI 0x00000008 #define GL_VERTEX_ARRAY 0x8074 #define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 #define GL_VERTEX_ARRAY_BINDING 0x85B5 #define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 #define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 #define GL_VERTEX_ARRAY_COUNT_EXT 0x807D #define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_VERTEX_ARRAY_KHR 0x8074 #define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B #define GL_VERTEX_ARRAY_LIST_IBM 103070 #define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 @@ -4564,9 +4883,12 @@ typedef void GLvoid; #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD #define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD #define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A #define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E @@ -4599,14 +4921,16 @@ typedef void GLvoid; #define GL_VERTEX_BLEND_ARB 0x86A7 #define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B #define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 #define GL_VERTEX_ID_NV 0x8C7B +#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 #define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF #define GL_VERTEX_PRECLIP_SGIX 0x83EE #define GL_VERTEX_PROGRAM_ARB 0x8620 #define GL_VERTEX_PROGRAM_BINDING_NV 0x864A #define GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8BB7 #define GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8BB6 -#define GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8BB4 +#define GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8BB5 #define GL_VERTEX_PROGRAM_NV 0x8620 #define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 @@ -4686,9 +5010,14 @@ typedef void GLvoid; #define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE #define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF #define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 #define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 #define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 #define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 +#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 +#define GL_VIVIDLIGHT_NV 0x92A6 #define GL_VOLATILE_APPLE 0x8A1A #define GL_WAIT_FAILED 0x911D #define GL_WAIT_FAILED_APPLE 0x911D @@ -4718,6 +5047,7 @@ typedef void GLvoid; #define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C #define GL_W_EXT 0x87D8 #define GL_XOR 0x1506 +#define GL_XOR_NV 0x1506 #define GL_X_EXT 0x87D5 #define GL_YCBAYCR8A_4224_NV 0x9032 #define GL_YCBCR_422_APPLE 0x85B9 @@ -4749,7 +5079,7 @@ void GLAPIENTRY glBindTexture(GLenum,GLuint); void GLAPIENTRY glBitmap(GLsizei,GLsizei,GLfloat,GLfloat,GLfloat,GLfloat,const GLubyte*); void GLAPIENTRY glBlendFunc(GLenum,GLenum); void GLAPIENTRY glCallList(GLuint); -void GLAPIENTRY glCallLists(GLsizei,GLenum,const GLvoid*); +void GLAPIENTRY glCallLists(GLsizei,GLenum,const void*); void GLAPIENTRY glClear(GLbitfield); void GLAPIENTRY glClearAccum(GLfloat,GLfloat,GLfloat,GLfloat); void GLAPIENTRY glClearColor(GLfloat,GLfloat,GLfloat,GLfloat); @@ -4791,7 +5121,7 @@ void GLAPIENTRY glColor4us(GLushort,GLushort,GLushort,GLushort); void GLAPIENTRY glColor4usv(const GLushort*); void GLAPIENTRY glColorMask(GLboolean,GLboolean,GLboolean,GLboolean); void GLAPIENTRY glColorMaterial(GLenum,GLenum); -void GLAPIENTRY glColorPointer(GLint,GLenum,GLsizei,const GLvoid*); +void GLAPIENTRY glColorPointer(GLint,GLenum,GLsizei,const void*); void GLAPIENTRY glCopyPixels(GLint,GLint,GLsizei,GLsizei,GLenum); void GLAPIENTRY glCopyTexImage1D(GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLint); void GLAPIENTRY glCopyTexImage2D(GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLsizei,GLint); @@ -4808,10 +5138,10 @@ void GLAPIENTRY glDisable(GLenum); void GLAPIENTRY glDisableClientState(GLenum); void GLAPIENTRY glDrawArrays(GLenum,GLint,GLsizei); void GLAPIENTRY glDrawBuffer(GLenum); -void GLAPIENTRY glDrawElements(GLenum,GLsizei,GLenum,const GLvoid*); -void GLAPIENTRY glDrawPixels(GLsizei,GLsizei,GLenum,GLenum,const GLvoid*); +void GLAPIENTRY glDrawElements(GLenum,GLsizei,GLenum,const void*); +void GLAPIENTRY glDrawPixels(GLsizei,GLsizei,GLenum,GLenum,const void*); void GLAPIENTRY glEdgeFlag(GLboolean); -void GLAPIENTRY glEdgeFlagPointer(GLsizei,const GLvoid*); +void GLAPIENTRY glEdgeFlagPointer(GLsizei,const void*); void GLAPIENTRY glEdgeFlagv(const GLboolean*); void GLAPIENTRY glEnable(GLenum); void GLAPIENTRY glEnableClientState(GLenum); @@ -4856,22 +5186,22 @@ void GLAPIENTRY glGetMaterialiv(GLenum,GLenum,GLint*); void GLAPIENTRY glGetPixelMapfv(GLenum,GLfloat*); void GLAPIENTRY glGetPixelMapuiv(GLenum,GLuint*); void GLAPIENTRY glGetPixelMapusv(GLenum,GLushort*); -void GLAPIENTRY glGetPointerv(GLenum,GLvoid**); +void GLAPIENTRY glGetPointerv(GLenum,void**); void GLAPIENTRY glGetPolygonStipple(GLubyte*); -const GLubyte * GLAPIENTRY glGetString(GLenum); +const GLubyte* GLAPIENTRY glGetString(GLenum); void GLAPIENTRY glGetTexEnvfv(GLenum,GLenum,GLfloat*); void GLAPIENTRY glGetTexEnviv(GLenum,GLenum,GLint*); void GLAPIENTRY glGetTexGendv(GLenum,GLenum,GLdouble*); void GLAPIENTRY glGetTexGenfv(GLenum,GLenum,GLfloat*); void GLAPIENTRY glGetTexGeniv(GLenum,GLenum,GLint*); -void GLAPIENTRY glGetTexImage(GLenum,GLint,GLenum,GLenum,GLvoid*); +void GLAPIENTRY glGetTexImage(GLenum,GLint,GLenum,GLenum,void*); void GLAPIENTRY glGetTexLevelParameterfv(GLenum,GLint,GLenum,GLfloat*); void GLAPIENTRY glGetTexLevelParameteriv(GLenum,GLint,GLenum,GLint*); void GLAPIENTRY glGetTexParameterfv(GLenum,GLenum,GLfloat*); void GLAPIENTRY glGetTexParameteriv(GLenum,GLenum,GLint*); void GLAPIENTRY glHint(GLenum,GLenum); void GLAPIENTRY glIndexMask(GLuint); -void GLAPIENTRY glIndexPointer(GLenum,GLsizei,const GLvoid*); +void GLAPIENTRY glIndexPointer(GLenum,GLsizei,const void*); void GLAPIENTRY glIndexd(GLdouble); void GLAPIENTRY glIndexdv(const GLdouble*); void GLAPIENTRY glIndexf(GLfloat); @@ -4883,7 +5213,7 @@ void GLAPIENTRY glIndexsv(const GLshort*); void GLAPIENTRY glIndexub(GLubyte); void GLAPIENTRY glIndexubv(const GLubyte*); void GLAPIENTRY glInitNames(void); -void GLAPIENTRY glInterleavedArrays(GLenum,GLsizei,const GLvoid*); +void GLAPIENTRY glInterleavedArrays(GLenum,GLsizei,const void*); GLboolean GLAPIENTRY glIsEnabled(GLenum); GLboolean GLAPIENTRY glIsList(GLuint); GLboolean GLAPIENTRY glIsTexture(GLuint); @@ -4929,12 +5259,12 @@ void GLAPIENTRY glNormal3i(GLint,GLint,GLint); void GLAPIENTRY glNormal3iv(const GLint*); void GLAPIENTRY glNormal3s(GLshort,GLshort,GLshort); void GLAPIENTRY glNormal3sv(const GLshort*); -void GLAPIENTRY glNormalPointer(GLenum,GLsizei,const GLvoid*); +void GLAPIENTRY glNormalPointer(GLenum,GLsizei,const void*); void GLAPIENTRY glOrtho(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble); void GLAPIENTRY glPassThrough(GLfloat); -void GLAPIENTRY glPixelMapfv(GLenum,GLint,const GLfloat*); -void GLAPIENTRY glPixelMapuiv(GLenum,GLint,const GLuint*); -void GLAPIENTRY glPixelMapusv(GLenum,GLint,const GLushort*); +void GLAPIENTRY glPixelMapfv(GLenum,GLsizei,const GLfloat*); +void GLAPIENTRY glPixelMapuiv(GLenum,GLsizei,const GLuint*); +void GLAPIENTRY glPixelMapusv(GLenum,GLsizei,const GLushort*); void GLAPIENTRY glPixelStoref(GLenum,GLfloat); void GLAPIENTRY glPixelStorei(GLenum,GLint); void GLAPIENTRY glPixelTransferf(GLenum,GLfloat); @@ -4978,7 +5308,7 @@ void GLAPIENTRY glRasterPos4iv(const GLint*); void GLAPIENTRY glRasterPos4s(GLshort,GLshort,GLshort,GLshort); void GLAPIENTRY glRasterPos4sv(const GLshort*); void GLAPIENTRY glReadBuffer(GLenum); -void GLAPIENTRY glReadPixels(GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,GLvoid*); +void GLAPIENTRY glReadPixels(GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,void*); void GLAPIENTRY glRectd(GLdouble,GLdouble,GLdouble,GLdouble); void GLAPIENTRY glRectdv(const GLdouble*,const GLdouble*); void GLAPIENTRY glRectf(GLfloat,GLfloat,GLfloat,GLfloat); @@ -5030,7 +5360,7 @@ void GLAPIENTRY glTexCoord4i(GLint,GLint,GLint,GLint); void GLAPIENTRY glTexCoord4iv(const GLint*); void GLAPIENTRY glTexCoord4s(GLshort,GLshort,GLshort,GLshort); void GLAPIENTRY glTexCoord4sv(const GLshort*); -void GLAPIENTRY glTexCoordPointer(GLint,GLenum,GLsizei,const GLvoid*); +void GLAPIENTRY glTexCoordPointer(GLint,GLenum,GLsizei,const void*); void GLAPIENTRY glTexEnvf(GLenum,GLenum,GLfloat); void GLAPIENTRY glTexEnvfv(GLenum,GLenum,const GLfloat*); void GLAPIENTRY glTexEnvi(GLenum,GLenum,GLint); @@ -5041,14 +5371,14 @@ void GLAPIENTRY glTexGenf(GLenum,GLenum,GLfloat); void GLAPIENTRY glTexGenfv(GLenum,GLenum,const GLfloat*); void GLAPIENTRY glTexGeni(GLenum,GLenum,GLint); void GLAPIENTRY glTexGeniv(GLenum,GLenum,const GLint*); -void GLAPIENTRY glTexImage1D(GLenum,GLint,GLint,GLsizei,GLint,GLenum,GLenum,const GLvoid*); -void GLAPIENTRY glTexImage2D(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*); +void GLAPIENTRY glTexImage1D(GLenum,GLint,GLint,GLsizei,GLint,GLenum,GLenum,const void*); +void GLAPIENTRY glTexImage2D(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const void*); void GLAPIENTRY glTexParameterf(GLenum,GLenum,GLfloat); void GLAPIENTRY glTexParameterfv(GLenum,GLenum,const GLfloat*); void GLAPIENTRY glTexParameteri(GLenum,GLenum,GLint); void GLAPIENTRY glTexParameteriv(GLenum,GLenum,const GLint*); -void GLAPIENTRY glTexSubImage1D(GLenum,GLint,GLint,GLsizei,GLenum,GLenum,const GLvoid*); -void GLAPIENTRY glTexSubImage2D(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*); +void GLAPIENTRY glTexSubImage1D(GLenum,GLint,GLint,GLsizei,GLenum,GLenum,const void*); +void GLAPIENTRY glTexSubImage2D(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const void*); void GLAPIENTRY glTranslated(GLdouble,GLdouble,GLdouble); void GLAPIENTRY glTranslatef(GLfloat,GLfloat,GLfloat); void GLAPIENTRY glVertex2d(GLdouble,GLdouble); @@ -5075,7 +5405,7 @@ void GLAPIENTRY glVertex4i(GLint,GLint,GLint,GLint); void GLAPIENTRY glVertex4iv(const GLint*); void GLAPIENTRY glVertex4s(GLshort,GLshort,GLshort,GLshort); void GLAPIENTRY glVertex4sv(const GLshort*); -void GLAPIENTRY glVertexPointer(GLint,GLenum,GLsizei,const GLvoid*); +void GLAPIENTRY glVertexPointer(GLint,GLenum,GLsizei,const void*); void GLAPIENTRY glViewport(GLint,GLint,GLsizei,GLsizei); #endif /* __WINE_WGL_H */ diff --git a/reactos/include/reactos/wine/wined3d.h b/reactos/include/reactos/wine/wined3d.h index bf4b39209ca..7ddd4664bff 100644 --- a/reactos/include/reactos/wine/wined3d.h +++ b/reactos/include/reactos/wine/wined3d.h @@ -824,6 +824,7 @@ enum wined3d_display_rotation #define WINED3DUSAGE_AUTOGENMIPMAP 0x00000400 #define WINED3DUSAGE_DMAP 0x00004000 #define WINED3DUSAGE_MASK 0x00004fff +#define WINED3DUSAGE_TEXTURE 0x10000000 #define WINED3DUSAGE_OWNDC 0x20000000 #define WINED3DUSAGE_STATICDECL 0x40000000 #define WINED3DUSAGE_OVERLAY 0x80000000 @@ -1267,6 +1268,7 @@ enum wined3d_display_rotation #define WINEDDBLT_WAIT 0x01000000 #define WINEDDBLT_DEPTHFILL 0x02000000 #define WINEDDBLT_DONOTWAIT 0x08000000 +#define WINEDDBLT_ALPHATEST 0x80000000 /* DDSURFACEDESC.dwFlags */ #define WINEDDSD_CAPS 0x00000001 @@ -1480,18 +1482,9 @@ enum wined3d_display_rotation #define WINEDDCAPS2_STEREO 0x02000000 #define WINEDDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL 0x04000000 -/* DDCAPS.d */ -#define WINEDDPCAPS_4BIT 0x00000001 -#define WINEDDPCAPS_8BITENTRIES 0x00000002 -#define WINEDDPCAPS_8BIT 0x00000004 -#define WINEDDPCAPS_INITIALIZE 0x00000008 -#define WINEDDPCAPS_PRIMARYSURFACE 0x00000010 -#define WINEDDPCAPS_PRIMARYSURFACELEFT 0x00000020 -#define WINEDDPCAPS_ALLOW256 0x00000040 -#define WINEDDPCAPS_VSYNC 0x00000080 -#define WINEDDPCAPS_1BIT 0x00000100 -#define WINEDDPCAPS_2BIT 0x00000200 -#define WINEDDPCAPS_ALPHA 0x00000400 +#define WINED3D_PALETTE_8BIT_ENTRIES 0x00000001 +#define WINED3D_PALETTE_ALLOW_256 0x00000002 +#define WINED3D_PALETTE_ALPHA 0x00000004 #define WINED3D_SURFACE_MAPPABLE 0x00000001 #define WINED3D_SURFACE_DISCARD 0x00000002 @@ -1736,7 +1729,6 @@ struct wined3d_ddraw_caps DWORD color_key_caps; DWORD fx_caps; DWORD fx_alpha_caps; - DWORD pal_caps; DWORD sv_caps; DWORD svb_caps; DWORD svb_color_key_caps; @@ -1979,14 +1971,12 @@ struct wined3d_device_parent_ops { void (__cdecl *wined3d_device_created)(struct wined3d_device_parent *device_parent, struct wined3d_device *device); void (__cdecl *mode_changed)(struct wined3d_device_parent *device_parent); + HRESULT (__cdecl *surface_created)(struct wined3d_device_parent *device_parent, void *container_parent, + struct wined3d_surface *surface, void **parent, const struct wined3d_parent_ops **parent_ops); + HRESULT (__cdecl *volume_created)(struct wined3d_device_parent *device_parent, void *container_parent, + struct wined3d_volume *volume, void **parent, const struct wined3d_parent_ops **parent_ops); HRESULT (__cdecl *create_swapchain_surface)(struct wined3d_device_parent *device_parent, void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface); - HRESULT (__cdecl *create_texture_surface)(struct wined3d_device_parent *device_parent, void *container_parent, - const struct wined3d_resource_desc *desc, UINT sub_resource_idx, DWORD flags, - struct wined3d_surface **surface); - HRESULT (__cdecl *create_volume)(struct wined3d_device_parent *device_parent, void *container_parent, - UINT width, UINT height, UINT depth, UINT level, enum wined3d_format_id format_id, - enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume); HRESULT (__cdecl *create_swapchain)(struct wined3d_device_parent *device_parent, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain); }; @@ -2236,12 +2226,10 @@ HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device, HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes); HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flags, - const PALETTEENTRY *entries, void *parent, struct wined3d_palette **palette); + unsigned int entry_count, const PALETTEENTRY *entries, struct wined3d_palette **palette); ULONG __cdecl wined3d_palette_decref(struct wined3d_palette *palette); HRESULT __cdecl wined3d_palette_get_entries(const struct wined3d_palette *palette, DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries); -DWORD __cdecl wined3d_palette_get_flags(const struct wined3d_palette *palette); -void * __cdecl wined3d_palette_get_parent(const struct wined3d_palette *palette); ULONG __cdecl wined3d_palette_incref(struct wined3d_palette *palette); HRESULT __cdecl wined3d_palette_set_entries(struct wined3d_palette *palette, DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries); @@ -2261,6 +2249,7 @@ void __cdecl wined3d_resource_get_desc(const struct wined3d_resource *resource, void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resource); HRESULT __cdecl wined3d_resource_get_private_data(const struct wined3d_resource *resource, REFGUID guid, void *data, DWORD *data_size); +void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent); HRESULT __cdecl wined3d_resource_set_private_data(struct wined3d_resource *resource, REFGUID guid, const void *data, DWORD data_size, DWORD flags); @@ -2303,12 +2292,7 @@ ULONG __cdecl wined3d_stateblock_incref(struct wined3d_stateblock *stateblock); HRESULT __cdecl wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const WINEDDBLTFX *blt_fx, enum wined3d_texture_filter_type filter); -HRESULT __cdecl wined3d_surface_create(struct wined3d_device *device, UINT width, UINT height, - enum wined3d_format_id format_id, DWORD usage, enum wined3d_pool pool, - enum wined3d_multisample_type multisample_type, DWORD multisample_quality, DWORD flags, - void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_surface **surface); ULONG __cdecl wined3d_surface_decref(struct wined3d_surface *surface); -HRESULT __cdecl wined3d_surface_flip(struct wined3d_surface *surface, struct wined3d_surface *override, DWORD flags); struct wined3d_surface * __cdecl wined3d_surface_from_resource(struct wined3d_resource *resource); HRESULT __cdecl wined3d_surface_get_blt_status(const struct wined3d_surface *surface, DWORD flags); HRESULT __cdecl wined3d_surface_get_flip_status(const struct wined3d_surface *surface, DWORD flags); @@ -2328,16 +2312,14 @@ HRESULT __cdecl wined3d_surface_map(struct wined3d_surface *surface, void __cdecl wined3d_surface_preload(struct wined3d_surface *surface); HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc); HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface); -HRESULT __cdecl wined3d_surface_set_color_key(struct wined3d_surface *surface, - DWORD flags, const struct wined3d_color_key *color_key); -HRESULT __cdecl wined3d_surface_set_mem(struct wined3d_surface *surface, void *mem, UINT pitch); HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y); void __cdecl wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette); DWORD __cdecl wined3d_surface_set_priority(struct wined3d_surface *surface, DWORD new_priority); HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface); HRESULT __cdecl wined3d_surface_update_desc(struct wined3d_surface *surface, UINT width, UINT height, enum wined3d_format_id format_id, - enum wined3d_multisample_type multisample_type, UINT multisample_quality); + enum wined3d_multisample_type multisample_type, UINT multisample_quality, + void *mem, UINT pitch); HRESULT __cdecl wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect, struct wined3d_surface *dst_surface, const RECT *dst_rect, DWORD flags, const WINEDDOVERLAYFX *fx); HRESULT __cdecl wined3d_surface_update_overlay_z_order(struct wined3d_surface *surface, @@ -2370,12 +2352,7 @@ void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, H HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture, UINT layer, const struct wined3d_box *dirty_region); -HRESULT __cdecl wined3d_texture_create_2d(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_texture **texture); -HRESULT __cdecl wined3d_texture_create_3d(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); -HRESULT __cdecl wined3d_texture_create_cube(struct wined3d_device *device, const struct wined3d_resource_desc *desc, +HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture); @@ -2392,6 +2369,8 @@ ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture); void __cdecl wined3d_texture_preload(struct wined3d_texture *texture); 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); DWORD __cdecl wined3d_texture_set_priority(struct wined3d_texture *texture, DWORD priority); @@ -2405,9 +2384,6 @@ ULONG __cdecl wined3d_vertex_declaration_decref(struct wined3d_vertex_declaratio void * __cdecl wined3d_vertex_declaration_get_parent(const struct wined3d_vertex_declaration *declaration); ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration *declaration); -HRESULT __cdecl wined3d_volume_create(struct wined3d_device *device, UINT width, UINT height, UINT depth, - UINT level, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent, - const struct wined3d_parent_ops *parent_ops, struct wined3d_volume **volume); ULONG __cdecl wined3d_volume_decref(struct wined3d_volume *volume); struct wined3d_volume * __cdecl wined3d_volume_from_resource(struct wined3d_resource *resource); void * __cdecl wined3d_volume_get_parent(const struct wined3d_volume *volume);