[DIRECT3D]

- Update d3d9, d3d8, ddraw and wined3d to wine 1.7.11
CORE-7796 CORE-7803 #resolve #comment Fixed with wine sync. Thanks.

svn path=/trunk/; revision=61843
This commit is contained in:
Jérôme Gardou 2014-01-26 20:53:31 +00:00
parent 518460d44c
commit 275f6e8360
52 changed files with 7050 additions and 6632 deletions

View file

@ -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;
}

View file

@ -35,7 +35,6 @@
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define COBJMACROS
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
@ -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

View file

@ -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,
};

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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))

View file

@ -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;
}

View file

@ -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));
}

View file

@ -35,7 +35,6 @@
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define COBJMACROS
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
@ -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 */

View file

@ -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,
};

View file

@ -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)

View file

@ -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,

View file

@ -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))

View file

@ -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;
}

View file

@ -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)

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma makedep register
[
helpstring("DirectDraw Object"),
threading(both),

View file

@ -26,7 +26,7 @@
#include <stdarg.h>
#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

View file

@ -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);

View file

@ -25,11 +25,10 @@
*/
#include "ddraw_private.h"
#include <winreg.h>
#include <rpcproxy.h>
#include <wine/exception.h>
#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;

View file

@ -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);

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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)
{

View file

@ -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 },
};

View file

@ -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)
{

View file

@ -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();

View file

@ -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);
}

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,8 @@
*/
#include "wined3d_private.h"
#include <winternl.h>
#include <winnls.h>
#include <wine/unicode.h>
@ -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;

View file

@ -29,9 +29,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
//#include <stdio.h>
//#include <math.h>
/* 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(&current_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy);
else
SetRectEmpty(&current_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;
}

View file

@ -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 *)&reg->immconst_data[0], imm_str[0]);
shader_glsl_ftoa(*(const float *)&reg->immconst_data[1], imm_str[1]);
shader_glsl_ftoa(*(const float *)&reg->immconst_data[2], imm_str[2]);
shader_glsl_ftoa(*(const float *)&reg->immconst_data[3], imm_str[3]);
wined3d_ftoa(*(const float *)&reg->immconst_data[0], imm_str[0]);
wined3d_ftoa(*(const float *)&reg->immconst_data[1], imm_str[1]);
wined3d_ftoa(*(const float *)&reg->immconst_data[2], imm_str[2]);
wined3d_ftoa(*(const float *)&reg->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 },

View file

@ -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 },

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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 <operation> 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 <operation> a1 <operation> 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 <operation> 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 <operation> a1 <operation> 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,

View file

@ -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)))

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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;
}

View file

@ -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());
}

View file

@ -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;

View file

@ -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)

View file

@ -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,

View file

@ -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))

View file

@ -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

View file

@ -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
*/

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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);