* Sync with Wine 1.7.1.
svn path=/trunk/; revision=60090
const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface)
{
struct wined3d_device_parent *device_parent;
+ struct wined3d_resource_desc surface_desc;
IWineDXGIDeviceParent *dxgi_device_parent;
HRESULT hr;
UINT i;
device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent);
FIXME("Implement DXGI<->wined3d usage conversion\n");
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
+ surface_desc.format = wined3dformat_from_dxgi_format(desc->Format);
+ surface_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE;
+ surface_desc.multisample_quality = desc->SampleDesc.Quality;
+ surface_desc.usage = usage;
+ surface_desc.pool = WINED3D_POOL_DEFAULT;
+ surface_desc.width = desc->Width;
+ surface_desc.height = desc->Height;
+ surface_desc.depth = 1;
+ surface_desc.size = 0;
memset(surface, 0, surface_count * sizeof(*surface));
for (i = 0; i < surface_count; ++i)
struct wined3d_surface *wined3d_surface;
IUnknown *parent;
- hr = device_parent->ops->create_swapchain_surface(device_parent, NULL,
- desc->Width, desc->Height, wined3dformat_from_dxgi_format(desc->Format), usage,
- desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE,
- desc->SampleDesc.Quality, &wined3d_surface);
- if (FAILED(hr))
+ if (FAILED(hr = device_parent->ops->create_swapchain_surface(device_parent,
+ NULL, &surface_desc, &wined3d_surface)))
{
- ERR("CreateSurface failed, returning %#x\n", hr);
+ ERR("Failed to create surface, hr %#x.\n", hr);
goto fail;
}
static void dxgi_main_cleanup(void)
{
- EnterCriticalSection(&dxgi_cs);
-
HeapFree(GetProcessHeap(), 0, dxgi_main.device_layers);
- dxgi_main.device_layers = NULL;
- dxgi_main.layer_count = 0;
-
FreeLibrary(dxgi_main.d3d10core);
- dxgi_main.d3d10core = NULL;
-
- LeaveCriticalSection(&dxgi_cs);
DeleteCriticalSection(&dxgi_cs);
}
break;
case DLL_PROCESS_DETACH:
+ if (lpv) break;
dxgi_main_cleanup();
break;
}
add_library(d3d8 SHARED ${SOURCE})
set_module_type(d3d8 win32dll UNICODE)
-target_link_libraries(d3d8 uuid wine)
-
-add_importlibs(d3d8
- user32
- gdi32
- advapi32
- wined3d
- msvcrt
- kernel32
- ntdll)
-
-add_dependencies(d3d8 wineheaders)
+target_link_libraries(d3d8 wine)
+add_importlibs(d3d8 wined3d msvcrt kernel32 ntdll)
add_pch(d3d8 d3d8_private.h)
add_cd_file(TARGET d3d8 DESTINATION reactos/system32 FOR all)
};
HRESULT volume_init(struct d3d8_volume *volume, struct d3d8_device *device, UINT width, UINT height,
- UINT depth, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool) DECLSPEC_HIDDEN;
+ UINT depth, UINT level, DWORD usage, enum wined3d_format_id format,
+ enum wined3d_pool pool) DECLSPEC_HIDDEN;
struct d3d8_swapchain
{
};
HRESULT surface_init(struct d3d8_surface *surface, struct d3d8_device *device, UINT width, UINT height,
- D3DFORMAT format, BOOL lockable, BOOL discard, DWORD usage, D3DPOOL pool,
- D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) DECLSPEC_HIDDEN;
+ D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
+ DWORD multisample_quality) DECLSPEC_HIDDEN;
struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN;
struct d3d8_vertexbuffer
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+static void STDMETHODCALLTYPE d3d8_null_wined3d_object_destroyed(void *parent) {}
+
+static const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops =
+{
+ d3d8_null_wined3d_object_destroyed,
+};
+
D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format)
{
BYTE *c = (BYTE *)&format;
{
struct d3d8_surface *surface;
+ if (desc.resource_type == WINED3D_RTYPE_TEXTURE)
+ {
+ IUnknown *parent = wined3d_resource_get_parent(resource);
+ IDirect3DBaseTexture8 *texture;
+
+ if (SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture8, (void **)&texture)))
+ {
+ IDirect3DBaseTexture8_Release(texture);
+ WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource);
+ return D3DERR_DEVICELOST;
+ }
+
+ return D3D_OK;
+ }
+
if (desc.resource_type != WINED3D_RTYPE_SURFACE)
{
WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
}
static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width, UINT height,
- D3DFORMAT format, BOOL lockable, BOOL discard, IDirect3DSurface8 **surface, UINT usage,
- D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
+ D3DFORMAT format, DWORD flags, IDirect3DSurface8 **surface, UINT usage, D3DPOOL pool,
+ D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
{
- struct d3d8_surface *object;
+ struct wined3d_resource *sub_resource;
+ struct wined3d_resource_desc desc;
+ struct d3d8_surface *surface_impl;
+ struct wined3d_texture *texture;
HRESULT hr;
- TRACE("device %p, width %u, height %u, format %#x, lockable %#x, discard %#x, surface %p,\n"
+ TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p,\n"
"\tusage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
- device, width, height, format, lockable, discard, surface,
+ device, width, height, format, flags, surface,
usage, pool, multisample_type, multisample_quality);
- if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
- {
- FIXME("Failed to allocate surface memory.\n");
- return D3DERR_OUTOFVIDEOMEMORY;
- }
+ desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = multisample_type;
+ desc.multisample_quality = multisample_quality;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = 1;
+ desc.size = 0;
+
+ wined3d_mutex_lock();
- if (FAILED(hr = surface_init(object, device, width, height, format, lockable,
- discard, usage, pool, multisample_type, multisample_quality)))
+ if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &desc,
+ 1, flags, NULL, &d3d8_null_wined3d_parent_ops, &texture)))
{
- WARN("Failed to initialize surface, hr %#x.\n", hr);
- HeapFree(GetProcessHeap(), 0, object);
+ wined3d_mutex_unlock();
+ WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- TRACE("Created surface %p.\n", object);
- *surface = &object->IDirect3DSurface8_iface;
+ sub_resource = wined3d_texture_get_sub_resource(texture, 0);
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ surface_impl->forwardReference = NULL;
+ surface_impl->parent_device = &device->IDirect3DDevice8_iface;
+ *surface = &surface_impl->IDirect3DSurface8_iface;
+ IDirect3DSurface8_AddRef(*surface);
+ wined3d_texture_decref(texture);
+
+ wined3d_mutex_unlock();
return D3D_OK;
}
IDirect3DSurface8 **surface)
{
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ DWORD flags = 0;
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);
- return d3d8_device_create_surface(device, width, height, format, lockable, FALSE,
- surface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, 0);
+ if (lockable)
+ flags |= WINED3D_SURFACE_MAPPABLE;
+
+ return d3d8_device_create_surface(device, width, height, format, flags, surface,
+ D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, 0);
}
static HRESULT WINAPI d3d8_device_CreateDepthStencilSurface(IDirect3DDevice8 *iface,
iface, width, height, format, multisample_type, surface);
/* TODO: Verify that Discard is false */
- return d3d8_device_create_surface(device, width, height, format, TRUE, FALSE,
+ return d3d8_device_create_surface(device, width, height, format, WINED3D_SURFACE_MAPPABLE,
surface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, 0);
}
TRACE("iface %p, width %u, height %u, format %#x, surface %p.\n",
iface, width, height, format, surface);
- return d3d8_device_create_surface(device, width, height, format, TRUE, FALSE,
+ return d3d8_device_create_surface(device, width, height, format, WINED3D_SURFACE_MAPPABLE,
surface, 0, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0);
}
return hr;
}
-static void STDMETHODCALLTYPE d3d8_null_wined3d_object_destroyed(void *parent) {}
-
-static const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops =
-{
- d3d8_null_wined3d_object_destroyed,
-};
-
/* The caller is responsible for wined3d locking */
static HRESULT d3d8_device_prepare_vertex_buffer(struct d3d8_device *device, UINT min_size)
{
}
static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, enum wined3d_format_id format, DWORD usage,
- enum wined3d_pool pool, UINT sub_resource_idx, struct wined3d_surface **surface)
+ void *container_parent, const struct wined3d_resource_desc *desc, UINT sub_resource_idx,
+ DWORD flags, struct wined3d_surface **surface)
{
struct d3d8_device *device = device_from_device_parent(device_parent);
struct d3d8_surface *d3d_surface;
- BOOL lockable = TRUE;
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, usage %#x,\n"
- "\tpool %#x, sub_resource_idx %u, surface %p.\n",
- device_parent, container_parent, width, height, format, usage, pool, sub_resource_idx, surface);
-
+ 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);
- if (pool == WINED3D_POOL_DEFAULT && !(usage & WINED3DUSAGE_DYNAMIC))
- lockable = FALSE;
+ if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
+ {
+ FIXME("Failed to allocate surface memory.\n");
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
- if (FAILED(hr = d3d8_device_create_surface(device, width, height, d3dformat_from_wined3dformat(format),
- lockable, FALSE, (IDirect3DSurface8 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0)))
+ 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 create surface, hr %#x.\n", hr);
+ WARN("Failed to initialize surface, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, d3d_surface);
return hr;
}
+ TRACE("Created surface %p.\n", d3d_surface);
+
*surface = d3d_surface->wined3d_surface;
wined3d_surface_incref(*surface);
}
static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, enum wined3d_format_id format_id, DWORD usage,
- enum wined3d_multisample_type multisample_type, DWORD multisample_quality, struct wined3d_surface **surface)
+ void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface)
{
struct d3d8_device *device = device_from_device_parent(device_parent);
+ struct wined3d_resource_desc texture_desc;
struct d3d8_surface *d3d_surface;
+ struct wined3d_texture *texture;
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, width %u, height %u, format_id %#x, usage %#x,\n"
- "\tmultisample_type %#x, multisample_quality %u, surface %p.\n",
- device_parent, container_parent, width, height, format_id, usage,
- multisample_type, multisample_quality, surface);
+ TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n",
+ device_parent, container_parent, desc, surface);
- if (FAILED(hr = d3d8_device_create_surface(device, width, height, d3dformat_from_wined3dformat(format_id),
- TRUE, FALSE, (IDirect3DSurface8 **)&d3d_surface, usage, D3DPOOL_DEFAULT, multisample_type,
- multisample_quality)))
+ texture_desc = *desc;
+ texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &texture_desc, 1,
+ WINED3D_SURFACE_MAPPABLE, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture)))
{
- WARN("Failed to create surface, hr %#x.\n", hr);
+ WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- *surface = d3d_surface->wined3d_surface;
+ *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
wined3d_surface_incref(*surface);
+ wined3d_texture_decref(texture);
- d3d_surface->container = (IUnknown *)&device->IDirect3DDevice8_iface;
- /* Implicit surfaces are created with an refcount of 0 */
- IDirect3DSurface8_Release(&d3d_surface->IDirect3DSurface8_iface);
+ d3d_surface = wined3d_surface_get_parent(*surface);
+ d3d_surface->forwardReference = NULL;
+ d3d_surface->parent_device = &device->IDirect3DDevice8_iface;
return hr;
}
static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, UINT depth, enum wined3d_format_id format,
- enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume)
+ 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;
return D3DERR_OUTOFVIDEOMEMORY;
}
- hr = volume_init(object, device, width, height, depth, usage, format, pool);
+ hr = volume_init(object, device, width, height, depth, level, usage, format, pool);
if (FAILED(hr))
{
WARN("Failed to initialize volume, hr %#x.\n", hr);
BOOL d3d8_init(struct d3d8 *d3d8)
{
+ DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING;
+
d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
d3d8->refcount = 1;
wined3d_mutex_lock();
- d3d8->wined3d = wined3d_create(8, WINED3D_LEGACY_DEPTH_BIAS);
+ d3d8->wined3d = wined3d_create(8, flags);
wined3d_mutex_unlock();
if (!d3d8->wined3d)
return FALSE;
};
HRESULT surface_init(struct d3d8_surface *surface, struct d3d8_device *device, UINT width, UINT height,
- D3DFORMAT format, BOOL lockable, BOOL discard, DWORD usage, D3DPOOL pool,
- D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
+ D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
+ DWORD multisample_quality)
{
- DWORD flags = 0;
HRESULT hr;
surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl;
multisample_quality = 0;
}
- if (lockable)
- flags |= WINED3D_SURFACE_MAPPABLE;
- if (discard)
- flags |= WINED3D_SURFACE_DISCARD;
-
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,
{
if (!iface)
return NULL;
- assert(iface->lpVtbl == (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl
- || iface->lpVtbl == (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl
- || iface->lpVtbl == (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl);
+
+ /* SetTexture() in particular doesn't do a lot of validation on the pointer
+ * that gets passed in, and passing an invalid pointer works as long as the
+ * application doesn't try to actually render anything with it, so we print
+ * a WARN and return NULL instead of having the usual assert() here.
+ * One application affected by this is Fishdom 2. */
+ if (iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl
+ && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl
+ && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl)
+ {
+ WARN("%p is not a valid IDirect3DBaseTexture8 interface.\n", iface);
+ return NULL;
+ }
+
return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
}
HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
+ struct wined3d_resource_desc desc;
+ DWORD surface_flags = 0;
HRESULT hr;
texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl;
texture->refcount = 1;
+ desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = 1;
+ desc.size = 0;
+
+ if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
+ surface_flags |= WINED3D_SURFACE_MAPPABLE;
+
wined3d_mutex_lock();
- hr = wined3d_texture_create_2d(device->wined3d_device, width, height, levels,
- usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool,
+ hr = wined3d_texture_create_2d(device->wined3d_device, &desc, levels, surface_flags,
texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
+ struct wined3d_resource_desc desc;
+ DWORD surface_flags = 0;
HRESULT hr;
texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl;
texture->refcount = 1;
+ desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = edge_length;
+ desc.height = edge_length;
+ desc.depth = 1;
+ desc.size = 0;
+
+ if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
+ surface_flags |= WINED3D_SURFACE_MAPPABLE;
+
wined3d_mutex_lock();
- hr = wined3d_texture_create_cube(device->wined3d_device, edge_length, levels,
- usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture,
- &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
+ hr = wined3d_texture_create_cube(device->wined3d_device, &desc, levels, surface_flags,
+ texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{
HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
+ struct wined3d_resource_desc desc;
HRESULT hr;
texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl;
texture->refcount = 1;
+ desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = depth;
+ desc.size = 0;
+
wined3d_mutex_lock();
- hr = wined3d_texture_create_3d(device->wined3d_device, width, height, depth, levels,
- usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture,
- &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
+ hr = wined3d_texture_create_3d(device->wined3d_device, &desc, levels,
+ texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{
};
HRESULT volume_init(struct d3d8_volume *volume, struct d3d8_device *device, UINT width, UINT height,
- UINT depth, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool)
+ UINT depth, UINT level, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool)
{
HRESULT hr;
volume->IDirect3DVolume8_iface.lpVtbl = &d3d8_volume_vtbl;
volume->refcount = 1;
- hr = wined3d_volume_create(device->wined3d_device, width, height, depth, usage,
+ 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))
{
add_library(d3d9 SHARED ${SOURCE})
set_module_type(d3d9 win32dll UNICODE)
-target_link_libraries(d3d9 uuid wine)
-
-add_importlibs(d3d9
- user32
- gdi32
- advapi32
- wined3d
- msvcrt
- kernel32
- ntdll)
-
-add_dependencies(d3d9 wineheaders)
+target_link_libraries(d3d9 wine)
+add_importlibs(d3d9 wined3d msvcrt kernel32 ntdll)
add_pch(d3d9 d3d9_private.h)
add_cd_file(TARGET d3d9 DESTINATION reactos/system32 FOR all)
};
HRESULT volume_init(struct d3d9_volume *volume, struct d3d9_device *device, UINT width, UINT height,
- UINT depth, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool) DECLSPEC_HIDDEN;
+ UINT depth, UINT level, DWORD usage, enum wined3d_format_id format,
+ enum wined3d_pool pool) DECLSPEC_HIDDEN;
struct d3d9_swapchain
{
};
HRESULT surface_init(struct d3d9_surface *surface, struct d3d9_device *device, UINT width, UINT height,
- D3DFORMAT format, BOOL lockable, BOOL discard, DWORD usage, D3DPOOL pool,
- D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) DECLSPEC_HIDDEN;
+ D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
+ DWORD multisample_quality) DECLSPEC_HIDDEN;
struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) DECLSPEC_HIDDEN;
struct d3d9_vertexbuffer
WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {}
+
+static const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops =
+{
+ d3d9_null_wined3d_object_destroyed,
+};
+
D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format)
{
BYTE *c = (BYTE *)&format;
{
struct d3d9_surface *surface;
+ if (desc.resource_type == WINED3D_RTYPE_TEXTURE)
+ {
+ IUnknown *parent = wined3d_resource_get_parent(resource);
+ IDirect3DBaseTexture9 *texture;
+
+ if (SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture9, (void **)&texture)))
+ {
+ IDirect3DBaseTexture9_Release(texture);
+ WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource);
+ return D3DERR_INVALIDCALL;
+ }
+
+ return D3D_OK;
+ }
+
if (desc.resource_type != WINED3D_RTYPE_SURFACE)
{
WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
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);
+ wined3d_surface_set_mem(surface->wined3d_surface, *shared_handle, 0);
}
TRACE("Created texture %p.\n", object);
}
static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width, UINT height,
- D3DFORMAT format, BOOL lockable, BOOL discard, IDirect3DSurface9 **surface, UINT usage,
- D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
+ D3DFORMAT format, DWORD flags, IDirect3DSurface9 **surface, UINT usage, D3DPOOL pool,
+ D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
{
- struct d3d9_surface *object;
+ struct wined3d_resource *sub_resource;
+ struct wined3d_resource_desc desc;
+ struct d3d9_surface *surface_impl;
+ struct wined3d_texture *texture;
HRESULT hr;
- TRACE("device %p, width %u, height %u, format %#x, lockable %#x, discard %#x, surface %p.\n"
+ TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p.\n"
"usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
- device, width, height, format, lockable, discard, surface, usage, pool,
+ device, width, height, format, flags, surface, usage, pool,
multisample_type, multisample_quality);
- if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
- {
- FIXME("Failed to allocate surface memory.\n");
- return D3DERR_OUTOFVIDEOMEMORY;
- }
+ desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = multisample_type;
+ desc.multisample_quality = multisample_quality;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = 1;
+ desc.size = 0;
+
+ wined3d_mutex_lock();
- if (FAILED(hr = surface_init(object, device, width, height, format, lockable,
- discard, usage, pool, multisample_type, multisample_quality)))
+ if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &desc,
+ 1, flags, NULL, &d3d9_null_wined3d_parent_ops, &texture)))
{
- WARN("Failed to initialize surface, hr %#x.\n", hr);
- HeapFree(GetProcessHeap(), 0, object);
+ wined3d_mutex_unlock();
+ WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- TRACE("Created surface %p.\n", object);
- *surface = &object->IDirect3DSurface9_iface;
+ sub_resource = wined3d_texture_get_sub_resource(texture, 0);
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ surface_impl->forwardReference = NULL;
+ surface_impl->parent_device = &device->IDirect3DDevice9Ex_iface;
+ *surface = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*surface);
+ wined3d_texture_decref(texture);
+
+ wined3d_mutex_unlock();
return D3D_OK;
}
BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ DWORD flags = 0;
TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
"lockable %#x, surface %p, shared_handle %p.\n",
if (shared_handle)
FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
- return d3d9_device_create_surface(device, width, height, format, lockable, FALSE, surface,
+ 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);
}
BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ DWORD flags = WINED3D_SURFACE_MAPPABLE;
TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
"discard %#x, surface %p, shared_handle %p.\n",
if (shared_handle)
FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
- return d3d9_device_create_surface(device, width, height, format, TRUE, discard, surface,
+ 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);
}
/* 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, TRUE,
- FALSE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0);
+ return d3d9_device_create_surface(device, width, height, format,
+ WINED3D_SURFACE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0);
}
static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 *surface)
return hr;
}
-static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {}
-
-static const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops =
-{
- d3d9_null_wined3d_object_destroyed,
-};
-
/* The caller is responsible for wined3d locking */
static HRESULT d3d9_device_prepare_vertex_buffer(struct d3d9_device *device, UINT min_size)
{
}
static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, enum wined3d_format_id format, DWORD usage,
- enum wined3d_pool pool, UINT sub_resource_idx, struct wined3d_surface **surface)
+ void *container_parent, const struct wined3d_resource_desc *desc, UINT sub_resource_idx,
+ DWORD flags, struct wined3d_surface **surface)
{
struct d3d9_device *device = device_from_device_parent(device_parent);
struct d3d9_surface *d3d_surface;
- BOOL lockable = TRUE;
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, usage %#x,\n"
- "\tpool %#x, sub_resource_idx %u, surface %p.\n",
- device_parent, container_parent, width, height, format, usage, pool, sub_resource_idx, surface);
+ 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);
- if (pool == WINED3D_POOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC))
- lockable = FALSE;
+ if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
+ {
+ FIXME("Failed to allocate surface memory.\n");
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
- if (FAILED(hr = d3d9_device_create_surface(device, width, height, d3dformat_from_wined3dformat(format),
- lockable, FALSE, (IDirect3DSurface9 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0)))
+ 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 create surface, hr %#x.\n", hr);
+ WARN("Failed to initialize surface, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, d3d_surface);
return hr;
}
+ TRACE("Created surface %p.\n", d3d_surface);
+
*surface = d3d_surface->wined3d_surface;
wined3d_surface_incref(*surface);
}
static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, enum wined3d_format_id format_id, DWORD usage,
- enum wined3d_multisample_type multisample_type, DWORD multisample_quality, struct wined3d_surface **surface)
+ void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface)
{
struct d3d9_device *device = device_from_device_parent(device_parent);
+ struct wined3d_resource_desc texture_desc;
struct d3d9_surface *d3d_surface;
+ struct wined3d_texture *texture;
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, width %u, height %u, format_id %#x, usage %#x,\n"
- "\tmultisample_type %#x, multisample_quality %u, surface %p.\n",
- device_parent, container_parent, width, height, format_id, usage,
- multisample_type, multisample_quality, surface);
+ TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n",
+ device_parent, container_parent, desc, surface);
- if (FAILED(hr = d3d9_device_create_surface(device, width, height, d3dformat_from_wined3dformat(format_id),
- TRUE, FALSE, (IDirect3DSurface9 **)&d3d_surface, usage, D3DPOOL_DEFAULT, multisample_type,
- multisample_quality)))
+ if (container_parent == device_parent)
+ container_parent = &device->IDirect3DDevice9Ex_iface;
+
+ texture_desc = *desc;
+ texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &texture_desc, 1,
+ WINED3D_SURFACE_MAPPABLE, container_parent, &d3d9_null_wined3d_parent_ops, &texture)))
{
- WARN("Failed to create surface, hr %#x.\n", hr);
+ WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- *surface = d3d_surface->wined3d_surface;
+ *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
wined3d_surface_incref(*surface);
+ wined3d_texture_decref(texture);
- if (container_parent == device_parent)
- d3d_surface->container = (IUnknown *)&device->IDirect3DDevice9Ex_iface;
- else
- d3d_surface->container = container_parent;
- /* Implicit surfaces are created with an refcount of 0 */
- IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface);
+ d3d_surface = wined3d_surface_get_parent(*surface);
+ d3d_surface->forwardReference = NULL;
+ d3d_surface->parent_device = &device->IDirect3DDevice9Ex_iface;
return hr;
}
static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, UINT depth, enum wined3d_format_id format,
- enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume)
+ 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;
return D3DERR_OUTOFVIDEOMEMORY;
}
- hr = volume_init(object, device, width, height, depth, usage, format, pool);
+ hr = volume_init(object, device, width, height, depth, level, usage, format, pool);
if (FAILED(hr))
{
WARN("Failed to initialize volume, hr %#x.\n", hr);
BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
{
+ DWORD flags = extended ? 0 : WINED3D_VIDMEM_ACCOUNTING;
d3d9->IDirect3D9Ex_iface.lpVtbl = &d3d9_vtbl;
d3d9->refcount = 1;
wined3d_mutex_lock();
- d3d9->wined3d = wined3d_create(9, 0);
+ d3d9->wined3d = wined3d_create(9, flags);
wined3d_mutex_unlock();
if (!d3d9->wined3d)
return FALSE;
};
HRESULT surface_init(struct d3d9_surface *surface, struct d3d9_device *device, UINT width, UINT height,
- D3DFORMAT format, BOOL lockable, BOOL discard, DWORD usage, D3DPOOL pool,
- D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
+ D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
+ DWORD multisample_quality)
{
- DWORD flags = 0;
HRESULT hr;
surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl;
multisample_quality = 0;
}
- if (lockable)
- flags |= WINED3D_SURFACE_MAPPABLE;
- if (discard)
- flags |= WINED3D_SURFACE_DISCARD;
-
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,
HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
+ struct wined3d_resource_desc desc;
+ DWORD surface_flags = 0;
HRESULT hr;
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
texture->refcount = 1;
+ desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = 1;
+ desc.size = 0;
+
+ if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
+ surface_flags |= WINED3D_SURFACE_MAPPABLE;
+
wined3d_mutex_lock();
- hr = wined3d_texture_create_2d(device->wined3d_device, width, height, levels,
- usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool,
+ hr = wined3d_texture_create_2d(device->wined3d_device, &desc, levels, surface_flags,
texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
+ struct wined3d_resource_desc desc;
+ DWORD surface_flags = 0;
HRESULT hr;
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
texture->refcount = 1;
+ desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = edge_length;
+ desc.height = edge_length;
+ desc.depth = 1;
+ desc.size = 0;
+
+ if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
+ surface_flags |= WINED3D_SURFACE_MAPPABLE;
+
wined3d_mutex_lock();
- hr = wined3d_texture_create_cube(device->wined3d_device, edge_length,
- levels, usage, wined3dformat_from_d3dformat(format), pool, texture,
- &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
+ hr = wined3d_texture_create_cube(device->wined3d_device, &desc, levels, surface_flags,
+ texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{
HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
+ struct wined3d_resource_desc desc;
HRESULT hr;
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
texture->refcount = 1;
+ desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = depth;
+ desc.size = 0;
+
wined3d_mutex_lock();
- hr = wined3d_texture_create_3d(device->wined3d_device, width, height, depth, levels,
- usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture,
- &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
+ hr = wined3d_texture_create_3d(device->wined3d_device, &desc, levels,
+ texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{
};
HRESULT volume_init(struct d3d9_volume *volume, struct d3d9_device *device, UINT width, UINT height,
- UINT depth, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool)
+ UINT depth, UINT level, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool)
{
HRESULT hr;
volume->IDirect3DVolume9_iface.lpVtbl = &d3d9_volume_vtbl;
volume->refcount = 1;
- hr = wined3d_volume_create(device->wined3d_device, width, height, depth, usage & WINED3DUSAGE_MASK,
- format, pool, volume, &d3d9_volume_wined3d_parent_ops, &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);
main.c
material.c
palette.c
- stubs.c
surface.c
utils.c
vertexbuffer.c
${CMAKE_CURRENT_BINARY_DIR}/ddraw_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/ddraw.def)
-add_library(ddraw SHARED
- ${SOURCE}
- ddraw.rc)
-
if(MSVC)
# FIXME: http://www.cmake.org/Bug/view.php?id=12998
#add_target_compile_flags(ddraw "/FIwine/typeof.h")
set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/FIwine/typeof.h")
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)
-
+target_link_libraries(ddraw wine uuid dxguid ${PSEH_LIB})
+add_importlibs(ddraw advapi32 gdi32 ole32 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)
* Copyright 2000-2001 TransGaming Technologies Inc.
* Copyright 2006 Stefan Dösinger
* Copyright 2008 Denver Gingerich
+ * Copyright 2007-2008, 2011, 2013 Stefan Dösinger for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
wined3d_swapchain_decref(ddraw->wined3d_swapchain);
ddraw->wined3d_swapchain = NULL;
- if (DefaultSurfaceType == DDRAW_SURFACE_TYPE_OPENGL)
+ if (!(ddraw->flags & DDRAW_NO3D))
{
UINT i;
}
}
- ddraw->d3d_initialized = FALSE;
+ ddraw->flags &= ~DDRAW_D3D_INITIALIZED;
}
else
{
/* Set this NOW, otherwise creating the depth stencil surface will cause a
* recursive loop until ram or emulated video memory is full. */
- ddraw->d3d_initialized = TRUE;
+ ddraw->flags |= DDRAW_D3D_INITIALIZED;
hr = wined3d_device_init_3d(ddraw->wined3d_device, swapchain_desc);
if (FAILED(hr))
{
- ddraw->d3d_initialized = FALSE;
+ ddraw->flags &= ~DDRAW_D3D_INITIALIZED;
return hr;
}
swapchain_desc.device_window = window;
swapchain_desc.windowed = windowed;
- if (DefaultSurfaceType == DDRAW_SURFACE_TYPE_OPENGL)
+ if (!(ddraw->flags & DDRAW_NO3D))
hr = ddraw_attach_d3d_device(ddraw, &swapchain_desc);
else
hr = wined3d_device_init_gdi(ddraw->wined3d_device, &swapchain_desc);
return DD_OK;
}
+/*****************************************************************************
+ * IDirectDraw7::RestoreDisplayMode
+ *
+ * Restores the display mode to what it was at creation time. Basically.
+ *
+ * Returns
+ * DD_OK on success
+ * DDERR_NOEXCLUSIVE mode if the device isn't in fullscreen mode
+ *
+ *****************************************************************************/
+static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface)
+{
+ struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+
+ if (!(ddraw->flags & DDRAW_RESTORE_MODE))
+ {
+ wined3d_mutex_unlock();
+ return DD_OK;
+ }
+
+ if (exclusive_ddraw && exclusive_ddraw != ddraw)
+ {
+ wined3d_mutex_unlock();
+ return DDERR_NOEXCLUSIVEMODE;
+ }
+
+ if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &original_mode)))
+ {
+ ddraw->flags &= ~DDRAW_RESTORE_MODE;
+ restore_mode = FALSE;
+ }
+
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI ddraw4_RestoreDisplayMode(IDirectDraw4 *iface)
+{
+ struct ddraw *ddraw = impl_from_IDirectDraw4(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface);
+}
+
+static HRESULT WINAPI ddraw2_RestoreDisplayMode(IDirectDraw2 *iface)
+{
+ struct ddraw *ddraw = impl_from_IDirectDraw2(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface);
+}
+
+static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface)
+{
+ struct ddraw *ddraw = impl_from_IDirectDraw(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface);
+}
+
/*****************************************************************************
* IDirectDraw7::SetCooperativeLevel
*
* fixme, be sure to run again with a +ddraw trace.
*
* What is known about cooperative levels (See the ddraw modes test):
- * DDSCL_EXCLUSIVE and DDSCL_FULLSCREEN must be used with each other
- * DDSCL_NORMAL is not compatible with DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN
+ * DDSCL_EXCLUSIVE requires DDSCL_FULLSCREEN.
+ * DDSCL_NORMAL is not compatible with DDSCL_EXCLUSIVE.
+ * Unlike what msdn claims, DDSCL_NORMAL | DDSCL_FULLSCREEN is allowed.
* DDSCL_SETFOCUSWINDOW can be passed only in DDSCL_NORMAL mode, but after that
- * DDSCL_FULLSCREEN can be activated
- * DDSCL_SETFOCUSWINDOW may only be used with DDSCL_NOWINDOWCHANGES
+ * DDSCL_EXCLUSIVE can be activated.
+ * DDSCL_SETFOCUSWINDOW may only be used with DDSCL_NOWINDOWCHANGES or
+ * DDSCL_CREATEDEVICEWINDOW.
*
* Handled flags: DDSCL_NORMAL, DDSCL_FULLSCREEN, DDSCL_EXCLUSIVE,
+ * DDSCL_CREATEDEVICEWINDOW, DDSCL_SETDEVICEWINDOW
* DDSCL_SETFOCUSWINDOW (partially),
* DDSCL_MULTITHREADED (work in progress)
+ * DDSCL_FPUPRESERVE (see device.c)
*
- * Unhandled flags, which should be implemented
- * DDSCL_SETDEVICEWINDOW: Sets a window specially used for rendering (I don't
- * expect any difference to a normal window for wine)
- * DDSCL_CREATEDEVICEWINDOW: Tells ddraw to create its own window for
- * rendering (Possible test case: Half-Life)
- *
- * Unsure about these: DDSCL_FPUSETUP DDSCL_FPURESERVE
+ * Unsure about this: DDSCL_FPUSETUP
*
* These don't seem very important for wine:
* DDSCL_ALLOWREBOOT, DDSCL_NOWINDOWCHANGES, DDSCL_ALLOWMODEX
* (Probably others too, have to investigate)
*
*****************************************************************************/
-static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND window, DWORD cooplevel)
+static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
+ DWORD cooplevel, BOOL restore_mode_on_normal)
{
- struct ddraw *This = impl_from_IDirectDraw7(iface);
struct wined3d_surface *rt = NULL, *ds = NULL;
struct wined3d_stateblock *stateblock;
BOOL restore_state = FALSE;
HRESULT hr;
- TRACE("iface %p, window %p, flags %#x.\n", iface, window, cooplevel);
+ TRACE("ddraw %p, window %p, flags %#x, restore_mode_on_normal %x.\n", ddraw, window, cooplevel,
+ restore_mode_on_normal);
DDRAW_dump_cooperativelevel(cooplevel);
wined3d_mutex_lock();
return DDERR_INVALIDPARAMS;
}
- hr = ddraw_set_focus_window(This, window);
+ hr = ddraw_set_focus_window(ddraw, window);
wined3d_mutex_unlock();
return hr;
}
{
HWND device_window;
- if (!This->focuswindow && !(cooplevel & DDSCL_SETFOCUSWINDOW))
+ if (!ddraw->focuswindow && !(cooplevel & DDSCL_SETFOCUSWINDOW))
{
WARN("No focus window set.\n");
wined3d_mutex_unlock();
/* Native apparently leaks the created device window if setting the
* focus window below fails. */
- This->cooperative_level |= DDSCL_CREATEDEVICEWINDOW;
- This->devicewindow = device_window;
+ ddraw->cooperative_level |= DDSCL_CREATEDEVICEWINDOW;
+ ddraw->devicewindow = device_window;
if (cooplevel & DDSCL_SETFOCUSWINDOW)
{
return DDERR_NOHWND;
}
- if (FAILED(hr = ddraw_set_focus_window(This, window)))
+ if (FAILED(hr = ddraw_set_focus_window(ddraw, window)))
{
wined3d_mutex_unlock();
return hr;
}
else
{
- if (This->cooperative_level & DDSCL_CREATEDEVICEWINDOW)
- DestroyWindow(This->devicewindow);
- This->devicewindow = NULL;
- This->focuswindow = NULL;
+ if (ddraw->cooperative_level & DDSCL_CREATEDEVICEWINDOW)
+ DestroyWindow(ddraw->devicewindow);
+ ddraw->devicewindow = NULL;
+ ddraw->focuswindow = NULL;
}
- if ((This->cooperative_level & DDSCL_EXCLUSIVE)
- && (window != This->dest_window || !(cooplevel & DDSCL_EXCLUSIVE)))
- wined3d_device_release_focus_window(This->wined3d_device);
-
- if ((cooplevel & DDSCL_FULLSCREEN) != (This->cooperative_level & DDSCL_FULLSCREEN) || window != This->dest_window)
+ if ((cooplevel & DDSCL_FULLSCREEN) != (ddraw->cooperative_level & DDSCL_FULLSCREEN) || window != ddraw->dest_window)
{
- if (This->cooperative_level & DDSCL_FULLSCREEN)
- wined3d_device_restore_fullscreen_window(This->wined3d_device, This->dest_window);
+ if (ddraw->cooperative_level & DDSCL_FULLSCREEN)
+ wined3d_device_restore_fullscreen_window(ddraw->wined3d_device, ddraw->dest_window);
if (cooplevel & DDSCL_FULLSCREEN)
{
struct wined3d_display_mode display_mode;
- wined3d_get_adapter_display_mode(This->wined3d, WINED3DADAPTER_DEFAULT, &display_mode, NULL);
- wined3d_device_setup_fullscreen_window(This->wined3d_device, window,
+ wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &display_mode, NULL);
+ wined3d_device_setup_fullscreen_window(ddraw->wined3d_device, window,
display_mode.width, display_mode.height);
}
}
- if ((cooplevel & DDSCL_EXCLUSIVE)
- && (window != This->dest_window || !(This->cooperative_level & DDSCL_EXCLUSIVE)))
- {
- hr = wined3d_device_acquire_focus_window(This->wined3d_device, window);
- if (FAILED(hr))
- {
- ERR("Failed to acquire focus window, hr %#x.\n", hr);
- wined3d_mutex_unlock();
- return hr;
- }
- }
-
- if (cooplevel & DDSCL_MULTITHREADED && !(This->cooperative_level & DDSCL_MULTITHREADED))
- wined3d_device_set_multithreaded(This->wined3d_device);
+ if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED))
+ wined3d_device_set_multithreaded(ddraw->wined3d_device);
- if (This->wined3d_swapchain)
+ if (ddraw->wined3d_swapchain)
{
- if (DefaultSurfaceType != DDRAW_SURFACE_TYPE_GDI)
+ if (!(ddraw->flags & DDRAW_NO3D))
{
restore_state = TRUE;
- if (FAILED(hr = wined3d_stateblock_create(This->wined3d_device, WINED3D_SBT_ALL, &stateblock)))
+ if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, WINED3D_SBT_ALL, &stateblock)))
{
ERR("Failed to create stateblock, hr %#x.\n", hr);
wined3d_mutex_unlock();
}
wined3d_stateblock_capture(stateblock);
- rt = wined3d_device_get_render_target(This->wined3d_device, 0);
- if (rt == This->wined3d_frontbuffer)
+ rt = wined3d_device_get_render_target(ddraw->wined3d_device, 0);
+ if (rt == ddraw->wined3d_frontbuffer)
rt = NULL;
else if (rt)
wined3d_surface_incref(rt);
- if ((ds = wined3d_device_get_depth_stencil(This->wined3d_device)))
+ if ((ds = wined3d_device_get_depth_stencil(ddraw->wined3d_device)))
wined3d_surface_incref(ds);
}
- ddraw_destroy_swapchain(This);
+ ddraw_destroy_swapchain(ddraw);
}
- if (FAILED(hr = ddraw_create_swapchain(This, window, !(cooplevel & DDSCL_FULLSCREEN))))
+ if (FAILED(hr = ddraw_create_swapchain(ddraw, window, !(cooplevel & DDSCL_FULLSCREEN))))
ERR("Failed to create swapchain, hr %#x.\n", hr);
if (restore_state)
{
if (ds)
{
- wined3d_device_set_depth_stencil(This->wined3d_device, ds);
+ wined3d_device_set_depth_stencil(ddraw->wined3d_device, ds);
wined3d_surface_decref(ds);
}
if (rt)
{
- wined3d_device_set_render_target(This->wined3d_device, 0, rt, FALSE);
+ wined3d_device_set_render_target(ddraw->wined3d_device, 0, rt, FALSE);
wined3d_surface_decref(rt);
}
wined3d_stateblock_decref(stateblock);
}
+ if (!(cooplevel & DDSCL_EXCLUSIVE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE)
+ && restore_mode_on_normal)
+ {
+ hr = ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface);
+ if (FAILED(hr))
+ ERR("RestoreDisplayMode failed\n");
+ }
+
+ if ((ddraw->cooperative_level & DDSCL_EXCLUSIVE)
+ && (window != ddraw->dest_window || !(cooplevel & DDSCL_EXCLUSIVE)))
+ wined3d_device_release_focus_window(ddraw->wined3d_device);
+
+ if ((cooplevel & DDSCL_EXCLUSIVE)
+ && (window != ddraw->dest_window || !(ddraw->cooperative_level & DDSCL_EXCLUSIVE)))
+ {
+ hr = wined3d_device_acquire_focus_window(ddraw->wined3d_device, window);
+ if (FAILED(hr))
+ {
+ ERR("Failed to acquire focus window, hr %#x.\n", hr);
+ wined3d_mutex_unlock();
+ return hr;
+ }
+ }
+
/* Unhandled flags */
- if(cooplevel & DDSCL_ALLOWREBOOT)
- WARN("(%p) Unhandled flag DDSCL_ALLOWREBOOT, harmless\n", This);
- if(cooplevel & DDSCL_ALLOWMODEX)
- WARN("(%p) Unhandled flag DDSCL_ALLOWMODEX, harmless\n", This);
- if(cooplevel & DDSCL_FPUSETUP)
- WARN("(%p) Unhandled flag DDSCL_FPUSETUP, harmless\n", This);
+ if (cooplevel & DDSCL_ALLOWREBOOT)
+ WARN("Unhandled flag DDSCL_ALLOWREBOOT, harmless\n");
+ if (cooplevel & DDSCL_ALLOWMODEX)
+ WARN("Unhandled flag DDSCL_ALLOWMODEX, harmless\n");
+ if (cooplevel & DDSCL_FPUSETUP)
+ WARN("Unhandled flag DDSCL_FPUSETUP, harmless\n");
if (cooplevel & DDSCL_EXCLUSIVE)
- exclusive_ddraw = This;
- else if (exclusive_ddraw == This)
+ exclusive_ddraw = ddraw;
+ else if (exclusive_ddraw == ddraw)
exclusive_ddraw = NULL;
/* Store the cooperative_level */
- This->cooperative_level = cooplevel;
- This->dest_window = window;
+ ddraw->cooperative_level = cooplevel;
+ ddraw->dest_window = window;
+
TRACE("SetCooperativeLevel retuning DD_OK\n");
wined3d_mutex_unlock();
return DD_OK;
}
+static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND window, DWORD flags)
+{
+ struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
+
+ TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
+
+ return ddraw_set_cooperative_level(ddraw, window, flags, !(ddraw->flags & DDRAW_SCL_DDRAW1));
+}
+
static HRESULT WINAPI ddraw4_SetCooperativeLevel(IDirectDraw4 *iface, HWND window, DWORD flags)
{
struct ddraw *ddraw = impl_from_IDirectDraw4(iface);
TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
- return ddraw7_SetCooperativeLevel(&ddraw->IDirectDraw7_iface, window, flags);
+ return ddraw_set_cooperative_level(ddraw, window, flags, !(ddraw->flags & DDRAW_SCL_DDRAW1));
}
static HRESULT WINAPI ddraw2_SetCooperativeLevel(IDirectDraw2 *iface, HWND window, DWORD flags)
TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
- return ddraw7_SetCooperativeLevel(&ddraw->IDirectDraw7_iface, window, flags);
+ return ddraw_set_cooperative_level(ddraw, window, flags, !(ddraw->flags & DDRAW_SCL_DDRAW1));
}
static HRESULT WINAPI ddraw1_SetCooperativeLevel(IDirectDraw *iface, HWND window, DWORD flags)
{
struct ddraw *ddraw = impl_from_IDirectDraw(iface);
+ HRESULT hr;
TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
- return ddraw7_SetCooperativeLevel(&ddraw->IDirectDraw7_iface, window, flags);
+ hr = ddraw_set_cooperative_level(ddraw, window, flags, FALSE);
+ if (SUCCEEDED(hr))
+ ddraw->flags |= DDRAW_SCL_DDRAW1;
+ return hr;
}
/*****************************************************************************
/* TODO: Lose the primary surface. */
if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
{
- ddraw->restore_mode = TRUE;
+ ddraw->flags |= DDRAW_RESTORE_MODE;
restore_mode = TRUE;
}
return ddraw7_SetDisplayMode(&ddraw->IDirectDraw7_iface, width, height, bpp, 0, 0);
}
-/*****************************************************************************
- * IDirectDraw7::RestoreDisplayMode
- *
- * Restores the display mode to what it was at creation time. Basically.
- *
- * Returns
- * DD_OK on success
- * DDERR_NOEXCLUSIVE mode if the device isn't in fullscreen mode
- *
- *****************************************************************************/
-static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface)
-{
- struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
- HRESULT hr;
-
- TRACE("iface %p.\n", iface);
-
- wined3d_mutex_lock();
-
- if (!ddraw->restore_mode)
- {
- wined3d_mutex_unlock();
- return DD_OK;
- }
-
- if (exclusive_ddraw && exclusive_ddraw != ddraw)
- {
- wined3d_mutex_unlock();
- return DDERR_NOEXCLUSIVEMODE;
- }
-
- if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &original_mode)))
- {
- ddraw->restore_mode = FALSE;
- restore_mode = FALSE;
- }
-
- wined3d_mutex_unlock();
-
- return hr;
-}
-
-static HRESULT WINAPI ddraw4_RestoreDisplayMode(IDirectDraw4 *iface)
-{
- struct ddraw *ddraw = impl_from_IDirectDraw4(iface);
-
- TRACE("iface %p.\n", iface);
-
- return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface);
-}
-
-static HRESULT WINAPI ddraw2_RestoreDisplayMode(IDirectDraw2 *iface)
-{
- struct ddraw *ddraw = impl_from_IDirectDraw2(iface);
-
- TRACE("iface %p.\n", iface);
-
- return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface);
-}
-
-static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface)
-{
- struct ddraw *ddraw = impl_from_IDirectDraw(iface);
-
- TRACE("iface %p.\n", iface);
-
- return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface);
-}
-
/*****************************************************************************
* IDirectDraw7::GetCaps
*
caps.dwSSBCKeyCaps = winecaps.ddraw_caps.ssb_color_key_caps;
caps.dwSSBFXCaps = winecaps.ddraw_caps.ssb_fx_caps;
- /* Even if wined3d supports 3D rendering, remove the cap if ddraw is
- * configured not to use it. */
- if (DefaultSurfaceType == DDRAW_SURFACE_TYPE_GDI)
- {
- caps.dwCaps &= ~DDCAPS_3D;
- caps.ddsCaps.dwCaps &= ~(DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER);
- }
- if (winecaps.ddraw_caps.stride_align)
- {
- caps.dwCaps |= DDCAPS_ALIGNSTRIDE;
- caps.dwAlignStrideAlign = winecaps.ddraw_caps.stride_align;
- }
+ caps.dwCaps |= DDCAPS_ALIGNSTRIDE;
+ caps.dwAlignStrideAlign = DDRAW_STRIDE_ALIGNMENT;
if(DriverCaps)
{
DDSD->u2.dwRefreshRate = 60;
DDSD->ddsCaps.dwCaps = 0;
DDSD->u4.ddpfPixelFormat.dwSize = sizeof(DDSD->u4.ddpfPixelFormat);
- PixelFormat_WineD3DtoDD(&DDSD->u4.ddpfPixelFormat, mode.format_id);
+ ddrawformat_from_wined3dformat(&DDSD->u4.ddpfPixelFormat, mode.format_id);
DDSD->u1.lPitch = mode.width * DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount / 8;
if(TRACE_ON(ddraw))
TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
- if (ddraw->initialized)
+ if (ddraw->flags & DDRAW_INITIALIZED)
return DDERR_ALREADYINITIALIZED;
/* FIXME: To properly take the GUID into account we should call
if (guid)
FIXME("Ignoring guid %s.\n", debugstr_guid(guid));
- ddraw->initialized = TRUE;
+ ddraw->flags |= DDRAW_INITIALIZED;
return DD_OK;
}
struct wined3d_display_mode mode;
unsigned int modenum, fmt;
DDSURFACEDESC2 callback_sd;
- unsigned enum_mode_count = 0, enum_mode_array_size = 0;
+ unsigned enum_mode_count = 0, enum_mode_array_size = 16;
DDPIXELFORMAT pixelformat;
static const enum wined3d_format_id checkFormatList[] =
if (!cb)
return DDERR_INVALIDPARAMS;
+ enum_modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*enum_modes) * enum_mode_array_size);
+ if (!enum_modes) return DDERR_OUTOFMEMORY;
+
wined3d_mutex_lock();
- if(!(Flags & DDEDM_REFRESHRATES))
- {
- enum_mode_array_size = 16;
- enum_modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*enum_modes) * enum_mode_array_size);
- if (!enum_modes)
- {
- ERR("Out of memory\n");
- wined3d_mutex_unlock();
- return DDERR_OUTOFMEMORY;
- }
- }
pixelformat.dwSize = sizeof(pixelformat);
for(fmt = 0; fmt < (sizeof(checkFormatList) / sizeof(checkFormatList[0])); fmt++)
while (wined3d_enum_adapter_modes(ddraw->wined3d, WINED3DADAPTER_DEFAULT, checkFormatList[fmt],
WINED3D_SCANLINE_ORDERING_UNKNOWN, modenum++, &mode) == WINED3D_OK)
{
- PixelFormat_WineD3DtoDD(&pixelformat, mode.format_id);
+ BOOL found = FALSE;
+ unsigned i;
+
+ ddrawformat_from_wined3dformat(&pixelformat, mode.format_id);
if (DDSD)
{
if (DDSD->dwFlags & DDSD_WIDTH && mode.width != DDSD->dwWidth)
continue;
}
- if(!(Flags & DDEDM_REFRESHRATES))
+ /* DX docs state EnumDisplayMode should return only unique modes */
+ for (i = 0; i < enum_mode_count; i++)
{
- /* DX docs state EnumDisplayMode should return only unique modes. If DDEDM_REFRESHRATES is not set, refresh
- * rate doesn't matter when determining if the mode is unique. So modes only differing in refresh rate have
- * to be reduced to a single unique result in such case.
- */
- BOOL found = FALSE;
- unsigned i;
-
- for (i = 0; i < enum_mode_count; i++)
+ if (enum_modes[i].width == mode.width && enum_modes[i].height == mode.height
+ && enum_modes[i].format_id == mode.format_id
+ && (enum_modes[i].refresh_rate == mode.refresh_rate || !(Flags & DDEDM_REFRESHRATES)))
{
- if (enum_modes[i].width == mode.width && enum_modes[i].height == mode.height
- && enum_modes[i].format_id == mode.format_id)
- {
- found = TRUE;
- break;
- }
+ found = TRUE;
+ break;
}
-
- if(found) continue;
}
+ if(found) continue;
memset(&callback_sd, 0, sizeof(callback_sd));
callback_sd.dwSize = sizeof(callback_sd);
return DD_OK;
}
- if(!(Flags & DDEDM_REFRESHRATES))
+ if (enum_mode_count == enum_mode_array_size)
{
- if (enum_mode_count == enum_mode_array_size)
+ struct wined3d_display_mode *new_enum_modes;
+
+ enum_mode_array_size *= 2;
+ new_enum_modes = HeapReAlloc(GetProcessHeap(), 0, enum_modes,
+ sizeof(*new_enum_modes) * enum_mode_array_size);
+ if (!new_enum_modes)
{
- struct wined3d_display_mode *new_enum_modes;
-
- enum_mode_array_size *= 2;
- new_enum_modes = HeapReAlloc(GetProcessHeap(), 0, enum_modes,
- sizeof(*new_enum_modes) * enum_mode_array_size);
- if (!new_enum_modes)
- {
- ERR("Out of memory\n");
- HeapFree(GetProcessHeap(), 0, enum_modes);
- wined3d_mutex_unlock();
- return DDERR_OUTOFMEMORY;
- }
-
- enum_modes = new_enum_modes;
+ HeapFree(GetProcessHeap(), 0, enum_modes);
+ wined3d_mutex_unlock();
+ return DDERR_OUTOFMEMORY;
}
- enum_modes[enum_mode_count++] = mode;
+ enum_modes = new_enum_modes;
}
+ enum_modes[enum_mode_count++] = mode;
}
}
* DD_OK on success
*
*****************************************************************************/
-static HRESULT ddraw_create_surface(struct ddraw *ddraw, DDSURFACEDESC2 *pDDSD,
- struct ddraw_surface **surface, UINT version)
+static HRESULT ddraw_create_surface(struct ddraw *ddraw, DDSURFACEDESC2 *desc,
+ DWORD flags, struct ddraw_surface **surface, UINT version)
{
HRESULT hr;
- TRACE("ddraw %p, surface_desc %p, surface %p.\n", ddraw, pDDSD, surface);
+ TRACE("ddraw %p, desc %p, flags %#x, surface %p.\n", ddraw, desc, flags, surface);
if (TRACE_ON(ddraw))
{
TRACE("Requesting surface desc:\n");
- DDRAW_dump_surface_desc(pDDSD);
+ DDRAW_dump_surface_desc(desc);
}
- if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && DefaultSurfaceType != DDRAW_SURFACE_TYPE_OPENGL)
+ if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && (ddraw->flags & DDRAW_NO3D))
{
- WARN("The application requests a 3D capable surface, but a non-OpenGL surface type was set in the registry.\n");
+ WARN("The application requests a 3D capable surface, but the ddraw object was created without 3D support.\n");
/* Do not fail surface creation, only fail 3D device creation. */
}
return DDERR_OUTOFVIDEOMEMORY;
}
- if (FAILED(hr = ddraw_surface_init(*surface, ddraw, pDDSD, version)))
+ if (FAILED(hr = ddraw_surface_init(*surface, ddraw, desc, flags, version)))
{
WARN("Failed to initialize surface, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, *surface);
HRESULT hr;
DDSURFACEDESC2 desc2;
const DWORD sysvidmem = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
+ /* Some applications assume surfaces will always be mapped at the same
+ * address. Some of those also assume that this address is valid even when
+ * the surface isn't mapped, and that updates done this way will be
+ * visible on the screen. The game Nox is such an application,
+ * Commandos: Behind Enemy Lines is another. */
+ const DWORD flags = WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_PIN_SYSMEM;
TRACE("ddraw %p, surface_desc %p, surface %p, outer_unknown %p.\n", ddraw, DDSD, surface, UnkOuter);
desc2.dwFlags |= DDSD_PIXELFORMAT;
desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
- PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, mode.format_id);
+ ddrawformat_from_wined3dformat(&desc2.u4.ddpfPixelFormat, mode.format_id);
}
/* No Width or no Height? Use the original screen size
}
/* Create the first surface */
- if (FAILED(hr = ddraw_create_surface(ddraw, &desc2, &object, version)))
+ if (FAILED(hr = ddraw_create_surface(ddraw, &desc2, flags, &object, version)))
{
WARN("ddraw_create_surface failed, hr %#x.\n", hr);
return hr;
{
struct ddraw_surface *object2 = NULL;
- if (FAILED(hr = ddraw_create_surface(ddraw, &desc2, &object2, version)))
+ if (FAILED(hr = ddraw_create_surface(ddraw, &desc2, flags, &object2, version)))
{
if (version == 7)
IDirectDrawSurface7_Release(&object->IDirectDrawSurface7_iface);
/* Create a WineD3DTexture if a texture was requested */
if (desc2.ddsCaps.dwCaps & DDSCAPS_TEXTURE)
- ddraw_surface_create_texture(object);
+ ddraw_surface_create_texture(object, flags);
return hr;
}
memset(&pformat, 0, sizeof(pformat));
pformat.dwSize = sizeof(pformat);
- PixelFormat_WineD3DtoDD(&pformat, formats[i]);
+ ddrawformat_from_wined3dformat(&pformat, formats[i]);
TRACE("Enumerating wined3d format %#x.\n", formats[i]);
hr = callback(&pformat, context);
TRACE("iface %p!\n", iface);
wined3d_mutex_lock();
- if (ddraw->d3d_initialized)
+ if (ddraw->flags & DDRAW_D3D_INITIALIZED)
wined3d_device_evict_managed_resources(ddraw->wined3d_device);
wined3d_mutex_unlock();
}
static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, enum wined3d_format_id format, DWORD usage,
- enum wined3d_pool pool, UINT sub_resource_idx, struct wined3d_surface **surface)
+ void *container_parent, const struct wined3d_resource_desc *wined3d_desc, UINT sub_resource_idx,
+ DWORD flags, struct wined3d_surface **surface)
{
struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
struct ddraw_surface *tex_root = container_parent;
struct ddraw_surface *ddraw_surface;
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, usage %#x,\n"
- "\tpool %#x, sub_resource_idx %u, surface %p.\n",
- device_parent, container_parent, width, height, format, usage, pool, sub_resource_idx, surface);
+ TRACE("device_parent %p, container_parent %p, wined3d_desc %p, sub_resource_idx %u, flags %#x, surface %p.\n",
+ device_parent, container_parent, wined3d_desc, sub_resource_idx, flags, surface);
/* The ddraw root surface is created before the wined3d texture. */
if (!sub_resource_idx)
goto done;
}
- desc.dwWidth = width;
- desc.dwHeight = height;
+ desc.dwWidth = wined3d_desc->width;
+ desc.dwHeight = wined3d_desc->height;
/* FIXME: Validate that format, usage, pool, etc. really make sense. */
- if (FAILED(hr = ddraw_create_surface(ddraw, &desc, &ddraw_surface, tex_root->version)))
+ if (FAILED(hr = ddraw_create_surface(ddraw, &desc, flags, &ddraw_surface, tex_root->version)))
return hr;
done:
};
static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, enum wined3d_format_id format_id, DWORD usage,
- enum wined3d_multisample_type multisample_type, DWORD multisample_quality, struct wined3d_surface **surface)
+ void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface)
{
struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, width %u, height %u, format_id %#x, usage %#x,\n"
- "\tmultisample_type %#x, multisample_quality %u, surface %p.\n",
- device_parent, container_parent, width, height, format_id, usage,
- multisample_type, multisample_quality, surface);
+ TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n",
+ device_parent, container_parent, desc, surface);
if (ddraw->wined3d_frontbuffer)
{
return E_FAIL;
}
- if (SUCCEEDED(hr = wined3d_surface_create(ddraw->wined3d_device, width, height, format_id, usage,
- WINED3D_POOL_DEFAULT, multisample_type, multisample_quality, WINED3D_SURFACE_MAPPABLE,
+ if (SUCCEEDED(hr = wined3d_surface_create(ddraw->wined3d_device, desc->width, desc->height, desc->format,
+ desc->usage, desc->pool, desc->multisample_type, desc->multisample_quality, WINED3D_SURFACE_MAPPABLE,
ddraw, &ddraw_frontbuffer_parent_ops, surface)))
ddraw->wined3d_frontbuffer = *surface;
}
static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent,
- void *container_parent, UINT width, UINT height, UINT depth, enum wined3d_format_id format,
- enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume)
+ void *container_parent, UINT width, UINT height, UINT depth, UINT level,
+ enum wined3d_format_id format, enum wined3d_pool pool, DWORD usage,
+ struct wined3d_volume **volume)
{
TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, "
"format %#x, pool %#x, usage %#x, volume %p.\n",
HRESULT ddraw_init(struct ddraw *ddraw, enum wined3d_device_type device_type)
{
+ WINED3DCAPS caps;
DWORD flags;
HRESULT hr;
ddraw->numIfaces = 1;
ddraw->ref7 = 1;
- flags = WINED3D_LEGACY_DEPTH_BIAS;
- if (DefaultSurfaceType != DDRAW_SURFACE_TYPE_OPENGL)
- flags |= WINED3D_NO3D;
-
+ flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING;
if (!(ddraw->wined3d = wined3d_create(7, flags)))
{
- if ((flags & WINED3D_NO3D) || !(ddraw->wined3d = wined3d_create(7, flags | WINED3D_NO3D)))
+ if (!(ddraw->wined3d = wined3d_create(7, flags | WINED3D_NO3D)))
{
WARN("Failed to create a wined3d object.\n");
return E_FAIL;
}
+ }
+
+ if (FAILED(hr = wined3d_get_device_caps(ddraw->wined3d, WINED3DADAPTER_DEFAULT, device_type, &caps)))
+ {
+ ERR("Failed to get device caps, hr %#x.\n", hr);
+ wined3d_decref(ddraw->wined3d);
+ return E_FAIL;
+ }
+ if (!(caps.ddraw_caps.caps & WINEDDCAPS_3D))
+ {
WARN("Created a wined3d object without 3D support.\n");
- DefaultSurfaceType = DDRAW_SURFACE_TYPE_GDI;
+ ddraw->flags |= DDRAW_NO3D;
}
- hr = wined3d_device_create(ddraw->wined3d, WINED3DADAPTER_DEFAULT, device_type,
- NULL, 0, 8, &ddraw->device_parent, &ddraw->wined3d_device);
- if (FAILED(hr))
+ if (FAILED(hr = wined3d_device_create(ddraw->wined3d, WINED3DADAPTER_DEFAULT, device_type,
+ NULL, 0, DDRAW_STRIDE_ALIGNMENT, &ddraw->device_parent, &ddraw->wined3d_device)))
{
WARN("Failed to create a wined3d device, hr %#x.\n", hr);
wined3d_decref(ddraw->wined3d);
#include <winbase.h>
#include <wingdi.h>
-#include "winuser.h"
#include <winuser.h>
#include <d3d.h>
#include <wine/list.h>
#include <wine/wined3d.h>
-enum ddraw_surface_type
-{
- DDRAW_SURFACE_TYPE_OPENGL,
- DDRAW_SURFACE_TYPE_GDI,
-};
-
extern const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops DECLSPEC_HIDDEN;
-extern enum ddraw_surface_type DefaultSurfaceType DECLSPEC_HIDDEN;
extern DWORD force_refresh_rate DECLSPEC_HIDDEN;
/*****************************************************************************
struct wined3d_vertex_declaration *decl;
};
+#define DDRAW_INITIALIZED 0x00000001
+#define DDRAW_D3D_INITIALIZED 0x00000002
+#define DDRAW_RESTORE_MODE 0x00000004
+#define DDRAW_NO3D 0x00000008
+#define DDRAW_SCL_DDRAW1 0x00000010
+
+#define DDRAW_STRIDE_ALIGNMENT 8
+
struct ddraw
{
/* Interfaces */
/* See comment in IDirectDraw::AddRef */
LONG ref7, ref4, ref2, ref3, ref1, numIfaces;
- BOOL initialized;
struct wined3d *wined3d;
struct wined3d_device *wined3d_device;
- BOOL d3d_initialized;
- BOOL restore_mode;
+ DWORD flags;
struct ddraw_surface *primary;
RECT primary_lock;
DWORD Handle;
};
-HRESULT ddraw_surface_create_texture(struct ddraw_surface *surface) DECLSPEC_HIDDEN;
+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, UINT version) DECLSPEC_HIDDEN;
+ DDSURFACEDESC2 *desc, DWORD flags, UINT version) DECLSPEC_HIDDEN;
ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN;
static inline struct ddraw_surface *impl_from_IDirect3DTexture(IDirect3DTexture *iface)
#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
(((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
-void PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, enum wined3d_format_id WineD3DFormat) DECLSPEC_HIDDEN;
-enum wined3d_format_id PixelFormat_DD2WineD3D(const DDPIXELFORMAT *DDPixelFormat) DECLSPEC_HIDDEN;
+void ddrawformat_from_wined3dformat(DDPIXELFORMAT *ddraw_format,
+ enum wined3d_format_id wined3d_format) DECLSPEC_HIDDEN;
+enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *format) DECLSPEC_HIDDEN;
void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd) DECLSPEC_HIDDEN;
void dump_D3DMATRIX(const D3DMATRIX *mat) DECLSPEC_HIDDEN;
void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) DECLSPEC_HIDDEN;
/*
* Copyright (c) 1998-2004 Lionel Ulmer
* Copyright (c) 2002-2005 Christian Costa
- * Copyright (c) 2006-2009, 2011-2012 Stefan Dösinger
+ * Copyright (c) 2006-2009, 2011-2013 Stefan Dösinger
* Copyright (c) 2008 Alexander Dorofeyev
*
* This library is free software; you can redistribute it and/or
memset(&pformat, 0, sizeof(pformat));
pformat.dwSize = sizeof(pformat);
- PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
+ ddrawformat_from_wined3dformat(&pformat, FormatList[i]);
TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
hr = callback(&pformat, context);
memset(&pformat, 0, sizeof(pformat));
pformat.dwSize = sizeof(pformat);
- PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
+ ddrawformat_from_wined3dformat(&pformat, BumpFormatList[i]);
TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
hr = callback(&pformat, context);
sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
- PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
+ ddrawformat_from_wined3dformat(&sdesc.ddpfPixelFormat, FormatList[i]);
TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
hr = callback(&sdesc, context);
return d3d_device3_Index(&device->IDirect3DDevice3_iface, index);
}
-/*****************************************************************************
- * IDirect3DDevice3::End
- *
- * Ends a draw begun with IDirect3DDevice3::Begin or
- * IDirect3DDevice::BeginIndexed. The vertices specified with
- * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
- * the IDirect3DDevice7::DrawPrimitive method. So far only
- * non-indexed mode is supported
- *
- * Version 2 and 3
- *
- * Params:
- * Flags: Some flags, as usual. Don't know which are defined
- *
- * Returns:
- * The return value of IDirect3DDevice7::DrawPrimitive
- *
- *****************************************************************************/
-static HRESULT WINAPI d3d_device3_End(IDirect3DDevice3 *iface, DWORD flags)
-{
- struct d3d_device *device = impl_from_IDirect3DDevice3(iface);
-
- TRACE("iface %p, flags %#x.\n", iface, flags);
-
- return IDirect3DDevice7_DrawPrimitive(&device->IDirect3DDevice7_iface, device->primitive_type,
- device->vertex_type, device->sysmem_vertex_buffer, device->nb_vertices, device->render_flags);
-}
-
-static HRESULT WINAPI d3d_device2_End(IDirect3DDevice2 *iface, DWORD flags)
-{
- struct d3d_device *device = impl_from_IDirect3DDevice2(iface);
-
- TRACE("iface %p, flags %#x.\n", iface, flags);
-
- return d3d_device3_End(&device->IDirect3DDevice3_iface, flags);
-}
-
/*****************************************************************************
* IDirect3DDevice7::GetRenderState
*
wined3d_resource_get_desc(sub_resource, &desc);
ddfmt.dwSize = sizeof(ddfmt);
- PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
+ ddrawformat_from_wined3dformat(&ddfmt, desc.format);
if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
}
}
return D3D_OK;
}
+ case D3DRENDERSTATE_LIGHTING:
+ *value = 0xffffffff;
+ return D3D_OK;
+
default:
return IDirect3DDevice7_GetRenderState(&device->IDirect3DDevice7_iface, state, value);
}
wined3d_resource_get_desc(sub_resource, &desc);
ddfmt.dwSize = sizeof(ddfmt);
- PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
+ ddrawformat_from_wined3dformat(&ddfmt, desc.format);
if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
}
}
break;
}
+ case D3DRENDERSTATE_LIGHTING:
+ hr = D3D_OK;
+ break;
+
default:
hr = IDirect3DDevice7_SetRenderState(&device->IDirect3DDevice7_iface, state, value);
break;
return hr;
}
+static void setup_lighting(const struct d3d_device *device, DWORD fvf, DWORD flags)
+{
+ BOOL enable;
+
+ /* Ignore the D3DFVF_XYZRHW case here, wined3d takes care of that */
+ if (flags & D3DDP_DONOTLIGHT)
+ enable = FALSE;
+ else if (!(fvf & D3DFVF_NORMAL))
+ enable = FALSE;
+ else
+ enable = TRUE;
+
+ wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_LIGHTING, enable);
+}
+
+
static HRESULT WINAPI d3d_device3_DrawPrimitive(IDirect3DDevice3 *iface,
D3DPRIMITIVETYPE primitive_type, DWORD fvf, void *vertices, DWORD vertex_count,
DWORD flags)
TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
iface, primitive_type, fvf, vertices, vertex_count, flags);
+ setup_lighting(device, fvf, flags);
+
return IDirect3DDevice7_DrawPrimitive(&device->IDirect3DDevice7_iface,
primitive_type, fvf, vertices, vertex_count, flags);
}
return DDERR_INVALIDPARAMS; /* Should never happen */
}
- return IDirect3DDevice7_DrawPrimitive(&device->IDirect3DDevice7_iface,
+ return d3d_device3_DrawPrimitive(&device->IDirect3DDevice3_iface,
primitive_type, fvf, vertices, vertex_count, flags);
}
"indices %p, index_count %u, flags %#x.\n",
iface, primitive_type, fvf, vertices, vertex_count, indices, index_count, flags);
+ setup_lighting(device, fvf, flags);
+
return IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface,
primitive_type, fvf, vertices, vertex_count, indices, index_count, flags);
}
return DDERR_INVALIDPARAMS; /* Should never happen */
}
- return IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface,
+ return d3d_device3_DrawIndexedPrimitive(&device->IDirect3DDevice3_iface,
primitive_type, fvf, vertices, vertex_count, indices, index_count, flags);
}
+/*****************************************************************************
+ * IDirect3DDevice3::End
+ *
+ * Ends a draw begun with IDirect3DDevice3::Begin or
+ * IDirect3DDevice::BeginIndexed. The vertices specified with
+ * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
+ * the IDirect3DDevice3::DrawPrimitive method. So far only
+ * non-indexed mode is supported
+ *
+ * Version 2 and 3
+ *
+ * Params:
+ * Flags: Some flags, as usual. Don't know which are defined
+ *
+ * Returns:
+ * The return value of IDirect3DDevice3::DrawPrimitive
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_device3_End(IDirect3DDevice3 *iface, DWORD flags)
+{
+ struct d3d_device *device = impl_from_IDirect3DDevice3(iface);
+
+ TRACE("iface %p, flags %#x.\n", iface, flags);
+
+ return d3d_device3_DrawPrimitive(&device->IDirect3DDevice3_iface, device->primitive_type,
+ device->vertex_type, device->sysmem_vertex_buffer, device->nb_vertices, device->render_flags);
+}
+
+static HRESULT WINAPI d3d_device2_End(IDirect3DDevice2 *iface, DWORD flags)
+{
+ struct d3d_device *device = impl_from_IDirect3DDevice2(iface);
+
+ TRACE("iface %p, flags %#x.\n", iface, flags);
+
+ return d3d_device3_End(&device->IDirect3DDevice3_iface, flags);
+}
+
/*****************************************************************************
* IDirect3DDevice7::SetClipStatus
*
TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
+ setup_lighting(device, VertexType, Flags);
+
return IDirect3DDevice7_DrawPrimitiveStrided(&device->IDirect3DDevice7_iface,
PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
}
TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
+ setup_lighting(device, VertexType, Flags);
+
return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&device->IDirect3DDevice7_iface,
PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
}
TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
+ setup_lighting(device, vb->fvf, Flags);
+
return IDirect3DDevice7_DrawPrimitiveVB(&device->IDirect3DDevice7_iface,
PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, StartVertex, NumVertices, Flags);
}
TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
iface, PrimitiveType, D3DVertexBuf, Indices, IndexCount, Flags);
+ setup_lighting(device, vb->fvf, Flags);
+
return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device->IDirect3DDevice7_iface, PrimitiveType,
&vb->IDirect3DVertexBuffer7_iface, 0, IndexCount, Indices, IndexCount, Flags);
}
{
float distance, norm;
- norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
+ norm = sqrtf(normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z);
distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
wined3d_resource_get_desc(sub_resource, &desc);
ddfmt.dwSize = sizeof(ddfmt);
- PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
+ ddrawformat_from_wined3dformat(&ddfmt, desc.format);
if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
}
}
d3d_device_update_depth_stencil(device));
if (version == 1) /* Color keying is initially enabled for version 1 devices. */
wined3d_device_set_render_state(ddraw->wined3d_device, WINED3D_RS_COLORKEYENABLE, TRUE);
+ else if (version == 2)
+ wined3d_device_set_render_state(ddraw->wined3d_device, WINED3D_RS_SPECULARENABLE, TRUE);
return D3D_OK;
}
TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n",
ddraw, target, version, device, outer_unknown);
- if (DefaultSurfaceType != DDRAW_SURFACE_TYPE_OPENGL)
+ if (ddraw->flags & DDRAW_NO3D)
{
ERR_(winediag)("The application wants to create a Direct3D device, "
"but the current DirectDrawRenderer does not support this.\n");
dst->u7.tu = src->u7.tu;
dst->u8.tv = src->u8.tv;
- /* Now, the matrix multiplication */
- dst->u1.sx = (src->u1.x * mat._11) + (src->u2.y * mat._21) + (src->u3.z * mat._31) + (1.0 * mat._41);
- dst->u2.sy = (src->u1.x * mat._12) + (src->u2.y * mat._22) + (src->u3.z * mat._32) + (1.0 * mat._42);
- dst->u3.sz = (src->u1.x * mat._13) + (src->u2.y * mat._23) + (src->u3.z * mat._33) + (1.0 * mat._43);
- dst->u4.rhw = (src->u1.x * mat._14) + (src->u2.y * mat._24) + (src->u3.z * mat._34) + (1.0 * mat._44);
+ dst->u1.sx = (src->u1.x * mat._11) + (src->u2.y * mat._21) + (src->u3.z * mat._31) + mat._41;
+ dst->u2.sy = (src->u1.x * mat._12) + (src->u2.y * mat._22) + (src->u3.z * mat._32) + mat._42;
+ dst->u3.sz = (src->u1.x * mat._13) + (src->u2.y * mat._23) + (src->u3.z * mat._33) + mat._43;
+ dst->u4.rhw = (src->u1.x * mat._14) + (src->u2.y * mat._24) + (src->u3.z * mat._34) + mat._44;
dst->u1.sx = dst->u1.sx / dst->u4.rhw * Viewport->dvScaleX
+ Viewport->dwX + Viewport->dwWidth / 2;
dst->u7.tu = src->u6.tu;
dst->u8.tv = src->u7.tv;
- /* Now, the matrix multiplication */
- dst->u1.sx = (src->u1.x * mat._11) + (src->u2.y * mat._21) + (src->u3.z * mat._31) + (1.0 * mat._41);
- dst->u2.sy = (src->u1.x * mat._12) + (src->u2.y * mat._22) + (src->u3.z * mat._32) + (1.0 * mat._42);
- dst->u3.sz = (src->u1.x * mat._13) + (src->u2.y * mat._23) + (src->u3.z * mat._33) + (1.0 * mat._43);
- dst->u4.rhw = (src->u1.x * mat._14) + (src->u2.y * mat._24) + (src->u3.z * mat._34) + (1.0 * mat._44);
+ dst->u1.sx = (src->u1.x * mat._11) + (src->u2.y * mat._21) + (src->u3.z * mat._31) + mat._41;
+ dst->u2.sy = (src->u1.x * mat._12) + (src->u2.y * mat._22) + (src->u3.z * mat._32) + mat._42;
+ dst->u3.sz = (src->u1.x * mat._13) + (src->u2.y * mat._23) + (src->u3.z * mat._33) + mat._43;
+ dst->u4.rhw = (src->u1.x * mat._14) + (src->u2.y * mat._24) + (src->u3.z * mat._34) + mat._44;
dst->u1.sx = dst->u1.sx / dst->u4.rhw * Viewport->dvScaleX
+ Viewport->dwX + Viewport->dwWidth / 2;
WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
-/* The configured default surface */
-enum ddraw_surface_type DefaultSurfaceType = DDRAW_SURFACE_TYPE_OPENGL;
-
static struct list global_ddraw_list = LIST_INIT(global_ddraw_list);
static HINSTANCE instance;
HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA callback, void *context, DWORD flags)
{
struct wined3d *wined3d;
- DWORD wined3d_flags;
TRACE("callback %p, context %p, flags %#x.\n", callback, context, flags);
if (flags)
FIXME("flags 0x%08x not handled\n", flags);
- wined3d_flags = WINED3D_LEGACY_DEPTH_BIAS;
- if (DefaultSurfaceType != DDRAW_SURFACE_TYPE_OPENGL)
- wined3d_flags |= WINED3D_NO3D;
-
TRACE("Enumerating ddraw interfaces\n");
- if (!(wined3d = wined3d_create(7, wined3d_flags)))
+ if (!(wined3d = wined3d_create(7, WINED3D_LEGACY_DEPTH_BIAS)))
{
- if ((wined3d_flags & WINED3D_NO3D) || !(wined3d = wined3d_create(7, wined3d_flags | WINED3D_NO3D)))
+ if (!(wined3d = wined3d_create(7, WINED3D_LEGACY_DEPTH_BIAS | WINED3D_NO3D)))
{
WARN("Failed to create a wined3d object.\n");
return E_FAIL;
}
WARN("Created a wined3d object without 3D support.\n");
- DefaultSurfaceType = DDRAW_SURFACE_TYPE_GDI;
}
__TRY
* app didn't release them properly(Gothic 2, Diablo 2, Moto racer, ...)
*
***********************************************************************/
-BOOL WINAPI
-DllMain(HINSTANCE hInstDLL,
- DWORD Reason,
- LPVOID lpv)
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID reserved)
{
- TRACE("(%p,%x,%p)\n", hInstDLL, Reason, lpv);
- if (Reason == DLL_PROCESS_ATTACH)
+ TRACE("(%p,%x,%p)\n", hInstDLL, reason, reserved);
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
{
static HMODULE ddraw_self;
- char buffer[MAX_PATH+10];
- DWORD size = sizeof(buffer);
HKEY hkey = 0;
- HKEY appkey = 0;
WNDCLASSA wc;
- DWORD len;
/* Register the window class. This is used to create a hidden window
* for D3D rendering, if the application didn't pass one. It can also
return FALSE;
}
- /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */
- if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0;
-
- len = GetModuleFileNameA( 0, buffer, MAX_PATH );
- if (len && len < MAX_PATH)
- {
- HKEY tmpkey;
- /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Direct3D */
- if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
- {
- char *p, *appname = buffer;
- if ((p = strrchr( appname, '/' ))) appname = p + 1;
- if ((p = strrchr( appname, '\\' ))) appname = p + 1;
- strcat( appname, "\\Direct3D" );
- TRACE("appname = [%s]\n", appname);
- if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
- RegCloseKey( tmpkey );
- }
- }
-
- if ( 0 != hkey || 0 != appkey )
- {
- if ( !get_config_key( hkey, appkey, "DirectDrawRenderer", buffer, size) )
- {
- if (!strcmp(buffer,"gdi"))
- {
- TRACE("Defaulting to GDI surfaces\n");
- DefaultSurfaceType = DDRAW_SURFACE_TYPE_GDI;
- }
- else if (!strcmp(buffer,"opengl"))
- {
- TRACE("Defaulting to opengl surfaces\n");
- DefaultSurfaceType = DDRAW_SURFACE_TYPE_OPENGL;
- }
- else
- {
- ERR("Unknown default surface type. Supported are:\n gdi, opengl\n");
- }
- }
- }
-
/* On Windows one can force the refresh rate that DirectDraw uses by
* setting an override value in dxdiag. This is documented in KB315614
* (main article), KB230002, and KB217348. By comparing registry dumps
*/
if ( !RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\DirectDraw", &hkey ) )
{
- DWORD type, data;
+ DWORD type, data, size;
+
size = sizeof(data);
if (!RegQueryValueExA( hkey, "ForceRefreshRate", NULL, &type, (LPBYTE)&data, &size ) && type == REG_DWORD)
{
instance = hInstDLL;
DisableThreadLibraryCalls(hInstDLL);
+ break;
}
- else if (Reason == DLL_PROCESS_DETACH)
- {
+
+ case DLL_PROCESS_DETACH:
if(!list_empty(&global_ddraw_list))
{
struct list *entry, *entry2;
}
}
- /* Unregister the window class. */
+ if (reserved) break;
UnregisterClassA(DDRAW_WINDOW_CLASS_NAME, hInstDLL);
}
| DDSD_HEIGHT | DDSD_PITCH | DDSD_CAPS;
enum wined3d_format_id format_id;
BOOL update_wined3d = FALSE;
- UINT width, height;
+ UINT pitch, width, height;
TRACE("iface %p, surface_desc %p, flags %#x.\n", iface, DDSD, Flags);
TRACE("Surface pitch changed from %u to %u.\n", This->surface_desc.u1.lPitch, DDSD->u1.lPitch);
update_wined3d = TRUE;
}
+ pitch = DDSD->u1.lPitch;
width = DDSD->dwWidth;
}
else if (DDSD->dwFlags & DDSD_PITCH)
}
else
{
+ pitch = This->surface_desc.u1.lPitch;
width = This->surface_desc.dwWidth;
}
if (DDSD->dwFlags & DDSD_PIXELFORMAT)
{
enum wined3d_format_id current_format_id;
- format_id = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
+ format_id = wined3dformat_from_ddrawformat(&DDSD->u4.ddpfPixelFormat);
if (format_id == WINED3DFMT_UNKNOWN)
{
wined3d_mutex_unlock();
return DDERR_INVALIDPARAMS;
}
- current_format_id = PixelFormat_DD2WineD3D(&This->surface_desc.u4.ddpfPixelFormat);
+ current_format_id = wined3dformat_from_ddrawformat(&This->surface_desc.u4.ddpfPixelFormat);
if (format_id != current_format_id)
{
TRACE("Surface format changed from %#x to %#x.\n", current_format_id, format_id);
}
else
{
- format_id = PixelFormat_DD2WineD3D(&This->surface_desc.u4.ddpfPixelFormat);
+ format_id = wined3dformat_from_ddrawformat(&This->surface_desc.u4.ddpfPixelFormat);
}
if (update_wined3d)
if (DDSD->dwFlags & DDSD_LPSURFACE && DDSD->lpSurface)
{
- hr = wined3d_surface_set_mem(This->wined3d_surface, DDSD->lpSurface);
- if (FAILED(hr))
+ if (FAILED(hr = wined3d_surface_set_mem(This->wined3d_surface, DDSD->lpSurface, pitch)))
{
/* No need for a trace here, wined3d does that for us */
switch(hr)
ddraw_texture_wined3d_object_destroyed,
};
-HRESULT ddraw_surface_create_texture(struct ddraw_surface *surface)
+HRESULT ddraw_surface_create_texture(struct ddraw_surface *surface, DWORD surface_flags)
{
const DDSURFACEDESC2 *desc = &surface->surface_desc;
+ struct wined3d_resource_desc wined3d_desc;
struct ddraw_surface *mip, **attach;
struct wined3d_resource *resource;
- enum wined3d_format_id format;
UINT layers, levels, i, j;
DDSURFACEDESC2 *mip_desc;
enum wined3d_pool pool;
else
pool = WINED3D_POOL_DEFAULT;
- format = PixelFormat_DD2WineD3D(&surface->surface_desc.u4.ddpfPixelFormat);
+ wined3d_desc.format = wined3dformat_from_ddrawformat(&surface->surface_desc.u4.ddpfPixelFormat);
+ wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ wined3d_desc.multisample_quality = 0;
+ wined3d_desc.usage = 0;
+ wined3d_desc.pool = pool;
+ wined3d_desc.width = desc->dwWidth;
+ wined3d_desc.height = desc->dwHeight;
+ wined3d_desc.depth = 1;
+ wined3d_desc.size = 0;
+
if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
- hr = wined3d_texture_create_cube(surface->ddraw->wined3d_device, desc->dwWidth,
- levels, 0, format, pool, surface, &ddraw_texture_wined3d_parent_ops, &surface->wined3d_texture);
+ {
+ wined3d_desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
+ hr = wined3d_texture_create_cube(surface->ddraw->wined3d_device, &wined3d_desc, levels,
+ surface_flags, surface, &ddraw_texture_wined3d_parent_ops, &surface->wined3d_texture);
+ }
else
- hr = wined3d_texture_create_2d(surface->ddraw->wined3d_device, desc->dwWidth, desc->dwHeight,
- levels, 0, format, pool, surface, &ddraw_texture_wined3d_parent_ops, &surface->wined3d_texture);
+ {
+ wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ hr = wined3d_texture_create_2d(surface->ddraw->wined3d_device, &wined3d_desc, levels,
+ surface_flags, surface, &ddraw_texture_wined3d_parent_ops, &surface->wined3d_texture);
+ }
if (FAILED(hr))
{
return DD_OK;
}
-HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, DDSURFACEDESC2 *desc, UINT version)
+HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw,
+ DDSURFACEDESC2 *desc, DWORD flags, UINT version)
{
enum wined3d_pool pool = WINED3D_POOL_DEFAULT;
- DWORD flags = WINED3D_SURFACE_MAPPABLE;
enum wined3d_format_id format;
DWORD usage = 0;
HRESULT hr;
desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
}
- /* Some applications assume surfaces will always be mapped at the same
- * address. Some of those also assume that this address is valid even when
- * the surface isn't mapped, and that updates done this way will be
- * visible on the screen. The game Nox is such an application,
- * Commandos: Behind Enemy Lines is another. */
- flags |= WINED3D_SURFACE_PIN_SYSMEM;
-
if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
usage |= WINED3DUSAGE_RENDERTARGET;
desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
}
- format = PixelFormat_DD2WineD3D(&desc->u4.ddpfPixelFormat);
+ format = wined3dformat_from_ddrawformat(&desc->u4.ddpfPixelFormat);
if (format == WINED3DFMT_UNKNOWN)
{
WARN("Unsupported / unknown pixelformat.\n");
}
if (desc->dwFlags & DDSD_LPSURFACE)
{
- hr = wined3d_surface_set_mem(surface->wined3d_surface, desc->lpSurface);
- if (FAILED(hr))
+ UINT pitch = 0;
+
+ if (desc->dwFlags & DDSD_PITCH)
+ {
+ pitch = desc->u1.lPitch;
+ surface->surface_desc.u1.lPitch = pitch;
+ }
+
+ if (FAILED(hr = wined3d_surface_set_mem(surface->wined3d_surface, desc->lpSurface, pitch)))
{
ERR("Failed to set surface memory, hr %#x.\n", hr);
wined3d_surface_decref(surface->wined3d_surface);
static void DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf);
-/*****************************************************************************
- * PixelFormat_WineD3DtoDD
- *
- * Converts an wined3d format ID into a DDPIXELFORMAT structure
- *
- * Params:
- * DDPixelFormat: Address of the structure to write the pixel format to
- * WineD3DFormat: Source format
- *
- *****************************************************************************/
-void PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, enum wined3d_format_id WineD3DFormat)
+void ddrawformat_from_wined3dformat(DDPIXELFORMAT *DDPixelFormat, enum wined3d_format_id wined3d_format)
{
DWORD Size = DDPixelFormat->dwSize;
- TRACE("Converting wined3d format %#x to DDRAW.\n", WineD3DFormat);
if(Size==0) return;
memset(DDPixelFormat, 0x00, Size);
DDPixelFormat->dwSize = Size;
- switch(WineD3DFormat)
+ switch (wined3d_format)
{
case WINED3DFMT_B8G8R8_UNORM:
DDPixelFormat->dwFlags = DDPF_RGB;
case WINED3DFMT_YUY2:
DDPixelFormat->u1.dwYUVBitCount = 16;
DDPixelFormat->dwFlags = DDPF_FOURCC;
- DDPixelFormat->dwFourCC = WineD3DFormat;
+ DDPixelFormat->dwFourCC = wined3d_format;
break;
case WINED3DFMT_YV12:
DDPixelFormat->u1.dwYUVBitCount = 12;
DDPixelFormat->dwFlags = DDPF_FOURCC;
- DDPixelFormat->dwFourCC = WineD3DFormat;
+ DDPixelFormat->dwFourCC = wined3d_format;
break;
case WINED3DFMT_DXT1:
case WINED3DFMT_G8R8_G8B8:
case WINED3DFMT_R8G8_B8G8:
DDPixelFormat->dwFlags = DDPF_FOURCC;
- DDPixelFormat->dwFourCC = WineD3DFormat;
+ DDPixelFormat->dwFourCC = wined3d_format;
break;
/* Luminance */
break;
default:
- ERR("Can't translate this Pixelformat %d\n", WineD3DFormat);
+ FIXME("Unhandled wined3d format %#x.\n", wined3d_format);
+ break;
}
if(TRACE_ON(ddraw)) {
DDRAW_dump_pixelformat(DDPixelFormat);
}
}
-/*****************************************************************************
- * PixelFormat_DD2WineD3D
- *
- * Reads a DDPIXELFORMAT structure and returns the equivalent wined3d
- * format ID.
- *
- * Params:
- * DDPixelFormat: The source format
- *
- * Returns:
- * The wined3d format ID equivalent to the DDraw format
- * WINED3DFMT_UNKNOWN if a matching format wasn't found
- *****************************************************************************/
-enum wined3d_format_id PixelFormat_DD2WineD3D(const DDPIXELFORMAT *DDPixelFormat)
+
+enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *DDPixelFormat)
{
TRACE("Convert a DirectDraw Pixelformat to a WineD3D Pixelformat\n");
if(TRACE_ON(ddraw))
outH = lpData->lpHOut;
for(i = 0; i < dwVertexCount; i++)
{
- x = (in[0] * mat._11) + (in[1] * mat._21) + (in[2] * mat._31) + (1.0 * mat._41);
- y = (in[0] * mat._12) + (in[1] * mat._22) + (in[2] * mat._32) + (1.0 * mat._42);
- z = (in[0] * mat._13) + (in[1] * mat._23) + (in[2] * mat._33) + (1.0 * mat._43);
- w = (in[0] * mat._14) + (in[1] * mat._24) + (in[2] * mat._34) + (1.0 * mat._44);
+ x = (in[0] * mat._11) + (in[1] * mat._21) + (in[2] * mat._31) + mat._41;
+ y = (in[0] * mat._12) + (in[1] * mat._22) + (in[2] * mat._32) + mat._42;
+ z = (in[0] * mat._13) + (in[1] * mat._23) + (in[2] * mat._33) + mat._43;
+ w = (in[0] * mat._14) + (in[1] * mat._24) + (in[2] * mat._34) + mat._44;
if(dwFlags & D3DTRANSFORM_CLIPPED)
{
wined3d_main.c
${CMAKE_CURRENT_BINARY_DIR}/wined3d.def)
-add_library(wined3d SHARED
- ${SOURCE}
- version.rc)
+add_library(wined3d SHARED ${SOURCE} version.rc)
set_module_type(wined3d win32dll)
-
target_link_libraries(wined3d wine)
-
-add_importlibs(wined3d
- user32
- opengl32
- gdi32
- advapi32
- msvcrt
- kernel32
- ntdll)
-
-add_dependencies(wined3d wineheaders)
+add_importlibs(wined3d user32 opengl32 gdi32 advapi32 msvcrt kernel32 ntdll)
add_pch(wined3d wined3d_private.h)
add_cd_file(TARGET wined3d DESTINATION reactos/system32 FOR all)
-
-if(NOT MSVC)
- # FIXME: http://www.cmake.org/Bug/view.php?id=12998
- #allow_warnings(wined3d)
- set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-Wno-error")
-endif()
* Copyright 2006 Ivan Gyurdiev
* Copyright 2006 Jason Green
* Copyright 2006 Henri Verbeet
- * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
* Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
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;
BOOL muted;
unsigned int num_loops, loop_depth, num_ifcs;
int aL;
+ BOOL ps_post_process;
unsigned int vs_clipplanes;
BOOL footer_written;
char *vshader_const_dirty, *pshader_const_dirty;
const struct wined3d_context *last_context;
+ const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
BOOL ffp_proj_control;
};
}
}
-/**
- * Loads the texture dimensions for NP2 fixup into the currently set ARB_[vertex/fragment]_programs.
- */
-static void shader_arb_load_np2fixup_constants(void *shader_priv,
+/* Loads the texture dimensions for NP2 fixup into the currently set
+ * ARB_[vertex/fragment]_programs. */
+static void shader_arb_load_np2fixup_constants(const struct arb_ps_np2fixup_info *fixup,
const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
{
- const struct shader_arb_priv * priv = shader_priv;
-
- /* NP2 texcoord fixup is (currently) only done for pixelshaders. */
- if (!use_ps(state)) return;
-
- if (priv->compiled_fprog && priv->compiled_fprog->np2fixup_info.super.active) {
- const struct arb_ps_np2fixup_info* const fixup = &priv->compiled_fprog->np2fixup_info;
- UINT i;
- WORD active = fixup->super.active;
- GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
+ GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
+ WORD active = fixup->super.active;
+ UINT i;
- for (i = 0; active; active >>= 1, ++i)
- {
- const struct wined3d_texture *tex = state->textures[i];
- const unsigned char idx = fixup->super.idx[i];
- GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4];
+ if (!active)
+ return;
- if (!(active & 1)) continue;
+ for (i = 0; active; active >>= 1, ++i)
+ {
+ const struct wined3d_texture *tex = state->textures[i];
+ unsigned char idx = fixup->super.idx[i];
+ GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4];
- if (!tex) {
- FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n");
- continue;
- }
+ if (!(active & 1))
+ continue;
- if (idx % 2)
- {
- tex_dim[2] = tex->pow2_matrix[0];
- tex_dim[3] = tex->pow2_matrix[5];
- }
- else
- {
- tex_dim[0] = tex->pow2_matrix[0];
- tex_dim[1] = tex->pow2_matrix[5];
- }
+ if (!tex)
+ {
+ ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n");
+ continue;
}
- for (i = 0; i < fixup->super.num_consts; ++i) {
- GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
- fixup->offset + i, &np2fixup_constants[i * 4]));
+ if (idx % 2)
+ {
+ tex_dim[2] = tex->pow2_matrix[0];
+ tex_dim[3] = tex->pow2_matrix[5];
+ }
+ else
+ {
+ tex_dim[0] = tex->pow2_matrix[0];
+ tex_dim[1] = tex->pow2_matrix[5];
}
}
+
+ for (i = 0; i < fixup->super.num_consts; ++i)
+ {
+ GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
+ fixup->offset + i, &np2fixup_constants[i * 4]));
+ }
}
/* Context activation is done by the caller. */
checkGLcall("Load vs int consts");
}
-static void shader_arb_select(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
- enum wined3d_shader_mode fragment_mode);
+static void shader_arb_select(void *shader_priv, struct wined3d_context *context,
+ const struct wined3d_state *state);
/**
* Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
* worry about the Integers or Booleans
*/
/* Context activation is done by the caller (state handler). */
-static void shader_arb_load_constants_internal(const struct wined3d_context *context,
+static void shader_arb_load_constants_internal(struct shader_arb_priv *priv,
+ struct wined3d_context *context, const struct wined3d_state *state,
BOOL usePixelShader, BOOL useVertexShader, BOOL from_shader_select)
{
- struct wined3d_device *device = context->swapchain->device;
- const struct wined3d_stateblock *stateblock = device->stateBlock;
- const struct wined3d_state *state = &stateblock->state;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
const struct wined3d_gl_info *gl_info = context->gl_info;
- struct shader_arb_priv *priv = device->shader_priv;
if (!from_shader_select)
{
const struct wined3d_shader *vshader = state->vertex_shader, *pshader = state->pixel_shader;
if (vshader
- && (stateblock->changed.vertexShaderConstantsB & vshader->reg_maps.boolean_constants
+ && (vshader->reg_maps.boolean_constants
|| (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]
- && (stateblock->changed.vertexShaderConstantsI
- & vshader->reg_maps.integer_constants & ~vshader->reg_maps.local_int_consts))))
+ && (vshader->reg_maps.integer_constants & ~vshader->reg_maps.local_int_consts))))
{
TRACE("bool/integer vertex shader constants potentially modified, forcing shader reselection.\n");
- shader_arb_select(context,
- useVertexShader ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP,
- usePixelShader ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP);
+ shader_arb_select(priv, context, state);
}
else if (pshader
- && (stateblock->changed.pixelShaderConstantsB & pshader->reg_maps.boolean_constants
+ && (pshader->reg_maps.boolean_constants
|| (!gl_info->supported[NV_FRAGMENT_PROGRAM_OPTION]
- && (stateblock->changed.pixelShaderConstantsI
- & pshader->reg_maps.integer_constants & ~pshader->reg_maps.local_int_consts))))
+ && (pshader->reg_maps.integer_constants & ~pshader->reg_maps.local_int_consts))))
{
TRACE("bool/integer pixel shader constants potentially modified, forcing shader reselection.\n");
- shader_arb_select(context,
- useVertexShader ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP,
- usePixelShader ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP);
+ shader_arb_select(priv, context, state);
}
}
if (context != priv->last_context)
{
memset(priv->vshader_const_dirty, 1,
- sizeof(*priv->vshader_const_dirty) * device->d3d_vshader_constantF);
- priv->highest_dirty_vs_const = device->d3d_vshader_constantF;
+ sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count);
+ priv->highest_dirty_vs_const = d3d_info->limits.vs_uniform_count;
memset(priv->pshader_const_dirty, 1,
- sizeof(*priv->pshader_const_dirty) * device->d3d_pshader_constantF);
- priv->highest_dirty_ps_const = device->d3d_pshader_constantF;
+ sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count);
+ priv->highest_dirty_ps_const = d3d_info->limits.ps_uniform_count;
priv->last_context = context;
}
priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
priv->highest_dirty_ps_const, state->ps_consts_f, priv->pshader_const_dirty);
shader_arb_ps_local_constants(gl_shader, context, state, rt_height);
+
+ if (context->constant_update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP)
+ shader_arb_load_np2fixup_constants(&gl_shader->np2fixup_info, gl_info, state);
}
}
-static void shader_arb_load_constants(const struct wined3d_context *context, BOOL ps, BOOL vs)
+static void shader_arb_load_constants(void *shader_priv, struct wined3d_context *context,
+ const struct wined3d_state *state)
{
- shader_arb_load_constants_internal(context, ps, vs, FALSE);
+ BOOL vs = use_vs(state);
+ BOOL ps = use_ps(state);
+
+ shader_arb_load_constants_internal(shader_priv, context, state, ps, vs, FALSE);
}
static void shader_arb_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
{
struct wined3d_context *context = context_get_current();
struct shader_arb_priv *priv = device->shader_priv;
+ unsigned int i;
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F;
+ }
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
* context. On a context switch the old context will be fully dirtified */
{
struct wined3d_context *context = context_get_current();
struct shader_arb_priv *priv = device->shader_priv;
+ unsigned int i;
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
+ }
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
* context. On a context switch the old context will be fully dirtified */
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, start + count);
}
-static DWORD *local_const_mapping(const struct wined3d_shader *shader)
-{
- const struct wined3d_shader_lconst *lconst;
- DWORD *ret;
- DWORD idx = 0;
-
- if (shader->load_local_constsF || list_empty(&shader->constantsF))
- return NULL;
-
- ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * shader->limits.constant_float);
- if (!ret)
- {
- ERR("Out of memory\n");
- return NULL;
- }
-
- LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
- {
- ret[lconst->idx] = idx++;
- }
- return ret;
-}
-
/* Generate the variable & register declarations for the ARB_vertex_program output target */
-static DWORD shader_generate_arb_declarations(const struct wined3d_shader *shader,
+static void shader_generate_arb_declarations(const struct wined3d_shader *shader,
const struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_buffer *buffer,
- const struct wined3d_gl_info *gl_info, const DWORD *lconst_map,
- DWORD *num_clipplanes, const struct shader_arb_ctx_priv *ctx)
+ const struct wined3d_gl_info *gl_info, DWORD *num_clipplanes,
+ const struct shader_arb_ctx_priv *ctx)
{
- DWORD i, next_local = 0;
+ DWORD i;
char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
const struct wined3d_shader_lconst *lconst;
unsigned max_constantsF;
}
}
- /* Load local constants using the program-local space,
- * this avoids reloading them each time the shader is used
- */
- if (lconst_map)
+ if (!shader->load_local_constsF)
{
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
{
- shader_addline(buffer, "PARAM C%u = program.local[%u];\n", lconst->idx,
- lconst_map[lconst->idx]);
- next_local = max(next_local, lconst_map[lconst->idx] + 1);
+ 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]);
}
}
}
}
}
-
- return next_local;
}
static const char * const shift_tab[] = {
break;
case WINED3DSPR_COLOROUT:
- if (ctx->cur_ps_args->super.srgb_correction && !reg->idx[0].offset)
+ if (ctx->ps_post_process && !reg->idx[0].offset)
{
strcpy(register_name, "TMP_COLOR");
}
{
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
- const struct wined3d_shader *shader = ins->ctx->shader;
- const struct wined3d_texture *texture;
const char *tex_type;
BOOL np2_fixup = FALSE;
- struct wined3d_device *device = shader->device;
struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
const char *mod;
BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
+ const struct wined3d_shader *shader;
+ const struct wined3d_device *device;
+ const struct wined3d_gl_info *gl_info;
/* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */
if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS;
break;
case WINED3DSTT_2D:
- texture = device->stateBlock->state.textures[sampler_idx];
- if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
- {
+ shader = ins->ctx->shader;
+ device = shader->device;
+ gl_info = &device->adapter->gl_info;
+
+ if (pshader && priv->cur_ps_args->super.np2_fixup & (1 << sampler_idx)
+ && gl_info->supported[ARB_TEXTURE_RECTANGLE])
tex_type = "RECT";
- } else {
+ else
tex_type = "2D";
- }
if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
{
if (priv->cur_np2fixup_info->super.active & (1 << sampler_idx))
shader_arb_get_dst_param(ins, dst, dst_name);
shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
- /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
- if (shader_version <= WINED3D_SHADER_VERSION(1, 3) && ins->coissue)
+ if (shader_version <= WINED3D_SHADER_VERSION(1, 3) && ins->coissue
+ && ins->dst->write_mask != WINED3DSP_WRITEMASK_3)
{
shader_addline(buffer, "MOV%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name[1]);
}
}
else if (ins->dst[0].reg.type == WINED3DSPR_COLOROUT && !ins->dst[0].reg.idx[0].offset && pshader)
{
- if (ctx->cur_ps_args->super.srgb_correction && shader->u.ps.color0_mov)
+ if (ctx->ps_post_process && shader->u.ps.color0_mov)
{
- shader_addline(buffer, "#mov handled in srgb write code\n");
+ shader_addline(buffer, "#mov handled in srgb write or fog code\n");
return;
}
shader_hw_map2gl(ins);
}
}
+static void arbfp_add_linear_fog(struct wined3d_shader_buffer *buffer,
+ const char *fragcolor, const char *tmp)
+{
+ shader_addline(buffer, "SUB %s.x, state.fog.params.z, fragment.fogcoord.x;\n", tmp);
+ shader_addline(buffer, "MUL_SAT %s.x, %s.x, state.fog.params.w;\n", tmp, tmp);
+ shader_addline(buffer, "LRP %s.rgb, %s.x, %s, state.fog.color;\n", fragcolor, tmp, fragcolor);
+}
+
/* Context activation is done by the caller. */
static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
const struct wined3d_gl_info *gl_info, struct wined3d_shader_buffer *buffer,
const struct arb_ps_compile_args *args, struct arb_ps_compiled_shader *compiled)
{
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
- const struct wined3d_shader_lconst *lconst;
const DWORD *function = shader->function;
GLuint retval;
char fragcolor[16];
- DWORD *lconst_map = local_const_mapping(shader), next_local;
+ DWORD next_local = 0;
struct shader_arb_ctx_priv priv_ctx;
BOOL dcl_td = FALSE;
BOOL want_nv_prog = FALSE;
struct arb_pshader_private *shader_priv = shader->backend_data;
GLint errPos;
DWORD map;
+ BOOL custom_linear_fog = FALSE;
char srgbtmp[4][4];
unsigned int i, found = 0;
priv_ctx.cur_np2fixup_info = &compiled->np2fixup_info;
init_ps_input(shader, args, &priv_ctx);
list_init(&priv_ctx.control_frames);
+ priv_ctx.ps_post_process = args->super.srgb_correction;
/* Avoid enabling NV_fragment_program* if we do not need it.
*
if (reg_maps->shader_version.major < 3)
{
- switch(args->super.fog) {
- case FOG_OFF:
+ switch (args->super.fog)
+ {
+ case WINED3D_FFP_PS_FOG_OFF:
break;
- case FOG_LINEAR:
+ case WINED3D_FFP_PS_FOG_LINEAR:
+ if (gl_info->quirks & WINED3D_QUIRK_BROKEN_ARB_FOG)
+ {
+ custom_linear_fog = TRUE;
+ priv_ctx.ps_post_process = TRUE;
+ break;
+ }
shader_addline(buffer, "OPTION ARB_fog_linear;\n");
break;
- case FOG_EXP:
+ case WINED3D_FFP_PS_FOG_EXP:
shader_addline(buffer, "OPTION ARB_fog_exp;\n");
break;
- case FOG_EXP2:
+ case WINED3D_FFP_PS_FOG_EXP2:
shader_addline(buffer, "OPTION ARB_fog_exp2;\n");
break;
}
}
else
{
- if (args->super.srgb_correction)
+ if (priv_ctx.ps_post_process)
{
if (shader->u.ps.color0_mov)
{
}
/* Base Declarations */
- next_local = shader_generate_arb_declarations(shader, reg_maps,
- buffer, gl_info, lconst_map, NULL, &priv_ctx);
+ shader_generate_arb_declarations(shader, reg_maps, buffer, gl_info, NULL, &priv_ctx);
for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
{
priv_ctx.target_version >= NV2);
}
+ if (custom_linear_fog)
+ arbfp_add_linear_fog(buffer, fragcolor, "TA");
+
if(strcmp(fragcolor, "result.color")) {
shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
}
TRACE("Created hw pixel shader, prg=%d\n", retval);
/* Create the program and check for errors */
GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
- buffer->bsize, buffer->buffer));
+ buffer->content_size, buffer->buffer));
checkGLcall("glProgramStringARB()");
gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
if (!native) WARN("Program exceeds native resource limits.\n");
}
- /* Load immediate constants */
- if (lconst_map)
- {
- LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
- {
- const float *value = (const float *)lconst->value;
- GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value));
- checkGLcall("glProgramLocalParameter4fvARB");
- }
- HeapFree(GetProcessHeap(), 0, lconst_map);
- }
-
return retval;
}
return found_sig->idx;
}
-static void init_output_registers(const struct wined3d_shader *shader, DWORD sig_num,
+static void init_output_registers(const struct wined3d_shader *shader,
+ const struct wined3d_shader_signature_element *ps_input_sig,
struct shader_arb_ctx_priv *priv_ctx, struct arb_vs_compiled_shader *compiled)
{
unsigned int i, j;
"result.texcoord[0]", "result.texcoord[1]", "result.texcoord[2]", "result.texcoord[3]",
"result.texcoord[4]", "result.texcoord[5]", "result.texcoord[6]", "result.texcoord[7]"
};
- struct wined3d_device *device = shader->device;
- const struct wined3d_shader_signature_element *sig;
const char *semantic_name;
DWORD semantic_idx, reg_idx;
"result.color.primary", "result.color.secondary"
};
- if(sig_num == ~0)
+ if (!ps_input_sig)
{
TRACE("Pixel shader uses builtin varyings\n");
/* Map builtins to builtins */
return;
}
- /* Instead of searching for the signature in the signature list, read the one from the current pixel shader.
- * Its maybe not the shader where the signature came from, but it is the same signature and faster to find
- */
- sig = device->stateBlock->state.pixel_shader->input_signature;
TRACE("Pixel shader uses declared varyings\n");
/* Map builtin to declared. /dev/null the results by default to the TA temp reg */
for(i = 0; i < MAX_REG_INPUT; i++)
{
- semantic_name = sig[i].semantic_name;
- semantic_idx = sig[i].semantic_idx;
- reg_idx = sig[i].register_idx;
+ semantic_name = ps_input_sig[i].semantic_name;
+ semantic_idx = ps_input_sig[i].semantic_idx;
+ reg_idx = ps_input_sig[i].register_idx;
if (!semantic_name) continue;
/* If a declared input register is not written by builtin arguments, don't write to it.
for(j = 0; j < MAX_REG_INPUT; j++)
{
- if (!sig[j].semantic_name) continue;
+ if (!ps_input_sig[j].semantic_name) continue;
- if (!strcmp(sig[j].semantic_name, semantic_name)
- && sig[j].semantic_idx == shader->output_signature[i].semantic_idx)
+ if (!strcmp(ps_input_sig[j].semantic_name, semantic_name)
+ && ps_input_sig[j].semantic_idx == shader->output_signature[i].semantic_idx)
{
- priv_ctx->vs_output[i] = decl_idx_to_string[sig[j].register_idx];
+ priv_ctx->vs_output[i] = decl_idx_to_string[ps_input_sig[j].register_idx];
if (!strcmp(priv_ctx->vs_output[i], "result.color.primary")
|| !strcmp(priv_ctx->vs_output[i], "result.color.secondary"))
/* Context activation is done by the caller. */
static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader,
const struct wined3d_gl_info *gl_info, struct wined3d_shader_buffer *buffer,
- const struct arb_vs_compile_args *args, struct arb_vs_compiled_shader *compiled)
+ const struct arb_vs_compile_args *args, struct arb_vs_compiled_shader *compiled,
+ const struct wined3d_shader_signature_element *ps_input_sig)
{
const struct arb_vshader_private *shader_data = shader->backend_data;
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
struct shader_arb_priv *priv = shader->device->shader_priv;
- const struct wined3d_shader_lconst *lconst;
const DWORD *function = shader->function;
GLuint ret;
- DWORD next_local, *lconst_map = local_const_mapping(shader);
+ DWORD next_local = 0;
struct shader_arb_ctx_priv priv_ctx;
unsigned int i;
GLint errPos;
memset(&priv_ctx, 0, sizeof(priv_ctx));
priv_ctx.cur_vs_args = args;
list_init(&priv_ctx.control_frames);
- init_output_registers(shader, args->ps_signature, &priv_ctx, compiled);
+ init_output_registers(shader, ps_input_sig, &priv_ctx, compiled);
/* Create the hw ARB shader */
shader_addline(buffer, "!!ARBvp1.0\n");
shader_addline(buffer, "TEMP TB;\n");
/* Base Declarations */
- next_local = shader_generate_arb_declarations(shader, reg_maps, buffer,
- gl_info, lconst_map, &priv_ctx.vs_clipplanes, &priv_ctx);
+ shader_generate_arb_declarations(shader, reg_maps, buffer, gl_info,
+ &priv_ctx.vs_clipplanes, &priv_ctx);
for(i = 0; i < MAX_CONST_I; i++)
{
TRACE("Created hw vertex shader, prg=%d\n", ret);
/* Create the program and check for errors */
GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
- buffer->bsize, buffer->buffer));
+ buffer->content_size, buffer->buffer));
checkGLcall("glProgramStringARB()");
gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native));
checkGLcall("glGetProgramivARB()");
if (!native) WARN("Program exceeds native resource limits.\n");
-
- /* Load immediate constants */
- if (lconst_map)
- {
- LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
- {
- const float *value = (const float *)lconst->value;
- GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst_map[lconst->idx], value));
- }
- }
}
- HeapFree(GetProcessHeap(), 0, lconst_map);
return ret;
}
{
struct wined3d_device *device = shader->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
UINT i;
DWORD new_size;
struct arb_ps_compiled_shader *new_array;
shader_data->clamp_consts = shader->reg_maps.shader_version.major == 1;
if (shader->reg_maps.shader_version.major < 3)
- shader_data->input_signature_idx = ~0;
+ shader_data->input_signature_idx = ~0U;
else
shader_data->input_signature_idx = find_input_signature(priv, shader->input_signature);
TRACE("Shader got assigned input signature index %u\n", shader_data->input_signature_idx);
- if (!device->vs_clipping)
+ if (!d3d_info->vs_clipping)
shader_data->clipplane_emulation = shader_find_free_input_register(&shader->reg_maps,
- gl_info->limits.texture_stages - 1);
+ d3d_info->limits.ffp_blend_stages - 1);
else
shader_data->clipplane_emulation = ~0U;
}
shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
- pixelshader_update_samplers(&shader->reg_maps, device->stateBlock->state.textures);
+ pixelshader_update_samplers(shader, args->super.tex_types);
if (!shader_buffer_init(&buffer))
{
}
static struct arb_vs_compiled_shader *find_arb_vshader(struct wined3d_shader *shader,
- const struct arb_vs_compile_args *args)
+ 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->strided_streams.use_map;
+ DWORD use_map = device->stream_info.use_map;
UINT i;
DWORD new_size;
struct arb_vs_compiled_shader *new_array;
}
ret = shader_arb_generate_vshader(shader, gl_info, &buffer, args,
- &shader_data->gl_shaders[shader_data->num_gl_shaders]);
+ &shader_data->gl_shaders[shader_data->num_gl_shaders],
+ ps_input_sig);
shader_buffer_free(&buffer);
shader_data->gl_shaders[shader_data->num_gl_shaders].prgId = ret;
}
static void find_arb_ps_compile_args(const struct wined3d_state *state,
- const struct wined3d_shader *shader, struct arb_ps_compile_args *args)
+ const struct wined3d_context *context, const struct wined3d_shader *shader,
+ struct arb_ps_compile_args *args)
{
- struct wined3d_device *device = shader->device;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ 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;
* is quite expensive because it forces the driver to disable early Z discards. It is cheaper to
* duplicate the shader than have a no-op KIL instruction in every shader
*/
- if (!device->vs_clipping && use_vs(state)
+ if (!d3d_info->vs_clipping && use_vs(state)
&& state->render_states[WINED3D_RS_CLIPPING]
&& state->render_states[WINED3D_RS_CLIPPLANEENABLE])
args->clip = 1;
}
static void find_arb_vs_compile_args(const struct wined3d_state *state,
- const struct wined3d_shader *shader, struct arb_vs_compile_args *args)
+ 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_gl_info *gl_info = &device->adapter->gl_info;
+ 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;
else
{
args->ps_signature = ~0;
- if (!device->vs_clipping && device->adapter->fragment_pipe == &arbfp_fragment_pipeline)
+ if (!d3d_info->vs_clipping && adapter->fragment_pipe == &arbfp_fragment_pipeline)
{
- args->clip.boolclip.clip_texcoord = ffp_clip_emul(state) ? gl_info->limits.texture_stages : 0;
+ args->clip.boolclip.clip_texcoord = ffp_clip_emul(state) ? d3d_info->limits.ffp_blend_stages : 0;
}
/* Otherwise: Setting boolclip_compare set clip_texcoord to 0 */
}
}
/* Context activation is done by the caller. */
-static void shader_arb_select(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
- enum wined3d_shader_mode fragment_mode)
+static void shader_arb_select(void *shader_priv, struct wined3d_context *context,
+ const struct wined3d_state *state)
{
- struct wined3d_device *device = context->swapchain->device;
- struct shader_arb_priv *priv = device->shader_priv;
+ struct shader_arb_priv *priv = shader_priv;
const struct wined3d_gl_info *gl_info = context->gl_info;
- const struct wined3d_state *state = &device->stateBlock->state;
int i;
/* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */
- if (fragment_mode == WINED3D_SHADER_MODE_SHADER)
+ if (use_ps(state))
{
struct wined3d_shader *ps = state->pixel_shader;
struct arb_ps_compile_args compile_args;
struct arb_ps_compiled_shader *compiled;
TRACE("Using pixel shader %p.\n", ps);
- find_arb_ps_compile_args(state, ps, &compile_args);
+ find_arb_ps_compile_args(state, context, ps, &compile_args);
compiled = find_arb_pshader(ps, &compile_args);
priv->current_fprogram_id = compiled->prgId;
priv->compiled_fprog = compiled;
gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);");
- TRACE("(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n",
- device, priv->current_fprogram_id);
+ TRACE("Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n", priv->current_fprogram_id);
/* Pixel Shader 1.x constants are clamped to [-1;1], Pixel Shader 2.0 constants are not. If switching between
* a 1.x and newer shader, reload the first 8 constants
priv->pshader_const_dirty[i] = 1;
}
/* Also takes care of loading local constants */
- shader_arb_load_constants_internal(context, TRUE, FALSE, TRUE);
+ shader_arb_load_constants_internal(shader_priv, context, state, TRUE, FALSE, TRUE);
}
else
{
/* Force constant reloading for the NP2 fixup (see comment in shader_glsl_select for more info) */
if (compiled->np2fixup_info.super.active)
- shader_arb_load_np2fixup_constants(priv, gl_info, state);
+ context->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP;
+
+ if (ps->load_local_constsF)
+ context->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
}
else
{
checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
priv->current_fprogram_id = 0;
}
- priv->fragment_pipe->enable_extension(gl_info, fragment_mode == WINED3D_SHADER_MODE_FFP);
+ priv->fragment_pipe->enable_extension(gl_info, TRUE);
}
- if (vertex_mode == WINED3D_SHADER_MODE_SHADER)
+ if (use_vs(state))
{
struct wined3d_shader *vs = state->vertex_shader;
struct arb_vs_compile_args compile_args;
struct arb_vs_compiled_shader *compiled;
+ const struct wined3d_shader_signature_element *ps_input_sig;
TRACE("Using vertex shader %p\n", vs);
- find_arb_vs_compile_args(state, vs, &compile_args);
- compiled = find_arb_vshader(vs, &compile_args);
+ find_arb_vs_compile_args(state, context, vs, &compile_args);
+
+ /* Instead of searching for the signature in the signature list, read the one from the
+ * current pixel shader. It's maybe not the shader where the signature came from, but it
+ * is the same signature and faster to find. */
+ if (compile_args.ps_signature == ~0U)
+ ps_input_sig = NULL;
+ else
+ ps_input_sig = state->pixel_shader->input_signature;
+
+ compiled = find_arb_vshader(vs, &compile_args, ps_input_sig);
priv->current_vprogram_id = compiled->prgId;
priv->compiled_vprog = compiled;
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);");
+ priv->vertex_pipe->vp_enable(gl_info, FALSE);
+
/* Enable OpenGL vertex programs */
gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_ARB);
checkGLcall("glEnable(GL_VERTEX_PROGRAM_ARB);");
- TRACE("(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n", device, priv->current_vprogram_id);
+ TRACE("Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n", priv->current_vprogram_id);
shader_arb_vs_local_constants(compiled, context, state);
if(priv->last_vs_color_unclamp != compiled->need_color_unclamp) {
FIXME("vertex color clamp needs to be changed, but extension not supported.\n");
}
}
+
+ if (vs->load_local_constsF)
+ context->constant_update_mask |= WINED3D_SHADER_CONST_VS_F;
}
- else if (gl_info->supported[ARB_VERTEX_PROGRAM])
+ else
+ {
+ if (gl_info->supported[ARB_VERTEX_PROGRAM])
+ {
+ priv->current_vprogram_id = 0;
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
+ }
+ priv->vertex_pipe->vp_enable(gl_info, TRUE);
+ }
+}
+
+
+/* Context activation is done by the caller. */
+static void shader_arb_disable(void *shader_priv, struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct shader_arb_priv *priv = shader_priv;
+
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
+ priv->current_fprogram_id = 0;
+ }
+ priv->fragment_pipe->enable_extension(gl_info, FALSE);
+
+ if (gl_info->supported[ARB_VERTEX_PROGRAM])
{
priv->current_vprogram_id = 0;
gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB);
checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
}
+ priv->vertex_pipe->vp_enable(gl_info, FALSE);
+
+ if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT] && priv->last_vs_color_unclamp)
+ {
+ GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FIXED_ONLY_ARB));
+ checkGLcall("glClampColorARB");
+ priv->last_vs_color_unclamp = FALSE;
+ }
+
+ context->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
+ | (1 << WINED3D_SHADER_TYPE_VERTEX)
+ | (1 << WINED3D_SHADER_TYPE_GEOMETRY);
}
/* Context activation is done by the caller. */
sig_tree_compare
};
-static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe)
+static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+ const struct fragment_pipeline *fragment_pipe)
{
struct shader_arb_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv));
struct fragment_caps fragment_caps;
- void *fragment_priv;
+ void *vertex_priv, *fragment_priv;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+
+ if (!(vertex_priv = vertex_pipe->vp_alloc(&arb_program_shader_backend, priv)))
+ {
+ ERR("Failed to initialize vertex pipe.\n");
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
if (!(fragment_priv = fragment_pipe->alloc_private(&arb_program_shader_backend, priv)))
{
ERR("Failed to initialize fragment pipe.\n");
+ vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv);
return E_FAIL;
}
priv->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
- sizeof(*priv->vshader_const_dirty) * device->d3d_vshader_constantF);
+ sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count);
if (!priv->vshader_const_dirty)
goto fail;
memset(priv->vshader_const_dirty, 1,
- sizeof(*priv->vshader_const_dirty) * device->d3d_vshader_constantF);
+ sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count);
priv->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
- sizeof(*priv->pshader_const_dirty) * device->d3d_pshader_constantF);
+ sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count);
if (!priv->pshader_const_dirty)
goto fail;
memset(priv->pshader_const_dirty, 1,
- sizeof(*priv->pshader_const_dirty) * device->d3d_pshader_constantF);
+ sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count);
if(wine_rb_init(&priv->signature_tree, &sig_tree_functions) == -1)
{
goto fail;
}
+ priv->vertex_pipe = vertex_pipe;
+ priv->fragment_pipe = fragment_pipe;
fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps);
priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
+
+ device->vertex_priv = vertex_priv;
device->fragment_priv = fragment_priv;
- priv->fragment_pipe = fragment_pipe;
device->shader_priv = priv;
+
return WINED3D_OK;
fail:
HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
fragment_pipe->free_private(device);
+ vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv);
return E_OUTOFMEMORY;
}
HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
priv->fragment_pipe->free_private(device);
+ priv->vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, device->shader_priv);
}
-static void shader_arb_context_destroyed(void *shader_priv, const struct wined3d_context *context)
+static BOOL shader_arb_allocate_context_data(struct wined3d_context *context)
{
- struct shader_arb_priv *priv = shader_priv;
+ return TRUE;
+}
+
+static void shader_arb_free_context_data(struct wined3d_context *context)
+{
+ struct shader_arb_priv *priv = context->swapchain->device->shader_priv;
if (priv->last_context == context)
priv->last_context = NULL;
{
shader_arb_handle_instruction,
shader_arb_select,
+ shader_arb_disable,
shader_arb_select_depth_blt,
shader_arb_deselect_depth_blt,
shader_arb_update_float_vertex_constants,
shader_arb_update_float_pixel_constants,
shader_arb_load_constants,
- shader_arb_load_np2fixup_constants,
shader_arb_destroy,
shader_arb_alloc,
shader_arb_free,
- shader_arb_context_destroyed,
+ shader_arb_allocate_context_data,
+ shader_arb_free_context_data,
shader_arb_get_caps,
shader_arb_color_fixup_supported,
shader_arb_has_ffp_proj_control,
const struct wined3d_gl_info *gl_info = context->gl_info;
float mat[2][2];
- if (use_ps(state))
- {
- /* The pixel shader has to know the bump env matrix. Do a constants
- * update. */
- if (stage && (state->pixel_shader->reg_maps.bumpmat & (1 << stage)))
- context->load_constants = 1;
+ context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV;
- if(device->shader_backend == &arb_program_shader_backend) {
- /* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
- return;
- }
- }
- else if (device->shader_backend == &arb_program_shader_backend)
+ if (device->shader_backend == &arb_program_shader_backend)
{
struct shader_arb_priv *priv = device->shader_priv;
+
+ /* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants. */
+ if (use_ps(state))
+ return;
+
priv->pshader_const_dirty[ARB_FFP_CONST_BUMPMAT(stage)] = 1;
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_BUMPMAT(stage) + 1);
}
const struct wined3d_gl_info *gl_info = context->gl_info;
float param[4];
- if (use_ps(state))
- {
- /* The pixel shader has to know the luminance offset. Do a constants
- * update. */
- if (stage && (state->pixel_shader->reg_maps.luminanceparams & (1 << stage)))
- context->load_constants = 1;
+ context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV;
- if(device->shader_backend == &arb_program_shader_backend) {
- /* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
- return;
- }
- }
- else if (device->shader_backend == &arb_program_shader_backend)
+ if (device->shader_backend == &arb_program_shader_backend)
{
struct shader_arb_priv *priv = device->shader_priv;
+
+ /* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants. */
+ if (use_ps(state))
+ return;
+
priv->pshader_const_dirty[ARB_FFP_CONST_LUMINANCE(stage)] = 1;
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_LUMINANCE(stage) + 1);
}
BOOL op_equal;
const char *final_combiner_src = "ret";
GLint pos;
+ BOOL custom_linear_fog = FALSE;
/* Find out which textures are read */
for (stage = 0; stage < MAX_TEXTURES; ++stage)
shader_addline(&buffer, "!!ARBfp1.0\n");
- switch(settings->fog) {
- case FOG_OFF: break;
- case FOG_LINEAR: shader_addline(&buffer, "OPTION ARB_fog_linear;\n"); break;
- case FOG_EXP: shader_addline(&buffer, "OPTION ARB_fog_exp;\n"); break;
- case FOG_EXP2: shader_addline(&buffer, "OPTION ARB_fog_exp2;\n"); break;
+ switch (settings->fog)
+ {
+ case WINED3D_FFP_PS_FOG_OFF: break;
+ case WINED3D_FFP_PS_FOG_LINEAR:
+ if (gl_info->quirks & WINED3D_QUIRK_BROKEN_ARB_FOG)
+ {
+ custom_linear_fog = TRUE;
+ break;
+ }
+ shader_addline(&buffer, "OPTION ARB_fog_linear;\n");
+ break;
+
+ case WINED3D_FFP_PS_FOG_EXP: shader_addline(&buffer, "OPTION ARB_fog_exp;\n"); break;
+ case WINED3D_FFP_PS_FOG_EXP2: shader_addline(&buffer, "OPTION ARB_fog_exp2;\n"); break;
default: FIXME("Unexpected fog setting %d\n", settings->fog);
}
}
}
- if(settings->sRGB_write) {
+ if (settings->sRGB_write || custom_linear_fog)
+ {
shader_addline(&buffer, "MAD ret, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
- arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg", FALSE);
+ if (settings->sRGB_write)
+ arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg", FALSE);
+ if (custom_linear_fog)
+ arbfp_add_linear_fog(&buffer, "ret", "arg0");
shader_addline(&buffer, "MOV result.color, ret;\n");
- } else {
- shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
+ }
+ else
+ {
+ shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n",
+ final_combiner_src);
}
/* Footer */
}
else if (use_pshader)
{
- context->select_shader = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
return;
}
{
/* Find or create a shader implementing the fixed function pipeline
* settings, then activate it. */
- gen_ffp_frag_op(device, state, &settings, FALSE);
+ gen_ffp_frag_op(context, state, &settings, FALSE);
desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
if(!desc) {
struct arbfp_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
context->last_was_pshader = TRUE;
}
- context->select_shader = 1;
- context->load_constants = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
/* We can't link the fog states to the fragment state directly since the
static void state_arbfp_fog(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
enum fogsource new_source;
+ DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
+ DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
new_source = FOGSOURCE_FFP;
}
- if (new_source != context->fog_source)
+ if (new_source != context->fog_source || fogstart == fogend)
{
context->fog_source = new_source;
state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
{
BYTE table[256][4];
struct wined3d_device *device = surface->resource.device;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ 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;
d3dfmt_p8_init_palette(surface, table, colorkey);
- if (gl_info->supported[APPLE_CLIENT_STORAGE])
- {
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
- }
-
if (!priv->palette_texture)
gl_info->gl_ops.gl.p_glGenTextures(1, &priv->palette_texture);
/* TODO: avoid unneeded uploads in the future by adding some SFLAG_PALETTE_DIRTY mechanism */
gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table);
- if (gl_info->supported[APPLE_CLIENT_STORAGE])
- {
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
- }
-
/* Switch back to unit 0 in which the 2D texture will be stored. */
context_active_texture(context, gl_info, 0);
}
const struct wined3d_gl_info *gl_info = context->gl_info;
GLenum textype;
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
- textype = surface->container.u.texture->target;
+ if (surface->container)
+ textype = surface->container->target;
else
textype = surface->texture_target;
arbfp_blit_unset(context->gl_info);
if (wined3d_settings.strict_draw_ordering
- || (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN
- && (dst_surface->container.u.swapchain->front_buffer == dst_surface)))
+ || (dst_surface->swapchain && (dst_surface->swapchain->front_buffer == dst_surface)))
context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
{
const struct wined3d_device *device = context->swapchain->device;
const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
const struct atifs_ffp_desc *desc;
struct ffp_frag_settings settings;
struct atifs_private_data *priv = device->fragment_priv;
DWORD mapped_stage;
unsigned int i;
- gen_ffp_frag_op(device, state, &settings, TRUE);
+ gen_ffp_frag_op(context, state, &settings, TRUE);
desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
if(!desc) {
struct atifs_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
return;
}
new_desc->num_textures_used = 0;
- for (i = 0; i < gl_info->limits.texture_stages; ++i)
+ for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i)
{
if (settings.op[i].cop == WINED3D_TOP_DISABLE)
break;
* startup, and blitting disables all shaders and dirtifies all shader
* states. If atifs can deal with this it keeps the rest of the code
* simpler. */
- context->select_shader = 1;
- context->load_constants = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
static void atifs_srgbwriteenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
}
/* Context activation is done by the caller. */
-static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *context)
+static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *cb_ctx)
{
- struct wined3d_device *device = context;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_gl_info *gl_info = cb_ctx;
struct atifs_ffp_desc *entry_ati = WINE_RB_ENTRY_VALUE(entry, struct atifs_ffp_desc, parent.entry);
GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader));
{
struct atifs_private_data *priv = device->fragment_priv;
- wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, device);
+ wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, &device->adapter->gl_info);
HeapFree(GetProcessHeap(), 0, priv);
device->fragment_priv = NULL;
* Copyright 2002-2005 Raphael Junqueira
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
- * Copyright 2007-2010 Stefan Dösinger for CodeWeavers
+ * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
* Copyright 2009-2010 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+#define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */
+#define WINED3D_BUFFER_CREATEBO 0x02 /* Create a buffer object for this buffer. */
+#define WINED3D_BUFFER_DOUBLEBUFFER 0x04 /* Keep both a buffer object and a system memory copy for this buffer. */
+#define WINED3D_BUFFER_FLUSH 0x08 /* Manual unmap flushing. */
+#define WINED3D_BUFFER_DISCARD 0x10 /* A DISCARD lock has occurred since the last preload. */
+#define WINED3D_BUFFER_NOSYNC 0x20 /* All locks since the last preload had NOOVERWRITE set. */
+#define WINED3D_BUFFER_APPLESYNC 0x40 /* Using sync as in GL_APPLE_flush_buffer_range. */
+
#define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */
#define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */
#define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */
#define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */
-static inline BOOL buffer_add_dirty_area(struct wined3d_buffer *This, UINT offset, UINT size)
+static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size)
{
- if (!This->buffer_object) return TRUE;
+ if (!offset && !size)
+ goto invalidate_all;
- if (This->maps_size <= This->modified_areas)
+ if (offset > buffer->resource.size || offset + size > buffer->resource.size)
{
- void *new = HeapReAlloc(GetProcessHeap(), 0, This->maps,
- This->maps_size * 2 * sizeof(*This->maps));
- if (!new)
- {
- ERR("Out of memory\n");
- return FALSE;
- }
- else
- {
- This->maps = new;
- This->maps_size *= 2;
- }
+ WARN("Invalid range specified, invalidating entire buffer.\n");
+ goto invalidate_all;
}
- if(offset > This->resource.size || offset + size > This->resource.size)
- {
- WARN("Invalid range dirtified, marking entire buffer dirty\n");
- offset = 0;
- size = This->resource.size;
- }
- else if(!offset && !size)
+ if (buffer->modified_areas >= buffer->maps_size)
{
- size = This->resource.size;
+ struct wined3d_map_range *new;
+
+ if (!(new = HeapReAlloc(GetProcessHeap(), 0, buffer->maps, 2 * buffer->maps_size * sizeof(*buffer->maps))))
+ {
+ ERR("Failed to allocate maps array, invalidating entire buffer.\n");
+ goto invalidate_all;
+ }
+
+ buffer->maps = new;
+ buffer->maps_size *= 2;
}
- This->maps[This->modified_areas].offset = offset;
- This->maps[This->modified_areas].size = size;
- This->modified_areas++;
- return TRUE;
+ buffer->maps[buffer->modified_areas].offset = offset;
+ buffer->maps[buffer->modified_areas].size = size;
+ ++buffer->modified_areas;
+ return;
+
+invalidate_all:
+ buffer->modified_areas = 1;
+ buffer->maps[0].offset = 0;
+ buffer->maps[0].size = buffer->resource.size;
}
static inline void buffer_clear_dirty_areas(struct wined3d_buffer *This)
/* Context activation is done by the caller. */
static void buffer_create_buffer_object(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
{
- GLenum error, gl_usage;
+ GLenum gl_usage = GL_STATIC_DRAW_ARB;
+ GLenum error;
TRACE("Creating an OpenGL vertex buffer object for wined3d_buffer %p with usage %s.\n",
This, debug_d3dusage(This->resource.usage));
goto fail;
}
- /* Don't use static, because dx apps tend to update the buffer
- * quite often even if they specify 0 usage.
- */
- if(This->resource.usage & WINED3DUSAGE_DYNAMIC)
+ if (This->resource.usage & WINED3DUSAGE_DYNAMIC)
{
- TRACE("Gl usage = GL_STREAM_DRAW_ARB\n");
+ TRACE("Buffer has WINED3DUSAGE_DYNAMIC set.\n");
gl_usage = GL_STREAM_DRAW_ARB;
if(gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
}
/* No setup is needed here for GL_ARB_map_buffer_range */
}
- else
- {
- TRACE("Gl usage = GL_DYNAMIC_DRAW_ARB\n");
- gl_usage = GL_DYNAMIC_DRAW_ARB;
- }
/* Reserve memory for the buffer. The amount of data won't change
* so we are safe with calling glBufferData once and
This->buffer_object_size = This->resource.size;
This->buffer_object_usage = gl_usage;
- if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)
+ if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER)
{
- if(!buffer_add_dirty_area(This, 0, 0))
- {
- ERR("buffer_add_dirty_area failed, this is not expected\n");
- goto fail;
- }
+ buffer_invalidate_bo_range(This, 0, 0);
}
else
{
- HeapFree(GetProcessHeap(), 0, This->resource.heapMemory);
+ wined3d_resource_free_sysmem(This->resource.heap_memory);
This->resource.allocatedMemory = NULL;
- This->resource.heapMemory = NULL;
+ This->resource.heap_memory = NULL;
}
return;
}
static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
- UINT attrib_idx, const BOOL check_d3dcolor, const BOOL is_ffp_position, const BOOL is_ffp_color,
+ UINT attrib_idx, const BOOL check_d3dcolor, const BOOL check_position, const BOOL is_ffp_color,
DWORD *stride_this_run)
{
const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
if (!is_ffp_color) FIXME("Test for non-color fixed function WINED3DFMT_B8G8R8A8_UNORM format\n");
}
- else if (is_ffp_position && si->position_transformed)
+ else if (check_position && si->position_transformed)
{
if (format != WINED3DFMT_R32G32B32A32_FLOAT)
{
static BOOL buffer_find_decl(struct wined3d_buffer *This)
{
struct wined3d_device *device = This->resource.device;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct wined3d_stream_info *si = &device->strided_streams;
- const struct wined3d_state *state = &device->stateBlock->state;
+ 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;
- BOOL support_d3dcolor = gl_info->supported[ARB_VERTEX_ARRAY_BGRA];
/* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer.
* Once we have our declaration there is no need to look it up again. Index buffers also never need
*/
ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
- TRUE, TRUE, FALSE, &stride_this_run) || ret;
+ TRUE, !support_xyzrhw, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
/* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */
if(This->resource.allocatedMemory) return This->resource.allocatedMemory;
- This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
- This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ This->resource.heap_memory = wined3d_resource_allocate_sysmem(This->resource.size);
+ This->resource.allocatedMemory = This->resource.heap_memory;
if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
device_invalidate_state(This->resource.device, STATE_INDEXBUFFER);
ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
{
ULONG refcount = InterlockedDecrement(&buffer->resource.ref);
+ struct wined3d_context *context;
TRACE("%p decreasing refcount to %u.\n", buffer, refcount);
if (!refcount)
{
- buffer_unload(&buffer->resource);
+ if (buffer->buffer_object)
+ {
+ context = context_acquire(buffer->resource.device, NULL);
+ delete_gl_buffer(buffer, context->gl_info);
+ context_release(context);
+
+ HeapFree(GetProcessHeap(), 0, buffer->conversion_map);
+ }
+
resource_cleanup(&buffer->resource);
buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent);
HeapFree(GetProcessHeap(), 0, buffer->maps);
return;
}
- /* The declaration changed, reload the whole buffer */
- WARN("Reloading buffer because of decl change\n");
- buffer_clear_dirty_areas(buffer);
- if (!buffer_add_dirty_area(buffer, 0, 0))
- {
- ERR("buffer_add_dirty_area failed, this is not expected\n");
- return;
- }
+ /* The declaration changed, reload the whole buffer. */
+ WARN("Reloading buffer because of a vertex declaration change.\n");
+ buffer_invalidate_bo_range(buffer, 0, 0);
+
/* Avoid unfenced updates, we might overwrite more areas of the buffer than the application
* cleared for unsynchronized updates
*/
context_release(context);
}
-static DWORD buffer_sanitize_flags(const struct wined3d_buffer *buffer, DWORD flags)
-{
- /* Not all flags make sense together, but Windows never returns an error.
- * Catch the cases that could cause issues. */
- if (flags & WINED3D_MAP_READONLY)
- {
- if (flags & WINED3D_MAP_DISCARD)
- {
- WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
- return 0;
- }
- if (flags & WINED3D_MAP_NOOVERWRITE)
- {
- WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
- return 0;
- }
- }
- else if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
- == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
- {
- WARN("WINED3D_MAP_DISCARD and WINED3D_MAP_NOOVERWRITE used together, ignoring.\n");
- return 0;
- }
- else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)
- && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
- {
- WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
- return 0;
- }
-
- return flags;
-}
-
-static GLbitfield buffer_gl_map_flags(DWORD d3d_flags)
-{
- GLbitfield ret = 0;
-
- if (!(d3d_flags & WINED3D_MAP_READONLY))
- ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
- if (!(d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
- ret |= GL_MAP_READ_BIT;
-
- if (d3d_flags & WINED3D_MAP_DISCARD)
- ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
- if (d3d_flags & WINED3D_MAP_NOOVERWRITE)
- ret |= GL_MAP_UNSYNCHRONIZED_BIT;
-
- return ret;
-}
-
struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer)
{
TRACE("buffer %p.\n", buffer);
TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags);
- flags = buffer_sanitize_flags(buffer, flags);
- if (!(flags & WINED3D_MAP_READONLY))
- {
- if (flags & WINED3D_MAP_DISCARD)
- {
- /* DISCARD invalidates the entire buffer, regardless of the
- * specified offset and size. Some applications also depend on the
- * entire buffer being uploaded in that case. Two such
- * applications are Port Royale and Darkstar One. */
- if (!buffer_add_dirty_area(buffer, 0, 0))
- return E_OUTOFMEMORY;
- }
- else
- {
- if (!buffer_add_dirty_area(buffer, offset, size))
- return E_OUTOFMEMORY;
- }
- }
-
+ flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags);
count = ++buffer->resource.map_count;
if (buffer->buffer_object)
{
+ /* DISCARD invalidates the entire buffer, regardless of the specified
+ * offset and size. Some applications also depend on the entire buffer
+ * being uploaded in that case. Two such applications are Port Royale
+ * and Darkstar One. */
+ if (flags & WINED3D_MAP_DISCARD)
+ buffer_invalidate_bo_range(buffer, 0, 0);
+ else if (!(flags & WINED3D_MAP_READONLY))
+ buffer_invalidate_bo_range(buffer, offset, size);
+
if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER))
{
if (count == 1)
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
- GLbitfield mapflags = buffer_gl_map_flags(flags);
+ GLbitfield mapflags = wined3d_resource_gl_map_flags(flags);
buffer->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint,
0, buffer->resource.size, mapflags));
checkGLcall("glMapBufferRange");
/*
* Context and render target management in wined3d
*
- * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_synchronous);
+
+#define WINED3D_MAX_FBO_ENTRIES 64
static DWORD wined3d_context_tls_idx;
/* FBO helper functions */
/* Context activation is done by the caller. */
-static void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo)
+static void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint fbo)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
- GLuint f;
-
- if (!fbo)
- {
- f = 0;
- }
- else
- {
- if (!*fbo)
- {
- gl_info->fbo_ops.glGenFramebuffers(1, fbo);
- checkGLcall("glGenFramebuffers()");
- TRACE("Created FBO %u.\n", *fbo);
- }
- f = *fbo;
- }
switch (target)
{
case GL_READ_FRAMEBUFFER:
- if (context->fbo_read_binding == f) return;
- context->fbo_read_binding = f;
+ if (context->fbo_read_binding == fbo) return;
+ context->fbo_read_binding = fbo;
break;
case GL_DRAW_FRAMEBUFFER:
- if (context->fbo_draw_binding == f) return;
- context->fbo_draw_binding = f;
+ if (context->fbo_draw_binding == fbo) return;
+ context->fbo_draw_binding = fbo;
break;
case GL_FRAMEBUFFER:
- if (context->fbo_read_binding == f
- && context->fbo_draw_binding == f) return;
- context->fbo_read_binding = f;
- context->fbo_draw_binding = f;
+ if (context->fbo_read_binding == fbo
+ && context->fbo_draw_binding == fbo) return;
+ context->fbo_read_binding = fbo;
+ context->fbo_draw_binding = fbo;
break;
default:
break;
}
- gl_info->fbo_ops.glBindFramebuffer(target, f);
+ gl_info->fbo_ops.glBindFramebuffer(target, fbo);
checkGLcall("glBindFramebuffer()");
}
}
/* Context activation is done by the caller. */
-static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo)
+static void context_destroy_fbo(struct wined3d_context *context, GLuint fbo)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
context_bind_fbo(context, GL_FRAMEBUFFER, fbo);
context_clean_fbo_attachments(gl_info, GL_FRAMEBUFFER);
- context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
+ context_bind_fbo(context, GL_FRAMEBUFFER, 0);
- gl_info->fbo_ops.glDeleteFramebuffers(1, fbo);
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
checkGLcall("glDeleteFramebuffers()");
}
entry->location = location;
entry->rt_mask = context_generate_rt_mask(GL_COLOR_ATTACHMENT0);
entry->attached = FALSE;
- entry->id = 0;
+ gl_info->fbo_ops.glGenFramebuffers(1, &entry->id);
+ checkGLcall("glGenFramebuffers()");
+ TRACE("Created FBO %u.\n", entry->id);
return entry;
}
{
const struct wined3d_gl_info *gl_info = context->gl_info;
- context_bind_fbo(context, target, &entry->id);
+ context_bind_fbo(context, target, entry->id);
context_clean_fbo_attachments(gl_info, target);
memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
{
if (entry->id)
{
- TRACE("Destroy FBO %d\n", entry->id);
- context_destroy_fbo(context, &entry->id);
+ TRACE("Destroy FBO %u.\n", entry->id);
+ context_destroy_fbo(context, entry->id);
}
--context->fbo_entry_count;
list_remove(&entry->entry);
{
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int i;
+ GLuint read_binding, draw_binding;
- context_bind_fbo(context, target, &entry->id);
+ if (entry->attached)
+ {
+ context_bind_fbo(context, target, entry->id);
+ return;
+ }
- if (entry->attached) return;
+ read_binding = context->fbo_read_binding;
+ draw_binding = context->fbo_draw_binding;
+ context_bind_fbo(context, GL_FRAMEBUFFER, entry->id);
/* Apply render targets */
for (i = 0; i < gl_info->limits.buffers; ++i)
surface_set_compatible_renderbuffer(entry->depth_stencil, entry->render_targets[0]);
context_attach_depth_stencil_fbo(context, target, entry->depth_stencil, entry->location);
+ /* Set valid read and draw buffer bindings to satisfy pedantic pre-ES2_compatibility
+ * GL contexts requirements. */
+ glReadBuffer(GL_NONE);
+ context_set_draw_buffer(context, GL_NONE);
+ if (target != GL_FRAMEBUFFER)
+ {
+ if (target == GL_READ_FRAMEBUFFER)
+ context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, draw_binding);
+ else
+ context_bind_fbo(context, GL_READ_FRAMEBUFFER, read_binding);
+ }
+
entry->attached = TRUE;
}
if (context->rebind_fbo)
{
- context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
+ context_bind_fbo(context, GL_FRAMEBUFFER, 0);
context->rebind_fbo = FALSE;
}
if (location == SFLAG_INDRAWABLE)
{
context->current_fbo = NULL;
- context_bind_fbo(context, target, NULL);
+ context_bind_fbo(context, target, 0);
}
else
{
}
}
+BOOL context_debug_output_enabled(const struct wined3d_gl_info *gl_info)
+{
+ return gl_info->supported[ARB_DEBUG_OUTPUT]
+ && (ERR_ON(d3d) || FIXME_ON(d3d) || WARN_ON(d3d_perf));
+}
+
+static void WINE_GLAPI wined3d_debug_callback(GLenum source, GLenum type, GLuint id,
+ GLenum severity, GLsizei length, const char *message, void *ctx)
+{
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR_ARB:
+ ERR("%p: %s.\n", ctx, debugstr_an(message, length));
+ break;
+
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
+ case GL_DEBUG_TYPE_PORTABILITY_ARB:
+ FIXME("%p: %s.\n", ctx, debugstr_an(message, length));
+ break;
+
+ case GL_DEBUG_TYPE_PERFORMANCE_ARB:
+ WARN_(d3d_perf)("%p: %s.\n", ctx, debugstr_an(message, length));
+ break;
+
+ default:
+ FIXME("ctx %p, type %#x: %s.\n", ctx, type, debugstr_an(message, length));
+ break;
+ }
+}
+
/* 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)
const struct wined3d_format *color_format;
struct wined3d_context *ret;
BOOL auxBuffers = FALSE;
+ HGLRC ctx, share_ctx;
int pixel_format;
unsigned int s;
int swap_interval;
DWORD state;
- HGLRC ctx;
HDC hdc;
TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle);
list_init(&ret->fbo_list);
list_init(&ret->fbo_destroy_list);
+ if (!device->shader_backend->shader_allocate_context_data(ret))
+ {
+ ERR("Failed to allocate shader backend context data.\n");
+ goto out;
+ }
+
if (!(hdc = GetDC(swapchain->win_handle)))
{
WARN("Failed to retireve device context, trying swapchain backup.\n");
goto out;
}
- if (!(ctx = wglCreateContext(hdc)))
+ share_ctx = device->context_count ? device->contexts[0]->glCtx : NULL;
+ if (gl_info->p_wglCreateContextAttribsARB)
{
- ERR("Failed to create a WGL context.\n");
- context_release(ret);
- goto out;
- }
+ unsigned int ctx_attrib_idx = 0;
+ GLint ctx_attribs[3];
- if (device->context_count)
+ if (context_debug_output_enabled(gl_info))
+ {
+ ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
+ ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_DEBUG_BIT_ARB;
+ }
+ ctx_attribs[ctx_attrib_idx] = 0;
+
+ if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
+ {
+ ERR("Failed to create a WGL context.\n");
+ context_release(ret);
+ goto out;
+ }
+ }
+ else
{
- if (!wglShareLists(device->contexts[0]->glCtx, ctx))
+ if (!(ctx = wglCreateContext(hdc)))
+ {
+ ERR("Failed to create a WGL context.\n");
+ context_release(ret);
+ goto out;
+ }
+
+ if (share_ctx && !wglShareLists(share_ctx, ctx))
{
- ERR("wglShareLists(%p, %p) failed, last error %#x.\n",
- device->contexts[0]->glCtx, ctx, GetLastError());
+ ERR("wglShareLists(%p, %p) failed, last error %#x.\n", share_ctx, ctx, GetLastError());
context_release(ret);
if (!wglDeleteContext(ctx))
ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError());
}
ret->gl_info = gl_info;
+ ret->d3d_info = &device->adapter->d3d_info;
ret->state_table = device->StateTable;
/* Mark all states dirty to force a proper initialization of the states
goto out;
}
+ if (context_debug_output_enabled(gl_info))
+ {
+ GL_EXTCALL(glDebugMessageCallbackARB(wined3d_debug_callback, ret));
+ if (TRACE_ON(d3d_synchronous))
+ gl_info->gl_ops.gl.p_glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE));
+ if (ERR_ON(d3d))
+ {
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ }
+ if (FIXME_ON(d3d))
+ {
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PORTABILITY_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ }
+ if (WARN_ON(d3d_perf))
+ {
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ }
+ }
+
switch (swapchain->desc.swap_interval)
{
case WINED3DPRESENT_INTERVAL_IMMEDIATE:
gl_info->gl_ops.gl.p_glGetIntegerv(GL_AUX_BUFFERS, &ret->aux_buffers);
TRACE("Setting up the screen\n");
- /* Clear the screen */
- gl_info->gl_ops.gl.p_glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
- checkGLcall("glClearColor");
- gl_info->gl_ops.gl.p_glClearIndex(0);
- gl_info->gl_ops.gl.p_glClearDepth(1);
- gl_info->gl_ops.gl.p_glClearStencil(0xffff);
-
- checkGLcall("glClear");
gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);
checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);");
- if (gl_info->supported[APPLE_CLIENT_STORAGE])
- {
- /* Most textures will use client storage if supported. Exceptions are
- * non-native power of 2 textures and textures in DIB sections. */
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
- }
if (gl_info->supported[ARB_VERTEX_BLEND])
{
/* Direct3D always uses n-1 weights for n world matrices and uses
{
GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT));
}
- ret->select_shader = 1;
+ ret->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
+ | (1 << WINED3D_SHADER_TYPE_VERTEX)
+ | (1 << WINED3D_SHADER_TYPE_GEOMETRY);
/* If this happens to be the first context for the device, dummy textures
* are not created yet. In that case, they will be created (and bound) by
return ret;
out:
+ device->shader_backend->shader_free_context_data(ret);
HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
HeapFree(GetProcessHeap(), 0, ret->draw_buffers);
destroy = FALSE;
}
+ device->shader_backend->shader_free_context_data(context);
HeapFree(GetProcessHeap(), 0, context->draw_buffers);
HeapFree(GetProcessHeap(), 0, context->blit_targets);
device_context_remove(device, context);
{
const struct wined3d_surface *rt = context->current_rt;
- if (rt->container.type == WINED3D_CONTAINER_SWAPCHAIN
- && rt->container.u.swapchain->front_buffer == rt)
+ if (rt->swapchain && rt->swapchain->front_buffer == rt)
{
RECT window_size;
set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
/* Disable shaders */
- device->shader_backend->shader_select(context, WINED3D_SHADER_MODE_NONE, WINED3D_SHADER_MODE_NONE);
- context->select_shader = 1;
- context->load_constants = 1;
+ device->shader_backend->shader_disable(device->shader_priv, context);
context->blit_w = rt_size.cx;
context->blit_h = rt_size.cy;
void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD *current_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
+ DWORD new_mask = context_generate_rt_mask(buffer);
+
+ if (new_mask == *current_mask)
+ return;
gl_info->gl_ops.gl.p_glDrawBuffer(buffer);
checkGLcall("glDrawBuffer()");
- if (context->current_fbo)
- context->current_fbo->rt_mask = context_generate_rt_mask(buffer);
- else
- context->draw_buffers_mask = context_generate_rt_mask(buffer);
+
+ *current_mask = new_mask;
}
/* Context activation is done by the caller. */
const struct wined3d_surface *depth_stencil)
{
/* Onscreen surfaces are always in a swapchain */
- struct wined3d_swapchain *swapchain = context->current_rt->container.u.swapchain;
+ struct wined3d_swapchain *swapchain = context->current_rt->swapchain;
if (context->render_offscreen || !depth_stencil) return;
if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format)) return;
{
if (!rt || rt->resource.format->id == WINED3DFMT_NULL)
return 0;
- else if (rt->container.type == WINED3D_CONTAINER_SWAPCHAIN)
+ else if (rt->swapchain)
return context_generate_rt_mask_from_surface(rt);
else
return context_generate_rt_mask(device->offscreenBuffer);
}
else
{
- context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
+ context->current_fbo = NULL;
+ context_bind_fbo(context, GL_FRAMEBUFFER, 0);
rt_mask = context_generate_rt_mask_from_surface(rt);
}
}
}
context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, fb->depth_stencil,
rt_count ? rts[0]->draw_binding : SFLAG_INTEXTURE);
- gl_info->gl_ops.gl.p_glReadBuffer(GL_NONE);
- checkGLcall("glReadBuffer");
}
else
{
static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device)
{
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_state *state = &device->state;
struct wined3d_surface **rts = state->fb->render_targets;
struct wined3d_shader *ps = state->pixel_shader;
DWORD rt_mask, rt_mask_bits;
else if (!context->render_offscreen) return context_generate_rt_mask_from_surface(rts[0]);
rt_mask = ps ? ps->reg_maps.rt_mask : 1;
- rt_mask &= device->valid_rt_mask;
+ rt_mask &= context->d3d_info->valid_rt_mask;
rt_mask_bits = rt_mask;
i = 0;
while (rt_mask_bits)
void context_state_fb(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;
const struct wined3d_fb_state *fb = state->fb;
DWORD rt_mask = find_draw_buffers_mask(context, device);
DWORD *cur_mask;
{
context_apply_fbo_state(context, GL_FRAMEBUFFER, fb->render_targets, fb->depth_stencil,
fb->render_targets[0]->draw_binding);
- gl_info->gl_ops.gl.p_glReadBuffer(GL_NONE);
- checkGLcall("glReadBuffer");
}
}
/* Context activation is done by the caller. */
BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device)
{
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_state *state = &device->state;
const struct StateEntry *state_table = context->state_table;
const struct wined3d_fb_state *fb = state->fb;
unsigned int i;
device_update_stream_info(device, context->gl_info);
if (state->index_buffer)
{
- if (device->strided_streams.all_vbo)
+ if (device->stream_info.all_vbo)
wined3d_buffer_preload(state->index_buffer);
else
buffer_get_sysmem(state->index_buffer, context->gl_info);
state_table[rep].apply(context, state, rep);
}
- if (context->select_shader)
+ if (context->shader_update_mask)
{
- device->shader_backend->shader_select(context,
- use_vs(state) ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP,
- use_ps(state) ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP);
- context->select_shader = 0;
+ device->shader_backend->shader_select(device->shader_priv, context, state);
+ context->shader_update_mask = 0;
}
- if (context->load_constants)
+ if (context->constant_update_mask)
{
- device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
- context->load_constants = 0;
+ device->shader_backend->shader_load_constants(device->shader_priv, context, state);
+ context->constant_update_mask = 0;
}
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
context = current_context;
}
- else if (target->container.type == WINED3D_CONTAINER_SWAPCHAIN)
+ else if (target->swapchain)
{
TRACE("Rendering onscreen.\n");
- context = swapchain_get_context(target->container.u.swapchain);
+ context = swapchain_get_context(target->swapchain);
}
else
{
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
/* Define the default light parameters as specified by MSDN. */
const struct wined3d_light WINED3D_default_light =
0.0f /* Phi */
};
-/**********************************************************
- * Global variable / Constants follow
- **********************************************************/
-const struct wined3d_matrix identity =
-{{{
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f,
-}}}; /* When needed for comparisons */
-
/* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these
* actually have the same values in GL and D3D. */
GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
/* Context activation is done by the caller. */
static void device_stream_info_from_declaration(struct wined3d_device *device, struct wined3d_stream_info *stream_info)
{
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_state *state = &device->state;
/* We need to deal with frequency data! */
struct wined3d_vertex_declaration *declaration = state->vertex_declaration;
BOOL use_vshader;
* drawStridedSlow() is needed, including a vertex buffer path. */
if (state->load_base_vertex_index < 0)
{
- WARN("load_base_vertex_index is < 0 (%d), not using VBOs.\n", state->load_base_vertex_index);
+ WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n", state->load_base_vertex_index);
data.buffer_object = 0;
data.addr = buffer_get_sysmem(buffer, &device->adapter->gl_info);
if ((UINT_PTR)data.addr < -state->load_base_vertex_index * stride)
/* Context activation is done by the caller. */
void device_update_stream_info(struct wined3d_device *device, const struct wined3d_gl_info *gl_info)
{
- struct wined3d_stream_info *stream_info = &device->strided_streams;
- const struct wined3d_state *state = &device->stateBlock->state;
+ struct wined3d_stream_info *stream_info = &device->stream_info;
+ const struct wined3d_state *state = &device->state;
DWORD prev_all_vbo = stream_info->all_vbo;
TRACE("============================= Vertex Declaration =============================\n");
slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
& ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
- if ((stream_info->position_transformed || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo)
- {
+ if (((stream_info->position_transformed && !device->adapter->d3d_info.xyzrhw)
+ || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo)
device->useDrawStridedSlow = TRUE;
- }
else
- {
device->useDrawStridedSlow = FALSE;
- }
}
if (prev_all_vbo != stream_info->all_vbo)
void device_preload_textures(const struct wined3d_device *device)
{
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_state *state = &device->state;
unsigned int i;
if (use_vs(state))
{
RECT current_rect, r;
+ if (ds->flags & SFLAG_DISCARDED)
+ {
+ /* Depth buffer was discarded, make it entirely current in its new location since
+ * there is no other place where we would get data anyway. */
+ SetRect(out_rect, 0, 0, ds->resource.width, ds->resource.height);
+ return;
+ }
+
if (ds->flags & location)
SetRect(¤t_rect, 0, 0,
ds->ds_current_size.cx,
}
if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET
- && target->container.type == WINED3D_CONTAINER_SWAPCHAIN
- && target->container.u.swapchain->front_buffer == target))
+ && target->swapchain && target->swapchain->front_buffer == target))
gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
if (!refcount)
{
- struct wined3d_stateblock *stateblock;
UINT i;
- if (wined3d_stateblock_decref(device->updateStateBlock)
- && device->updateStateBlock != device->stateBlock)
- FIXME("Something's still holding the update stateblock.\n");
- device->updateStateBlock = NULL;
+ if (device->recording && wined3d_stateblock_decref(device->recording))
+ FIXME("Something's still holding the recording stateblock.\n");
+ device->recording = NULL;
- stateblock = device->stateBlock;
- device->stateBlock = NULL;
- if (wined3d_stateblock_decref(stateblock))
- FIXME("Something's still holding the stateblock.\n");
+ state_cleanup(&device->state);
for (i = 0; i < sizeof(device->multistate_funcs) / sizeof(device->multistate_funcs[0]); ++i)
{
* We emulate this by creating dummy textures and binding them
* to each texture stage when the currently set D3D texture is NULL. */
- if (gl_info->supported[APPLE_CLIENT_STORAGE])
- {
- /* The dummy texture does not have client storage backing */
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
- }
-
count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers);
for (i = 0; i < count; ++i)
{
}
}
}
-
- if (gl_info->supported[APPLE_CLIENT_STORAGE])
- {
- /* Re-enable because if supported it is enabled by default */
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
- }
}
/* Context activation is done by the caller. */
gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_2d);
checkGLcall("glDeleteTextures(count, device->dummy_texture_2d)");
- memset(device->dummy_texture_cube, 0, gl_info->limits.textures * sizeof(*device->dummy_texture_cube));
- memset(device->dummy_texture_3d, 0, gl_info->limits.textures * sizeof(*device->dummy_texture_3d));
- memset(device->dummy_texture_rect, 0, gl_info->limits.textures * sizeof(*device->dummy_texture_rect));
- memset(device->dummy_texture_2d, 0, gl_info->limits.textures * sizeof(*device->dummy_texture_2d));
+ memset(device->dummy_texture_cube, 0, count * sizeof(*device->dummy_texture_cube));
+ memset(device->dummy_texture_3d, 0, count * sizeof(*device->dummy_texture_3d));
+ memset(device->dummy_texture_rect, 0, count * sizeof(*device->dummy_texture_rect));
+ memset(device->dummy_texture_2d, 0, count * sizeof(*device->dummy_texture_2d));
}
static LONG fullscreen_style(LONG style)
SetWindowLongW(window, GWL_STYLE, style);
SetWindowLongW(window, GWL_EXSTYLE, exstyle);
- SetWindowPos(window, HWND_TOP, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+ SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
device->filter_messages = filter_messages;
}
if (!device->style && !device->exStyle) return;
- TRACE("Restoring window style of window %p to %08x, %08x.\n",
- window, device->style, device->exStyle);
-
style = GetWindowLongW(window, GWL_STYLE);
exstyle = GetWindowLongW(window, GWL_EXSTYLE);
+ /* These flags are set by wined3d_device_setup_fullscreen_window, not the
+ * application, and we want to ignore them in the test below, since it's
+ * not the application's fault that they changed. Additionally, we want to
+ * preserve the current status of these flags (i.e. don't restore them) to
+ * more closely emulate the behavior of Direct3D, which leaves these flags
+ * alone when returning to windowed mode. */
+ device->style ^= (device->style ^ style) & WS_VISIBLE;
+ device->exStyle ^= (device->exStyle ^ exstyle) & WS_EX_TOPMOST;
+
+ TRACE("Restoring window style of window %p to %08x, %08x.\n",
+ window, device->style, device->exStyle);
+
filter_messages = device->filter_messages;
device->filter_messages = TRUE;
struct wined3d_context *context;
HRESULT hr;
DWORD state;
- unsigned int i;
TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc);
if (device->wined3d->flags & WINED3D_NO3D)
return WINED3DERR_INVALIDCALL;
- device->valid_rt_mask = 0;
- for (i = 0; i < gl_info->limits.buffers; ++i)
- device->valid_rt_mask |= (1 << i);
device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(*device->fb.render_targets) * gl_info->limits.buffers);
}
}
- if (FAILED(hr = device->shader_backend->shader_alloc_private(device, device->adapter->fragment_pipe)))
+ if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
+ device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
{
TRACE("Shader private data couldn't be allocated\n");
goto err_out;
/* Set up some starting GL setup */
/* Setup all the devices defaults */
- stateblock_init_default_state(device->stateBlock);
+ state_init_default(&device->state, device);
context = context_acquire(device, swapchain->front_buffer);
create_dummy_textures(device, context);
- /* Initialize the current view state */
- device->view_ident = 1;
device->contexts[0]->last_was_rhw = 0;
switch (wined3d_settings.offscreen_rendering_mode)
if (device->logo_surface)
wined3d_surface_decref(device->logo_surface);
- stateblock_unbind_resources(device->stateBlock);
+ state_unbind_resources(&device->state);
/* Unload resources */
LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
/* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */
device->blitter->free_private(device);
device->shader_backend->shader_free_private(device);
+ destroy_dummy_textures(device, gl_info);
/* Release the buffers (with sanity checks)*/
if (device->onscreen_depth_stencil)
return;
}
- prev_buffer = device->updateStateBlock->state.stream_output[idx].buffer;
- device->updateStateBlock->state.stream_output[idx].buffer = buffer;
- device->updateStateBlock->state.stream_output[idx].offset = offset;
+ prev_buffer = device->update_state->stream_output[idx].buffer;
+ device->update_state->stream_output[idx].buffer = buffer;
+ device->update_state->stream_output[idx].offset = offset;
- if (device->isRecordingState)
+ if (device->recording)
{
if (buffer)
wined3d_buffer_incref(buffer);
return NULL;
}
- *offset = device->stateBlock->state.stream_output[idx].offset;
- return device->stateBlock->state.stream_output[idx].buffer;
+ *offset = device->state.stream_output[idx].offset;
+ return device->state.stream_output[idx].buffer;
}
HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UINT stream_idx,
return WINED3DERR_INVALIDCALL;
}
- stream = &device->updateStateBlock->state.streams[stream_idx];
+ stream = &device->update_state->streams[stream_idx];
prev_buffer = stream->buffer;
- device->updateStateBlock->changed.streamSource |= 1 << stream_idx;
+ if (device->recording)
+ device->recording->changed.streamSource |= 1 << stream_idx;
if (prev_buffer == buffer
&& stream->stride == stride
}
/* Handle recording of state blocks. */
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
if (buffer)
HRESULT CDECL wined3d_device_get_stream_source(const struct wined3d_device *device,
UINT stream_idx, struct wined3d_buffer **buffer, UINT *offset, UINT *stride)
{
- struct wined3d_stream_state *stream;
+ const struct wined3d_stream_state *stream;
TRACE("device %p, stream_idx %u, buffer %p, offset %p, stride %p.\n",
device, stream_idx, buffer, offset, stride);
return WINED3DERR_INVALIDCALL;
}
- stream = &device->stateBlock->state.streams[stream_idx];
+ stream = &device->state.streams[stream_idx];
*buffer = stream->buffer;
if (*buffer)
wined3d_buffer_incref(*buffer);
return WINED3DERR_INVALIDCALL;
}
- stream = &device->updateStateBlock->state.streams[stream_idx];
+ stream = &device->update_state->streams[stream_idx];
old_flags = stream->flags;
old_freq = stream->frequency;
stream->flags = divider & (WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA);
stream->frequency = divider & 0x7fffff;
- device->updateStateBlock->changed.streamFreq |= 1 << stream_idx;
-
- if (stream->frequency != old_freq || stream->flags != old_flags)
+ if (device->recording)
+ device->recording->changed.streamFreq |= 1 << stream_idx;
+ else if (stream->frequency != old_freq || stream->flags != old_flags)
device_invalidate_state(device, STATE_STREAMSRC);
return WINED3D_OK;
HRESULT CDECL wined3d_device_get_stream_source_freq(const struct wined3d_device *device,
UINT stream_idx, UINT *divider)
{
- struct wined3d_stream_state *stream;
+ const struct wined3d_stream_state *stream;
TRACE("device %p, stream_idx %u, divider %p.\n", device, stream_idx, divider);
- stream = &device->updateStateBlock->state.streams[stream_idx];
+ stream = &device->state.streams[stream_idx];
*divider = stream->flags | stream->frequency;
TRACE("Returning %#x.\n", *divider);
TRACE("%.8e %.8e %.8e %.8e\n", matrix->u.s._41, matrix->u.s._42, matrix->u.s._43, matrix->u.s._44);
/* Handle recording of state blocks. */
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
- device->updateStateBlock->changed.transform[d3dts >> 5] |= 1 << (d3dts & 0x1f);
- device->updateStateBlock->state.transforms[d3dts] = *matrix;
+ device->recording->changed.transform[d3dts >> 5] |= 1 << (d3dts & 0x1f);
+ device->update_state->transforms[d3dts] = *matrix;
return;
}
* tend towards setting the same matrix repeatedly for some reason.
*
* From here on we assume that the new matrix is different, wherever it matters. */
- if (!memcmp(&device->stateBlock->state.transforms[d3dts].u.m[0][0], matrix, sizeof(*matrix)))
+ if (!memcmp(&device->state.transforms[d3dts].u.m[0][0], matrix, sizeof(*matrix)))
{
TRACE("The application is setting the same matrix over again.\n");
return;
}
- device->stateBlock->state.transforms[d3dts] = *matrix;
- if (d3dts == WINED3D_TS_VIEW)
- device->view_ident = !memcmp(matrix, &identity, sizeof(identity));
+ device->state.transforms[d3dts] = *matrix;
if (d3dts < WINED3D_TS_WORLD_MATRIX(device->adapter->gl_info.limits.blends))
device_invalidate_state(device, STATE_TRANSFORM(d3dts));
{
TRACE("device %p, state %s, matrix %p.\n", device, debug_d3dtstype(state), matrix);
- *matrix = device->stateBlock->state.transforms[state];
+ *matrix = device->state.transforms[state];
}
void CDECL wined3d_device_multiply_transform(struct wined3d_device *device,
return;
}
- mat = &device->updateStateBlock->state.transforms[state];
+ mat = &device->update_state->transforms[state];
multiply_matrix(&temp, mat, matrix);
/* Apply change via set transform - will reapply to eg. lights this way. */
return WINED3DERR_INVALIDCALL;
}
- LIST_FOR_EACH(e, &device->updateStateBlock->state.light_map[hash_idx])
+ LIST_FOR_EACH(e, &device->update_state->light_map[hash_idx])
{
object = LIST_ENTRY(e, struct wined3d_light_info, entry);
if (object->OriginalIndex == light_idx)
if (!object)
return E_OUTOFMEMORY;
- list_add_head(&device->updateStateBlock->state.light_map[hash_idx], &object->entry);
+ list_add_head(&device->update_state->light_map[hash_idx], &object->entry);
object->glIndex = -1;
object->OriginalIndex = light_idx;
}
TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n",
light->range, light->falloff, light->theta, light->phi);
+ /* Update the live definitions if the light is currently assigned a glIndex. */
+ if (object->glIndex != -1 && !device->recording)
+ {
+ if (object->OriginalParms.type != light->type)
+ device_invalidate_state(device, STATE_LIGHT_TYPE);
+ device_invalidate_state(device, STATE_ACTIVELIGHT(object->glIndex));
+ }
+
/* Save away the information. */
object->OriginalParms = *light;
FIXME("Unrecognized light type %#x.\n", light->type);
}
- /* Update the live definitions if the light is currently assigned a glIndex. */
- if (object->glIndex != -1 && !device->isRecordingState)
- device_invalidate_state(device, STATE_ACTIVELIGHT(object->glIndex));
-
return WINED3D_OK;
}
TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light);
- LIST_FOR_EACH(e, &device->stateBlock->state.light_map[hash_idx])
+ LIST_FOR_EACH(e, &device->state.light_map[hash_idx])
{
light_info = LIST_ENTRY(e, struct wined3d_light_info, entry);
if (light_info->OriginalIndex == light_idx)
TRACE("device %p, light_idx %u, enable %#x.\n", device, light_idx, enable);
- LIST_FOR_EACH(e, &device->updateStateBlock->state.light_map[hash_idx])
+ LIST_FOR_EACH(e, &device->update_state->light_map[hash_idx])
{
light_info = LIST_ENTRY(e, struct wined3d_light_info, entry);
if (light_info->OriginalIndex == light_idx)
wined3d_device_set_light(device, light_idx, &WINED3D_default_light);
/* Search for it again! Should be fairly quick as near head of list. */
- LIST_FOR_EACH(e, &device->updateStateBlock->state.light_map[hash_idx])
+ LIST_FOR_EACH(e, &device->update_state->light_map[hash_idx])
{
light_info = LIST_ENTRY(e, struct wined3d_light_info, entry);
if (light_info->OriginalIndex == light_idx)
{
if (light_info->glIndex != -1)
{
- if (!device->isRecordingState)
+ if (!device->recording)
+ {
+ device_invalidate_state(device, STATE_LIGHT_TYPE);
device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex));
+ }
- device->updateStateBlock->state.lights[light_info->glIndex] = NULL;
+ device->update_state->lights[light_info->glIndex] = NULL;
light_info->glIndex = -1;
}
else
/* Find a free GL light. */
for (i = 0; i < gl_info->limits.lights; ++i)
{
- if (!device->updateStateBlock->state.lights[i])
+ if (!device->update_state->lights[i])
{
- device->updateStateBlock->state.lights[i] = light_info;
+ device->update_state->lights[i] = light_info;
light_info->glIndex = i;
break;
}
}
/* i == light_info->glIndex */
- if (!device->isRecordingState)
+ if (!device->recording)
+ {
+ device_invalidate_state(device, STATE_LIGHT_TYPE);
device_invalidate_state(device, STATE_ACTIVELIGHT(i));
+ }
}
}
TRACE("device %p, light_idx %u, enable %p.\n", device, light_idx, enable);
- LIST_FOR_EACH(e, &device->stateBlock->state.light_map[hash_idx])
+ LIST_FOR_EACH(e, &device->state.light_map[hash_idx])
{
light_info = LIST_ENTRY(e, struct wined3d_light_info, entry);
if (light_info->OriginalIndex == light_idx)
return WINED3DERR_INVALIDCALL;
}
- device->updateStateBlock->changed.clipplane |= 1 << plane_idx;
+ if (device->recording)
+ device->recording->changed.clipplane |= 1 << plane_idx;
- if (!memcmp(&device->updateStateBlock->state.clip_planes[plane_idx], plane, sizeof(*plane)))
+ if (!memcmp(&device->update_state->clip_planes[plane_idx], plane, sizeof(*plane)))
{
TRACE("Application is setting old values over, nothing to do.\n");
return WINED3D_OK;
}
- device->updateStateBlock->state.clip_planes[plane_idx] = *plane;
+ device->update_state->clip_planes[plane_idx] = *plane;
/* Handle recording of state blocks. */
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
return WINED3D_OK;
return WINED3DERR_INVALIDCALL;
}
- *plane = device->stateBlock->state.clip_planes[plane_idx];
+ *plane = device->state.clip_planes[plane_idx];
return WINED3D_OK;
}
{
TRACE("device %p, material %p.\n", device, material);
- device->updateStateBlock->changed.material = TRUE;
- device->updateStateBlock->state.material = *material;
+ device->update_state->material = *material;
/* Handle recording of state blocks */
- if (device->isRecordingState)
+ if (device->recording)
{
+ device->recording->changed.material = TRUE;
TRACE("Recording... not performing anything.\n");
return;
}
{
TRACE("device %p, material %p.\n", device, material);
- *material = device->updateStateBlock->state.material;
+ *material = device->state.material;
TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
material->diffuse.r, material->diffuse.g,
TRACE("device %p, buffer %p, format %s.\n",
device, buffer, debug_d3dformat(format_id));
- prev_buffer = device->updateStateBlock->state.index_buffer;
+ prev_buffer = device->update_state->index_buffer;
- device->updateStateBlock->changed.indices = TRUE;
- device->updateStateBlock->state.index_buffer = buffer;
- device->updateStateBlock->state.index_format = format_id;
+ device->update_state->index_buffer = buffer;
+ device->update_state->index_format = format_id;
/* Handle recording of state blocks. */
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
+ device->recording->changed.indices = TRUE;
if (buffer)
wined3d_buffer_incref(buffer);
if (prev_buffer)
{
TRACE("device %p, format %p.\n", device, format);
- *format = device->stateBlock->state.index_format;
- return device->stateBlock->state.index_buffer;
+ *format = device->state.index_format;
+ return device->state.index_buffer;
}
void CDECL wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index)
{
TRACE("device %p, base_index %d.\n", device, base_index);
- device->updateStateBlock->state.base_vertex_index = base_index;
+ device->update_state->base_vertex_index = base_index;
}
INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *device)
{
TRACE("device %p.\n", device);
- return device->stateBlock->state.base_vertex_index;
+ return device->state.base_vertex_index;
}
void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport)
TRACE("x %u, y %u, w %u, h %u, min_z %.8e, max_z %.8e.\n",
viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z);
- device->updateStateBlock->changed.viewport = TRUE;
- device->updateStateBlock->state.viewport = *viewport;
+ device->update_state->viewport = *viewport;
/* Handle recording of state blocks */
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything\n");
+ device->recording->changed.viewport = TRUE;
return;
}
{
TRACE("device %p, viewport %p.\n", device, viewport);
- *viewport = device->stateBlock->state.viewport;
+ *viewport = device->state.viewport;
+}
+
+static void resolve_depth_buffer(struct wined3d_state *state)
+{
+ struct wined3d_texture *texture = state->textures[0];
+ struct wined3d_surface *depth_stencil, *surface;
+
+ if (!texture || texture->resource.type != WINED3D_RTYPE_TEXTURE
+ || !(texture->resource.format->flags & WINED3DFMT_FLAG_DEPTH))
+ return;
+ surface = surface_from_resource(texture->sub_resources[0]);
+ depth_stencil = state->fb->depth_stencil;
+ if (!depth_stencil)
+ return;
+
+ wined3d_surface_blt(surface, NULL, depth_stencil, NULL, 0, NULL, WINED3D_TEXF_POINT);
}
void CDECL wined3d_device_set_render_state(struct wined3d_device *device,
enum wined3d_render_state state, DWORD value)
{
- DWORD old_value = device->stateBlock->state.render_states[state];
+ DWORD old_value = device->state.render_states[state];
TRACE("device %p, state %s (%#x), value %#x.\n", device, debug_d3drenderstate(state), state, value);
- device->updateStateBlock->changed.renderState[state >> 5] |= 1 << (state & 0x1f);
- device->updateStateBlock->state.render_states[state] = value;
+ device->update_state->render_states[state] = value;
/* Handle recording of state blocks. */
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
+ device->recording->changed.renderState[state >> 5] |= 1 << (state & 0x1f);
return;
}
TRACE("Application is setting the old value over, nothing to do.\n");
else
device_invalidate_state(device, STATE_RENDER(state));
+
+ if (state == WINED3D_RS_POINTSIZE && value == WINED3D_RESZ_CODE)
+ {
+ TRACE("RESZ multisampled depth buffer resolve triggered.\n");
+ resolve_depth_buffer(&device->state);
+ }
}
DWORD CDECL wined3d_device_get_render_state(const struct wined3d_device *device, enum wined3d_render_state state)
{
TRACE("device %p, state %s (%#x).\n", device, debug_d3drenderstate(state), state);
- return device->stateBlock->state.render_states[state];
+ return device->state.render_states[state];
}
void CDECL wined3d_device_set_sampler_state(struct wined3d_device *device,
if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <= WINED3DVERTEXTEXTURESAMPLER3)
sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
- if (sampler_idx >= sizeof(device->stateBlock->state.sampler_states)
- / sizeof(*device->stateBlock->state.sampler_states))
+ if (sampler_idx >= sizeof(device->state.sampler_states) / sizeof(*device->state.sampler_states))
{
WARN("Invalid sampler %u.\n", sampler_idx);
return; /* Windows accepts overflowing this array ... we do not. */
}
- old_value = device->stateBlock->state.sampler_states[sampler_idx][state];
- device->updateStateBlock->state.sampler_states[sampler_idx][state] = value;
- device->updateStateBlock->changed.samplerState[sampler_idx] |= 1 << state;
+ old_value = device->state.sampler_states[sampler_idx][state];
+ device->update_state->sampler_states[sampler_idx][state] = value;
/* Handle recording of state blocks. */
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
+ device->recording->changed.samplerState[sampler_idx] |= 1 << state;
return;
}
if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <= WINED3DVERTEXTEXTURESAMPLER3)
sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
- if (sampler_idx >= sizeof(device->stateBlock->state.sampler_states)
- / sizeof(*device->stateBlock->state.sampler_states))
+ if (sampler_idx >= sizeof(device->state.sampler_states) / sizeof(*device->state.sampler_states))
{
WARN("Invalid sampler %u.\n", sampler_idx);
return 0; /* Windows accepts overflowing this array ... we do not. */
}
- return device->stateBlock->state.sampler_states[sampler_idx][state];
+ return device->state.sampler_states[sampler_idx][state];
}
void CDECL wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect)
{
TRACE("device %p, rect %s.\n", device, wine_dbgstr_rect(rect));
- device->updateStateBlock->changed.scissorRect = TRUE;
- if (EqualRect(&device->updateStateBlock->state.scissor_rect, rect))
+ if (device->recording)
+ device->recording->changed.scissorRect = TRUE;
+
+ if (EqualRect(&device->update_state->scissor_rect, rect))
{
TRACE("App is setting the old scissor rectangle over, nothing to do.\n");
return;
}
- CopyRect(&device->updateStateBlock->state.scissor_rect, rect);
+ CopyRect(&device->update_state->scissor_rect, rect);
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
return;
{
TRACE("device %p, rect %p.\n", device, rect);
- *rect = device->updateStateBlock->state.scissor_rect;
+ *rect = device->state.scissor_rect;
TRACE("Returning rect %s.\n", wine_dbgstr_rect(rect));
}
void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device,
struct wined3d_vertex_declaration *declaration)
{
- struct wined3d_vertex_declaration *prev = device->updateStateBlock->state.vertex_declaration;
+ struct wined3d_vertex_declaration *prev = device->update_state->vertex_declaration;
TRACE("device %p, declaration %p.\n", device, declaration);
if (prev)
wined3d_vertex_declaration_decref(prev);
- device->updateStateBlock->state.vertex_declaration = declaration;
- device->updateStateBlock->changed.vertexDecl = TRUE;
+ device->update_state->vertex_declaration = declaration;
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
+ device->recording->changed.vertexDecl = TRUE;
return;
}
{
TRACE("device %p.\n", device);
- return device->stateBlock->state.vertex_declaration;
+ return device->state.vertex_declaration;
}
void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader)
{
- struct wined3d_shader *prev = device->updateStateBlock->state.vertex_shader;
+ struct wined3d_shader *prev = device->update_state->vertex_shader;
TRACE("device %p, shader %p.\n", device, shader);
if (prev)
wined3d_shader_decref(prev);
- device->updateStateBlock->state.vertex_shader = shader;
- device->updateStateBlock->changed.vertexShader = TRUE;
+ device->update_state->vertex_shader = shader;
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
+ device->recording->changed.vertexShader = TRUE;
return;
}
{
TRACE("device %p.\n", device);
- return device->stateBlock->state.vertex_shader;
+ return device->state.vertex_shader;
}
void CDECL wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer)
return;
}
- prev = device->updateStateBlock->state.vs_cb[idx];
- device->updateStateBlock->state.vs_cb[idx] = buffer;
+ prev = device->update_state->vs_cb[idx];
+ device->update_state->vs_cb[idx] = buffer;
- if (device->isRecordingState)
+ if (device->recording)
{
if (buffer)
wined3d_buffer_incref(buffer);
return NULL;
}
- return device->stateBlock->state.vs_cb[idx];
+ return device->state.vs_cb[idx];
}
void CDECL wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler)
return;
}
- prev = device->updateStateBlock->state.vs_sampler[idx];
- device->updateStateBlock->state.vs_sampler[idx] = sampler;
+ prev = device->update_state->vs_sampler[idx];
+ device->update_state->vs_sampler[idx] = sampler;
if (sampler)
wined3d_sampler_incref(sampler);
return NULL;
}
- return device->stateBlock->state.vs_sampler[idx];
+ return device->state.vs_sampler[idx];
+}
+
+void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask)
+{
+ UINT i;
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ device->contexts[i]->constant_update_mask |= mask;
+ }
}
HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device,
if (!constants || start_register >= MAX_CONST_B)
return WINED3DERR_INVALIDCALL;
- memcpy(&device->updateStateBlock->state.vs_consts_b[start_register], constants, count * sizeof(BOOL));
+ memcpy(&device->update_state->vs_consts_b[start_register], constants, count * sizeof(BOOL));
for (i = 0; i < count; ++i)
TRACE("Set BOOL constant %u to %s.\n", start_register + i, constants[i] ? "true" : "false");
- for (i = start_register; i < count + start_register; ++i)
- device->updateStateBlock->changed.vertexShaderConstantsB |= (1 << i);
-
- if (!device->isRecordingState)
- device_invalidate_state(device, STATE_VERTEXSHADERCONSTANT);
+ if (device->recording)
+ {
+ for (i = start_register; i < count + start_register; ++i)
+ device->recording->changed.vertexShaderConstantsB |= (1 << i);
+ }
+ else
+ {
+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B);
+ }
return WINED3D_OK;
}
if (!constants || start_register >= MAX_CONST_B)
return WINED3DERR_INVALIDCALL;
- memcpy(constants, &device->stateBlock->state.vs_consts_b[start_register], count * sizeof(BOOL));
+ memcpy(constants, &device->state.vs_consts_b[start_register], count * sizeof(BOOL));
return WINED3D_OK;
}
if (!constants || start_register >= MAX_CONST_I)
return WINED3DERR_INVALIDCALL;
- memcpy(&device->updateStateBlock->state.vs_consts_i[start_register * 4], constants, count * sizeof(int) * 4);
+ memcpy(&device->update_state->vs_consts_i[start_register * 4], constants, count * sizeof(int) * 4);
for (i = 0; i < count; ++i)
TRACE("Set INT constant %u to {%d, %d, %d, %d}.\n", start_register + i,
constants[i * 4], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]);
- for (i = start_register; i < count + start_register; ++i)
- device->updateStateBlock->changed.vertexShaderConstantsI |= (1 << i);
-
- if (!device->isRecordingState)
- device_invalidate_state(device, STATE_VERTEXSHADERCONSTANT);
+ if (device->recording)
+ {
+ for (i = start_register; i < count + start_register; ++i)
+ device->recording->changed.vertexShaderConstantsI |= (1 << i);
+ }
+ else
+ {
+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I);
+ }
return WINED3D_OK;
}
if (!constants || start_register >= MAX_CONST_I)
return WINED3DERR_INVALIDCALL;
- memcpy(constants, &device->stateBlock->state.vs_consts_i[start_register * 4], count * sizeof(int) * 4);
+ memcpy(constants, &device->state.vs_consts_i[start_register * 4], count * sizeof(int) * 4);
return WINED3D_OK;
}
UINT start_register, const float *constants, UINT vector4f_count)
{
UINT i;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n",
device, start_register, constants, vector4f_count);
/* Specifically test start_register > limit to catch MAX_UINT overflows
* when adding start_register + vector4f_count. */
if (!constants
- || start_register + vector4f_count > device->d3d_vshader_constantF
- || start_register > device->d3d_vshader_constantF)
+ || start_register + vector4f_count > d3d_info->limits.vs_uniform_count
+ || start_register > d3d_info->limits.vs_uniform_count)
return WINED3DERR_INVALIDCALL;
- memcpy(&device->updateStateBlock->state.vs_consts_f[start_register * 4],
+ memcpy(&device->update_state->vs_consts_f[start_register * 4],
constants, vector4f_count * sizeof(float) * 4);
if (TRACE_ON(d3d))
{
constants[i * 4 + 2], constants[i * 4 + 3]);
}
- if (!device->isRecordingState)
- {
+ if (device->recording)
+ memset(device->recording->changed.vertexShaderConstantsF + start_register, 1,
+ sizeof(*device->recording->changed.vertexShaderConstantsF) * vector4f_count);
+ else
device->shader_backend->shader_update_float_vertex_constants(device, start_register, vector4f_count);
- device_invalidate_state(device, STATE_VERTEXSHADERCONSTANT);
- }
- memset(device->updateStateBlock->changed.vertexShaderConstantsF + start_register, 1,
- sizeof(*device->updateStateBlock->changed.vertexShaderConstantsF) * vector4f_count);
return WINED3D_OK;
}
HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device,
UINT start_register, float *constants, UINT vector4f_count)
{
- int count = min(vector4f_count, device->d3d_vshader_constantF - start_register);
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ int count = min(vector4f_count, d3d_info->limits.vs_uniform_count - start_register);
TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n",
device, start_register, constants, vector4f_count);
if (!constants || count < 0)
return WINED3DERR_INVALIDCALL;
- memcpy(constants, &device->stateBlock->state.vs_consts_f[start_register * 4], count * sizeof(float) * 4);
+ memcpy(constants, &device->state.vs_consts_f[start_register * 4], count * sizeof(float) * 4);
return WINED3D_OK;
}
device->fixed_function_usage_map = 0;
for (i = 0; i < MAX_TEXTURES; ++i)
{
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_state *state = &device->state;
enum wined3d_texture_op color_op = state->texture_states[i][WINED3D_TSS_COLOR_OP];
enum wined3d_texture_op alpha_op = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
DWORD color_arg1 = state->texture_states[i][WINED3D_TSS_COLOR_ARG1] & WINED3DTA_SELECTMASK;
}
}
-static void device_map_fixed_function_samplers(struct wined3d_device *device, const struct wined3d_gl_info *gl_info)
+static void device_map_fixed_function_samplers(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info)
{
unsigned int i, tex;
WORD ffu_map;
device_update_fixed_function_usage_map(device);
ffu_map = device->fixed_function_usage_map;
- if (device->max_ffp_textures == gl_info->limits.texture_stages
- || device->stateBlock->state.lowest_disabled_stage <= device->max_ffp_textures)
+ if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages
+ || device->state.lowest_disabled_stage <= d3d_info->limits.ffp_textures)
{
for (i = 0; ffu_map; ffu_map >>= 1, ++i)
{
}
}
-static void device_map_psamplers(struct wined3d_device *device, const struct wined3d_gl_info *gl_info)
+static void device_map_psamplers(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info)
{
const enum wined3d_sampler_texture_type *sampler_type =
- device->stateBlock->state.pixel_shader->reg_maps.sampler_type;
+ device->state.pixel_shader->reg_maps.sampler_type;
unsigned int i;
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
device_map_stage(device, i, i);
device_invalidate_state(device, STATE_SAMPLER(i));
- if (i < gl_info->limits.texture_stages)
+ if (i < d3d_info->limits.ffp_blend_stages)
device_invalidate_texture_stage(device, i);
}
}
static void device_map_vsamplers(struct wined3d_device *device, BOOL ps, const struct wined3d_gl_info *gl_info)
{
const enum wined3d_sampler_texture_type *vshader_sampler_type =
- device->stateBlock->state.vertex_shader->reg_maps.sampler_type;
+ device->state.vertex_shader->reg_maps.sampler_type;
const enum wined3d_sampler_texture_type *pshader_sampler_type = NULL;
int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
int i;
{
/* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
* Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
- pshader_sampler_type = device->stateBlock->state.pixel_shader->reg_maps.sampler_type;
+ pshader_sampler_type = device->state.pixel_shader->reg_maps.sampler_type;
}
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
void device_update_tex_unit_map(struct wined3d_device *device)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ const struct wined3d_state *state = &device->state;
BOOL vs = use_vs(state);
BOOL ps = use_ps(state);
/*
* to be reset. Because of that try to work with a 1:1 mapping as much as possible
*/
if (ps)
- device_map_psamplers(device, gl_info);
+ device_map_psamplers(device, d3d_info);
else
- device_map_fixed_function_samplers(device, gl_info);
+ device_map_fixed_function_samplers(device, d3d_info);
if (vs)
device_map_vsamplers(device, ps, gl_info);
void CDECL wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader)
{
- struct wined3d_shader *prev = device->updateStateBlock->state.pixel_shader;
+ struct wined3d_shader *prev = device->update_state->pixel_shader;
TRACE("device %p, shader %p.\n", device, shader);
if (prev)
wined3d_shader_decref(prev);
- device->updateStateBlock->state.pixel_shader = shader;
- device->updateStateBlock->changed.pixelShader = TRUE;
+ device->update_state->pixel_shader = shader;
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
+ device->recording->changed.pixelShader = TRUE;
return;
}
{
TRACE("device %p.\n", device);
- return device->stateBlock->state.pixel_shader;
+ return device->state.pixel_shader;
}
void CDECL wined3d_device_set_ps_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer)
return;
}
- prev = device->updateStateBlock->state.ps_cb[idx];
- device->updateStateBlock->state.ps_cb[idx] = buffer;
+ prev = device->update_state->ps_cb[idx];
+ device->update_state->ps_cb[idx] = buffer;
- if (device->isRecordingState)
+ if (device->recording)
{
if (buffer)
wined3d_buffer_incref(buffer);
return NULL;
}
- return device->stateBlock->state.ps_cb[idx];
+ return device->state.ps_cb[idx];
}
void CDECL wined3d_device_set_ps_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler)
return;
}
- prev = device->updateStateBlock->state.ps_sampler[idx];
- device->updateStateBlock->state.ps_sampler[idx] = sampler;
+ prev = device->update_state->ps_sampler[idx];
+ device->update_state->ps_sampler[idx] = sampler;
if (sampler)
wined3d_sampler_incref(sampler);
return NULL;
}
- return device->stateBlock->state.ps_sampler[idx];
+ return device->state.ps_sampler[idx];
}
HRESULT CDECL wined3d_device_set_ps_consts_b(struct wined3d_device *device,
if (!constants || start_register >= MAX_CONST_B)
return WINED3DERR_INVALIDCALL;
- memcpy(&device->updateStateBlock->state.ps_consts_b[start_register], constants, count * sizeof(BOOL));
+ memcpy(&device->update_state->ps_consts_b[start_register], constants, count * sizeof(BOOL));
for (i = 0; i < count; ++i)
TRACE("Set BOOL constant %u to %s.\n", start_register + i, constants[i] ? "true" : "false");
- for (i = start_register; i < count + start_register; ++i)
- device->updateStateBlock->changed.pixelShaderConstantsB |= (1 << i);
-
- if (!device->isRecordingState)
- device_invalidate_state(device, STATE_PIXELSHADERCONSTANT);
+ if (device->recording)
+ {
+ for (i = start_register; i < count + start_register; ++i)
+ device->recording->changed.pixelShaderConstantsB |= (1 << i);
+ }
+ else
+ {
+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B);
+ }
return WINED3D_OK;
}
if (!constants || start_register >= MAX_CONST_B)
return WINED3DERR_INVALIDCALL;
- memcpy(constants, &device->stateBlock->state.ps_consts_b[start_register], count * sizeof(BOOL));
+ memcpy(constants, &device->state.ps_consts_b[start_register], count * sizeof(BOOL));
return WINED3D_OK;
}
if (!constants || start_register >= MAX_CONST_I)
return WINED3DERR_INVALIDCALL;
- memcpy(&device->updateStateBlock->state.ps_consts_i[start_register * 4], constants, count * sizeof(int) * 4);
+ memcpy(&device->update_state->ps_consts_i[start_register * 4], constants, count * sizeof(int) * 4);
for (i = 0; i < count; ++i)
TRACE("Set INT constant %u to {%d, %d, %d, %d}.\n", start_register + i,
constants[i * 4], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]);
- for (i = start_register; i < count + start_register; ++i)
- device->updateStateBlock->changed.pixelShaderConstantsI |= (1 << i);
-
- if (!device->isRecordingState)
- device_invalidate_state(device, STATE_PIXELSHADERCONSTANT);
+ if (device->recording)
+ {
+ for (i = start_register; i < count + start_register; ++i)
+ device->recording->changed.pixelShaderConstantsI |= (1 << i);
+ }
+ else
+ {
+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I);
+ }
return WINED3D_OK;
}
if (!constants || start_register >= MAX_CONST_I)
return WINED3DERR_INVALIDCALL;
- memcpy(constants, &device->stateBlock->state.ps_consts_i[start_register * 4], count * sizeof(int) * 4);
+ memcpy(constants, &device->state.ps_consts_i[start_register * 4], count * sizeof(int) * 4);
return WINED3D_OK;
}
UINT start_register, const float *constants, UINT vector4f_count)
{
UINT i;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n",
device, start_register, constants, vector4f_count);
/* Specifically test start_register > limit to catch MAX_UINT overflows
* when adding start_register + vector4f_count. */
if (!constants
- || start_register + vector4f_count > device->d3d_pshader_constantF
- || start_register > device->d3d_pshader_constantF)
+ || start_register + vector4f_count > d3d_info->limits.ps_uniform_count
+ || start_register > d3d_info->limits.ps_uniform_count)
return WINED3DERR_INVALIDCALL;
- memcpy(&device->updateStateBlock->state.ps_consts_f[start_register * 4],
+ memcpy(&device->update_state->ps_consts_f[start_register * 4],
constants, vector4f_count * sizeof(float) * 4);
if (TRACE_ON(d3d))
{
constants[i * 4 + 2], constants[i * 4 + 3]);
}
- if (!device->isRecordingState)
- {
+ if (device->recording)
+ memset(device->recording->changed.pixelShaderConstantsF + start_register, 1,
+ sizeof(*device->recording->changed.pixelShaderConstantsF) * vector4f_count);
+ else
device->shader_backend->shader_update_float_pixel_constants(device, start_register, vector4f_count);
- device_invalidate_state(device, STATE_PIXELSHADERCONSTANT);
- }
-
- memset(device->updateStateBlock->changed.pixelShaderConstantsF + start_register, 1,
- sizeof(*device->updateStateBlock->changed.pixelShaderConstantsF) * vector4f_count);
return WINED3D_OK;
}
HRESULT CDECL wined3d_device_get_ps_consts_f(const struct wined3d_device *device,
UINT start_register, float *constants, UINT vector4f_count)
{
- int count = min(vector4f_count, device->d3d_pshader_constantF - start_register);
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ int count = min(vector4f_count, d3d_info->limits.ps_uniform_count - start_register);
TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n",
device, start_register, constants, vector4f_count);
if (!constants || count < 0)
return WINED3DERR_INVALIDCALL;
- memcpy(constants, &device->stateBlock->state.ps_consts_f[start_register * 4], count * sizeof(float) * 4);
+ memcpy(constants, &device->state.ps_consts_f[start_register * 4], count * sizeof(float) * 4);
return WINED3D_OK;
}
void CDECL wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader)
{
- struct wined3d_shader *prev = device->updateStateBlock->state.geometry_shader;
+ struct wined3d_shader *prev = device->update_state->geometry_shader;
TRACE("device %p, shader %p.\n", device, shader);
if (prev)
wined3d_shader_decref(prev);
- device->updateStateBlock->state.geometry_shader = shader;
+ device->update_state->geometry_shader = shader;
- if (device->isRecordingState || shader == prev)
+ if (device->recording || shader == prev)
return;
device_invalidate_state(device, STATE_GEOMETRY_SHADER);
{
TRACE("device %p.\n", device);
- return device->stateBlock->state.geometry_shader;
+ return device->state.geometry_shader;
}
void CDECL wined3d_device_set_gs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer)
return;
}
- prev = device->updateStateBlock->state.gs_cb[idx];
- device->updateStateBlock->state.gs_cb[idx] = buffer;
+ prev = device->update_state->gs_cb[idx];
+ device->update_state->gs_cb[idx] = buffer;
- if (device->isRecordingState)
+ if (device->recording)
{
if (buffer)
wined3d_buffer_incref(buffer);
return NULL;
}
- return device->stateBlock->state.gs_cb[idx];
+ return device->state.gs_cb[idx];
}
void CDECL wined3d_device_set_gs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler)
return;
}
- prev = device->updateStateBlock->state.gs_sampler[idx];
- device->updateStateBlock->state.gs_sampler[idx] = sampler;
+ prev = device->update_state->gs_sampler[idx];
+ device->update_state->gs_sampler[idx] = sampler;
if (sampler)
wined3d_sampler_incref(sampler);
return NULL;
}
- return device->stateBlock->state.gs_sampler[idx];
+ return device->state.gs_sampler[idx];
}
/* Context activation is done by the caller. */
return WINED3DERR_INVALIDCALL;
}
- if (device->stateBlock->state.render_states[WINED3D_RS_CLIPPING])
+ if (device->state.render_states[WINED3D_RS_CLIPPING])
{
static BOOL warned = FALSE;
/*
UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer,
const struct wined3d_vertex_declaration *declaration, DWORD flags, DWORD dst_fvf)
{
- struct wined3d_state *state = &device->stateBlock->state;
+ struct wined3d_state *state = &device->state;
struct wined3d_stream_info stream_info;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
void CDECL wined3d_device_set_texture_stage_state(struct wined3d_device *device,
UINT stage, enum wined3d_texture_stage_state state, DWORD value)
{
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
DWORD old_value;
TRACE("device %p, stage %u, state %s, value %#x.\n",
return;
}
- if (stage >= gl_info->limits.texture_stages)
+ if (stage >= d3d_info->limits.ffp_blend_stages)
{
WARN("Attempting to set stage %u which is higher than the max stage %u, ignoring.\n",
- stage, gl_info->limits.texture_stages - 1);
+ stage, d3d_info->limits.ffp_blend_stages - 1);
return;
}
- old_value = device->updateStateBlock->state.texture_states[stage][state];
- device->updateStateBlock->changed.textureState[stage] |= 1 << state;
- device->updateStateBlock->state.texture_states[stage][state] = value;
+ old_value = device->update_state->texture_states[stage][state];
+ device->update_state->texture_states[stage][state] = value;
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything.\n");
+ device->recording->changed.textureState[stage] |= 1 << state;
return;
}
return;
}
- if (stage > device->stateBlock->state.lowest_disabled_stage
+ if (stage > device->state.lowest_disabled_stage
&& device->StateTable[STATE_TEXTURESTAGE(0, state)].representative
== STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP))
{
* all enabled stages above stage, they have to be disabled.
*
* The current stage is dirtified below. */
- for (i = stage + 1; i < device->stateBlock->state.lowest_disabled_stage; ++i)
+ for (i = stage + 1; i < device->state.lowest_disabled_stage; ++i)
{
TRACE("Additionally dirtifying stage %u.\n", i);
device_invalidate_state(device, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
}
- device->stateBlock->state.lowest_disabled_stage = stage;
+ device->state.lowest_disabled_stage = stage;
TRACE("New lowest disabled: %u.\n", stage);
}
else if (value != WINED3D_TOP_DISABLE && old_value == WINED3D_TOP_DISABLE)
*
* Again stage stage doesn't need to be dirtified here, it is
* handled below. */
- for (i = stage + 1; i < gl_info->limits.texture_stages; ++i)
+ for (i = stage + 1; i < d3d_info->limits.ffp_blend_stages; ++i)
{
- if (device->updateStateBlock->state.texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
+ if (device->update_state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
break;
TRACE("Additionally dirtifying stage %u due to enable.\n", i);
device_invalidate_state(device, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
}
- device->stateBlock->state.lowest_disabled_stage = i;
+ device->state.lowest_disabled_stage = i;
TRACE("New lowest disabled: %u.\n", i);
}
}
return 0;
}
- return device->updateStateBlock->state.texture_states[stage][state];
+ return device->state.texture_states[stage][state];
}
HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device,
UINT stage, struct wined3d_texture *texture)
{
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
struct wined3d_texture *prev;
TRACE("device %p, stage %u, texture %p.\n", device, stage, texture);
stage -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
/* Windows accepts overflowing this array... we do not. */
- if (stage >= sizeof(device->stateBlock->state.textures) / sizeof(*device->stateBlock->state.textures))
+ if (stage >= sizeof(device->state.textures) / sizeof(*device->state.textures))
{
WARN("Ignoring invalid stage %u.\n", stage);
return WINED3D_OK;
return WINED3DERR_INVALIDCALL;
}
- device->updateStateBlock->changed.textures |= 1 << stage;
+ if (device->recording)
+ device->recording->changed.textures |= 1 << stage;
- prev = device->updateStateBlock->state.textures[stage];
+ prev = device->update_state->textures[stage];
TRACE("Previous texture %p.\n", prev);
if (texture == prev)
}
TRACE("Setting new texture to %p.\n", texture);
- device->updateStateBlock->state.textures[stage] = texture;
+ device->update_state->textures[stage] = texture;
- if (device->isRecordingState)
+ if (device->recording)
{
TRACE("Recording... not performing anything\n");
if (!prev || texture->target != prev->target)
device_invalidate_state(device, STATE_PIXELSHADER);
- if (!prev && stage < gl_info->limits.texture_stages)
+ if (!prev && stage < d3d_info->limits.ffp_blend_stages)
{
/* The source arguments for color and alpha ops have different
* meanings when a NULL texture is bound, so the COLOR_OP and
{
LONG bind_count = InterlockedDecrement(&prev->resource.bind_count);
- if (!texture && stage < gl_info->limits.texture_stages)
+ if (!texture && stage < d3d_info->limits.ffp_blend_stages)
{
device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP));
device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP));
TRACE("Searching for other stages the texture is bound to.\n");
for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
{
- if (device->updateStateBlock->state.textures[i] == prev)
+ if (device->update_state->textures[i] == prev)
{
TRACE("Texture is also bound to stage %u.\n", i);
prev->sampler = i;
if (stage >= WINED3DVERTEXTEXTURESAMPLER0 && stage <= WINED3DVERTEXTEXTURESAMPLER3)
stage -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
- if (stage >= sizeof(device->stateBlock->state.textures) / sizeof(*device->stateBlock->state.textures))
+ if (stage >= sizeof(device->state.textures) / sizeof(*device->state.textures))
{
WARN("Ignoring invalid stage %u.\n", stage);
return NULL; /* Windows accepts overflowing this array ... we do not. */
}
- return device->stateBlock->state.textures[stage];
+ return device->state.textures[stage];
}
HRESULT CDECL wined3d_device_get_back_buffer(const struct wined3d_device *device, UINT swapchain_idx,
TRACE("device %p.\n", device);
- if (device->isRecordingState)
+ if (device->recording)
return WINED3DERR_INVALIDCALL;
hr = wined3d_stateblock_create(device, WINED3D_SBT_RECORDED, &stateblock);
if (FAILED(hr))
return hr;
- wined3d_stateblock_decref(device->updateStateBlock);
- device->updateStateBlock = stateblock;
- device->isRecordingState = TRUE;
+ device->recording = stateblock;
+ device->update_state = &stateblock->state;
TRACE("Recording stateblock %p.\n", stateblock);
HRESULT CDECL wined3d_device_end_stateblock(struct wined3d_device *device,
struct wined3d_stateblock **stateblock)
{
- struct wined3d_stateblock *object = device->updateStateBlock;
+ struct wined3d_stateblock *object = device->recording;
TRACE("device %p, stateblock %p.\n", device, stateblock);
- if (!device->isRecordingState)
+ if (!device->recording)
{
WARN("Not recording.\n");
*stateblock = NULL;
stateblock_init_contained_states(object);
*stateblock = object;
- device->isRecordingState = FALSE;
- device->updateStateBlock = device->stateBlock;
- wined3d_stateblock_incref(device->updateStateBlock);
+ device->recording = NULL;
+ device->update_state = &device->state;
TRACE("Returning stateblock %p.\n", *stateblock);
}
}
- wined3d_get_draw_rect(&device->stateBlock->state, &draw_rect);
+ wined3d_get_draw_rect(&device->state, &draw_rect);
device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
&device->fb, rect_count, rects, &draw_rect, flags, color, depth, stencil);
void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device,
enum wined3d_primitive_type primitive_type)
{
+ GLenum gl_primitive_type, prev;
+
TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type));
- device->updateStateBlock->changed.primitive_type = TRUE;
- device->updateStateBlock->state.gl_primitive_type = gl_primitive_type_from_d3d(primitive_type);
+ gl_primitive_type = gl_primitive_type_from_d3d(primitive_type);
+ prev = device->update_state->gl_primitive_type;
+ device->update_state->gl_primitive_type = gl_primitive_type;
+ if (device->recording)
+ device->recording->changed.primitive_type = TRUE;
+ else if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS))
+ device_invalidate_state(device, STATE_POINT_SIZE_ENABLE);
}
void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device,
{
TRACE("device %p, primitive_type %p\n", device, primitive_type);
- *primitive_type = d3d_primitive_type_from_gl(device->stateBlock->state.gl_primitive_type);
+ *primitive_type = d3d_primitive_type_from_gl(device->state.gl_primitive_type);
TRACE("Returning %s\n", debug_d3dprimitivetype(*primitive_type));
}
{
TRACE("device %p, start_vertex %u, vertex_count %u.\n", device, start_vertex, vertex_count);
- if (!device->stateBlock->state.vertex_declaration)
+ if (!device->state.vertex_declaration)
{
WARN("Called without a valid vertex declaration set.\n");
return WINED3DERR_INVALIDCALL;
}
- if (device->stateBlock->state.load_base_vertex_index)
+ if (device->state.load_base_vertex_index)
{
- device->stateBlock->state.load_base_vertex_index = 0;
+ device->state.load_base_vertex_index = 0;
device_invalidate_state(device, STATE_BASEVERTEXINDEX);
}
/* Account for the loading offset due to index buffers. Instead of
* reloading all sources correct it with the startvertex parameter. */
- draw_primitive(device, start_vertex, vertex_count, 0, 0, FALSE, NULL);
+ draw_primitive(device, start_vertex, vertex_count, 0, 0, FALSE);
return WINED3D_OK;
}
TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
- if (!device->stateBlock->state.index_buffer)
+ if (!device->state.index_buffer)
{
/* D3D9 returns D3DERR_INVALIDCALL when DrawIndexedPrimitive is called
* without an index buffer set. (The first time at least...)
return WINED3DERR_INVALIDCALL;
}
- if (!device->stateBlock->state.vertex_declaration)
+ if (!device->state.vertex_declaration)
{
WARN("Called without a valid vertex declaration set.\n");
return WINED3DERR_INVALIDCALL;
}
if (!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] &&
- device->stateBlock->state.load_base_vertex_index != device->stateBlock->state.base_vertex_index)
+ device->state.load_base_vertex_index != device->state.base_vertex_index)
{
- device->stateBlock->state.load_base_vertex_index = device->stateBlock->state.base_vertex_index;
+ device->state.load_base_vertex_index = device->state.base_vertex_index;
device_invalidate_state(device, STATE_BASEVERTEXINDEX);
}
- draw_primitive(device, start_idx, index_count, 0, 0, TRUE, NULL);
+ draw_primitive(device, start_idx, index_count, 0, 0, TRUE);
return WINED3D_OK;
}
{
TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
- draw_primitive(device, start_idx, index_count, start_instance, instance_count, TRUE, NULL);
+ draw_primitive(device, start_idx, index_count, start_instance, instance_count, TRUE);
}
/* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */
struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume)
{
struct wined3d_map_desc src;
- struct wined3d_map_desc dst;
HRESULT hr;
+ struct wined3d_bo_address data;
+ struct wined3d_context *context;
TRACE("device %p, src_volume %p, dst_volume %p.\n",
device, src_volume, dst_volume);
- /* TODO: Implement direct loading into the gl volume instead of using
- * memcpy and dirtification to improve loading performance. */
- if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY)))
- return hr;
- if (FAILED(hr = wined3d_volume_map(dst_volume, &dst, NULL, WINED3D_MAP_DISCARD)))
+ if (src_volume->resource.format != dst_volume->resource.format)
{
- wined3d_volume_unmap(src_volume);
- return hr;
+ FIXME("Source and destination formats do not match.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ if (src_volume->resource.width != dst_volume->resource.width
+ || src_volume->resource.height != dst_volume->resource.height
+ || src_volume->resource.depth != dst_volume->resource.depth)
+ {
+ FIXME("Source and destination sizes do not match.\n");
+ return WINED3DERR_INVALIDCALL;
}
- memcpy(dst.data, src.data, dst_volume->resource.size);
+ if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY)))
+ return hr;
- hr = wined3d_volume_unmap(dst_volume);
- if (FAILED(hr))
- wined3d_volume_unmap(src_volume);
- else
- hr = wined3d_volume_unmap(src_volume);
+ context = context_acquire(device, NULL);
+
+ wined3d_volume_load(dst_volume, context, FALSE);
+
+ data.buffer_object = 0;
+ data.addr = src.data;
+ wined3d_volume_upload_data(dst_volume, context, &data);
+ wined3d_volume_invalidate_location(dst_volume, ~WINED3D_LOCATION_TEXTURE_RGB);
+
+ context_release(context);
+
+ hr = wined3d_volume_unmap(src_volume);
return hr;
}
return WINED3DERR_INVALIDCALL;
}
- if (src_texture == dst_texture)
+ if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM)
{
- WARN("Source and destination are the same object, returning WINED3DERR_INVALIDCALL.\n");
+ WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT)
+ {
+ WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n");
return WINED3DERR_INVALIDCALL;
}
HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes)
{
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_state *state = &device->state;
struct wined3d_texture *texture;
DWORD i;
if (state->sampler_states[i][WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_POINT)
{
- WARN("Non-filterable texture and mag filter enabled on samper %u, returning E_FAIL\n", i);
+ WARN("Non-filterable texture and mag filter enabled on sampler %u, returning E_FAIL\n", i);
return E_FAIL;
}
if (state->sampler_states[i][WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_POINT)
{
- WARN("Non-filterable texture and min filter enabled on samper %u, returning E_FAIL\n", i);
+ WARN("Non-filterable texture and min filter enabled on sampler %u, returning E_FAIL\n", i);
return E_FAIL;
}
if (state->sampler_states[i][WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_NONE
&& state->sampler_states[i][WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_POINT)
{
- WARN("Non-filterable texture and mip filter enabled on samper %u, returning E_FAIL\n", i);
+ WARN("Non-filterable texture and mip filter enabled on sampler %u, returning E_FAIL\n", i);
return E_FAIL;
}
}
* primary stateblock. */
if (!render_target_idx && set_viewport)
{
- struct wined3d_state *state = &device->stateBlock->state;
+ struct wined3d_state *state = &device->state;
state->viewport.x = 0;
state->viewport.y = 0;
context = context_acquire(device, NULL);
- if (gl_info->supported[APPLE_CLIENT_STORAGE])
- {
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
- }
-
invalidate_active_texture(device, context);
/* Create a new cursor texture */
gl_info->gl_ops.gl.p_glGenTextures(1, &device->cursorTexture);
checkGLcall("glTexImage2D");
HeapFree(GetProcessHeap(), 0, mem);
- if (gl_info->supported[APPLE_CLIENT_STORAGE])
- {
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
- }
-
context_release(context);
}
else
struct wined3d_surface *target;
HRESULT hr;
- if (FAILED(hr = device->shader_backend->shader_alloc_private(device, device->adapter->fragment_pipe)))
+ if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
+ device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
{
ERR("Failed to allocate shader private data, hr %#x.\n", hr);
return hr;
struct wined3d_display_mode m;
BOOL DisplayModeChanged = FALSE;
BOOL update_desc = FALSE;
+ UINT backbuffer_width = swapchain_desc->backbuffer_width;
+ UINT backbuffer_height = swapchain_desc->backbuffer_height;
HRESULT hr = WINED3D_OK;
unsigned int i;
}
if (reset_state)
- stateblock_unbind_resources(device->stateBlock);
+ state_unbind_resources(&device->state);
if (device->fb.render_targets)
{
if (swapchain_desc->enable_auto_depth_stencil && !device->auto_depth_stencil)
{
+ struct wined3d_resource_desc surface_desc;
+
TRACE("Creating the depth stencil buffer\n");
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
+ surface_desc.format = swapchain_desc->auto_depth_stencil_format;
+ surface_desc.multisample_type = swapchain_desc->multisample_type;
+ surface_desc.multisample_quality = swapchain_desc->multisample_quality;
+ surface_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
+ surface_desc.pool = WINED3D_POOL_DEFAULT;
+ surface_desc.width = swapchain_desc->backbuffer_width;
+ surface_desc.height = swapchain_desc->backbuffer_height;
+ surface_desc.depth = 1;
+ surface_desc.size = 0;
+
if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
- device->device_parent, swapchain_desc->backbuffer_width, swapchain_desc->backbuffer_height,
- swapchain_desc->auto_depth_stencil_format, WINED3DUSAGE_DEPTHSTENCIL,
- swapchain_desc->multisample_type, swapchain_desc->multisample_quality,
- &device->auto_depth_stencil)))
+ device->device_parent, &surface_desc, &device->auto_depth_stencil)))
{
ERR("Failed to create the depth stencil buffer, hr %#x.\n", hr);
return WINED3DERR_INVALIDCALL;
}
else if (swapchain_desc->windowed)
{
- m.width = swapchain->orig_width;
- m.height = swapchain->orig_height;
- m.refresh_rate = 0;
- m.format_id = swapchain->desc.backbuffer_format;
- m.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+ m = swapchain->original_mode;
}
else
{
m.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
}
- /* Should Width == 800 && Height == 0 set 800x600? */
- if (swapchain_desc->backbuffer_width && swapchain_desc->backbuffer_height
- && (swapchain_desc->backbuffer_width != swapchain->desc.backbuffer_width
- || swapchain_desc->backbuffer_height != swapchain->desc.backbuffer_height))
+ if (!backbuffer_width || !backbuffer_height)
+ {
+ /* The application is requesting that either the swapchain width or
+ * height be set to the corresponding dimension in the window's
+ * client rect. */
+
+ RECT client_rect;
+
+ if (!swapchain_desc->windowed)
+ return WINED3DERR_INVALIDCALL;
+
+ if (!GetClientRect(swapchain->device_window, &client_rect))
+ {
+ ERR("Failed to get client rect, last error %#x.\n", GetLastError());
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!backbuffer_width)
+ backbuffer_width = client_rect.right;
+
+ if (!backbuffer_height)
+ backbuffer_height = client_rect.bottom;
+ }
+
+ if (backbuffer_width != swapchain->desc.backbuffer_width
+ || backbuffer_height != swapchain->desc.backbuffer_height)
{
if (!swapchain_desc->windowed)
DisplayModeChanged = TRUE;
- swapchain->desc.backbuffer_width = swapchain_desc->backbuffer_width;
- swapchain->desc.backbuffer_height = swapchain_desc->backbuffer_height;
+ swapchain->desc.backbuffer_width = backbuffer_width;
+ swapchain->desc.backbuffer_height = backbuffer_height;
update_desc = TRUE;
}
if (reset_state)
{
TRACE("Resetting stateblock.\n");
- wined3d_stateblock_decref(device->updateStateBlock);
- wined3d_stateblock_decref(device->stateBlock);
+ if (device->recording)
+ {
+ wined3d_stateblock_decref(device->recording);
+ device->recording = NULL;
+ }
+ state_cleanup(&device->state);
if (device->d3d_initialized)
delete_opengl_contexts(device, swapchain);
- /* Note: No parent needed for initial internal stateblock */
- hr = wined3d_stateblock_create(device, WINED3D_SBT_INIT, &device->stateBlock);
- if (FAILED(hr))
- ERR("Resetting the stateblock failed with error %#x.\n", hr);
- else
- TRACE("Created stateblock %p.\n", device->stateBlock);
- device->updateStateBlock = device->stateBlock;
- wined3d_stateblock_incref(device->updateStateBlock);
-
- stateblock_init_default_state(device->stateBlock);
+ if (FAILED(hr = state_init(&device->state, &device->adapter->d3d_info)))
+ ERR("Failed to initialize device state, hr %#x.\n", hr);
+ state_init_default(&device->state, device);
+ device->update_state = &device->state;
}
else
{
struct wined3d_surface *rt = device->fb.render_targets[0];
- struct wined3d_state *state = &device->stateBlock->state;
+ struct wined3d_state *state = &device->state;
/* Note the min_z / max_z is not reset. */
state->viewport.x = 0;
{
struct wined3d_texture *texture = wined3d_texture_from_resource(resource);
- if (device->stateBlock && device->stateBlock->state.textures[i] == texture)
+ if (device->state.textures[i] == texture)
{
- ERR("Texture %p is still in use by stateblock %p, stage %u.\n",
- texture, device->stateBlock, i);
- device->stateBlock->state.textures[i] = NULL;
+ ERR("Texture %p is still in use, stage %u.\n", texture, i);
+ device->state.textures[i] = NULL;
}
- if (device->updateStateBlock != device->stateBlock
- && device->updateStateBlock->state.textures[i] == texture)
+ if (device->recording && device->update_state->textures[i] == texture)
{
- ERR("Texture %p is still in use by stateblock %p, stage %u.\n",
- texture, device->updateStateBlock, i);
- device->updateStateBlock->state.textures[i] = NULL;
+ ERR("Texture %p is still in use by recording stateblock %p, stage %u.\n",
+ texture, device->recording, i);
+ device->update_state->textures[i] = NULL;
}
}
break;
for (i = 0; i < MAX_STREAMS; ++i)
{
- if (device->stateBlock && device->stateBlock->state.streams[i].buffer == buffer)
+ if (device->state.streams[i].buffer == buffer)
{
- ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
- buffer, device->stateBlock, i);
- device->stateBlock->state.streams[i].buffer = NULL;
+ ERR("Buffer %p is still in use, stream %u.\n", buffer, i);
+ device->state.streams[i].buffer = NULL;
}
- if (device->updateStateBlock != device->stateBlock
- && device->updateStateBlock->state.streams[i].buffer == buffer)
+ if (device->recording && device->update_state->streams[i].buffer == buffer)
{
ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
- buffer, device->updateStateBlock, i);
- device->updateStateBlock->state.streams[i].buffer = NULL;
+ buffer, device->recording, i);
+ device->update_state->streams[i].buffer = NULL;
}
-
}
- if (device->stateBlock && device->stateBlock->state.index_buffer == buffer)
+ if (device->state.index_buffer == buffer)
{
- ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
- buffer, device->stateBlock);
- device->stateBlock->state.index_buffer = NULL;
+ ERR("Buffer %p is still in use as index buffer.\n", buffer);
+ device->state.index_buffer = NULL;
}
- if (device->updateStateBlock != device->stateBlock
- && device->updateStateBlock->state.index_buffer == buffer)
+ if (device->recording && device->update_state->index_buffer == buffer)
{
ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
- buffer, device->updateStateBlock);
- device->updateStateBlock->state.index_buffer = NULL;
+ buffer, device->recording);
+ device->update_state->index_buffer = NULL;
}
}
break;
{
struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
const struct fragment_pipeline *fragment_pipeline;
- struct shader_caps shader_caps;
- struct fragment_caps ffp_caps;
+ const struct wined3d_vertex_pipe_ops *vertex_pipeline;
unsigned int i;
HRESULT hr;
device->create_parms.flags = flags;
device->shader_backend = adapter->shader_backend;
- device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
- device->vs_version = shader_caps.vs_version;
- device->gs_version = shader_caps.gs_version;
- device->ps_version = shader_caps.ps_version;
- device->d3d_vshader_constantF = shader_caps.vs_uniform_count;
- device->d3d_pshader_constantF = shader_caps.ps_uniform_count;
- device->vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
+
+ vertex_pipeline = adapter->vertex_pipe;
fragment_pipeline = adapter->fragment_pipe;
- fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps);
- device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
- if (fragment_pipeline->states
+ if (vertex_pipeline->vp_states && fragment_pipeline->states
&& FAILED(hr = compile_state_table(device->StateTable, device->multistate_funcs,
- &adapter->gl_info, ffp_vertexstate_template, fragment_pipeline, misc_state_template)))
+ &adapter->gl_info, &adapter->d3d_info, vertex_pipeline,
+ fragment_pipeline, misc_state_template)))
{
ERR("Failed to compile state table, hr %#x.\n", hr);
wined3d_decref(device->wined3d);
device->blitter = adapter->blitter;
- hr = wined3d_stateblock_create(device, WINED3D_SBT_INIT, &device->stateBlock);
- if (FAILED(hr))
+ if (FAILED(hr = state_init(&device->state, &adapter->d3d_info)))
{
- WARN("Failed to create stateblock.\n");
+ ERR("Failed to initialize device state, hr %#x.\n", hr);
for (i = 0; i < sizeof(device->multistate_funcs) / sizeof(device->multistate_funcs[0]); ++i)
{
HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
wined3d_decref(device->wined3d);
return hr;
}
-
- TRACE("Created stateblock %p.\n", device->stateBlock);
- device->updateStateBlock = device->stateBlock;
- wined3d_stateblock_incref(device->updateStateBlock);
+ device->update_state = &device->state;
return WINED3D_OK;
}
//#include "winternl.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
#define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
+#define DEFAULT_REFRESH_RATE 0
/* The driver names reflect the lowest GPU supported
* by a certain driver, so DRIVER_AMD_R300 supports
/* ARB */
{"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT },
+ {"GL_ARB_debug_output", ARB_DEBUG_OUTPUT },
{"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT },
{"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP },
{"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE },
{"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL },
{"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX },
{"GL_ARB_instanced_arrays", ARB_INSTANCED_ARRAYS, },
+ {"GL_ARB_internalformat_query2", ARB_INTERNALFORMAT_QUERY2, },
{"GL_ARB_map_buffer_alignment", ARB_MAP_BUFFER_ALIGNMENT },
{"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE },
{"GL_ARB_multisample", ARB_MULTISAMPLE }, /* needs GLX_ARB_MULTISAMPLE as well */
{"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS },
{"GL_EXT_gpu_shader4", EXT_GPU_SHADER4 },
{"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL },
- {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE },
{"GL_EXT_point_parameters", EXT_POINT_PARAMETERS },
{"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX },
{"GL_EXT_secondary_color", EXT_SECONDARY_COLOR },
GL_NEAREST, GL_NEAREST, GL_NEAREST,
};
-/* drawStridedSlow attributes */
-glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT];
-glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT];
-glAttribFunc specular_func_3ubv;
-glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT];
-glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT];
-glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
-
-/**
- * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
- * i.e., there is no GL Context - Get a default rendering context to enable the
- * function query some info from GL.
- */
-
struct wined3d_fake_gl_ctx
{
HDC dc;
ERR("Failed to restore previous GL context.\n");
}
+static void wined3d_create_fake_gl_context_attribs(struct wined3d_fake_gl_ctx *fake_gl_ctx,
+ struct wined3d_gl_info *gl_info, const GLint *ctx_attribs)
+{
+ HGLRC new_ctx;
+
+ if (!(gl_info->p_wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB")))
+ return;
+
+ if (!(new_ctx = gl_info->p_wglCreateContextAttribsARB(fake_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))
+ {
+ ERR("Failed to make new context current, last error %#x.\n", GetLastError());
+ if (!wglDeleteContext(new_ctx))
+ ERR("Failed to delete new context, last error %#x.\n", GetLastError());
+ gl_info->p_wglCreateContextAttribsARB = NULL;
+ return;
+ }
+
+ if (!wglDeleteContext(fake_gl_ctx->gl_ctx))
+ ERR("Failed to delete old context, last error %#x.\n", GetLastError());
+ fake_gl_ctx->gl_ctx = new_ctx;
+}
+
/* Do not call while under the GL lock. */
static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
{
if (memcmp(check, pattern, sizeof(check)))
{
- WARN("PBO test failed, read back data doesn't match original.\n"
+ WARN_(d3d_perf)("PBO test failed, read back data doesn't match original.\n"
"Disabling PBOs. This may result in slower performance.\n");
gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
}
return FALSE;
}
+static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ DWORD data[4];
+ GLuint tex, fbo;
+ GLenum status;
+ float color[4] = {0.0f, 1.0f, 0.0f, 0.0f};
+ GLuint prog;
+ GLint err_pos;
+ static const char *program_code =
+ "!!ARBfp1.0\n"
+ "OPTION ARB_fog_linear;\n"
+ "MOV result.color, {1.0, 0.0, 0.0, 0.0};\n"
+ "END\n";
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+ return FALSE;
+ if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ return FALSE;
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
+ checkGLcall("glTexImage2D");
+
+ gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+ checkGLcall("glFramebufferTexture2D");
+
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
+ checkGLcall("glCheckFramebufferStatus");
+
+ gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
+ checkGLcall("glClear");
+ gl_info->gl_ops.gl.p_glViewport(0, 0, 4, 1);
+ checkGLcall("glViewport");
+
+ gl_info->gl_ops.gl.p_glEnable(GL_FOG);
+ gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, 0.5f);
+ gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, 0.5f);
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
+ gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
+ gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, color);
+ checkGLcall("fog setup");
+
+ GL_EXTCALL(glGenProgramsARB(1, &prog));
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog));
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(program_code), program_code));
+ gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("Test fragment program setup");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &err_pos);
+ if (err_pos != -1)
+ {
+ const char *error_str;
+ error_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB);
+ FIXME("Fog test program error at position %d: %s\n\n", err_pos, debugstr_a(error_str));
+ }
+
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f( 1.0f, -1.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f( 1.0f, 1.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glEnd();
+ checkGLcall("ARBfp fog test draw");
+
+ gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+ checkGLcall("glGetTexImage");
+ data[0] &= 0x00ffffff;
+ data[1] &= 0x00ffffff;
+ data[2] &= 0x00ffffff;
+ data[3] &= 0x00ffffff;
+
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);
+
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glDisable(GL_FOG);
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0));
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ GL_EXTCALL(glDeleteProgramsARB(1, &prog));
+ checkGLcall("ARBfp fog test teardown");
+
+ TRACE("Fog test data: %08x %08x %08x %08x\n", data[0], data[1], data[2], data[3]);
+ return data[0] != 0x00ff0000 || data[3] != 0x0000ff00;
+}
+
static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
{
/* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
gl_info->reserved_arb_constants = max(gl_info->reserved_arb_constants, 1);
}
+static void quirk_broken_arb_fog(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_BROKEN_ARB_FOG;
+}
+
struct driver_quirk
{
BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
quirk_r200_constants,
"r200 vertex shader constants"
},
+ {
+ match_broken_arb_fog,
+ quirk_broken_arb_fog,
+ "ARBfp fogstart == fogend workaround"
+ },
};
/* Certain applications (Steam) complain if we report an outdated driver version. In general,
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", DRIVER_NVIDIA_GEFORCE6, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", DRIVER_NVIDIA_GEFORCE6, 896 },
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_315M, "NVIDIA GeForce 315M", DRIVER_NVIDIA_GEFORCE6, 512 },
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_320M, "NVIDIA GeForce 320M", DRIVER_NVIDIA_GEFORCE6, 256},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_410M, "NVIDIA GeForce 410M", DRIVER_NVIDIA_GEFORCE6, 512},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT320M, "NVIDIA GeForce GT 320M", DRIVER_NVIDIA_GEFORCE6, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT325M, "NVIDIA GeForce GT 325M", DRIVER_NVIDIA_GEFORCE6, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT330, "NVIDIA GeForce GT 330", DRIVER_NVIDIA_GEFORCE6, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX570, "NVIDIA GeForce GTX 570", DRIVER_NVIDIA_GEFORCE6, 1280},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX580, "NVIDIA GeForce GTX 580", DRIVER_NVIDIA_GEFORCE6, 1536},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT610, "NVIDIA GeForce GT 610", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630, "NVIDIA GeForce GT 630", DRIVER_NVIDIA_GEFORCE6, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630M, "NVIDIA GeForce GT 630M", DRIVER_NVIDIA_GEFORCE6, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT640M, "NVIDIA GeForce GT 640M", DRIVER_NVIDIA_GEFORCE6, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT650M, "NVIDIA GeForce GT 650M", DRIVER_NVIDIA_GEFORCE6, 2048},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660, "NVIDIA GeForce GTX 660", 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_GTX770M, "NVIDIA GeForce GTX 770M", DRIVER_NVIDIA_GEFORCE6, 3072},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770, "NVIDIA GeForce GTX 770", DRIVER_NVIDIA_GEFORCE6, 2048},
/* AMD cards */
{HW_VENDOR_AMD, CARD_AMD_RAGE_128PRO, "ATI Rage Fury", DRIVER_AMD_RAGE_128PRO, 16 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD2600, "ATI Mobility Radeon HD 2600", DRIVER_AMD_R600, 256 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD2900, "ATI Radeon HD 2900 XT", DRIVER_AMD_R600, 512 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD3200, "ATI Radeon HD 3200 Graphics", DRIVER_AMD_R600, 128 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD4200M, "ATI Mobility Radeon HD 4200", DRIVER_AMD_R600, 256 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD4350, "ATI Radeon HD 4350", DRIVER_AMD_R600, 256 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD4600, "ATI Radeon HD 4600 Series", DRIVER_AMD_R600, 512 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD4700, "ATI Radeon HD 4700 Series", DRIVER_AMD_R600, 512 },
driver_os_version = 7;
driver_model = DRIVER_MODEL_NT6X;
}
+ else if (os_version.dwMinorVersion == 1)
+ {
+ driver_os_version = 8;
+ driver_model = DRIVER_MODEL_NT6X;
+ }
else
{
- if (os_version.dwMinorVersion > 1)
+ if (os_version.dwMinorVersion > 2)
{
- FIXME("Unhandled OS version %u.%u, reporting Win 7.\n",
+ FIXME("Unhandled OS version %u.%u, reporting Win 8.\n",
os_version.dwMajorVersion, os_version.dwMinorVersion);
}
- driver_os_version = 8;
+ driver_os_version = 9;
driver_model = DRIVER_MODEL_NT6X;
}
break;
}
cards[] =
{
+ {"GTX 770M", CARD_NVIDIA_GEFORCE_GTX770M}, /* Geforce 700 - midend high mobile */
+ {"GTX 770", CARD_NVIDIA_GEFORCE_GTX770}, /* Geforce 700 - highend */
{"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 660", CARD_NVIDIA_GEFORCE_GTX660}, /* Geforce 600 - midend high */
{"GT 650M", CARD_NVIDIA_GEFORCE_GT650M}, /* Geforce 600 - midend mobile */
{"GT 640M", CARD_NVIDIA_GEFORCE_GT640M}, /* Geforce 600 - midend mobile */
{"GT 630M", CARD_NVIDIA_GEFORCE_GT630M}, /* Geforce 600 - midend mobile */
+ {"GT 630", CARD_NVIDIA_GEFORCE_GT630}, /* Geforce 600 - lowend */
{"GT 610", CARD_NVIDIA_GEFORCE_GT610}, /* Geforce 600 - lowend */
{"GTX 580", CARD_NVIDIA_GEFORCE_GTX580}, /* Geforce 500 - highend */
{"GTX 570", CARD_NVIDIA_GEFORCE_GTX570}, /* Geforce 500 - midend high */
{"GT 440", CARD_NVIDIA_GEFORCE_GT440}, /* Geforce 400 - lowend */
{"GT 430", CARD_NVIDIA_GEFORCE_GT430}, /* Geforce 400 - lowend */
{"GT 420", CARD_NVIDIA_GEFORCE_GT420}, /* Geforce 400 - lowend */
+ {"410M", CARD_NVIDIA_GEFORCE_410M}, /* Geforce 400 - lowend mobile */
{"GT 330", CARD_NVIDIA_GEFORCE_GT330}, /* Geforce 300 - highend */
{"GTS 360M", CARD_NVIDIA_GEFORCE_GTS350M}, /* Geforce 300 - highend mobile */
{"GTS 350M", CARD_NVIDIA_GEFORCE_GTS350M}, /* Geforce 300 - highend mobile */
{"GT 325M", CARD_NVIDIA_GEFORCE_GT325M}, /* Geforce 300 - midend mobile */
{"GT 320M", CARD_NVIDIA_GEFORCE_GT320M}, /* Geforce 300 - midend mobile */
{"320M", CARD_NVIDIA_GEFORCE_320M}, /* Geforce 300 - midend mobile */
+ {"315M", CARD_NVIDIA_GEFORCE_315M}, /* Geforce 300 - midend mobile */
{"GTX 295", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */
{"GTX 285", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */
{"GTX 280", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */
{"HD 4550", CARD_AMD_RADEON_HD4350}, /* Radeon RV710 */
{"HD 4350", CARD_AMD_RADEON_HD4350}, /* Radeon RV710 */
/* R600/R700 integrated */
+ {"HD 4200M", CARD_AMD_RADEON_HD4200M},
{"HD 3300", CARD_AMD_RADEON_HD3200},
{"HD 3200", CARD_AMD_RADEON_HD3200},
{"HD 3100", CARD_AMD_RADEON_HD3200},
{"RV730", CARD_AMD_RADEON_HD4600},
{"RV710", CARD_AMD_RADEON_HD4350},
/* R600/R700 integrated */
- {"RS880", CARD_AMD_RADEON_HD3200},
+ {"RS880", CARD_AMD_RADEON_HD4200M},
{"RS780", CARD_AMD_RADEON_HD3200},
/* R600 */
{"R680", CARD_AMD_RADEON_HD2900},
cards[] =
{
/* Kepler */
+ {"NVE6", CARD_NVIDIA_GEFORCE_GTX770M},
{"NVE4", CARD_NVIDIA_GEFORCE_GTX680},
/* Fermi */
{"NVD9", CARD_NVIDIA_GEFORCE_GT520},
* memory behind our backs if really needed. Note that the amount of video
* memory can be overruled using a registry setting. */
- int i;
+ unsigned int i;
enum wined3d_pci_device device;
for (i = 0; i < (sizeof(card_vendor_table) / sizeof(*card_vendor_table)); ++i)
return select_card_fallback_nvidia(gl_info);
}
+static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const struct wined3d_gl_info *gl_info,
+ const struct wined3d_shader_backend_ops *shader_backend_ops)
+{
+ if (shader_backend_ops == &glsl_shader_backend)
+ return &glsl_vertex_pipe;
+ return &ffp_vertex_pipe;
+}
+
static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info,
const struct wined3d_shader_backend_ops *shader_backend_ops)
{
}
else
{
- WARN("Driver doesn't guarantee a minimum buffer map alignment.\n");
+ WARN_(d3d_perf)("Driver doesn't guarantee a minimum buffer map alignment.\n");
}
if (gl_info->supported[NV_REGISTER_COMBINERS])
{
struct wined3d_driver_info *driver_info = &adapter->driver_info;
const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
struct wined3d_gl_info *gl_info = &adapter->gl_info;
+ struct wined3d_vertex_caps vertex_caps;
enum wined3d_pci_vendor card_vendor;
struct fragment_caps fragment_caps;
+ struct shader_caps shader_caps;
const char *WGL_Extensions = NULL;
const char *GL_Extensions = NULL;
enum wined3d_gl_vendor gl_vendor;
enum wined3d_pci_device device;
DWORD gl_version;
HDC hdc;
+ unsigned int i;
TRACE("adapter %p.\n", adapter);
* we never render to sRGB surfaces). */
gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE;
}
+ if (gl_info->supported[ARB_OCCLUSION_QUERY])
+ {
+ GLint counter_bits;
+
+ GL_EXTCALL(glGetQueryivARB(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB, &counter_bits));
+ TRACE("Occlusion query counter has %d bits.\n", counter_bits);
+ if (!counter_bits)
+ gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE;
+ }
wined3d_adapter_init_limits(gl_info);
checkGLcall("extension detection");
adapter->shader_backend = select_shader_backend(gl_info);
+ adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend);
adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
adapter->blitter = select_blit_implementation(gl_info, adapter->shader_backend);
+ adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
+ adapter->d3d_info.vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
+ adapter->d3d_info.limits.vs_version = shader_caps.vs_version;
+ adapter->d3d_info.limits.gs_version = shader_caps.gs_version;
+ adapter->d3d_info.limits.ps_version = shader_caps.ps_version;
+ adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count;
+ adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count;
+
+ adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps);
+ adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw;
+
adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
- gl_info->limits.texture_stages = fragment_caps.MaxTextureBlendStages;
- TRACE("Max texture stages: %u.\n", gl_info->limits.texture_stages);
+ adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
+ adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
+ TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages);
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
{
}
else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
- WARN("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
+ WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
}
if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
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;
+ adapter->d3d_info.valid_rt_mask = 0;
+ for (i = 0; i < gl_info->limits.buffers; ++i)
+ adapter->d3d_info.valid_rt_mask |= (1 << i);
+
fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device);
init_driver_info(driver_info, card_vendor, device);
add_gl_compat_wrappers(gl_info);
return FALSE;
}
+/* OpenGL supports mipmapping on all formats. Wrapping is unsupported, but we
+ * have to report mipmapping so we cannot reject WRAPANDMIP. Tests show that
+ * Windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to
+ * show that wrapping is supported. The lack of filtering will sort out the
+ * mipmapping capability anyway.
+ *
+ * For now lets report this on all formats, but in the future we may want to
+ * restrict it to some should applications need that. */
HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT adapter_idx,
enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, DWORD usage,
enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id)
const struct wined3d_gl_info *gl_info = &adapter->gl_info;
const struct wined3d_format *adapter_format = wined3d_get_format(gl_info, adapter_format_id);
const struct wined3d_format *format = wined3d_get_format(gl_info, check_format_id);
- DWORD usage_caps = 0;
+ DWORD format_flags = 0;
+ DWORD allowed_usage;
TRACE("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s,\n"
"resource_type %s, check_format %s.\n",
switch (resource_type)
{
case WINED3D_RTYPE_CUBE_TEXTURE:
- /* Cubetexture allows:
- * - WINED3DUSAGE_AUTOGENMIPMAP
- * - WINED3DUSAGE_DEPTHSTENCIL
- * - WINED3DUSAGE_DYNAMIC
- * - WINED3DUSAGE_NONSECURE (d3d9ex)
- * - WINED3DUSAGE_RENDERTARGET
- * - WINED3DUSAGE_SOFTWAREPROCESSING
- * - WINED3DUSAGE_QUERY_WRAPANDMIP
- */
- if (wined3d->flags & WINED3D_NO3D)
- {
- TRACE("[FAILED]\n");
- return WINED3DERR_NOTAVAILABLE;
- }
-
if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP])
{
TRACE("[FAILED] - No cube texture support.\n");
return WINED3DERR_NOTAVAILABLE;
}
- if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
- {
- TRACE("[FAILED] - Cube texture format not supported.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
-
- if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
- {
- if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
- /* When autogenmipmap isn't around continue and return
- * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
- TRACE("[FAILED] - No autogenmipmap support, but continuing.\n");
- else
- usage_caps |= WINED3DUSAGE_AUTOGENMIPMAP;
- }
-
- /* Always report dynamic locking. */
- if (usage & WINED3DUSAGE_DYNAMIC)
- usage_caps |= WINED3DUSAGE_DYNAMIC;
-
- if (usage & WINED3DUSAGE_RENDERTARGET)
- {
- if (!CheckRenderTargetCapability(adapter, adapter_format, format))
- {
- TRACE("[FAILED] - No render target support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_RENDERTARGET;
- }
-
- /* Always report software processing. */
- if (usage & WINED3DUSAGE_SOFTWAREPROCESSING)
- usage_caps |= WINED3DUSAGE_SOFTWAREPROCESSING;
-
- if (usage & WINED3DUSAGE_QUERY_FILTER)
- {
- if (!(format->flags & WINED3DFMT_FLAG_FILTERING))
- {
- TRACE("[FAILED] - No filter support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_FILTER;
- }
-
- if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
- {
- if (!(format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
- {
- TRACE("[FAILED] - No post pixelshader blending support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
- }
-
- if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
- {
- if (!(format->flags & WINED3DFMT_FLAG_SRGB_READ))
- {
- TRACE("[FAILED] - No sRGB read support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_SRGBREAD;
- }
-
- if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
- {
- if (!(format->flags & WINED3DFMT_FLAG_SRGB_WRITE))
- {
- TRACE("[FAILED] - No sRGB write support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_SRGBWRITE;
- }
-
- if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
- {
- if (!(format->flags & WINED3DFMT_FLAG_VTF))
- {
- TRACE("[FAILED] - No vertex texture support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
- }
-
- /* OpenGL supports mipmapping on all formats. Wrapping is
- * unsupported, but we have to report mipmapping so we cannot
- * reject this flag. Tests show that Windows reports WRAPANDMIP on
- * unfilterable surfaces as well, apparently to show that wrapping
- * is supported. The lack of filtering will sort out the
- * mipmapping capability anyway.
- *
- * For now lets report this on all formats, but in the future we
- * may want to restrict it to some should applications need that. */
- if (usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
- usage_caps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
-
+ format_flags |= WINED3DFMT_FLAG_TEXTURE;
+ allowed_usage = WINED3DUSAGE_AUTOGENMIPMAP
+ | WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_RENDERTARGET
+ | WINED3DUSAGE_SOFTWAREPROCESSING
+ | WINED3DUSAGE_QUERY_FILTER
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+ | WINED3DUSAGE_QUERY_SRGBREAD
+ | WINED3DUSAGE_QUERY_SRGBWRITE
+ | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+ | WINED3DUSAGE_QUERY_WRAPANDMIP;
break;
case WINED3D_RTYPE_SURFACE:
- /* Surface allows:
- * - WINED3DUSAGE_DEPTHSTENCIL
- * - WINED3DUSAGE_NONSECURE (d3d9ex)
- * - WINED3DUSAGE_RENDERTARGET
- */
if (!CheckSurfaceCapability(adapter, adapter_format, format, wined3d->flags & WINED3D_NO3D))
{
TRACE("[FAILED] - Not supported for plain surfaces.\n");
return WINED3DERR_NOTAVAILABLE;
}
- if (usage & WINED3DUSAGE_DEPTHSTENCIL)
- {
- if (!CheckDepthStencilCapability(adapter, adapter_format, format))
- {
- TRACE("[FAILED] - No depth/stencil support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_DEPTHSTENCIL;
- }
-
- if (usage & WINED3DUSAGE_RENDERTARGET)
- {
- if (!CheckRenderTargetCapability(adapter, adapter_format, format))
- {
- TRACE("[FAILED] - No render target support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_RENDERTARGET;
- }
-
- if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
- {
- if (!(format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
- {
- TRACE("[FAILED] - No post pixelshader blending support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
- }
+ allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
+ | WINED3DUSAGE_RENDERTARGET
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
break;
case WINED3D_RTYPE_TEXTURE:
- /* Texture allows:
- * - WINED3DUSAGE_AUTOGENMIPMAP
- * - WINED3DUSAGE_DEPTHSTENCIL
- * - WINED3DUSAGE_DMAP
- * - WINED3DUSAGE_DYNAMIC
- * - WINED3DUSAGE_NONSECURE (d3d9ex)
- * - WINED3DUSAGE_RENDERTARGET
- * - WINED3DUSAGE_SOFTWAREPROCESSING
- * - WINED3DUSAGE_TEXTAPI (d3d9ex)
- * - WINED3DUSAGE_QUERY_WRAPANDMIP
- */
- if (wined3d->flags & WINED3D_NO3D)
- {
- TRACE("[FAILED]\n");
- return WINED3DERR_NOTAVAILABLE;
- }
-
- if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
+ if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && (format->flags & WINED3DFMT_FLAG_SHADOW)
+ && !gl_info->supported[ARB_SHADOW])
{
- TRACE("[FAILED] - Texture format not supported.\n");
+ TRACE("[FAILED] - No shadow sampler support.\n");
return WINED3DERR_NOTAVAILABLE;
}
- if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
- {
- if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
- /* When autogenmipmap isn't around continue and return
- * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
- TRACE("[FAILED] - No autogenmipmap support, but continuing.\n");
- else
- usage_caps |= WINED3DUSAGE_AUTOGENMIPMAP;
- }
-
- /* Always report dynamic locking. */
- if (usage & WINED3DUSAGE_DYNAMIC)
- usage_caps |= WINED3DUSAGE_DYNAMIC;
-
- if (usage & WINED3DUSAGE_RENDERTARGET)
- {
- if (!CheckRenderTargetCapability(adapter, adapter_format, format))
- {
- TRACE("[FAILED] - No render target support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_RENDERTARGET;
- }
-
- /* Always report software processing. */
- if (usage & WINED3DUSAGE_SOFTWAREPROCESSING)
- usage_caps |= WINED3DUSAGE_SOFTWAREPROCESSING;
-
- if (usage & WINED3DUSAGE_QUERY_FILTER)
- {
- if (!(format->flags & WINED3DFMT_FLAG_FILTERING))
- {
- TRACE("[FAILED] - No filter support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_FILTER;
- }
-
- if (usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
- {
- if (!(format->flags & WINED3DFMT_FLAG_BUMPMAP))
- {
- TRACE("[FAILED] - No legacy bumpmap support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
- }
-
- if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
- {
- if (!(format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
- {
- TRACE("[FAILED] - No post pixelshader blending support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
- }
-
- if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
- {
- if (!(format->flags & WINED3DFMT_FLAG_SRGB_READ))
- {
- TRACE("[FAILED] - No sRGB read support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_SRGBREAD;
- }
-
- if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
- {
- if (!(format->flags & WINED3DFMT_FLAG_SRGB_WRITE))
- {
- TRACE("[FAILED] - No sRGB write support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_SRGBWRITE;
- }
-
- if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
- {
- if (!(format->flags & WINED3DFMT_FLAG_VTF))
- {
- TRACE("[FAILED] - No vertex texture support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
- }
-
- if (usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
- usage_caps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
-
- if (usage & WINED3DUSAGE_DEPTHSTENCIL)
- {
- if (!CheckDepthStencilCapability(adapter, adapter_format, format))
- {
- TRACE("[FAILED] - No depth/stencil support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- if ((format->flags & WINED3DFMT_FLAG_SHADOW) && !gl_info->supported[ARB_SHADOW])
- {
- TRACE("[FAILED] - No shadow sampler support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_DEPTHSTENCIL;
- }
+ format_flags |= WINED3DFMT_FLAG_TEXTURE;
+ allowed_usage = WINED3DUSAGE_AUTOGENMIPMAP
+ | WINED3DUSAGE_DEPTHSTENCIL
+ | WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_RENDERTARGET
+ | WINED3DUSAGE_SOFTWAREPROCESSING
+ | WINED3DUSAGE_QUERY_FILTER
+ | WINED3DUSAGE_QUERY_LEGACYBUMPMAP
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+ | WINED3DUSAGE_QUERY_SRGBREAD
+ | WINED3DUSAGE_QUERY_SRGBWRITE
+ | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+ | WINED3DUSAGE_QUERY_WRAPANDMIP;
break;
case WINED3D_RTYPE_VOLUME_TEXTURE:
case WINED3D_RTYPE_VOLUME:
/* Volume is to VolumeTexture what Surface is to Texture, but its
* usage caps are not documented. Most driver seem to offer
- * (nearly) the same on Volume and VolumeTexture, so do that too.
- *
- * Volumetexture allows:
- * - D3DUSAGE_DYNAMIC
- * - D3DUSAGE_NONSECURE (d3d9ex)
- * - D3DUSAGE_SOFTWAREPROCESSING
- * - D3DUSAGE_QUERY_WRAPANDMIP
- */
- if (wined3d->flags & WINED3D_NO3D)
- {
- TRACE("[FAILED]\n");
- return WINED3DERR_NOTAVAILABLE;
- }
-
+ * (nearly) the same on Volume and VolumeTexture, so do that too. */
if (!gl_info->supported[EXT_TEXTURE3D])
{
TRACE("[FAILED] - No volume texture support.\n");
return WINED3DERR_NOTAVAILABLE;
}
- if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
- {
- TRACE("[FAILED] - Format not supported.\n");
- 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, except for
- * WINED3DFMT_R32_FLOAT. */
- switch (check_format_id)
+ * support most of those formats on volumes anyway. */
+ if (format->convert)
{
- case WINED3DFMT_P8_UINT:
- case WINED3DFMT_L4A4_UNORM:
- case WINED3DFMT_R32_FLOAT:
- case WINED3DFMT_R16_FLOAT:
- case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
- case WINED3DFMT_R5G5_SNORM_L6_UNORM:
- case WINED3DFMT_R16G16_UNORM:
- TRACE("[FAILED] - No converted formats on volumes.\n");
- return WINED3DERR_NOTAVAILABLE;
-
- case WINED3DFMT_R8G8B8A8_SNORM:
- case WINED3DFMT_R16G16_SNORM:
- if (!gl_info->supported[NV_TEXTURE_SHADER])
- {
- TRACE("[FAILED] - No converted formats on volumes.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- break;
-
- case WINED3DFMT_R8G8_SNORM:
- if (!gl_info->supported[NV_TEXTURE_SHADER])
- {
- TRACE("[FAILED] - No converted formats on volumes.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- break;
+ 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
+ * driver does not, so we're free not to support this format. */
+ switch (check_format_id)
+ {
case WINED3DFMT_DXT1:
case WINED3DFMT_DXT2:
case WINED3DFMT_DXT3:
case WINED3DFMT_DXT4:
case WINED3DFMT_DXT5:
- /* 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 driver does not, so we're free
- * not to support this format. */
TRACE("[FAILED] - DXTn does not support 3D textures.\n");
return WINED3DERR_NOTAVAILABLE;
break;
}
- /* Always report dynamic locking. */
- if (usage & WINED3DUSAGE_DYNAMIC)
- usage_caps |= WINED3DUSAGE_DYNAMIC;
-
- /* Always report software processing. */
- if (usage & WINED3DUSAGE_SOFTWAREPROCESSING)
- usage_caps |= WINED3DUSAGE_SOFTWAREPROCESSING;
-
- if (usage & WINED3DUSAGE_QUERY_FILTER)
- {
- if (!(format->flags & WINED3DFMT_FLAG_FILTERING))
- {
- TRACE("[FAILED] - No filter support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_FILTER;
- }
+ format_flags |= WINED3DFMT_FLAG_TEXTURE;
+ allowed_usage = WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_SOFTWAREPROCESSING
+ | WINED3DUSAGE_QUERY_FILTER
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+ | WINED3DUSAGE_QUERY_SRGBREAD
+ | WINED3DUSAGE_QUERY_SRGBWRITE
+ | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+ | WINED3DUSAGE_QUERY_WRAPANDMIP;
+ break;
- if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
- {
- if (!(format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
- {
- TRACE("[FAILED] - No post pixelshader blending support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
- }
+ default:
+ FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
+ return WINED3DERR_NOTAVAILABLE;
+ }
- if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
- {
- if (!(format->flags & WINED3DFMT_FLAG_SRGB_READ))
- {
- TRACE("[FAILED] - No sRGB read support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_SRGBREAD;
- }
+ if ((usage & allowed_usage) != usage)
+ {
+ TRACE("Requested usage %#x, but resource type %s only allows %#x.\n",
+ usage, debug_d3dresourcetype(resource_type), allowed_usage);
+ return WINED3DERR_NOTAVAILABLE;
+ }
- if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
- {
- if (!(format->flags & WINED3DFMT_FLAG_SRGB_WRITE))
- {
- TRACE("[FAILED] - No sRGB write support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_SRGBWRITE;
- }
+ if (usage & WINED3DUSAGE_QUERY_FILTER)
+ format_flags |= WINED3DFMT_FLAG_FILTERING;
+ if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
+ format_flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+ if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
+ format_flags |= WINED3DFMT_FLAG_SRGB_READ;
+ if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
+ format_flags |= WINED3DFMT_FLAG_SRGB_WRITE;
+ if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
+ format_flags |= WINED3DFMT_FLAG_VTF;
+ if (usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
+ format_flags |= WINED3DFMT_FLAG_BUMPMAP;
- if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
- {
- if (!(format->flags & WINED3DFMT_FLAG_VTF))
- {
- TRACE("[FAILED] - No vertex texture support.\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- usage_caps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
- }
+ if ((format->flags & format_flags) != format_flags)
+ {
+ TRACE("Requested format flags %#x, but format %s only has %#x.\n",
+ format_flags, debug_d3dformat(check_format_id), format->flags);
+ return WINED3DERR_NOTAVAILABLE;
+ }
- if (usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
- usage_caps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
+ if ((format_flags & WINED3DFMT_FLAG_TEXTURE) && (wined3d->flags & WINED3D_NO3D))
+ {
+ TRACE("Requested texturing support, but wined3d was created with WINED3D_NO3D.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
- break;
+ if ((usage & WINED3DUSAGE_DEPTHSTENCIL)
+ && !CheckDepthStencilCapability(adapter, adapter_format, format))
+ {
+ TRACE("Requested WINED3DUSAGE_DEPTHSTENCIL, but format %s is not supported for depth / stencil buffers.\n",
+ debug_d3dformat(check_format_id));
+ return WINED3DERR_NOTAVAILABLE;
+ }
- default:
- FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
- return WINED3DERR_NOTAVAILABLE;
+ if ((usage & WINED3DUSAGE_RENDERTARGET)
+ && !CheckRenderTargetCapability(adapter, adapter_format, format))
+ {
+ TRACE("Requested WINED3DUSAGE_RENDERTARGET, but format %s is not supported for render targets.\n",
+ debug_d3dformat(check_format_id));
+ return WINED3DERR_NOTAVAILABLE;
}
- /* When the usage_caps exactly matches usage return WINED3D_OK except for
- * the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn't around, then
- * WINED3DOK_NOAUTOGEN is returned if all the other usage flags match. */
- if (usage_caps == usage)
- return WINED3D_OK;
- if (usage_caps == (usage & ~WINED3DUSAGE_AUTOGENMIPMAP))
+ if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !gl_info->supported[SGIS_GENERATE_MIPMAP])
+ {
+ TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n");
return WINED3DOK_NOAUTOGEN;
+ }
- TRACE("[FAILED] - Usage %#x requested for format %s and resource_type %s but only %#x is available.\n",
- usage, debug_d3dformat(check_format_id), debug_d3dresourcetype(resource_type), usage_caps);
-
- return WINED3DERR_NOTAVAILABLE;
+ return WINED3D_OK;
}
HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
const struct wined3d_gl_info *gl_info = &adapter->gl_info;
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;
TRACE("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n",
WINED3DPRASTERCAPS_ZBIAS |
WINED3DPRASTERCAPS_MIPMAPLODBIAS;
}
- if (gl_info->supported[NV_FOG_DISTANCE])
- {
- caps->RasterCaps |= WINED3DPRASTERCAPS_FOGRANGE;
- }
- /* FIXME Add:
- WINED3DPRASTERCAPS_COLORPERSPECTIVE
- WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
- WINED3DPRASTERCAPS_ANTIALIASEDGES
- WINED3DPRASTERCAPS_ZBUFFERLESSHSR
- WINED3DPRASTERCAPS_WBUFFER */
caps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
WINED3DPCMPCAPS_EQUAL |
caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
}
- caps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
-
- caps->MaxUserClipPlanes = gl_info->limits.clipplanes;
- caps->MaxActiveLights = gl_info->limits.lights;
-
- caps->MaxVertexBlendMatrices = gl_info->limits.blends;
- caps->MaxVertexBlendMatrixIndex = 0;
-
caps->MaxAnisotropy = gl_info->limits.anisotropy;
caps->MaxPointSize = gl_info->limits.pointsize_max;
-
- /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
- caps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
- WINED3DVTXPCAPS_MATERIALSOURCE7 |
- WINED3DVTXPCAPS_POSITIONALLIGHTS |
- WINED3DVTXPCAPS_LOCALVIEWER |
- WINED3DVTXPCAPS_VERTEXFOG |
- WINED3DVTXPCAPS_TEXGEN;
-
caps->MaxPrimitiveCount = 0xfffff; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
caps->MaxVertexIndex = 0xfffff;
caps->MaxStreams = MAX_STREAMS;
adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
+ adapter->vertex_pipe->vp_get_caps(&adapter->gl_info, &vertex_caps);
/* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
caps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
caps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
caps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures;
+ caps->MaxUserClipPlanes = vertex_caps.max_user_clip_planes;
+ caps->MaxActiveLights = vertex_caps.max_active_lights;
+ caps->MaxVertexBlendMatrices = vertex_caps.max_vertex_blend_matrices;
+ caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index;
+ caps->VertexProcessingCaps = vertex_caps.vertex_processing_caps;
+ caps->FVFCaps = vertex_caps.fvf_caps;
+ caps->RasterCaps |= vertex_caps.raster_caps;
+
/* The following caps are shader specific, but they are things we cannot detect, or which
* are the same among all shader models. So to avoid code duplication set the shader version
* specific, but otherwise constant caps here
WINEDDSCAPS_SYSTEMMEMORY |
WINEDDSCAPS_VIDEOMEMORY |
WINEDDSCAPS_VISIBLE;
- caps->ddraw_caps.stride_align = DDRAW_PITCH_ALIGNMENT;
if (!(wined3d->flags & WINED3D_NO3D))
{
static void WINE_GLAPI specular_d3dcolor(const void *data)
{
DWORD specularColor = *((const DWORD *)data);
- GLbyte d[] = {D3DCOLOR_B_R(specularColor),
- D3DCOLOR_B_G(specularColor),
- D3DCOLOR_B_B(specularColor)};
+ GLubyte d[] =
+ {
+ D3DCOLOR_B_R(specularColor),
+ D3DCOLOR_B_G(specularColor),
+ D3DCOLOR_B_B(specularColor)
+ };
- specular_func_3ubv(d);
+ context_get_current()->gl_info->gl_ops.ext.p_glSecondaryColor3ubvEXT(d);
}
static void WINE_GLAPI warn_no_specular_func(const void *data)
WARN("GL_EXT_secondary_color not supported\n");
}
-static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
+static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter)
{
- position_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)gl_info->gl_ops.gl.p_glVertex3fv;
- position_funcs[WINED3D_FFP_EMIT_FLOAT4] = position_float4;
- position_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor;
- position_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_SHORT4] = (glAttribFunc)gl_info->gl_ops.gl.p_glVertex2sv;
- position_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
- position_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
-
- diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor3fv;
- diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor4fv;
- diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor;
- diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor4ubv;
- diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor4sv;
- diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor4usv;
- diffuse_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
- diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
-
- /* No 4 component entry points here */
- specular_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ const struct wined3d_gl_info *gl_info = &adapter->gl_info;
+ struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
+ struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops;
+
+ ops->position[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex3fv;
+ if (!d3d_info->xyzrhw)
+ ops->position[WINED3D_FFP_EMIT_FLOAT4] = position_float4;
+ else
+ ops->position[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex4fv;
+ ops->position[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor;
+ ops->position[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_SHORT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex2sv;
+ ops->position[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+ ops->position[WINED3D_FFP_EMIT_INVALID] = invalid_func;
+
+ ops->diffuse[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor3fv;
+ ops->diffuse[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4fv;
+ ops->diffuse[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor;
+ ops->diffuse[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_UBYTE4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4ubv;
+ ops->diffuse[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_SHORT4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4sv;
+ ops->diffuse[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_USHORT4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4usv;
+ ops->diffuse[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+ ops->diffuse[WINED3D_FFP_EMIT_INVALID] = invalid_func;
+
+ /* No 4 component entry points here. */
+ ops->specular[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
if (gl_info->supported[EXT_SECONDARY_COLOR])
- {
- specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
- }
+ ops->specular[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)GL_EXTCALL(glSecondaryColor3fvEXT);
else
- {
- specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func;
- }
- specular_funcs[WINED3D_FFP_EMIT_FLOAT4] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func;
+ ops->specular[WINED3D_FFP_EMIT_FLOAT4] = invalid_func;
if (gl_info->supported[EXT_SECONDARY_COLOR])
+ ops->specular[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
+ else
+ ops->specular[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
+ ops->specular[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+ ops->specular[WINED3D_FFP_EMIT_INVALID] = invalid_func;
+
+ /* Only 3 component entry points here. Test how others behave. Float4
+ * normals are used by one of our tests, trying to pass it to the pixel
+ * shader, which fails on Windows. */
+ ops->normal[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv;
+ /* Just ignore the 4th value. */
+ ops->normal[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv;
+ ops->normal[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+ ops->normal[WINED3D_FFP_EMIT_INVALID] = invalid_func;
+
+ ops->texcoord[WINED3D_FFP_EMIT_FLOAT1] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB;
+ ops->texcoord[WINED3D_FFP_EMIT_FLOAT2] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2fvARB;
+ ops->texcoord[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord3fvARB;
+ ops->texcoord[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4fvARB;
+ ops->texcoord[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_UBYTE4] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_SHORT2] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2svARB;
+ ops->texcoord[WINED3D_FFP_EMIT_SHORT4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4svARB;
+ ops->texcoord[WINED3D_FFP_EMIT_UBYTE4N] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_SHORT2N] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_SHORT4N] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_USHORT2N] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_USHORT4N] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_UDEC3] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func;
+ if (gl_info->supported[NV_HALF_FLOAT])
{
- specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
- specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
+ /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT. */
+ ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_2] =
+ (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2hvNV;
+ ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_4] =
+ (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4hvNV;
}
else
{
- specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
- }
- specular_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
- specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
-
- /* Only 3 component entry points here. Test how others behave. Float4 normals are used
- * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
- */
- normal_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)gl_info->gl_ops.gl.p_glNormal3fv;
- normal_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)gl_info->gl_ops.gl.p_glNormal3fv; /* Just ignore the 4th value */
- normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
- normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
-
- multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
- multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
- multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
- multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
- multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
- multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
- multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func;
- if (gl_info->supported[NV_HALF_FLOAT])
- {
- /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
- multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
- multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
- } else {
- multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
- multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
+ ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
}
+ ops->texcoord[WINED3D_FFP_EMIT_INVALID] = invalid_texcoord_func;
}
static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc)
{
const struct wined3d_gl_info *gl_info = &adapter->gl_info;
- unsigned int i;
+ int i;
if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
{
{
struct wined3d_gl_info *gl_info = &adapter->gl_info;
struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
+ unsigned int ctx_attrib_idx = 0;
DISPLAY_DEVICEW display_device;
+ GLint ctx_attribs[3];
TRACE("adapter %p, ordinal %u.\n", adapter, ordinal);
return FALSE;
}
+ if (context_debug_output_enabled(gl_info))
+ {
+ ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
+ 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);
+
if (!wined3d_adapter_init_gl_caps(adapter))
{
ERR("Failed to initialize GL caps for adapter %p.\n", adapter);
WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
- fillGLAttribFuncs(&adapter->gl_info);
+ wined3d_adapter_init_ffp_attrib_ops(adapter);
return TRUE;
}
initPixelFormatsNoGL(&adapter->gl_info);
+ adapter->vertex_pipe = &none_vertex_pipe;
adapter->fragment_pipe = &none_fragment_pipe;
adapter->shader_backend = &none_shader_backend;
adapter->blitter = &cpu_blit;
-
+
display_device.cb = sizeof(display_device);
EnumDisplayDevicesW(NULL, ordinal, &display_device, 0);
TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName));
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
//#include <stdio.h>
//#include <math.h>
const WORD *pIdxBufS = NULL;
const DWORD *pIdxBufL = NULL;
UINT vx_index;
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_state *state = &device->state;
LONG SkipnStrides = startIdx;
BOOL pixelShader = use_ps(state);
BOOL specular_fog = FALSE;
const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
const struct wined3d_gl_info *gl_info = context->gl_info;
- UINT texture_stages = gl_info->limits.texture_stages;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ const struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops;
+ UINT texture_stages = d3d_info->limits.ffp_blend_stages;
const struct wined3d_stream_info_element *element;
UINT num_untracked_materials;
DWORD tex_mask = 0;
- TRACE("Using slow vertex array code\n");
+ TRACE_(d3d_perf)("Using slow vertex array code\n");
/* Variable Initialization */
if (idxSize)
ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);
texture_idx = device->texUnitMap[texture];
- multi_texcoord_funcs[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx](
+ ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx](
GL_TEXTURE0_ARB + texture_idx, ptr);
}
/* Diffuse -------------------------------- */
- if (diffuse) {
+ if (diffuse)
+ {
const void *ptrToCoords = diffuse + SkipnStrides * si->elements[WINED3D_FFP_DIFFUSE].stride;
+ ops->diffuse[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptrToCoords);
- diffuse_funcs[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptrToCoords);
if (num_untracked_materials)
{
DWORD diffuseColor = ((const DWORD *)ptrToCoords)[0];
}
/* Specular ------------------------------- */
- if (specular) {
+ if (specular)
+ {
const void *ptrToCoords = specular + SkipnStrides * si->elements[WINED3D_FFP_SPECULAR].stride;
-
- specular_funcs[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptrToCoords);
+ ops->specular[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptrToCoords);
if (specular_fog)
{
if (normal)
{
const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride;
- normal_funcs[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptrToCoords);
+ ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptrToCoords);
}
/* Position -------------------------------- */
- if (position) {
+ if (position)
+ {
const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride;
- position_funcs[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptrToCoords);
+ ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptrToCoords);
}
/* For non indexed mode, step onto next parts */
/* Routine common to the draw primitive and draw indexed primitive routines */
void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count,
- UINT start_instance, UINT instance_count, BOOL indexed, const void *idx_data)
+ UINT start_instance, UINT instance_count, BOOL indexed)
{
- const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_state *state = &device->state;
const struct wined3d_stream_info *stream_info;
struct wined3d_event_query *ib_query = NULL;
struct wined3d_stream_info si_emulated;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
BOOL emulation = FALSE;
+ const void *idx_data = NULL;
UINT idx_size = 0;
unsigned int i;
FIXME("Point sprite coordinate origin switching not supported.\n");
}
- stream_info = &device->strided_streams;
+ stream_info = &device->stream_info;
if (device->instance_count)
instance_count = device->instance_count;
if (!warned++)
FIXME("Using software emulation because not all material properties could be tracked.\n");
else
- WARN("Using software emulation because not all material properties could be tracked.\n");
+ WARN_(d3d_perf)("Using software emulation because not all material properties could be tracked.\n");
emulation = TRUE;
}
else if (context->fog_coord && state->render_states[WINED3D_RS_FOGENABLE])
if (!warned++)
FIXME("Using software emulation because manual fog coordinates are provided.\n");
else
- WARN("Using software emulation because manual fog coordinates are provided.\n");
+ WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n");
emulation = TRUE;
}
if (emulation)
{
- si_emulated = device->strided_streams;
+ si_emulated = device->stream_info;
remove_vbos(gl_info, state, &si_emulated);
stream_info = &si_emulated;
}
if (!warned++)
FIXME("Using immediate mode with vertex shaders for half float emulation.\n");
else
- WARN("Using immediate mode with vertex shaders for half float emulation.\n");
+ WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n");
drawStridedSlowVs(gl_info, state, stream_info, index_count,
state->gl_primitive_type, idx_data, idx_size, start_idx);
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(gl_compat);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
/* Start GL_ARB_multitexture emulation */
static void WINE_GLAPI wine_glMultiTexCoord1fARB(GLenum target, GLfloat s) {
if(param == GL_FRAGMENT_DEPTH_EXT) {
if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
} else {
- WARN("Fog coords activated, but not supported. Using slow emulation\n");
+ WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n");
old_fogcoord_glDisable(GL_FOG);
}
} else {
if(*param == GL_FRAGMENT_DEPTH_EXT) {
if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
} else {
- WARN("Fog coords activated, but not supported. Using slow emulation\n");
+ WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n");
old_fogcoord_glDisable(GL_FOG);
}
} else {
if(param == GL_FRAGMENT_DEPTH_EXT) {
if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
} else {
- WARN("Fog coords activated, but not supported. Using slow emulation\n");
+ WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n");
old_fogcoord_glDisable(GL_FOG);
}
} else {
if(*param == GL_FRAGMENT_DEPTH_EXT) {
if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
} else {
- WARN("Fog coords activated, but not supported. Using slow emulation\n");
+ WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n");
old_fogcoord_glDisable(GL_FOG);
}
} else {
*
* Copyright 2006 Jason Green
* Copyright 2006-2007 Henri Verbeet
- * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2007-2009, 2013 Stefan Dösinger for CodeWeavers
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
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_RECT 0x2
+#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];
struct constant_heap
{
struct constant_entry *entries;
+ BOOL *contained;
unsigned int *positions;
unsigned int size;
};
struct shader_glsl_priv {
struct wined3d_shader_buffer shader_buffer;
struct wine_rb_tree program_lookup;
- struct glsl_shader_prog_link *glsl_program;
struct constant_heap vconst_heap;
struct constant_heap pconst_heap;
unsigned char *stack;
GLhandleARB depth_blt_program_masked[tex_type_count];
UINT next_constant_version;
+ const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
+ struct wine_rb_tree ffp_vertex_shaders;
struct wine_rb_tree ffp_fragment_shaders;
BOOL ffp_proj_control;
};
struct glsl_gs_program gs;
struct glsl_ps_program ps;
GLhandleARB programId;
+ DWORD constant_update_mask;
UINT constant_version;
};
struct ps_np2fixup_info *cur_np2fixup_info;
};
+struct glsl_context_data
+{
+ struct glsl_shader_prog_link *glsl_program;
+};
+
struct glsl_ps_compiled_shader
{
struct ps_compile_args args;
UINT num_gl_shaders, shader_array_size;
};
+struct glsl_ffp_vertex_shader
+{
+ struct wined3d_ffp_vs_desc desc;
+ GLhandleARB id;
+ struct list linked_programs;
+};
+
struct glsl_ffp_fragment_shader
{
struct ffp_frag_desc entry;
struct list linked_programs;
};
+struct glsl_ffp_destroy_ctx
+{
+ struct shader_glsl_priv *priv;
+ const struct wined3d_gl_info *gl_info;
+};
+
static const char *debug_gl_shader_type(GLenum type)
{
switch (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];
+
+ 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]);
+ shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]);
+}
+
/* Extract a line from the info log.
* Note that this modifies the source string. */
static char *get_info_log_line(char **ptr)
static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, const float *constants,
const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
{
+ unsigned int start = ~0U, end = 0;
int stack_idx = 0;
unsigned int heap_idx = 1;
unsigned int idx;
if (heap->entries[heap_idx].version <= version) return;
idx = heap->entries[heap_idx].idx;
- if (constant_locations[idx] != -1) GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+ if (constant_locations[idx] != -1)
+ start = end = idx;
stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
while (stack_idx >= 0)
heap_idx = left_idx;
idx = heap->entries[heap_idx].idx;
if (constant_locations[idx] != -1)
- GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+ {
+ if (start > idx)
+ start = idx;
+ if (end < idx)
+ end = idx;
+ }
stack[stack_idx++] = HEAP_NODE_TRAVERSE_RIGHT;
stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
heap_idx = right_idx;
idx = heap->entries[heap_idx].idx;
if (constant_locations[idx] != -1)
- GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+ {
+ if (start > idx)
+ start = idx;
+ if (end < idx)
+ end = idx;
+ }
stack[stack_idx++] = HEAP_NODE_POP;
stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
break;
}
}
+ if (start <= end)
+ GL_EXTCALL(glUniform4fvARB(constant_locations[start], end - start + 1, &constants[start * 4]));
checkGLcall("walk_constant_heap()");
}
/* Immediate constants are clamped to [-1;1] at shader creation time if needed */
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
{
- GLint location = constant_locations[lconst->idx];
- /* We found this uniform name in the program - go ahead and send the data */
- if (location != -1) GL_EXTCALL(glUniform4fvARB(location, 1, (const GLfloat *)lconst->value));
+ GL_EXTCALL(glUniform4fvARB(constant_locations[lconst->idx], 1, (const GLfloat *)lconst->value));
}
checkGLcall("glUniform4fvARB()");
}
* locations of the constants to avoid looking up each time */
snprintf(tmp_name, sizeof(tmp_name), "%s_b[%i]", prefix, i);
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
- if (tmp_loc != -1)
- {
- /* We found this uniform name in the program - go ahead and send the data */
- GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, &constants[i]));
- checkGLcall("glUniform1ivARB");
- }
+ GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, &constants[i]));
}
/* Load immediate constants */
snprintf(tmp_name, sizeof(tmp_name), "%s_b[%i]", prefix, idx);
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
- if (tmp_loc != -1) {
- /* We found this uniform name in the program - go ahead and send the data */
- GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, values));
- checkGLcall("glUniform1ivARB");
- }
+ GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, values));
ptr = list_next(&shader->constantsB, ptr);
}
+
+ checkGLcall("shader_glsl_load_constantsB()");
}
static void reset_program_constant_version(struct wine_rb_entry *entry, void *context)
}
/* Context activation is done by the caller (state handler). */
-static void shader_glsl_load_np2fixup_constants(void *shader_priv,
+static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps,
const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
{
- struct shader_glsl_priv *glsl_priv = shader_priv;
- const struct glsl_shader_prog_link *prog = glsl_priv->glsl_program;
-
- /* No GLSL program set - nothing to do. */
- if (!prog) return;
-
- /* NP2 texcoord fixup is (currently) only done for pixelshaders. */
- if (!use_ps(state)) return;
+ GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
+ UINT fixup = ps->np2_fixup_info->active;
+ UINT i;
- if (prog->ps.np2_fixup_info && prog->ps.np2_fixup_location != -1)
+ for (i = 0; fixup; fixup >>= 1, ++i)
{
- UINT i;
- UINT fixup = prog->ps.np2_fixup_info->active;
- GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
+ const struct wined3d_texture *tex = state->textures[i];
+ unsigned char idx = ps->np2_fixup_info->idx[i];
+ GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4];
- for (i = 0; fixup; fixup >>= 1, ++i)
+ if (!tex)
{
- const struct wined3d_texture *tex = state->textures[i];
- const unsigned char idx = prog->ps.np2_fixup_info->idx[i];
- GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4];
-
- if (!tex)
- {
- ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n");
- continue;
- }
-
- if (idx % 2)
- {
- tex_dim[2] = tex->pow2_matrix[0];
- tex_dim[3] = tex->pow2_matrix[5];
- }
- else
- {
- tex_dim[0] = tex->pow2_matrix[0];
- tex_dim[1] = tex->pow2_matrix[5];
- }
+ ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n");
+ continue;
}
- GL_EXTCALL(glUniform4fvARB(prog->ps.np2_fixup_location,
- prog->ps.np2_fixup_info->num_consts, np2fixup_constants));
+ if (idx % 2)
+ {
+ tex_dim[2] = tex->pow2_matrix[0];
+ tex_dim[3] = tex->pow2_matrix[5];
+ }
+ else
+ {
+ tex_dim[0] = tex->pow2_matrix[0];
+ tex_dim[1] = tex->pow2_matrix[5];
+ }
}
+
+ GL_EXTCALL(glUniform4fvARB(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, np2fixup_constants));
}
/* Context activation is done by the caller (state handler). */
-static void shader_glsl_load_constants(const struct wined3d_context *context,
- BOOL usePixelShader, BOOL useVertexShader)
+static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *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_gl_info *gl_info = context->gl_info;
- struct wined3d_device *device = context->swapchain->device;
- struct wined3d_stateblock *stateBlock = device->stateBlock;
- const struct wined3d_state *state = &stateBlock->state;
- struct shader_glsl_priv *priv = device->shader_priv;
+ struct shader_glsl_priv *priv = shader_priv;
float position_fixup[4];
+ DWORD update_mask = 0;
GLhandleARB programId;
- struct glsl_shader_prog_link *prog = priv->glsl_program;
+ struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
UINT constant_version;
int i;
}
programId = prog->programId;
constant_version = prog->constant_version;
+ update_mask = context->constant_update_mask & prog->constant_update_mask;
- if (useVertexShader)
- {
- const struct wined3d_shader *vshader = state->vertex_shader;
-
- /* Load DirectX 9 float constants/uniforms for vertex shader */
+ if (update_mask & WINED3D_SHADER_CONST_VS_F)
shader_glsl_load_constantsF(vshader, gl_info, state->vs_consts_f,
prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version);
- /* Load DirectX 9 integer constants/uniforms for vertex shader */
+ if (update_mask & WINED3D_SHADER_CONST_VS_I)
shader_glsl_load_constantsI(vshader, gl_info, prog->vs.uniform_i_locations, state->vs_consts_i,
- stateBlock->changed.vertexShaderConstantsI & vshader->reg_maps.integer_constants);
+ vshader->reg_maps.integer_constants);
- /* Load DirectX 9 boolean constants/uniforms for vertex shader */
+ if (update_mask & WINED3D_SHADER_CONST_VS_B)
shader_glsl_load_constantsB(vshader, gl_info, programId, state->vs_consts_b,
- stateBlock->changed.vertexShaderConstantsB & vshader->reg_maps.boolean_constants);
+ vshader->reg_maps.boolean_constants);
- /* Upload the position fixup params */
+ if (update_mask & WINED3D_SHADER_CONST_VS_POS_FIXUP)
+ {
shader_get_position_fixup(context, state, position_fixup);
GL_EXTCALL(glUniform4fvARB(prog->vs.pos_fixup_location, 1, position_fixup));
checkGLcall("glUniform4fvARB");
}
- if (usePixelShader)
- {
- const struct wined3d_shader *pshader = state->pixel_shader;
-
- /* Load DirectX 9 float constants/uniforms for pixel shader */
+ if (update_mask & WINED3D_SHADER_CONST_PS_F)
shader_glsl_load_constantsF(pshader, gl_info, state->ps_consts_f,
prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version);
- /* Load DirectX 9 integer constants/uniforms for pixel shader */
+ if (update_mask & WINED3D_SHADER_CONST_PS_I)
shader_glsl_load_constantsI(pshader, gl_info, prog->ps.uniform_i_locations, state->ps_consts_i,
- stateBlock->changed.pixelShaderConstantsI & pshader->reg_maps.integer_constants);
+ pshader->reg_maps.integer_constants);
- /* Load DirectX 9 boolean constants/uniforms for pixel shader */
+ if (update_mask & WINED3D_SHADER_CONST_PS_B)
shader_glsl_load_constantsB(pshader, gl_info, programId, state->ps_consts_b,
- stateBlock->changed.pixelShaderConstantsB & pshader->reg_maps.boolean_constants);
+ pshader->reg_maps.boolean_constants);
- /* Upload the environment bump map matrix if needed. The needsbumpmat
- * member specifies the texture stage to load the matrix from. It
- * can't be 0 for a valid texbem instruction. */
+ if (update_mask & WINED3D_SHADER_CONST_PS_BUMP_ENV)
+ {
for (i = 0; i < MAX_TEXTURES; ++i)
{
- const float *data;
-
if (prog->ps.bumpenv_mat_location[i] == -1)
continue;
- data = (const float *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00];
- GL_EXTCALL(glUniformMatrix2fvARB(prog->ps.bumpenv_mat_location[i], 1, 0, data));
- checkGLcall("glUniformMatrix2fvARB");
+ GL_EXTCALL(glUniformMatrix2fvARB(prog->ps.bumpenv_mat_location[i], 1, 0,
+ (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00]));
- /* texbeml needs the luminance scale and offset too. If texbeml
- * is used, needsbumpmat is set too, so we can check that in the
- * needsbumpmat check. */
if (prog->ps.bumpenv_lum_scale_location[i] != -1)
{
- const GLfloat *scale = (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE];
- const GLfloat *offset = (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET];
-
- GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_scale_location[i], 1, scale));
- checkGLcall("glUniform1fvARB");
- GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_offset_location[i], 1, offset));
- checkGLcall("glUniform1fvARB");
+ GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_scale_location[i], 1,
+ (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE]));
+ GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_offset_location[i], 1,
+ (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET]));
}
}
- if (prog->ps.ycorrection_location != -1)
- {
- float correction_params[4];
+ checkGLcall("bump env uniforms");
+ }
- if (context->render_offscreen)
- {
- correction_params[0] = 0.0f;
- correction_params[1] = 1.0f;
- } else {
- /* position is window relative, not viewport relative */
- correction_params[0] = (float) context->current_rt->resource.height;
- correction_params[1] = -1.0f;
- }
- GL_EXTCALL(glUniform4fvARB(prog->ps.ycorrection_location, 1, correction_params));
+ if (update_mask & WINED3D_SHADER_CONST_PS_Y_CORR)
+ {
+ float correction_params[4];
+
+ if (context->render_offscreen)
+ {
+ correction_params[0] = 0.0f;
+ correction_params[1] = 1.0f;
+ } else {
+ /* position is window relative, not viewport relative */
+ correction_params[0] = (float) context->current_rt->resource.height;
+ correction_params[1] = -1.0f;
}
+ GL_EXTCALL(glUniform4fvARB(prog->ps.ycorrection_location, 1, correction_params));
}
- else if (priv->fragment_pipe == &glsl_fragment_pipe)
+
+ if (update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP)
+ shader_glsl_load_np2fixup_constants(&prog->ps, gl_info, state);
+
+ if (update_mask & WINED3D_SHADER_CONST_FFP_PS)
{
float col[4];
- for (i = 0; i < MAX_TEXTURES; ++i)
+ if (prog->ps.tex_factor_location != -1)
{
- GL_EXTCALL(glUniformMatrix2fvARB(prog->ps.bumpenv_mat_location[i], 1, 0,
- (const float *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00]));
- GL_EXTCALL(glUniform1fARB(prog->ps.bumpenv_lum_scale_location[i],
- *(const float *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE]));
- GL_EXTCALL(glUniform1fARB(prog->ps.bumpenv_lum_offset_location[i],
- *(const float *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET]));
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
+ GL_EXTCALL(glUniform4fvARB(prog->ps.tex_factor_location, 1, col));
}
- D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
- GL_EXTCALL(glUniform4fARB(prog->ps.tex_factor_location, col[0], col[1], col[2], col[3]));
-
if (state->render_states[WINED3D_RS_SPECULARENABLE])
GL_EXTCALL(glUniform4fARB(prog->ps.specular_enable_location, 1.0f, 1.0f, 1.0f, 0.0f));
else
}
}
-static void update_heap_entry(const struct constant_heap *heap, unsigned int idx,
- unsigned int heap_idx, DWORD new_version)
+static void update_heap_entry(struct constant_heap *heap, unsigned int idx, DWORD new_version)
{
struct constant_entry *entries = heap->entries;
unsigned int *positions = heap->positions;
- unsigned int parent_idx;
+ unsigned int heap_idx, parent_idx;
+
+ if (!heap->contained[idx])
+ {
+ heap_idx = heap->size++;
+ heap->contained[idx] = TRUE;
+ }
+ else
+ {
+ heap_idx = positions[idx];
+ }
while (heap_idx > 1)
{
for (i = start; i < count + start; ++i)
{
- if (!device->stateBlock->changed.vertexShaderConstantsF[i])
- update_heap_entry(heap, i, heap->size++, priv->next_constant_version);
- else
- update_heap_entry(heap, i, heap->positions[i], priv->next_constant_version);
+ update_heap_entry(heap, i, priv->next_constant_version);
+ }
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F;
}
}
for (i = start; i < count + start; ++i)
{
- if (!device->stateBlock->changed.pixelShaderConstantsF[i])
- update_heap_entry(heap, i, heap->size++, priv->next_constant_version);
- else
- update_heap_entry(heap, i, heap->positions[i], priv->next_constant_version);
+ update_heap_entry(heap, i, priv->next_constant_version);
+ }
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
}
}
const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv)
{
const struct wined3d_shader_version *version = ®_maps->shader_version;
- const struct wined3d_state *state = &shader->device->stateBlock->state;
+ const struct wined3d_state *state = &shader->device->state;
const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_fb_state *fb = &shader->device->fb;
if (reg_maps->sampler_type[i])
{
BOOL shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << i));
- const struct wined3d_texture *texture;
+ BOOL tex_rect;
switch (reg_maps->sampler_type[i])
{
shader_addline(buffer, "uniform sampler1D %s_sampler%u;\n", prefix, i);
break;
case WINED3DSTT_2D:
- texture = state->textures[i];
+ tex_rect = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->np2_fixup & (1 << i));
+ tex_rect = tex_rect && gl_info->supported[ARB_TEXTURE_RECTANGLE];
if (shadow_sampler)
{
- if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
+ if (tex_rect)
shader_addline(buffer, "uniform sampler2DRectShadow %s_sampler%u;\n", prefix, i);
else
shader_addline(buffer, "uniform sampler2DShadow %s_sampler%u;\n", prefix, i);
}
else
{
- if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
+ if (tex_rect)
shader_addline(buffer, "uniform sampler2DRect %s_sampler%u;\n", prefix, i);
else
shader_addline(buffer, "uniform sampler2D %s_sampler%u;\n", prefix, i);
if (ps_args->srgb_correction)
{
- shader_addline(buffer, "const vec4 srgb_const0 = vec4(%.8e, %.8e, %.8e, %.8e);\n",
- srgb_pow, srgb_mul_high, srgb_sub_high, srgb_mul_low);
- shader_addline(buffer, "const vec4 srgb_const1 = vec4(%.8e, 0.0, 0.0, 0.0);\n",
- srgb_cmp);
+ shader_addline(buffer, "const vec4 srgb_const0 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const0);
+ shader_addline(buffer, ";\n");
+ shader_addline(buffer, "const vec4 srgb_const1 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const1);
+ shader_addline(buffer, ";\n");
}
if (reg_maps->vpos || reg_maps->usesdsy)
{
}
else
{
- /* This happens because we do not have proper tracking of the constant registers that are
- * actually used, only the max limit of the shader version
- */
+ float ycorrection[] =
+ {
+ context->render_offscreen ? 0.0f : fb->render_targets[0]->resource.height,
+ context->render_offscreen ? 1.0f : -1.0f,
+ 0.0f,
+ 0.0f,
+ };
+
+ /* This happens because we do not have proper tracking of the
+ * constant registers that are actually used, only the max
+ * limit of the shader version. */
FIXME("Cannot find a free uniform for vpos correction params\n");
- shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n",
- context->render_offscreen ? 0.0f : fb->render_targets[0]->resource.height,
- context->render_offscreen ? 1.0f : -1.0f);
+ shader_addline(buffer, "const vec4 ycorrection = ");
+ shader_glsl_append_imm_vec4(buffer, ycorrection);
+ shader_addline(buffer, ";\n");
}
shader_addline(buffer, "vec4 vpos;\n");
}
shader_addline(buffer, "vec4 tmp0;\n");
shader_addline(buffer, "vec4 tmp1;\n");
- /* Local constants use a different name so they can be loaded once at shader link time
- * They can't be hardcoded into the shader text via LC = {x, y, z, w}; because the
- * float -> string conversion can cause precision loss.
- */
if (!shader->load_local_constsF)
{
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
{
- shader_addline(buffer, "uniform vec4 %s_lc%u;\n", prefix, lconst->idx);
+ shader_addline(buffer, "const vec4 %s_lc%u = ", prefix, lconst->idx);
+ shader_glsl_append_imm_vec4(buffer, (const float *)lconst->value);
+ shader_addline(buffer, ";\n");
}
}
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];
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);
switch (reg->data_type)
{
case WINED3D_DATA_FLOAT:
- sprintf(register_name, "%.8e", *(const float *)reg->immconst_data);
+ shader_glsl_ftoa(*(const float *)reg->immconst_data, register_name);
break;
case WINED3D_DATA_INT:
sprintf(register_name, "%#x", reg->immconst_data[0]);
switch (reg->data_type)
{
case WINED3D_DATA_FLOAT:
- sprintf(register_name, "vec4(%.8e, %.8e, %.8e, %.8e)",
- *(const float *)®->immconst_data[0], *(const float *)®->immconst_data[1],
- *(const float *)®->immconst_data[2], *(const float *)®->immconst_data[3]);
+ shader_glsl_ftoa(*(const float *)®->immconst_data[0], imm_str[0]);
+ shader_glsl_ftoa(*(const float *)®->immconst_data[1], imm_str[1]);
+ shader_glsl_ftoa(*(const float *)®->immconst_data[2], imm_str[2]);
+ shader_glsl_ftoa(*(const float *)®->immconst_data[3], imm_str[3]);
+ sprintf(register_name, "vec4(%s, %s, %s, %s)",
+ imm_str[0], imm_str[1], imm_str[2], imm_str[3]);
break;
case WINED3D_DATA_INT:
sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)",
BOOL shadow = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
&& (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << sampler_idx));
BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
- BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT;
+ BOOL texrect = flags & WINED3D_GLSL_SAMPLE_NPOT && gl_info->supported[ARB_TEXTURE_RECTANGLE];
BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD;
shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
- /* Fun: The D3DSI_COISSUE flag changes the semantic of the cnd instruction for < 1.4 shaders */
- if (ins->coissue)
- {
+ if (ins->coissue && ins->dst->write_mask != WINED3DSP_WRITEMASK_3)
shader_addline(ins->ctx->buffer, "%s /* COISSUE! */);\n", src1_param.param_str);
- } else {
+ else
shader_addline(ins->ctx->buffer, "%s > 0.5 ? %s : %s);\n",
src0_param.param_str, src1_param.param_str, src2_param.param_str);
- }
return;
}
********************************************/
static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
{
- const struct wined3d_shader *shader = ins->ctx->shader;
- struct wined3d_device *device = shader->device;
DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
ins->ctx->reg_maps->shader_version.minor);
struct glsl_sample_function sample_function;
- const struct wined3d_texture *texture;
DWORD sample_flags = 0;
DWORD sampler_idx;
DWORD mask = 0, swizzle;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
/* 1.0-1.4: Use destination register as sampler source.
* 2.0+: Use provided sampler source. */
sampler_idx = ins->dst[0].reg.idx[0].offset;
else
sampler_idx = ins->src[1].reg.idx[0].offset;
- texture = device->stateBlock->state.textures[sampler_idx];
if (shader_version < WINED3D_SHADER_VERSION(1,4))
{
- const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
DWORD flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
& WINED3D_PSARGS_TEXTRANSFORM_MASK;
enum wined3d_sampler_texture_type sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
mask = WINED3DSP_WRITEMASK_3;
}
- } else {
- if (ins->flags & WINED3DSI_TEXLD_PROJECT)
+ }
+ else
+ {
+ if ((ins->flags & WINED3DSI_TEXLD_PROJECT)
+ && ins->ctx->reg_maps->sampler_type[sampler_idx] != WINED3DSTT_CUBE)
{
/* ps 2.0 texldp instruction always divides by the fourth component. */
sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
}
}
- if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
- sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
+ if (priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+ sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
mask |= sample_function.coord_mask;
static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
{
- const struct wined3d_shader *shader = ins->ctx->shader;
- struct wined3d_device *device = shader->device;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
struct glsl_src_param coord_param, dx_param, dy_param;
DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD;
struct glsl_sample_function sample_function;
DWORD sampler_idx;
DWORD swizzle = ins->src[1].swizzle;
- const struct wined3d_texture *texture;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4])
{
}
sampler_idx = ins->src[1].reg.idx[0].offset;
- texture = device->stateBlock->state.textures[sampler_idx];
- if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
- sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
+ if (priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+ sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
{
- const struct wined3d_shader *shader = ins->ctx->shader;
- struct wined3d_device *device = shader->device;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
struct glsl_src_param coord_param, lod_param;
DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
struct glsl_sample_function sample_function;
DWORD sampler_idx;
DWORD swizzle = ins->src[1].swizzle;
- const struct wined3d_texture *texture;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
sampler_idx = ins->src[1].reg.idx[0].offset;
- texture = device->stateBlock->state.textures[sampler_idx];
- if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
- sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
+ if (ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
+ && priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+ sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
shader_addline(buffer, "gl_FragData[0] = clamp(gl_FragData[0], 0.0, 1.0);\n");
}
-static void shader_glsl_generate_fog_code(struct wined3d_shader_buffer *buffer, enum fogmode mode)
+static void shader_glsl_generate_fog_code(struct wined3d_shader_buffer *buffer, enum wined3d_ffp_ps_fog_mode mode)
{
switch (mode)
{
- case FOG_OFF:
+ case WINED3D_FFP_PS_FOG_OFF:
return;
- case FOG_LINEAR:
- /* Fog = (gl_Fog.end - gl_FogFragCoord) / (gl_Fog.end - gl_Fog.start) */
- shader_addline(buffer, "float Fog = (gl_Fog.end - gl_FogFragCoord) / (gl_Fog.end - gl_Fog.start);\n");
+ case WINED3D_FFP_PS_FOG_LINEAR:
+ shader_addline(buffer, "float Fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale;\n");
break;
- case FOG_EXP:
+ case WINED3D_FFP_PS_FOG_EXP:
/* Fog = e^-(gl_Fog.density * gl_FogFragCoord) */
shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_FogFragCoord);\n");
break;
- case FOG_EXP2:
+ case WINED3D_FFP_PS_FOG_EXP2:
/* Fog = e^-((gl_Fog.density * gl_FogFragCoord)^2) */
shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);\n");
break;
shader_addline(buffer, "gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, clamp(Fog, 0.0, 1.0));\n");
}
-/* Context activation is done by the caller. */
-static void hardcode_local_constants(const struct wined3d_shader *shader,
- const struct wined3d_gl_info *gl_info, GLhandleARB programId, const char *prefix)
-{
- const struct wined3d_shader_lconst *lconst;
- GLint tmp_loc;
- const float *value;
- char glsl_name[10];
-
- LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
- {
- value = (const float *)lconst->value;
- snprintf(glsl_name, sizeof(glsl_name), "%s_lc%u", prefix, lconst->idx);
- tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
- GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, value));
- }
- checkGLcall("Hardcoding local constants");
-}
-
/* Context activation is done by the caller. */
static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context,
struct wined3d_shader_buffer *buffer, const struct wined3d_shader *shader,
struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader,
const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
{
- struct wined3d_state *state = &shader->device->stateBlock->state;
struct glsl_ps_compiled_shader *gl_shaders, *new_array;
struct glsl_shader_private *shader_data;
struct ps_np2fixup_info *np2fixup;
memset(np2fixup, 0, sizeof(*np2fixup));
*np2fixup_info = args->np2_fixup ? np2fixup : NULL;
- pixelshader_update_samplers(&shader->reg_maps, state->textures);
+ pixelshader_update_samplers(shader, args->tex_types);
shader_buffer_clear(buffer);
ret = shader_glsl_generate_pshader(context, buffer, shader, args, np2fixup);
{
UINT i;
DWORD new_size;
- DWORD use_map = shader->device->strided_streams.use_map;
+ DWORD use_map = shader->device->stream_info.use_map;
struct glsl_vs_compiled_shader *gl_shaders, *new_array;
struct glsl_shader_private *shader_data;
GLhandleARB ret;
return ret;
}
+static const char *shader_glsl_ffp_mcs(enum wined3d_material_color_source mcs, const char *material)
+{
+ switch (mcs)
+ {
+ case WINED3D_MCS_MATERIAL:
+ return material;
+ case WINED3D_MCS_COLOR1:
+ return "gl_Color";
+ case WINED3D_MCS_COLOR2:
+ return "gl_SecondaryColor";
+ default:
+ ERR("Invalid material color source %#x.\n", mcs);
+ return "<invalid>";
+ }
+}
+
+static void shader_glsl_ffp_vertex_lighting(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
+{
+ const char *diffuse, *specular, *emission, *ambient;
+ enum wined3d_light_type light_type;
+ unsigned int i;
+
+ if (!settings->lighting)
+ {
+ shader_addline(buffer, "gl_FrontColor = gl_Color;\n");
+ shader_addline(buffer, "gl_FrontSecondaryColor = gl_SecondaryColor;\n");
+ return;
+ }
+
+ shader_addline(buffer, "vec3 ambient = gl_LightModel.ambient.xyz;\n");
+ shader_addline(buffer, "vec3 diffuse = vec3(0.0);\n");
+ shader_addline(buffer, "vec4 specular = vec4(0.0);\n");
+ shader_addline(buffer, "vec3 dir, dst;\n");
+ shader_addline(buffer, "float att, t;\n");
+
+ ambient = shader_glsl_ffp_mcs(settings->ambient_source, "gl_FrontMaterial.ambient");
+ diffuse = shader_glsl_ffp_mcs(settings->diffuse_source, "gl_FrontMaterial.diffuse");
+ specular = shader_glsl_ffp_mcs(settings->specular_source, "gl_FrontMaterial.specular");
+ emission = shader_glsl_ffp_mcs(settings->emission_source, "gl_FrontMaterial.emission");
+
+ for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
+ {
+ light_type = (settings->light_type >> WINED3D_FFP_LIGHT_TYPE_SHIFT(i)) & WINED3D_FFP_LIGHT_TYPE_MASK;
+ switch (light_type)
+ {
+ case WINED3D_LIGHT_POINT:
+ shader_addline(buffer, "dir = gl_LightSource[%u].position.xyz - ec_pos.xyz;\n", i);
+ shader_addline(buffer, "dst.z = dot(dir, dir);\n");
+ shader_addline(buffer, "dst.y = sqrt(dst.z);\n");
+ shader_addline(buffer, "dst.x = 1.0;\n");
+ shader_addline(buffer, "att = dot(dst.xyz, vec3(gl_LightSource[%u].constantAttenuation,"
+ " gl_LightSource[%u].linearAttenuation, gl_LightSource[%u].quadraticAttenuation));\n", i, i, i);
+ shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz / att;\n", i);
+ if (!settings->normal)
+ break;
+ shader_addline(buffer, "dir = normalize(dir);\n");
+ shader_addline(buffer, "diffuse += (max(0.0, dot(dir, normal))"
+ " * gl_LightSource[%u].diffuse.xyz) / att;\n", i);
+ if (settings->localviewer)
+ shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
+ else
+ shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, 1.0)));\n");
+ shader_addline(buffer, "if (t > 0.0) specular += (pow(t, gl_FrontMaterial.shininess)"
+ " * gl_LightSource[%u].specular) / att;\n", i);
+ break;
+
+ case WINED3D_LIGHT_SPOT:
+ shader_addline(buffer, "dir = gl_LightSource[%u].position.xyz - ec_pos.xyz;\n", i);
+ shader_addline(buffer, "dst.z = dot(dir, dir);\n");
+ shader_addline(buffer, "dst.y = sqrt(dst.z);\n");
+ shader_addline(buffer, "dst.x = 1.0;\n");
+ shader_addline(buffer, "dir = normalize(dir);\n");
+ shader_addline(buffer, "t = dot(-dir, normalize(gl_LightSource[%u].spotDirection));\n", i);
+ shader_addline(buffer, "if (t < gl_LightSource[%u].spotCosCutoff) att = 0.0;\n", i);
+ shader_addline(buffer, "else att = pow(t, gl_LightSource[%u].spotExponent)"
+ " / dot(dst.xyz, vec3(gl_LightSource[%u].constantAttenuation,"
+ " gl_LightSource[%u].linearAttenuation, gl_LightSource[%u].quadraticAttenuation));\n",
+ i, i, i, i);
+ 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))"
+ " * gl_LightSource[%u].diffuse.xyz) * att;\n", i);
+ if (settings->localviewer)
+ shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
+ else
+ shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, 1.0)));\n");
+ shader_addline(buffer, "if (t > 0.0) specular += (pow(t, gl_FrontMaterial.shininess)"
+ " * gl_LightSource[%u].specular) * att;\n", i);
+ break;
+
+ case WINED3D_LIGHT_DIRECTIONAL:
+ shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz;\n", i);
+ 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, "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);
+ break;
+
+ default:
+ if (light_type)
+ FIXME("Unhandled light type %#x.\n", light_type);
+ continue;
+ }
+ }
+
+ shader_addline(buffer, "gl_FrontColor.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n",
+ ambient, diffuse, emission);
+ shader_addline(buffer, "gl_FrontColor.w = %s.w;\n", diffuse);
+ shader_addline(buffer, "gl_FrontSecondaryColor = %s * specular;\n", specular);
+}
+
+/* Context activation is done by the caller. */
+static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
+{
+ GLhandleARB shader_obj;
+ unsigned int i;
+
+ shader_buffer_clear(buffer);
+
+ shader_addline(buffer, "#version 120\n");
+ shader_addline(buffer, "\n");
+ shader_addline(buffer, "void main()\n{\n");
+ shader_addline(buffer, "float m;\n");
+ shader_addline(buffer, "vec3 r;\n");
+
+ if (settings->transformed)
+ {
+ shader_addline(buffer, "vec4 ec_pos = vec4(gl_Vertex.xyz, 1.0);\n");
+ shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
+ shader_addline(buffer, "if (gl_Vertex.w != 0.0) gl_Position /= gl_Vertex.w;\n");
+ }
+ else
+ {
+ shader_addline(buffer, "vec4 ec_pos = gl_ModelViewMatrix * gl_Vertex;\n");
+ shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
+ if (settings->clipping)
+ shader_addline(buffer, "gl_ClipVertex = ec_pos;\n");
+ shader_addline(buffer, "ec_pos /= ec_pos.w;\n");
+ }
+
+ if (!settings->normal)
+ shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
+ else if (settings->normalize)
+ shader_addline(buffer, "vec3 normal = normalize(gl_NormalMatrix * gl_Normal);\n");
+ else
+ shader_addline(buffer, "vec3 normal = gl_NormalMatrix * gl_Normal;\n");
+
+ shader_glsl_ffp_vertex_lighting(buffer, settings, gl_info);
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ switch (settings->texgen[i] << WINED3D_FFP_TCI_SHIFT)
+ {
+ case WINED3DTSS_TCI_PASSTHRU:
+ if (settings->texcoords & (1 << i))
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * gl_MultiTexCoord%d;\n",
+ i, i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACENORMAL:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * vec4(normal, 1.0);\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACEPOSITION:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * ec_pos;\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u]"
+ " * vec4(reflect(normalize(ec_pos.xyz), normal), 1.0);\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_SPHEREMAP:
+ shader_addline(buffer, "r = reflect(normalize(ec_pos.xyz), normal);\n");
+ shader_addline(buffer, "m = 2.0 * length(vec3(r.x, r.y, r.z + 1.0));\n");
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u]"
+ " * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);\n", i, i);
+ break;
+
+ default:
+ ERR("Unhandled texgen %#x.\n", settings->texgen[i]);
+ break;
+ }
+ }
+
+ switch (settings->fog_mode)
+ {
+ case WINED3D_FFP_VS_FOG_OFF:
+ break;
+
+ case WINED3D_FFP_VS_FOG_FOGCOORD:
+ shader_addline(buffer, "gl_FogFragCoord = gl_SecondaryColor.w * 255.0;\n");
+ break;
+
+ case WINED3D_FFP_VS_FOG_RANGE:
+ shader_addline(buffer, "gl_FogFragCoord = length(ec_pos.xyz);\n");
+ break;
+
+ case WINED3D_FFP_VS_FOG_DEPTH:
+ if (settings->ortho_fog)
+ /* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */
+ shader_addline(buffer, "gl_FogFragCoord = gl_Position.z * 0.5 + 0.5;\n");
+ else
+ shader_addline(buffer, "gl_FogFragCoord = ec_pos.z;\n");
+ break;
+
+ default:
+ ERR("Unhandled fog mode %#x.\n", settings->fog_mode);
+ break;
+ }
+
+ if (settings->point_size)
+ {
+ shader_addline(buffer, "gl_PointSize = gl_Point.size / sqrt(gl_Point.distanceConstantAttenuation"
+ " + gl_Point.distanceLinearAttenuation * length(ec_pos.xyz)"
+ " + gl_Point.distanceQuadraticAttenuation * dot(ec_pos.xyz, ec_pos.xyz));\n");
+ shader_addline(buffer, "gl_PointSize = clamp(gl_PointSize, gl_Point.sizeMin, gl_Point.sizeMax);\n");
+ }
+
+ shader_addline(buffer, "}\n");
+
+ shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+ shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
+
+ return shader_obj;
+}
+
static const char *shader_glsl_get_ffp_fragment_op_arg(struct wined3d_shader_buffer *buffer,
DWORD argnum, unsigned int stage, DWORD arg)
{
shader_addline(buffer, "#version 120\n");
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
+
shader_addline(buffer, "vec4 tmp0, tmp1;\n");
shader_addline(buffer, "vec4 ret;\n");
if (tempreg_used || settings->sRGB_write)
if (settings->sRGB_write)
{
- shader_addline(buffer, "const vec4 srgb_const0 = vec4(%.8e, %.8e, %.8e, %.8e);\n",
- srgb_pow, srgb_mul_high, srgb_sub_high, srgb_mul_low);
- shader_addline(buffer, "const vec4 srgb_const1 = vec4(%.8e, 0.0, 0.0, 0.0);\n",
- srgb_cmp);
+ shader_addline(buffer, "const vec4 srgb_const0 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const0);
+ shader_addline(buffer, ";\n");
+ shader_addline(buffer, "const vec4 srgb_const1 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const1);
+ shader_addline(buffer, ";\n");
}
shader_addline(buffer, "void main()\n{\n");
if (lowest_disabled_stage < 7 && settings->emul_clipplanes)
- shader_addline(buffer, "if (any(lessThan(gl_texCoord[7], vec4(0.0)))) discard;\n");
+ shader_addline(buffer, "if (any(lessThan(gl_TexCoord[7], vec4(0.0)))) discard;\n");
/* Generate texture sampling instructions) */
for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage)
return shader_obj;
}
+static struct glsl_ffp_vertex_shader *shader_glsl_find_ffp_vertex_shader(struct shader_glsl_priv *priv,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_ffp_vs_settings *settings)
+{
+ struct glsl_ffp_vertex_shader *shader;
+ const struct wine_rb_entry *entry;
+
+ if ((entry = wine_rb_get(&priv->ffp_vertex_shaders, settings)))
+ return WINE_RB_ENTRY_VALUE(entry, struct glsl_ffp_vertex_shader, desc.entry);
+
+ if (!(shader = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader))))
+ return NULL;
+
+ shader->desc.settings = *settings;
+ shader->id = shader_glsl_generate_ffp_vertex_shader(&priv->shader_buffer, settings, gl_info);
+ list_init(&shader->linked_programs);
+ if (wine_rb_put(&priv->ffp_vertex_shaders, &shader->desc.settings, &shader->desc.entry) == -1)
+ ERR("Failed to insert ffp vertex shader.\n");
+
+ return shader;
+}
+
static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(struct shader_glsl_priv *priv,
const struct wined3d_gl_info *gl_info, const struct ffp_frag_settings *args)
{
}
/* Context activation is done by the caller. */
-static void set_glsl_shader_program(const struct wined3d_context *context, struct wined3d_device *device,
- enum wined3d_shader_mode vertex_mode, enum wined3d_shader_mode fragment_mode)
+static void set_glsl_shader_program(const struct wined3d_context *context, const struct wined3d_state *state,
+ struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data)
{
- const struct wined3d_state *state = &device->stateBlock->state;
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct ps_np2fixup_info *np2fixup_info = NULL;
- struct shader_glsl_priv *priv = device->shader_priv;
struct glsl_shader_prog_link *entry = NULL;
struct wined3d_shader *vshader = NULL;
struct wined3d_shader *gshader = NULL;
GLhandleARB programId = 0;
GLhandleARB reorder_shader_id = 0;
unsigned int i;
- struct ps_compile_args ps_compile_args;
- struct vs_compile_args vs_compile_args;
- GLhandleARB vs_id, gs_id, ps_id;
- struct list *ps_list;
+ GLhandleARB vs_id = 0;
+ GLhandleARB gs_id = 0;
+ GLhandleARB ps_id = 0;
+ struct list *ps_list, *vs_list;
+ struct wined3d_device *device = context->swapchain->device;
- if (vertex_mode == WINED3D_SHADER_MODE_SHADER)
+ if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_VERTEX)))
{
+ vs_id = ctx_data->glsl_program->vs.id;
+ vs_list = &ctx_data->glsl_program->vs.shader_entry;
+
+ if (use_vs(state))
+ {
+ vshader = state->vertex_shader;
+ gshader = state->geometry_shader;
+
+ if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_GEOMETRY))
+ && ctx_data->glsl_program->gs.id)
+ gs_id = ctx_data->glsl_program->gs.id;
+ else if (gshader)
+ gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, gshader);
+ }
+ }
+ else if (use_vs(state))
+ {
+ struct vs_compile_args vs_compile_args;
vshader = state->vertex_shader;
+
find_vs_compile_args(state, vshader, &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))
gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, gshader);
- else
- gs_id = 0;
}
- else
+ else if (priv->vertex_pipe == &glsl_vertex_pipe)
{
- vs_id = 0;
- gs_id = 0;
+ struct glsl_ffp_vertex_shader *ffp_shader;
+ struct wined3d_ffp_vs_settings settings;
+
+ wined3d_ffp_get_vs_settings(state, &device->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;
}
- if (fragment_mode == WINED3D_SHADER_MODE_SHADER)
+ if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_PIXEL)))
+ {
+ ps_id = ctx_data->glsl_program->ps.id;
+ ps_list = &ctx_data->glsl_program->ps.shader_entry;
+
+ if (use_ps(state))
+ pshader = state->pixel_shader;
+ }
+ 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);
ps_id = find_glsl_pshader(context, &priv->shader_buffer,
pshader, &ps_compile_args, &np2fixup_info);
ps_list = &pshader->linked_programs;
}
- else if (fragment_mode == WINED3D_SHADER_MODE_FFP && priv->fragment_pipe == &glsl_fragment_pipe)
+ else if (priv->fragment_pipe == &glsl_fragment_pipe)
{
struct glsl_ffp_fragment_shader *ffp_shader;
struct ffp_frag_settings settings;
- gen_ffp_frag_op(device, state, &settings, FALSE);
+ gen_ffp_frag_op(context, state, &settings, FALSE);
ffp_shader = shader_glsl_find_ffp_fragment_shader(priv, gl_info, &settings);
ps_id = ffp_shader->id;
ps_list = &ffp_shader->linked_programs;
}
- else
- {
- ps_id = 0;
- }
if ((!vs_id && !gs_id && !ps_id) || (entry = get_glsl_program_entry(priv, vs_id, gs_id, ps_id)))
{
- priv->glsl_program = entry;
+ ctx_data->glsl_program = entry;
return;
}
add_glsl_program_entry(priv, entry);
/* Set the current program */
- priv->glsl_program = entry;
+ ctx_data->glsl_program = entry;
/* Attach GLSL vshader */
+ if (vs_id)
+ {
+ TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, programId);
+ GL_EXTCALL(glAttachObjectARB(programId, vs_id));
+ checkGLcall("glAttachObjectARB");
+
+ list_add_head(vs_list, &entry->vs.shader_entry);
+ }
+
if (vshader)
{
WORD map = vshader->reg_maps.input_registers;
*/
GL_EXTCALL(glDeleteObjectARB(reorder_shader_id));
- TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, programId);
- GL_EXTCALL(glAttachObjectARB(programId, vs_id));
- checkGLcall("glAttachObjectARB");
-
/* Bind vertex attributes to a corresponding index number to match
* the same index numbers as ARB_vertex_programs (makes loading
* vertex attributes simpler). With this method, we can use the
GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
}
checkGLcall("glBindAttribLocationARB");
-
- list_add_head(&vshader->linked_programs, &entry->vs.shader_entry);
}
if (gshader)
shader_glsl_load_vsamplers(gl_info, device->texUnitMap, programId);
shader_glsl_load_psamplers(gl_info, device->texUnitMap, programId);
- /* If the local constants do not have to be loaded with the environment constants,
- * load them now to have them hardcoded in the GLSL program. This saves some CPU cycles
- * later
- */
- if (pshader && !pshader->load_local_constsF)
- hardcode_local_constants(pshader, gl_info, programId, "ps");
- if (vshader && !vshader->load_local_constsF)
- hardcode_local_constants(vshader, gl_info, programId, "vs");
+ entry->constant_update_mask = 0;
+ if (vshader)
+ {
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_F;
+ if (vshader->reg_maps.integer_constants)
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_I;
+ if (vshader->reg_maps.boolean_constants)
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B;
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP;
+ }
+
+ if (ps_id)
+ {
+ if (pshader)
+ {
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
+ if (pshader->reg_maps.integer_constants)
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_I;
+ if (pshader->reg_maps.boolean_constants)
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_B;
+ if (entry->ps.ycorrection_location != -1)
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR;
+ }
+ else
+ {
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PS;
+ }
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ if (entry->ps.bumpenv_mat_location[i] != -1)
+ {
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV;
+ break;
+ }
+ }
+
+ if (entry->ps.np2_fixup_location != -1)
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP;
+ }
}
/* Context activation is done by the caller. */
}
/* Context activation is done by the caller. */
-static void shader_glsl_select(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
- enum wined3d_shader_mode fragment_mode)
+static void shader_glsl_select(void *shader_priv, struct wined3d_context *context,
+ const struct wined3d_state *state)
{
+ struct glsl_context_data *ctx_data = context->shader_backend_data;
const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_device *device = context->swapchain->device;
- struct shader_glsl_priv *priv = device->shader_priv;
- GLhandleARB program_id = 0;
+ struct shader_glsl_priv *priv = shader_priv;
+ GLhandleARB program_id = 0, prev_id = 0;
GLenum old_vertex_color_clamp, current_vertex_color_clamp;
- old_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vs.vertex_color_clamp : GL_FIXED_ONLY_ARB;
- set_glsl_shader_program(context, device, vertex_mode, fragment_mode);
- current_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vs.vertex_color_clamp : GL_FIXED_ONLY_ARB;
+ priv->vertex_pipe->vp_enable(gl_info, !use_vs(state));
+ priv->fragment_pipe->enable_extension(gl_info, !use_ps(state));
+
+ if (ctx_data->glsl_program)
+ {
+ prev_id = ctx_data->glsl_program->programId;
+ old_vertex_color_clamp = ctx_data->glsl_program->vs.vertex_color_clamp;
+ }
+ else
+ {
+ prev_id = 0;
+ old_vertex_color_clamp = GL_FIXED_ONLY_ARB;
+ }
+
+ set_glsl_shader_program(context, state, priv, ctx_data);
+
+ if (ctx_data->glsl_program)
+ {
+ program_id = ctx_data->glsl_program->programId;
+ current_vertex_color_clamp = ctx_data->glsl_program->vs.vertex_color_clamp;
+ }
+ else
+ {
+ program_id = 0;
+ current_vertex_color_clamp = GL_FIXED_ONLY_ARB;
+ }
+
if (old_vertex_color_clamp != current_vertex_color_clamp)
{
if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT])
}
}
- program_id = priv->glsl_program ? priv->glsl_program->programId : 0;
- if (program_id) TRACE("Using GLSL program %u\n", program_id);
- GL_EXTCALL(glUseProgramObjectARB(program_id));
+ TRACE("Using GLSL program %u.\n", program_id);
+
+ if (prev_id != program_id)
+ {
+ GL_EXTCALL(glUseProgramObjectARB(program_id));
+ checkGLcall("glUseProgramObjectARB");
+
+ if (program_id)
+ context->constant_update_mask |= ctx_data->glsl_program->constant_update_mask;
+ }
+}
+
+/* "context" is not necessarily the currently active context. */
+static void shader_glsl_invalidate_current_program(struct wined3d_context *context)
+{
+ struct glsl_context_data *ctx_data = context->shader_backend_data;
+
+ ctx_data->glsl_program = NULL;
+ context->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
+ | (1 << WINED3D_SHADER_TYPE_VERTEX)
+ | (1 << WINED3D_SHADER_TYPE_GEOMETRY);
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_disable(void *shader_priv, struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct shader_glsl_priv *priv = shader_priv;
+
+ shader_glsl_invalidate_current_program(context);
+ GL_EXTCALL(glUseProgramObjectARB(0));
checkGLcall("glUseProgramObjectARB");
- /* In case that NP2 texcoord fixup data is found for the selected program, trigger a reload of the
- * constants. This has to be done because it can't be guaranteed that sampler() (from state.c) is
- * called between selecting the shader and using it, which results in wrong fixup for some frames. */
- if (priv->glsl_program && priv->glsl_program->ps.np2_fixup_info)
+ priv->vertex_pipe->vp_enable(gl_info, FALSE);
+ priv->fragment_pipe->enable_extension(gl_info, FALSE);
+
+ if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT])
{
- shader_glsl_load_np2fixup_constants(priv, gl_info, &device->stateBlock->state);
+ GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FIXED_ONLY_ARB));
+ checkGLcall("glClampColorARB");
}
}
/* Context activation is done by the caller. */
static void shader_glsl_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info)
{
- struct shader_glsl_priv *priv = shader_priv;
+ const struct glsl_context_data *ctx_data = context_get_current()->shader_backend_data;
GLhandleARB program_id;
- program_id = priv->glsl_program ? priv->glsl_program->programId : 0;
+ program_id = ctx_data->glsl_program ? ctx_data->glsl_program->programId : 0;
if (program_id) TRACE("Using GLSL program %u\n", program_id);
GL_EXTCALL(glUseProgramObjectARB(program_id));
checkGLcall("glUseProgramObjectARB");
}
+static void shader_glsl_invalidate_contexts_program(struct wined3d_device *device,
+ const struct glsl_shader_prog_link *program)
+{
+ const struct glsl_context_data *ctx_data;
+ struct wined3d_context *context;
+ unsigned int i;
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ context = device->contexts[i];
+ ctx_data = context->shader_backend_data;
+
+ if (ctx_data->glsl_program == program)
+ shader_glsl_invalidate_current_program(context);
+ }
+}
+
static void shader_glsl_destroy(struct wined3d_shader *shader)
{
struct glsl_shader_private *shader_data = shader->backend_data;
{
struct glsl_ps_compiled_shader *gl_shaders = shader_data->gl_shaders.ps;
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
- struct glsl_shader_prog_link, ps.shader_entry)
- {
- delete_glsl_program_entry(priv, gl_info, entry);
- }
-
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting pixel shader %u.\n", gl_shaders[i].prgId);
- if (priv->glsl_program && priv->glsl_program->ps.id == gl_shaders[i].prgId)
- shader_glsl_select(context, WINED3D_SHADER_MODE_NONE, WINED3D_SHADER_MODE_NONE);
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ps);
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
+ struct glsl_shader_prog_link, ps.shader_entry)
+ {
+ shader_glsl_invalidate_contexts_program(device, entry);
+ delete_glsl_program_entry(priv, gl_info, entry);
+ }
+
break;
}
{
struct glsl_vs_compiled_shader *gl_shaders = shader_data->gl_shaders.vs;
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
- struct glsl_shader_prog_link, vs.shader_entry)
- {
- delete_glsl_program_entry(priv, gl_info, entry);
- }
-
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting vertex shader %u.\n", gl_shaders[i].prgId);
- if (priv->glsl_program && priv->glsl_program->vs.id == gl_shaders[i].prgId)
- shader_glsl_select(context, WINED3D_SHADER_MODE_NONE, WINED3D_SHADER_MODE_NONE);
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.vs);
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
+ struct glsl_shader_prog_link, vs.shader_entry)
+ {
+ shader_glsl_invalidate_contexts_program(device, entry);
+ delete_glsl_program_entry(priv, gl_info, entry);
+ }
+
break;
}
{
struct glsl_gs_compiled_shader *gl_shaders = shader_data->gl_shaders.gs;
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
- struct glsl_shader_prog_link, gs.shader_entry)
- {
- delete_glsl_program_entry(priv, gl_info, entry);
- }
-
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting geometry shader %u.\n", gl_shaders[i].id);
- if (priv->glsl_program && priv->glsl_program->gs.id == gl_shaders[i].id)
- shader_glsl_select(context, WINED3D_SHADER_MODE_NONE, WINED3D_SHADER_MODE_NONE);
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].id));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.gs);
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
+ struct glsl_shader_prog_link, gs.shader_entry)
+ {
+ shader_glsl_invalidate_contexts_program(device, entry);
+ delete_glsl_program_entry(priv, gl_info, entry);
+ }
+
break;
}
static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant_count)
{
- SIZE_T size = (constant_count + 1) * sizeof(*heap->entries) + constant_count * sizeof(*heap->positions);
+ SIZE_T size = (constant_count + 1) * sizeof(*heap->entries)
+ + constant_count * sizeof(*heap->contained)
+ + constant_count * sizeof(*heap->positions);
void *mem = HeapAlloc(GetProcessHeap(), 0, size);
if (!mem)
heap->entries = mem;
heap->entries[1].version = 0;
- heap->positions = (unsigned int *)(heap->entries + constant_count + 1);
+ heap->contained = (BOOL *)(heap->entries + constant_count + 1);
+ memset(heap->contained, 0, constant_count * sizeof(*heap->contained));
+ heap->positions = (unsigned int *)(heap->contained + constant_count);
heap->size = 1;
return TRUE;
glsl_program_key_compare,
};
-static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe)
+static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+ const struct fragment_pipeline *fragment_pipe)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
SIZE_T stack_size = wined3d_log2i(max(gl_info->limits.glsl_vs_float_constants,
gl_info->limits.glsl_ps_float_constants)) + 1;
struct fragment_caps fragment_caps;
- void *fragment_priv;
+ void *vertex_priv, *fragment_priv;
+
+ if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
+ {
+ ERR("Failed to initialize vertex pipe.\n");
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
if (!(fragment_priv = fragment_pipe->alloc_private(&glsl_shader_backend, priv)))
{
ERR("Failed to initialize fragment pipe.\n");
+ vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv);
return E_FAIL;
}
}
priv->next_constant_version = 1;
+ priv->vertex_pipe = vertex_pipe;
+ priv->fragment_pipe = fragment_pipe;
fragment_pipe->get_caps(gl_info, &fragment_caps);
priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
- device->fragment_priv = fragment_priv;
- priv->fragment_pipe = fragment_pipe;
+ device->vertex_priv = vertex_priv;
+ device->fragment_priv = fragment_priv;
device->shader_priv = priv;
+
return WINED3D_OK;
fail:
HeapFree(GetProcessHeap(), 0, priv->stack);
shader_buffer_free(&priv->shader_buffer);
fragment_pipe->free_private(device);
+ vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv);
return E_OUTOFMEMORY;
}
HeapFree(GetProcessHeap(), 0, priv->stack);
shader_buffer_free(&priv->shader_buffer);
priv->fragment_pipe->free_private(device);
+ priv->vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, device->shader_priv);
device->shader_priv = NULL;
}
-static void shader_glsl_context_destroyed(void *shader_priv, const struct wined3d_context *context) {}
+static BOOL shader_glsl_allocate_context_data(struct wined3d_context *context)
+{
+ return !!(context->shader_backend_data = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY, sizeof(struct glsl_context_data)));
+}
+
+static void shader_glsl_free_context_data(struct wined3d_context *context)
+{
+ HeapFree(GetProcessHeap(), 0, context->shader_backend_data);
+}
static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
{
{
shader_glsl_handle_instruction,
shader_glsl_select,
+ shader_glsl_disable,
shader_glsl_select_depth_blt,
shader_glsl_deselect_depth_blt,
shader_glsl_update_float_vertex_constants,
shader_glsl_update_float_pixel_constants,
shader_glsl_load_constants,
- shader_glsl_load_np2fixup_constants,
shader_glsl_destroy,
shader_glsl_alloc,
shader_glsl_free,
- shader_glsl_context_destroyed,
+ shader_glsl_allocate_context_data,
+ shader_glsl_free_context_data,
shader_glsl_get_caps,
shader_glsl_color_fixup_supported,
shader_glsl_has_ffp_proj_control,
};
+static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
+{
+ if (enable)
+ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
+ else
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
+ checkGLcall("GL_VERTEX_PROGRAM_POINT_SIZE_ARB");
+}
+
+static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
+{
+ caps->xyzrhw = TRUE;
+ caps->max_active_lights = gl_info->limits.lights;
+ caps->max_vertex_blend_matrices = 0;
+ caps->max_vertex_blend_matrix_index = 0;
+ caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN
+ | WINED3DVTXPCAPS_MATERIALSOURCE7
+ | WINED3DVTXPCAPS_VERTEXFOG
+ | WINED3DVTXPCAPS_DIRECTIONALLIGHTS
+ | WINED3DVTXPCAPS_POSITIONALLIGHTS
+ | WINED3DVTXPCAPS_LOCALVIEWER
+ | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP;
+ caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 8; /* 8 texture coordinates. */
+ caps->max_user_clip_planes = gl_info->limits.clipplanes;
+ caps->raster_caps = WINED3DPRASTERCAPS_FOGRANGE;
+}
+
+static void *glsl_vertex_pipe_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ struct shader_glsl_priv *priv;
+
+ if (shader_backend == &glsl_shader_backend)
+ {
+ priv = shader_priv;
+
+ if (wine_rb_init(&priv->ffp_vertex_shaders, &wined3d_ffp_vertex_program_rb_functions) == -1)
+ {
+ ERR("Failed to initialize rbtree.\n");
+ return NULL;
+ }
+
+ return priv;
+ }
+
+ FIXME("GLSL vertex pipe without GLSL shader backend not implemented.\n");
+
+ return NULL;
+}
+
+static void shader_glsl_free_ffp_vertex_shader(struct wine_rb_entry *entry, void *context)
+{
+ struct glsl_ffp_vertex_shader *shader = WINE_RB_ENTRY_VALUE(entry,
+ struct glsl_ffp_vertex_shader, desc.entry);
+ struct glsl_shader_prog_link *program, *program2;
+ struct glsl_ffp_destroy_ctx *ctx = context;
+
+ LIST_FOR_EACH_ENTRY_SAFE(program, program2, &shader->linked_programs,
+ struct glsl_shader_prog_link, vs.shader_entry)
+ {
+ delete_glsl_program_entry(ctx->priv, ctx->gl_info, program);
+ }
+ ctx->gl_info->gl_ops.ext.p_glDeleteObjectARB(shader->id);
+ HeapFree(GetProcessHeap(), 0, shader);
+}
+
+/* Context activation is done by the caller. */
+static void glsl_vertex_pipe_vp_free(struct wined3d_device *device)
+{
+ struct shader_glsl_priv *priv = device->vertex_priv;
+ struct glsl_ffp_destroy_ctx ctx;
+
+ ctx.priv = priv;
+ ctx.gl_info = &device->adapter->gl_info;
+ wine_rb_destroy(&priv->ffp_vertex_shaders, shader_glsl_free_ffp_vertex_shader, &ctx);
+}
+
+static void glsl_vertex_pipe_shader(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+}
+
+static void glsl_vertex_pipe_projection(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ /* Table fog behavior depends on the projection matrix. */
+ if (state->render_states[WINED3D_RS_FOGENABLE]
+ && state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+ transform_projection(context, state, state_id);
+}
+
+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_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 */
+ {STATE_CLIPPLANE(0), {STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(1), {STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(2), {STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(3), {STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(4), {STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(5), {STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(6), {STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(7), {STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(8), {STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(9), {STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(10), {STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(11), {STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(12), {STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(13), {STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(14), {STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(15), {STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(16), {STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(17), {STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(18), {STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(19), {STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(20), {STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(21), {STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(22), {STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(23), {STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(24), {STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(25), {STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(26), {STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(27), {STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(28), {STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(29), {STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(30), {STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(31), {STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
+ /* Lights */
+ {STATE_LIGHT_TYPE, {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(0), {STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(1), {STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(2), {STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(3), {STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(4), {STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(5), {STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(6), {STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(7), {STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
+ /* Viewport */
+ {STATE_VIEWPORT, {STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
+ /* Transform states */
+ {STATE_TRANSFORM(WINED3D_TS_VIEW), {STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_PROJECTION), {STATE_TRANSFORM(WINED3D_TS_PROJECTION), glsl_vertex_pipe_projection}, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE0), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE1), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE2), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE3), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE4), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE5), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE6), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE7), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)), transform_world }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ /* Fog */
+ {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_vertex_pipe_shader}, 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_RANGEFOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_CLIPPING), {STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), {STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_LIGHTING), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_AMBIENT), {STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_COLORVERTEX), {STATE_RENDER(WINED3D_RS_COLORVERTEX), glsl_vertex_pipe_shader}, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_LOCALVIEWER), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
+ {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_C), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_TWEENFACTOR), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ /* Samplers for NP2 texture matrix adjustions. They are not needed if
+ * GL_ARB_texture_non_power_of_two is supported, so register a NULL state
+ * handler in that case to get the vertex part of sampler() skipped (VTF
+ * is handled in the misc states). Otherwise, register
+ * sampler_texmatrix(), which takes care of updating the texture matrix. */
+ {STATE_SAMPLER(0), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(0), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(0), {STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(1), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(1), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(1), {STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(2), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(2), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(2), {STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(3), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(3), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(3), {STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(4), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(4), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(4), {STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(5), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(5), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(5), {STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(6), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(6), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(6), {STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(7), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(7), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(7), {STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_POINT_SIZE_ENABLE, {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE },
+};
+
+/* TODO:
+ * - This currently depends on GL fixed function functions to set things
+ * like light parameters. Ideally we'd use regular uniforms for that.
+ * - In part because of the previous point, much of this is modelled after
+ * GL fixed function, and has much of the same limitations. For example,
+ * D3D spot lights are slightly different from GL spot lights.
+ * - We can now implement drawing transformed vertices using the GLSL pipe,
+ * instead of using the immediate mode fallback.
+ * - Similarly, we don't need the fallback for certain combinations of
+ * material sources anymore.
+ * - Implement vertex blending and vertex tweening.
+ * - Handle WINED3D_TSS_TEXCOORD_INDEX in the shader, instead of duplicating
+ * attribute arrays in load_tex_coords().
+ * - Per-vertex point sizes. */
+const struct wined3d_vertex_pipe_ops glsl_vertex_pipe =
+{
+ glsl_vertex_pipe_vp_enable,
+ glsl_vertex_pipe_vp_get_caps,
+ glsl_vertex_pipe_vp_alloc,
+ glsl_vertex_pipe_vp_free,
+ glsl_vertex_pipe_vp_states,
+};
+
static void glsl_fragment_pipe_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
{
/* Nothing to do. */
return NULL;
}
-struct glsl_ffp_destroy_ctx
-{
- struct shader_glsl_priv *priv;
- const struct wined3d_gl_info *gl_info;
-};
-
static void shader_glsl_free_ffp_fragment_shader(struct wine_rb_entry *entry, void *context)
{
struct glsl_ffp_fragment_shader *shader = WINE_RB_ENTRY_VALUE(entry,
{
context->last_was_pshader = use_ps(state);
- context->select_shader = 1;
- context->load_constants = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
static void glsl_fragment_pipe_fog(struct wined3d_context *context,
{
BOOL use_vshader = use_vs(state);
enum fogsource new_source;
+ DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
+ DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
- context->select_shader = 1;
- context->load_constants = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
if (!state->render_states[WINED3D_RS_FOGENABLE])
return;
new_source = FOGSOURCE_FFP;
}
- if (new_source != context->fog_source)
+ if (new_source != context->fog_source || fogstart == fogend)
{
context->fog_source = new_source;
state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
static void glsl_fragment_pipe_tex_transform(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
- context->select_shader = 1;
- context->load_constants = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
- context->load_constants = 1;
+ context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PS;
}
static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] =
{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_BUMPENV_MAT00), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, 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), glsl_fragment_pipe_invalidate_constants}, 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_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_BUMPENV_MAT00), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, 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), glsl_fragment_pipe_invalidate_constants}, 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_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_BUMPENV_MAT00), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, 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), glsl_fragment_pipe_invalidate_constants}, 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_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_BUMPENV_MAT00), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, 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), glsl_fragment_pipe_invalidate_constants}, 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_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_BUMPENV_MAT00), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, 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), glsl_fragment_pipe_invalidate_constants}, 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_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_BUMPENV_MAT00), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, 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), glsl_fragment_pipe_invalidate_constants}, 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_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_BUMPENV_MAT00), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, 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), glsl_fragment_pipe_invalidate_constants}, 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_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_BUMPENV_MAT00), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, 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), glsl_fragment_pipe_invalidate_constants}, 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, 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 },
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
* Copyright 2009-2010 Henri Verbeet for CodeWeavers
+ * Copyright 2006-2008, 2013 Stefan Dösinger for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
case WINED3D_POOL_MANAGED:
return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU;
+ case WINED3D_POOL_SCRATCH:
case WINED3D_POOL_SYSTEM_MEM:
return WINED3D_RESOURCE_ACCESS_CPU;
- case WINED3D_POOL_SCRATCH:
- return WINED3D_RESOURCE_ACCESS_SCRATCH;
-
default:
FIXME("Unhandled pool %#x.\n", pool);
return 0;
void *parent, const struct wined3d_parent_ops *parent_ops,
const struct wined3d_resource_ops *resource_ops)
{
+ const struct wined3d *d3d = device->wined3d;
+
resource->ref = 1;
resource->device = device;
resource->type = type;
if (size)
{
- resource->heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + RESOURCE_ALIGNMENT);
- if (!resource->heapMemory)
+ resource->heap_memory = wined3d_resource_allocate_sysmem(size);
+ if (!resource->heap_memory)
{
ERR("Out of memory!\n");
return WINED3DERR_OUTOFVIDEOMEMORY;
}
else
{
- resource->heapMemory = NULL;
+ resource->heap_memory = NULL;
}
- resource->allocatedMemory = (BYTE *)(((ULONG_PTR)resource->heapMemory
- + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ resource->allocatedMemory = resource->heap_memory;
/* Check that we have enough video ram left */
- if (pool == WINED3D_POOL_DEFAULT)
+ if (pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
{
if (size > wined3d_device_get_available_texture_mem(device))
{
ERR("Out of adapter memory\n");
- HeapFree(GetProcessHeap(), 0, resource->heapMemory);
+ wined3d_resource_free_sysmem(resource->heap_memory);
return WINED3DERR_OUTOFVIDEOMEMORY;
}
adapter_adjust_memory(device->adapter, size);
void resource_cleanup(struct wined3d_resource *resource)
{
+ const struct wined3d *d3d = resource->device->wined3d;
struct private_data *data;
struct list *e1, *e2;
HRESULT hr;
TRACE("Cleaning up resource %p.\n", resource);
- if (resource->pool == WINED3D_POOL_DEFAULT)
+ if (resource->pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
{
TRACE("Decrementing device memory pool by %u.\n", resource->size);
adapter_adjust_memory(resource->device->adapter, 0 - resource->size);
ERR("Failed to free private data when destroying resource %p, hr = %#x.\n", resource, hr);
}
- HeapFree(GetProcessHeap(), 0, resource->heapMemory);
- resource->allocatedMemory = 0;
- resource->heapMemory = 0;
+ wined3d_resource_free_sysmem(resource->heap_memory);
+ resource->allocatedMemory = NULL;
+ resource->heap_memory = NULL;
- if (resource->device)
- device_resource_released(resource->device, resource);
+ device_resource_released(resource->device, resource);
}
void resource_unload(struct wined3d_resource *resource)
desc->depth = resource->depth;
desc->size = resource->size;
}
+
+void *wined3d_resource_allocate_sysmem(SIZE_T size)
+{
+ void **p;
+ SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p);
+ void *mem;
+
+ if (!(mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + align)))
+ return NULL;
+
+ p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1;
+ *p = mem;
+
+ return ++p;
+}
+
+void wined3d_resource_free_sysmem(void *mem)
+{
+ void **p = mem;
+
+ if (!mem)
+ return;
+
+ HeapFree(GetProcessHeap(), 0, *(--p));
+}
+
+DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags)
+{
+ /* Not all flags make sense together, but Windows never returns an error.
+ * Catch the cases that could cause issues. */
+ if (flags & WINED3D_MAP_READONLY)
+ {
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
+ return 0;
+ }
+ if (flags & WINED3D_MAP_NOOVERWRITE)
+ {
+ WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
+ return 0;
+ }
+ }
+ else if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+ == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+ {
+ WARN("WINED3D_MAP_DISCARD and WINED3D_MAP_NOOVERWRITE used together, ignoring.\n");
+ return 0;
+ }
+ else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)
+ && !(resource->usage & WINED3DUSAGE_DYNAMIC))
+ {
+ WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
+ return 0;
+ }
+
+ return flags;
+}
+
+GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
+{
+ GLbitfield ret = 0;
+
+ if (!(d3d_flags & WINED3D_MAP_READONLY))
+ ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
+ if (!(d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
+ ret |= GL_MAP_READ_BIT;
+
+ if (d3d_flags & WINED3D_MAP_DISCARD)
+ ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
+ if (d3d_flags & WINED3D_MAP_NOOVERWRITE)
+ ret |= GL_MAP_UNSYNCHRONIZED_BIT;
+
+ return ret;
+}
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
* Copyright 2006 Ivan Gyurdiev
- * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2007-2008, 2013 Stefan Dösinger for CodeWeavers
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
void shader_buffer_clear(struct wined3d_shader_buffer *buffer)
{
buffer->buffer[0] = '\0';
- buffer->bsize = 0;
+ buffer->content_size = 0;
buffer->lineNo = 0;
buffer->newline = TRUE;
}
BOOL shader_buffer_init(struct wined3d_shader_buffer *buffer)
{
- buffer->buffer = HeapAlloc(GetProcessHeap(), 0, SHADER_PGMSIZE);
- if (!buffer->buffer)
+ buffer->buffer_size = 16384;
+ if (!(buffer->buffer = HeapAlloc(GetProcessHeap(), 0, buffer->buffer_size)))
{
ERR("Failed to allocate shader buffer memory.\n");
return FALSE;
int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *format, va_list args)
{
- char *base = buffer->buffer + buffer->bsize;
+ char *base = buffer->buffer + buffer->content_size;
int rc;
+ char *new_buffer;
- rc = vsnprintf(base, SHADER_PGMSIZE - 1 - buffer->bsize, format, args);
-
- if (rc < 0 /* C89 */ || (unsigned int)rc > SHADER_PGMSIZE - 1 - buffer->bsize /* C99 */)
+ while(1)
{
- ERR("The buffer allocated for the shader program string "
- "is too small at %d bytes.\n", SHADER_PGMSIZE);
- buffer->bsize = SHADER_PGMSIZE - 1;
- return -1;
+ rc = vsnprintf(base, buffer->buffer_size - buffer->content_size, format, args);
+ if (rc < 0 /* C89 */ || (unsigned int)rc >= buffer->buffer_size - buffer->content_size /* C99 */)
+ {
+ new_buffer = HeapReAlloc(GetProcessHeap(), 0, buffer->buffer, buffer->buffer_size * 2);
+ if (!new_buffer)
+ {
+ ERR("The buffer allocated for the shader program string is too small at %d bytes.\n", buffer->buffer_size);
+ buffer->content_size = buffer->buffer_size - 1;
+ return -1;
+ }
+ buffer->buffer = new_buffer;
+ buffer->buffer_size = buffer->buffer_size * 2;
+ base = buffer->buffer + buffer->content_size;
+ }
+ else
+ {
+ break;
+ }
}
if (buffer->newline)
{
- TRACE("GL HW (%u, %u) : %s", buffer->lineNo + 1, buffer->bsize, base);
+ TRACE("GL HW (%u, %u) : %s", buffer->lineNo + 1, buffer->content_size, base);
buffer->newline = FALSE;
}
else
TRACE("%s", base);
}
- buffer->bsize += rc;
- if (buffer->buffer[buffer->bsize-1] == '\n')
+ buffer->content_size += rc;
+ if (buffer->buffer[buffer->content_size-1] == '\n')
{
++buffer->lineNo;
buffer->newline = TRUE;
else if (ins.handler_idx == WINED3DSIH_DEF)
{
struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
+ float *value;
if (!lconst) return E_OUTOFMEMORY;
lconst->idx = ins.dst[0].reg.idx[0].offset;
memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
+ value = (float *)lconst->value;
/* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
if (shader_version.major == 1 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
{
- float *value = (float *)lconst->value;
if (value[0] < -1.0f) value[0] = -1.0f;
else if (value[0] > 1.0f) value[0] = 1.0f;
if (value[1] < -1.0f) value[1] = -1.0f;
}
list_add_head(&shader->constantsF, &lconst->entry);
+
+ if (isinf(value[0]) || isnan(value[0]) || isinf(value[1]) || isnan(value[1])
+ || isinf(value[2]) || isnan(value[2]) || isinf(value[3]) || isnan(value[3]))
+ {
+ shader->lconst_inf_or_nan = TRUE;
+ }
}
else if (ins.handler_idx == WINED3DSIH_DEFI)
{
struct shader_none_priv
{
+ const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
BOOL ffp_proj_control;
};
static void shader_none_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info) {}
static void shader_none_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count) {}
static void shader_none_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count) {}
-static void shader_none_load_constants(const struct wined3d_context *context, BOOL usePS, BOOL useVS) {}
-static void shader_none_load_np2fixup_constants(void *shader_priv,
- const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) {}
+static void shader_none_load_constants(void *shader_priv, struct wined3d_context *context,
+ const struct wined3d_state *state) {}
static void shader_none_destroy(struct wined3d_shader *shader) {}
-static void shader_none_context_destroyed(void *shader_priv, const struct wined3d_context *context) {}
+static void shader_none_free_context_data(struct wined3d_context *context) {}
-static void shader_none_select(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
- enum wined3d_shader_mode fragment_mode)
+/* Context activation is done by the caller. */
+static void shader_none_select(void *shader_priv, struct wined3d_context *context,
+ const struct wined3d_state *state)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_device *device = context->swapchain->device;
- struct shader_none_priv *priv = device->shader_priv;
+ struct shader_none_priv *priv = shader_priv;
- priv->fragment_pipe->enable_extension(gl_info, fragment_mode == WINED3D_SHADER_MODE_FFP);
+ priv->vertex_pipe->vp_enable(gl_info, !use_vs(state));
+ priv->fragment_pipe->enable_extension(gl_info, !use_ps(state));
}
-static HRESULT shader_none_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe)
+/* Context activation is done by the caller. */
+static void shader_none_disable(void *shader_priv, struct wined3d_context *context)
+{
+ struct shader_none_priv *priv = shader_priv;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ priv->vertex_pipe->vp_enable(gl_info, FALSE);
+ priv->fragment_pipe->enable_extension(gl_info, FALSE);
+
+ context->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
+ | (1 << WINED3D_SHADER_TYPE_VERTEX)
+ | (1 << WINED3D_SHADER_TYPE_GEOMETRY);
+}
+
+static HRESULT shader_none_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+ const struct fragment_pipeline *fragment_pipe)
{
struct fragment_caps fragment_caps;
+ void *vertex_priv, *fragment_priv;
struct shader_none_priv *priv;
- void *fragment_priv;
if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
return E_OUTOFMEMORY;
+ if (!(vertex_priv = vertex_pipe->vp_alloc(&none_shader_backend, priv)))
+ {
+ ERR("Failed to initialize vertex pipe.\n");
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
+
if (!(fragment_priv = fragment_pipe->alloc_private(&none_shader_backend, priv)))
{
ERR("Failed to initialize fragment pipe.\n");
+ vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv);
return E_FAIL;
}
+ priv->vertex_pipe = vertex_pipe;
+ priv->fragment_pipe = fragment_pipe;
fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps);
priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
+
+ device->vertex_priv = vertex_priv;
device->fragment_priv = fragment_priv;
- priv->fragment_pipe = fragment_pipe;
device->shader_priv = priv;
return WINED3D_OK;
struct shader_none_priv *priv = device->shader_priv;
priv->fragment_pipe->free_private(device);
+ priv->vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv);
}
+static BOOL shader_none_allocate_context_data(struct wined3d_context *context)
+{
+ return TRUE;
+}
+
static void shader_none_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
{
/* Set the shader caps to 0 for the none shader backend */
{
shader_none_handle_instruction,
shader_none_select,
+ shader_none_disable,
shader_none_select_depth_blt,
shader_none_deselect_depth_blt,
shader_none_update_float_vertex_constants,
shader_none_update_float_pixel_constants,
shader_none_load_constants,
- shader_none_load_np2fixup_constants,
shader_none_destroy,
shader_none_alloc,
shader_none_free,
- shader_none_context_destroyed,
+ shader_none_allocate_context_data,
+ shader_none_free_context_data,
shader_none_get_caps,
shader_none_color_fixup_supported,
shader_none_has_ffp_proj_control,
const struct wined3d_shader_frontend *fe;
HRESULT hr;
unsigned int backend_version;
+ const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info;
TRACE("shader %p, byte_code %p, output_signature %p, float_const_count %u.\n",
shader, byte_code, output_signature, float_const_count);
list_init(&shader->constantsF);
list_init(&shader->constantsB);
list_init(&shader->constantsI);
+ shader->lconst_inf_or_nan = FALSE;
/* Second pass: figure out which registers are used, what the semantics are, etc. */
hr = shader_get_registers_used(shader, fe,
switch (type)
{
case WINED3D_SHADER_TYPE_VERTEX:
- backend_version = shader->device->vs_version;
+ backend_version = d3d_info->limits.vs_version;
break;
case WINED3D_SHADER_TYPE_GEOMETRY:
- backend_version = shader->device->gs_version;
+ backend_version = d3d_info->limits.gs_version;
break;
case WINED3D_SHADER_TYPE_PIXEL:
- backend_version = shader->device->ps_version;
+ backend_version = d3d_info->limits.ps_version;
break;
default:
FIXME("No backend version-checking for this shader type\n");
for (i = start_idx; i < end_idx; ++i)
{
struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
+ float *value;
if (!lconst)
return E_OUTOFMEMORY;
lconst->idx = i;
- memcpy(lconst->value, src_data + (i - start_idx) * 4 /* 4 components */, 4 * sizeof(float));
+ value = (float *)lconst->value;
+ memcpy(value, src_data + (i - start_idx) * 4 /* 4 components */, 4 * sizeof(float));
list_add_head(&shader->constantsF, &lconst->entry);
+
+ if (isinf(value[0]) || isnan(value[0]) || isinf(value[1]) || isnan(value[1])
+ || isinf(value[2]) || isnan(value[2]) || isinf(value[3]) || isnan(value[3]))
+ {
+ shader->lconst_inf_or_nan = TRUE;
+ }
}
return WINED3D_OK;
== 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->strided_streams.swizzle_map;
+ args->swizzle_map = shader->device->stream_info.swizzle_map;
}
static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2)
DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
struct wined3d_device *device = shader->device;
+ const DWORD vs_uniform_count = device->adapter->d3d_info.limits.vs_uniform_count;
shader->limits.packed_input = 0;
/* TODO: vs_1_1 has a minimum of 96 constants. What happens when
* a vs_1_1 shader is used on a vs_3_0 capable card that has 256
* constants? */
- shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
+ shader->limits.constant_float = min(256, vs_uniform_count);
break;
case WINED3D_SHADER_VERSION(2, 0):
shader->limits.constant_int = 16;
shader->limits.packed_output = 12;
shader->limits.sampler = 0;
- shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
+ shader->limits.constant_float = min(256, vs_uniform_count);
break;
case WINED3D_SHADER_VERSION(3, 0):
* drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
* wined3d-advertised maximum. Clamp the constant limit for <= 3.0
* shaders to 256. */
- shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
+ shader->limits.constant_float = min(256, vs_uniform_count);
break;
case WINED3D_SHADER_VERSION(4, 0):
shader->limits.constant_int = 16;
shader->limits.packed_output = 12;
shader->limits.sampler = 0;
- shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
+ shader->limits.constant_float = min(256, vs_uniform_count);
FIXME("Unrecognized vertex shader version \"%u.%u\".\n",
shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
unsigned int i;
HRESULT hr;
WORD map;
+ const DWORD vs_uniform_count = device->adapter->d3d_info.limits.vs_uniform_count;
if (!byte_code) return WINED3DERR_INVALIDCALL;
shader_init(shader, device, parent, parent_ops);
- hr = shader_set_function(shader, byte_code, output_signature, device->d3d_vshader_constantF,
+ hr = shader_set_function(shader, byte_code, output_signature, vs_uniform_count,
WINED3D_SHADER_TYPE_VERTEX, max_version);
if (FAILED(hr))
{
vertexshader_set_limits(shader);
- shader->load_local_constsF = reg_maps->usesrelconstF
- && !list_empty(&shader->constantsF);
+ shader->load_local_constsF = (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) ||
+ shader->lconst_inf_or_nan;
return WINED3D_OK;
}
geometryshader_set_limits(shader);
- shader->load_local_constsF = FALSE;
+ shader->load_local_constsF = shader->lconst_inf_or_nan;
return WINED3D_OK;
}
if (shader->reg_maps.shader_version.major == 1
&& shader->reg_maps.shader_version.minor <= 3)
{
- for (i = 0; i < 4; ++i)
+ for (i = 0; i < shader->limits.sampler; ++i)
{
DWORD flags = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
}
}
}
+ if (shader->reg_maps.shader_version.major == 1
+ && shader->reg_maps.shader_version.minor <= 4)
+ {
+ for (i = 0; i < shader->limits.sampler; ++i)
+ {
+ const struct wined3d_texture *texture = state->textures[i];
+
+ if (!shader->reg_maps.sampler_type[i])
+ continue;
+
+ /* Treat unbound textures as 2D. The dummy texture will provide
+ * the proper sample value. The tex_types bitmap defaults to
+ * 2D because of the memset. */
+ if (!texture)
+ continue;
+
+ switch (texture->target)
+ {
+ /* RECT textures are distinguished from 2D textures via np2_fixup */
+ case GL_TEXTURE_RECTANGLE_ARB:
+ case GL_TEXTURE_2D:
+ break;
+
+ case GL_TEXTURE_3D:
+ args->tex_types |= WINED3D_SHADER_TEX_3D << i * WINED3D_PSARGS_TEXTYPE_SHIFT;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ args->tex_types |= WINED3D_SHADER_TEX_CUBE << i * WINED3D_PSARGS_TEXTYPE_SHIFT;
+ break;
+ }
+ }
+ }
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
}
if (shader->reg_maps.shader_version.major >= 3)
{
- if (device->strided_streams.position_transformed)
- {
+ if (device->stream_info.position_transformed)
args->vp_mode = pretransformed;
- }
else if (use_vs(state))
- {
args->vp_mode = vertexshader;
- }
else
- {
args->vp_mode = fixedfunction;
- }
- args->fog = FOG_OFF;
+ args->fog = WINED3D_FFP_PS_FOG_OFF;
}
else
{
switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
{
case WINED3D_FOG_NONE:
- if (device->strided_streams.position_transformed || use_vs(state))
+ if (device->stream_info.position_transformed || use_vs(state))
{
- args->fog = FOG_LINEAR;
+ args->fog = WINED3D_FFP_PS_FOG_LINEAR;
break;
}
switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
{
case WINED3D_FOG_NONE: /* Fall through. */
- case WINED3D_FOG_LINEAR: args->fog = FOG_LINEAR; break;
- case WINED3D_FOG_EXP: args->fog = FOG_EXP; break;
- case WINED3D_FOG_EXP2: args->fog = FOG_EXP2; break;
+ case WINED3D_FOG_LINEAR: args->fog = WINED3D_FFP_PS_FOG_LINEAR; break;
+ case WINED3D_FOG_EXP: args->fog = WINED3D_FFP_PS_FOG_EXP; break;
+ case WINED3D_FOG_EXP2: args->fog = WINED3D_FFP_PS_FOG_EXP2; break;
}
break;
- case WINED3D_FOG_LINEAR: args->fog = FOG_LINEAR; break;
- case WINED3D_FOG_EXP: args->fog = FOG_EXP; break;
- case WINED3D_FOG_EXP2: args->fog = FOG_EXP2; break;
+ case WINED3D_FOG_LINEAR: args->fog = WINED3D_FFP_PS_FOG_LINEAR; break;
+ case WINED3D_FOG_EXP: args->fog = WINED3D_FFP_PS_FOG_EXP; break;
+ case WINED3D_FOG_EXP2: args->fog = WINED3D_FFP_PS_FOG_EXP2; break;
}
}
else
{
- args->fog = FOG_OFF;
+ args->fog = WINED3D_FFP_PS_FOG_OFF;
}
}
}
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
unsigned int i, highest_reg_used = 0, num_regs_used = 0;
HRESULT hr;
+ const DWORD ps_uniform_count = device->adapter->d3d_info.limits.ps_uniform_count;
if (!byte_code) return WINED3DERR_INVALIDCALL;
shader_init(shader, device, parent, parent_ops);
- hr = shader_set_function(shader, byte_code, output_signature, device->d3d_pshader_constantF,
+ hr = shader_set_function(shader, byte_code, output_signature, ps_uniform_count,
WINED3D_SHADER_TYPE_PIXEL, max_version);
if (FAILED(hr))
{
}
}
- shader->load_local_constsF = FALSE;
+ shader->load_local_constsF = shader->lconst_inf_or_nan;
return WINED3D_OK;
}
-void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps, struct wined3d_texture * const *textures)
+void pixelshader_update_samplers(struct wined3d_shader *shader, WORD tex_types)
{
+ struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
enum wined3d_sampler_texture_type *sampler_type = reg_maps->sampler_type;
unsigned int i;
if (reg_maps->shader_version.major != 1) return;
- for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i)
+ for (i = 0; i < shader->limits.sampler; ++i)
{
/* We don't sample from this sampler. */
if (!sampler_type[i]) continue;
- if (!textures[i])
- {
- WARN("No texture bound to sampler %u, using 2D.\n", i);
- sampler_type[i] = WINED3DSTT_2D;
- continue;
- }
-
- switch (textures[i]->target)
+ switch ((tex_types >> i * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK)
{
- case GL_TEXTURE_RECTANGLE_ARB:
- case GL_TEXTURE_2D:
- /* We have to select between texture rectangles and 2D
- * textures later because 2.0 and 3.0 shaders only have
- * WINED3DSTT_2D as well. */
+ case WINED3D_SHADER_TEX_2D:
sampler_type[i] = WINED3DSTT_2D;
break;
- case GL_TEXTURE_3D:
+ case WINED3D_SHADER_TEX_3D:
sampler_type[i] = WINED3DSTT_VOLUME;
break;
- case GL_TEXTURE_CUBE_MAP_ARB:
+ case WINED3D_SHADER_TEX_CUBE:
sampler_type[i] = WINED3DSTT_CUBE;
break;
-
- default:
- FIXME("Unrecognized texture type %#x, using 2D.\n", textures[i]->target);
- sampler_type[i] = WINED3DSTT_2D;
}
}
}
return;
if (state->render_states[WINED3D_RS_LIGHTING]
- && !context->swapchain->device->strided_streams.position_transformed)
+ && !context->swapchain->device->stream_info.position_transformed)
{
gl_info->gl_ops.gl.p_glEnable(GL_LIGHTING);
checkGLcall("glEnable GL_LIGHTING");
if (context->gl_info->supported[ARB_DEPTH_CLAMP])
{
- if (!zenable && context->swapchain->device->strided_streams.position_transformed)
+ if (!zenable && context->swapchain->device->stream_info.position_transformed)
{
gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
checkGLcall("glEnable(GL_DEPTH_CLAMP)");
if (!depth_func) return;
- if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
- {
- static BOOL once;
- /* There are a few issues with this: First, our inability to
- * select a proper Z depth, most of the time we're stuck with
- * D24S8, even if the app selects D32 or D16. There seem to be
- * some other precision problems which have to be debugged to
- * make NOTEQUAL and EQUAL work properly. */
- if (!once)
- {
- once = TRUE;
- FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
- }
- }
-
gl_info->gl_ops.gl.p_glDepthFunc(depth_func);
checkGLcall("glDepthFunc");
}
-static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
}
}
-static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
-{
- context->load_constants = 1;
-}
-
-static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
DWORD enable = 0xffffffff;
DWORD disable = 0x00000000;
- if (use_vs(state))
+ if (use_vs(state) && !context->d3d_info->vs_clipping)
{
- const struct wined3d_device *device = context->swapchain->device;
-
- if (!device->vs_clipping)
- {
- /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
- * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
- * conditions I got sick of tracking down. The shader state handler disables all clip planes because
- * of that - don't do anything here and keep them disabled
- */
- if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
- {
- static BOOL warned = FALSE;
- if(!warned) {
- FIXME("Clipping not supported with vertex shaders\n");
- warned = TRUE;
- }
- }
- return;
- }
+ static BOOL warned;
- /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
- * hardcoded into the shader. Update the shader to update the enabled clipplanes */
- context->select_shader = 1;
- context->load_constants = 1;
+ /* The OpenGL spec says that clipping planes are disabled when using
+ * shaders. Direct3D planes aren't, so that is an issue. The MacOS ATI
+ * driver keeps clipping planes activated with shaders in some
+ * conditions I got sick of tracking down. The shader state handler
+ * disables all clip planes because of that - don't do anything here
+ * and keep them disabled. */
+ if (state->render_states[WINED3D_RS_CLIPPLANEENABLE] && !warned++)
+ FIXME("Clipping not supported with vertex shaders\n");
+ return;
}
+ /* glEnable(GL_CLIP_PLANEx) doesn't apply to (ARB backend) vertex shaders.
+ * The enabled / disabled planes are hardcoded into the shader. Update the
+ * shader to update the enabled clipplanes. In case of fixed function, we
+ * need to update the clipping field from ffp_vertex_settings. */
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+
/* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
* of already set values
*/
checkGLcall("clip plane disable");
}
-static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
/* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
/* And now the default texture color as well */
- for (i = 0; i < gl_info->limits.texture_stages; ++i)
+ for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i)
{
/* Note the WINED3D_RS value applies to all textures, but GL has one
* per texture, so apply it now ready to be used! */
fogstart = tmpvalue.f;
tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
fogend = tmpvalue.f;
- /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
- if(fogstart == fogend) {
+ /* Special handling for fogstart == fogend. In d3d with vertex
+ * fog, everything is fogged. With table fog, everything with
+ * fog_coord < fog_start is unfogged, and fog_coord > fog_start
+ * is fogged. Windows drivers disagree when fog_coord == fog_start. */
+ if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE
+ && fogstart == fogend)
+ {
fogstart = -INFINITY;
fogend = 0.0f;
}
{
const struct wined3d_gl_info *gl_info = context->gl_info;
enum fogsource new_source;
+ DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
+ DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
glEnableWINE(GL_FOG);
checkGLcall("glEnable GL_FOG");
- if (new_source != context->fog_source)
+ if (new_source != context->fog_source || fogstart == fogend)
{
context->fog_source = new_source;
state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
}
context->num_untracked_materials = 0;
- if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
+ if ((device->stream_info.use_map & (1 << WINED3D_FFP_DIFFUSE))
&& state->render_states[WINED3D_RS_COLORVERTEX])
{
TRACE("diff %d, amb %d, emis %d, spec %d\n",
* by zero and is not properly defined in opengl, so avoid it
*/
if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
- && (context->swapchain->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
+ && (context->swapchain->device->stream_info.use_map & (1 << WINED3D_FFP_NORMAL)))
{
gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE);
checkGLcall("glEnable(GL_NORMALIZE);");
}
}
-static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
union {
DWORD d;
}
-static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
union
checkGLcall("glPointParameterfEXT(...)");
}
-static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
union
checkGLcall("glPointParameterfARB(...)");
}
-static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
/* TODO: Group this with the viewport */
}
}
-static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
static BOOL warned;
}
}
-static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
}
}
-static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
const struct wined3d_device *device = context->swapchain->device;
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->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
- ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
+ device->stream_info.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
+ ? device->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
: WINED3DFMT_UNKNOWN,
device->shader_backend->shader_has_ffp_proj_control(device->shader_priv));
unsigned int mapped_stage = 0;
unsigned int textureNo = 0;
- for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
+ for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo)
{
int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
unload_tex_coords(gl_info);
- load_tex_coords(context, &device->strided_streams, &curVBO, state);
+ load_tex_coords(context, &device->stream_info, &curVBO, state);
}
}
-static void tex_bumpenvlscale(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_shader *ps = state->pixel_shader;
-
- /* The pixel shader has to know the luminance scale. Do a constants update. */
- if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
- context->load_constants = 1;
-}
-
-static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const DWORD sampler = state_id - STATE_SAMPLER(0);
const struct wined3d_texture *texture = state->textures[sampler];
/* Trigger shader constant reloading (for NP2 texcoord fixup) */
if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
- device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
+ context->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP;
}
else
{
{
/* Disabled the pixel shader - color ops weren't applied while it was
* enabled, so re-apply them. */
- for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
+ for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i)
{
if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
context->last_was_pshader = FALSE;
}
- context->select_shader = 1;
- context->load_constants = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
- context->select_shader = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_GEOMETRY;
}
-static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static void shader_bumpenv(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_shader *ps = state->pixel_shader;
-
- /* The pixel shader has to know the bump env matrix. Do a constants update. */
- if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
- context->load_constants = 1;
+ context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV;
}
-static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
}
else
{
- /* In the general case, the view matrix is the identity matrix */
- if (context->swapchain->device->view_ident)
- {
- gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- }
- else
- {
- gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
- checkGLcall("glMultMatrixf");
- }
+ gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
+ checkGLcall("glMultMatrixf");
}
}
-static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
UINT index = state_id - STATE_CLIPPLANE(0);
/* World matrix 0 is multiplied with the view matrix because d3d uses 3
* matrices while gl uses only 2. To avoid weighting the view matrix
* incorrectly it has to be multiplied into every GL modelview matrix. */
- if (context->swapchain->device->view_ident)
- {
- gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- }
- else
- {
- gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
- checkGLcall("glMultMatrixf");
- }
+ gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
+ checkGLcall("glMultMatrixf");
}
static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
}
}
-static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_light_info *light = NULL;
}
}
-static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
if (load_numbered)
{
TRACE("Loading numbered arrays\n");
- load_numbered_arrays(context, &device->strided_streams, state);
+ load_numbered_arrays(context, &device->stream_info, state);
context->numberedArraysLoaded = TRUE;
}
else if (load_named)
{
TRACE("Loading vertex data\n");
- load_vertex_data(context, &device->strided_streams, state);
+ load_vertex_data(context, &device->stream_info, state);
context->namedArraysLoaded = TRUE;
}
}
streamsrc(context, state, STATE_STREAMSRC);
}
-static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+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 wasrhw = context->last_was_rhw;
unsigned int i;
- transformed = device->strided_streams.position_transformed;
+ transformed = device->stream_info.position_transformed;
if (transformed != context->last_was_rhw && !useVertexShaderFunction)
updateFog = TRUE;
&& !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
- state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
+ context_apply_state(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
{
updateFog = TRUE;
- if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
+ if (!context->d3d_info->vs_clipping
+ && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
+ {
state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
+ }
for (i = 0; i < gl_info->limits.clipplanes; ++i)
{
{
if(!context->last_was_vshader) {
static BOOL warned = FALSE;
- if(!device->vs_clipping) {
+ if (!context->d3d_info->vs_clipping)
+ {
/* Disable all clip planes to get defined results on all drivers. See comment in the
* state_clipping state handler
*/
}
context->last_was_vshader = useVertexShaderFunction;
- context->select_shader = 1;
- context->load_constants = 1;
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
if (updateFog)
context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
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)
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
vp.width, vp.height);
}
-
checkGLcall("glViewport");
}
-static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
- if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
+ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE))
+ && state->render_states[WINED3D_RS_POINTSCALEENABLE])
state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
/* Update the position fixup. */
- context->load_constants = 1;
+ context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP;
}
-static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
UINT Index = state_id - STATE_ACTIVELIGHT(0);
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->strided_streams;
+ const struct wined3d_stream_info *stream_info = &context->swapchain->device->stream_info;
const struct wined3d_gl_info *gl_info = context->gl_info;
if (!state->index_buffer || !stream_info->all_vbo)
/* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
* vshader loadings are untied from each other
*/
- { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
- { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, 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(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, 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(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, 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(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, 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(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, 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(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, 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(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, 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(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, 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(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, 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_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, 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_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, 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_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, 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_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, 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_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, 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_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, 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_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
{0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
};
-const struct StateEntryTemplate ffp_vertexstate_template[] = {
+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_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
{ STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
/* Lights */
+ { STATE_LIGHT_TYPE, { STATE_LIGHT_TYPE, state_nop }, WINED3D_GL_EXT_NONE },
{ STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
{ STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
{ STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
{ STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
{ STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_POINT_SIZE_ENABLE, { STATE_POINT_SIZE_ENABLE, state_nop }, WINED3D_GL_EXT_NONE },
{0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
};
/* Context activation is done by the caller. */
static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
+static void *ffp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ return shader_priv;
+}
+
+static void ffp_free(struct wined3d_device *device) {}
+
+static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
+{
+ caps->xyzrhw = FALSE;
+ caps->max_active_lights = gl_info->limits.lights;
+ caps->max_vertex_blend_matrices = gl_info->limits.blends;
+ caps->max_vertex_blend_matrix_index = 0;
+ caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS
+ | WINED3DVTXPCAPS_MATERIALSOURCE7
+ | WINED3DVTXPCAPS_POSITIONALLIGHTS
+ | WINED3DVTXPCAPS_LOCALVIEWER
+ | WINED3DVTXPCAPS_VERTEXFOG
+ | WINED3DVTXPCAPS_TEXGEN
+ | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP;
+ caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
+ caps->max_user_clip_planes = gl_info->limits.clipplanes;
+ caps->raster_caps = 0;
+ if (gl_info->supported[NV_FOG_DISTANCE])
+ caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE;
+}
+
+const struct wined3d_vertex_pipe_ops ffp_vertex_pipe =
+{
+ ffp_enable,
+ vp_ffp_get_caps,
+ ffp_alloc,
+ ffp_free,
+ vp_ffp_states,
+};
+
static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
{
caps->wined3d_caps = 0;
caps->MaxSimultaneousTextures = gl_info->limits.textures;
}
-static void *ffp_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
-{
- return shader_priv;
-}
-
-static void ffp_fragment_free(struct wined3d_device *device) {}
static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d))
const struct fragment_pipeline ffp_fragment_pipeline = {
ffp_enable,
ffp_fragment_get_caps,
- ffp_fragment_alloc,
- ffp_fragment_free,
+ ffp_alloc,
+ ffp_free,
ffp_color_fixup_supported,
ffp_fragmentstate_template,
};
-static void fp_none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
+static void none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
-static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+static void *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
{
- memset(caps, 0, sizeof(*caps));
+ return shader_priv;
}
-static void *fp_none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+static void none_free(struct wined3d_device *device) {}
+
+static void vp_none_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
{
- return shader_priv;
+ memset(caps, 0, sizeof(*caps));
}
-static void fp_none_free(struct wined3d_device *device) {}
+const struct wined3d_vertex_pipe_ops none_vertex_pipe =
+{
+ none_enable,
+ vp_none_get_caps,
+ none_alloc,
+ none_free,
+ NULL,
+};
+
+static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+{
+ memset(caps, 0, sizeof(*caps));
+}
static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
{
const struct fragment_pipeline none_fragment_pipe =
{
- fp_none_enable,
+ none_enable,
fp_none_get_caps,
- fp_none_alloc,
- fp_none_free,
+ none_alloc,
+ none_free,
fp_none_color_fixup_supported,
NULL,
};
context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
}
-static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
+static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_d3d_info *d3d_info)
{
unsigned int start, last, i;
- start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
+ start = STATE_TEXTURESTAGE(d3d_info->limits.ffp_blend_stages, 0);
last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
for (i = start; i <= last; ++i)
{
state_table[i].apply = state_undefined;
}
- start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
+ start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + d3d_info->limits.ffp_blend_stages);
last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
for (i = start; i <= last; ++i)
{
STATE_VDECL,
STATE_STREAMSRC,
STATE_INDEXBUFFER,
- STATE_VERTEXSHADERCONSTANT,
- STATE_PIXELSHADERCONSTANT,
STATE_VSHADER,
STATE_GEOMETRY_SHADER,
STATE_PIXELSHADER,
STATE_VIEWPORT,
+ STATE_LIGHT_TYPE,
STATE_SCISSORRECT,
STATE_FRONTFACE,
STATE_POINTSPRITECOORDORIGIN,
STATE_BASEVERTEXINDEX,
- STATE_FRAMEBUFFER
+ STATE_FRAMEBUFFER,
+ STATE_POINT_SIZE_ENABLE,
};
unsigned int i, current;
}
HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
- const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
- const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
+ const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info,
+ const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
+ const struct StateEntryTemplate *misc)
{
unsigned int i, type, handlers;
APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
switch(type) {
case 0: cur = misc; break;
case 1: cur = fragment->states; break;
- case 2: cur = vertex; break;
+ case 2: cur = vertex->vp_states; break;
default: cur = NULL; /* Stupid compiler */
}
if(!cur) continue;
cur[i].state, handlers + 1);
}
- if(StateTable[cur[i].state].representative &&
- StateTable[cur[i].state].representative != cur[i].content.representative) {
- FIXME("State %u has different representatives in different pipeline parts\n",
- cur[i].state);
+ if (StateTable[cur[i].state].representative
+ && StateTable[cur[i].state].representative != cur[i].content.representative)
+ {
+ FIXME("State %s (%#x) has different representatives in different pipeline parts.\n",
+ debug_d3dstate(cur[i].state), cur[i].state);
}
StateTable[cur[i].state].representative = cur[i].content.representative;
}
}
- prune_invalid_states(StateTable, gl_info);
+ prune_invalid_states(StateTable, gl_info, d3d_info);
validate_state_table(StateTable);
return WINED3D_OK;
*/
static HRESULT stateblock_allocate_shader_constants(struct wined3d_stateblock *object)
{
- struct wined3d_device *device = object->device;
-
- /* Allocate space for floating point constants */
- object->state.ps_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(float) * device->d3d_pshader_constantF * 4);
- if (!object->state.ps_consts_f) goto fail;
+ const struct wined3d_d3d_info *d3d_info = &object->device->adapter->d3d_info;
object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(BOOL) * device->d3d_pshader_constantF);
+ sizeof(BOOL) * d3d_info->limits.ps_uniform_count);
if (!object->changed.pixelShaderConstantsF) goto fail;
- object->state.vs_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(float) * device->d3d_vshader_constantF * 4);
- if (!object->state.vs_consts_f) goto fail;
-
object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(BOOL) * device->d3d_vshader_constantF);
+ sizeof(BOOL) * d3d_info->limits.vs_uniform_count);
if (!object->changed.vertexShaderConstantsF) goto fail;
object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0,
- sizeof(DWORD) * device->d3d_vshader_constantF);
+ sizeof(DWORD) * d3d_info->limits.vs_uniform_count);
if (!object->contained_vs_consts_f) goto fail;
object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0,
- sizeof(DWORD) * device->d3d_pshader_constantF);
+ sizeof(DWORD) * d3d_info->limits.ps_uniform_count);
if (!object->contained_ps_consts_f) goto fail;
return WINED3D_OK;
fail:
ERR("Failed to allocate memory\n");
- HeapFree(GetProcessHeap(), 0, object->state.ps_consts_f);
HeapFree(GetProcessHeap(), 0, object->changed.pixelShaderConstantsF);
- HeapFree(GetProcessHeap(), 0, object->state.vs_consts_f);
HeapFree(GetProcessHeap(), 0, object->changed.vertexShaderConstantsF);
HeapFree(GetProcessHeap(), 0, object->contained_vs_consts_f);
HeapFree(GetProcessHeap(), 0, object->contained_ps_consts_f);
void stateblock_init_contained_states(struct wined3d_stateblock *stateblock)
{
- struct wined3d_device *device = stateblock->device;
+ const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info;
unsigned int i, j;
for (i = 0; i <= WINEHIGHEST_RENDER_STATE >> 5; ++i)
}
}
- for (i = 0; i < device->d3d_vshader_constantF; ++i)
+ for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i)
{
if (stateblock->changed.vertexShaderConstantsF[i])
{
}
}
- for (i = 0; i < device->d3d_pshader_constantF; ++i)
+ for (i = 0; i < d3d_info->limits.ps_uniform_count; ++i)
{
if (stateblock->changed.pixelShaderConstantsF[i])
{
return refcount;
}
-void stateblock_unbind_resources(struct wined3d_stateblock *stateblock)
+void state_unbind_resources(struct wined3d_state *state)
{
- struct wined3d_state *state = &stateblock->state;
struct wined3d_vertex_declaration *decl;
struct wined3d_sampler *sampler;
struct wined3d_texture *texture;
}
}
+void state_cleanup(struct wined3d_state *state)
+{
+ unsigned int counter;
+
+ state_unbind_resources(state);
+
+ for (counter = 0; counter < LIGHTMAP_SIZE; ++counter)
+ {
+ struct list *e1, *e2;
+ LIST_FOR_EACH_SAFE(e1, e2, &state->light_map[counter])
+ {
+ struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry);
+ list_remove(&light->entry);
+ HeapFree(GetProcessHeap(), 0, light);
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, state->vs_consts_f);
+ 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);
if (!refcount)
{
- int counter;
-
- stateblock_unbind_resources(stateblock);
-
- for (counter = 0; counter < LIGHTMAP_SIZE; ++counter)
- {
- struct list *e1, *e2;
- LIST_FOR_EACH_SAFE(e1, e2, &stateblock->state.light_map[counter])
- {
- struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry);
- list_remove(&light->entry);
- HeapFree(GetProcessHeap(), 0, light);
- }
- }
+ state_cleanup(&stateblock->state);
- HeapFree(GetProcessHeap(), 0, stateblock->state.vs_consts_f);
HeapFree(GetProcessHeap(), 0, stateblock->changed.vertexShaderConstantsF);
- HeapFree(GetProcessHeap(), 0, stateblock->state.ps_consts_f);
HeapFree(GetProcessHeap(), 0, stateblock->changed.pixelShaderConstantsF);
HeapFree(GetProcessHeap(), 0, stateblock->contained_vs_consts_f);
HeapFree(GetProcessHeap(), 0, stateblock->contained_ps_consts_f);
void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
{
- const struct wined3d_state *src_state = &stateblock->device->stateBlock->state;
+ const struct wined3d_state *src_state = &stateblock->device->state;
unsigned int i;
DWORD map;
if (stateblock->changed.primitive_type)
{
- stateblock->device->updateStateBlock->changed.primitive_type = TRUE;
- stateblock->device->updateStateBlock->state.gl_primitive_type = stateblock->state.gl_primitive_type;
+ GLenum gl_primitive_type, prev;
+
+ if (device->recording)
+ device->recording->changed.primitive_type = TRUE;
+ gl_primitive_type = stateblock->state.gl_primitive_type;
+ prev = device->update_state->gl_primitive_type;
+ device->update_state->gl_primitive_type = gl_primitive_type;
+ if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS))
+ device_invalidate_state(device, STATE_POINT_SIZE_ENABLE);
}
if (stateblock->changed.indices)
wined3d_device_set_clip_plane(device, i, &stateblock->state.clip_planes[i]);
}
- stateblock->device->stateBlock->state.lowest_disabled_stage = MAX_TEXTURES - 1;
+ stateblock->device->state.lowest_disabled_stage = MAX_TEXTURES - 1;
for (i = 0; i < MAX_TEXTURES - 1; ++i)
{
- if (stateblock->device->stateBlock->state.texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
+ if (stateblock->device->state.texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
{
- stateblock->device->stateBlock->state.lowest_disabled_stage = i;
+ stateblock->device->state.lowest_disabled_stage = i;
break;
}
}
TRACE("Applied stateblock %p.\n", stateblock);
}
-void stateblock_init_default_state(struct wined3d_stateblock *stateblock)
+void state_init_default(struct wined3d_state *state, struct wined3d_device *device)
{
- struct wined3d_device *device = stateblock->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- struct wined3d_state *state = &stateblock->state;
union
{
struct wined3d_line_pattern lp;
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,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ }}};
- TRACE("stateblock %p.\n", stateblock);
-
- memset(stateblock->changed.pixelShaderConstantsF, 0, device->d3d_pshader_constantF * sizeof(BOOL));
- memset(stateblock->changed.vertexShaderConstantsF, 0, device->d3d_vshader_constantF * sizeof(BOOL));
+ TRACE("state %p, device %p.\n", state, device);
/* Set some of the defaults for lights, transforms etc */
state->transforms[WINED3D_TS_PROJECTION] = identity;
static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
struct wined3d_device *device, enum wined3d_stateblock_type type)
{
- unsigned int i;
HRESULT hr;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
stateblock->ref = 1;
stateblock->device = device;
- for (i = 0; i < LIGHTMAP_SIZE; i++)
+ if (FAILED(hr = state_init(&stateblock->state, d3d_info)))
+ return hr;
+
+ if (FAILED(hr = stateblock_allocate_shader_constants(stateblock)))
{
- list_init(&stateblock->state.light_map[i]);
+ state_cleanup(&stateblock->state);
+ return hr;
}
- hr = stateblock_allocate_shader_constants(stateblock);
- if (FAILED(hr)) return hr;
-
- /* The WINED3D_SBT_INIT stateblock type is used during initialization to
- * produce a placeholder stateblock so other functions called can update a
- * state block. */
- if (type == WINED3D_SBT_INIT || type == WINED3D_SBT_RECORDED) return WINED3D_OK;
+ if (type == WINED3D_SBT_RECORDED)
+ return WINED3D_OK;
TRACE("Updating changed flags appropriate for type %#x.\n", type);
switch (type)
{
case WINED3D_SBT_ALL:
- stateblock_init_lights(stateblock, device->stateBlock->state.light_map);
- stateblock_savedstates_set_all(&stateblock->changed, device->d3d_vshader_constantF,
- device->d3d_pshader_constantF);
+ stateblock_init_lights(stateblock, device->state.light_map);
+ stateblock_savedstates_set_all(&stateblock->changed,
+ d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count);
break;
case WINED3D_SBT_PIXEL_STATE:
- stateblock_savedstates_set_pixel(&stateblock->changed, device->d3d_pshader_constantF);
+ stateblock_savedstates_set_pixel(&stateblock->changed,
+ d3d_info->limits.ps_uniform_count);
break;
case WINED3D_SBT_VERTEX_STATE:
- stateblock_init_lights(stateblock, device->stateBlock->state.light_map);
- stateblock_savedstates_set_vertex(&stateblock->changed, device->d3d_vshader_constantF);
+ stateblock_init_lights(stateblock, device->state.light_map);
+ stateblock_savedstates_set_vertex(&stateblock->changed,
+ d3d_info->limits.vs_uniform_count);
break;
default:
* Copyright 2002-2003 Raphael Junqueira
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
- * Copyright 2006-2011 Stefan Dösinger for CodeWeavers
+ * Copyright 2006-2011, 2013 Stefan Dösinger for CodeWeavers
* Copyright 2007-2008 Henri Verbeet
* Copyright 2006-2008 Roderick Colenbrander
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
}
if (surface->flags & SFLAG_USERPTR)
- wined3d_surface_set_mem(surface, NULL);
+ wined3d_surface_set_mem(surface, NULL, 0);
if (surface->overlay_dest)
list_remove(&surface->overlay_entry);
surface->draw_binding = SFLAG_INTEXTURE;
}
-void surface_set_container(struct wined3d_surface *surface, enum wined3d_container_type type, void *container)
+void surface_set_swapchain(struct wined3d_surface *surface, struct wined3d_swapchain *swapchain)
{
- TRACE("surface %p, container %p.\n", surface, container);
-
- if (!container && type != WINED3D_CONTAINER_NONE)
- ERR("Setting NULL container of type %#x.\n", type);
+ TRACE("surface %p, swapchain %p.\n", surface, swapchain);
- if (type == WINED3D_CONTAINER_SWAPCHAIN)
+ if (swapchain)
{
surface->get_drawable_size = get_drawable_size_swapchain;
}
}
}
- surface->container.type = type;
- surface->container.u.base = container;
+ surface->swapchain = swapchain;
+ surface_update_draw_binding(surface);
+}
+
+void surface_set_container(struct wined3d_surface *surface, struct wined3d_texture *container)
+{
+ TRACE("surface %p, container %p.\n", surface, container);
+
+ if (!surface->swapchain)
+ {
+ switch (wined3d_settings.offscreen_rendering_mode)
+ {
+ case ORM_FBO:
+ surface->get_drawable_size = get_drawable_size_fbo;
+ break;
+
+ case ORM_BACKBUFFER:
+ surface->get_drawable_size = get_drawable_size_backbuffer;
+ break;
+
+ default:
+ ERR("Unhandled offscreen rendering mode %#x.\n", wined3d_settings.offscreen_rendering_mode);
+ return;
+ }
+ }
+
+ surface->container = container;
surface_update_draw_binding(surface);
}
/* We changed the filtering settings on the texture. Inform the
* container about this to get the filters reset properly next draw. */
- if (src_surface->container.type == WINED3D_CONTAINER_TEXTURE)
+ if (src_surface->container)
{
- struct wined3d_texture *texture = src_surface->container.u.texture;
+ struct wined3d_texture *texture = src_surface->container;
texture->texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT;
texture->texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT;
texture->texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE;
/* We don't need the system memory anymore and we can't even use it for PBOs. */
if (!(surface->flags & SFLAG_CLIENT))
{
- HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
- surface->resource.heapMemory = NULL;
+ wined3d_resource_free_sysmem(surface->resource.heap_memory);
+ surface->resource.heap_memory = NULL;
}
surface->resource.allocatedMemory = NULL;
surface->flags |= SFLAG_PBO;
{
/* Whatever surface we have, make sure that there is memory allocated
* for the downloaded copy, or a PBO to map. */
- if (!surface->resource.heapMemory)
- surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), 0, surface->resource.size + RESOURCE_ALIGNMENT);
+ if (!surface->resource.heap_memory)
+ surface->resource.heap_memory = wined3d_resource_allocate_sysmem(surface->resource.size);
- surface->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)surface->resource.heapMemory
- + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ surface->resource.allocatedMemory = surface->resource.heap_memory;
if (surface->flags & SFLAG_INSYSMEM)
ERR("Surface without memory or PBO has SFLAG_INSYSMEM set.\n");
if (surface->resource.map_count || (surface->flags & SFLAG_DONOTFREE))
return;
- HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+ wined3d_resource_free_sysmem(surface->resource.heap_memory);
surface->resource.allocatedMemory = NULL;
- surface->resource.heapMemory = NULL;
+ surface->resource.heap_memory = NULL;
surface_modify_location(surface, SFLAG_INSYSMEM, FALSE);
}
{
TRACE("surface %p, context %p, srgb %#x.\n", surface, context, srgb);
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
+ if (surface->container)
{
- struct wined3d_texture *texture = surface->container.u.texture;
+ struct wined3d_texture *texture = surface->container;
TRACE("Passing to container (%p).\n", texture);
texture->texture_ops->texture_bind(texture, context, srgb);
struct wined3d_context *context = context_acquire(surface->resource.device, NULL);
const struct wined3d_gl_info *gl_info = context->gl_info;
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
if (surface->texture_name)
{
surface_bind_and_dirtify(surface, context, FALSE);
gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
}
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
context_release(context);
TRACE("Creating an oversized surface: %ux%u.\n",
surface->pow2Width, surface->pow2Height);
}
- else
- {
- /* Don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8
- * and EXT_PALETTED_TEXTURE is used in combination with texture
- * uploads (RTL_READTEX/RTL_TEXTEX). The reason is that
- * EXT_PALETTED_TEXTURE doesn't work in combination with
- * ARB_TEXTURE_RECTANGLE. */
- if (surface->flags & SFLAG_NONPOW2 && gl_info->supported[ARB_TEXTURE_RECTANGLE]
- && !(surface->resource.format->id == WINED3DFMT_P8_UINT
- && gl_info->supported[EXT_PALETTED_TEXTURE]
- && wined3d_settings.rendertargetlock_mode == RTL_READTEX))
- {
- surface->texture_target = GL_TEXTURE_RECTANGLE_ARB;
- surface->pow2Width = surface->resource.width;
- surface->pow2Height = surface->resource.height;
- surface->flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD);
- }
- }
switch (wined3d_settings.offscreen_rendering_mode)
{
}
else
{
+ if (surface->resource.usage & WINED3DUSAGE_DYNAMIC)
+ WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n");
+
/* surface_load_location() does not check if the rectangle specifies
* the full surface. Most callers don't need that, so do it here. */
if (rect && !rect->top && !rect->left
goto done;
}
- if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN
- && surface->container.u.swapchain->front_buffer == surface)
+ if (surface->swapchain && surface->swapchain->front_buffer == surface)
{
if (!surface->dirtyRect.left && !surface->dirtyRect.top
&& surface->dirtyRect.right == surface->resource.width
return TRUE;
}
-static void wined3d_surface_depth_blt_fbo(const struct wined3d_device *device, struct wined3d_surface *src_surface,
- const RECT *src_rect, struct wined3d_surface *dst_surface, const RECT *dst_rect)
+static void surface_depth_blt_fbo(const struct wined3d_device *device,
+ struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect,
+ struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
DWORD src_mask, dst_mask;
GLbitfield gl_mask;
- TRACE("device %p, src_surface %p, src_rect %s, dst_surface %p, dst_rect %s.\n",
- device, src_surface, wine_dbgstr_rect(src_rect),
- dst_surface, wine_dbgstr_rect(dst_rect));
+ TRACE("device %p\n", device);
+ TRACE("src_surface %p, src_location %s, src_rect %s,\n",
+ src_surface, debug_surflocation(src_location), wine_dbgstr_rect(src_rect));
+ TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n",
+ dst_surface, debug_surflocation(dst_location), wine_dbgstr_rect(dst_rect));
src_mask = src_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
dst_mask = dst_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
/* Make sure the locations are up-to-date. Loading the destination
* surface isn't required if the entire surface is overwritten. */
- surface_load_location(src_surface, SFLAG_INTEXTURE, NULL);
+ surface_load_location(src_surface, src_location, NULL);
if (!surface_is_full_rect(dst_surface, dst_rect))
- surface_load_location(dst_surface, SFLAG_INTEXTURE, NULL);
+ surface_load_location(dst_surface, dst_location, NULL);
context = context_acquire(device, NULL);
if (!context->valid)
gl_info = context->gl_info;
- context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, src_surface, SFLAG_INTEXTURE);
- gl_info->gl_ops.gl.p_glReadBuffer(GL_NONE);
- checkGLcall("glReadBuffer()");
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, src_surface, src_location);
context_check_fbo_status(context, GL_READ_FRAMEBUFFER);
- context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, NULL, dst_surface, SFLAG_INTEXTURE);
+ context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, NULL, dst_surface, dst_location);
context_set_draw_buffer(context, GL_NONE);
context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER);
context_invalidate_state(context, STATE_FRAMEBUFFER);
if (wined3d_settings.strict_draw_ordering
|| (dst_location == SFLAG_INDRAWABLE
- && dst_surface->container.u.swapchain->front_buffer == dst_surface))
+ && dst_surface->swapchain->front_buffer == dst_surface))
gl_info->gl_ops.gl.p_glFlush();
context_release(context);
return blitter->depth_fill(device, surface, rect, depth);
}
-static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, const RECT *src_rect,
- struct wined3d_surface *dst_surface, const RECT *dst_rect)
+static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect,
+ struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect)
{
struct wined3d_device *device = src_surface->resource.device;
dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format))
return WINED3DERR_INVALIDCALL;
- wined3d_surface_depth_blt_fbo(device, src_surface, src_rect, dst_surface, dst_rect);
+ surface_depth_blt_fbo(device, src_surface, src_location, src_rect, dst_surface, dst_location, dst_rect);
- surface_modify_ds_location(dst_surface, SFLAG_INTEXTURE,
+ surface_modify_ds_location(dst_surface, dst_location,
dst_surface->ds_current_size.cx, dst_surface->ds_current_size.cy);
return WINED3D_OK;
* locking them. */
if (dst_surface->flags & SFLAG_CONVERTED)
{
- WARN("Converted surface, using CPU blit.\n");
+ WARN_(d3d_perf)("Converted surface, using CPU blit.\n");
return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter);
}
if (flags & ~simple_blit)
{
- WARN("Using fallback for complex blit (%#x).\n", flags);
+ WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags);
goto fallback;
}
- if (src_surface && src_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- src_swapchain = src_surface->container.u.swapchain;
+ if (src_surface)
+ src_swapchain = src_surface->swapchain;
else
src_swapchain = NULL;
- if (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- dst_swapchain = dst_surface->container.u.swapchain;
- else
- dst_swapchain = NULL;
+ dst_swapchain = dst_surface->swapchain;
/* This isn't strictly needed. FBO blits for example could deal with
* cross-swapchain blits by first downloading the source to a texture
return WINED3DERR_INVALIDCALL;
}
- if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, &src_rect, dst_surface, &dst_rect)))
+ if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->draw_binding, &src_rect,
+ dst_surface, dst_surface->draw_binding, &dst_rect)))
return WINED3D_OK;
}
}
}
else
{
- if (!surface->resource.heapMemory)
- surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), 0, surface->resource.size + RESOURCE_ALIGNMENT);
+ if (!surface->resource.heap_memory)
+ surface->resource.heap_memory = wined3d_resource_allocate_sysmem(surface->resource.size);
else if (!(surface->flags & SFLAG_CLIENT))
- ERR("Surface %p has heapMemory %p and flags %#x.\n",
- surface, surface->resource.heapMemory, surface->flags);
+ ERR("Surface %p has heap_memory %p and flags %#x.\n",
+ surface, surface->resource.heap_memory, surface->flags);
- surface->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)surface->resource.heapMemory
- + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ surface->resource.allocatedMemory = surface->resource.heap_memory;
}
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
{
if (!surface->resource.allocatedMemory)
{
- if (!surface->resource.heapMemory)
+ if (!surface->resource.heap_memory)
{
- if (!(surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- surface->resource.size + RESOURCE_ALIGNMENT)))
+ surface->resource.heap_memory = wined3d_resource_allocate_sysmem(surface->resource.size);
+ if (!surface->resource.heap_memory)
{
ERR("Failed to allocate memory.\n");
return FALSE;
}
else if (!(surface->flags & SFLAG_CLIENT))
{
- ERR("Surface %p has heapMemory %p and flags %#x.\n",
- surface, surface->resource.heapMemory, surface->flags);
+ ERR("Surface %p has heap_memory %p and flags %#x.\n",
+ surface, surface->resource.heap_memory, surface->flags);
}
- surface->resource.allocatedMemory =
- (BYTE *)(((ULONG_PTR)surface->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ surface->resource.allocatedMemory = surface->resource.heap_memory;
}
else
{
/* If we're in a texture, the texture name belongs to the texture.
* Otherwise, destroy it. */
- if (surface->container.type != WINED3D_CONTAINER_TEXTURE)
+ if (!surface->container)
{
gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name);
surface->texture_name = 0;
hr = surface_create_dib_section(surface);
if (SUCCEEDED(hr))
{
- HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
- surface->resource.heapMemory = NULL;
+ wined3d_resource_free_sysmem(surface->resource.heap_memory);
+ surface->resource.heap_memory = NULL;
surface->resource.allocatedMemory = surface->dib.bitmap_data;
}
/* Update the image because of the palette change. Some games like e.g.
* Red Alert call SetEntries a lot to implement fading. */
/* Tell the swapchain to update the screen. */
- if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- {
- struct wined3d_swapchain *swapchain = surface->container.u.swapchain;
- if (surface == swapchain->front_buffer)
- {
- x11_copy_to_screen(swapchain, NULL);
- }
- }
+ if (surface->swapchain && surface == surface->swapchain->front_buffer)
+ x11_copy_to_screen(surface->swapchain, NULL);
}
static void gdi_surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD flags)
ERR("Failed to create dib section, hr %#x.\n", hr);
return;
}
- HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
- surface->resource.heapMemory = NULL;
+ wined3d_resource_free_sysmem(surface->resource.heap_memory);
+ surface->resource.heap_memory = NULL;
surface->resource.allocatedMemory = surface->dib.bitmap_data;
}
}
TRACE("surface %p.\n", surface);
/* Tell the swapchain to update the screen. */
- if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- {
- struct wined3d_swapchain *swapchain = surface->container.u.swapchain;
- if (surface == swapchain->front_buffer)
- {
- x11_copy_to_screen(swapchain, &surface->lockedRect);
- }
- }
+ if (surface->swapchain && surface == surface->swapchain->front_buffer)
+ x11_copy_to_screen(surface->swapchain, &surface->lockedRect);
memset(&surface->lockedRect, 0, sizeof(RECT));
}
src_data = mem;
dst_data = surface->resource.allocatedMemory;
TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch);
- for (y = 1; y < surface->resource.height; ++y)
+ for (y = 0; y < surface->resource.height; ++y)
{
- /* skip the first row */
+ memcpy(dst_data, src_data, dst_pitch);
src_data += src_pitch;
dst_data += dst_pitch;
- memcpy(dst_data, src_data, dst_pitch);
}
HeapFree(GetProcessHeap(), 0, mem);
if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
{
- UINT row_length = wined3d_format_calculate_size(format, 1, update_w, 1);
+ UINT row_length = wined3d_format_calculate_size(format, 1, update_w, 1, 1);
UINT row_count = (update_h + format->block_height - 1) / format->block_height;
const BYTE *addr = data->addr;
GLenum internal;
&rect, surface->resource.usage, surface->resource.pool, surface->resource.format,
&rect, surface->resource.usage, surface->resource.pool, surface->resource.format);
#endif
- blit_supported = gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM];
+ blit_supported = gl_info->supported[ARB_FRAGMENT_PROGRAM];
/* Use conversion when the blit_shader backend supports it. It only supports this in case of
* texturing. Further also use conversion in case of color keying.
static void surface_allocate_surface(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
const struct wined3d_format *format, BOOL srgb)
{
- BOOL enable_client_storage = FALSE;
+ BOOL disable_client_storage = FALSE;
GLsizei width = surface->pow2Width;
GLsizei height = surface->pow2Height;
const BYTE *mem = NULL;
* SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface
* allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively
*/
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
surface->flags &= ~SFLAG_CLIENT;
- enable_client_storage = TRUE;
}
else
{
/* Point OpenGL to our allocated texture memory. Do not use
* resource.allocatedMemory here because it might point into a
- * PBO. Instead use heapMemory, but get the alignment right. */
- mem = (BYTE *)(((ULONG_PTR)surface->resource.heapMemory
- + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ * PBO. Instead use heap_memory. */
+ mem = surface->resource.heap_memory;
+
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+ disable_client_storage = TRUE;
}
}
checkGLcall("glTexImage2D");
}
- if (enable_client_storage)
+ if (disable_client_storage)
{
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
- checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
}
}
GLenum surface_get_gl_buffer(const struct wined3d_surface *surface)
{
- const struct wined3d_swapchain *swapchain = surface->container.u.swapchain;
+ const struct wined3d_swapchain *swapchain = surface->swapchain;
TRACE("surface %p.\n", surface);
- if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN)
+ if (!swapchain)
{
ERR("Surface %p is not on a swapchain.\n", surface);
return GL_NONE;
}
/* if the container is a texture then mark it dirty. */
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
+ if (surface->container)
{
TRACE("Passing to container.\n");
- wined3d_texture_set_dirty(surface->container.u.texture, TRUE);
+ wined3d_texture_set_dirty(surface->container, TRUE);
}
}
{
ULONG refcount;
- TRACE("Surface %p, container %p of type %#x.\n",
- surface, surface->container.u.base, surface->container.type);
+ TRACE("surface %p, swapchain %p, container %p.\n",
+ surface, surface->swapchain, surface->container);
- switch (surface->container.type)
- {
- case WINED3D_CONTAINER_TEXTURE:
- return wined3d_texture_incref(surface->container.u.texture);
+ if (surface->swapchain)
+ return wined3d_swapchain_incref(surface->swapchain);
- case WINED3D_CONTAINER_SWAPCHAIN:
- return wined3d_swapchain_incref(surface->container.u.swapchain);
-
- default:
- ERR("Unhandled container type %#x.\n", surface->container.type);
- case WINED3D_CONTAINER_NONE:
- break;
- }
+ if (surface->container)
+ return wined3d_texture_incref(surface->container);
refcount = InterlockedIncrement(&surface->resource.ref);
TRACE("%p increasing refcount to %u.\n", surface, refcount);
{
ULONG refcount;
- TRACE("Surface %p, container %p of type %#x.\n",
- surface, surface->container.u.base, surface->container.type);
+ TRACE("surface %p, swapchain %p, container %p.\n",
+ surface, surface->swapchain, surface->container);
- switch (surface->container.type)
- {
- case WINED3D_CONTAINER_TEXTURE:
- return wined3d_texture_decref(surface->container.u.texture);
+ if (surface->swapchain)
+ return wined3d_swapchain_decref(surface->swapchain);
- case WINED3D_CONTAINER_SWAPCHAIN:
- return wined3d_swapchain_decref(surface->container.u.swapchain);
-
- default:
- ERR("Unhandled container type %#x.\n", surface->container.type);
- case WINED3D_CONTAINER_NONE:
- break;
- }
+ if (surface->container)
+ return wined3d_texture_decref(surface->container);
refcount = InterlockedDecrement(&surface->resource.ref);
TRACE("%p decreasing refcount to %u.\n", surface, refcount);
TRACE("surface %p.\n", surface);
+ if (surface->pitch)
+ return surface->pitch;
+
if (format->flags & WINED3DFMT_FLAG_BLOCKS)
{
/* Since compressed formats are block based, pitch means the amount of
return pitch;
}
-HRESULT CDECL wined3d_surface_set_mem(struct wined3d_surface *surface, void *mem)
+HRESULT CDECL wined3d_surface_set_mem(struct wined3d_surface *surface, void *mem, UINT pitch)
{
TRACE("surface %p, mem %p.\n", surface, mem);
}
else if (!(surface->flags & SFLAG_USERPTR))
{
- release = surface->resource.heapMemory;
- surface->resource.heapMemory = NULL;
+ release = surface->resource.heap_memory;
+ surface->resource.heap_memory = NULL;
}
surface->resource.allocatedMemory = mem;
surface->flags |= SFLAG_USERPTR;
surface_release_client_storage(surface);
/* Now free the old memory if any. */
- HeapFree(GetProcessHeap(), 0, release);
+ wined3d_resource_free_sysmem(release);
}
else if (surface->flags & SFLAG_USERPTR)
{
- /* HeapMemory should be NULL already. */
- if (surface->resource.heapMemory)
+ /* heap_memory should be NULL already. */
+ if (surface->resource.heap_memory)
ERR("User pointer surface has heap memory allocated.\n");
if (!mem)
surface_modify_location(surface, SFLAG_INSYSMEM, TRUE);
}
+ surface->pitch = pitch;
+
return WINED3D_OK;
}
struct wined3d_device *device = surface->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
- UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height);
+ UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
TRACE("surface %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u.\n",
surface, width, height, debug_d3dformat(format_id), multisample_type, multisample_type);
surface->flags &= ~(SFLAG_LOCATIONS | SFLAG_USERPTR);
surface->resource.allocatedMemory = NULL;
- HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
- surface->resource.heapMemory = NULL;
+ wined3d_resource_free_sysmem(surface->resource.heap_memory);
+ surface->resource.heap_memory = NULL;
surface->resource.width = width;
surface->resource.height = height;
unsigned int bpp, UINT pitch, DWORD color)
{
BYTE *first;
- int x, y;
+ unsigned int x, y;
/* Do first row */
/* Use the DIB section from now on if we are not using a PBO. */
if (!(surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)))
{
- HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
- surface->resource.heapMemory = NULL;
+ wined3d_resource_free_sysmem(surface->resource.heap_memory);
+ surface->resource.heap_memory = NULL;
surface->resource.allocatedMemory = surface->dib.bitmap_data;
}
}
WARN("Ignoring flags %#x.\n", flags);
}
- if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
+ if (surface->swapchain)
{
ERR("Not supported on swapchain surfaces.\n");
return WINEDDERR_NOTFLIPPABLE;
TRACE("iface %p, srgb %#x.\n", surface, srgb);
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
+ if (surface->container)
{
- struct wined3d_texture *texture = surface->container.u.texture;
+ struct wined3d_texture *texture = surface->container;
TRACE("Passing to container (%p).\n", texture);
texture->texture_ops->texture_preload(texture, srgb);
/* Context activation is done by the caller. */
void surface_prepare_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb)
{
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
+ if (surface->container)
{
- struct wined3d_texture *texture = surface->container.u.texture;
+ struct wined3d_texture *texture = surface->container;
UINT sub_count = texture->level_count * texture->layer_count;
UINT i;
}
}
-static void flush_to_framebuffer_drawpixels(struct wined3d_surface *surface,
- const RECT *rect, GLenum fmt, GLenum type, UINT bpp, const BYTE *mem)
-{
- struct wined3d_device *device = surface->resource.device;
- UINT pitch = wined3d_surface_get_pitch(surface);
- const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
- RECT local_rect;
- UINT w, h;
-
- surface_get_rect(surface, rect, &local_rect);
-
- mem += local_rect.top * pitch + local_rect.left * bpp;
- w = local_rect.right - local_rect.left;
- h = local_rect.bottom - local_rect.top;
-
- /* Activate the correct context for the render target */
- context = context_acquire(device, surface);
- context_apply_blit_state(context, device);
- gl_info = context->gl_info;
-
- if (!surface_is_offscreen(surface))
- {
- GLenum buffer = surface_get_gl_buffer(surface);
- TRACE("Unlocking %#x buffer.\n", buffer);
- context_set_draw_buffer(context, buffer);
-
- surface_translate_drawable_coords(surface, context->win_handle, &local_rect);
- gl_info->gl_ops.gl.p_glPixelZoom(1.0f, -1.0f);
- }
- else
- {
- /* Primary offscreen render target */
- TRACE("Offscreen render target.\n");
- context_set_draw_buffer(context, device->offscreenBuffer);
-
- gl_info->gl_ops.gl.p_glPixelZoom(1.0f, 1.0f);
- }
-
- gl_info->gl_ops.gl.p_glRasterPos3i(local_rect.left, local_rect.top, 1);
- checkGLcall("glRasterPos3i");
-
- /* If not fullscreen, we need to skip a number of bytes to find the next row of data */
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->resource.width);
-
- if (surface->flags & SFLAG_PBO)
- {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
- checkGLcall("glBindBufferARB");
- }
-
- gl_info->gl_ops.gl.p_glDrawPixels(w, h, fmt, type, mem);
- checkGLcall("glDrawPixels");
-
- if (surface->flags & SFLAG_PBO)
- {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
- checkGLcall("glBindBufferARB");
- }
-
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- checkGLcall("glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)");
-
- if (wined3d_settings.strict_draw_ordering
- || (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN
- && surface->container.u.swapchain->front_buffer == surface))
- gl_info->gl_ops.gl.p_glFlush();
-
- context_release(context);
-}
-
static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD color)
{
/* FIXME: Is this really how color keys are supposed to work? I think it
if (!pal)
{
- ERR("This code should never get entered for DirectDraw!, expect problems\n");
+ FIXME("No palette set.\n");
if (index_in_alpha)
{
/* Guarantees that memory representation remains correct after sysmem<->texture transfers even if
front->resource.allocatedMemory = back->resource.allocatedMemory;
back->resource.allocatedMemory = tmp;
- tmp = front->resource.heapMemory;
- front->resource.heapMemory = back->resource.heapMemory;
- back->resource.heapMemory = tmp;
+ tmp = front->resource.heap_memory;
+ front->resource.heap_memory = back->resource.heap_memory;
+ back->resource.heap_memory = tmp;
}
/* Flip the PBO */
struct wined3d_device *device = dst_surface->resource.device;
const struct wined3d_gl_info *gl_info;
float xrel, yrel;
- UINT row;
struct wined3d_context *context;
BOOL upsidedown = FALSE;
RECT dst_rect = *dst_rect_in;
GLenum dst_target;
- if (dst_surface->container.type == WINED3D_CONTAINER_TEXTURE)
- dst_target = dst_surface->container.u.texture->target;
+ if (dst_surface->container)
+ dst_target = dst_surface->container->target;
else
dst_target = dst_surface->texture_target;
}
else
{
+ LONG row;
UINT yoffset = src_surface->resource.height - src_rect->top + dst_rect.top - 1;
/* I have to process this row by row to swap the image,
* otherwise it would be upside down, so stretching in y direction
/* Well, that stuff works, but it's very slow.
* find a better way instead
*/
- UINT col;
+ LONG col;
for (col = dst_rect.left; col < dst_rect.right; ++col)
{
const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter)
{
struct wined3d_device *device = dst_surface->resource.device;
- struct wined3d_swapchain *src_swapchain = NULL;
GLuint src, backup = 0;
float left, right, top, bottom; /* Texture coordinates */
UINT fbwidth = src_surface->resource.width;
wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE));
checkGLcall("glTexParameteri");
- if (src_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- src_swapchain = src_surface->container.u.swapchain;
- if (!src_swapchain || src_surface == src_swapchain->back_buffers[0])
+ if (!src_surface->swapchain || src_surface == src_surface->swapchain->back_buffers[0])
{
src = backup ? backup : src_surface->texture_name;
}
{
UINT drawable_height;
- if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN
- && surface == surface->container.u.swapchain->front_buffer)
+ if (surface->swapchain && surface == surface->swapchain->front_buffer)
{
POINT offset = {0, 0};
RECT windowsize;
device->blitter->unset_shader(context->gl_info);
if (wined3d_settings.strict_draw_ordering
- || (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN
- && (dst_surface->container.u.swapchain->front_buffer == dst_surface)))
+ || (dst_surface->swapchain && dst_surface->swapchain->front_buffer == dst_surface))
gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
{
struct wined3d_device *device = dst_surface->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- struct wined3d_swapchain *srcSwapchain = NULL, *dstSwapchain = NULL;
+ struct wined3d_swapchain *src_swapchain, *dst_swapchain;
TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n",
dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect),
return WINED3DERR_INVALIDCALL;
}
- if (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- dstSwapchain = dst_surface->container.u.swapchain;
+ dst_swapchain = dst_surface->swapchain;
if (src_surface)
{
return WINED3DERR_INVALIDCALL;
}
- if (src_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- srcSwapchain = src_surface->container.u.swapchain;
+ src_swapchain = src_surface->swapchain;
+ }
+ else
+ {
+ src_swapchain = NULL;
}
/* Early sort out of cases where no render target is used */
- if (!dstSwapchain && !srcSwapchain
+ if (!dst_swapchain && !src_swapchain
&& src_surface != device->fb.render_targets[0]
&& dst_surface != device->fb.render_targets[0])
{
return WINED3DERR_INVALIDCALL;
}
- if (dstSwapchain && dstSwapchain == srcSwapchain)
+ if (dst_swapchain && dst_swapchain == src_swapchain)
{
FIXME("Implement hardware blit between two surfaces on the same swapchain\n");
return WINED3DERR_INVALIDCALL;
}
- if (dstSwapchain && srcSwapchain)
+ if (dst_swapchain && src_swapchain)
{
FIXME("Implement hardware blit between two different swapchains\n");
return WINED3DERR_INVALIDCALL;
}
- if (dstSwapchain)
+ if (dst_swapchain)
{
/* Handled with regular texture -> swapchain blit */
if (src_surface == device->fb.render_targets[0])
TRACE("Blit from active render target to a swapchain\n");
}
- else if (srcSwapchain && dst_surface == device->fb.render_targets[0])
+ else if (src_swapchain && dst_surface == device->fb.render_targets[0])
{
FIXME("Implement blit from a swapchain to the active render target\n");
return WINED3DERR_INVALIDCALL;
}
- if ((srcSwapchain || src_surface == device->fb.render_targets[0]) && !dstSwapchain)
+ if ((src_swapchain || src_surface == device->fb.render_targets[0]) && !dst_swapchain)
{
/* Blit from render target to texture */
BOOL stretchx;
if (!dst_surface->resource.map_count && !(dst_surface->flags & SFLAG_DONOTFREE))
{
- HeapFree(GetProcessHeap(), 0, dst_surface->resource.heapMemory);
+ wined3d_resource_free_sysmem(dst_surface->resource.heap_memory);
dst_surface->resource.allocatedMemory = NULL;
- dst_surface->resource.heapMemory = NULL;
+ dst_surface->resource.heap_memory = NULL;
}
else
{
if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE))
|| (!(surface->flags & SFLAG_INTEXTURE) && (location & SFLAG_INTEXTURE)))
{
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
+ if (surface->container)
{
TRACE("Passing to container.\n");
- wined3d_texture_set_dirty(surface->container.u.texture, TRUE);
+ wined3d_texture_set_dirty(surface->container, TRUE);
}
}
context_apply_fbo_state_blit(context, GL_FRAMEBUFFER,
NULL, surface, SFLAG_INTEXTURE);
context_set_draw_buffer(context, GL_NONE);
- gl_info->gl_ops.gl.p_glReadBuffer(GL_NONE);
/* Do the actual blit */
surface_depth_blt(surface, context, device->depth_blt_texture, 0, 0, w, h, bind_target);
if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE))
|| ((surface->flags & SFLAG_INSRGBTEX) && !(location & SFLAG_INSRGBTEX)))
{
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
+ if (surface->container)
{
TRACE("Passing to container.\n");
- wined3d_texture_set_dirty(surface->container.u.texture, TRUE);
+ wined3d_texture_set_dirty(surface->container, TRUE);
}
}
surface->flags &= ~SFLAG_LOCATIONS;
{
if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (location & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)))
{
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
+ if (surface->container)
{
TRACE("Passing to container\n");
- wined3d_texture_set_dirty(surface->container.u.texture, TRUE);
+ wined3d_texture_set_dirty(surface->container, TRUE);
}
}
surface->flags &= ~location;
static HRESULT surface_load_drawable(struct wined3d_surface *surface,
const struct wined3d_gl_info *gl_info, const RECT *rect)
{
- struct wined3d_device *device = surface->resource.device;
- enum wined3d_conversion_type convert;
- struct wined3d_format format;
- UINT byte_count;
- BYTE *mem;
+ RECT r;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && surface_is_offscreen(surface))
{
return WINED3DERR_INVALIDCALL;
}
- if (wined3d_settings.rendertargetlock_mode == RTL_READTEX)
- surface_load_location(surface, SFLAG_INTEXTURE, NULL);
-
- if (surface->flags & SFLAG_INTEXTURE)
- {
- RECT r;
-
- surface_get_rect(surface, rect, &r);
- surface_blt_to_drawable(device, WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r);
-
- return WINED3D_OK;
- }
-
- if ((surface->flags & SFLAG_LOCATIONS) == SFLAG_INSRGBTEX)
- {
- /* This needs colorspace conversion from sRGB to RGB. We take the slow
- * path through sysmem. */
- surface_load_location(surface, SFLAG_INSYSMEM, rect);
- }
-
- d3dfmt_get_conv(surface, FALSE, FALSE, &format, &convert);
-
- /* Don't use PBOs for converted surfaces. During PBO conversion we look at
- * SFLAG_CONVERTED but it isn't set (yet) in all cases where it is getting
- * called. */
- if ((convert != WINED3D_CT_NONE) && (surface->flags & SFLAG_PBO))
- {
- struct wined3d_context *context;
-
- TRACE("Removing the pbo attached to surface %p.\n", surface);
-
- /* TODO: Use already acquired context when possible. */
- context = context_acquire(device, NULL);
-
- surface_remove_pbo(surface, gl_info);
-
- context_release(context);
- }
-
- if ((convert != WINED3D_CT_NONE) && surface->resource.allocatedMemory)
- {
- UINT height = surface->resource.height;
- UINT width = surface->resource.width;
- UINT src_pitch, dst_pitch;
-
- byte_count = format.conv_byte_count;
- src_pitch = wined3d_surface_get_pitch(surface);
-
- /* Stick to the alignment for the converted surface too, makes it
- * easier to load the surface. */
- dst_pitch = width * byte_count;
- dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
-
- if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
- {
- ERR("Out of memory (%u).\n", dst_pitch * height);
- return E_OUTOFMEMORY;
- }
-
- d3dfmt_convert_surface(surface->resource.allocatedMemory, mem,
- src_pitch, width, height, dst_pitch, convert, surface);
-
- surface->flags |= SFLAG_CONVERTED;
- }
- else
- {
- surface->flags &= ~SFLAG_CONVERTED;
- mem = surface->resource.allocatedMemory;
- byte_count = format.byte_count;
- }
-
- flush_to_framebuffer_drawpixels(surface, rect, format.glFormat, format.glType, byte_count, mem);
-
- /* Don't delete PBO memory. */
- if ((mem != surface->resource.allocatedMemory) && !(surface->flags & SFLAG_PBO))
- HeapFree(GetProcessHeap(), 0, mem);
+ surface_get_rect(surface, rect, &r);
+ surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+ surface_blt_to_drawable(surface->resource.device,
+ WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r);
return WINED3D_OK;
}
if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
{
- if (location == SFLAG_INTEXTURE)
+ if (location == SFLAG_INTEXTURE && surface->flags & SFLAG_INDRAWABLE)
{
struct wined3d_context *context = context_acquire(device, NULL);
surface_load_ds_location(surface, context, location);
context_release(context);
return WINED3D_OK;
}
+ else if (location & surface->flags && surface->draw_binding != SFLAG_INDRAWABLE)
+ {
+ /* Already up to date, nothing to do. */
+ return WINED3D_OK;
+ }
else
{
- FIXME("Unimplemented location %s for depth/stencil buffers.\n", debug_surflocation(location));
+ FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n",
+ debug_surflocation(surface->flags & SFLAG_LOCATIONS), debug_surflocation(location));
return WINED3DERR_INVALIDCALL;
}
}
BOOL surface_is_offscreen(const struct wined3d_surface *surface)
{
- struct wined3d_swapchain *swapchain = surface->container.u.swapchain;
+ struct wined3d_swapchain *swapchain;
/* Not on a swapchain - must be offscreen */
- if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN) return TRUE;
+ if (!(swapchain = surface->swapchain))
+ return TRUE;
/* The front buffer is always onscreen */
if (surface == swapchain->front_buffer) return FALSE;
/* Context activation is done by the caller. */
static void ffp_blit_free(struct wined3d_device *device) { }
-/* This function is used in case of 8bit paletted textures using GL_EXT_paletted_texture */
-/* Context activation is done by the caller. */
-static void ffp_blit_p8_upload_palette(const struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
-{
- BYTE table[256][4];
- BOOL colorkey_active = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) != 0;
- GLenum target;
-
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
- target = surface->container.u.texture->target;
- else
- target = surface->texture_target;
-
- d3dfmt_p8_init_palette(surface, table, colorkey_active);
-
- TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n");
- GL_EXTCALL(glColorTableEXT(target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table));
-}
-
/* Context activation is done by the caller. */
static HRESULT ffp_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface)
{
- enum complex_fixup fixup = get_complex_fixup(surface->resource.format->color_fixup);
const struct wined3d_gl_info *gl_info = context->gl_info;
GLenum target;
- if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
- target = surface->container.u.texture->target;
+ if (surface->container)
+ target = surface->container->target;
else
target = surface->texture_target;
- /* When EXT_PALETTED_TEXTURE is around, palette conversion is done by the GPU
- * else the surface is converted in software at upload time in LoadLocation.
- */
- if (!(surface->flags & SFLAG_CONVERTED) && fixup == COMPLEX_FIXUP_P8
- && gl_info->supported[EXT_PALETTED_TEXTURE])
- ffp_blit_p8_upload_palette(surface, gl_info);
-
gl_info->gl_ops.gl.p_glEnable(target);
checkGLcall("glEnable(target)");
const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
{
- enum complex_fixup src_fixup;
-
switch (blit_op)
{
case WINED3D_BLIT_OP_COLOR_BLIT:
if (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM)
return FALSE;
- src_fixup = get_complex_fixup(src_format->color_fixup);
if (TRACE_ON(d3d_surface) && TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(src_format->color_fixup);
}
- if (!is_identity_fixup(dst_format->color_fixup))
- {
- TRACE("Destination fixups are not supported\n");
- return FALSE;
- }
-
- if (src_fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE])
- {
- TRACE("P8 fixup supported\n");
- return TRUE;
- }
-
/* We only support identity conversions. */
- if (is_identity_fixup(src_format->color_fixup))
+ if (!is_identity_fixup(src_format->color_fixup)
+ || !is_identity_fixup(dst_format->color_fixup))
{
- TRACE("[OK]\n");
- return TRUE;
+ TRACE("Fixups are not supported.\n");
+ return FALSE;
}
- TRACE("[FAILED]\n");
- return FALSE;
+ return TRUE;
case WINED3D_BLIT_OP_COLOR_FILL:
if (dst_pool == WINED3D_POOL_SYSTEM_MEM)
/* FIXME: Check that the format is supported by the device. */
- resource_size = wined3d_format_calculate_size(format, alignment, width, height);
+ resource_size = wined3d_format_calculate_size(format, alignment, width, height, 1);
if (!resource_size)
return WINED3DERR_INVALIDCALL;
}
/* "Standalone" surface. */
- surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL);
+ surface_set_container(surface, NULL);
list_init(&surface->overlays);
if ((usage & WINED3DUSAGE_OWNDC) && !surface->hDC
&& SUCCEEDED(surface_create_dib_section(surface)))
{
- HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
- surface->resource.heapMemory = NULL;
+ wined3d_resource_free_sysmem(surface->resource.heap_memory);
+ surface->resource.heap_memory = NULL;
surface->resource.allocatedMemory = surface->dib.bitmap_data;
}
/* Do not call while under the GL lock. */
static void swapchain_cleanup(struct wined3d_swapchain *swapchain)
{
- struct wined3d_display_mode mode;
HRESULT hr;
UINT i;
* is the last buffer to be destroyed, FindContext() depends on that. */
if (swapchain->front_buffer)
{
- if (swapchain->front_buffer->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL);
+ surface_set_swapchain(swapchain->front_buffer, NULL);
if (wined3d_surface_decref(swapchain->front_buffer))
WARN("Something's still holding the front buffer (%p).\n", swapchain->front_buffer);
swapchain->front_buffer = NULL;
while (i--)
{
- if (swapchain->back_buffers[i]->container.type == WINED3D_CONTAINER_SWAPCHAIN)
- surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_NONE, NULL);
+ surface_set_swapchain(swapchain->back_buffers[i], NULL);
if (wined3d_surface_decref(swapchain->back_buffers[i]))
WARN("Something's still holding back buffer %u (%p).\n", i, swapchain->back_buffers[i]);
}
* orig_height will be equal to the modes in the presentation params. */
if (!swapchain->desc.windowed && swapchain->desc.auto_restore_display_mode)
{
- mode.width = swapchain->orig_width;
- mode.height = swapchain->orig_height;
- mode.refresh_rate = 0;
- mode.format_id = swapchain->orig_fmt;
- mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
if (FAILED(hr = wined3d_set_adapter_display_mode(swapchain->device->wined3d,
- swapchain->device->adapter->ordinal, &mode)))
+ swapchain->device->adapter->ordinal, &swapchain->original_mode)))
ERR("Failed to restore display mode, hr %#x.\n", hr);
}
front->resource.allocatedMemory = back->resource.allocatedMemory;
back->resource.allocatedMemory = tmp;
- if (front->resource.heapMemory)
+ if (front->resource.heap_memory)
ERR("GDI Surface %p has heap memory allocated.\n", front);
- if (back->resource.heapMemory)
+ if (back->resource.heap_memory)
ERR("GDI Surface %p has heap memory allocated.\n", back);
}
struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_adapter *adapter = device->adapter;
- const struct wined3d_format *format;
- struct wined3d_display_mode mode;
+ struct wined3d_resource_desc surface_desc;
BOOL displaymode_set = FALSE;
RECT client_rect;
HWND window;
swapchain->win_handle = window;
swapchain->device_window = window;
- wined3d_get_adapter_display_mode(device->wined3d, adapter->ordinal, &mode, NULL);
- swapchain->orig_width = mode.width;
- swapchain->orig_height = mode.height;
- swapchain->orig_fmt = mode.format_id;
- format = wined3d_get_format(&adapter->gl_info, mode.format_id);
+ if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d,
+ adapter->ordinal, &swapchain->original_mode, NULL)))
+ {
+ ERR("Failed to get current display mode, hr %#x.\n", hr);
+ goto err;
+ }
GetClientRect(window, &client_rect);
if (desc->windowed
if (desc->backbuffer_format == WINED3DFMT_UNKNOWN)
{
- desc->backbuffer_format = swapchain->orig_fmt;
- TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->orig_fmt));
+ desc->backbuffer_format = swapchain->original_mode.format_id;
+ TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->original_mode.format_id));
}
}
swapchain->desc = *desc;
swapchain_update_render_to_fbo(swapchain);
TRACE("Creating front buffer.\n");
- if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent, parent,
- swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height,
- swapchain->desc.backbuffer_format, WINED3DUSAGE_RENDERTARGET,
- swapchain->desc.multisample_type, swapchain->desc.multisample_quality,
- &swapchain->front_buffer)))
+
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
+ 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.pool = WINED3D_POOL_DEFAULT;
+ surface_desc.width = swapchain->desc.backbuffer_width;
+ surface_desc.height = swapchain->desc.backbuffer_height;
+ surface_desc.depth = 1;
+ surface_desc.size = 0;
+
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
+ parent, &surface_desc, &swapchain->front_buffer)))
{
WARN("Failed to create front buffer, hr %#x.\n", hr);
goto err;
}
- if (swapchain->front_buffer->container.type == WINED3D_CONTAINER_NONE)
- surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_SWAPCHAIN, swapchain);
+ surface_set_swapchain(swapchain->front_buffer, swapchain);
if (!(device->wined3d->flags & WINED3D_NO3D))
surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE);
mode.refresh_rate = desc->refresh_rate;
mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
- if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, device->adapter->ordinal, &mode)))
+ if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &mode)))
{
WARN("Failed to set display mode, hr %#x.\n", hr);
goto err;
WINED3DFMT_S1_UINT_D15_UNORM
};
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_gl_info *gl_info = &adapter->gl_info;
swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context));
if (!swapchain->context)
for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
{
TRACE("Creating back buffer %u.\n", i);
- if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent, parent,
- swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height,
- swapchain->desc.backbuffer_format, WINED3DUSAGE_RENDERTARGET,
- swapchain->desc.multisample_type, swapchain->desc.multisample_quality,
- &swapchain->back_buffers[i])))
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
+ parent, &surface_desc, &swapchain->back_buffers[i])))
{
WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
goto err;
}
- if (swapchain->back_buffers[i]->container.type == WINED3D_CONTAINER_NONE)
- surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_SWAPCHAIN, swapchain);
+ surface_set_swapchain(swapchain->back_buffers[i], swapchain);
}
}
TRACE("Creating depth/stencil buffer.\n");
if (!device->auto_depth_stencil)
{
+ surface_desc.format = swapchain->desc.auto_depth_stencil_format;
+ surface_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
+
if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
- device->device_parent, swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height,
- swapchain->desc.auto_depth_stencil_format, WINED3DUSAGE_DEPTHSTENCIL,
- swapchain->desc.multisample_type, swapchain->desc.multisample_quality,
- &device->auto_depth_stencil)))
+ device->device_parent, &surface_desc, &device->auto_depth_stencil)))
{
WARN("Failed to create the auto depth stencil, hr %#x.\n", hr);
goto err;
}
-
- surface_set_container(device->auto_depth_stencil, WINED3D_CONTAINER_NONE, NULL);
}
}
err:
if (displaymode_set)
{
- DEVMODEW devmode;
-
+ if (FAILED(wined3d_set_adapter_display_mode(device->wined3d,
+ adapter->ordinal, &swapchain->original_mode)))
+ ERR("Failed to restore display mode.\n");
ClipCursor(NULL);
-
- /* Change the display settings */
- memset(&devmode, 0, sizeof(devmode));
- devmode.dmSize = sizeof(devmode);
- devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- devmode.dmBitsPerPel = format->byte_count * CHAR_BIT;
- devmode.dmPelsWidth = swapchain->orig_width;
- devmode.dmPelsHeight = swapchain->orig_height;
- ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
}
if (swapchain->back_buffers)
{
if (swapchain->back_buffers[i])
{
- surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_NONE, NULL);
+ surface_set_swapchain(swapchain->back_buffers[i], NULL);
wined3d_surface_decref(swapchain->back_buffers[i]);
}
}
if (swapchain->front_buffer)
{
- surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL);
+ surface_set_swapchain(swapchain->front_buffer, NULL);
wined3d_surface_decref(swapchain->front_buffer);
}
* Copyright 2002-2005 Jason Edmeades
* Copyright 2002-2005 Raphael Junqueira
* Copyright 2005 Oliver Stieber
- * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2007-2009, 2013 Stefan Dösinger for CodeWeavers
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops,
- UINT layer_count, UINT level_count, enum wined3d_resource_type resource_type, struct wined3d_device *device,
- DWORD usage, const struct wined3d_format *format, enum wined3d_pool pool, void *parent,
- const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops)
+ UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, struct wined3d_device *device,
+ void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops)
{
+ const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format);
HRESULT hr;
- hr = resource_init(&texture->resource, device, resource_type, format,
- WINED3D_MULTISAMPLE_NONE, 0, usage, pool, 0, 0, 0, 0,
- parent, parent_ops, resource_ops);
- if (FAILED(hr))
+ TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
+ "multisample_type %#x, multisample_quality %#x, usage %s, pool %s, width %u, height %u, depth %u, "
+ "device %p, parent %p, parent_ops %p, resource_ops %p.\n",
+ texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type),
+ debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality,
+ debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth,
+ device, parent, parent_ops, resource_ops);
+
+ 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)))
{
WARN("Failed to initialize resource, returning %#x\n", hr);
return hr;
texture->layer_count = layer_count;
texture->level_count = level_count;
- texture->filter_type = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE;
+ 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;
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, WINED3D_CONTAINER_NONE, NULL);
+ surface_set_container(surface, NULL);
wined3d_surface_decref(surface);
}
texture2d_unload,
};
-static HRESULT cubetexture_init(struct wined3d_texture *texture, UINT edge_length, UINT levels,
- struct wined3d_device *device, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool,
- void *parent, const struct wined3d_parent_ops *parent_ops)
+static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+ UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent,
+ const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
- UINT pow2_edge_length;
+ struct wined3d_resource_desc surface_desc;
unsigned int i, j;
- UINT tmp_w;
HRESULT hr;
/* TODO: It should only be possible to create textures for formats
* that are reported as supported. */
- if (WINED3DFMT_UNKNOWN >= format_id)
+ if (WINED3DFMT_UNKNOWN >= desc->format)
{
WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
return WINED3DERR_INVALIDCALL;
}
- if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP] && pool != WINED3D_POOL_SCRATCH)
+ if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP] && desc->pool != WINED3D_POOL_SCRATCH)
{
WARN("(%p) : Tried to create not supported cube texture.\n", texture);
return WINED3DERR_INVALIDCALL;
}
/* Calculate levels for mip mapping */
- if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
+ if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
{
if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
{
}
else if (!levels)
{
- levels = wined3d_log2i(edge_length) + 1;
+ levels = wined3d_log2i(desc->width) + 1;
TRACE("Calculated levels = %u.\n", levels);
}
- hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels,
- WINED3D_RTYPE_CUBE_TEXTURE, device, usage, format, pool,
- parent, parent_ops, &texture2d_resource_ops);
- if (FAILED(hr))
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
{
- WARN("Failed to initialize texture, returning %#x\n", hr);
- return hr;
- }
-
- /* Find the nearest pow2 match. */
- pow2_edge_length = 1;
- while (pow2_edge_length < edge_length) pow2_edge_length <<= 1;
+ UINT pow2_edge_length = 1;
+ while (pow2_edge_length < desc->width)
+ pow2_edge_length <<= 1;
- if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || (edge_length == pow2_edge_length))
- {
- /* Precalculated scaling for 'faked' non power of two texture coords. */
- texture->pow2_matrix[0] = 1.0f;
- texture->pow2_matrix[5] = 1.0f;
- texture->pow2_matrix[10] = 1.0f;
- texture->pow2_matrix[15] = 1.0f;
+ if (desc->width != pow2_edge_length)
+ {
+ if (desc->pool == WINED3D_POOL_SCRATCH)
+ {
+ /* SCRATCH textures cannot be used for texturing */
+ WARN("Creating a scratch NPOT cube texture despite lack of HW support.\n");
+ }
+ else
+ {
+ WARN("Attempted to create a NPOT cube texture (edge length %u) without GL support.\n", desc->width);
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
}
- else
+
+ if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels,
+ desc, device, parent, parent_ops, &texture2d_resource_ops)))
{
- /* Precalculated scaling for 'faked' non power of two texture coords. */
- texture->pow2_matrix[0] = ((float)edge_length) / ((float)pow2_edge_length);
- texture->pow2_matrix[5] = ((float)edge_length) / ((float)pow2_edge_length);
- texture->pow2_matrix[10] = ((float)edge_length) / ((float)pow2_edge_length);
- texture->pow2_matrix[15] = 1.0f;
- texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
+ WARN("Failed to initialize texture, returning %#x\n", hr);
+ return hr;
}
+
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
+ texture->pow2_matrix[10] = 1.0f;
+ texture->pow2_matrix[15] = 1.0f;
texture->target = GL_TEXTURE_CUBE_MAP_ARB;
/* Generate all the surfaces. */
- tmp_w = edge_length;
+ surface_desc = *desc;
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
for (i = 0; i < texture->level_count; ++i)
{
/* Create the 6 faces. */
struct wined3d_surface *surface;
if (FAILED(hr = device->device_parent->ops->create_texture_surface(device->device_parent,
- parent, tmp_w, tmp_w, format_id, usage, pool, idx, &surface)))
+ parent, &surface_desc, idx, surface_flags, &surface)))
{
FIXME("(%p) Failed to create surface, hr %#x.\n", texture, hr);
wined3d_texture_cleanup(texture);
return hr;
}
- surface_set_container(surface, WINED3D_CONTAINER_TEXTURE, texture);
+ 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);
}
- tmp_w = max(1, tmp_w >> 1);
+ surface_desc.width = max(1, surface_desc.width >> 1);
+ surface_desc.height = surface_desc.width;
}
return WINED3D_OK;
}
-static HRESULT texture_init(struct wined3d_texture *texture, UINT width, UINT height, UINT levels,
- struct wined3d_device *device, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool,
- void *parent, const struct wined3d_parent_ops *parent_ops)
+static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+ UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent,
+ const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
+ struct wined3d_resource_desc surface_desc;
UINT pow2_width, pow2_height;
- UINT tmp_w, tmp_h;
unsigned int i;
HRESULT hr;
/* TODO: It should only be possible to create textures for formats
* that are reported as supported. */
- if (WINED3DFMT_UNKNOWN >= format_id)
+ if (WINED3DFMT_UNKNOWN >= desc->format)
{
WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
return WINED3DERR_INVALIDCALL;
/* Non-power2 support. */
if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
{
- pow2_width = width;
- pow2_height = height;
+ pow2_width = desc->width;
+ pow2_height = desc->height;
}
else
{
/* Find the nearest pow2 match. */
pow2_width = pow2_height = 1;
- while (pow2_width < width) pow2_width <<= 1;
- while (pow2_height < height) pow2_height <<= 1;
+ while (pow2_width < desc->width)
+ pow2_width <<= 1;
+ while (pow2_height < desc->height)
+ pow2_height <<= 1;
- if (pow2_width != width || pow2_height != height)
+ if (pow2_width != desc->width || pow2_height != desc->height)
{
- if (levels > 1)
+ /* levels == 0 returns an error as well */
+ if (levels != 1)
{
- WARN("Attempted to create a mipmapped np2 texture without unconditional np2 support.\n");
- return WINED3DERR_INVALIDCALL;
+ if (desc->pool == WINED3D_POOL_SCRATCH)
+ {
+ WARN("Creating a scratch mipmapped NPOT texture despite lack of HW support.\n");
+ }
+ else
+ {
+ WARN("Attempted to create a mipmapped NPOT texture without unconditional NPOT support.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
}
- levels = 1;
}
}
/* Calculate levels for mip mapping. */
- if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
+ if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
{
if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
{
}
else if (!levels)
{
- levels = wined3d_log2i(max(width, height)) + 1;
+ levels = wined3d_log2i(max(desc->width, desc->height)) + 1;
TRACE("Calculated levels = %u.\n", levels);
}
- hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels,
- WINED3D_RTYPE_TEXTURE, device, usage, format, pool,
- parent, parent_ops, &texture2d_resource_ops);
- if (FAILED(hr))
+ if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels,
+ desc, device, parent, parent_ops, &texture2d_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
return hr;
}
- /* Precalculated scaling for 'faked' non power of two texture coords.
- * Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
- * is used in combination with texture uploads (RTL_READTEX). The reason is that EXT_PALETTED_TEXTURE
- * doesn't work in combination with ARB_TEXTURE_RECTANGLE. */
- if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] && (width != pow2_width || height != pow2_height))
+ /* Precalculated scaling for 'faked' non power of two texture coords. */
+ if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]
+ && (desc->width != pow2_width || desc->height != pow2_height))
{
texture->pow2_matrix[0] = 1.0f;
texture->pow2_matrix[5] = 1.0f;
texture->flags |= WINED3D_TEXTURE_COND_NP2;
texture->min_mip_lookup = minMipLookup_noFilter;
}
- else if (gl_info->supported[ARB_TEXTURE_RECTANGLE] && (width != pow2_width || height != pow2_height)
- && !(format->id == WINED3DFMT_P8_UINT && gl_info->supported[EXT_PALETTED_TEXTURE]
- && wined3d_settings.rendertargetlock_mode == RTL_READTEX))
+ else if (gl_info->supported[ARB_TEXTURE_RECTANGLE]
+ && (desc->width != pow2_width || desc->height != pow2_height))
{
- if (width != 1 || height != 1)
- texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
-
- texture->pow2_matrix[0] = (float)width;
- texture->pow2_matrix[5] = (float)height;
+ texture->pow2_matrix[0] = (float)desc->width;
+ texture->pow2_matrix[5] = (float)desc->height;
texture->pow2_matrix[10] = 1.0f;
texture->pow2_matrix[15] = 1.0f;
texture->target = GL_TEXTURE_RECTANGLE_ARB;
texture->flags |= WINED3D_TEXTURE_COND_NP2;
+ texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING)
texture->min_mip_lookup = minMipLookup_noMip;
}
else
{
- if ((width != pow2_width) || (height != pow2_height))
+ if ((desc->width != pow2_width) || (desc->height != pow2_height))
{
- texture->pow2_matrix[0] = (((float)width) / ((float)pow2_width));
- texture->pow2_matrix[5] = (((float)height) / ((float)pow2_height));
+ texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
+ texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
}
else
TRACE("xf(%f) yf(%f)\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
/* Generate all the surfaces. */
- tmp_w = width;
- tmp_h = height;
+ surface_desc = *desc;
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
for (i = 0; i < texture->level_count; ++i)
{
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, tmp_w, tmp_h, format->id, usage, pool, i, &surface)))
+ parent, &surface_desc, i, surface_flags, &surface)))
{
FIXME("Failed to create surface %p, hr %#x\n", texture, hr);
wined3d_texture_cleanup(texture);
return hr;
}
- surface_set_container(surface, WINED3D_CONTAINER_TEXTURE, texture);
+ 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);
/* Calculate the next mipmap level. */
- tmp_w = max(1, tmp_w >> 1);
- tmp_h = max(1, tmp_h >> 1);
+ surface_desc.width = max(1, surface_desc.width >> 1);
+ surface_desc.height = max(1, surface_desc.height >> 1);
}
return WINED3D_OK;
/* 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;
- struct wined3d_context *context;
- BOOL srgb_was_toggled = FALSE;
- unsigned int i;
+ 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);
- /* TODO: Use already acquired context when possible. */
- context = context_acquire(device, NULL);
- if (texture->resource.bind_count > 0)
+ srgb_mode = texture_srgb_mode(texture, srgb);
+ gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, srgb_mode);
+
+ if (gl_tex->dirty)
{
- BOOL texture_srgb = texture->flags & WINED3D_TEXTURE_IS_SRGB;
- BOOL sampler_srgb = texture_srgb_mode(texture, srgb);
- srgb_was_toggled = !texture_srgb != !sampler_srgb;
+ context = context_acquire(device, NULL);
- if (srgb_was_toggled)
+ /* Reload the surfaces if the texture is marked dirty. */
+ for (i = 0; i < sub_count; ++i)
{
- if (sampler_srgb)
- texture->flags |= WINED3D_TEXTURE_IS_SRGB;
- else
- texture->flags &= ~WINED3D_TEXTURE_IS_SRGB;
+ wined3d_volume_load(volume_from_resource(texture->sub_resources[i]), context,
+ srgb_mode);
}
- }
- /* If the texture is marked dirty or the sRGB sampler setting has changed
- * since the last load then reload the volumes. */
- if (texture->texture_rgb.dirty)
- {
- for (i = 0; i < texture->level_count; ++i)
- {
- volume_load(volume_from_resource(texture->sub_resources[i]), context, i,
- texture->flags & WINED3D_TEXTURE_IS_SRGB);
- }
- }
- else if (srgb_was_toggled)
- {
- for (i = 0; i < texture->level_count; ++i)
- {
- struct wined3d_volume *volume = volume_from_resource(texture->sub_resources[i]);
- volume_add_dirty_box(volume, NULL);
- volume_load(volume, context, i, texture->flags & WINED3D_TEXTURE_IS_SRGB);
- }
+ context_release(context);
}
else
{
TRACE("Texture %p not dirty, nothing to do.\n", texture);
}
- context_release(context);
-
- /* No longer dirty */
- texture->texture_rgb.dirty = FALSE;
+ /* No longer dirty. */
+ gl_tex->dirty = FALSE;
}
static void texture3d_sub_resource_add_dirty_region(struct wined3d_resource *sub_resource,
const struct wined3d_box *dirty_region)
{
- volume_add_dirty_box(volume_from_resource(sub_resource), dirty_region);
}
static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource)
texture3d_unload,
};
-static HRESULT volumetexture_init(struct wined3d_texture *texture, UINT width, UINT height,
- UINT depth, UINT levels, struct wined3d_device *device, DWORD usage, enum wined3d_format_id format_id,
- enum wined3d_pool pool, void *parent, const struct wined3d_parent_ops *parent_ops)
+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;
- const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
UINT tmp_w, tmp_h, tmp_d;
unsigned int i;
HRESULT hr;
/* TODO: It should only be possible to create textures for formats
* that are reported as supported. */
- if (WINED3DFMT_UNKNOWN >= format_id)
+ if (WINED3DFMT_UNKNOWN >= desc->format)
{
WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
return WINED3DERR_INVALIDCALL;
}
/* Calculate levels for mip mapping. */
- if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
+ if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
{
if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
{
}
else if (!levels)
{
- levels = wined3d_log2i(max(max(width, height), depth)) + 1;
+ levels = wined3d_log2i(max(max(desc->width, desc->height), desc->depth)) + 1;
TRACE("Calculated levels = %u.\n", levels);
}
- hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels,
- WINED3D_RTYPE_VOLUME_TEXTURE, device, usage, format, pool,
- parent, parent_ops, &texture3d_resource_ops);
- if (FAILED(hr))
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ UINT pow2_w, pow2_h, pow2_d;
+ pow2_w = 1;
+ while (pow2_w < desc->width)
+ pow2_w <<= 1;
+ pow2_h = 1;
+ while (pow2_h < desc->height)
+ pow2_h <<= 1;
+ pow2_d = 1;
+ while (pow2_d < desc->depth)
+ pow2_d <<= 1;
+
+ if (pow2_w != desc->width || pow2_h != desc->height || pow2_d != desc->depth)
+ {
+ if (desc->pool == WINED3D_POOL_SCRATCH)
+ {
+ WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n");
+ }
+ else
+ {
+ WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n",
+ desc->width, desc->height, desc->depth);
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+ }
+
+ if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels,
+ desc, device, parent, parent_ops, &texture3d_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
return hr;
}
- /* Is NP2 support for volumes needed? */
texture->pow2_matrix[0] = 1.0f;
texture->pow2_matrix[5] = 1.0f;
texture->pow2_matrix[10] = 1.0f;
texture->target = GL_TEXTURE_3D;
/* Generate all the surfaces. */
- tmp_w = width;
- tmp_h = height;
- tmp_d = depth;
+ tmp_w = desc->width;
+ tmp_h = desc->height;
+ tmp_d = desc->depth;
for (i = 0; i < texture->level_count; ++i)
{
/* Create the volume. */
hr = device->device_parent->ops->create_volume(device->device_parent, parent,
- tmp_w, tmp_h, tmp_d, format_id, pool, usage, &volume);
+ tmp_w, tmp_h, tmp_d, i, desc->format, desc->pool, desc->usage, &volume);
if (FAILED(hr))
{
ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr);
return WINED3D_OK;
}
-HRESULT CDECL wined3d_texture_create_2d(struct wined3d_device *device, UINT width, UINT height,
- UINT level_count, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent,
- const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
+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)
{
struct wined3d_texture *object;
HRESULT hr;
- TRACE("device %p, width %u, height %u, level_count %u, usage %#x\n",
- device, width, height, level_count, usage);
- TRACE("format %s, pool %#x, parent %p, parent_ops %p, texture %p.\n",
- debug_d3dformat(format_id), pool, parent, parent_ops, texture);
+ 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)
return WINED3DERR_OUTOFVIDEOMEMORY;
}
- hr = texture_init(object, width, height, level_count,
- device, usage, format_id, pool, parent, parent_ops);
- if (FAILED(hr))
+ if (FAILED(hr = texture_init(object, desc, level_count, surface_flags, device, parent, parent_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return WINED3D_OK;
}
-HRESULT CDECL wined3d_texture_create_3d(struct wined3d_device *device, UINT width, UINT height, UINT depth,
- UINT level_count, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, 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)
{
struct wined3d_texture *object;
HRESULT hr;
- TRACE("device %p, width %u, height %u, depth %u, level_count %u, usage %#x\n",
- device, width, height, depth, level_count, usage);
- TRACE("format %s, pool %#x, parent %p, parent_ops %p, texture %p.\n",
- debug_d3dformat(format_id), pool, parent, parent_ops, texture);
+ 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)
return WINED3DERR_OUTOFVIDEOMEMORY;
}
- hr = volumetexture_init(object, width, height, depth, level_count,
- device, usage, format_id, pool, parent, parent_ops);
- if (FAILED(hr))
+ 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);
return WINED3D_OK;
}
-HRESULT CDECL wined3d_texture_create_cube(struct wined3d_device *device, UINT edge_length,
- UINT level_count, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, 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,
+ 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, edge_length %u, level_count %u, usage %#x\n",
- device, edge_length, level_count, usage);
- TRACE("format %s, pool %#x, parent %p, parent_ops %p, texture %p.\n",
- debug_d3dformat(format_id), pool, parent, parent_ops, texture);
+ 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)
return WINED3DERR_OUTOFVIDEOMEMORY;
}
- hr = cubetexture_init(object, edge_length, level_count,
- device, usage, format_id, pool, parent, parent_ops);
- if (FAILED(hr))
+ 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);
{WINED3DFMT_VERTEXDATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{WINED3DFMT_R16_UINT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{WINED3DFMT_R32_UINT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R32G32_UINT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
+ {WINED3DFMT_R32G32B32_UINT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
+ {WINED3DFMT_R32G32B32A32_UINT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
{WINED3DFMT_R16G16B16A16_SNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
/* Vendor-specific formats */
{WINED3DFMT_ATI2N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_NVDB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{WINED3DFMT_INST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{WINED3DFMT_INTZ, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
+ {WINED3DFMT_RESZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
/* Unsure about them, could not find a Windows driver that supports them */
{WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
+ /* Typeless */
+ {WINED3DFMT_R8_TYPELESS, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_R8G8_TYPELESS, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
+ {WINED3DFMT_R16_TYPELESS, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R16G16_TYPELESS, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R16G16B16A16_TYPELESS, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
+ {WINED3DFMT_R32_TYPELESS, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R32G32_TYPELESS, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
+ {WINED3DFMT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
+ {WINED3DFMT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
};
struct wined3d_format_base_flags
* resource size. */
static const struct wined3d_format_base_flags format_base_flags[] =
{
- {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
{WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
- {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH},
{WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
{WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
{WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
{WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
{WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
{WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
- {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
+ {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)},
+ {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, 1, GL_FALSE, sizeof(UINT)},
+ {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, 2, GL_FALSE, sizeof(UINT)},
+ {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, 3, GL_FALSE, sizeof(UINT)},
+ {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, 4, GL_FALSE, sizeof(UINT)},
};
struct wined3d_format_texture_info
* WINED3DFMT_NVHS */
static const struct wined3d_format_texture_info format_texture_info[] =
{
- /* format id internal srgbInternal rtInternal
- format type
+ /* format id gl_internal gl_srgb_internal gl_rt_internal
+ gl_format gl_type conv_byte_count
flags
- extension */
+ extension convert */
/* FourCC formats */
/* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
* is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
GL_ALPHA, GL_UNSIGNED_BYTE, 0,
0,
ARB_FRAGMENT_PROGRAM, NULL},
- {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
- GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
- 0,
- EXT_PALETTED_TEXTURE, NULL},
/* Standard ARGB formats */
{WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
GL_BGR, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
ARB_FRAMEBUFFER_OBJECT, NULL},
- {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
+ {WINED3DFMT_NULL, 0, 0, 0,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
ARB_FRAMEBUFFER_OBJECT, NULL},
gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
}
+static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format,
+ GLint internal, GLenum pname, DWORD flag, const char *string)
+{
+ GLint value;
+
+ gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, internal, pname, 1, &value);
+ if (value == GL_FULL_SUPPORT)
+ {
+ TRACE("Format %s supports %s.\n", debug_d3dformat(format->id), string);
+ format->flags |= flag;
+ }
+ else
+ {
+ TRACE("Format %s doesn't support %s.\n", debug_d3dformat(format->id), string);
+ format->flags &= ~flag;
+ }
+}
+
/* Context activation is done by the caller. */
static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
{
unsigned int i;
GLuint fbo;
+ if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
+ {
+ for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
+ {
+ GLint value;
+ struct wined3d_format *format = &gl_info->formats[i];
+
+ if (!format->glInternal)
+ continue;
+ if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+ continue;
+
+ gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glInternal,
+ GL_FRAMEBUFFER_RENDERABLE, 1, &value);
+ if (value == GL_FULL_SUPPORT)
+ {
+ TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
+ format->rtInternal = format->glInternal;
+
+ query_format_flag(gl_info, format, format->glInternal, GL_FRAMEBUFFER_BLEND,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, "post-pixelshader blending");
+ }
+ else
+ {
+ if (!format->rtInternal)
+ {
+ if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
+ {
+ WARN("Format %s with rendertarget flag is not supported as FBO color attachment"
+ " and no fallback specified.\n", debug_d3dformat(format->id));
+ format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+ }
+ else
+ TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
+ format->rtInternal = format->glInternal;
+ }
+ else
+ {
+ gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->rtInternal,
+ GL_FRAMEBUFFER_RENDERABLE, 1, &value);
+ if (value == GL_FULL_SUPPORT)
+ {
+ TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
+ debug_d3dformat(format->id));
+ }
+ else
+ {
+ WARN("Format %s rtInternal format is not supported as FBO color attachment.\n",
+ debug_d3dformat(format->id));
+ format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+ }
+ }
+ }
+
+ if (format->glInternal != format->glGammaInternal)
+ {
+ gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glGammaInternal,
+ GL_FRAMEBUFFER_RENDERABLE, 1, &value);
+ if (value == GL_FULL_SUPPORT)
+ {
+ TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+ }
+ else
+ {
+ WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
+ }
+ }
+ else if (format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+ }
+ return;
+ }
+
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
format->height_scale.numerator = 1;
format->height_scale.denominator = 1;
- if (!gl_info->limits.vertex_samplers)
- format->flags &= ~WINED3DFMT_FLAG_VTF;
-
- if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
- format->flags |= WINED3DFMT_FLAG_FILTERING;
- else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
- format->flags &= ~WINED3DFMT_FLAG_VTF;
-
- if (format->glGammaInternal != format->glInternal)
+ if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
{
- /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
- if (!gl_info->supported[EXT_TEXTURE_SRGB])
+ query_format_flag(gl_info, format, format->glInternal, GL_VERTEX_TEXTURE,
+ WINED3DFMT_FLAG_VTF, "vertex texture usage");
+ query_format_flag(gl_info, format, format->glInternal, GL_FILTER,
+ WINED3DFMT_FLAG_FILTERING, "filtering");
+
+ if (format->glGammaInternal != format->glInternal)
{
- format->glGammaInternal = format->glInternal;
- format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
+ query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ,
+ WINED3DFMT_FLAG_SRGB_READ, "sRGB read");
+
+ if (srgb_write)
+ query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE,
+ WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write");
+ else
+ format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
+
+ if (!(format->flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)))
+ format->glGammaInternal = format->glInternal;
+ else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ format->glInternal = format->glGammaInternal;
}
- else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ }
+ else
+ {
+ if (!gl_info->limits.vertex_samplers)
+ format->flags &= ~WINED3DFMT_FLAG_VTF;
+
+ if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
+ format->flags |= WINED3DFMT_FLAG_FILTERING;
+ else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
+ format->flags &= ~WINED3DFMT_FLAG_VTF;
+
+ if (format->glGammaInternal != format->glInternal)
{
- format->glInternal = format->glGammaInternal;
+ /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
+ if (!gl_info->supported[EXT_TEXTURE_SRGB])
+ {
+ format->glGammaInternal = format->glInternal;
+ format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
+ }
+ else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ {
+ format->glInternal = format->glGammaInternal;
+ }
}
- }
- if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
- format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
+ if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
+ format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
+ }
/* Texture conversion stuff */
format->convert = format_texture_info[i].convert;
};
BOOL filtered;
+ if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
+ /* This was already handled by init_format_texture_info(). */
+ return;
+
if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
{
WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
gl_info->formats[idx].height_scale.denominator = 2;
gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
- if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
{
idx = getFmtIdx(WINED3DFMT_P8_UINT);
gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
}
+ /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
+ * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with
+ * RENDERTARGET usage. */
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
+ {
+ idx = getFmtIdx(WINED3DFMT_RESZ);
+ gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
+ }
+
for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
{
- struct wined3d_format *format = &gl_info->formats[idx];
+ struct wined3d_format *format = &gl_info->formats[i];
if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
continue;
return &gl_info->formats[idx];
}
-UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
+UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment,
+ UINT width, UINT height, UINT depth)
{
UINT size;
size /= format->height_scale.denominator;
}
+ size *= depth;
+
return size;
}
FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
FMT_TO_STR(WINED3DFMT_INTZ);
+ FMT_TO_STR(WINED3DFMT_RESZ);
FMT_TO_STR(WINED3DFMT_NULL);
FMT_TO_STR(WINED3DFMT_R16);
FMT_TO_STR(WINED3DFMT_AL16);
return "STATE_GEOMETRY_SHADER";
if (STATE_IS_VIEWPORT(state))
return "STATE_VIEWPORT";
- if (STATE_IS_VERTEXSHADERCONSTANT(state))
- return "STATE_VERTEXSHADERCONSTANT";
- if (STATE_IS_PIXELSHADERCONSTANT(state))
- return "STATE_PIXELSHADERCONSTANT";
+ if (STATE_IS_LIGHT_TYPE(state))
+ return "STATE_LIGHT_TYPE";
if (STATE_IS_ACTIVELIGHT(state))
return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
if (STATE_IS_SCISSORRECT(state))
return "STATE_BASEVERTEXINDEX";
if (STATE_IS_FRAMEBUFFER(state))
return "STATE_FRAMEBUFFER";
+ if (STATE_IS_POINT_SIZE_ENABLE(state))
+ return "STATE_POINT_SIZE_ENABLE";
return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
}
return size;
}
-void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
+void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
struct ffp_frag_settings *settings, BOOL ignore_textype)
{
#define ARG1 0x01
DWORD ttff;
DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
const struct wined3d_surface *rt = state->fb->render_targets[0];
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
- for (i = 0; i < gl_info->limits.texture_stages; ++i)
+ for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i)
{
const struct wined3d_texture *texture;
if (!state->render_states[WINED3D_RS_FOGENABLE])
{
- settings->fog = FOG_OFF;
+ settings->fog = WINED3D_FFP_PS_FOG_OFF;
}
else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
{
if (use_vs(state) || state->vertex_declaration->position_transformed)
{
- settings->fog = FOG_LINEAR;
+ settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
}
else
{
{
case WINED3D_FOG_NONE:
case WINED3D_FOG_LINEAR:
- settings->fog = FOG_LINEAR;
+ settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
break;
case WINED3D_FOG_EXP:
- settings->fog = FOG_EXP;
+ settings->fog = WINED3D_FFP_PS_FOG_EXP;
break;
case WINED3D_FOG_EXP2:
- settings->fog = FOG_EXP2;
+ settings->fog = WINED3D_FFP_PS_FOG_EXP2;
break;
}
}
switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
{
case WINED3D_FOG_LINEAR:
- settings->fog = FOG_LINEAR;
+ settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
break;
case WINED3D_FOG_EXP:
- settings->fog = FOG_EXP;
+ settings->fog = WINED3D_FFP_PS_FOG_EXP;
break;
case WINED3D_FOG_EXP2:
- settings->fog = FOG_EXP2;
+ settings->fog = WINED3D_FFP_PS_FOG_EXP2;
break;
}
}
} else {
settings->sRGB_write = 0;
}
- if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
+ if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
|| !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
{
/* No need to emulate clipplanes if GL supports native vertex shader clipping or if
ffp_frag_program_key_compare,
};
+void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
+ struct wined3d_ffp_vs_settings *settings)
+{
+ unsigned int coord_idx, i;
+
+ if (si->position_transformed)
+ {
+ memset(settings, 0, sizeof(*settings));
+
+ settings->transformed = 1;
+ settings->point_size = state->gl_primitive_type == GL_POINTS;
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
+ else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+ else
+ settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+ if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
+ settings->texcoords |= 1 << i;
+ settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
+ & WINED3D_FFP_TCI_MASK;
+ }
+ return;
+ }
+
+ settings->transformed = 0;
+ settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
+ && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
+ settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));
+ settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS];
+ settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING];
+ settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER];
+ settings->point_size = state->gl_primitive_type == GL_POINTS;
+
+ if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1 << WINED3D_FFP_DIFFUSE)))
+ {
+ settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE];
+ settings->emission_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE];
+ settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE];
+ settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE];
+ }
+ else
+ {
+ settings->diffuse_source = WINED3D_MCS_MATERIAL;
+ settings->emission_source = WINED3D_MCS_MATERIAL;
+ settings->ambient_source = WINED3D_MCS_MATERIAL;
+ settings->specular_source = WINED3D_MCS_MATERIAL;
+ }
+
+ settings->texcoords = 0;
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+ if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
+ settings->texcoords |= 1 << i;
+ settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
+ & WINED3D_FFP_TCI_MASK;
+ }
+
+ settings->light_type = 0;
+ for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
+ {
+ if (state->lights[i])
+ settings->light_type |= (state->lights[i]->OriginalParms.type
+ & WINED3D_FFP_LIGHT_TYPE_MASK) << WINED3D_FFP_LIGHT_TYPE_SHIFT(i);
+ }
+
+ settings->ortho_fog = 0;
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
+ else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
+ {
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+
+ if (state->transforms[WINED3D_TS_PROJECTION].u.m[0][3] == 0.0f
+ && state->transforms[WINED3D_TS_PROJECTION].u.m[1][3] == 0.0f
+ && state->transforms[WINED3D_TS_PROJECTION].u.m[2][3] == 0.0f
+ && state->transforms[WINED3D_TS_PROJECTION].u.m[3][3] == 1.0f)
+ settings->ortho_fog = 1;
+ }
+ else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE)
+ settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
+ else if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE;
+ else
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+
+ settings->padding = 0;
+}
+
+static int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ const struct wined3d_ffp_vs_settings *ka = key;
+ const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry,
+ const struct wined3d_ffp_vs_desc, entry)->settings;
+
+ return memcmp(ka, kb, sizeof(*ka));
+}
+
+const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions =
+{
+ wined3d_rb_alloc,
+ wined3d_rb_realloc,
+ wined3d_rb_free,
+ wined3d_ffp_vertex_program_key_compare,
+};
+
UINT wined3d_log2i(UINT32 x)
{
static const UINT l[] =
if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
IntersectRect(rect, rect, &state->scissor_rect);
}
+
+const char *wined3d_debug_location(DWORD location)
+{
+ char buf[200];
+
+ 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_BUFFER);
+ LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB);
+ LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB);
+#undef LOCATION_TO_STR
+ if (location) FIXME("Unrecognized location flag(s) %#x.\n", location);
+
+ return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
+}
void *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- WORD preloaded = 0; /* MAX_STREAMS, 16 */
unsigned int i;
if (TRACE_ON(d3d_decl))
return E_FAIL;
}
- if (!(preloaded & (1 << e->input_slot)))
- {
- declaration->streams[declaration->num_streams] = e->input_slot;
- ++declaration->num_streams;
- preloaded |= 1 << e->input_slot;
- }
-
if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
{
if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) declaration->half_float_conv_needed = TRUE;
* Copyright 2002-2005 Raphael Junqueira
* Copyright 2005 Oliver Stieber
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ * Copyright 2013 Stefan Dösinger for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include "wined3d_private.h"
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)
+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;
if (active_sampler != WINED3D_UNMAPPED_STAGE)
device_invalidate_state(volume->resource.device, STATE_SAMPLER(active_sampler));
- container->texture_ops->texture_bind(container, context, FALSE);
+ container->texture_ops->texture_bind(container, context, srgb);
}
-void volume_add_dirty_box(struct wined3d_volume *volume, const struct wined3d_box *dirty_box)
+void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container)
+{
+ TRACE("volume %p, container %p.\n", volume, container);
+
+ volume->container = container;
+}
+
+/* Context activation is done by the caller. */
+static void wined3d_volume_allocate_texture(const 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;
+
+ 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));
+ checkGLcall("glTexImage3D");
+}
+
+/* Context activation is done by the caller. */
+void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
+ const struct wined3d_bo_address *data)
{
- volume->dirty = TRUE;
- if (dirty_box)
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_format *format = volume->resource.format;
+
+ TRACE("volume %p, context %p, level %u, format %s (%#x).\n",
+ volume, context, volume->texture_level, debug_d3dformat(format->id),
+ format->id);
+
+
+ if (data->buffer_object)
{
- volume->lockedBox.left = min(volume->lockedBox.left, dirty_box->left);
- volume->lockedBox.top = min(volume->lockedBox.top, dirty_box->top);
- volume->lockedBox.front = min(volume->lockedBox.front, dirty_box->front);
- volume->lockedBox.right = max(volume->lockedBox.right, dirty_box->right);
- volume->lockedBox.bottom = max(volume->lockedBox.bottom, dirty_box->bottom);
- volume->lockedBox.back = max(volume->lockedBox.back, dirty_box->back);
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, data->buffer_object));
+ checkGLcall("glBindBufferARB");
}
- else
+
+ 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));
+ checkGLcall("glTexSubImage3D");
+
+ if (data->buffer_object)
{
- volume->lockedBox.left = 0;
- volume->lockedBox.top = 0;
- volume->lockedBox.front = 0;
- volume->lockedBox.right = volume->resource.width;
- volume->lockedBox.bottom = volume->resource.height;
- volume->lockedBox.back = volume->resource.depth;
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
}
}
-void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container)
+static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location)
{
- TRACE("volume %p, container %p.\n", volume, container);
+ TRACE("Volume %p, setting %s.\n", volume, wined3d_debug_location(location));
+ volume->locations |= location;
+ TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations));
+}
- volume->container = container;
+void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location)
+{
+ TRACE("Volume %p, clearing %s.\n", volume, wined3d_debug_location(location));
+ volume->locations &= ~location;
+ TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations));
}
/* Context activation is done by the caller. */
-void volume_load(const struct wined3d_volume *volume, struct wined3d_context *context, UINT level, BOOL srgb_mode)
+static void wined3d_volume_download_data(struct wined3d_volume *volume,
+ const struct wined3d_context *context, const struct wined3d_bo_address *data)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_format *format = volume->resource.format;
- TRACE("volume %p, context %p, level %u, srgb %#x, format %s (%#x).\n",
- volume, context, level, srgb_mode, debug_d3dformat(format->id), format->id);
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data->buffer_object));
+ checkGLcall("glBindBufferARB");
+ }
- volume_bind_and_dirtify(volume, context);
+ gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, volume->texture_level,
+ format->glFormat, format->glType, data->addr);
+ checkGLcall("glGetTexImage");
- GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, level, format->glInternal,
- volume->resource.width, volume->resource.height, volume->resource.depth,
- 0, format->glFormat, format->glType, volume->resource.allocatedMemory));
- checkGLcall("glTexImage3D");
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
+ }
- /* When adding code releasing volume->resource.allocatedMemory to save
- * data keep in mind that GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by
- * default if supported(GL_APPLE_client_storage). Thus do not release
- * volume->resource.allocatedMemory if GL_APPLE_client_storage is
- * supported. */
}
-/* Do not call while under the GL lock. */
+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_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM);
+}
+
+static DWORD volume_access_from_location(DWORD location)
+{
+ switch (location)
+ {
+ case WINED3D_LOCATION_DISCARDED:
+ return 0;
+
+ case WINED3D_LOCATION_SYSMEM:
+ return WINED3D_RESOURCE_ACCESS_CPU;
+
+ case WINED3D_LOCATION_BUFFER:
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ return WINED3D_RESOURCE_ACCESS_GPU;
+
+ default:
+ FIXME("Unhandled location %#x.\n", location);
+ return 0;
+ }
+}
+
+/* Context activation is done by the caller. */
+static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
+ struct wined3d_context *context, BOOL dest_is_srgb)
+{
+ struct wined3d_bo_address data;
+ /* Optimizations are possible, but the effort should be put into either
+ * 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
+ * for DEFAULT pool surfaces. */
+
+ WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
+ data.buffer_object = 0;
+ data.addr = HeapAlloc(GetProcessHeap(), 0, volume->resource.size);
+ if (!data.addr)
+ return;
+
+ volume_bind_and_dirtify(volume, context, !dest_is_srgb);
+ wined3d_volume_download_data(volume, context, &data);
+ volume_bind_and_dirtify(volume, context, dest_is_srgb);
+ wined3d_volume_upload_data(volume, context, &data);
+
+ HeapFree(GetProcessHeap(), 0, data.addr);
+}
+
+/* Context activation is done by the caller. */
+static void wined3d_volume_load_location(struct wined3d_volume *volume,
+ struct wined3d_context *context, DWORD location)
+{
+ DWORD required_access = volume_access_from_location(location);
+
+ TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location),
+ wined3d_debug_location(volume->locations));
+
+ if ((volume->locations & location) == location)
+ {
+ TRACE("Location(s) already up to date.\n");
+ return;
+ }
+
+ if ((volume->resource.access_flags & required_access) != required_access)
+ {
+ ERR("Operation requires %#x access, but volume only has %#x.\n",
+ required_access, volume->resource.access_flags);
+ return;
+ }
+
+ switch (location)
+ {
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ if ((location == WINED3D_LOCATION_TEXTURE_RGB
+ && !(volume->flags & WINED3D_VFLAG_ALLOCATED))
+ || (location == WINED3D_LOCATION_TEXTURE_SRGB
+ && !(volume->flags & WINED3D_VFLAG_SRGB_ALLOCATED)))
+ ERR("Trying to load (s)RGB texture without prior allocation.\n");
+
+ if (volume->locations & WINED3D_LOCATION_DISCARDED)
+ {
+ TRACE("Volume previously discarded, nothing to do.\n");
+ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED);
+ }
+ else if (volume->locations & WINED3D_LOCATION_SYSMEM)
+ {
+ struct wined3d_bo_address data = {0, volume->resource.allocatedMemory};
+ wined3d_volume_upload_data(volume, context, &data);
+ }
+ else if (volume->locations & WINED3D_LOCATION_BUFFER)
+ {
+ struct wined3d_bo_address data = {volume->pbo, NULL};
+ wined3d_volume_upload_data(volume, context, &data);
+ }
+ else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
+ {
+ wined3d_volume_srgb_transfer(volume, context, TRUE);
+ }
+ else if (volume->locations & WINED3D_LOCATION_TEXTURE_SRGB)
+ {
+ wined3d_volume_srgb_transfer(volume, context, FALSE);
+ }
+ else
+ {
+ FIXME("Implement texture loading from %s.\n", wined3d_debug_location(volume->locations));
+ return;
+ }
+ wined3d_volume_validate_location(volume, location);
+
+ if (volume->resource.pool == WINED3D_POOL_MANAGED && volume->download_count < 10)
+ wined3d_volume_evict_sysmem(volume);
+
+ break;
+
+ case WINED3D_LOCATION_SYSMEM:
+ if (!volume->resource.allocatedMemory || !volume->resource.heap_memory)
+ {
+ ERR("Trying to load WINED3D_LOCATION_SYSMEM without setting it up first.\n");
+ return;
+ }
+
+ if (volume->locations & WINED3D_LOCATION_DISCARDED)
+ {
+ TRACE("Volume previously discarded, nothing to do.\n");
+ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED);
+ }
+ else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+ {
+ struct wined3d_bo_address data = {0, volume->resource.allocatedMemory};
+
+ if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
+ volume_bind_and_dirtify(volume, context, FALSE);
+ else
+ volume_bind_and_dirtify(volume, context, TRUE);
+
+ volume->download_count++;
+ wined3d_volume_download_data(volume, context, &data);
+ }
+ else
+ {
+ FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
+ wined3d_debug_location(volume->locations));
+ return;
+ }
+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM);
+ break;
+
+ case WINED3D_LOCATION_BUFFER:
+ if (!volume->pbo || !(volume->flags & WINED3D_VFLAG_PBO))
+ ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n");
+
+ if (volume->locations & WINED3D_LOCATION_DISCARDED)
+ {
+ TRACE("Volume previously discarded, nothing to do.\n");
+ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED);
+ }
+ else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+ {
+ struct wined3d_bo_address data = {volume->pbo, NULL};
+
+ if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
+ volume_bind_and_dirtify(volume, context, FALSE);
+ else
+ volume_bind_and_dirtify(volume, context, TRUE);
+
+ wined3d_volume_download_data(volume, context, &data);
+ }
+ else
+ {
+ FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
+ wined3d_debug_location(volume->locations));
+ return;
+ }
+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER);
+ break;
+
+ default:
+ FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
+ wined3d_debug_location(volume->locations));
+ }
+}
+
+/* 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);
+
+ if (srgb_mode)
+ {
+ if (!(volume->flags & WINED3D_VFLAG_SRGB_ALLOCATED))
+ {
+ wined3d_volume_allocate_texture(volume, context, TRUE);
+ volume->flags |= WINED3D_VFLAG_SRGB_ALLOCATED;
+ }
+
+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_TEXTURE_SRGB);
+ }
+ else
+ {
+ if (!(volume->flags & WINED3D_VFLAG_ALLOCATED))
+ {
+ wined3d_volume_allocate_texture(volume, context, FALSE);
+ volume->flags |= WINED3D_VFLAG_ALLOCATED;
+ }
+
+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_TEXTURE_RGB);
+ }
+}
+
+/* Context activation is done by the caller. */
+static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (volume->pbo)
+ return;
+
+ GL_EXTCALL(glGenBuffersARB(1, &volume->pbo));
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
+ GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->resource.size, NULL, GL_STREAM_DRAW_ARB));
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("Create PBO");
+
+ TRACE("Created PBO %u for volume %p.\n", volume->pbo, volume);
+}
+
+static void wined3d_volume_free_pbo(struct wined3d_volume *volume)
+{
+ struct wined3d_context *context = context_acquire(volume->resource.device, NULL);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ TRACE("Deleting PBO %u belonging to volume %p.\n", volume->pbo, volume);
+ GL_EXTCALL(glDeleteBuffersARB(1, &volume->pbo));
+ checkGLcall("glDeleteBuffersARB");
+ volume->pbo = 0;
+ 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);
+ struct wined3d_device *device = volume->resource.device;
+ struct wined3d_context *context;
+
+ if (volume->resource.pool == WINED3D_POOL_DEFAULT)
+ ERR("Unloading DEFAULT pool volume.\n");
+
TRACE("texture %p.\n", resource);
- /* The whole content is shadowed on This->resource.allocatedMemory, and
- * the texture name is managed by the VolumeTexture container. */
+ if (volume_prepare_system_memory(volume))
+ {
+ context = context_acquire(device, NULL);
+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM);
+ context_release(context);
+ wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_SYSMEM);
+ }
+ else
+ {
+ ERR("Out of memory when unloading volume %p.\n", volume);
+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_DISCARDED);
+ wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_DISCARDED);
+ }
+
+ if (volume->pbo)
+ {
+ /* Should not happen because only dynamic default pool volumes
+ * have a buffer, and those are not evicted by device_evit_managed_resources
+ * and must be freed before a non-ex device reset. */
+ ERR("Unloading a volume with a buffer\n");
+ wined3d_volume_free_pbo(volume);
+ }
+
+ /* The texture name is managed by the container. */
+ volume->flags &= ~(WINED3D_VFLAG_ALLOCATED | WINED3D_VFLAG_SRGB_ALLOCATED);
resource_unload(resource);
}
if (!refcount)
{
+ if (volume->pbo)
+ wined3d_volume_free_pbo(volume);
+
resource_cleanup(&volume->resource);
volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent);
HeapFree(GetProcessHeap(), 0, volume);
HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
{
+ struct wined3d_device *device = volume->resource.device;
+ struct wined3d_context *context;
+ const struct wined3d_gl_info *gl_info;
+ BYTE *base_memory;
+
TRACE("volume %p, map_desc %p, box %p, flags %#x.\n",
volume, map_desc, box, flags);
- if (!volume->resource.allocatedMemory)
- volume->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->resource.size);
+ 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;
+ }
+ flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags);
- TRACE("allocatedMemory %p.\n", volume->resource.allocatedMemory);
+ if (volume->flags & WINED3D_VFLAG_PBO)
+ {
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ wined3d_volume_prepare_pbo(volume, context);
+ if (flags & WINED3D_MAP_DISCARD)
+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER);
+ else
+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
+
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ GLbitfield mapflags = wined3d_resource_gl_map_flags(flags);
+ mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT;
+ base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER_ARB,
+ 0, volume->resource.size, mapflags));
+ }
+ else
+ {
+ base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ }
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("Map PBO");
+
+ context_release(context);
+ }
+ else
+ {
+ if (!volume_prepare_system_memory(volume))
+ {
+ WARN("Out of memory.\n");
+ map_desc->data = NULL;
+ return E_OUTOFMEMORY;
+ }
+
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM);
+ }
+ else if (!(volume->locations & WINED3D_LOCATION_SYSMEM))
+ {
+ context = context_acquire(device, NULL);
+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM);
+ context_release(context);
+ }
+ base_memory = volume->resource.allocatedMemory;
+ }
+
+ 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
if (!box)
{
TRACE("No box supplied - all is ok\n");
- map_desc->data = volume->resource.allocatedMemory;
- volume->lockedBox.left = 0;
- volume->lockedBox.top = 0;
- volume->lockedBox.front = 0;
- volume->lockedBox.right = volume->resource.width;
- volume->lockedBox.bottom = volume->resource.height;
- volume->lockedBox.back = volume->resource.depth;
+ map_desc->data = base_memory;
}
else
{
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 = volume->resource.allocatedMemory
+ 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);
- volume->lockedBox.left = box->left;
- volume->lockedBox.top = box->top;
- volume->lockedBox.front = box->front;
- volume->lockedBox.right = box->right;
- volume->lockedBox.bottom = box->bottom;
- volume->lockedBox.back = box->back;
}
if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
{
- volume_add_dirty_box(volume, &volume->lockedBox);
wined3d_texture_set_dirty(volume->container, TRUE);
+
+ if (volume->flags & WINED3D_VFLAG_PBO)
+ wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_BUFFER);
+ else
+ wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_SYSMEM);
}
- volume->locked = TRUE;
+ volume->flags |= WINED3D_VFLAG_LOCKED;
TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n",
map_desc->data, map_desc->row_pitch, map_desc->slice_pitch);
{
TRACE("volume %p.\n", volume);
- if (!volume->locked)
+ if (!(volume->flags & WINED3D_VFLAG_LOCKED))
{
WARN("Trying to unlock unlocked volume %p.\n", volume);
return WINED3DERR_INVALIDCALL;
}
- volume->locked = FALSE;
- memset(&volume->lockedBox, 0, sizeof(volume->lockedBox));
+ if (volume->flags & WINED3D_VFLAG_PBO)
+ {
+ struct wined3d_device *device = volume->resource.device;
+ struct wined3d_context *context = context_acquire(device, NULL);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
+ GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("Unmap PBO");
+
+ context_release(context);
+ }
+
+ volume->flags &= ~WINED3D_VFLAG_LOCKED;
return WINED3D_OK;
}
};
static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device *device, UINT width,
- UINT height, UINT depth, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool,
- void *parent, const struct wined3d_parent_ops *parent_ops)
+ 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)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
HRESULT hr;
+ UINT size;
if (!gl_info->supported[EXT_TEXTURE3D])
{
WARN("Volume cannot be created - no volume texture support.\n");
return WINED3DERR_INVALIDCALL;
}
+ /* 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))
+ {
+ WARN("Attempted to create a DYNAMIC texture in pool %u.\n", pool);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, depth);
hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format,
WINED3D_MULTISAMPLE_NONE, 0, usage, pool, width, height, depth,
- width * height * depth * format->byte_count, parent, parent_ops,
- &volume_resource_ops);
+ size, parent, parent_ops, &volume_resource_ops);
if (FAILED(hr))
{
WARN("Failed to initialize resource, returning %#x.\n", hr);
return hr;
}
- volume->lockable = TRUE;
- volume->locked = FALSE;
- memset(&volume->lockedBox, 0, sizeof(volume->lockedBox));
- volume->dirty = TRUE;
+ volume->texture_level = level;
+ volume->locations = WINED3D_LOCATION_DISCARDED;
- volume_add_dirty_box(volume, NULL);
+ if (pool == WINED3D_POOL_DEFAULT && usage & WINED3DUSAGE_DYNAMIC
+ && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT])
+ {
+ wined3d_resource_free_sysmem(volume->resource.heap_memory);
+ volume->resource.heap_memory = NULL;
+ volume->resource.allocatedMemory = NULL;
+ volume->flags |= WINED3D_VFLAG_PBO;
+ }
return WINED3D_OK;
}
HRESULT CDECL wined3d_volume_create(struct wined3d_device *device, UINT width, UINT height,
- UINT depth, 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)
+ 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)
{
struct wined3d_volume *object;
HRESULT hr;
return WINED3DERR_OUTOFVIDEOMEMORY;
}
- hr = volume_init(object, device, width, height, depth, usage, format_id, pool, parent, parent_ops);
+ hr = volume_init(object, device, width, height, depth, level,
+ usage, format_id, pool, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize volume, returning %#x.\n", hr);
@ 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)
+@ 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_swapchain_set_window(ptr ptr)
@ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
-@ cdecl wined3d_texture_create_2d(ptr long long long long long long ptr ptr ptr)
-@ cdecl wined3d_texture_create_3d(ptr long long long long long long long ptr ptr ptr)
-@ cdecl wined3d_texture_create_cube(ptr long long long long long ptr ptr 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_decref(ptr)
@ cdecl wined3d_texture_generate_mipmaps(ptr)
@ cdecl wined3d_texture_get_autogen_filter_type(ptr)
APPLE_YCBCR_422,
/* ARB */
ARB_COLOR_BUFFER_FLOAT,
+ ARB_DEBUG_OUTPUT,
ARB_DEPTH_BUFFER_FLOAT,
ARB_DEPTH_CLAMP,
ARB_DEPTH_TEXTURE,
ARB_HALF_FLOAT_PIXEL,
ARB_HALF_FLOAT_VERTEX,
ARB_INSTANCED_ARRAYS,
+ ARB_INTERNALFORMAT_QUERY2,
ARB_MAP_BUFFER_ALIGNMENT,
ARB_MAP_BUFFER_RANGE,
ARB_MULTISAMPLE,
EXT_GPU_PROGRAM_PARAMETERS,
EXT_GPU_SHADER4,
EXT_PACKED_DEPTH_STENCIL,
- EXT_PALETTED_TEXTURE,
EXT_POINT_PARAMETERS,
EXT_PROVOKING_VERTEX,
EXT_SECONDARY_COLOR,
USE_GL_FUNC(glFlushMappedBufferRangeAPPLE) \
/* GL_ARB_color_buffer_float */ \
USE_GL_FUNC(glClampColorARB) \
+ /* GL_ARB_debug_output */ \
+ USE_GL_FUNC(glDebugMessageCallbackARB) \
+ USE_GL_FUNC(glDebugMessageControlARB) \
+ USE_GL_FUNC(glDebugMessageInsertARB) \
+ USE_GL_FUNC(glGetDebugMessageLogARB) \
/* GL_ARB_draw_buffers */ \
USE_GL_FUNC(glDrawBuffersARB) \
/* GL_ARB_draw_elements_base_vertex */ \
USE_GL_FUNC(glProgramParameteriARB) \
/* GL_ARB_instanced_arrays */ \
USE_GL_FUNC(glVertexAttribDivisorARB) \
+ /* GL_ARB_internalformat_query */ \
+ USE_GL_FUNC(glGetInternalformativ) \
+ /* GL_ARB_internalformat_query2 */ \
+ USE_GL_FUNC(glGetInternalformati64v) \
/* GL_ARB_map_buffer_range */ \
USE_GL_FUNC(glFlushMappedBufferRange) \
USE_GL_FUNC(glMapBufferRange) \
USE_GL_FUNC(glDeleteQueriesARB) \
USE_GL_FUNC(glEndQueryARB) \
USE_GL_FUNC(glGenQueriesARB) \
+ USE_GL_FUNC(glGetQueryivARB) \
USE_GL_FUNC(glGetQueryObjectivARB) \
USE_GL_FUNC(glGetQueryObjectuivARB) \
+ USE_GL_FUNC(glIsQueryARB) \
/* GL_ARB_point_parameters */ \
USE_GL_FUNC(glPointParameterfARB) \
USE_GL_FUNC(glPointParameterfvARB) \
USE_GL_FUNC(glVertexAttribI4uivEXT) \
USE_GL_FUNC(glVertexAttribI4usvEXT) \
USE_GL_FUNC(glVertexAttribIPointerEXT) \
- /* GL_EXT_paletted_texture */ \
- USE_GL_FUNC(glColorTableEXT) \
/* GL_EXT_point_parameters */ \
USE_GL_FUNC(glPointParameterfEXT) \
USE_GL_FUNC(glPointParameterfvEXT) \
{
TRUE, /* Use of GLSL enabled by default */
ORM_FBO, /* Use FBOs to do offscreen rendering */
- RTL_READTEX, /* Default render target locking method */
PCI_VENDOR_NONE,/* PCI Vendor ID */
PCI_DEVICE_NONE,/* PCI Device ID */
0, /* The default of memory is set in init_driver_info */
~0U, /* No VS shader model limit by default. */
~0U, /* No GS shader model limit by default. */
~0U, /* No PS shader model limit by default. */
+ FALSE, /* 3D support enabled by default. */
};
/* Do not call while under the GL lock. */
return NULL;
}
+ if (version == 7 && wined3d_settings.no_3d)
+ flags |= WINED3D_NO3D;
+
hr = wined3d_init(object, version, flags);
if (FAILED(hr))
{
wined3d_settings.offscreen_rendering_mode = ORM_FBO;
}
}
- if ( !get_config_key( hkey, appkey, "RenderTargetLockMode", buffer, size) )
- {
- if (!strcmp(buffer,"readdraw"))
- {
- TRACE("Using glReadPixels for render target reading and glDrawPixels for writing\n");
- wined3d_settings.rendertargetlock_mode = RTL_READDRAW;
- }
- else if (!strcmp(buffer,"readtex"))
- {
- TRACE("Using glReadPixels for render target reading and textures for writing\n");
- wined3d_settings.rendertargetlock_mode = RTL_READTEX;
- }
- }
if ( !get_config_key_dword( hkey, appkey, "VideoPciDeviceID", &tmpvalue) )
{
int pci_device_id = tmpvalue;
TRACE("Limiting GS shader model to %u.\n", wined3d_settings.max_sm_gs);
if (!get_config_key_dword(hkey, appkey, "MaxShaderModelPS", &wined3d_settings.max_sm_ps))
TRACE("Limiting PS shader model to %u.\n", wined3d_settings.max_sm_ps);
+ if (!get_config_key(hkey, appkey, "DirectDrawRenderer", buffer, size)
+ && !strcmp(buffer, "gdi"))
+ {
+ TRACE("Disabling 3D support.\n");
+ wined3d_settings.no_3d = TRUE;
+ }
}
if (appkey) RegCloseKey( appkey );
return wined3d_dll_init(hInstDLL);
case DLL_PROCESS_DETACH:
+ if (lpv) break;
return wined3d_dll_destroy(hInstDLL);
case DLL_THREAD_DETACH:
- {
if (!context_set_current(NULL))
{
ERR("Failed to clear current context.\n");
}
return TRUE;
- }
-
- default:
- return TRUE;
}
+ return TRUE;
}
* Copyright 2002-2003 Raphael Junqueira
* Copyright 2002-2003, 2004 Jason Edmeades
* Copyright 2005 Oliver Stieber
+ * Copyright 2006-2011, 2013 Stefan Dösinger for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#define WINED3D_QUIRK_BROKEN_RGBA16 0x00000040
#define WINED3D_QUIRK_INFO_LOG_SPAM 0x00000080
#define WINED3D_QUIRK_LIMITED_TEX_FILTERING 0x00000100
+#define WINED3D_QUIRK_BROKEN_ARB_FOG 0x00000200
/* Texture format fixups */
void wined3d_rb_free(void *ptr) DECLSPEC_HIDDEN;
/* Device caps */
-#define MAX_PALETTES 65536
#define MAX_STREAM_OUT 4
#define MAX_STREAMS 16
#define MAX_TEXTURES 8
#define ORM_BACKBUFFER 0
#define ORM_FBO 1
-#define RTL_READDRAW 1
-#define RTL_READTEX 2
-
#define PCI_VENDOR_NONE 0xffff /* e.g. 0x8086 for Intel and 0x10de for Nvidia */
#define PCI_DEVICE_NONE 0xffff /* e.g. 0x14f for a Geforce6200 */
* implemented, we'll leave it as a registry setting for developers. */
BOOL glslRequested;
int offscreen_rendering_mode;
- int rendertargetlock_mode;
unsigned short pci_vendor_id;
unsigned short pci_device_id;
/* Memory tracking and object counting. */
unsigned int max_sm_vs;
unsigned int max_sm_gs;
unsigned int max_sm_ps;
+ BOOL no_3d;
};
extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN;
WINED3DSTT_VOLUME = 4,
};
+#define WINED3D_SHADER_CONST_VS_F 0x00000001
+#define WINED3D_SHADER_CONST_VS_I 0x00000002
+#define WINED3D_SHADER_CONST_VS_B 0x00000004
+#define WINED3D_SHADER_CONST_VS_POS_FIXUP 0x00000008
+#define WINED3D_SHADER_CONST_PS_F 0x00000010
+#define WINED3D_SHADER_CONST_PS_I 0x00000020
+#define WINED3D_SHADER_CONST_PS_B 0x00000040
+#define WINED3D_SHADER_CONST_PS_BUMP_ENV 0x00000080
+#define WINED3D_SHADER_CONST_PS_Y_CORR 0x00000100
+#define WINED3D_SHADER_CONST_PS_NP2_FIXUP 0x00000200
+#define WINED3D_SHADER_CONST_FFP_PS 0x00000400
+
enum wined3d_shader_register_type
{
WINED3DSPR_TEMP = 0,
* Shader model 3 according to msdn (and for software shaders) */
#define MAX_LABELS 16
-#define SHADER_PGMSIZE 65535
-
struct wined3d_shader_buffer
{
char *buffer;
- unsigned int bsize;
+ unsigned int buffer_size;
+ unsigned int content_size;
unsigned int lineNo;
BOOL newline;
};
#define WINED3D_CONST_NUM_UNUSED ~0U
-enum fogmode {
- FOG_OFF,
- FOG_LINEAR,
- FOG_EXP,
- FOG_EXP2
+enum wined3d_ffp_ps_fog_mode
+{
+ WINED3D_FFP_PS_FOG_OFF,
+ WINED3D_FFP_PS_FOG_LINEAR,
+ WINED3D_FFP_PS_FOG_EXP,
+ WINED3D_FFP_PS_FOG_EXP2,
};
/* Stateblock dependent parameters which have to be hardcoded
#define WINED3D_PSARGS_PROJECTED (1 << 3)
#define WINED3D_PSARGS_TEXTRANSFORM_SHIFT 4
#define WINED3D_PSARGS_TEXTRANSFORM_MASK 0xf
+#define WINED3D_PSARGS_TEXTYPE_SHIFT 2
+#define WINED3D_PSARGS_TEXTYPE_MASK 0x3
+
+/* Similar to tex_types, except that it doesn't have 1d textures
+ * (can't be bound), rect textures (handled via np2_fixup) and
+ * none / unknown (treated as 2d and handled via dummy textures). */
+enum wined3d_shader_tex_types
+{
+ WINED3D_SHADER_TEX_2D = 0,
+ WINED3D_SHADER_TEX_3D = 1,
+ WINED3D_SHADER_TEX_CUBE = 2,
+};
struct ps_compile_args {
struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS];
enum vertexprocessing_mode vp_mode;
- enum fogmode fog;
+ enum wined3d_ffp_ps_fog_mode fog;
WORD tex_transform; /* ps 1.0-1.3, 4 textures */
- /* Texture types(2D, Cube, 3D) in ps 1.x */
+ WORD tex_types; /* ps 1.0 - 1.4, 6 textures */
WORD srgb_correction;
WORD np2_fixup;
/* Bitmap for NP2 texcoord fixups (16 samplers max currently).
WORD swizzle_map; /* MAX_ATTRIBS, 16 */
};
-enum wined3d_shader_mode
-{
- WINED3D_SHADER_MODE_NONE,
- WINED3D_SHADER_MODE_FFP,
- WINED3D_SHADER_MODE_SHADER,
-};
-
struct wined3d_context;
struct wined3d_state;
struct fragment_pipeline;
+struct wined3d_vertex_pipe_ops;
struct wined3d_shader_backend_ops
{
void (*shader_handle_instruction)(const struct wined3d_shader_instruction *);
- void (*shader_select)(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
- enum wined3d_shader_mode fragment_mode);
+ void (*shader_select)(void *shader_priv, struct wined3d_context *context,
+ const struct wined3d_state *state);
+ void (*shader_disable)(void *shader_priv, struct wined3d_context *context);
void (*shader_select_depth_blt)(void *shader_priv, const struct wined3d_gl_info *gl_info,
enum tex_types tex_type, const SIZE *ds_mask_size);
void (*shader_deselect_depth_blt)(void *shader_priv, const struct wined3d_gl_info *gl_info);
void (*shader_update_float_vertex_constants)(struct wined3d_device *device, UINT start, UINT count);
void (*shader_update_float_pixel_constants)(struct wined3d_device *device, UINT start, UINT count);
- void (*shader_load_constants)(const struct wined3d_context *context, BOOL usePS, BOOL useVS);
- void (*shader_load_np2fixup_constants)(void *shader_priv, const struct wined3d_gl_info *gl_info,
+ void (*shader_load_constants)(void *shader_priv, struct wined3d_context *context,
const struct wined3d_state *state);
void (*shader_destroy)(struct wined3d_shader *shader);
- HRESULT (*shader_alloc_private)(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe);
+ HRESULT (*shader_alloc_private)(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+ const struct fragment_pipeline *fragment_pipe);
void (*shader_free_private)(struct wined3d_device *device);
- void (*shader_context_destroyed)(void *shader_priv, const struct wined3d_context *context);
+ BOOL (*shader_allocate_context_data)(struct wined3d_context *context);
+ void (*shader_free_context_data)(struct wined3d_context *context);
void (*shader_get_caps)(const struct wined3d_gl_info *gl_info, struct shader_caps *caps);
BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
BOOL (*shader_has_ffp_proj_control)(void *shader_priv);
#define checkGLcall(A) do {} while(0)
#endif
-/* Trace vector and strided data information */
-#define TRACE_STRIDED(si, name) do { if (si->use_map & (1 << name)) \
- TRACE( #name " = (data {%#x:%p}, stride %d, format %s, stream %u)\n", \
- si->elements[name].data.buffer_object, si->elements[name].data.addr, si->elements[name].stride, \
- debug_d3dformat(si->elements[name].format->id), si->elements[name].stream_idx); } while(0)
-
-/* Global variables */
-extern const struct wined3d_matrix identity DECLSPEC_HIDDEN;
-
enum wined3d_ffp_idx
{
WINED3D_FFP_POSITION = 0,
WINED3D_FFP_EMIT_DEC3N = 14,
WINED3D_FFP_EMIT_FLOAT16_2 = 15,
WINED3D_FFP_EMIT_FLOAT16_4 = 16,
- WINED3D_FFP_EMIT_COUNT = 17
+ WINED3D_FFP_EMIT_INVALID = 17,
+ WINED3D_FFP_EMIT_COUNT = 18
};
struct wined3d_bo_address
{
GLuint buffer_object;
- const BYTE *addr;
+ BYTE *addr;
};
struct wined3d_stream_info_element
};
void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count,
- UINT start_instance, UINT instance_count, BOOL indexed, const void *idx_data) DECLSPEC_HIDDEN;
+ UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN;
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
-typedef void (WINE_GLAPI *glAttribFunc)(const void *data);
-typedef void (WINE_GLAPI *glMultiTexCoordFunc)(GLenum unit, const void *data);
-extern glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
-extern glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
-extern glAttribFunc specular_func_3ubv DECLSPEC_HIDDEN;
-extern glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
-extern glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
-extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
-
#define eps 1e-8
#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
#define STATE_VIEWPORT (STATE_GEOMETRY_SHADER + 1)
#define STATE_IS_VIEWPORT(a) ((a) == STATE_VIEWPORT)
-#define STATE_VERTEXSHADERCONSTANT (STATE_VIEWPORT + 1)
-#define STATE_PIXELSHADERCONSTANT (STATE_VERTEXSHADERCONSTANT + 1)
-#define STATE_IS_VERTEXSHADERCONSTANT(a) ((a) == STATE_VERTEXSHADERCONSTANT)
-#define STATE_IS_PIXELSHADERCONSTANT(a) ((a) == STATE_PIXELSHADERCONSTANT)
-
-#define STATE_ACTIVELIGHT(a) (STATE_PIXELSHADERCONSTANT + (a) + 1)
+#define STATE_LIGHT_TYPE (STATE_VIEWPORT + 1)
+#define STATE_IS_LIGHT_TYPE(a) ((a) == STATE_LIGHT_TYPE)
+#define STATE_ACTIVELIGHT(a) (STATE_LIGHT_TYPE + 1 + (a))
#define STATE_IS_ACTIVELIGHT(a) ((a) >= STATE_ACTIVELIGHT(0) && (a) < STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS))
#define STATE_SCISSORRECT (STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS - 1) + 1)
#define STATE_FRAMEBUFFER (STATE_BASEVERTEXINDEX + 1)
#define STATE_IS_FRAMEBUFFER(a) ((a) == STATE_FRAMEBUFFER)
-#define STATE_HIGHEST (STATE_FRAMEBUFFER)
+#define STATE_POINT_SIZE_ENABLE (STATE_FRAMEBUFFER + 1)
+#define STATE_IS_POINT_SIZE_ENABLE(a) ((a) == STATE_POINT_SIZE_ENABLE)
+
+#define STATE_HIGHEST (STATE_POINT_SIZE_ENABLE)
enum fogsource {
FOGSOURCE_FFP,
FOGSOURCE_COORD,
};
-#define WINED3D_MAX_FBO_ENTRIES 64
-
struct wined3d_occlusion_query
{
struct list entry;
struct wined3d_context
{
const struct wined3d_gl_info *gl_info;
+ const struct wined3d_d3d_info *d3d_info;
const struct StateEntry *state_table;
/* State dirtification
* dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
DWORD current : 1;
DWORD destroyed : 1;
DWORD valid : 1;
- DWORD select_shader : 1;
- DWORD load_constants : 1;
- DWORD padding : 15;
- BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
- BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
+ DWORD padding : 1;
+ DWORD texShaderBumpMap : 8; /* MAX_TEXTURES, 8 */
+ DWORD lastWasPow2Texture : 8; /* MAX_TEXTURES, 8 */
+ DWORD shader_update_mask;
+ DWORD constant_update_mask;
DWORD numbered_array_mask;
GLenum tracking_parm; /* Which source is tracking current colour */
GLenum untracked_materials[2];
int pixel_format;
GLint aux_buffers;
+ void *shader_backend_data;
+
/* FBOs */
UINT fbo_entry_count;
struct list fbo_list;
const struct StateEntryTemplate *states;
};
+struct wined3d_vertex_caps
+{
+ BOOL xyzrhw;
+ DWORD max_active_lights;
+ DWORD max_vertex_blend_matrices;
+ DWORD max_vertex_blend_matrix_index;
+ DWORD vertex_processing_caps;
+ DWORD fvf_caps;
+ DWORD max_user_clip_planes;
+ DWORD raster_caps;
+};
+
+struct wined3d_vertex_pipe_ops
+{
+ void (*vp_enable)(const struct wined3d_gl_info *gl_info, BOOL enable);
+ void (*vp_get_caps)(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps);
+ void *(*vp_alloc)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv);
+ void (*vp_free)(struct wined3d_device *device);
+ const struct StateEntryTemplate *vp_states;
+};
+
extern const struct StateEntryTemplate misc_state_template[] DECLSPEC_HIDDEN;
-extern const struct StateEntryTemplate ffp_vertexstate_template[] DECLSPEC_HIDDEN;
extern const struct fragment_pipeline none_fragment_pipe DECLSPEC_HIDDEN;
extern const struct fragment_pipeline ffp_fragment_pipeline DECLSPEC_HIDDEN;
extern const struct fragment_pipeline atifs_fragment_pipeline DECLSPEC_HIDDEN;
extern const struct fragment_pipeline nvrc_fragment_pipeline DECLSPEC_HIDDEN;
extern const struct fragment_pipeline glsl_fragment_pipe DECLSPEC_HIDDEN;
+extern const struct wined3d_vertex_pipe_ops none_vertex_pipe DECLSPEC_HIDDEN;
+extern const struct wined3d_vertex_pipe_ops ffp_vertex_pipe DECLSPEC_HIDDEN;
+extern const struct wined3d_vertex_pipe_ops glsl_vertex_pipe DECLSPEC_HIDDEN;
+
/* "Base" state table */
HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
- const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
- const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
+ const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info,
+ const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
+ const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
enum wined3d_blit_op
{
void context_check_fbo_status(const struct wined3d_context *context, GLenum target) DECLSPEC_HIDDEN;
struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_surface *target,
const struct wined3d_format *ds_format) DECLSPEC_HIDDEN;
+BOOL context_debug_output_enabled(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
CARD_AMD_RADEON_HD2600 = 0x9581,
CARD_AMD_RADEON_HD2900 = 0x9400,
CARD_AMD_RADEON_HD3200 = 0x9620,
+ CARD_AMD_RADEON_HD4200M = 0x9712,
CARD_AMD_RADEON_HD4350 = 0x954f,
CARD_AMD_RADEON_HD4600 = 0x9495,
CARD_AMD_RADEON_HD4700 = 0x944e,
CARD_NVIDIA_GEFORCE_GTX260 = 0x05e2,
CARD_NVIDIA_GEFORCE_GTX275 = 0x05e6,
CARD_NVIDIA_GEFORCE_GTX280 = 0x05e1,
+ CARD_NVIDIA_GEFORCE_315M = 0x0a7a,
CARD_NVIDIA_GEFORCE_320M = 0x08a3,
CARD_NVIDIA_GEFORCE_GT320M = 0x0a2d,
CARD_NVIDIA_GEFORCE_GT325M = 0x0a35,
CARD_NVIDIA_GEFORCE_GT330 = 0x0ca0,
CARD_NVIDIA_GEFORCE_GTS350M = 0x0cb0,
+ CARD_NVIDIA_GEFORCE_410M = 0x1055,
CARD_NVIDIA_GEFORCE_GT420 = 0x0de2,
CARD_NVIDIA_GEFORCE_GT430 = 0x0de1,
CARD_NVIDIA_GEFORCE_GT440 = 0x0de0,
CARD_NVIDIA_GEFORCE_GTX570 = 0x1081,
CARD_NVIDIA_GEFORCE_GTX580 = 0x1080,
CARD_NVIDIA_GEFORCE_GT610 = 0x104a,
+ CARD_NVIDIA_GEFORCE_GT630 = 0x0f00,
CARD_NVIDIA_GEFORCE_GT630M = 0x0de9,
CARD_NVIDIA_GEFORCE_GT640M = 0x0fd2,
CARD_NVIDIA_GEFORCE_GT650M = 0x0fd1,
CARD_NVIDIA_GEFORCE_GTX660 = 0x11c0,
CARD_NVIDIA_GEFORCE_GTX660TI = 0x1183,
CARD_NVIDIA_GEFORCE_GTX670 = 0x1189,
+ CARD_NVIDIA_GEFORCE_GTX670MX = 0x11a1,
CARD_NVIDIA_GEFORCE_GTX680 = 0x1180,
+ CARD_NVIDIA_GEFORCE_GTX770M = 0x11e0,
+ CARD_NVIDIA_GEFORCE_GTX770 = 0x1184,
CARD_INTEL_830M = 0x3577,
CARD_INTEL_855GM = 0x3582,
UINT buffers;
UINT lights;
UINT textures;
- UINT texture_stages;
UINT texture_coords;
UINT fragment_samplers;
UINT vertex_samplers;
BOOL supported[WINED3D_GL_EXT_COUNT];
GLint wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP + 1];
+ HGLRC (WINAPI *p_wglCreateContextAttribsARB)(HDC dc, HGLRC share, const GLint *attribs);
struct opengl_funcs gl_ops;
struct wined3d_fbo_ops fbo_ops;
DWORD version_low;
};
+struct wined3d_d3d_limits
+{
+ UINT vs_version, gs_version, ps_version;
+ DWORD vs_uniform_count;
+ DWORD ps_uniform_count;
+ UINT ffp_textures;
+ UINT ffp_blend_stages;
+};
+
+typedef void (WINE_GLAPI *wined3d_ffp_attrib_func)(const void *data);
+typedef void (WINE_GLAPI *wined3d_ffp_texcoord_func)(GLenum unit, const void *data);
+extern wined3d_ffp_attrib_func specular_func_3ubv DECLSPEC_HIDDEN;
+
+struct wined3d_ffp_attrib_ops
+{
+ wined3d_ffp_attrib_func position[WINED3D_FFP_EMIT_COUNT];
+ wined3d_ffp_attrib_func diffuse[WINED3D_FFP_EMIT_COUNT];
+ wined3d_ffp_attrib_func specular[WINED3D_FFP_EMIT_COUNT];
+ wined3d_ffp_attrib_func normal[WINED3D_FFP_EMIT_COUNT];
+ wined3d_ffp_texcoord_func texcoord[WINED3D_FFP_EMIT_COUNT];
+};
+
+struct wined3d_d3d_info
+{
+ struct wined3d_d3d_limits limits;
+ struct wined3d_ffp_attrib_ops ffp_attrib_ops;
+ BOOL xyzrhw;
+ BOOL vs_clipping;
+ DWORD valid_rt_mask;
+};
+
/* The adapter structure */
struct wined3d_adapter
{
enum wined3d_format_id screen_format;
struct wined3d_gl_info gl_info;
+ struct wined3d_d3d_info d3d_info;
struct wined3d_driver_info driver_info;
WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
unsigned int cfg_count;
unsigned int UsedTextureRam;
LUID luid;
+ const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
const struct wined3d_shader_backend_ops *shader_backend;
const struct blit_shader *blitter;
unsigned padding : 10;
};
-struct ffp_frag_settings {
- struct texture_stage_op op[MAX_TEXTURES];
- enum fogmode fog;
+struct ffp_frag_settings
+{
+ struct texture_stage_op op[MAX_TEXTURES];
+ enum wined3d_ffp_ps_fog_mode fog;
/* Use shorts instead of chars to get dword alignment */
unsigned short sRGB_write;
unsigned short emul_clipplanes;
};
extern const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions DECLSPEC_HIDDEN;
+extern const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions DECLSPEC_HIDDEN;
extern const struct wined3d_parent_ops wined3d_null_parent_ops DECLSPEC_HIDDEN;
-void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
+void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
struct ffp_frag_settings *settings, BOOL ignore_textype) DECLSPEC_HIDDEN;
const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
const struct ffp_frag_settings *settings) DECLSPEC_HIDDEN;
void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) DECLSPEC_HIDDEN;
void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) DECLSPEC_HIDDEN;
+enum wined3d_ffp_vs_fog_mode
+{
+ WINED3D_FFP_VS_FOG_OFF = 0,
+ WINED3D_FFP_VS_FOG_FOGCOORD = 1,
+ WINED3D_FFP_VS_FOG_DEPTH = 2,
+ WINED3D_FFP_VS_FOG_RANGE = 3,
+};
+
+#define WINED3D_FFP_TCI_SHIFT 16
+#define WINED3D_FFP_TCI_MASK 0xff
+
+#define WINED3D_FFP_LIGHT_TYPE_SHIFT(idx) (3 * (idx))
+#define WINED3D_FFP_LIGHT_TYPE_MASK 0x7
+
+struct wined3d_ffp_vs_settings
+{
+ DWORD light_type : 24; /* MAX_ACTIVE_LIGHTS, 8 * 3 */
+ DWORD diffuse_source : 2;
+ DWORD emission_source : 2;
+ DWORD ambient_source : 2;
+ DWORD specular_source : 2;
+
+ DWORD transformed : 1;
+ DWORD clipping : 1;
+ DWORD normal : 1;
+ DWORD normalize : 1;
+ DWORD lighting : 1;
+ DWORD localviewer : 1;
+ DWORD point_size : 1;
+ DWORD fog_mode : 2;
+ DWORD texcoords : 8; /* MAX_TEXTURES */
+ DWORD ortho_fog : 1;
+ DWORD padding : 14;
+
+ BYTE texgen[MAX_TEXTURES];
+};
+
+struct wined3d_ffp_vs_desc
+{
+ struct wine_rb_entry entry;
+ struct wined3d_ffp_vs_settings settings;
+};
+
+void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
+ struct wined3d_ffp_vs_settings *settings) DECLSPEC_HIDDEN;
+
struct wined3d
{
LONG ref;
BOOL wined3d_register_window(HWND window, struct wined3d_device *device) DECLSPEC_HIDDEN;
void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
+struct wined3d_stream_output
+{
+ struct wined3d_buffer *buffer;
+ UINT offset;
+};
+
+struct wined3d_stream_state
+{
+ struct wined3d_buffer *buffer;
+ UINT offset;
+ UINT stride;
+ UINT frequency;
+ UINT flags;
+};
+
+struct wined3d_state
+{
+ const struct wined3d_fb_state *fb;
+
+ struct wined3d_vertex_declaration *vertex_declaration;
+ struct wined3d_stream_output stream_output[MAX_STREAM_OUT];
+ struct wined3d_stream_state streams[MAX_STREAMS + 1 /* tesselated pseudo-stream */];
+ struct wined3d_buffer *index_buffer;
+ enum wined3d_format_id index_format;
+ INT base_vertex_index;
+ 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];
+ 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;
+
+ 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];
+ struct wined3d_material material;
+ struct wined3d_viewport viewport;
+ RECT scissor_rect;
+
+ /* Light hashmap. Collisions are handled using linked lists. */
+#define LIGHTMAP_SIZE 43
+#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE)
+ struct list light_map[LIGHTMAP_SIZE];
+ const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS];
+
+ DWORD render_states[WINEHIGHEST_RENDER_STATE + 1];
+};
+
/*****************************************************************************
* IWineD3DDevice implementation structure
*/
const struct wined3d_shader_backend_ops *shader_backend;
void *shader_priv;
void *fragment_priv;
+ void *vertex_priv;
void *blit_priv;
struct StateEntry StateTable[STATE_HIGHEST + 1];
/* Array of functions for states which are handled by more than one pipeline part */
APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1];
const struct blit_shader *blitter;
- unsigned int max_ffp_textures;
- UINT vs_version, gs_version, ps_version;
- DWORD d3d_vshader_constantF, d3d_pshader_constantF; /* Advertised d3d caps, not GL ones */
- DWORD vs_clipping;
UINT instance_count;
- WORD view_ident : 1; /* true iff view matrix is identity */
WORD vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */
- WORD isRecordingState : 1;
WORD isInDraw : 1;
WORD bCursorVisible : 1;
WORD d3d_initialized : 1;
WORD softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */
WORD useDrawStridedSlow : 1;
WORD filter_messages : 1;
- WORD padding : 6;
+ WORD padding : 8;
BYTE fixed_function_usage_map; /* MAX_TEXTURES, 8 */
-#define DDRAW_PITCH_ALIGNMENT 8
-#define D3D8_PITCH_ALIGNMENT 4
unsigned char surface_alignment; /* Line Alignment of surfaces */
- /* State block related */
- struct wined3d_stateblock *stateBlock;
- struct wined3d_stateblock *updateStateBlock;
+ struct wined3d_state state;
+ struct wined3d_state *update_state;
+ struct wined3d_stateblock *recording;
/* Internal use fields */
struct wined3d_device_creation_parameters create_parms;
struct list shaders; /* a linked list to track shaders (pixel and vertex) */
/* Render Target Support */
- DWORD valid_rt_mask;
struct wined3d_fb_state fb;
struct wined3d_surface *onscreen_depth_stencil;
struct wined3d_surface *auto_depth_stencil;
DWORD rev_tex_unit_map[MAX_COMBINED_SAMPLERS];
/* Stream source management */
- struct wined3d_stream_info strided_streams;
+ struct wined3d_stream_info stream_info;
struct wined3d_event_query *buffer_queries[MAX_ATTRIBS];
unsigned int num_buffer_queries;
#define WINED3D_RESOURCE_ACCESS_GPU 0x1
#define WINED3D_RESOURCE_ACCESS_CPU 0x2
-/* SCRATCH is mostly the same as CPU, but can't be used by the GPU at all,
- * not even for resource uploads. */
-#define WINED3D_RESOURCE_ACCESS_SCRATCH 0x4
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;
enum wined3d_resource_type type;
const struct wined3d_format *format;
enum wined3d_multisample_type multisample_type;
- UINT multisample_quality;
- DWORD usage;
+ UINT multisample_quality;
+ DWORD usage;
enum wined3d_pool pool;
DWORD access_flags;
UINT width;
UINT height;
UINT depth;
- UINT size;
- DWORD priority;
- BYTE *allocatedMemory; /* Pointer to the real data location */
- BYTE *heapMemory; /* Pointer to the HeapAlloced block of memory */
- struct list privateData;
- struct list resource_list_entry;
+ UINT size;
+ DWORD priority;
+ BYTE *allocatedMemory; /* Pointer to the real data location */
+ void *heap_memory;
+ struct list privateData;
+ struct list resource_list_entry;
void *parent;
const struct wined3d_parent_ops *parent_ops;
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;
+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;
/* Tests show that the start address of resources is 32 byte aligned */
#define RESOURCE_ALIGNMENT 16
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_texture_set_dirty(struct wined3d_texture *texture, BOOL dirty) 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_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
+
+const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN;
+
struct wined3d_volume
{
struct wined3d_resource resource;
struct wined3d_texture *container;
- BOOL lockable;
- BOOL locked;
- struct wined3d_box lockedBox;
- struct wined3d_box dirtyBox;
- BOOL dirty;
+
+ DWORD flags, locations;
+ GLint texture_level;
+ DWORD download_count;
+ GLuint pbo;
};
static inline struct wined3d_volume *volume_from_resource(struct wined3d_resource *resource)
return CONTAINING_RECORD(resource, struct wined3d_volume, resource);
}
-void volume_add_dirty_box(struct wined3d_volume *volume, const struct wined3d_box *dirty_box) DECLSPEC_HIDDEN;
-void volume_load(const struct wined3d_volume *volume, struct wined3d_context *context, UINT level, BOOL srgb_mode) 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,
+ const struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
struct wined3d_surface_dib
{
GLuint id;
};
-enum wined3d_container_type
-{
- WINED3D_CONTAINER_NONE = 0,
- WINED3D_CONTAINER_SWAPCHAIN,
- WINED3D_CONTAINER_TEXTURE,
-};
-
-struct wined3d_subresource_container
-{
- enum wined3d_container_type type;
- union
- {
- struct wined3d_swapchain *swapchain;
- struct wined3d_texture *texture;
- void *base;
- } u;
-};
-
struct wined3d_surface_ops
{
HRESULT (*surface_private_setup)(struct wined3d_surface *surface);
{
struct wined3d_resource resource;
const struct wined3d_surface_ops *surface_ops;
- struct wined3d_subresource_container container;
+ struct wined3d_texture *container;
+ struct wined3d_swapchain *swapchain;
struct wined3d_palette *palette; /* D3D7 style palette handling */
DWORD draw_binding;
DWORD flags;
- UINT pow2Width;
- UINT pow2Height;
+ UINT pitch;
+ UINT pow2Width;
+ UINT pow2Height;
/* A method to retrieve the drawable size. Not in the Vtable to make it changeable */
void (*get_drawable_size)(const struct wined3d_context *context, UINT *width, UINT *height);
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
const struct wined3d_surface *rt) DECLSPEC_HIDDEN;
-void surface_set_container(struct wined3d_surface *surface,
- enum wined3d_container_type type, void *container) 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;
struct wined3d_vertex_declaration_element *elements;
UINT element_count;
- DWORD streams[MAX_STREAMS];
- UINT num_streams;
- BOOL position_transformed;
- BOOL half_float_conv_needed;
+ BOOL position_transformed;
+ BOOL half_float_conv_needed;
};
struct wined3d_saved_states
DWORD state;
};
-struct wined3d_stream_output
-{
- struct wined3d_buffer *buffer;
- UINT offset;
-};
-
-struct wined3d_stream_state
-{
- struct wined3d_buffer *buffer;
- UINT offset;
- UINT stride;
- UINT frequency;
- UINT flags;
-};
-
-struct wined3d_state
-{
- const struct wined3d_fb_state *fb;
-
- struct wined3d_vertex_declaration *vertex_declaration;
- struct wined3d_stream_output stream_output[MAX_STREAM_OUT];
- struct wined3d_stream_state streams[MAX_STREAMS + 1 /* tesselated pseudo-stream */];
- struct wined3d_buffer *index_buffer;
- enum wined3d_format_id index_format;
- INT base_vertex_index;
- 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];
- 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;
-
- 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];
- struct wined3d_material material;
- struct wined3d_viewport viewport;
- RECT scissor_rect;
-
- /* Light hashmap . Collisions are handled using standard wine double linked lists */
-#define LIGHTMAP_SIZE 43 /* Use of a prime number recommended. Set to 1 for a linked list! */
-#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE) /* Primitive and simple function */
- struct list light_map[LIGHTMAP_SIZE]; /* Hash map containing the lights */
- const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS]; /* Map of opengl lights to d3d lights */
-
- DWORD render_states[WINEHIGHEST_RENDER_STATE + 1];
-};
-
struct wined3d_stateblock
{
LONG ref; /* Note: Ref counting not required */
};
void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
-void stateblock_init_default_state(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
-void stateblock_unbind_resources(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;
+void state_unbind_resources(struct wined3d_state *state) 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
UINT size;
};
-#define WINED3D_BUFFER_OPTIMIZED 0x01 /* Optimize has been called for the buffer */
-#define WINED3D_BUFFER_HASDESC 0x02 /* A vertex description has been found */
-#define WINED3D_BUFFER_CREATEBO 0x04 /* Attempt to create a buffer object next PreLoad */
-#define WINED3D_BUFFER_DOUBLEBUFFER 0x08 /* Use a vbo and local allocated memory */
-#define WINED3D_BUFFER_FLUSH 0x10 /* Manual unmap flushing */
-#define WINED3D_BUFFER_DISCARD 0x20 /* A DISCARD lock has occurred since the last PreLoad */
-#define WINED3D_BUFFER_NOSYNC 0x40 /* All locks since the last PreLoad had NOOVERWRITE set */
-#define WINED3D_BUFFER_APPLESYNC 0x80 /* Using sync as in GL_APPLE_flush_buffer_range */
-
struct wined3d_buffer
{
struct wined3d_resource resource;
struct wined3d_surface **back_buffers;
struct wined3d_surface *front_buffer;
struct wined3d_swapchain_desc desc;
- DWORD orig_width, orig_height;
- enum wined3d_format_id orig_fmt;
+ struct wined3d_display_mode original_mode;
struct wined3d_gamma_ramp orig_gamma;
BOOL render_to_fbo;
const struct wined3d_format *ds_format;
void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
-#define DEFAULT_REFRESH_RATE 0
-
/*****************************************************************************
* Utility function prototypes
*/
void state_srgbwrite(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void sampler_texmatrix(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_specularenable(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_world(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_view(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_projection(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_texture(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_ambient(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void viewport_vertexpart(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_clipping(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void light(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void vertexdeclaration(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void clipplane(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_w(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_ext(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_arb(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pointsprite_w(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pointsprite(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pscale(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+
BOOL getColorBits(const struct wined3d_format *format,
BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize) DECLSPEC_HIDDEN;
BOOL getDepthStencilBits(const struct wined3d_format *format,
struct list constantsF;
struct list constantsI;
struct wined3d_shader_reg_maps reg_maps;
+ BOOL lconst_inf_or_nan;
struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
} u;
};
-void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps,
- struct wined3d_texture * const *textures) DECLSPEC_HIDDEN;
+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;
WORD num_consts;
};
-/* 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;
-
struct wined3d_palette
{
LONG ref;
#define WINED3DFMT_FLAG_DEPTH 0x00000004
#define WINED3DFMT_FLAG_STENCIL 0x00000008
#define WINED3DFMT_FLAG_RENDERTARGET 0x00000010
-#define WINED3DFMT_FLAG_FOURCC 0x00000020
#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040
#define WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB 0x00000080
#define WINED3DFMT_FLAG_GETDC 0x00000100
const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
enum wined3d_format_id format_id) DECLSPEC_HIDDEN;
UINT wined3d_format_calculate_size(const struct wined3d_format *format,
- UINT alignment, UINT width, UINT height) DECLSPEC_HIDDEN;
+ UINT alignment, UINT width, UINT height, UINT depth) DECLSPEC_HIDDEN;
DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface,
const struct wined3d_color *color) DECLSPEC_HIDDEN;
* Copyright 2002-2003 Jason Edmeades
* Copyright 2002-2003 Raphael Junqueira
* Copyright 2005 Oliver Stieber
- * Copyright 2006 Stefan DÃ\83¶singer
- * Copyright 2006 Stefan DÃ\83¶singer for CodeWeavers
+ * Copyright 2006 Stefan Dösinger
+ * Copyright 2006 Stefan Dösinger for CodeWeavers
* Copyright 2007 Henri Verbeet
* Copyright 2008 Henri Verbeet for CodeWeavers
*
WINED3DFMT_NVHU = WINEMAKEFOURCC('N','V','H','U'),
WINED3DFMT_NVHS = WINEMAKEFOURCC('N','V','H','S'),
WINED3DFMT_INTZ = WINEMAKEFOURCC('I','N','T','Z'),
+ WINED3DFMT_RESZ = WINEMAKEFOURCC('R','E','S','Z'),
WINED3DFMT_NULL = WINEMAKEFOURCC('N','U','L','L'),
WINED3DFMT_R16 = WINEMAKEFOURCC(' ','R','1','6'),
WINED3DFMT_AL16 = WINEMAKEFOURCC('A','L','1','6'),
enum wined3d_stateblock_type
{
- WINED3D_SBT_INIT = 0,
WINED3D_SBT_ALL = 1,
WINED3D_SBT_PIXEL_STATE = 2,
WINED3D_SBT_VERTEX_STATE = 3,
#define WINED3D_LEGACY_DEPTH_BIAS 0x00000001
#define WINED3D_NO3D 0x00000002
+#define WINED3D_VIDMEM_ACCOUNTING 0x00000004
+
+#define WINED3D_RESZ_CODE 0x7fa05000
/* dwDDFX */
/* arithmetic stretching along y axis */
UINT back;
};
-struct wined3d_strided_element
-{
- enum wined3d_format_id format; /* Format of the data */
- const BYTE *data; /* Pointer to start of data */
- UINT stride; /* Stride between occurrences of this data */
-};
-
-struct wined3d_strided_data
-{
- struct wined3d_strided_element position;
- struct wined3d_strided_element normal;
- struct wined3d_strided_element diffuse;
- struct wined3d_strided_element specular;
- struct wined3d_strided_element tex_coords[WINED3DDP_MAXTEXCOORD];
- BOOL position_transformed;
-};
-
struct wined3d_vertex_shader_caps
{
DWORD caps;
DWORD ssb_color_key_caps;
DWORD ssb_fx_caps;
DWORD dds_caps;
- DWORD stride_align;
};
typedef struct _WINED3DCAPS
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 *create_swapchain_surface)(struct wined3d_device_parent *device_parent, void *container_parent,
- UINT width, UINT height, enum wined3d_format_id format_id, DWORD usage,
- enum wined3d_multisample_type multisample_type, DWORD multisample_quality,
- struct wined3d_surface **surface);
+ const struct wined3d_resource_desc *desc, struct wined3d_surface **surface);
HRESULT (__cdecl *create_texture_surface)(struct wined3d_device_parent *device_parent, void *container_parent,
- UINT width, UINT height, enum wined3d_format_id format_id, DWORD usage, enum wined3d_pool pool,
- UINT sub_resource_idx, struct wined3d_surface **surface);
+ 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, enum wined3d_format_id format_id, enum wined3d_pool pool, DWORD usage,
- struct wined3d_volume **volume);
+ 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);
};
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);
+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_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, UINT width, UINT height,
- UINT level_count, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent,
- const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
-HRESULT __cdecl wined3d_texture_create_3d(struct wined3d_device *device, UINT width, UINT height, UINT depth,
- UINT level_count, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent,
- const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
-HRESULT __cdecl wined3d_texture_create_cube(struct wined3d_device *device, UINT edge_length,
- UINT level_count, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent,
- const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
+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,
+ 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);
void __cdecl wined3d_texture_generate_mipmaps(struct wined3d_texture *texture);
enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture);
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,
- DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent,
+ 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);
reactos/dll/directx/dplayx # Synced to Wine-1.5.26
reactos/dll/directx/dsound # Synced to Wine-1.5.26
reactos/dll/directx/dxdiagn # Synced to Wine-0_9_5
-reactos/dll/directx/dxgi # Synced to Wine-1.5.26
+reactos/dll/directx/dxgi # Synced to Wine-1.7.1
reactos/dll/directx/msdmo # Autosync
reactos/dll/directx/qedit # Autosync
reactos/dll/directx/quartz # Synced to Wine-1.5.26
+reactos/dll/directx/wine/d3d8 # Synced to Wine-1.7.1
+reactos/dll/directx/wine/d3d9 # Synced to Wine-1.7.1
+reactos/dll/directx/wine/ddraw # Synced to Wine-1.7.1
+reactos/dll/directx/wine/wined3d # Synced to Wine-1.7.1
reactos/dll/win32/activeds # Synced to Wine-1.1.43?
reactos/dll/win32/actxprxy # Synced to Wine-1.5.26
reactos/dll/win32/advpack # Synced to Wine-1.7.1