[D3D8][D3D9][DDRAW][WINED3D] Sync with Wine Staging 1.7.37. CORE-9246

svn path=/trunk/; revision=66488
This commit is contained in:
Amine Khaldi 2015-02-28 10:18:41 +00:00
parent c7a1e940d7
commit 3bec612279
46 changed files with 4710 additions and 3050 deletions

View file

@ -542,16 +542,42 @@ static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
struct wined3d_swapchain_desc desc;
struct d3d8_swapchain *object;
UINT i, count;
HRESULT hr;
TRACE("iface %p, present_parameters %p, swapchain %p.\n",
iface, present_parameters, swapchain);
if (!present_parameters->Windowed)
{
WARN("Trying to create an additional fullscreen swapchain, returning D3DERR_INVALIDCALL.\n");
return D3DERR_INVALIDCALL;
}
wined3d_mutex_lock();
count = wined3d_device_get_swapchain_count(device->wined3d_device);
for (i = 0; i < count; ++i)
{
struct wined3d_swapchain *wined3d_swapchain;
wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i);
wined3d_swapchain_get_desc(wined3d_swapchain, &desc);
if (!desc.windowed)
{
wined3d_mutex_unlock();
WARN("Trying to create an additional swapchain in fullscreen mode, returning D3DERR_INVALIDCALL.\n");
return D3DERR_INVALIDCALL;
}
}
wined3d_mutex_unlock();
wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
if (SUCCEEDED(d3d8_swapchain_create(device, &desc, &object)))
if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object)))
*swapchain = &object->IDirect3DSwapChain8_iface;
present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
return D3D_OK;
return hr;
}
static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
@ -606,6 +632,12 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface,
TRACE("iface %p, present_parameters %p.\n", iface, present_parameters);
if (device->device_state == D3D8_DEVICE_STATE_LOST)
{
WARN("App not active, returning D3DERR_DEVICELOST.\n");
return D3DERR_DEVICELOST;
}
wined3d_mutex_lock();
if (device->vertex_buffer)
@ -894,7 +926,7 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width
wined3d_mutex_lock();
if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc,
1, flags, NULL, &d3d8_null_wined3d_parent_ops, &texture)))
1, flags, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture)))
{
wined3d_mutex_unlock();
WARN("Failed to create texture, hr %#x.\n", hr);
@ -972,7 +1004,6 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
struct wined3d_resource_desc wined3d_desc;
struct wined3d_resource *wined3d_resource;
UINT src_w, src_h;
HRESULT hr;
TRACE("iface %p, src_surface %p, src_rects %p, rect_count %u, dst_surface %p, dst_points %p.\n",
iface, src_surface, src_rects, rect_count, dst_surface, dst_points);
@ -1004,24 +1035,13 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
dst_format = wined3d_desc.format;
/* Check that the source and destination formats match */
if (src_format != dst_format && WINED3DFMT_UNKNOWN != dst_format)
if (src_format != dst_format)
{
WARN("Source %p format must match the destination %p format, returning D3DERR_INVALIDCALL.\n",
src_surface, dst_surface);
wined3d_mutex_unlock();
return D3DERR_INVALIDCALL;
}
else if (WINED3DFMT_UNKNOWN == dst_format)
{
TRACE("Converting destination surface from WINED3DFMT_UNKNOWN to the source format.\n");
if (FAILED(hr = wined3d_surface_update_desc(dst->wined3d_surface, wined3d_desc.width, wined3d_desc.height,
src_format, wined3d_desc.multisample_type, wined3d_desc.multisample_quality, NULL, 0)))
{
WARN("Failed to update surface desc, hr %#x.\n", hr);
wined3d_mutex_unlock();
return hr;
}
}
/* Quick if complete copy ... */
if (!rect_count && !src_rects && !dst_points)
@ -2977,7 +2997,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
texture_desc = *desc;
texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1,
WINED3D_SURFACE_MAPPABLE, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture)))
WINED3D_SURFACE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;

View file

@ -389,7 +389,7 @@ static const struct IDirect3D8Vtbl d3d8_vtbl =
BOOL d3d8_init(struct d3d8 *d3d8)
{
DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING;
DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING | WINED3D_HANDLE_RESTORE;
d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
d3d8->refcount = 1;

View file

@ -108,11 +108,19 @@ HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_d
if (byte_code)
{
if (usage) FIXME("Usage %#x not implemented.\n", usage);
struct wined3d_shader_desc desc;
if (usage)
FIXME("Usage %#x not implemented.\n", usage);
desc.byte_code = byte_code;
desc.input_signature = NULL;
desc.output_signature = NULL;
desc.max_version = 1;
wined3d_mutex_lock();
hr = wined3d_shader_create_vs(device->wined3d_device, byte_code, NULL /* output signature */,
shader, &d3d8_vertexshader_wined3d_parent_ops, &shader->wined3d_shader, 1);
hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
&d3d8_vertexshader_wined3d_parent_ops, &shader->wined3d_shader);
wined3d_mutex_unlock();
if (FAILED(hr))
{
@ -149,13 +157,19 @@ static const struct wined3d_parent_ops d3d8_pixelshader_wined3d_parent_ops =
HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_device *device,
const DWORD *byte_code, DWORD shader_handle)
{
struct wined3d_shader_desc desc;
HRESULT hr;
shader->handle = shader_handle;
desc.byte_code = byte_code;
desc.input_signature = NULL;
desc.output_signature = NULL;
desc.max_version = 1;
wined3d_mutex_lock();
hr = wined3d_shader_create_ps(device->wined3d_device, byte_code, NULL, shader,
&d3d8_pixelshader_wined3d_parent_ops, &shader->wined3d_shader, 1);
hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
&d3d8_pixelshader_wined3d_parent_ops, &shader->wined3d_shader);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View file

@ -1169,9 +1169,12 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
surface_flags |= WINED3D_SURFACE_MAPPABLE;
if (!levels)
levels = wined3d_log2i(max(width, height)) + 1;
wined3d_mutex_lock();
hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{
@ -1211,9 +1214,12 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic
if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
surface_flags |= WINED3D_SURFACE_MAPPABLE;
if (!levels)
levels = wined3d_log2i(edge_length) + 1;
wined3d_mutex_lock();
hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{
@ -1249,9 +1255,12 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev
desc.depth = depth;
desc.size = 0;
if (!levels)
levels = wined3d_log2i(max(max(width, height), depth)) + 1;
wined3d_mutex_lock();
hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0,
texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View file

@ -500,11 +500,36 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
struct wined3d_swapchain_desc desc;
struct d3d9_swapchain *object;
UINT i, count;
HRESULT hr;
TRACE("iface %p, present_parameters %p, swapchain %p.\n",
iface, present_parameters, swapchain);
if (!present_parameters->Windowed)
{
WARN("Trying to create an additional fullscreen swapchain, returning D3DERR_INVALIDCALL.\n");
return D3DERR_INVALIDCALL;
}
wined3d_mutex_lock();
count = wined3d_device_get_swapchain_count(device->wined3d_device);
for (i = 0; i < count; ++i)
{
struct wined3d_swapchain *wined3d_swapchain;
wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i);
wined3d_swapchain_get_desc(wined3d_swapchain, &desc);
if (!desc.windowed)
{
wined3d_mutex_unlock();
WARN("Trying to create an additional swapchain in fullscreen mode, returning D3DERR_INVALIDCALL.\n");
return D3DERR_INVALIDCALL;
}
}
wined3d_mutex_unlock();
wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object)))
*swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface;
@ -607,6 +632,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Reset(IDirect3DDevice9Ex *if
TRACE("iface %p, present_parameters %p.\n", iface, present_parameters);
if (!device->d3d_parent->extended && device->device_state == D3D9_DEVICE_STATE_LOST)
{
WARN("App not active, returning D3DERR_DEVICELOST.\n");
return D3DERR_DEVICELOST;
}
wined3d_mutex_lock();
if (device->vertex_buffer)
@ -784,16 +815,9 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface,
}
if (set_mem)
{
struct wined3d_resource *resource;
struct d3d9_surface *surface;
resource = wined3d_texture_get_sub_resource(object->wined3d_texture, 0);
surface = wined3d_resource_get_parent(resource);
wined3d_surface_update_desc(surface->wined3d_surface, width, height,
wined3d_texture_update_desc(object->wined3d_texture, width, height,
wined3dformat_from_d3dformat(format), WINED3D_MULTISAMPLE_NONE, 0,
*shared_handle, 0);
}
TRACE("Created texture %p.\n", object);
*texture = (IDirect3DTexture9 *)&object->IDirect3DBaseTexture9_iface;
@ -1014,7 +1038,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
wined3d_mutex_lock();
if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc,
1, flags, NULL, &d3d9_null_wined3d_parent_ops, &texture)))
1, flags, NULL, NULL, &d3d9_null_wined3d_parent_ops, &texture)))
{
wined3d_mutex_unlock();
WARN("Failed to create texture, hr %#x.\n", hr);
@ -1026,12 +1050,13 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
surface_impl->parent_device = &device->IDirect3DDevice9Ex_iface;
*surface = &surface_impl->IDirect3DSurface9_iface;
IDirect3DSurface9_AddRef(*surface);
wined3d_texture_decref(texture);
if (user_mem)
wined3d_surface_update_desc(surface_impl->wined3d_surface, width, height,
wined3d_texture_update_desc(texture, width, height,
desc.format, multisample_type, multisample_quality, user_mem, 0);
wined3d_texture_decref(texture);
wined3d_mutex_unlock();
return D3D_OK;
@ -3519,7 +3544,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
texture_desc = *desc;
texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1,
WINED3D_SURFACE_MAPPABLE, container_parent, &d3d9_null_wined3d_parent_ops, &texture)))
WINED3D_SURFACE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, &texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;

View file

@ -633,10 +633,13 @@ static const struct IDirect3D9ExVtbl d3d9_vtbl =
BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
{
DWORD flags = WINED3D_PRESENT_CONVERSION;
DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE;
if (!extended)
flags |= WINED3D_VIDMEM_ACCOUNTING;
else
flags |= WINED3D_RESTORE_MODE_ON_ACTIVATE;
d3d9->IDirect3D9Ex_iface.lpVtbl = &d3d9_vtbl;
d3d9->refcount = 1;

View file

@ -133,14 +133,20 @@ static const struct wined3d_parent_ops d3d9_vertexshader_wined3d_parent_ops =
HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device *device, const DWORD *byte_code)
{
struct wined3d_shader_desc desc;
HRESULT hr;
shader->refcount = 1;
shader->IDirect3DVertexShader9_iface.lpVtbl = &d3d9_vertexshader_vtbl;
desc.byte_code = byte_code;
desc.input_signature = NULL;
desc.output_signature = NULL;
desc.max_version = 3;
wined3d_mutex_lock();
hr = wined3d_shader_create_vs(device->wined3d_device, byte_code, NULL,
shader, &d3d9_vertexshader_wined3d_parent_ops, &shader->wined3d_shader, 3);
hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
&d3d9_vertexshader_wined3d_parent_ops, &shader->wined3d_shader);
wined3d_mutex_unlock();
if (FAILED(hr))
{
@ -158,7 +164,8 @@ struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVerte
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d9_vertexshader_vtbl);
if (iface->lpVtbl != &d3d9_vertexshader_vtbl)
WARN("Vertex shader %p with the wrong vtbl %p\n", iface, iface->lpVtbl);
return impl_from_IDirect3DVertexShader9(iface);
}
@ -277,14 +284,20 @@ static const struct wined3d_parent_ops d3d9_pixelshader_wined3d_parent_ops =
HRESULT pixelshader_init(struct d3d9_pixelshader *shader, struct d3d9_device *device, const DWORD *byte_code)
{
struct wined3d_shader_desc desc;
HRESULT hr;
shader->refcount = 1;
shader->IDirect3DPixelShader9_iface.lpVtbl = &d3d9_pixelshader_vtbl;
desc.byte_code = byte_code;
desc.input_signature = NULL;
desc.output_signature = NULL;
desc.max_version = 3;
wined3d_mutex_lock();
hr = wined3d_shader_create_ps(device->wined3d_device, byte_code, NULL, shader,
&d3d9_pixelshader_wined3d_parent_ops, &shader->wined3d_shader, 3);
hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
&d3d9_pixelshader_wined3d_parent_ops, &shader->wined3d_shader);
wined3d_mutex_unlock();
if (FAILED(hr))
{
@ -302,7 +315,8 @@ struct d3d9_pixelshader *unsafe_impl_from_IDirect3DPixelShader9(IDirect3DPixelSh
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d9_pixelshader_vtbl);
if (iface->lpVtbl != &d3d9_pixelshader_vtbl)
WARN("Pixel shader %p with the wrong vtbl %p\n", iface, iface->lpVtbl);
return impl_from_IDirect3DPixelShader9(iface);
}

View file

@ -88,6 +88,12 @@ static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface)
return IDirect3DBaseTexture9_Release(&surface->texture->IDirect3DBaseTexture9_iface);
}
if (!surface->resource.refcount)
{
ERR("Surface doesn't have any references.\n");
return 0;
}
refcount = InterlockedDecrement(&surface->resource.refcount);
TRACE("%p decreasing refcount to %u.\n", iface, refcount);

View file

@ -1293,9 +1293,17 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
surface_flags |= WINED3D_SURFACE_MAPPABLE;
if (!levels)
{
if (usage & D3DUSAGE_AUTOGENMIPMAP)
levels = 1;
else
levels = wined3d_log2i(max(width, height)) + 1;
}
wined3d_mutex_lock();
hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{
@ -1335,9 +1343,17 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
surface_flags |= WINED3D_SURFACE_MAPPABLE;
if (!levels)
{
if (usage & D3DUSAGE_AUTOGENMIPMAP)
levels = 1;
else
levels = wined3d_log2i(edge_length) + 1;
}
wined3d_mutex_lock();
hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{
@ -1373,9 +1389,17 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
desc.depth = depth;
desc.size = 0;
if (!levels)
{
if (usage & D3DUSAGE_AUTOGENMIPMAP)
levels = 1;
else
levels = wined3d_log2i(max(max(width, height), depth)) + 1;
}
wined3d_mutex_lock();
hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0,
texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View file

@ -23,9 +23,7 @@
#include "ddraw_private.h"
static struct wined3d_display_mode original_mode;
static const struct ddraw *exclusive_ddraw;
static BOOL restore_mode;
/* Device identifier. Don't relay it to WineD3D */
static const DDDEVICEIDENTIFIER2 deviceidentifier =
@ -679,11 +677,8 @@ static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface)
return DDERR_NOEXCLUSIVEMODE;
}
if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &original_mode)))
{
if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, NULL)))
ddraw->flags &= ~DDRAW_RESTORE_MODE;
restore_mode = FALSE;
}
wined3d_mutex_unlock();
@ -1092,10 +1087,6 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW
return DD_OK;
}
if (!restore_mode && FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d,
WINED3DADAPTER_DEFAULT, &original_mode, NULL)))
ERR("Failed to get current display mode, hr %#x.\n", hr);
switch (bpp)
{
case 8: format = WINED3DFMT_P8_UINT; break;
@ -1116,10 +1107,7 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW
* can't be changed if a surface is locked or some drawing is in progress. */
/* TODO: Lose the primary surface. */
if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
{
ddraw->flags |= DDRAW_RESTORE_MODE;
restore_mode = TRUE;
}
wined3d_mutex_unlock();
@ -4721,7 +4709,6 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
{
struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
struct ddraw_surface *ddraw_surface;
HRESULT hr;
TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
device_parent, container_parent, surface, parent, parent_ops);
@ -4741,13 +4728,7 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
return DDERR_OUTOFVIDEOMEMORY;
}
if (FAILED(hr = ddraw_surface_init(ddraw_surface, ddraw, container_parent, surface, parent_ops)))
{
WARN("Failed to initialize surface, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, ddraw_surface);
return hr;
}
ddraw_surface_init(ddraw_surface, ddraw, container_parent, surface, parent_ops);
*parent = ddraw_surface;
list_add_head(&ddraw->surface_list, &ddraw_surface->surface_list_entry);
@ -4800,7 +4781,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
texture_desc = *desc;
texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &texture_desc, 1,
WINED3D_SURFACE_MAPPABLE, ddraw, &ddraw_frontbuffer_parent_ops, &texture)))
WINED3D_SURFACE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, &texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
@ -4864,7 +4845,8 @@ HRESULT ddraw_init(struct ddraw *ddraw, enum wined3d_device_type device_type)
ddraw->numIfaces = 1;
ddraw->ref7 = 1;
flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING;
flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
| WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES;
if (!(ddraw->wined3d = wined3d_create(flags)))
{
if (!(ddraw->wined3d = wined3d_create(flags | WINED3D_NO3D)))

View file

@ -213,7 +213,7 @@ struct ddraw_texture
HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc,
struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) DECLSPEC_HIDDEN;
struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface) DECLSPEC_HIDDEN;
HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN;
HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,

View file

@ -144,9 +144,10 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
buffer->indices[(i * 3) + 2] = ci->u3.v3;
instr += size;
}
IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface,
D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, tl_vx, buffer->nb_vertices,
buffer->indices, count * 3, 0);
if (count)
IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface,
D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, tl_vx, buffer->nb_vertices,
buffer->indices, count * 3, 0);
} break;
case D3DOP_MATRIXLOAD:

View file

@ -424,7 +424,7 @@ HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA callback, void *contex
cont_enum = callback(NULL, driver_desc, driver_name, context, 0);
/* The Battle.net System Checker expects both a NULL device and a GUID-based device */
if (cont_enum && (flags & ~DDENUM_ATTACHEDSECONDARYDEVICES))
if (cont_enum && (flags & DDENUM_ATTACHEDSECONDARYDEVICES))
ddraw_enumerate_secondary_devices(wined3d, callback, context);
}
__EXCEPT_PAGE_FAULT

View file

@ -4461,7 +4461,7 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface,
format_id = wined3dformat_from_ddrawformat(&This->surface_desc.u4.ddpfPixelFormat);
}
if (FAILED(hr = wined3d_surface_update_desc(This->wined3d_surface, width, height,
if (FAILED(hr = wined3d_texture_update_desc(This->wined3d_texture, width, height,
format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch)))
{
WARN("Failed to update surface desc, hr %#x.\n", hr);
@ -5600,6 +5600,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
DDSURFACEDESC2 *desc, *mip_desc;
struct ddraw_texture *texture;
UINT layers, levels, i, j;
unsigned int pitch = 0;
HRESULT hr;
TRACE("ddraw %p, surface_desc %p, surface %p, outer_unknown %p, version %u.\n",
@ -5811,14 +5812,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
{
/* Undocumented feature: Create sublevels until either the
* width or the height is 1. */
DWORD min = desc->dwWidth < desc->dwHeight ? desc->dwWidth : desc->dwHeight;
desc->u2.dwMipMapCount = 0;
while (min)
{
++desc->u2.dwMipMapCount;
min >>= 1;
}
desc->u2.dwMipMapCount = wined3d_log2i(min(desc->dwWidth, desc->dwHeight)) + 1;
}
}
else
@ -5938,6 +5932,15 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
HeapFree(GetProcessHeap(), 0, texture);
return DDERR_INVALIDPARAMS;
}
if ((desc->dwFlags & DDSD_LINEARSIZE)
&& desc->u1.dwLinearSize < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
wined3d_desc.format, wined3d_desc.width) * ((desc->dwHeight + 3) / 4))
{
WARN("Invalid linear size %u specified.\n", desc->u1.dwLinearSize);
HeapFree(GetProcessHeap(), 0, texture);
return DDERR_INVALIDPARAMS;
}
}
else
{
@ -5947,6 +5950,16 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
HeapFree(GetProcessHeap(), 0, texture);
return DDERR_INVALIDPARAMS;
}
if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
{
WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
HeapFree(GetProcessHeap(), 0, texture);
return DDERR_INVALIDPARAMS;
}
pitch = desc->u1.lPitch;
}
}
@ -5974,7 +5987,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
* Commandos: Behind Enemy Lines is another. We set
* WINED3D_SURFACE_PIN_SYSMEM because of this. */
if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, levels,
WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
WINED3D_SURFACE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
{
WARN("Failed to create wined3d texture, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, texture);
@ -6051,6 +6064,14 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
}
}
if ((desc->dwFlags & DDSD_LPSURFACE) && FAILED(hr = wined3d_texture_update_desc(wined3d_texture,
wined3d_desc.width, wined3d_desc.height, wined3d_desc.format,
WINED3D_MULTISAMPLE_NONE, 0, desc->lpSurface, pitch)))
{
ERR("Failed to set surface memory, hr %#x.\n", hr);
goto fail;
}
if (desc->dwFlags & DDSD_BACKBUFFERCOUNT)
{
unsigned int count = desc->u5.dwBackBufferCount;
@ -6078,7 +6099,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
desc->u5.dwBackBufferCount = 0;
if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1,
WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
WINED3D_SURFACE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture)))
{
HeapFree(GetProcessHeap(), 0, texture);
hr = hr_ddraw_from_wined3d(hr);
@ -6126,13 +6147,12 @@ fail:
return hr;
}
HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
{
DDSURFACEDESC2 *desc = &surface->surface_desc;
struct wined3d_resource_desc wined3d_desc;
unsigned int version = texture->version;
HRESULT hr;
surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl;
surface->IDirectDrawSurface4_iface.lpVtbl = &ddraw_surface4_vtbl;
@ -6171,60 +6191,18 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, s
if (format_is_compressed(&desc->u4.ddpfPixelFormat))
{
if (desc->dwFlags & DDSD_LPSURFACE)
{
if ((desc->dwFlags & DDSD_LINEARSIZE)
&& desc->u1.dwLinearSize < wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4))
{
WARN("Invalid linear size %u specified.\n", desc->u1.dwLinearSize);
return DDERR_INVALIDPARAMS;
}
if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
desc->lpSurface, 0)))
{
ERR("Failed to set surface memory, hr %#x.\n", hr);
return hr;
}
desc->dwFlags |= DDSD_LINEARSIZE;
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_PITCH);
desc->u1.dwLinearSize = ~0u;
}
else
{
desc->dwFlags |= DDSD_LINEARSIZE;
desc->dwFlags &= ~DDSD_PITCH;
desc->u1.dwLinearSize = wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4);
}
desc->dwFlags |= DDSD_LINEARSIZE;
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_PITCH);
}
else
{
if (desc->dwFlags & DDSD_LPSURFACE)
{
if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
{
WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
return DDERR_INVALIDPARAMS;
}
if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
desc->lpSurface, desc->u1.lPitch)))
{
ERR("Failed to set surface memory, hr %#x.\n", hr);
return hr;
}
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE);
}
else
{
desc->dwFlags |= DDSD_PITCH;
desc->dwFlags &= ~DDSD_LINEARSIZE;
if (!(desc->dwFlags & DDSD_LPSURFACE))
desc->u1.lPitch = wined3d_surface_get_pitch(wined3d_surface);
}
desc->dwFlags |= DDSD_PITCH;
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE);
}
desc->lpSurface = NULL;
@ -6233,8 +6211,6 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, s
*parent_ops = &ddraw_surface_wined3d_parent_ops;
wined3d_private_store_init(&surface->private_store);
return DD_OK;
}
static void STDMETHODCALLTYPE view_wined3d_object_destroyed(void *parent)

View file

@ -19,6 +19,7 @@ list(APPEND SOURCE
device.c
directx.c
drawprim.c
dxtn.c
gl_compat.c
glsl_shader.c
nvidia_texture_shader.c

View file

@ -817,7 +817,7 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader
max_constantsF -= count_bits(reg_maps->integer_constants);
max_constantsF -= gl_info->reserved_arb_constants;
for (i = 0; i < shader->limits.constant_float; ++i)
for (i = 0; i < shader->limits->constant_float; ++i)
{
DWORD idx = i >> 5;
DWORD shift = i & 0x1f;
@ -893,7 +893,7 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader
}
/* Avoid declaring more constants than needed */
max_constantsF = min(max_constantsF, shader->limits.constant_float);
max_constantsF = min(max_constantsF, shader->limits->constant_float);
/* we use the array-based constants array if the local constants are marked for loading,
* because then we use indirect addressing, or when the local constant list is empty,
@ -1384,8 +1384,8 @@ static const char *shader_arb_get_modifier(const struct wined3d_shader_instructi
static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
const char *dst_str, const char *coord_reg, WORD flags, const char *dsx, const char *dsy)
{
enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[sampler_idx].type;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
const char *tex_type;
BOOL np2_fixup = FALSE;
struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
@ -1398,12 +1398,13 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
/* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */
if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS;
switch(sampler_type) {
case WINED3DSTT_1D:
switch (resource_type)
{
case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
tex_type = "1D";
break;
case WINED3DSTT_2D:
case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
shader = ins->ctx->shader;
device = shader->device;
gl_info = &device->adapter->gl_info;
@ -1423,16 +1424,16 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
}
break;
case WINED3DSTT_VOLUME:
case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
tex_type = "3D";
break;
case WINED3DSTT_CUBE:
case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
tex_type = "CUBE";
break;
default:
ERR("Unexpected texture type %d\n", sampler_type);
ERR("Unexpected resource type %#x.\n", resource_type);
tex_type = "";
}
@ -4251,7 +4252,7 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader,
{
int i;
const char *one = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ONE);
for(i = 0; i < min(8, MAX_REG_TEXCRD); i++)
for(i = 0; i < MAX_REG_TEXCRD; i++)
{
if (reg_maps->texcoord_mask[i] && reg_maps->texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL)
shader_addline(buffer, "MOV result.texcoord[%u].w, %s\n", i, one);
@ -4370,7 +4371,7 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh
shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
pixelshader_update_samplers(shader, args->super.tex_types);
pixelshader_update_resource_types(shader, args->super.tex_types);
if (!shader_buffer_init(&buffer))
{
@ -5231,8 +5232,10 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
/* WINED3DSIH_MOVA */ shader_hw_mov,
/* WINED3DSIH_MOVC */ NULL,
/* WINED3DSIH_MUL */ shader_hw_map2gl,
/* WINED3DSIH_NE */ NULL,
/* WINED3DSIH_NOP */ shader_hw_nop,
/* WINED3DSIH_NRM */ shader_hw_nrm,
/* WINED3DSIH_OR */ NULL,
/* WINED3DSIH_PHASE */ shader_hw_nop,
/* WINED3DSIH_POW */ shader_hw_pow,
/* WINED3DSIH_RCP */ shader_hw_scalar_op,
@ -5273,6 +5276,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
/* WINED3DSIH_TEXREG2GB */ pshader_hw_texreg2gb,
/* WINED3DSIH_TEXREG2RGB */ pshader_hw_texreg2rgb,
/* WINED3DSIH_UDIV */ NULL,
/* WINED3DSIH_UGE */ NULL,
/* WINED3DSIH_USHR */ NULL,
/* WINED3DSIH_UTOF */ NULL,
/* WINED3DSIH_XOR */ NULL,
@ -6529,7 +6533,11 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
}
context->last_was_pshader = FALSE;
} else {
}
else if (!context->last_was_pshader)
{
if (device->shader_backend == &arb_program_shader_backend)
context->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
context->last_was_pshader = TRUE;
}
@ -7243,7 +7251,7 @@ static GLuint gen_p8_shader(struct arbfp_blit_priv *priv,
/* The alpha-component contains the palette index */
if(textype == GL_TEXTURE_RECTANGLE_ARB)
shader_addline(&buffer, "TXP index, fragment.texcoord[0], texture[0], RECT;\n");
shader_addline(&buffer, "TEX index, fragment.texcoord[0], texture[0], RECT;\n");
else
shader_addline(&buffer, "TEX index, fragment.texcoord[0], texture[0], 2D;\n");
@ -7282,7 +7290,7 @@ static void upload_palette(const struct wined3d_texture *texture, struct wined3d
if (!priv->palette_texture)
gl_info->gl_ops.gl.p_glGenTextures(1, &priv->palette_texture);
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1));
GL_EXTCALL(glActiveTexture(GL_TEXTURE1));
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, priv->palette_texture);
gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -7463,7 +7471,7 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context,
struct arbfp_blit_type type;
struct arbfp_blit_desc *desc;
if (surface->flags & SFLAG_CONVERTED)
if (surface->container->flags & WINED3D_TEXTURE_CONVERTED)
{
gl_info->gl_ops.gl.p_glEnable(textype);
checkGLcall("glEnable(textype)");

View file

@ -102,8 +102,8 @@ static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_g
{
if(!This->buffer_object) return;
GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
checkGLcall("glDeleteBuffersARB");
GL_EXTCALL(glDeleteBuffers(1, &This->buffer_object));
checkGLcall("glDeleteBuffers");
This->buffer_object = 0;
if(This->query)
@ -137,7 +137,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine
* to be verified to check if the rhw and color values are in the correct
* format. */
GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object));
GL_EXTCALL(glGenBuffers(1, &This->buffer_object));
error = gl_info->gl_ops.gl.p_glGetError();
if (!This->buffer_object || error != GL_NO_ERROR)
{
@ -147,7 +147,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine
if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
context_invalidate_state(context, STATE_INDEXBUFFER);
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object));
error = gl_info->gl_ops.gl.p_glGetError();
if (error != GL_NO_ERROR)
{
@ -178,11 +178,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine
* calling glBufferSubData on updates. Upload the actual data in case
* we're not double buffering, so we can release the heap mem afterwards
*/
GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, This->resource.heap_memory, gl_usage));
GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, This->resource.heap_memory, gl_usage));
error = gl_info->gl_ops.gl.p_glGetError();
if (error != GL_NO_ERROR)
{
ERR("glBufferDataARB failed with error %s (%#x)\n", debug_glerror(error), error);
ERR("glBufferData failed with error %s (%#x)\n", debug_glerror(error), error);
goto fail;
}
@ -263,7 +263,7 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This,
#define WINED3D_BUFFER_FIXUP_XYZRHW 0x02
static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
UINT attrib_idx, DWORD fixup_flags, DWORD *stride_this_run)
const struct wined3d_state *state, UINT attrib_idx, DWORD fixup_flags, DWORD *stride_this_run)
{
const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
enum wined3d_format_id format;
@ -273,7 +273,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
* there, on nonexistent attribs the vbo is 0.
*/
if (!(si->use_map & (1 << attrib_idx))
|| attrib->data.buffer_object != This->buffer_object)
|| state->streams[attrib->stream_idx].buffer != This)
return FALSE;
format = attrib->format->id;
@ -301,7 +301,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
}
static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
DWORD fixup_flags)
const struct wined3d_state *state, DWORD fixup_flags)
{
UINT stride_this_run = 0;
BOOL ret = FALSE;
@ -375,31 +375,31 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_s
* texcoord needs no conversion while a FLOAT4 positiont needs one
*/
ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_POSITION,
fixup_flags, &stride_this_run) || ret;
fixup_flags &= ~WINED3D_BUFFER_FIXUP_XYZRHW;
ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_NORMAL,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_DIFFUSE,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_SPECULAR,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_SPECULAR,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD0,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD0,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD1,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD1,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD2,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD2,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD3,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD3,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD4,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD4,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD5,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD5,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD6,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD6,
fixup_flags, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD7,
ret = buffer_check_attribute(This, si, state, WINED3D_FFP_TEXCOORD7,
fixup_flags, &stride_this_run) || ret;
if (!stride_this_run && This->conversion_map)
@ -497,8 +497,8 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *con
if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
context_invalidate_state(context, STATE_INDEXBUFFER);
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
GL_EXTCALL(glGetBufferSubDataARB(This->buffer_type_hint, 0, This->resource.size, This->resource.heap_memory));
GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object));
GL_EXTCALL(glGetBufferSubData(This->buffer_type_hint, 0, This->resource.size, This->resource.heap_memory));
This->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
return This->resource.heap_memory;
@ -586,8 +586,8 @@ static void buffer_sync_apple(struct wined3d_buffer *This, DWORD flags, const st
if (flags & WINED3D_MAP_DISCARD)
{
GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage));
checkGLcall("glBufferDataARB\n");
GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage));
checkGLcall("glBufferData");
return;
}
@ -651,8 +651,8 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined
/* This potentially invalidates the element array buffer binding, but the
* caller always takes care of this. */
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object));
checkGLcall("glBindBuffer");
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
GLbitfield mapflags;
@ -676,8 +676,8 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined
syncflags |= WINED3D_MAP_NOOVERWRITE;
buffer_sync_apple(This, syncflags, gl_info);
}
map = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_WRITE_ONLY_ARB));
checkGLcall("glMapBufferARB");
map = GL_EXTCALL(glMapBuffer(This->buffer_type_hint, GL_WRITE_ONLY));
checkGLcall("glMapBuffer");
}
if (!map)
{
@ -704,8 +704,8 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined
checkGLcall("glFlushMappedBufferRangeAPPLE");
}
}
GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
checkGLcall("glUnmapBufferARB");
GL_EXTCALL(glUnmapBuffer(This->buffer_type_hint));
checkGLcall("glUnmapBuffer");
}
void buffer_mark_used(struct wined3d_buffer *buffer)
@ -764,7 +764,7 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte
fixup_flags |= WINED3D_BUFFER_FIXUP_XYZRHW;
}
decl_changed = buffer_find_decl(buffer, &context->stream_info, fixup_flags);
decl_changed = buffer_find_decl(buffer, &context->stream_info, state, fixup_flags);
buffer->flags |= WINED3D_BUFFER_HASDESC;
}
@ -910,10 +910,10 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte
}
}
GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(buffer->buffer_type_hint, start, len, data + start));
checkGLcall("glBufferSubDataARB");
GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object));
checkGLcall("glBindBuffer");
GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, start, len, data + start));
checkGLcall("glBufferSubData");
}
HeapFree(GetProcessHeap(), 0, data);
@ -976,7 +976,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN
if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
context_invalidate_state(context, STATE_INDEXBUFFER);
GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object));
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
@ -989,17 +989,17 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN
{
if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
buffer_sync_apple(buffer, flags, gl_info);
buffer->map_ptr = GL_EXTCALL(glMapBufferARB(buffer->buffer_type_hint,
GL_READ_WRITE_ARB));
checkGLcall("glMapBufferARB");
buffer->map_ptr = GL_EXTCALL(glMapBuffer(buffer->buffer_type_hint,
GL_READ_WRITE));
checkGLcall("glMapBuffer");
}
if (((DWORD_PTR)buffer->map_ptr) & (RESOURCE_ALIGNMENT - 1))
{
WARN("Pointer %p is not %u byte aligned.\n", buffer->map_ptr, RESOURCE_ALIGNMENT);
GL_EXTCALL(glUnmapBufferARB(buffer->buffer_type_hint));
checkGLcall("glUnmapBufferARB");
GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint));
checkGLcall("glUnmapBuffer");
buffer->map_ptr = NULL;
if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)
@ -1075,7 +1075,7 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer)
if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
context_invalidate_state(context, STATE_INDEXBUFFER);
GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object));
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
@ -1096,7 +1096,7 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer)
}
}
GL_EXTCALL(glUnmapBufferARB(buffer->buffer_type_hint));
GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint));
if (wined3d_settings.strict_draw_ordering)
gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);

View file

@ -133,7 +133,7 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
{
case WINED3D_LOCATION_TEXTURE_RGB:
case WINED3D_LOCATION_TEXTURE_SRGB:
surface_prepare_texture(depth_stencil, context, FALSE);
wined3d_texture_prepare_texture(depth_stencil->container, context, FALSE);
if (format_flags & WINED3DFMT_FLAG_DEPTH)
{
@ -209,7 +209,7 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
case WINED3D_LOCATION_TEXTURE_RGB:
case WINED3D_LOCATION_TEXTURE_SRGB:
srgb = location == WINED3D_LOCATION_TEXTURE_SRGB;
surface_prepare_texture(surface, context, srgb);
wined3d_texture_prepare_texture(surface->container, context, srgb);
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
surface->texture_target, surface_get_texture_name(surface, gl_info, srgb),
surface->texture_level);
@ -429,7 +429,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ
/* Set valid read and draw buffer bindings to satisfy pedantic pre-ES2_compatibility
* GL contexts requirements. */
glReadBuffer(GL_NONE);
gl_info->gl_ops.gl.p_glReadBuffer(GL_NONE);
context_set_draw_buffer(context, GL_NONE);
if (target != GL_FRAMEBUFFER)
{
@ -496,8 +496,8 @@ void context_alloc_occlusion_query(struct wined3d_context *context, struct wined
{
if (gl_info->supported[ARB_OCCLUSION_QUERY])
{
GL_EXTCALL(glGenQueriesARB(1, &query->id));
checkGLcall("glGenQueriesARB");
GL_EXTCALL(glGenQueries(1, &query->id));
checkGLcall("glGenQueries");
TRACE("Allocated occlusion query %u in context %p.\n", query->id, context);
}
@ -617,8 +617,8 @@ void context_alloc_timestamp_query(struct wined3d_context *context, struct wined
}
else
{
GL_EXTCALL(glGenQueriesARB(1, &query->id));
checkGLcall("glGenQueriesARB");
GL_EXTCALL(glGenQueries(1, &query->id));
checkGLcall("glGenQueries");
TRACE("Allocated timestamp query %u in context %p.\n", query->id, context);
}
@ -758,47 +758,11 @@ void context_surface_update(struct wined3d_context *context, const struct wined3
}
}
static BOOL context_restore_pixel_format(struct wined3d_context *ctx)
static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC dc, int format)
{
const struct wined3d_gl_info *gl_info = ctx->gl_info;
BOOL ret = FALSE;
int current = GetPixelFormat(dc);
if (ctx->restore_pf && IsWindow(ctx->restore_pf_win))
{
if (ctx->gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH])
{
HDC dc = GetDC(ctx->restore_pf_win);
if (dc)
{
if (!(ret = GL_EXTCALL(wglSetPixelFormatWINE(dc, ctx->restore_pf))))
{
ERR("wglSetPixelFormatWINE failed to restore pixel format %d on window %p.\n",
ctx->restore_pf, ctx->restore_pf_win);
}
ReleaseDC(ctx->restore_pf_win, dc);
}
}
else
{
ERR("can't restore pixel format %d on window %p\n", ctx->restore_pf, ctx->restore_pf_win);
}
}
ctx->restore_pf = 0;
ctx->restore_pf_win = NULL;
return ret;
}
static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BOOL private, int format)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
int current;
if (dc == context->hdc && context->hdc_is_private && context->hdc_has_format)
return TRUE;
current = GetPixelFormat(dc);
if (current == format) goto success;
if (current == format) return TRUE;
if (!current)
{
@ -809,10 +773,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO
format, dc, GetLastError());
return FALSE;
}
context->restore_pf = 0;
context->restore_pf_win = private ? NULL : WindowFromDC(dc);
goto success;
return TRUE;
}
/* By default WGL doesn't allow pixel format adjustments but we need it
@ -821,25 +782,13 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO
* when really needed. */
if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH])
{
HWND win;
if (!GL_EXTCALL(wglSetPixelFormatWINE(dc, format)))
{
ERR("wglSetPixelFormatWINE failed to set pixel format %d on device context %p.\n",
format, dc);
return FALSE;
}
win = private ? NULL : WindowFromDC(dc);
if (win != context->restore_pf_win)
{
context_restore_pixel_format(context);
context->restore_pf = private ? 0 : current;
context->restore_pf_win = win;
}
goto success;
return TRUE;
}
/* OpenGL doesn't allow pixel format adjustments. Print an error and
@ -849,11 +798,6 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO
ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n",
format, dc, current);
return TRUE;
success:
if (dc == context->hdc && context->hdc_is_private)
context->hdc_has_format = TRUE;
return TRUE;
}
static BOOL context_set_gl_context(struct wined3d_context *ctx)
@ -861,7 +805,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
struct wined3d_swapchain *swapchain = ctx->swapchain;
BOOL backup = FALSE;
if (!context_set_pixel_format(ctx, ctx->hdc, ctx->hdc_is_private, ctx->pixel_format))
if (!context_set_pixel_format(ctx->gl_info, ctx->hdc, ctx->pixel_format))
{
WARN("Failed to set pixel format %d on device context %p.\n",
ctx->pixel_format, ctx->hdc);
@ -894,7 +838,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
return FALSE;
}
if (!context_set_pixel_format(ctx, dc, TRUE, ctx->pixel_format))
if (!context_set_pixel_format(ctx->gl_info, dc, ctx->pixel_format))
{
ERR("Failed to set pixel format %d on device context %p.\n",
ctx->pixel_format, dc);
@ -916,8 +860,15 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
return TRUE;
}
static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HDC dc, HGLRC gl_ctx)
static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HDC dc, HGLRC gl_ctx, int pf)
{
if (!context_set_pixel_format(gl_info, dc, pf))
{
ERR("Failed to restore pixel format %d on device context %p.\n", pf, dc);
context_set_current(NULL);
return;
}
if (!wglMakeCurrent(dc, gl_ctx))
{
ERR("Failed to restore GL context %p on device context %p, last error %#x.\n",
@ -938,8 +889,6 @@ static void context_update_window(struct wined3d_context *context)
wined3d_release_dc(context->win_handle, context->hdc);
context->win_handle = context->swapchain->win_handle;
context->hdc_is_private = FALSE;
context->hdc_has_format = FALSE;
context->needs_set = 1;
context->valid = 1;
@ -960,9 +909,11 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
HGLRC restore_ctx;
HDC restore_dc;
unsigned int i;
int restore_pf;
restore_ctx = wglGetCurrentContext();
restore_dc = wglGetCurrentDC();
restore_pf = GetPixelFormat(restore_dc);
if (restore_ctx == context->glCtx)
restore_ctx = NULL;
@ -972,14 +923,14 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
LIST_FOR_EACH_ENTRY(timestamp_query, &context->timestamp_queries, struct wined3d_timestamp_query, entry)
{
if (context->valid)
GL_EXTCALL(glDeleteQueriesARB(1, &timestamp_query->id));
GL_EXTCALL(glDeleteQueries(1, &timestamp_query->id));
timestamp_query->context = NULL;
}
LIST_FOR_EACH_ENTRY(occlusion_query, &context->occlusion_queries, struct wined3d_occlusion_query, entry)
{
if (context->valid && gl_info->supported[ARB_OCCLUSION_QUERY])
GL_EXTCALL(glDeleteQueriesARB(1, &occlusion_query->id));
GL_EXTCALL(glDeleteQueries(1, &occlusion_query->id));
occlusion_query->context = NULL;
}
@ -1017,10 +968,10 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
}
if (gl_info->supported[ARB_TIMER_QUERY])
GL_EXTCALL(glDeleteQueriesARB(context->free_timestamp_query_count, context->free_timestamp_queries));
GL_EXTCALL(glDeleteQueries(context->free_timestamp_query_count, context->free_timestamp_queries));
if (gl_info->supported[ARB_OCCLUSION_QUERY])
GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, context->free_occlusion_queries));
GL_EXTCALL(glDeleteQueries(context->free_occlusion_query_count, context->free_occlusion_queries));
if (gl_info->supported[ARB_SYNC])
{
@ -1051,10 +1002,9 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
HeapFree(GetProcessHeap(), 0, context->free_event_queries);
context_restore_pixel_format(context);
if (restore_ctx)
{
context_restore_gl_context(gl_info, restore_dc, restore_ctx);
context_restore_gl_context(gl_info, restore_dc, restore_ctx, restore_pf);
}
else if (wglGetCurrentContext() && !wglMakeCurrent(NULL, NULL))
{
@ -1150,17 +1100,12 @@ void context_release(struct wined3d_context *context)
WARN("Context %p is not the current context.\n", context);
}
if (!--context->level)
if (!--context->level && context->restore_ctx)
{
if (context_restore_pixel_format(context))
context->needs_set = 1;
if (context->restore_ctx)
{
TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc);
context_restore_gl_context(context->gl_info, context->restore_dc, context->restore_ctx);
context->restore_ctx = NULL;
context->restore_dc = NULL;
}
TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc);
context_restore_gl_context(context->gl_info, context->restore_dc, context->restore_ctx, context->restore_pf);
context->restore_ctx = NULL;
context->restore_dc = NULL;
}
}
@ -1179,11 +1124,9 @@ static void context_enter(struct wined3d_context *context)
current_gl, wglGetCurrentDC());
context->restore_ctx = current_gl;
context->restore_dc = wglGetCurrentDC();
context->restore_pf = GetPixelFormat(context->restore_dc);
context->needs_set = 1;
}
else if (!context->needs_set && !(context->hdc_is_private && context->hdc_has_format)
&& context->pixel_format != GetPixelFormat(context->hdc))
context->needs_set = 1;
}
}
@ -1320,8 +1263,8 @@ static void bind_dummy_textures(const struct wined3d_device *device, const struc
for (i = 0; i < count; ++i)
{
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
checkGLcall("glActiveTextureARB");
GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i));
checkGLcall("glActiveTexture");
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[i]);
checkGLcall("glBindTexture");
@ -1391,7 +1334,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
int swap_interval;
DWORD state;
HDC hdc;
BOOL hdc_is_private = FALSE;
TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle);
@ -1459,9 +1401,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
{
WARN("Failed to retireve device context, trying swapchain backup.\n");
if ((hdc = swapchain_get_backup_dc(swapchain)))
hdc_is_private = TRUE;
else
if (!(hdc = swapchain_get_backup_dc(swapchain)))
{
ERR("Failed to retrieve a device context.\n");
goto out;
@ -1510,9 +1450,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
context_enter(ret);
ret->gl_info = gl_info;
if (!context_set_pixel_format(ret, hdc, hdc_is_private, pixel_format))
if (!context_set_pixel_format(gl_info, hdc, pixel_format))
{
ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc);
context_release(ret);
@ -1567,6 +1505,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
goto out;
}
ret->gl_info = gl_info;
ret->d3d_info = &device->adapter->d3d_info;
ret->state_table = device->StateTable;
@ -1589,8 +1528,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
ret->glCtx = ctx;
ret->win_handle = swapchain->win_handle;
ret->hdc = hdc;
ret->hdc_is_private = hdc_is_private;
ret->hdc_has_format = TRUE;
ret->pixel_format = pixel_format;
ret->needs_set = 1;
@ -1677,7 +1614,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);
checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);");
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);");
if (gl_info->supported[ARB_VERTEX_BLEND])
@ -1912,6 +1849,8 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
context_invalidate_state(context, STATE_SAMPLER(sampler));
}
}
if (gl_info->supported[ARB_SAMPLER_OBJECTS])
GL_EXTCALL(glBindSampler(0, 0));
context_active_texture(context, gl_info, 0);
sampler = context->rev_tex_unit_map[0];
@ -2072,7 +2011,7 @@ static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt
if (gl_info->supported[ARB_DRAW_BUFFERS])
{
GL_EXTCALL(glDrawBuffersARB(i, context->draw_buffers));
GL_EXTCALL(glDrawBuffers(i, context->draw_buffers));
checkGLcall("glDrawBuffers()");
}
else
@ -2107,8 +2046,8 @@ void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer)
/* Context activation is done by the caller. */
void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit)
{
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0 + unit));
checkGLcall("glActiveTextureARB");
GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + unit));
checkGLcall("glActiveTexture");
context->active_texture = unit;
}
@ -2577,14 +2516,14 @@ static void context_map_fixed_function_samplers(struct wined3d_context *context,
static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state)
{
const enum wined3d_sampler_texture_type *sampler_type =
state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type;
const struct wined3d_shader_resource_info *resource_info =
state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
unsigned int i;
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (sampler_type[i] && context->tex_unit_map[i] != i)
if (resource_info[i].type && context->tex_unit_map[i] != i)
{
context_map_stage(context, i, i);
context_invalidate_state(context, STATE_SAMPLER(i));
@ -2595,8 +2534,8 @@ static void context_map_psamplers(struct wined3d_context *context, const struct
}
static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
const enum wined3d_sampler_texture_type *pshader_sampler_tokens,
const enum wined3d_sampler_texture_type *vshader_sampler_tokens, DWORD unit)
const struct wined3d_shader_resource_info *ps_resource_info,
const struct wined3d_shader_resource_info *vs_resource_info, DWORD unit)
{
DWORD current_mapping = context->rev_tex_unit_map[unit];
@ -2608,39 +2547,39 @@ static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
{
/* Used by a fragment sampler */
if (!pshader_sampler_tokens)
if (!ps_resource_info)
{
/* No pixel shader, check fixed function */
return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1 << current_mapping));
}
/* Pixel shader, check the shader's sampler map */
return !pshader_sampler_tokens[current_mapping];
return !ps_resource_info[current_mapping].type;
}
/* Used by a vertex sampler */
return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS];
return !vs_resource_info[current_mapping - MAX_FRAGMENT_SAMPLERS].type;
}
static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state)
{
const enum wined3d_sampler_texture_type *vshader_sampler_type =
state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.sampler_type;
const enum wined3d_sampler_texture_type *pshader_sampler_type = NULL;
const struct wined3d_shader_resource_info *vs_resource_info =
state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info;
const struct wined3d_shader_resource_info *ps_resource_info = NULL;
const struct wined3d_gl_info *gl_info = context->gl_info;
int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
int i;
/* Note that we only care if a resource is used or not, not the
* resource's specific type. Otherwise we'd need to call
* shader_update_samplers() here for 1.x pixelshaders. */
if (ps)
{
/* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
* Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
pshader_sampler_type = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type;
}
ps_resource_info = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
{
DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
if (vshader_sampler_type[i])
if (vs_resource_info[i].type)
{
if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
{
@ -2650,7 +2589,7 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
while (start >= 0)
{
if (context_unit_free_for_vs(context, pshader_sampler_type, vshader_sampler_type, start))
if (context_unit_free_for_vs(context, ps_resource_info, vs_resource_info, start))
{
context_map_stage(context, vsampler_idx, start);
context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
@ -2922,7 +2861,7 @@ static void context_preload_textures(struct wined3d_context *context, const stru
{
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
{
if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.sampler_type[i])
if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info[i].type)
context_preload_texture(context, state, MAX_FRAGMENT_SAMPLERS + i);
}
}
@ -2931,7 +2870,7 @@ static void context_preload_textures(struct wined3d_context *context, const stru
{
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.sampler_type[i])
if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info[i].type)
context_preload_texture(context, state, i);
}
}
@ -2947,6 +2886,74 @@ static void context_preload_textures(struct wined3d_context *context, const stru
}
}
static void context_bind_shader_resources(struct wined3d_context *context, const struct wined3d_state *state)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_shader_sampler_map_entry *entry;
struct wined3d_shader_resource_view *view;
struct wined3d_sampler *sampler;
struct wined3d_texture *texture;
struct wined3d_shader *shader;
unsigned int i, j, count;
static const struct
{
enum wined3d_shader_type type;
unsigned int base_idx;
unsigned int count;
}
shader_types[] =
{
{WINED3D_SHADER_TYPE_PIXEL, 0, MAX_FRAGMENT_SAMPLERS},
{WINED3D_SHADER_TYPE_VERTEX, MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS},
};
for (i = 0; i < ARRAY_SIZE(shader_types); ++i)
{
if (!(shader = state->shader[shader_types[i].type]))
continue;
count = shader->reg_maps.sampler_map.count;
if (count > shader_types[i].count)
{
FIXME("Shader %p needs %u samplers, but only %u are supported.\n",
shader, count, shader_types[i].count);
count = shader_types[i].count;
}
for (j = 0; j < count; ++j)
{
entry = &shader->reg_maps.sampler_map.entries[j];
if (!(view = state->shader_resource_view[shader_types[i].type][entry->resource_idx]))
{
WARN("No resource view bound at index %u, %u.\n", shader_types[i].type, entry->resource_idx);
continue;
}
if (view->resource->type == WINED3D_RTYPE_BUFFER)
{
FIXME("Buffer shader resources not supported.\n");
continue;
}
if (!(sampler = state->sampler[shader_types[i].type][entry->sampler_idx]))
{
WARN("No sampler object bound at index %u, %u.\n", shader_types[i].type, entry->sampler_idx);
continue;
}
texture = wined3d_texture_from_resource(view->resource);
wined3d_texture_load(texture, context, FALSE);
context_active_texture(context, gl_info, shader_types[i].base_idx + entry->bind_idx);
wined3d_texture_bind(texture, context, FALSE);
GL_EXTCALL(glBindSampler(shader_types[i].base_idx + entry->bind_idx, sampler->name));
checkGLcall("glBindSampler");
}
}
}
/* Context activation is done by the caller. */
BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device)
{
@ -3020,6 +3027,12 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
context->constant_update_mask = 0;
}
if (context->update_shader_resource_bindings)
{
context_bind_shader_resources(context, state);
context->update_shader_resource_bindings = 0;
}
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
context_check_fbo_status(context, GL_FRAMEBUFFER);

View file

@ -634,10 +634,15 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
if (op->texture)
{
const struct wined3d_format *new_format = op->texture->resource.format;
const struct wined3d_format *old_format = prev ? prev->resource.format : NULL;
if (InterlockedIncrement(&op->texture->resource.bind_count) == 1)
op->texture->sampler = op->stage;
if (!prev || op->texture->target != prev->target)
if (!prev || op->texture->target != prev->target
|| !is_same_fixup(new_format->color_fixup, old_format->color_fixup)
|| (new_format->flags & WINED3DFMT_FLAG_SHADOW) != (old_format->flags & WINED3DFMT_FLAG_SHADOW))
device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
@ -697,6 +702,7 @@ static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, cons
const struct wined3d_cs_set_shader_resource_view *op = data;
cs->state.shader_resource_view[op->type][op->view_idx] = op->view;
device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
}
void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type,
@ -718,6 +724,7 @@ static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data)
const struct wined3d_cs_set_sampler *op = data;
cs->state.sampler[op->type][op->sampler_idx] = op->sampler;
device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
}
void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type,
@ -740,6 +747,7 @@ static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
cs->state.shader[op->type] = op->shader;
device_invalidate_state(cs->device, STATE_SHADER(op->type));
device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
}
void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader)

View file

@ -471,6 +471,13 @@ ULONG CDECL wined3d_device_incref(struct wined3d_device *device)
return refcount;
}
static void device_leftover_sampler(struct wine_rb_entry *entry, void *context)
{
struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
ERR("Leftover sampler %p.\n", sampler);
}
ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
{
ULONG refcount = InterlockedDecrement(&device->ref);
@ -514,6 +521,8 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
DestroyCursor(device->hardwareCursor);
device->hardwareCursor = 0;
wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL);
wined3d_decref(device->wined3d);
device->wined3d = NULL;
HeapFree(GetProcessHeap(), 0, device);
@ -583,7 +592,7 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
desc.depth = 1;
desc.size = 0;
if (FAILED(hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE,
NULL, &wined3d_null_parent_ops, &device->logo_texture)))
NULL, NULL, &wined3d_null_parent_ops, &device->logo_texture)))
{
ERR("Wine logo requested, but failed to create texture, hr %#x.\n", hr);
goto out;
@ -599,7 +608,7 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
color_key.color_space_low_value = 0;
color_key.color_space_high_value = 0;
wined3d_texture_set_color_key(device->logo_texture, WINEDDCKEY_SRCBLT, &color_key);
wined3d_texture_set_color_key(device->logo_texture, WINED3D_CKEY_SRC_BLT, &color_key);
}
else
{
@ -667,7 +676,7 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]);
checkGLcall("glBindTexture");
GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
checkGLcall("glTexImage3D");
}
@ -1012,6 +1021,13 @@ err_out:
return hr;
}
static void device_free_sampler(struct wine_rb_entry *entry, void *context)
{
struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
wined3d_sampler_decref(sampler);
}
HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
{
struct wined3d_resource *resource, *cursor;
@ -1046,6 +1062,8 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
resource->resource_ops->resource_unload(resource);
}
wine_rb_clear(&device->samplers, device_free_sampler, NULL);
/* Destroy the depth blt resources, they will be invalid after the reset. Also free shader
* private data, it might contain opengl pointers
*/
@ -3011,7 +3029,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device,
e->data.addr += (ULONG_PTR)buffer_get_sysmem(buffer, context);
if (buffer->buffer_object)
{
GL_EXTCALL(glDeleteBuffersARB(1, &buffer->buffer_object));
GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object));
buffer->buffer_object = 0;
}
if (e->data.addr)
@ -3447,9 +3465,9 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device
static HRESULT device_update_volume(struct wined3d_device *device,
struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume)
{
struct wined3d_const_bo_address data;
struct wined3d_map_desc src;
HRESULT hr;
struct wined3d_bo_address data;
struct wined3d_context *context;
TRACE("device %p, src_volume %p, dst_volume %p.\n",
@ -3473,7 +3491,9 @@ static HRESULT device_update_volume(struct wined3d_device *device,
context = context_acquire(device, NULL);
wined3d_volume_load(dst_volume, context, FALSE);
/* Only a prepare, since we're uploading the entire volume. */
wined3d_texture_prepare_texture(dst_volume->container, context, FALSE);
wined3d_texture_bind(dst_volume->container, context, FALSE);
data.buffer_object = 0;
data.addr = src.data;
@ -3978,13 +3998,11 @@ void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device,
static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device,
struct wined3d_surface *cursor_image)
{
struct wined3d_sub_resource_data data;
struct wined3d_resource_desc desc;
struct wined3d_map_desc map_desc;
struct wined3d_texture *texture;
struct wined3d_surface *surface;
BYTE *src_data, *dst_data;
unsigned int src_pitch;
unsigned int i;
HRESULT hr;
if (FAILED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY)))
{
@ -3992,8 +4010,9 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined
return NULL;
}
src_pitch = map_desc.row_pitch;
src_data = map_desc.data;
data.data = map_desc.data;
data.row_pitch = map_desc.row_pitch;
data.slice_pitch = map_desc.slice_pitch;
desc.resource_type = WINED3D_RTYPE_TEXTURE;
desc.format = WINED3DFMT_B8G8R8A8_UNORM;
@ -4006,31 +4025,15 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined
desc.depth = 1;
desc.size = 0;
if (FAILED(wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE,
NULL, &wined3d_null_parent_ops, &texture)))
hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE,
&data, NULL, &wined3d_null_parent_ops, &texture);
wined3d_surface_unmap(cursor_image);
if (FAILED(hr))
{
ERR("Failed to create cursor texture.\n");
wined3d_surface_unmap(cursor_image);
return NULL;
}
surface = surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
if (FAILED(wined3d_surface_map(surface, &map_desc, NULL, WINED3D_MAP_DISCARD)))
{
ERR("Failed to map destination surface.\n");
wined3d_texture_decref(texture);
wined3d_surface_unmap(cursor_image);
return NULL;
}
dst_data = map_desc.data;
for (i = 0; i < desc.height; ++i)
memcpy(&dst_data[map_desc.row_pitch * i], &src_data[src_pitch * i], desc.width * 4);
wined3d_surface_unmap(surface);
wined3d_surface_unmap(cursor_image);
return texture;
}
@ -4313,7 +4316,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
struct wined3d_resource *resource, *cursor;
struct wined3d_swapchain *swapchain;
struct wined3d_display_mode m;
BOOL DisplayModeChanged = FALSE;
BOOL DisplayModeChanged;
BOOL update_desc = FALSE;
UINT backbuffer_width = swapchain_desc->backbuffer_width;
UINT backbuffer_height = swapchain_desc->backbuffer_height;
@ -4327,6 +4330,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
ERR("Failed to get the first implicit swapchain.\n");
return WINED3DERR_INVALIDCALL;
}
DisplayModeChanged = swapchain->reapply_mode;
if (reset_state)
{
@ -4489,16 +4493,14 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
{
UINT i;
if (FAILED(hr = wined3d_surface_update_desc(surface_from_resource(
wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)), swapchain->desc.backbuffer_width,
if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width,
swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
return hr;
for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
{
if (FAILED(hr = wined3d_surface_update_desc(surface_from_resource(
wined3d_texture_get_sub_resource(swapchain->back_buffers[i], 0)), swapchain->desc.backbuffer_width,
if (FAILED(hr = wined3d_texture_update_desc(swapchain->back_buffers[i], swapchain->desc.backbuffer_width,
swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
return hr;
@ -4595,6 +4597,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
swapchain_desc->backbuffer_height,
TRUE);
}
swapchain->d3d_mode = m;
}
else if (!swapchain->desc.windowed)
{
@ -4621,6 +4624,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
device->exStyle = exStyle;
}
wine_rb_clear(&device->samplers, device_free_sampler, NULL);
if (reset_state)
{
TRACE("Resetting stateblock.\n");
@ -4858,6 +4863,21 @@ struct wined3d_surface * CDECL wined3d_device_get_surface_from_dc(const struct w
return NULL;
}
static int wined3d_sampler_compare(const void *key, const struct wine_rb_entry *entry)
{
const struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
return memcmp(&sampler->desc, key, sizeof(sampler->desc));
}
static const struct wine_rb_functions wined3d_sampler_rb_functions =
{
wined3d_rb_alloc,
wined3d_rb_realloc,
wined3d_rb_free,
wined3d_sampler_compare,
};
HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
BYTE surface_alignment, struct wined3d_device_parent *device_parent)
@ -4889,12 +4909,19 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
fragment_pipeline = adapter->fragment_pipe;
if (wine_rb_init(&device->samplers, &wined3d_sampler_rb_functions) == -1)
{
ERR("Failed to initialize sampler rbtree.\n");
return E_OUTOFMEMORY;
}
if (vertex_pipeline->vp_states && fragment_pipeline->states
&& FAILED(hr = compile_state_table(device->StateTable, device->multistate_funcs,
&adapter->gl_info, &adapter->d3d_info, vertex_pipeline,
fragment_pipeline, misc_state_template)))
{
ERR("Failed to compile state table, hr %#x.\n", hr);
wine_rb_destroy(&device->samplers, NULL, NULL);
wined3d_decref(device->wined3d);
return hr;
}
@ -4924,6 +4951,7 @@ err:
{
HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
}
wine_rb_destroy(&device->samplers, NULL, NULL);
wined3d_decref(device->wined3d);
return hr;
}
@ -4952,7 +4980,7 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state)
LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc)
{
if (device->filter_messages)
if (device->filter_messages && message != WM_DISPLAYCHANGE)
{
TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n",
window, message, wparam, lparam);
@ -4976,8 +5004,23 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
}
else if (message == WM_ACTIVATEAPP)
{
UINT i;
for (i = 0; i < device->swapchain_count; i++)
wined3d_swapchain_activate(device->swapchains[i], wparam);
device->device_parent->ops->activate(device->device_parent, wparam);
}
else if (message == WM_SYSCOMMAND)
{
if (wparam == SC_RESTORE && device->wined3d->flags & WINED3D_HANDLE_RESTORE)
{
if (unicode)
DefWindowProcW(window, message, wparam, lparam);
else
DefWindowProcA(window, message, wparam, lparam);
}
}
if (unicode)
return CallWindowProcW(proc, window, message, wparam, lparam);

File diff suppressed because it is too large Load diff

View file

@ -54,9 +54,9 @@ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primit
}
else
{
GL_EXTCALL(glDrawElementsInstancedARB(primitive_type, count, idxtype,
GL_EXTCALL(glDrawElementsInstanced(primitive_type, count, idxtype,
(const char *)idx_data + (idx_size * start_idx), instance_count));
checkGLcall("glDrawElementsInstancedARB");
checkGLcall("glDrawElementsInstanced");
}
}
}
@ -340,20 +340,20 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info,
switch(format)
{
case WINED3DFMT_R32_FLOAT:
GL_EXTCALL(glVertexAttrib1fvARB(index, ptr));
GL_EXTCALL(glVertexAttrib1fv(index, ptr));
break;
case WINED3DFMT_R32G32_FLOAT:
GL_EXTCALL(glVertexAttrib2fvARB(index, ptr));
GL_EXTCALL(glVertexAttrib2fv(index, ptr));
break;
case WINED3DFMT_R32G32B32_FLOAT:
GL_EXTCALL(glVertexAttrib3fvARB(index, ptr));
GL_EXTCALL(glVertexAttrib3fv(index, ptr));
break;
case WINED3DFMT_R32G32B32A32_FLOAT:
GL_EXTCALL(glVertexAttrib4fvARB(index, ptr));
GL_EXTCALL(glVertexAttrib4fv(index, ptr));
break;
case WINED3DFMT_R8G8B8A8_UINT:
GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr));
GL_EXTCALL(glVertexAttrib4ubv(index, ptr));
break;
case WINED3DFMT_B8G8R8A8_UNORM:
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
@ -362,38 +362,38 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info,
DWORD c = *src & 0xff00ff00;
c |= (*src & 0xff0000) >> 16;
c |= (*src & 0xff) << 16;
GL_EXTCALL(glVertexAttrib4NubvARB(index, (GLubyte *)&c));
GL_EXTCALL(glVertexAttrib4Nubv(index, (GLubyte *)&c));
break;
}
/* else fallthrough */
case WINED3DFMT_R8G8B8A8_UNORM:
GL_EXTCALL(glVertexAttrib4NubvARB(index, ptr));
GL_EXTCALL(glVertexAttrib4Nubv(index, ptr));
break;
case WINED3DFMT_R16G16_SINT:
GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
GL_EXTCALL(glVertexAttrib2sv(index, ptr));
break;
case WINED3DFMT_R16G16B16A16_SINT:
GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
GL_EXTCALL(glVertexAttrib4sv(index, ptr));
break;
case WINED3DFMT_R16G16_SNORM:
{
GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
GL_EXTCALL(glVertexAttrib4NsvARB(index, s));
GL_EXTCALL(glVertexAttrib4Nsv(index, s));
break;
}
case WINED3DFMT_R16G16_UNORM:
{
GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
GL_EXTCALL(glVertexAttrib4NusvARB(index, s));
GL_EXTCALL(glVertexAttrib4Nusv(index, s));
break;
}
case WINED3DFMT_R16G16B16A16_SNORM:
GL_EXTCALL(glVertexAttrib4NsvARB(index, ptr));
GL_EXTCALL(glVertexAttrib4Nsv(index, ptr));
break;
case WINED3DFMT_R16G16B16A16_UNORM:
GL_EXTCALL(glVertexAttrib4NusvARB(index, ptr));
GL_EXTCALL(glVertexAttrib4Nusv(index, ptr));
break;
case WINED3DFMT_R10G10B10A2_UINT:
@ -418,7 +418,7 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info,
{
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
GL_EXTCALL(glVertexAttrib2fARB(index, x, y));
GL_EXTCALL(glVertexAttrib2f(index, x, y));
}
break;
case WINED3DFMT_R16G16B16A16_FLOAT:
@ -433,7 +433,7 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info,
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
float z = float_16_to_32(((const unsigned short *)ptr) + 2);
float w = float_16_to_32(((const unsigned short *)ptr) + 3);
GL_EXTCALL(glVertexAttrib4fARB(index, x, y, z, w));
GL_EXTCALL(glVertexAttrib4f(index, x, y, z, w));
}
break;

View file

@ -0,0 +1,514 @@
/*
* Copyright 2014 Michael Müller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "wined3d_private.h"
#include <wine/library.h>
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
static void* txc_dxtn_handle;
static void (*pfetch_2d_texel_rgba_dxt1)(int srcRowStride, const BYTE *pixData, int i, int j, DWORD *texel);
static void (*pfetch_2d_texel_rgba_dxt3)(int srcRowStride, const BYTE *pixData, int i, int j, DWORD *texel);
static void (*pfetch_2d_texel_rgba_dxt5)(int srcRowStride, const BYTE *pixData, int i, int j, DWORD *texel);
static void (*ptx_compress_dxtn)(int comps, int width, int height, const BYTE *srcPixData,
GLenum destformat, BYTE *dest, int dstRowStride);
static inline BOOL dxt1_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
{
unsigned int x, y;
DWORD color;
TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
for (y = 0; y < h; ++y)
{
DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
for (x = 0; x < w; ++x)
{
/* pfetch_2d_texel_rgba_dxt1 doesn't correctly handle pitch */
pfetch_2d_texel_rgba_dxt1(0, src + (y / 4) * pitch_in + (x / 4) * 8,
x & 3, y & 3, &color);
if (alpha)
{
dst_line[x] = (color & 0xff00ff00) | ((color & 0xff) << 16) |
((color & 0xff0000) >> 16);
}
else
{
dst_line[x] = 0xff000000 | ((color & 0xff) << 16) |
(color & 0xff00) | ((color & 0xff0000) >> 16);
}
}
}
return TRUE;
}
static inline BOOL dxt1_to_x4r4g4b4(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
{
unsigned int x, y;
DWORD color;
TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
for (y = 0; y < h; ++y)
{
WORD *dst_line = (WORD *)(dst + y * pitch_out);
for (x = 0; x < w; ++x)
{
/* pfetch_2d_texel_rgba_dxt1 doesn't correctly handle pitch */
pfetch_2d_texel_rgba_dxt1(0, src + (y / 4) * pitch_in + (x / 4) * 16,
x & 3, y & 3, &color);
if (alpha)
{
dst_line[x] = ((color & 0xf0000000) >> 16) | ((color & 0xf00000) >> 20) |
((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
}
else
{
dst_line[x] = 0xf000 | ((color & 0xf00000) >> 20) |
((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
}
}
}
return TRUE;
}
static inline BOOL dxt1_to_x1r5g5b5(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
{
unsigned int x, y;
DWORD color;
TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
for (y = 0; y < h; ++y)
{
WORD *dst_line = (WORD *)(dst + y * pitch_out);
for (x = 0; x < w; ++x)
{
/* pfetch_2d_texel_rgba_dxt1 doesn't correctly handle pitch */
pfetch_2d_texel_rgba_dxt1(0, src + (y / 4) * pitch_in + (x / 4) * 16,
x & 3, y & 3, &color);
if (alpha)
{
dst_line[x] = ((color & 0x80000000) >> 16) | ((color & 0xf80000) >> 19) |
((color & 0xf800) >> 6) | ((color & 0xf8) << 7);
}
else
{
dst_line[x] = 0x8000 | ((color & 0xf80000) >> 19) |
((color & 0xf800) >> 6) | ((color & 0xf8) << 7);
}
}
}
return TRUE;
}
static inline BOOL dxt3_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
{
unsigned int x, y;
DWORD color;
TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
for (y = 0; y < h; ++y)
{
DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
for (x = 0; x < w; ++x)
{
/* pfetch_2d_texel_rgba_dxt3 doesn't correctly handle pitch */
pfetch_2d_texel_rgba_dxt3(0, src + (y / 4) * pitch_in + (x / 4) * 16,
x & 3, y & 3, &color);
if (alpha)
{
dst_line[x] = (color & 0xff00ff00) | ((color & 0xff) << 16) |
((color & 0xff0000) >> 16);
}
else
{
dst_line[x] = 0xff000000 | ((color & 0xff) << 16) |
(color & 0xff00) | ((color & 0xff0000) >> 16);
}
}
}
return TRUE;
}
static inline BOOL dxt3_to_x4r4g4b4(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
{
unsigned int x, y;
DWORD color;
TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
for (y = 0; y < h; ++y)
{
WORD *dst_line = (WORD *)(dst + y * pitch_out);
for (x = 0; x < w; ++x)
{
/* pfetch_2d_texel_rgba_dxt3 doesn't correctly handle pitch */
pfetch_2d_texel_rgba_dxt3(0, src + (y / 4) * pitch_in + (x / 4) * 16,
x & 3, y & 3, &color);
if (alpha)
{
dst_line[x] = ((color & 0xf0000000) >> 16) | ((color & 0xf00000) >> 20) |
((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
}
else
{
dst_line[x] = 0xf000 | ((color & 0xf00000) >> 20) |
((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
}
}
}
return TRUE;
}
static inline BOOL dxt5_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
{
unsigned int x, y;
DWORD color;
TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
for (y = 0; y < h; ++y)
{
DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
for (x = 0; x < w; ++x)
{
/* pfetch_2d_texel_rgba_dxt5 doesn't correctly handle pitch */
pfetch_2d_texel_rgba_dxt5(0, src + (y / 4) * pitch_in + (x / 4) * 16,
x & 3, y & 3, &color);
if (alpha)
{
dst_line[x] = (color & 0xff00ff00) | ((color & 0xff) << 16) |
((color & 0xff0000) >> 16);
}
else
{
dst_line[x] = 0xff000000 | ((color & 0xff) << 16) |
(color & 0xff00) | ((color & 0xff0000) >> 16);
}
}
}
return TRUE;
}
static inline BOOL x8r8g8b8_to_dxtn(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, GLenum destformat, BOOL alpha)
{
unsigned int x, y;
DWORD color, *tmp;
TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
tmp = HeapAlloc(GetProcessHeap(), 0, h * w * sizeof(DWORD));
if (!tmp)
{
ERR("Failed to allocate memory for conversion\n");
return FALSE;
}
for (y = 0; y < h; ++y)
{
const DWORD *src_line = (const DWORD *)(src + y * pitch_in);
DWORD *dst_line = tmp + y * w;
for (x = 0; x < w; ++x)
{
color = src_line[x];
if (alpha)
{
dst_line[x] = (color & 0xff00ff00) | ((color & 0xff) << 16) |
((color & 0xff0000) >> 16);
}
else
{
dst_line[x] = 0xff000000 | ((color & 0xff) << 16) |
(color & 0xff00) | ((color & 0xff0000) >> 16);
}
}
}
ptx_compress_dxtn(4, w, h, (BYTE *)tmp, destformat, dst, pitch_out);
HeapFree(GetProcessHeap(), 0, tmp);
return TRUE;
}
static inline BOOL x1r5g5b5_to_dxtn(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, GLenum destformat, BOOL alpha)
{
static const unsigned char convert_5to8[] =
{
0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a,
0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b,
0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd,
0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff,
};
unsigned int x, y;
DWORD *tmp;
WORD color;
TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out);
tmp = HeapAlloc(GetProcessHeap(), 0, h * w * sizeof(DWORD));
if (!tmp)
{
ERR("Failed to allocate memory for conversion\n");
return FALSE;
}
for (y = 0; y < h; ++y)
{
const WORD *src_line = (const WORD *)(src + y * pitch_in);
DWORD *dst_line = tmp + y * w;
for (x = 0; x < w; ++x)
{
color = src_line[x];
if (alpha)
{
dst_line[x] = ((color & 0x8000) ? 0xff000000 : 0) |
convert_5to8[(color & 0x001f)] << 16 |
convert_5to8[(color & 0x03e0) >> 5] << 8 |
convert_5to8[(color & 0x7c00) >> 10];
}
else
{
dst_line[x] = 0xff000000 |
convert_5to8[(color & 0x001f)] << 16 |
convert_5to8[(color & 0x03e0) >> 5] << 8 |
convert_5to8[(color & 0x7c00) >> 10];
}
}
}
ptx_compress_dxtn(4, w, h, (BYTE *)tmp, destformat, dst, pitch_out);
HeapFree(GetProcessHeap(), 0, tmp);
return TRUE;
}
BOOL wined3d_dxt1_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h)
{
if (!txc_dxtn_handle)
return FALSE;
switch (format)
{
case WINED3DFMT_B8G8R8A8_UNORM:
return dxt1_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, TRUE);
case WINED3DFMT_B8G8R8X8_UNORM:
return dxt1_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, FALSE);
case WINED3DFMT_B4G4R4A4_UNORM:
return dxt1_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, TRUE);
case WINED3DFMT_B4G4R4X4_UNORM:
return dxt1_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, FALSE);
case WINED3DFMT_B5G5R5A1_UNORM:
return dxt1_to_x1r5g5b5(src, dst, pitch_in, pitch_out, w, h, TRUE);
case WINED3DFMT_B5G5R5X1_UNORM:
return dxt1_to_x1r5g5b5(src, dst, pitch_in, pitch_out, w, h, FALSE);
default:
break;
}
FIXME("Cannot find a conversion function from format DXT1 to %s.\n", debug_d3dformat(format));
return FALSE;
}
BOOL wined3d_dxt3_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h)
{
if (!txc_dxtn_handle)
return FALSE;
switch (format)
{
case WINED3DFMT_B8G8R8A8_UNORM:
return dxt3_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, TRUE);
case WINED3DFMT_B8G8R8X8_UNORM:
return dxt3_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, FALSE);
case WINED3DFMT_B4G4R4A4_UNORM:
return dxt3_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, TRUE);
case WINED3DFMT_B4G4R4X4_UNORM:
return dxt3_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, FALSE);
default:
break;
}
FIXME("Cannot find a conversion function from format DXT3 to %s.\n", debug_d3dformat(format));
return FALSE;
}
BOOL wined3d_dxt5_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h)
{
if (!txc_dxtn_handle)
return FALSE;
switch (format)
{
case WINED3DFMT_B8G8R8A8_UNORM:
return dxt5_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, TRUE);
case WINED3DFMT_B8G8R8X8_UNORM:
return dxt5_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, FALSE);
default:
break;
}
FIXME("Cannot find a conversion function from format DXT5 to %s.\n", debug_d3dformat(format));
return FALSE;
}
BOOL wined3d_dxt1_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h)
{
if (!txc_dxtn_handle)
return FALSE;
switch (format)
{
case WINED3DFMT_B8G8R8A8_UNORM:
return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, TRUE);
case WINED3DFMT_B8G8R8X8_UNORM:
return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
GL_COMPRESSED_RGB_S3TC_DXT1_EXT, FALSE);
case WINED3DFMT_B5G5R5A1_UNORM:
return x1r5g5b5_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, TRUE);
case WINED3DFMT_B5G5R5X1_UNORM:
return x1r5g5b5_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
GL_COMPRESSED_RGB_S3TC_DXT1_EXT, FALSE);
default:
break;
}
FIXME("Cannot find a conversion function from format %s to DXT1.\n", debug_d3dformat(format));
return FALSE;
}
BOOL wined3d_dxt3_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h)
{
if (!txc_dxtn_handle)
return FALSE;
switch (format)
{
case WINED3DFMT_B8G8R8A8_UNORM:
return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, TRUE);
case WINED3DFMT_B8G8R8X8_UNORM:
return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, FALSE);
default:
break;
}
FIXME("Cannot find a conversion function from format %s to DXT3.\n", debug_d3dformat(format));
return FALSE;
}
BOOL wined3d_dxt5_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h)
{
if (!txc_dxtn_handle)
return FALSE;
switch (format)
{
case WINED3DFMT_B8G8R8A8_UNORM:
return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, TRUE);
case WINED3DFMT_B8G8R8X8_UNORM:
return x8r8g8b8_to_dxtn(src, dst, pitch_in, pitch_out, w, h,
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, FALSE);
default:
break;
}
FIXME("Cannot find a conversion function from format %s to DXT5.\n", debug_d3dformat(format));
return FALSE;
}
BOOL wined3d_dxtn_init(void)
{
static const char *soname[] =
{
#ifdef SONAME_LIBTXC_DXTN
SONAME_LIBTXC_DXTN,
#endif
"libtxc_dxtn.so",
"libtxc_dxtn_s2tc.so.0"
};
int i;
for (i = 0; i < sizeof(soname)/sizeof(soname[0]); i++)
{
txc_dxtn_handle = wine_dlopen(soname[i], RTLD_NOW, NULL, 0);
if (txc_dxtn_handle) break;
}
if (!txc_dxtn_handle)
{
FIXME("Wine cannot find the txc_dxtn library, DXTn software support unavailable.\n");
return FALSE;
}
#define LOAD_FUNCPTR(f) \
if (!(p##f = wine_dlsym(txc_dxtn_handle, #f, NULL, 0))) \
{ \
ERR("Can't find symbol %s , DXTn software support unavailable.\n", #f); \
goto error; \
}
LOAD_FUNCPTR(fetch_2d_texel_rgba_dxt1);
LOAD_FUNCPTR(fetch_2d_texel_rgba_dxt3);
LOAD_FUNCPTR(fetch_2d_texel_rgba_dxt5);
LOAD_FUNCPTR(tx_compress_dxtn);
#undef LOAD_FUNCPTR
return TRUE;
error:
wine_dlclose(txc_dxtn_handle, NULL, 0);
txc_dxtn_handle = NULL;
return FALSE;
}
BOOL wined3d_dxtn_supported(void)
{
return (txc_dxtn_handle != NULL);
}
void wined3d_dxtn_free(void)
{
if (txc_dxtn_handle)
wine_dlclose(txc_dxtn_handle, NULL, 0);
}

View file

@ -104,7 +104,8 @@ static void WINE_GLAPI wine_glMultiTexCoord4svARB(GLenum target, const GLshort *
context_get_current()->gl_info->gl_ops.gl.p_glTexCoord4sv(v);
}
static void WINE_GLAPI wine_glActiveTextureARB(GLenum texture) {
static void WINE_GLAPI wine_glActiveTexture(GLenum texture)
{
if(texture != GL_TEXTURE0) {
ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
return;
@ -343,7 +344,7 @@ void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info)
if (!gl_info->supported[ARB_MULTITEXTURE])
{
TRACE("Applying GL_ARB_multitexture emulation hooks\n");
gl_info->gl_ops.ext.p_glActiveTextureARB = wine_glActiveTextureARB;
gl_info->gl_ops.ext.p_glActiveTexture = wine_glActiveTexture;
gl_info->gl_ops.ext.p_glClientActiveTextureARB = wine_glClientActiveTextureARB;
gl_info->gl_ops.ext.p_glMultiTexCoord1fARB = wine_glMultiTexCoord1fARB;
gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB = wine_glMultiTexCoord1fvARB;

File diff suppressed because it is too large Load diff

View file

@ -348,16 +348,16 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
context = context_acquire(query->device, oq->context->current_rt);
GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
TRACE("available %#x.\n", available);
if (available)
{
if (size)
{
GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_ARB, &samples));
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)");
TRACE("Returning %d samples.\n", samples);
fill_query_data(data, size, &samples, sizeof(samples));
}
@ -490,7 +490,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
{
context = context_acquire(query->device, oq->context->current_rt);
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
checkGLcall("glEndQuery()");
}
}
@ -501,7 +501,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
context_alloc_occlusion_query(context, oq);
}
GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, oq->id));
GL_EXTCALL(glBeginQuery(GL_SAMPLES_PASSED, oq->id));
checkGLcall("glBeginQuery()");
context_release(context);
@ -522,7 +522,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
{
context = context_acquire(query->device, oq->context->current_rt);
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
checkGLcall("glEndQuery()");
context_release(context);
@ -578,16 +578,16 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
context = context_acquire(query->device, tq->context->current_rt);
GL_EXTCALL(glGetQueryObjectuivARB(tq->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
TRACE("available %#x.\n", available);
if (available)
{
if (size)
{
GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT_ARB, &timestamp));
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, &timestamp));
checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)");
TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp));
fill_query_data(data, size, &timestamp, sizeof(timestamp));
}

View file

@ -48,7 +48,7 @@ static DWORD resource_access_from_pool(enum wined3d_pool pool)
static void resource_check_usage(DWORD usage)
{
static const DWORD handled = WINED3DUSAGE_RENDERTARGET
static DWORD handled = WINED3DUSAGE_RENDERTARGET
| WINED3DUSAGE_DEPTHSTENCIL
| WINED3DUSAGE_WRITEONLY
| WINED3DUSAGE_DYNAMIC
@ -64,7 +64,10 @@ static void resource_check_usage(DWORD usage)
* driver. */
if (usage & ~handled)
{
FIXME("Unhandled usage flags %#x.\n", usage & ~handled);
handled |= usage;
}
if ((usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY)) == WINED3DUSAGE_DYNAMIC)
WARN_(d3d_perf)("WINED3DUSAGE_DYNAMIC used without WINED3DUSAGE_WRITEONLY.\n");
}
@ -79,14 +82,23 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
const struct wined3d *d3d = device->wined3d;
resource_check_usage(usage);
if (pool != WINED3D_POOL_SCRATCH)
if (pool != WINED3D_POOL_SCRATCH && type != WINED3D_RTYPE_BUFFER)
{
if ((usage & WINED3DUSAGE_RENDERTARGET) && !(format->flags & WINED3DFMT_FLAG_RENDERTARGET))
{
WARN("Format %s cannot be used for render targets.\n", debug_d3dformat(format->id));
return WINED3DERR_INVALIDCALL;
}
if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && !(format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
{
WARN("Format %s cannot be used for depth/stencil buffers.\n", debug_d3dformat(format->id));
return WINED3DERR_INVALIDCALL;
}
if ((usage & WINED3DUSAGE_TEXTURE) && !(format->flags & WINED3DFMT_FLAG_TEXTURE))
{
WARN("Format %s cannot be used for texturing.\n", debug_d3dformat(format->id));
return WINED3DERR_INVALIDCALL;
}
}
resource->ref = 1;
@ -149,7 +161,7 @@ void resource_cleanup(struct wined3d_resource *resource)
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);
adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size);
}
wined3d_resource_free_sysmem(resource);

View file

@ -1,5 +1,5 @@
/*
* Copyright 2012 Henri Verbeet for CodeWeavers
* Copyright 2012, 2015 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -33,11 +33,20 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler)
ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
{
ULONG refcount = InterlockedDecrement(&sampler->refcount);
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
TRACE("%p decreasing refcount to %u.\n", sampler, refcount);
if (!refcount)
{
context = context_acquire(sampler->device, NULL);
gl_info = context->gl_info;
GL_EXTCALL(glDeleteSamplers(1, &sampler->name));
context_release(context);
HeapFree(GetProcessHeap(), 0, sampler);
}
return refcount;
}
@ -49,22 +58,74 @@ void * CDECL wined3d_sampler_get_parent(const struct wined3d_sampler *sampler)
return sampler->parent;
}
static void wined3d_sampler_init(struct wined3d_sampler *sampler, void *parent)
static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d_device *device,
const struct wined3d_sampler_desc *desc, void *parent)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
sampler->refcount = 1;
sampler->device = device;
sampler->parent = parent;
sampler->desc = *desc;
context = context_acquire(device, NULL);
gl_info = context->gl_info;
GL_EXTCALL(glGenSamplers(1, &sampler->name));
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_S,
gl_info->wrap_lookup[desc->address_u - WINED3D_TADDRESS_WRAP]));
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_T,
gl_info->wrap_lookup[desc->address_v - WINED3D_TADDRESS_WRAP]));
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_R,
gl_info->wrap_lookup[desc->address_w - WINED3D_TADDRESS_WRAP]));
GL_EXTCALL(glSamplerParameterfv(sampler->name, GL_TEXTURE_BORDER_COLOR, &desc->border_color[0]));
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAG_FILTER,
wined3d_gl_mag_filter(desc->mag_filter)));
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MIN_FILTER,
wined3d_gl_min_mip_filter(desc->min_filter, desc->mip_filter)));
GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_LOD_BIAS, desc->lod_bias));
GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MIN_LOD, desc->min_lod));
GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MAX_LOD, desc->max_lod));
if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAX_ANISOTROPY_EXT, desc->max_anisotropy));
if (desc->compare)
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE));
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_FUNC,
wined3d_gl_compare_func(desc->comparison_func)));
if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && !desc->srgb_decode)
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT));
checkGLcall("sampler creation");
TRACE("Created sampler %u.\n", sampler->name);
context_release(context);
}
HRESULT CDECL wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler)
HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
void *parent, struct wined3d_sampler **sampler)
{
struct wined3d_sampler *object;
TRACE("parent %p, sampler %p.\n", parent, sampler);
TRACE("device %p, desc %p, parent %p, sampler %p.\n", device, desc, parent, sampler);
if (!device->adapter->gl_info.supported[ARB_SAMPLER_OBJECTS])
return WINED3DERR_INVALIDCALL;
if (desc->address_u < WINED3D_TADDRESS_WRAP || desc->address_u > WINED3D_TADDRESS_MIRROR_ONCE
|| desc->address_v < WINED3D_TADDRESS_WRAP || desc->address_v > WINED3D_TADDRESS_MIRROR_ONCE
|| desc->address_w < WINED3D_TADDRESS_WRAP || desc->address_w > WINED3D_TADDRESS_MIRROR_ONCE)
return WINED3DERR_INVALIDCALL;
if (desc->mag_filter < WINED3D_TEXF_POINT || desc->mag_filter > WINED3D_TEXF_LINEAR
|| desc->min_filter < WINED3D_TEXF_POINT || desc->min_filter > WINED3D_TEXF_LINEAR
|| desc->mip_filter > WINED3D_TEXF_LINEAR)
return WINED3DERR_INVALIDCALL;
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
wined3d_sampler_init(object, parent);
wined3d_sampler_init(object, device, desc, parent);
TRACE("Created sampler %p.\n", object);
*sampler = object;

View file

@ -101,8 +101,10 @@ static const char * const shader_opcode_names[] =
/* WINED3DSIH_MOVA */ "mova",
/* WINED3DSIH_MOVC */ "movc",
/* WINED3DSIH_MUL */ "mul",
/* WINED3DSIH_NE */ "ne",
/* WINED3DSIH_NOP */ "nop",
/* WINED3DSIH_NRM */ "nrm",
/* WINED3DSIH_OR */ "or",
/* WINED3DSIH_PHASE */ "phase",
/* WINED3DSIH_POW */ "pow",
/* WINED3DSIH_RCP */ "rcp",
@ -143,6 +145,7 @@ static const char * const shader_opcode_names[] =
/* WINED3DSIH_TEXREG2GB */ "texreg2gb",
/* WINED3DSIH_TEXREG2RGB */ "texreg2rgb",
/* WINED3DSIH_UDIV */ "udiv",
/* WINED3DSIH_UGE */ "uge",
/* WINED3DSIH_USHR */ "ushr",
/* WINED3DSIH_UTOF */ "utof",
/* WINED3DSIH_XOR */ "xor",
@ -363,6 +366,84 @@ static void shader_delete_constant_list(struct list *clist)
list_init(clist);
}
static void shader_set_limits(struct wined3d_shader *shader)
{
static const struct limits_entry
{
unsigned int min_version;
unsigned int max_version;
struct wined3d_shader_limits limits;
}
vs_limits[] =
{
/* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */
{WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 1), { 0, 0, 256, 0, 12, 0}},
{WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 1), { 0, 16, 256, 16, 12, 0}},
/* DX10 cards on Windows advertise a D3D9 constant limit of 256
* even though they are capable of supporting much more (GL
* drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
* wined3d-advertised maximum. Clamp the constant limit for <= 3.0
* shaders to 256. */
{WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 0), { 4, 16, 256, 16, 12, 0}},
{WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(4, 0), {16, 0, 0, 0, 16, 0}},
{0}
},
gs_limits[] =
{
/* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */
{WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(4, 0), {16, 0, 0, 0, 32, 16}},
{0}
},
ps_limits[] =
{
/* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */
{WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 3), { 4, 0, 8, 0, 0, 0}},
{WINED3D_SHADER_VERSION(1, 4), WINED3D_SHADER_VERSION(1, 4), { 6, 0, 8, 0, 0, 0}},
{WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 0), {16, 0, 32, 0, 0, 0}},
{WINED3D_SHADER_VERSION(2, 1), WINED3D_SHADER_VERSION(2, 1), {16, 16, 32, 16, 0, 0}},
{WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 0), {16, 16, 224, 16, 0, 12}},
{WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(4, 0), {16, 0, 0, 0, 0, 32}},
{0}
};
const struct limits_entry *limits_array;
DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
int i = 0;
switch (shader->reg_maps.shader_version.type)
{
default:
FIXME("Unexpected shader type %u found.\n", shader->reg_maps.shader_version.type);
/* Fall-through. */
case WINED3D_SHADER_TYPE_VERTEX:
limits_array = vs_limits;
break;
case WINED3D_SHADER_TYPE_GEOMETRY:
limits_array = gs_limits;
break;
case WINED3D_SHADER_TYPE_PIXEL:
limits_array = ps_limits;
break;
}
while (limits_array[i].min_version && limits_array[i].min_version <= shader_version)
{
if (shader_version <= limits_array[i].max_version)
{
shader->limits = &limits_array[i].limits;
break;
}
++i;
}
if (!shader->limits)
{
FIXME("Unexpected shader version \"%u.%u\".\n",
shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
shader->limits = &limits_array[max(0, i - 1)].limits;
}
}
static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
{
DWORD idx, shift;
@ -371,8 +452,8 @@ static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
bitmap[idx] |= (1 << shift);
}
static void shader_record_register_usage(struct wined3d_shader *shader, struct wined3d_shader_reg_maps *reg_maps,
const struct wined3d_shader_register *reg, enum wined3d_shader_type shader_type)
static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct wined3d_shader_reg_maps *reg_maps,
const struct wined3d_shader_register *reg, enum wined3d_shader_type shader_type, unsigned int constf_size)
{
switch (reg->type)
{
@ -436,16 +517,40 @@ static void shader_record_register_usage(struct wined3d_shader *shader, struct w
}
else
{
set_bitmap_bit(reg_maps->constf, reg->idx[0].offset);
if (reg->idx[0].offset >= min(shader->limits->constant_float, constf_size))
{
WARN("Shader using float constant %u which is not supported.\n", reg->idx[0].offset);
return FALSE;
}
else
{
set_bitmap_bit(reg_maps->constf, reg->idx[0].offset);
}
}
break;
case WINED3DSPR_CONSTINT:
reg_maps->integer_constants |= (1 << reg->idx[0].offset);
if (reg->idx[0].offset >= shader->limits->constant_int)
{
WARN("Shader using integer constant %u which is not supported.\n", reg->idx[0].offset);
return FALSE;
}
else
{
reg_maps->integer_constants |= (1 << reg->idx[0].offset);
}
break;
case WINED3DSPR_CONSTBOOL:
reg_maps->boolean_constants |= (1 << reg->idx[0].offset);
if (reg->idx[0].offset >= shader->limits->constant_bool)
{
WARN("Shader using bool constant %u which is not supported.\n", reg->idx[0].offset);
return FALSE;
}
else
{
reg_maps->boolean_constants |= (1 << reg->idx[0].offset);
}
break;
case WINED3DSPR_COLOROUT:
@ -457,6 +562,52 @@ static void shader_record_register_usage(struct wined3d_shader *shader, struct w
reg->type, reg->idx[0].offset, reg->idx[1].offset);
break;
}
return TRUE;
}
static void shader_record_sample(struct wined3d_shader_reg_maps *reg_maps,
unsigned int resource_idx, unsigned int sampler_idx, unsigned int bind_idx)
{
struct wined3d_shader_sampler_map_entry *entries, *entry;
struct wined3d_shader_sampler_map *map;
unsigned int i;
map = &reg_maps->sampler_map;
entries = map->entries;
for (i = 0; i < map->count; ++i)
{
if (entries[i].resource_idx == resource_idx && entries[i].sampler_idx == sampler_idx)
return;
}
if (!map->size)
{
if (!(entries = HeapAlloc(GetProcessHeap(), 0, sizeof(*entries) * 4)))
{
ERR("Failed to allocate sampler map entries.\n");
return;
}
map->size = 4;
map->entries = entries;
}
else if (map->count == map->size)
{
size_t new_size = map->size * 2;
if (sizeof(*entries) * new_size <= sizeof(*entries) * map->size
|| !(entries = HeapReAlloc(GetProcessHeap(), 0, entries, sizeof(*entries) * new_size)))
{
ERR("Failed to resize sampler map entries.\n");
return;
}
map->size = new_size;
map->entries = entries;
}
entry = &entries[map->count++];
entry->resource_idx = resource_idx;
entry->sampler_idx = sampler_idx;
entry->bind_idx = bind_idx;
}
static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, unsigned int param)
@ -495,8 +646,10 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
fe->shader_read_header(fe_data, &ptr, &shader_version);
reg_maps->shader_version = shader_version;
shader_set_limits(shader);
reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
sizeof(*reg_maps->constf) * ((min(shader->limits->constant_float, constf_size) + 31) / 32));
if (!reg_maps->constf)
{
ERR("Failed to allocate constant map memory.\n");
@ -521,26 +674,47 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
if (ins.handler_idx == WINED3DSIH_DCL)
{
struct wined3d_shader_semantic *semantic = &ins.declaration.semantic;
unsigned int reg_idx = semantic->reg.reg.idx[0].offset;
switch (semantic->reg.reg.type)
{
/* Mark input registers used. */
case WINED3DSPR_INPUT:
reg_maps->input_registers |= 1 << semantic->reg.reg.idx[0].offset;
shader_signature_from_semantic(&input_signature[semantic->reg.reg.idx[0].offset], semantic);
if (reg_idx >= MAX_REG_INPUT)
{
ERR("Invalid input register index %u.\n", reg_idx);
break;
}
if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL && shader_version.major == 3
&& semantic->usage == WINED3D_DECL_USAGE_POSITION && !semantic->usage_idx)
return WINED3DERR_INVALIDCALL;
reg_maps->input_registers |= 1 << reg_idx;
shader_signature_from_semantic(&input_signature[reg_idx], semantic);
break;
/* Vertex shader: mark 3.0 output registers used, save token. */
case WINED3DSPR_OUTPUT:
reg_maps->output_registers |= 1 << semantic->reg.reg.idx[0].offset;
shader_signature_from_semantic(&output_signature[semantic->reg.reg.idx[0].offset], semantic);
if (reg_idx >= MAX_REG_OUTPUT)
{
ERR("Invalid output register index %u.\n", reg_idx);
break;
}
reg_maps->output_registers |= 1 << reg_idx;
shader_signature_from_semantic(&output_signature[reg_idx], semantic);
if (semantic->usage == WINED3D_DECL_USAGE_FOG)
reg_maps->fog = 1;
break;
/* Save sampler usage token. */
case WINED3DSPR_SAMPLER:
reg_maps->sampler_type[semantic->reg.reg.idx[0].offset] = semantic->sampler_type;
shader_record_sample(reg_maps, reg_idx, reg_idx, reg_idx);
case WINED3DSPR_RESOURCE:
if (reg_idx >= ARRAY_SIZE(reg_maps->resource_info))
{
ERR("Invalid resource index %u.\n", reg_idx);
break;
}
reg_maps->resource_info[reg_idx].type = semantic->resource_type;
reg_maps->resource_info[reg_idx].data_type = semantic->resource_data_type;
break;
default:
@ -652,7 +826,9 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
* they are initialized (required by spec). */
for (i = 0; i < ins.dst_count; ++i)
{
shader_record_register_usage(shader, reg_maps, &ins.dst[i].reg, shader_version.type);
if (!shader_record_register_usage(shader, reg_maps, &ins.dst[i].reg,
shader_version.type, constf_size))
return WINED3DERR_INVALIDCALL;
/* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
* is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
@ -766,20 +942,21 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
|| ins.handler_idx == WINED3DSIH_TEXREG2GB
|| ins.handler_idx == WINED3DSIH_TEXREG2RGB))
{
/* Fake sampler usage, only set reserved bit and type. */
DWORD sampler_code = ins.dst[i].reg.idx[0].offset;
unsigned int reg_idx = ins.dst[i].reg.idx[0].offset;
TRACE("Setting fake 2D sampler for 1.x pixelshader.\n");
reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D;
TRACE("Setting fake 2D resource for 1.x pixelshader.\n");
reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_FLOAT;
shader_record_sample(reg_maps, reg_idx, reg_idx, reg_idx);
/* texbem is only valid with < 1.4 pixel shaders */
if (ins.handler_idx == WINED3DSIH_TEXBEM
|| ins.handler_idx == WINED3DSIH_TEXBEML)
{
reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
reg_maps->bumpmat |= 1 << reg_idx;
if (ins.handler_idx == WINED3DSIH_TEXBEML)
{
reg_maps->luminanceparams |= 1 << ins.dst[i].reg.idx[0].offset;
reg_maps->luminanceparams |= 1 << reg_idx;
}
}
}
@ -807,21 +984,36 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
}
else if (ins.handler_idx == WINED3DSIH_ENDLOOP
|| ins.handler_idx == WINED3DSIH_ENDREP)
{
--cur_loop_depth;
}
else if (ins.handler_idx == WINED3DSIH_SAMPLE
|| ins.handler_idx == WINED3DSIH_SAMPLE_GRAD
|| ins.handler_idx == WINED3DSIH_SAMPLE_LOD)
{
shader_record_sample(reg_maps, ins.src[1].reg.idx[0].offset,
ins.src[2].reg.idx[0].offset, reg_maps->sampler_map.count);
}
if (ins.predicate)
shader_record_register_usage(shader, reg_maps, &ins.predicate->reg, shader_version.type);
if (!shader_record_register_usage(shader, reg_maps, &ins.predicate->reg,
shader_version.type, constf_size))
return WINED3DERR_INVALIDCALL;
for (i = 0; i < ins.src_count; ++i)
{
unsigned int count = get_instr_extra_regcount(ins.handler_idx, i);
struct wined3d_shader_register reg = ins.src[i].reg;
shader_record_register_usage(shader, reg_maps, &ins.src[i].reg, shader_version.type);
if (!shader_record_register_usage(shader, reg_maps, &ins.src[i].reg,
shader_version.type, constf_size))
return WINED3DERR_INVALIDCALL;
while (count)
{
++reg.idx[0].offset;
shader_record_register_usage(shader, reg_maps, &reg, shader_version.type);
if (!shader_record_register_usage(shader, reg_maps, &reg,
shader_version.type, constf_size))
return WINED3DERR_INVALIDCALL;
--count;
}
@ -865,12 +1057,95 @@ static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semanti
if (semantic->reg.reg.type == WINED3DSPR_SAMPLER)
{
switch (semantic->sampler_type)
switch (semantic->resource_type)
{
case WINED3DSTT_2D: TRACE("_2d"); break;
case WINED3DSTT_CUBE: TRACE("_cube"); break;
case WINED3DSTT_VOLUME: TRACE("_volume"); break;
default: TRACE("_unknown_ttype(0x%08x)", semantic->sampler_type);
case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
TRACE("_2d");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
TRACE("_volume");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
TRACE("_cube");
break;
default:
TRACE("_unknown_ttype(0x%08x)", semantic->resource_type);
break;
}
}
else if (semantic->reg.reg.type == WINED3DSPR_RESOURCE)
{
TRACE("_resource_");
switch (semantic->resource_type)
{
case WINED3D_SHADER_RESOURCE_BUFFER:
TRACE("buffer");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
TRACE("texture1d");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
TRACE("texture2d");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_2DMS:
TRACE("texture2dms");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
TRACE("texture3d");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
TRACE("texturecube");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY:
TRACE("texture1darray");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
TRACE("texture2darray");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY:
TRACE("texture2dmsarray");
break;
default:
TRACE("unknown");
break;
}
switch (semantic->resource_data_type)
{
case WINED3D_DATA_FLOAT:
TRACE(" (float)");
break;
case WINED3D_DATA_INT:
TRACE(" (int)");
break;
case WINED3D_DATA_UINT:
TRACE(" (uint)");
break;
case WINED3D_DATA_UNORM:
TRACE(" (unorm)");
break;
case WINED3D_DATA_SNORM:
TRACE(" (snorm)");
break;
default:
TRACE(" (unknown)");
break;
}
}
else
@ -1483,6 +1758,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
static void shader_cleanup(struct wined3d_shader *shader)
{
HeapFree(GetProcessHeap(), 0, shader->signature_strings);
shader->device->shader_backend->shader_destroy(shader);
HeapFree(GetProcessHeap(), 0, shader->reg_maps.constf);
HeapFree(GetProcessHeap(), 0, shader->function);
@ -1783,11 +2059,11 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh
TRACE("shader %p, start_idx %u, src_data %p, count %u.\n", shader, start_idx, src_data, count);
if (end_idx > shader->limits.constant_float)
if (end_idx > shader->limits->constant_float)
{
WARN("end_idx %u > float constants limit %u.\n",
end_idx, shader->limits.constant_float);
end_idx = shader->limits.constant_float;
end_idx, shader->limits->constant_float);
end_idx = shader->limits->constant_float;
}
for (i = start_idx; i < end_idx; ++i)
@ -1856,75 +2132,8 @@ BOOL vshader_get_input(const struct wined3d_shader *shader,
return FALSE;
}
static void vertexshader_set_limits(struct wined3d_shader *shader)
{
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;
switch (shader_version)
{
case WINED3D_SHADER_VERSION(1, 0):
case WINED3D_SHADER_VERSION(1, 1):
shader->limits.constant_bool = 0;
shader->limits.constant_int = 0;
shader->limits.packed_output = 12;
shader->limits.sampler = 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, vs_uniform_count);
break;
case WINED3D_SHADER_VERSION(2, 0):
case WINED3D_SHADER_VERSION(2, 1):
shader->limits.constant_bool = 16;
shader->limits.constant_int = 16;
shader->limits.packed_output = 12;
shader->limits.sampler = 0;
shader->limits.constant_float = min(256, vs_uniform_count);
break;
case WINED3D_SHADER_VERSION(3, 0):
shader->limits.constant_bool = 16;
shader->limits.constant_int = 16;
shader->limits.packed_output = 12;
shader->limits.sampler = 4;
/* DX10 cards on Windows advertise a d3d9 constant limit of 256
* even though they are capable of supporting much more (GL
* 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, vs_uniform_count);
break;
case WINED3D_SHADER_VERSION(4, 0):
shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
shader->limits.constant_int = 0;
shader->limits.constant_float = 0;
shader->limits.constant_bool = 0;
shader->limits.packed_output = 16;
shader->limits.packed_input = 0;
break;
default:
shader->limits.constant_bool = 16;
shader->limits.constant_int = 16;
shader->limits.packed_output = 12;
shader->limits.sampler = 0;
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);
}
}
static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
{
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
unsigned int i;
@ -1932,12 +2141,12 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
WORD map;
const DWORD vs_uniform_count = device->adapter->d3d_info.limits.vs_uniform_count;
if (!byte_code) return WINED3DERR_INVALIDCALL;
if (!desc->byte_code)
return WINED3DERR_INVALIDCALL;
shader_init(shader, device, parent, parent_ops);
hr = shader_set_function(shader, byte_code, output_signature, vs_uniform_count,
WINED3D_SHADER_TYPE_VERTEX, max_version);
if (FAILED(hr))
if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
vs_uniform_count, WINED3D_SHADER_TYPE_VERTEX, desc->max_version)))
{
WARN("Failed to set function, hr %#x.\n", hr);
shader_cleanup(shader);
@ -1955,66 +2164,66 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
shader->u.vs.attributes[i].usage_idx = shader->input_signature[i].semantic_idx;
}
if (output_signature)
if (desc->output_signature)
{
for (i = 0; i < output_signature->element_count; ++i)
struct wined3d_shader_signature_element *e;
SIZE_T total, len;
char *ptr;
total = 0;
for (i = 0; i < desc->output_signature->element_count; ++i)
{
struct wined3d_shader_signature_element *e = &output_signature->elements[i];
e = &desc->output_signature->elements[i];
len = strlen(e->semantic_name);
if (len >= ~(SIZE_T)0 - total)
{
shader_cleanup(shader);
return E_OUTOFMEMORY;
}
total += len + 1;
}
if (!(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total)))
{
shader_cleanup(shader);
return E_OUTOFMEMORY;
}
ptr = shader->signature_strings;
for (i = 0; i < desc->output_signature->element_count; ++i)
{
e = &desc->output_signature->elements[i];
reg_maps->output_registers |= 1 << e->register_idx;
shader->output_signature[e->register_idx] = *e;
len = strlen(e->semantic_name);
memcpy(ptr, e->semantic_name, len + 1);
shader->output_signature[e->register_idx].semantic_name = ptr;
ptr += len + 1;
}
}
vertexshader_set_limits(shader);
shader->load_local_constsF = (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) ||
shader->lconst_inf_or_nan;
return WINED3D_OK;
}
static void geometryshader_set_limits(struct wined3d_shader *shader)
{
DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
switch (shader_version)
{
case WINED3D_SHADER_VERSION(4, 0):
shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
shader->limits.constant_int = 0;
shader->limits.constant_float = 0;
shader->limits.constant_bool = 0;
shader->limits.packed_output = 32;
shader->limits.packed_input = 16;
break;
default:
memset(&shader->limits, 0, sizeof(shader->limits));
FIXME("Unhandled geometry shader version \"%u.%u\".\n",
shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
}
}
static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
{
HRESULT hr;
shader_init(shader, device, parent, parent_ops);
hr = shader_set_function(shader, byte_code, output_signature, 0,
WINED3D_SHADER_TYPE_GEOMETRY, max_version);
if (FAILED(hr))
if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
0, WINED3D_SHADER_TYPE_GEOMETRY, desc->max_version)))
{
WARN("Failed to set function, hr %#x.\n", hr);
shader_cleanup(shader);
return hr;
}
geometryshader_set_limits(shader);
shader->load_local_constsF = shader->lconst_inf_or_nan;
return WINED3D_OK;
@ -2044,7 +2253,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
if (shader->reg_maps.shader_version.major == 1
&& shader->reg_maps.shader_version.minor <= 3)
{
for (i = 0; i < shader->limits.sampler; ++i)
for (i = 0; i < shader->limits->sampler; ++i)
{
DWORD flags = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
@ -2054,10 +2263,10 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
if (!state->shader[WINED3D_SHADER_TYPE_VERTEX])
{
enum wined3d_shader_resource_type resource_type = shader->reg_maps.resource_info[i].type;
unsigned int j;
unsigned int index = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
DWORD max_valid = WINED3D_TTFF_COUNT4;
enum wined3d_sampler_texture_type sampler_type = shader->reg_maps.sampler_type[i];
for (j = 0; j < state->vertex_declaration->element_count; ++j)
{
@ -2077,15 +2286,17 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
tex_transform, max_valid);
tex_transform = max_valid;
}
if ((sampler_type == WINED3DSTT_1D && tex_transform > WINED3D_TTFF_COUNT1)
|| (sampler_type == WINED3DSTT_2D && tex_transform > WINED3D_TTFF_COUNT2)
|| (sampler_type == WINED3DSTT_VOLUME && tex_transform > WINED3D_TTFF_COUNT3))
if ((resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_1D && tex_transform > WINED3D_TTFF_COUNT1)
|| (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2D
&& tex_transform > WINED3D_TTFF_COUNT2)
|| (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_3D
&& tex_transform > WINED3D_TTFF_COUNT3))
tex_transform |= WINED3D_PSARGS_PROJECTED;
else
{
WARN("Application requested projected texture with unsuitable texture coordinates.\n");
WARN("(texture unit %u, transform flags %#x, sampler type %u).\n",
i, tex_transform, sampler_type);
i, tex_transform, resource_type);
}
}
else
@ -2098,11 +2309,11 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
if (shader->reg_maps.shader_version.major == 1
&& shader->reg_maps.shader_version.minor <= 4)
{
for (i = 0; i < shader->limits.sampler; ++i)
for (i = 0; i < shader->limits->sampler; ++i)
{
const struct wined3d_texture *texture = state->textures[i];
if (!shader->reg_maps.sampler_type[i])
if (!shader->reg_maps.resource_info[i].type)
continue;
/* Treat unbound textures as 2D. The dummy texture will provide
@ -2131,7 +2342,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (!shader->reg_maps.sampler_type[i])
if (!shader->reg_maps.resource_info[i].type)
continue;
texture = state->textures[i];
@ -2194,102 +2405,26 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
}
}
static void pixelshader_set_limits(struct wined3d_shader *shader)
{
DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
shader->limits.packed_output = 0;
switch (shader_version)
{
case WINED3D_SHADER_VERSION(1, 0):
case WINED3D_SHADER_VERSION(1, 1):
case WINED3D_SHADER_VERSION(1, 2):
case WINED3D_SHADER_VERSION(1, 3):
shader->limits.constant_float = 8;
shader->limits.constant_int = 0;
shader->limits.constant_bool = 0;
shader->limits.sampler = 4;
shader->limits.packed_input = 0;
break;
case WINED3D_SHADER_VERSION(1, 4):
shader->limits.constant_float = 8;
shader->limits.constant_int = 0;
shader->limits.constant_bool = 0;
shader->limits.sampler = 6;
shader->limits.packed_input = 0;
break;
/* FIXME: Temporaries must match D3DPSHADERCAPS2_0.NumTemps. */
case WINED3D_SHADER_VERSION(2, 0):
shader->limits.constant_float = 32;
shader->limits.constant_int = 16;
shader->limits.constant_bool = 16;
shader->limits.sampler = 16;
shader->limits.packed_input = 0;
break;
case WINED3D_SHADER_VERSION(2, 1):
shader->limits.constant_float = 32;
shader->limits.constant_int = 16;
shader->limits.constant_bool = 16;
shader->limits.sampler = 16;
shader->limits.packed_input = 0;
break;
case WINED3D_SHADER_VERSION(3, 0):
shader->limits.constant_float = 224;
shader->limits.constant_int = 16;
shader->limits.constant_bool = 16;
shader->limits.sampler = 16;
shader->limits.packed_input = 12;
break;
case WINED3D_SHADER_VERSION(4, 0):
shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
shader->limits.constant_int = 0;
shader->limits.constant_float = 0;
shader->limits.constant_bool = 0;
shader->limits.packed_input = 32;
break;
default:
shader->limits.constant_float = 32;
shader->limits.constant_int = 16;
shader->limits.constant_bool = 16;
shader->limits.sampler = 16;
shader->limits.packed_input = 0;
FIXME("Unrecognized pixel shader version %u.%u\n",
shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
}
}
static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
{
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;
if (!desc->byte_code)
return WINED3DERR_INVALIDCALL;
shader_init(shader, device, parent, parent_ops);
hr = shader_set_function(shader, byte_code, output_signature, ps_uniform_count,
WINED3D_SHADER_TYPE_PIXEL, max_version);
if (FAILED(hr))
if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
ps_uniform_count, WINED3D_SHADER_TYPE_PIXEL, desc->max_version)))
{
WARN("Failed to set function, hr %#x.\n", hr);
shader_cleanup(shader);
return hr;
}
pixelshader_set_limits(shader);
for (i = 0; i < MAX_REG_INPUT; ++i)
{
if (shader->u.ps.input_reg_used[i])
@ -2332,55 +2467,97 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de
shader->load_local_constsF = shader->lconst_inf_or_nan;
if (desc->input_signature)
{
struct wined3d_shader_signature_element *e;
SIZE_T total, len;
char *ptr;
total = 0;
for (i = 0; i < desc->input_signature->element_count; ++i)
{
e = &desc->input_signature->elements[i];
len = strlen(e->semantic_name);
if (len >= ~(SIZE_T)0 - total)
{
shader_cleanup(shader);
return E_OUTOFMEMORY;
}
total += len + 1;
}
if (!(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total)))
{
shader_cleanup(shader);
return E_OUTOFMEMORY;
}
ptr = shader->signature_strings;
for (i = 0; i < desc->input_signature->element_count; ++i)
{
e = &desc->input_signature->elements[i];
shader->reg_maps.input_registers |= 1 << e->register_idx;
shader->input_signature[e->register_idx] = *e;
len = strlen(e->semantic_name);
memcpy(ptr, e->semantic_name, len + 1);
shader->input_signature[e->register_idx].semantic_name = ptr;
ptr += len + 1;
if (!strcmp(e->semantic_name, "SV_POSITION"))
shader->reg_maps.vpos = 1;
}
}
return WINED3D_OK;
}
void pixelshader_update_samplers(struct wined3d_shader *shader, WORD tex_types)
void pixelshader_update_resource_types(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;
struct wined3d_shader_resource_info *resource_info = reg_maps->resource_info;
unsigned int i;
if (reg_maps->shader_version.major != 1) return;
for (i = 0; i < shader->limits.sampler; ++i)
for (i = 0; i < shader->limits->sampler; ++i)
{
/* We don't sample from this sampler. */
if (!sampler_type[i]) continue;
if (!resource_info[i].type)
continue;
switch ((tex_types >> i * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK)
{
case WINED3D_SHADER_TEX_2D:
sampler_type[i] = WINED3DSTT_2D;
resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
break;
case WINED3D_SHADER_TEX_3D:
sampler_type[i] = WINED3DSTT_VOLUME;
resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_3D;
break;
case WINED3D_SHADER_TEX_CUBE:
sampler_type[i] = WINED3DSTT_CUBE;
resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_CUBE;
break;
}
}
}
HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const DWORD *byte_code,
const struct wined3d_shader_signature *output_signature, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader)
{
struct wined3d_shader *object;
HRESULT hr;
TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
device, byte_code, output_signature, parent, parent_ops, shader);
TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, parent, parent_ops, shader);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
return E_OUTOFMEMORY;
hr = geometryshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
if (FAILED(hr))
if (FAILED(hr = geometryshader_init(object, device, desc, parent, parent_ops)))
{
WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
@ -2393,22 +2570,20 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const DWOR
return WINED3D_OK;
}
HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const DWORD *byte_code,
const struct wined3d_shader_signature *output_signature, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader)
{
struct wined3d_shader *object;
HRESULT hr;
TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
device, byte_code, output_signature, parent, parent_ops, shader);
TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, parent, parent_ops, shader);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
return E_OUTOFMEMORY;
hr = pixelshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
if (FAILED(hr))
if (FAILED(hr = pixelshader_init(object, device, desc, parent, parent_ops)))
{
WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
@ -2421,22 +2596,20 @@ HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const DWOR
return WINED3D_OK;
}
HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const DWORD *byte_code,
const struct wined3d_shader_signature *output_signature, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader)
{
struct wined3d_shader *object;
HRESULT hr;
TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
device, byte_code, output_signature, parent, parent_ops, shader);
TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, parent, parent_ops, shader);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
return E_OUTOFMEMORY;
hr = vertexshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
if (FAILED(hr))
if (FAILED(hr = vertexshader_init(object, device, desc, parent, parent_ops)))
{
WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);

View file

@ -33,8 +33,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
#define WINED3DSP_DCL_USAGEINDEX_MASK (0xf << WINED3DSP_DCL_USAGEINDEX_SHIFT)
/* DCL sampler type */
#define WINED3DSP_TEXTURETYPE_SHIFT 27
#define WINED3DSP_TEXTURETYPE_MASK (0xf << WINED3DSP_TEXTURETYPE_SHIFT)
#define WINED3D_SM1_RESOURCE_TYPE_SHIFT 27
#define WINED3D_SM1_RESOURCE_TYPE_MASK (0xf << WINED3D_SM1_RESOURCE_TYPE_SHIFT)
/* Opcode-related masks */
#define WINED3DSI_OPCODE_MASK 0x0000ffff
@ -96,6 +96,15 @@ enum WINED3DSHADER_ADDRESSMODE_TYPE
WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
};
enum wined3d_sm1_resource_type
{
WINED3D_SM1_RESOURCE_UNKNOWN = 0x0,
WINED3D_SM1_RESOURCE_TEXTURE_1D = 0x1,
WINED3D_SM1_RESOURCE_TEXTURE_2D = 0x2,
WINED3D_SM1_RESOURCE_TEXTURE_CUBE = 0x3,
WINED3D_SM1_RESOURCE_TEXTURE_3D = 0x4,
};
enum wined3d_sm1_opcode
{
WINED3D_SM1_OP_NOP = 0x00,
@ -374,6 +383,15 @@ static const struct wined3d_sm1_opcode_info ps_opcode_table[] =
{0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 },
};
static const enum wined3d_shader_resource_type resource_type_table[] =
{
/* WINED3D_SM1_RESOURCE_UNKNOWN */ WINED3D_SHADER_RESOURCE_NONE,
/* WINED3D_SM1_RESOURCE_TEXTURE_1D */ WINED3D_SHADER_RESOURCE_TEXTURE_1D,
/* WINED3D_SM1_RESOURCE_TEXTURE_2D */ WINED3D_SHADER_RESOURCE_TEXTURE_2D,
/* WINED3D_SM1_RESOURCE_TEXTURE_CUBE */ WINED3D_SHADER_RESOURCE_TEXTURE_CUBE,
/* WINED3D_SM1_RESOURCE_TEXTURE_3D */ WINED3D_SHADER_RESOURCE_TEXTURE_3D,
};
/* Read a parameter opcode from the input stream,
* and possibly a relative addressing token.
* Return the number of tokens read */
@ -609,12 +627,23 @@ static void shader_sm1_read_dst_param(struct wined3d_sm1_data *priv, const DWORD
static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
{
enum wined3d_sm1_resource_type resource_type;
DWORD usage_token = *(*ptr)++;
DWORD dst_token = *(*ptr)++;
semantic->usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
semantic->usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
semantic->sampler_type = (usage_token & WINED3DSP_TEXTURETYPE_MASK) >> WINED3DSP_TEXTURETYPE_SHIFT;
resource_type = (usage_token & WINED3D_SM1_RESOURCE_TYPE_MASK) >> WINED3D_SM1_RESOURCE_TYPE_SHIFT;
if (resource_type >= ARRAY_SIZE(resource_type_table))
{
FIXME("Unhandled resource type %#x.\n", resource_type);
semantic->resource_type = WINED3D_SHADER_RESOURCE_NONE;
}
else
{
semantic->resource_type = resource_type_table[resource_type];
}
semantic->resource_data_type = WINED3D_DATA_FLOAT;
shader_parse_dst_param(dst_token, NULL, &semantic->reg);
}

View file

@ -26,6 +26,9 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode);
#define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT 24
#define WINED3D_SM4_INSTRUCTION_LENGTH_MASK (0x1f << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
#define WINED3D_SM4_RESOURCE_TYPE_SHIFT 11
#define WINED3D_SM4_RESOURCE_TYPE_MASK (0xf << WINED3D_SM4_RESOURCE_TYPE_SHIFT)
#define WINED3D_SM4_PRIMITIVE_TYPE_SHIFT 11
#define WINED3D_SM4_PRIMITIVE_TYPE_MASK (0x7 << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT)
@ -105,6 +108,8 @@ enum wined3d_sm4_opcode
WINED3D_SM4_OP_MOV = 0x36,
WINED3D_SM4_OP_MOVC = 0x37,
WINED3D_SM4_OP_MUL = 0x38,
WINED3D_SM4_OP_NE = 0x39,
WINED3D_SM4_OP_OR = 0x3c,
WINED3D_SM4_OP_RET = 0x3e,
WINED3D_SM4_OP_ROUND_NI = 0x41,
WINED3D_SM4_OP_RSQ = 0x44,
@ -114,9 +119,11 @@ enum wined3d_sm4_opcode
WINED3D_SM4_OP_SQRT = 0x4b,
WINED3D_SM4_OP_SINCOS = 0x4d,
WINED3D_SM4_OP_UDIV = 0x4e,
WINED3D_SM4_OP_UGE = 0x50,
WINED3D_SM4_OP_USHR = 0x55,
WINED3D_SM4_OP_UTOF = 0x56,
WINED3D_SM4_OP_XOR = 0x57,
WINED3D_SM4_OP_DCL_RESOURCE = 0x58,
WINED3D_SM4_OP_DCL_CONSTANT_BUFFER = 0x59,
WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY = 0x5c,
WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE = 0x5d,
@ -130,6 +137,7 @@ enum wined3d_sm4_register_type
WINED3D_SM4_RT_OUTPUT = 0x2,
WINED3D_SM4_RT_IMMCONST = 0x4,
WINED3D_SM4_RT_SAMPLER = 0x6,
WINED3D_SM4_RT_RESOURCE = 0x7,
WINED3D_SM4_RT_CONSTBUFFER = 0x8,
WINED3D_SM4_RT_PRIMID = 0xb,
WINED3D_SM4_RT_NULL = 0xd,
@ -163,6 +171,28 @@ enum wined3d_sm4_immconst_type
WINED3D_SM4_IMMCONST_VEC4 = 0x2,
};
enum wined3d_sm4_resource_type
{
WINED3D_SM4_RESOURCE_BUFFER = 0x1,
WINED3D_SM4_RESOURCE_TEXTURE_1D = 0x2,
WINED3D_SM4_RESOURCE_TEXTURE_2D = 0x3,
WINED3D_SM4_RESOURCE_TEXTURE_2DMS = 0x4,
WINED3D_SM4_RESOURCE_TEXTURE_3D = 0x5,
WINED3D_SM4_RESOURCE_TEXTURE_CUBE = 0x6,
WINED3D_SM4_RESOURCE_TEXTURE_1DARRAY = 0x7,
WINED3D_SM4_RESOURCE_TEXTURE_2DARRAY = 0x8,
WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY = 0x9,
};
enum wined3d_sm4_data_type
{
WINED3D_SM4_DATA_UNORM = 0x1,
WINED3D_SM4_DATA_SNORM = 0x2,
WINED3D_SM4_DATA_INT = 0x3,
WINED3D_SM4_DATA_UINT = 0x4,
WINED3D_SM4_DATA_FLOAT = 0x5,
};
struct wined3d_shader_src_param_entry
{
struct list entry;
@ -173,7 +203,12 @@ struct wined3d_sm4_data
{
struct wined3d_shader_version shader_version;
const DWORD *end;
const struct wined3d_shader_signature *output_signature;
struct
{
enum wined3d_shader_register_type register_type;
UINT register_idx;
} output_map[MAX_REG_OUTPUT];
struct wined3d_shader_src_param src_param[5];
struct wined3d_shader_dst_param dst_param[2];
@ -242,6 +277,8 @@ static const struct wined3d_sm4_opcode_info opcode_table[] =
{WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, "F", "F"},
{WINED3D_SM4_OP_MOVC, WINED3DSIH_MOVC, "F", "UFF"},
{WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, "F", "FF"},
{WINED3D_SM4_OP_NE, WINED3DSIH_NE, "U", "FF"},
{WINED3D_SM4_OP_OR, WINED3DSIH_OR, "U", "UU"},
{WINED3D_SM4_OP_RET, WINED3DSIH_RET, "", ""},
{WINED3D_SM4_OP_ROUND_NI, WINED3DSIH_ROUND_NI, "F", "F"},
{WINED3D_SM4_OP_RSQ, WINED3DSIH_RSQ, "F", "F"},
@ -251,9 +288,11 @@ static const struct wined3d_sm4_opcode_info opcode_table[] =
{WINED3D_SM4_OP_SQRT, WINED3DSIH_SQRT, "F", "F"},
{WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS, "FF", "F"},
{WINED3D_SM4_OP_UDIV, WINED3DSIH_UDIV, "UU", "UU"},
{WINED3D_SM4_OP_UGE, WINED3DSIH_UGE, "U", "UU"},
{WINED3D_SM4_OP_USHR, WINED3DSIH_USHR, "U", "UU"},
{WINED3D_SM4_OP_UTOF, WINED3DSIH_UTOF, "F", "U"},
{WINED3D_SM4_OP_XOR, WINED3DSIH_XOR, "U", "UU"},
{WINED3D_SM4_OP_DCL_RESOURCE, WINED3DSIH_DCL, "R", ""},
{WINED3D_SM4_OP_DCL_CONSTANT_BUFFER, WINED3DSIH_DCL_CONSTANT_BUFFER, "", ""},
{WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, WINED3DSIH_DCL_OUTPUT_TOPOLOGY, "", ""},
{WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE, WINED3DSIH_DCL_INPUT_PRIMITIVE, "", ""},
@ -313,6 +352,30 @@ static const struct sysval_map sysval_map[] =
{WINED3D_SV_TARGET7, WINED3DSPR_COLOROUT, 7},
};
static const enum wined3d_shader_resource_type resource_type_table[] =
{
/* 0 */ WINED3D_SHADER_RESOURCE_NONE,
/* WINED3D_SM4_RESOURCE_BUFFER */ WINED3D_SHADER_RESOURCE_BUFFER,
/* WINED3D_SM4_RESOURCE_TEXTURE_1D */ WINED3D_SHADER_RESOURCE_TEXTURE_1D,
/* WINED3D_SM4_RESOURCE_TEXTURE_2D */ WINED3D_SHADER_RESOURCE_TEXTURE_2D,
/* WINED3D_SM4_RESOURCE_TEXTURE_2DMS */ WINED3D_SHADER_RESOURCE_TEXTURE_2DMS,
/* WINED3D_SM4_RESOURCE_TEXTURE_3D */ WINED3D_SHADER_RESOURCE_TEXTURE_3D,
/* WINED3D_SM4_RESOURCE_TEXTURE_CUBE */ WINED3D_SHADER_RESOURCE_TEXTURE_CUBE,
/* WINED3D_SM4_RESOURCE_TEXTURE_1DARRAY */ WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY,
/* WINED3D_SM4_RESOURCE_TEXTURE_2DARRAY */ WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY,
/* WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY */ WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY,
};
static const enum wined3d_data_type data_type_table[] =
{
/* 0 */ WINED3D_DATA_FLOAT,
/* WINED3D_SM4_DATA_UNORM */ WINED3D_DATA_UNORM,
/* WINED3D_SM4_DATA_SNORM */ WINED3D_DATA_SNORM,
/* WINED3D_SM4_DATA_INT */ WINED3D_DATA_INT,
/* WINED3D_SM4_DATA_UINT */ WINED3D_DATA_UINT,
/* WINED3D_SM4_DATA_FLOAT */ WINED3D_DATA_FLOAT,
};
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param);
@ -328,20 +391,6 @@ static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_op
return NULL;
}
static void map_sysval(enum wined3d_sysval_semantic sysval, struct wined3d_shader_register *reg)
{
unsigned int i;
for (i = 0; i < sizeof(sysval_map) / sizeof(*sysval_map); ++i)
{
if (sysval == sysval_map[i].sysval)
{
reg->type = sysval_map[i].register_type;
reg->idx[0].offset = sysval_map[i].register_idx;
}
}
}
static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_shader_register *reg)
{
switch (priv->shader_version.type)
@ -349,23 +398,16 @@ static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_sha
case WINED3D_SHADER_TYPE_PIXEL:
if (reg->type == WINED3DSPR_OUTPUT)
{
unsigned int i;
const struct wined3d_shader_signature *s = priv->output_signature;
unsigned int reg_idx = reg->idx[0].offset;
if (!s)
if (reg_idx >= ARRAY_SIZE(priv->output_map))
{
ERR("Shader has no output signature, unable to map register.\n");
ERR("Invalid output index %u.\n", reg_idx);
break;
}
for (i = 0; i < s->element_count; ++i)
{
if (s->elements[i].register_idx == reg->idx[0].offset)
{
map_sysval(s->elements[i].sysval_semantic, reg);
break;
}
}
reg->type = priv->output_map[reg_idx].register_type;
reg->idx[0].offset = priv->output_map[reg_idx].register_idx;
}
break;
@ -396,14 +438,37 @@ static enum wined3d_data_type map_data_type(char t)
static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature)
{
struct wined3d_sm4_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
if (!priv)
struct wined3d_sm4_data *priv;
unsigned int i, j;
if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
{
ERR("Failed to allocate private data\n");
return NULL;
}
priv->output_signature = output_signature;
memset(priv->output_map, 0xff, sizeof(priv->output_map));
for (i = 0; i < output_signature->element_count; ++i)
{
struct wined3d_shader_signature_element *e = &output_signature->elements[i];
if (e->register_idx >= ARRAY_SIZE(priv->output_map))
{
WARN("Invalid output index %u.\n", e->register_idx);
continue;
}
for (j = 0; j < ARRAY_SIZE(sysval_map); ++j)
{
if (e->sysval_semantic == sysval_map[j].sysval)
{
priv->output_map[e->register_idx].register_type = sysval_map[j].register_type;
priv->output_map[e->register_idx].register_idx = sysval_map[j].register_idx;
break;
}
}
}
list_init(&priv->src_free);
list_init(&priv->src);
@ -731,7 +796,40 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi
FIXME("Skipping modifier 0x%08x.\n", modifier);
}
if (opcode == WINED3D_SM4_OP_DCL_CONSTANT_BUFFER)
if (opcode == WINED3D_SM4_OP_DCL_RESOURCE)
{
enum wined3d_sm4_resource_type resource_type;
enum wined3d_sm4_data_type data_type;
DWORD components;
resource_type = (opcode_token & WINED3D_SM4_RESOURCE_TYPE_MASK) >> WINED3D_SM4_RESOURCE_TYPE_SHIFT;
if (!resource_type || (resource_type >= ARRAY_SIZE(resource_type_table)))
{
FIXME("Unhandled resource type %#x.\n", resource_type);
ins->declaration.semantic.resource_type = WINED3D_SHADER_RESOURCE_NONE;
}
else
{
ins->declaration.semantic.resource_type = resource_type_table[resource_type];
}
shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_RESOURCE, &ins->declaration.semantic.reg);
components = *p++;
if ((components & 0xfff0) != (components & 0xf) * 0x1110)
FIXME("Components (%#x) have different data types.\n", components);
data_type = components & 0xf;
if (!data_type || (data_type >= ARRAY_SIZE(data_type_table)))
{
FIXME("Unhandled data type %#x.\n", data_type);
ins->declaration.semantic.resource_data_type = WINED3D_DATA_FLOAT;
}
else
{
ins->declaration.semantic.resource_data_type = data_type_table[data_type];
}
}
else if (opcode == WINED3D_SM4_OP_DCL_CONSTANT_BUFFER)
{
shader_sm4_read_src_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.src);
if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK)

View file

@ -95,7 +95,6 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_
{
enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE];
const struct wined3d_gl_info *gl_info = context->gl_info;
static UINT once;
/* No z test without depth stencil buffers */
if (!state->fb->depth_stencil)
@ -124,21 +123,8 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_
break;
}
if (context->gl_info->supported[ARB_DEPTH_CLAMP])
{
if (!zenable && context->stream_info.position_transformed)
{
gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
checkGLcall("glEnable(GL_DEPTH_CLAMP)");
}
else
{
gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
checkGLcall("glDisable(GL_DEPTH_CLAMP)");
}
}
else if (!zenable && !once++)
FIXME("Z buffer disabled, but ARB_depth_clamp isn't supported.\n");
if (context->last_was_rhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
}
static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -226,7 +212,7 @@ static void state_zwritenable(struct wined3d_context *context, const struct wine
}
}
static GLenum gl_compare_func(enum wined3d_cmp_func f)
GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f)
{
switch (f)
{
@ -254,7 +240,7 @@ static GLenum gl_compare_func(enum wined3d_cmp_func f)
static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
GLenum depth_func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
const struct wined3d_gl_info *gl_info = context->gl_info;
if (!depth_func) return;
@ -309,7 +295,7 @@ static void state_blendop(struct wined3d_context *context, const struct wined3d_
if (state->render_states[WINED3D_RS_BLENDOPALPHA]
&& !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
{
WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparate.\n");
return;
}
@ -319,12 +305,12 @@ static void state_blendop(struct wined3d_context *context, const struct wined3d_
if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
{
GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
checkGLcall("glBlendEquationSeparateEXT");
GL_EXTCALL(glBlendEquationSeparate(blend_equation, blend_equation_alpha));
checkGLcall("glBlendEquationSeparate");
}
else
{
GL_EXTCALL(glBlendEquationEXT(blend_equation));
GL_EXTCALL(glBlendEquation(blend_equation));
checkGLcall("glBlendEquation");
}
}
@ -454,7 +440,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
/* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
{
WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparate.\n");
return;
}
@ -478,8 +464,8 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA], rt_format);
}
GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
checkGLcall("glBlendFuncSeparateEXT");
GL_EXTCALL(glBlendFuncSeparate(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
checkGLcall("glBlendFuncSeparate");
}
else
{
@ -496,7 +482,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
WARN("Unsupported in local OpenGL implementation: glBlendColor.\n");
}
static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -507,7 +493,7 @@ static void state_blendfactor(struct wined3d_context *context, const struct wine
TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
GL_EXTCALL(glBlendColor(col[0], col[1], col[2], col[3]));
checkGLcall("glBlendColor");
}
@ -527,7 +513,7 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st
* WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture
* function will call alpha in case it finds some texture + colorkeyenable
* combination which needs extra care. */
if (state->textures[0] && (state->textures[0]->color_key_flags & WINEDDSD_CKSRCBLT))
if (state->textures[0] && (state->textures[0]->color_key_flags & WINED3D_CKEY_SRC_BLT))
enable_ckey = TRUE;
if (enable_ckey || context->last_was_ckey)
@ -558,7 +544,7 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st
else
{
ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
glParm = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
}
if (glParm)
{
@ -827,9 +813,9 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_
onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
if (!(func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
func = GL_ALWAYS;
if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
if (!(func_ccw = wined3d_gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
func_ccw = GL_ALWAYS;
ref = state->render_states[WINED3D_RS_STENCILREF];
mask = state->render_states[WINED3D_RS_STENCILMASK];
@ -852,7 +838,15 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_
gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
checkGLcall("glEnable GL_STENCIL_TEST");
if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
if (gl_info->supported[WINED3D_GL_VERSION_2_0])
{
GL_EXTCALL(glStencilFuncSeparate(GL_FRONT, func, ref, mask));
GL_EXTCALL(glStencilOpSeparate(GL_FRONT, stencilFail, depthFail, stencilPass));
GL_EXTCALL(glStencilFuncSeparate(GL_BACK, func_ccw, ref, mask));
GL_EXTCALL(glStencilOpSeparate(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
checkGLcall("setting two sided stencil state");
}
else if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
{
/* Apply back first, then front. This function calls glActiveStencilFaceEXT,
* which has an effect on the code below too. If we apply the front face
@ -873,7 +867,9 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_
checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
} else {
}
else
{
ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
}
}
@ -1592,11 +1588,12 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined
static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
{
GL_EXTCALL(glColorMaskIndexedEXT(index,
GL_EXTCALL(glColorMaski(index,
mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
checkGLcall("glColorMaski");
}
static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -3205,7 +3202,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
{
if (texture->color_key_flags & WINEDDSD_CKSRCBLT && !texture->resource.format->alpha_size)
if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size)
{
/* Color keying needs to pass alpha values from the texture through to have the alpha test work
* properly. On the other hand applications can still use texture combiners apparently. This code
@ -3358,8 +3355,8 @@ static void load_tex_coords(const struct wined3d_context *context, const struct
if (*curVBO != e->data.buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
checkGLcall("glBindBuffer");
*curVBO = e->data.buffer_object;
}
@ -3595,24 +3592,92 @@ void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_sta
}
}
static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static enum wined3d_texture_address wined3d_texture_address_mode(const struct wined3d_texture *texture,
enum wined3d_texture_address t)
{
DWORD sampler = state_id - STATE_SAMPLER(0);
DWORD mapped_stage = context->tex_unit_map[sampler];
const struct wined3d_gl_info *gl_info = context->gl_info;
union {
if (t < WINED3D_TADDRESS_WRAP || t > WINED3D_TADDRESS_MIRROR_ONCE)
{
FIXME("Unrecognized or unsupported texture address mode %#x.\n", t);
return WINED3D_TADDRESS_WRAP;
}
/* Cubemaps are always set to clamp, regardless of the sampler state. */
if (texture->target == GL_TEXTURE_CUBE_MAP_ARB || ((texture->flags & WINED3D_TEXTURE_COND_NP2)
&& t == WINED3D_TADDRESS_WRAP))
return WINED3D_TADDRESS_CLAMP;
return t;
}
static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc *desc,
const struct wined3d_gl_info *gl_info, const DWORD *sampler_states, const struct wined3d_texture *texture)
{
union
{
float f;
DWORD d;
} tmpvalue;
} lod_bias;
desc->address_u = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_U]);
desc->address_v = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_V]);
desc->address_w = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_W]);
D3DCOLORTOGLFLOAT4(sampler_states[WINED3D_SAMP_BORDER_COLOR], desc->border_color);
if (sampler_states[WINED3D_SAMP_MAG_FILTER] > WINED3D_TEXF_ANISOTROPIC)
FIXME("Unrecognized or unsupported WINED3D_SAMP_MAG_FILTER %#x.\n",
sampler_states[WINED3D_SAMP_MAG_FILTER]);
desc->mag_filter = min(max(sampler_states[WINED3D_SAMP_MAG_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR);
if (sampler_states[WINED3D_SAMP_MIN_FILTER] > WINED3D_TEXF_ANISOTROPIC)
FIXME("Unrecognized or unsupported WINED3D_SAMP_MIN_FILTER %#x.\n",
sampler_states[WINED3D_SAMP_MIN_FILTER]);
desc->min_filter = min(max(sampler_states[WINED3D_SAMP_MIN_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR);
if (sampler_states[WINED3D_SAMP_MIP_FILTER] > WINED3D_TEXF_ANISOTROPIC)
FIXME("Unrecognized or unsupported WINED3D_SAMP_MIP_FILTER %#x.\n",
sampler_states[WINED3D_SAMP_MIP_FILTER]);
desc->mip_filter = min(max(sampler_states[WINED3D_SAMP_MIP_FILTER], WINED3D_TEXF_NONE), WINED3D_TEXF_LINEAR);
lod_bias.d = sampler_states[WINED3D_SAMP_MIPMAP_LOD_BIAS];
desc->lod_bias = lod_bias.f;
desc->min_lod = -1000.0f;
desc->max_lod = 1000.0f;
desc->max_anisotropy = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY];
if ((sampler_states[WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_ANISOTROPIC
&& sampler_states[WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_ANISOTROPIC
&& sampler_states[WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_ANISOTROPIC)
|| (texture->flags & WINED3D_TEXTURE_COND_NP2))
desc->max_anisotropy = 1;
desc->compare = texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW;
desc->comparison_func = WINED3D_CMP_LESSEQUAL;
desc->srgb_decode = sampler_states[WINED3D_SAMP_SRGB_TEXTURE];
if (!(texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING))
{
desc->mag_filter = WINED3D_TEXF_POINT;
desc->min_filter = WINED3D_TEXF_POINT;
desc->mip_filter = WINED3D_TEXF_NONE;
}
if (texture->flags & WINED3D_TEXTURE_COND_NP2)
{
desc->mip_filter = WINED3D_TEXF_NONE;
if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
desc->min_filter = WINED3D_TEXF_POINT;
}
}
/* Enabling and disabling texture dimensions is done by texture stage state /
* pixel shader setup, this function only has to bind textures and set the per
* texture states. */
static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD sampler_idx = state_id - STATE_SAMPLER(0);
DWORD mapped_stage = context->tex_unit_map[sampler_idx];
const struct wined3d_gl_info *gl_info = context->gl_info;
TRACE("Sampler %u.\n", sampler_idx);
TRACE("Sampler: %d\n", sampler);
/* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
* only has to bind textures and set the per texture states
*/
if (mapped_stage == WINED3D_UNMAPPED_STAGE)
{
TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
TRACE("No sampler mapped to stage %u. Returning.\n", sampler_idx);
return;
}
@ -3622,25 +3687,75 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
}
context_active_texture(context, gl_info, mapped_stage);
if (state->textures[sampler])
if (state->textures[sampler_idx])
{
struct wined3d_texture *texture = state->textures[sampler];
BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
struct wined3d_texture *texture = state->textures[sampler_idx];
BOOL srgb = state->sampler_states[sampler_idx][WINED3D_SAMP_SRGB_TEXTURE];
const DWORD *sampler_states = state->sampler_states[sampler_idx];
struct wined3d_sampler_desc desc;
struct gl_texture *gl_tex;
unsigned int base_level;
wined3d_sampler_desc_from_sampler_states(&desc, gl_info, sampler_states, texture);
wined3d_texture_bind(texture, context, srgb);
wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
if (!gl_info->supported[ARB_SAMPLER_OBJECTS])
{
tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
wined3d_texture_apply_sampler_desc(texture, &desc, gl_info);
}
else
{
struct wined3d_device *device = context->swapchain->device;
struct wined3d_sampler *sampler;
struct wine_rb_entry *entry;
if ((entry = wine_rb_get(&device->samplers, &desc)))
{
sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
}
else
{
if (FAILED(wined3d_sampler_create(device, &desc, NULL, &sampler)))
{
ERR("Failed to create sampler.\n");
sampler = NULL;
}
else
{
if (wine_rb_put(&device->samplers, &desc, &sampler->entry) == -1)
ERR("Failed to insert sampler.\n");
}
}
if (sampler)
{
GL_EXTCALL(glBindSampler(sampler_idx, sampler->name));
checkGLcall("glBindSampler");
}
}
if (!use_ps(state) && sampler < context->lowest_disabled_stage)
if (texture->flags & WINED3D_TEXTURE_COND_NP2)
base_level = 0;
else if (desc.mip_filter == WINED3D_TEXF_NONE)
base_level = texture->lod;
else
base_level = min(max(sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL],
texture->lod), texture->level_count - 1);
gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB);
if (base_level != gl_tex->base_level)
{
if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
/* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap
* (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest
* mimap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL
* corresponds to GL_TEXTURE_BASE_LEVEL. */
gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, base_level);
gl_tex->base_level = base_level;
}
if (!use_ps(state) && sampler_idx < context->lowest_disabled_stage)
{
if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler_idx)
{
/* If color keying is enabled update the alpha test, it
* depends on the existence of a color key in stage 0. */
@ -3654,10 +3769,10 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
}
else
{
if (sampler < context->lowest_disabled_stage)
if (sampler_idx < context->lowest_disabled_stage)
{
/* TODO: What should I do with pixel shaders here ??? */
if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler_idx)
{
/* If color keying is enabled update the alpha test, it
* depends on the existence of a color key in stage 0. */
@ -3968,12 +4083,16 @@ void transform_projection(struct wined3d_context *context, const struct wined3d_
double y_offset = context->render_offscreen
? ((63.0 / 64.0) - (2.0 * y) - h) / h
: ((63.0 / 64.0) - (2.0 * y) - h) / -h;
enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ?
state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE;
double z_scale = zenable ? 2.0f : 0.0f;
double z_offset = zenable ? -1.0f : 0.0f;
const GLdouble projection[] =
{
x_scale, 0.0, 0.0, 0.0,
0.0, y_scale, 0.0, 0.0,
0.0, 0.0, 2.0, 0.0,
x_offset, y_offset, -1.0, 1.0,
x_scale, 0.0, 0.0, 0.0,
0.0, y_scale, 0.0, 0.0,
0.0, 0.0, z_scale, 0.0,
x_offset, y_offset, z_offset, 1.0,
};
gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
@ -4020,10 +4139,10 @@ static inline void unload_numbered_array(struct wined3d_context *context, int i)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
GL_EXTCALL(glDisableVertexAttribArrayARB(i));
checkGLcall("glDisableVertexAttribArrayARB(reg)");
GL_EXTCALL(glDisableVertexAttribArray(i));
checkGLcall("glDisableVertexAttribArray");
if (gl_info->supported[ARB_INSTANCED_ARRAYS])
GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
GL_EXTCALL(glVertexAttribDivisor(i, 0));
context->numbered_array_mask &= ~(1 << i);
}
@ -4059,7 +4178,7 @@ static void load_numbered_arrays(struct wined3d_context *context,
if (context->numbered_array_mask & (1 << i))
unload_numbered_array(context, i);
if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.input_registers & (1 << i))
GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f));
continue;
}
@ -4079,11 +4198,11 @@ static void load_numbered_arrays(struct wined3d_context *context,
continue;
}
GL_EXTCALL(glVertexAttribDivisorARB(i, 1));
GL_EXTCALL(glVertexAttribDivisor(i, 1));
}
else if (gl_info->supported[ARB_INSTANCED_ARRAYS])
{
GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
GL_EXTCALL(glVertexAttribDivisor(i, 0));
}
TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
@ -4092,15 +4211,15 @@ static void load_numbered_arrays(struct wined3d_context *context,
{
if (curVBO != stream_info->elements[i].data.buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, stream_info->elements[i].data.buffer_object));
checkGLcall("glBindBuffer");
curVBO = stream_info->elements[i].data.buffer_object;
}
/* Use the VBO to find out if a vertex buffer exists, not the vb
* pointer. vb can point to a user pointer data blob. In that case
* curVBO will be 0. If there is a vertex buffer but no vbo we
* won't be load converted attributes anyway. */
GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
GL_EXTCALL(glVertexAttribPointer(i, stream_info->elements[i].format->gl_vtx_format,
stream_info->elements[i].format->gl_vtx_type,
stream_info->elements[i].format->gl_normalized,
stream_info->elements[i].stride, stream_info->elements[i].data.addr
@ -4108,14 +4227,14 @@ static void load_numbered_arrays(struct wined3d_context *context,
if (!(context->numbered_array_mask & (1 << i)))
{
GL_EXTCALL(glEnableVertexAttribArrayARB(i));
GL_EXTCALL(glEnableVertexAttribArray(i));
context->numbered_array_mask |= (1 << i);
}
}
else
{
/* Stride = 0 means always the same values.
* glVertexAttribPointerARB doesn't do that. Instead disable the
* glVertexAttribPointer doesn't do that. Instead disable the
* pointer and set up the attribute statically. But we have to
* figure out the system memory address. */
const BYTE *ptr = stream_info->elements[i].data.addr;
@ -4129,20 +4248,20 @@ static void load_numbered_arrays(struct wined3d_context *context,
switch (stream_info->elements[i].format->id)
{
case WINED3DFMT_R32_FLOAT:
GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr));
break;
case WINED3DFMT_R32G32_FLOAT:
GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr));
break;
case WINED3DFMT_R32G32B32_FLOAT:
GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr));
break;
case WINED3DFMT_R32G32B32A32_FLOAT:
GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr));
break;
case WINED3DFMT_R8G8B8A8_UINT:
GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
GL_EXTCALL(glVertexAttrib4ubv(i, ptr));
break;
case WINED3DFMT_B8G8R8A8_UNORM:
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
@ -4151,38 +4270,38 @@ static void load_numbered_arrays(struct wined3d_context *context,
DWORD c = *src & 0xff00ff00;
c |= (*src & 0xff0000) >> 16;
c |= (*src & 0xff) << 16;
GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c));
break;
}
/* else fallthrough */
case WINED3DFMT_R8G8B8A8_UNORM:
GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
GL_EXTCALL(glVertexAttrib4Nubv(i, ptr));
break;
case WINED3DFMT_R16G16_SINT:
GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr));
break;
case WINED3DFMT_R16G16B16A16_SINT:
GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
GL_EXTCALL(glVertexAttrib4sv(i, (const GLshort *)ptr));
break;
case WINED3DFMT_R16G16_SNORM:
{
const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
GL_EXTCALL(glVertexAttrib4Nsv(i, s));
break;
}
case WINED3DFMT_R16G16_UNORM:
{
const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
GL_EXTCALL(glVertexAttrib4Nusv(i, s));
break;
}
case WINED3DFMT_R16G16B16A16_SNORM:
GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr));
break;
case WINED3DFMT_R16G16B16A16_UNORM:
GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr));
break;
case WINED3DFMT_R10G10B10A2_UINT:
@ -4204,7 +4323,7 @@ static void load_numbered_arrays(struct wined3d_context *context,
{
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
GL_EXTCALL(glVertexAttrib2fARB(i, x, y));
GL_EXTCALL(glVertexAttrib2f(i, x, y));
}
break;
case WINED3DFMT_R16G16B16A16_FLOAT:
@ -4219,7 +4338,7 @@ static void load_numbered_arrays(struct wined3d_context *context,
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
float z = float_16_to_32(((const unsigned short *)ptr) + 2);
float w = float_16_to_32(((const unsigned short *)ptr) + 3);
GL_EXTCALL(glVertexAttrib4fARB(i, x, y, z, w));
GL_EXTCALL(glVertexAttrib4f(i, x, y, z, w));
}
break;
@ -4263,8 +4382,8 @@ static void load_vertex_data(struct wined3d_context *context,
if (curVBO != e->data.buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
checkGLcall("glBindBuffer");
curVBO = e->data.buffer_object;
}
@ -4319,8 +4438,8 @@ static void load_vertex_data(struct wined3d_context *context,
if (curVBO != e->data.buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
checkGLcall("glBindBuffer");
curVBO = e->data.buffer_object;
}
@ -4341,8 +4460,8 @@ static void load_vertex_data(struct wined3d_context *context,
if (curVBO != e->data.buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
checkGLcall("glBindBuffer");
curVBO = e->data.buffer_object;
}
@ -4368,8 +4487,8 @@ static void load_vertex_data(struct wined3d_context *context,
if (curVBO != e->data.buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
checkGLcall("glBindBuffer");
curVBO = e->data.buffer_object;
}
@ -4403,8 +4522,8 @@ static void load_vertex_data(struct wined3d_context *context,
if (curVBO != e->data.buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
checkGLcall("glBindBuffer");
curVBO = e->data.buffer_object;
}
@ -4638,9 +4757,6 @@ void vertexdeclaration(struct wined3d_context *context, const struct wined3d_sta
&& state->shader[WINED3D_SHADER_TYPE_PIXEL]->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)))
state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
}
static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -4842,12 +4958,12 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st
if (!state->index_buffer || !stream_info->all_vbo)
{
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
else
{
struct wined3d_buffer *ib = state->index_buffer;
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer_object));
}
}
@ -4883,11 +4999,8 @@ static void psorigin(struct wined3d_context *context, const struct wined3d_state
const struct wined3d_gl_info *gl_info = context->gl_info;
GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
if (gl_info->supported[NV_POINT_SPRITE])
{
GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
}
GL_EXTCALL(glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin));
checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
}
void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -4954,6 +5067,14 @@ static void state_cb_warn(struct wined3d_context *context, const struct wined3d_
WARN("Constant buffers (%s) no supported.\n", debug_d3dstate(state_id));
}
static void state_shader_resource_binding(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
context->update_shader_resource_bindings = 1;
}
const struct StateEntryTemplate misc_state_template[] =
{
{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), state_cb_vs, }, ARB_UNIFORM_BUFFER_OBJECT },
@ -4962,6 +5083,7 @@ const struct StateEntryTemplate misc_state_template[] =
{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),state_cb_warn, }, WINED3D_GL_EXT_NONE },
{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), state_cb_ps, }, ARB_UNIFORM_BUFFER_OBJECT },
{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), state_cb_warn, }, WINED3D_GL_EXT_NONE },
{ STATE_SHADER_RESOURCE_BINDING, { STATE_SHADER_RESOURCE_BINDING, state_shader_resource_binding}, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
@ -5893,6 +6015,7 @@ static void validate_state_table(struct StateEntry *state_table)
STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX),
STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),
STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL),
STATE_SHADER_RESOURCE_BINDING,
STATE_VIEWPORT,
STATE_LIGHT_TYPE,
STATE_SCISSORRECT,

View file

@ -456,6 +456,7 @@ ULONG CDECL wined3d_stateblock_incref(struct wined3d_stateblock *stateblock)
void state_unbind_resources(struct wined3d_state *state)
{
struct wined3d_shader_resource_view *srv;
struct wined3d_vertex_declaration *decl;
struct wined3d_sampler *sampler;
struct wined3d_texture *texture;
@ -527,6 +528,15 @@ void state_unbind_resources(struct wined3d_state *state)
wined3d_sampler_decref(sampler);
}
}
for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j)
{
if ((srv = state->shader_resource_view[i][j]))
{
state->shader_resource_view[i][j] = NULL;
wined3d_shader_resource_view_decref(srv);
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -134,12 +134,17 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
const RGNDATA *dirty_region, DWORD flags)
{
static DWORD notified_flags = 0;
TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
dst_window_override, dirty_region, flags);
if (flags)
FIXME("Ignoring flags %#x.\n", flags);
if (flags & ~notified_flags)
{
FIXME("Ignoring flags %#x.\n", flags & ~notified_flags);
notified_flags |= flags;
}
if (!swapchain->back_buffers)
{
@ -347,7 +352,7 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
context2 = context_acquire(device, backbuffer);
context_apply_blit_state(context2, device);
if (backbuffer->flags & SFLAG_NORMCOORD)
if (backbuffer->container->flags & WINED3D_TEXTURE_NORMALIZED_COORDS)
{
tex_left /= src_w;
tex_right /= src_w;
@ -873,16 +878,14 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
if (!desc->windowed)
{
struct wined3d_display_mode mode;
/* Change the display settings */
mode.width = desc->backbuffer_width;
mode.height = desc->backbuffer_height;
mode.format_id = desc->backbuffer_format;
mode.refresh_rate = desc->refresh_rate;
mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
swapchain->d3d_mode.width = desc->backbuffer_width;
swapchain->d3d_mode.height = desc->backbuffer_height;
swapchain->d3d_mode.format_id = desc->backbuffer_format;
swapchain->d3d_mode.refresh_rate = desc->refresh_rate;
swapchain->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &mode)))
if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &swapchain->d3d_mode)))
{
WARN("Failed to set display mode, hr %#x.\n", hr);
goto err;
@ -1173,3 +1176,54 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain)
wined3d_resource_update_draw_binding(&swapchain->back_buffers[i]->resource);
}
}
void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate)
{
struct wined3d_device *device = swapchain->device;
BOOL filter_messages = device->filter_messages;
/* This code is not protected by the wined3d mutex, so it may run while
* wined3d_device_reset is active. Testing on Windows shows that changing
* focus during resets and resetting during focus change events causes
* the application to crash with an invalid memory access. */
device->filter_messages = !(device->wined3d->flags & WINED3D_FOCUS_MESSAGES);
if (activate)
{
if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES))
{
/* The d3d versions do not agree on the exact messages here. D3d8 restores
* the window but leaves the size untouched, d3d9 sets the size on an
* invisible window, generates messages but doesn't change the window
* properties. The implementation follows d3d9.
*
* Guild Wars 1 wants a WINDOWPOSCHANGED message on the device window to
* resume drawing after a focus loss. */
SetWindowPos(swapchain->device_window, NULL, 0, 0,
swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height,
SWP_NOACTIVATE | SWP_NOZORDER);
}
if (device->wined3d->flags & WINED3D_RESTORE_MODE_ON_ACTIVATE)
{
if (FAILED(wined3d_set_adapter_display_mode(device->wined3d,
device->adapter->ordinal, &swapchain->d3d_mode)))
ERR("Failed to set display mode.\n");
}
}
else
{
if (FAILED(wined3d_set_adapter_display_mode(device->wined3d,
device->adapter->ordinal, NULL)))
ERR("Failed to set display mode.\n");
swapchain->reapply_mode = TRUE;
if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES)
&& IsWindowVisible(swapchain->device_window))
ShowWindow(swapchain->device_window, SW_MINIMIZE);
}
device->filter_messages = filter_messages;
}

View file

@ -26,19 +26,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_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)
UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD surface_flags,
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;
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",
"surface_flags %#x, device %p, parent %p, parent_ops %p, resource_ops %p.\n",
texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type),
debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality,
debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth,
device, parent, parent_ops, resource_ops);
surface_flags, device, parent, parent_ops, resource_ops);
if ((format->flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BLOCKS_NO_VERIFY)) == WINED3DFMT_FLAG_BLOCKS)
{
@ -78,18 +79,9 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
texture->level_count = level_count;
texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE;
texture->lod = 0;
texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT;
if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING)
{
texture->min_mip_lookup = minMipLookup;
texture->mag_lookup = magLookup;
}
else
{
texture->min_mip_lookup = minMipLookup_noFilter;
texture->mag_lookup = magLookup_noFilter;
}
texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS;
if (surface_flags & WINED3D_SURFACE_PIN_SYSMEM)
texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM;
return WINED3D_OK;
}
@ -202,20 +194,24 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
/* Initialise the state of the texture object to the OpenGL defaults, not
* the wined3d defaults. */
gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_WRAP;
gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_WRAP;
gl_tex->states[WINED3DTEXSTA_ADDRESSW] = WINED3D_TADDRESS_WRAP;
gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = 0;
gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_LINEAR;
gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
gl_tex->sampler_desc.address_u = WINED3D_TADDRESS_WRAP;
gl_tex->sampler_desc.address_v = WINED3D_TADDRESS_WRAP;
gl_tex->sampler_desc.address_w = WINED3D_TADDRESS_WRAP;
memset(gl_tex->sampler_desc.border_color, 0, sizeof(gl_tex->sampler_desc.border_color));
gl_tex->sampler_desc.mag_filter = WINED3D_TEXF_LINEAR;
gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
gl_tex->sampler_desc.lod_bias = 0.0f;
gl_tex->sampler_desc.min_lod = -1000.0f;
gl_tex->sampler_desc.max_lod = 1000.0f;
gl_tex->sampler_desc.max_anisotropy = 1;
gl_tex->sampler_desc.compare = FALSE;
gl_tex->sampler_desc.comparison_func = WINED3D_CMP_LESSEQUAL;
if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = TRUE;
gl_tex->sampler_desc.srgb_decode = TRUE;
else
gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = srgb;
gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
gl_tex->sampler_desc.srgb_decode = srgb;
gl_tex->base_level = 0;
wined3d_texture_set_dirty(texture);
context_bind_texture(context, target, gl_tex->name);
@ -262,11 +258,11 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
checkGLcall("glTexParameteri");
gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_CLAMP;
gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_CLAMP;
gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT;
gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT;
gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE;
gl_tex->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP;
gl_tex->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP;
gl_tex->sampler_desc.mag_filter = WINED3D_TEXF_POINT;
gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT;
gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_NONE;
}
}
@ -292,190 +288,106 @@ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture,
wined3d_texture_bind(texture, context, srgb);
}
/* Context activation is done by the caller. */
static void apply_wrap(const struct wined3d_gl_info *gl_info, GLenum target,
enum wined3d_texture_address d3d_wrap, GLenum param, BOOL cond_np2)
{
GLint gl_wrap;
if (d3d_wrap < WINED3D_TADDRESS_WRAP || d3d_wrap > WINED3D_TADDRESS_MIRROR_ONCE)
{
FIXME("Unrecognized or unsupported texture address mode %#x.\n", d3d_wrap);
return;
}
/* Cubemaps are always set to clamp, regardless of the sampler state. */
if (target == GL_TEXTURE_CUBE_MAP_ARB
|| (cond_np2 && d3d_wrap == WINED3D_TADDRESS_WRAP))
gl_wrap = GL_CLAMP_TO_EDGE;
else
gl_wrap = gl_info->wrap_lookup[d3d_wrap - WINED3D_TADDRESS_WRAP];
TRACE("Setting param %#x to %#x for target %#x.\n", param, gl_wrap, target);
gl_info->gl_ops.gl.p_glTexParameteri(target, param, gl_wrap);
checkGLcall("glTexParameteri(target, param, gl_wrap)");
}
/* Context activation is done by the caller (state handler). */
void wined3d_texture_apply_state_changes(struct wined3d_texture *texture,
const DWORD sampler_states[WINED3D_HIGHEST_SAMPLER_STATE + 1],
const struct wined3d_gl_info *gl_info)
/* This function relies on the correct texture being bound and loaded. */
void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture,
const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info)
{
BOOL cond_np2 = texture->flags & WINED3D_TEXTURE_COND_NP2;
GLenum target = texture->target;
struct gl_texture *gl_tex;
DWORD state;
DWORD aniso;
TRACE("texture %p, sampler_states %p.\n", texture, sampler_states);
TRACE("texture %p, sampler_desc %p, gl_info %p.\n", texture, sampler_desc, gl_info);
gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB);
/* This function relies on the correct texture being bound and loaded. */
if (sampler_states[WINED3D_SAMP_ADDRESS_U] != gl_tex->states[WINED3DTEXSTA_ADDRESSU])
state = sampler_desc->address_u;
if (state != gl_tex->sampler_desc.address_u)
{
state = sampler_states[WINED3D_SAMP_ADDRESS_U];
apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_S, cond_np2);
gl_tex->states[WINED3DTEXSTA_ADDRESSU] = state;
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S,
gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
gl_tex->sampler_desc.address_u = state;
}
if (sampler_states[WINED3D_SAMP_ADDRESS_V] != gl_tex->states[WINED3DTEXSTA_ADDRESSV])
state = sampler_desc->address_v;
if (state != gl_tex->sampler_desc.address_v)
{
state = sampler_states[WINED3D_SAMP_ADDRESS_V];
apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_T, cond_np2);
gl_tex->states[WINED3DTEXSTA_ADDRESSV] = state;
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T,
gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
gl_tex->sampler_desc.address_v = state;
}
if (sampler_states[WINED3D_SAMP_ADDRESS_W] != gl_tex->states[WINED3DTEXSTA_ADDRESSW])
state = sampler_desc->address_w;
if (state != gl_tex->sampler_desc.address_w)
{
state = sampler_states[WINED3D_SAMP_ADDRESS_W];
apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_R, cond_np2);
gl_tex->states[WINED3DTEXSTA_ADDRESSW] = state;
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R,
gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
gl_tex->sampler_desc.address_w = state;
}
if (sampler_states[WINED3D_SAMP_BORDER_COLOR] != gl_tex->states[WINED3DTEXSTA_BORDERCOLOR])
if (memcmp(gl_tex->sampler_desc.border_color, sampler_desc->border_color,
sizeof(gl_tex->sampler_desc.border_color)))
{
float col[4];
state = sampler_states[WINED3D_SAMP_BORDER_COLOR];
D3DCOLORTOGLFLOAT4(state, col);
TRACE("Setting border color for %#x to %#x.\n", target, state);
gl_info->gl_ops.gl.p_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, &col[0]);
checkGLcall("glTexParameterfv(..., GL_TEXTURE_BORDER_COLOR, ...)");
gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = state;
gl_info->gl_ops.gl.p_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, &sampler_desc->border_color[0]);
memcpy(gl_tex->sampler_desc.border_color, sampler_desc->border_color,
sizeof(gl_tex->sampler_desc.border_color));
}
if (sampler_states[WINED3D_SAMP_MAG_FILTER] != gl_tex->states[WINED3DTEXSTA_MAGFILTER])
state = sampler_desc->mag_filter;
if (state != gl_tex->sampler_desc.mag_filter)
{
GLint gl_value;
state = sampler_states[WINED3D_SAMP_MAG_FILTER];
if (state > WINED3D_TEXF_ANISOTROPIC)
FIXME("Unrecognized or unsupported MAGFILTER* value %d.\n", state);
gl_value = wined3d_gl_mag_filter(texture->mag_lookup,
min(max(state, WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR));
TRACE("ValueMAG=%#x setting MAGFILTER to %#x.\n", state, gl_value);
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, gl_value);
gl_tex->states[WINED3DTEXSTA_MAGFILTER] = state;
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(state));
gl_tex->sampler_desc.mag_filter = state;
}
if ((sampler_states[WINED3D_SAMP_MIN_FILTER] != gl_tex->states[WINED3DTEXSTA_MINFILTER]
|| sampler_states[WINED3D_SAMP_MIP_FILTER] != gl_tex->states[WINED3DTEXSTA_MIPFILTER]
|| sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL] != gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL]))
if (sampler_desc->min_filter != gl_tex->sampler_desc.min_filter
|| sampler_desc->mip_filter != gl_tex->sampler_desc.mip_filter)
{
GLint gl_value;
gl_tex->states[WINED3DTEXSTA_MIPFILTER] = sampler_states[WINED3D_SAMP_MIP_FILTER];
gl_tex->states[WINED3DTEXSTA_MINFILTER] = sampler_states[WINED3D_SAMP_MIN_FILTER];
gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL];
if (gl_tex->states[WINED3DTEXSTA_MINFILTER] > WINED3D_TEXF_ANISOTROPIC
|| gl_tex->states[WINED3DTEXSTA_MIPFILTER] > WINED3D_TEXF_ANISOTROPIC)
{
FIXME("Unrecognized or unsupported MIN_FILTER value %#x MIP_FILTER value %#x.\n",
gl_tex->states[WINED3DTEXSTA_MINFILTER],
gl_tex->states[WINED3DTEXSTA_MIPFILTER]);
}
gl_value = wined3d_gl_min_mip_filter(texture->min_mip_lookup,
min(max(sampler_states[WINED3D_SAMP_MIN_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR),
min(max(sampler_states[WINED3D_SAMP_MIP_FILTER], WINED3D_TEXF_NONE), WINED3D_TEXF_LINEAR));
TRACE("ValueMIN=%#x, ValueMIP=%#x, setting MINFILTER to %#x.\n",
sampler_states[WINED3D_SAMP_MIN_FILTER],
sampler_states[WINED3D_SAMP_MIP_FILTER], gl_value);
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, gl_value);
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
if (!cond_np2)
{
if (gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3D_TEXF_NONE)
gl_value = texture->lod;
else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= texture->level_count)
gl_value = texture->level_count - 1;
else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < texture->lod)
/* texture->lod is already clamped in the setter. */
gl_value = texture->lod;
else
gl_value = gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL];
/* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap
* (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest
* mimap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL
* corresponds to GL_TEXTURE_BASE_LEVEL. */
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, gl_value);
}
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
wined3d_gl_min_mip_filter(sampler_desc->min_filter, sampler_desc->mip_filter));
gl_tex->sampler_desc.min_filter = sampler_desc->min_filter;
gl_tex->sampler_desc.mip_filter = sampler_desc->mip_filter;
}
if ((gl_tex->states[WINED3DTEXSTA_MAGFILTER] != WINED3D_TEXF_ANISOTROPIC
&& gl_tex->states[WINED3DTEXSTA_MINFILTER] != WINED3D_TEXF_ANISOTROPIC
&& gl_tex->states[WINED3DTEXSTA_MIPFILTER] != WINED3D_TEXF_ANISOTROPIC)
|| cond_np2)
aniso = 1;
else
aniso = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY];
if (gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] != aniso)
state = sampler_desc->max_anisotropy;
if (state != gl_tex->sampler_desc.max_anisotropy)
{
if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
{
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
checkGLcall("glTexParameteri(GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso)");
}
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, state);
else
{
WARN("Anisotropic filtering not supported.\n");
}
gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = aniso;
gl_tex->sampler_desc.max_anisotropy = state;
}
/* These should always be the same unless EXT_texture_sRGB_decode is supported. */
if (sampler_states[WINED3D_SAMP_SRGB_TEXTURE] != gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE])
if (!sampler_desc->srgb_decode != !gl_tex->sampler_desc.srgb_decode)
{
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
sampler_states[WINED3D_SAMP_SRGB_TEXTURE] ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT);
checkGLcall("glTexParameteri(GL_TEXTURE_SRGB_DECODE_EXT)");
gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = sampler_states[WINED3D_SAMP_SRGB_TEXTURE];
sampler_desc->srgb_decode ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT);
gl_tex->sampler_desc.srgb_decode = sampler_desc->srgb_decode;
}
if (!(texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
!= !gl_tex->states[WINED3DTEXSTA_SHADOW])
if (!sampler_desc->compare != !gl_tex->sampler_desc.compare)
{
if (texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
if (sampler_desc->compare)
{
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
checkGLcall("glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB)");
gl_tex->states[WINED3DTEXSTA_SHADOW] = TRUE;
}
else
{
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
checkGLcall("glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE)");
gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
}
gl_tex->sampler_desc.compare = sampler_desc->compare;
}
checkGLcall("Texture parameter application");
if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
{
gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
GL_TEXTURE_LOD_BIAS_EXT, sampler_desc->lod_bias);
checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
}
}
@ -542,6 +454,22 @@ void wined3d_texture_load(struct wined3d_texture *texture,
else
flag = WINED3D_TEXTURE_RGB_VALID;
if (!(texture->flags & WINED3D_TEXTURE_COLOR_KEY) != !(texture->color_key_flags & WINED3D_CKEY_SRC_BLT)
|| (texture->flags & WINED3D_TEXTURE_COLOR_KEY
&& (texture->gl_color_key.color_space_low_value != texture->src_blt_color_key.color_space_low_value
|| texture->gl_color_key.color_space_high_value != texture->src_blt_color_key.color_space_high_value)))
{
unsigned int sub_count = texture->level_count * texture->layer_count;
unsigned int i;
TRACE("Reloading because of color key value change.\n");
for (i = 0; i < sub_count; i++)
texture->texture_ops->texture_sub_resource_add_dirty_region(texture->sub_resources[i], NULL);
wined3d_texture_set_dirty(texture);
texture->gl_color_key = texture->src_blt_color_key;
}
if (texture->flags & flag)
{
TRACE("Texture %p not dirty, nothing to do.\n", texture);
@ -592,8 +520,8 @@ DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod)
{
texture->lod = lod;
texture->texture_rgb.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
texture->texture_srgb.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
texture->texture_rgb.base_level = ~0u;
texture->texture_srgb.base_level = ~0u;
if (texture->resource.bind_count)
device_invalidate_state(texture->resource.device, STATE_SAMPLER(texture->sampler));
}
@ -643,7 +571,7 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
{
TRACE("texture %p, flags %#x, color_key %p.\n", texture, flags, color_key);
if (flags & WINEDDCKEY_COLORSPACE)
if (flags & WINED3D_CKEY_COLORSPACE)
{
FIXME("Unhandled flags %#x.\n", flags);
return WINED3DERR_INVALIDCALL;
@ -651,47 +579,47 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
if (color_key)
{
switch (flags & ~WINEDDCKEY_COLORSPACE)
switch (flags & ~WINED3D_CKEY_COLORSPACE)
{
case WINEDDCKEY_DESTBLT:
case WINED3D_CKEY_DST_BLT:
texture->dst_blt_color_key = *color_key;
texture->color_key_flags |= WINEDDSD_CKDESTBLT;
texture->color_key_flags |= WINED3D_CKEY_DST_BLT;
break;
case WINEDDCKEY_DESTOVERLAY:
case WINED3D_CKEY_DST_OVERLAY:
texture->dst_overlay_color_key = *color_key;
texture->color_key_flags |= WINEDDSD_CKDESTOVERLAY;
texture->color_key_flags |= WINED3D_CKEY_DST_OVERLAY;
break;
case WINEDDCKEY_SRCOVERLAY:
texture->src_overlay_color_key = *color_key;
texture->color_key_flags |= WINEDDSD_CKSRCOVERLAY;
break;
case WINEDDCKEY_SRCBLT:
case WINED3D_CKEY_SRC_BLT:
texture->src_blt_color_key = *color_key;
texture->color_key_flags |= WINEDDSD_CKSRCBLT;
texture->color_key_flags |= WINED3D_CKEY_SRC_BLT;
break;
case WINED3D_CKEY_SRC_OVERLAY:
texture->src_overlay_color_key = *color_key;
texture->color_key_flags |= WINED3D_CKEY_SRC_OVERLAY;
break;
}
}
else
{
switch (flags & ~WINEDDCKEY_COLORSPACE)
switch (flags & ~WINED3D_CKEY_COLORSPACE)
{
case WINEDDCKEY_DESTBLT:
texture->color_key_flags &= ~WINEDDSD_CKDESTBLT;
case WINED3D_CKEY_DST_BLT:
texture->color_key_flags &= ~WINED3D_CKEY_DST_BLT;
break;
case WINEDDCKEY_DESTOVERLAY:
texture->color_key_flags &= ~WINEDDSD_CKDESTOVERLAY;
case WINED3D_CKEY_DST_OVERLAY:
texture->color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY;
break;
case WINEDDCKEY_SRCOVERLAY:
texture->color_key_flags &= ~WINEDDSD_CKSRCOVERLAY;
case WINED3D_CKEY_SRC_BLT:
texture->color_key_flags &= ~WINED3D_CKEY_SRC_BLT;
break;
case WINEDDCKEY_SRCBLT:
texture->color_key_flags &= ~WINEDDSD_CKSRCBLT;
case WINED3D_CKEY_SRC_OVERLAY:
texture->color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY;
break;
}
}
@ -699,6 +627,98 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
return WINED3D_OK;
}
HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height,
enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type,
UINT multisample_quality, void *mem, UINT pitch)
{
struct wined3d_device *device = texture->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
struct wined3d_surface *surface;
TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, "
"mem %p, pitch %u.\n",
texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_type, mem, pitch);
if (!resource_size)
return WINED3DERR_INVALIDCALL;
if (texture->level_count * texture->layer_count > 1)
{
WARN("Texture has multiple sub-resources, not supported.\n");
return WINED3DERR_INVALIDCALL;
}
if (texture->resource.type == WINED3D_RTYPE_VOLUME_TEXTURE)
{
WARN("Not supported on volume textures.\n");
return WINED3DERR_INVALIDCALL;
}
/* We have no way of supporting a pitch that is not a multiple of the pixel
* byte width short of uploading the texture row-by-row.
* Fortunately that's not an issue since D3D9Ex doesn't allow a custom pitch
* for user-memory textures (it always expects packed data) while DirectDraw
* requires a 4-byte aligned pitch and doesn't support texture formats
* larger than 4 bytes per pixel nor any format using 3 bytes per pixel.
* This check is here to verify that the assumption holds. */
if (pitch % texture->resource.format->byte_count)
{
WARN("Pitch unsupported, not a multiple of the texture format byte width.\n");
return WINED3DERR_INVALIDCALL;
}
surface = surface_from_resource(texture->sub_resources[0]);
if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE))
{
WARN("Surface is mapped or the DC is in use.\n");
return WINED3DERR_INVALIDCALL;
}
if (device->d3d_initialized)
texture->resource.resource_ops->resource_unload(&texture->resource);
texture->resource.format = format;
texture->resource.multisample_type = multisample_type;
texture->resource.multisample_quality = multisample_quality;
texture->resource.width = width;
texture->resource.height = height;
return wined3d_surface_update_desc(surface, gl_info, mem, pitch);
}
void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
{
DWORD alloc_flag = srgb ? WINED3D_TEXTURE_SRGB_ALLOCATED : WINED3D_TEXTURE_RGB_ALLOCATED;
if (!(texture->flags & WINED3D_TEXTURE_COLOR_KEY) != !(texture->color_key_flags & WINED3D_CKEY_SRC_BLT))
wined3d_texture_force_reload(texture);
if (texture->flags & alloc_flag)
return;
if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT)
texture->flags |= WINED3D_TEXTURE_COLOR_KEY;
texture->texture_ops->texture_prepare_texture(texture, context, srgb);
texture->flags |= alloc_flag;
}
void wined3d_texture_force_reload(struct wined3d_texture *texture)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
unsigned int i;
texture->flags &= ~(WINED3D_TEXTURE_RGB_ALLOCATED | WINED3D_TEXTURE_SRGB_ALLOCATED
| WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_COLOR_KEY);
for (i = 0; i < sub_count; ++i)
{
texture->texture_ops->texture_sub_resource_invalidate_location(texture->sub_resources[i],
WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB);
}
}
void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture)
{
/* TODO: Implement filters using GL_SGI_generate_mipmaps. */
@ -739,6 +759,29 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
return WINED3D_OK;
}
static void wined3d_texture_upload_data(struct wined3d_texture *texture, const struct wined3d_sub_resource_data *data)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
struct wined3d_context *context;
unsigned int i;
context = context_acquire(texture->resource.device, NULL);
wined3d_texture_prepare_texture(texture, context, FALSE);
wined3d_texture_bind(texture, context, FALSE);
for (i = 0; i < sub_count; ++i)
{
struct wined3d_resource *sub_resource = texture->sub_resources[i];
texture->texture_ops->texture_sub_resource_upload_data(sub_resource, context, &data[i]);
texture->texture_ops->texture_sub_resource_validate_location(sub_resource, WINED3D_LOCATION_TEXTURE_RGB);
texture->texture_ops->texture_sub_resource_invalidate_location(sub_resource, ~WINED3D_LOCATION_TEXTURE_RGB);
}
context_release(context);
}
static void texture2d_sub_resource_load(struct wined3d_resource *sub_resource,
struct wined3d_context *context, BOOL srgb)
{
@ -762,11 +805,148 @@ static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource
wined3d_surface_destroy(surface);
}
static void texture2d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location)
{
struct wined3d_surface *surface = surface_from_resource(sub_resource);
surface_invalidate_location(surface, location);
}
static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location)
{
struct wined3d_surface *surface = surface_from_resource(sub_resource);
surface_validate_location(surface, location);
}
static void texture2d_sub_resource_upload_data(struct wined3d_resource *sub_resource,
const struct wined3d_context *context, const struct wined3d_sub_resource_data *data)
{
struct wined3d_surface *surface = surface_from_resource(sub_resource);
static const POINT dst_point = {0, 0};
struct wined3d_const_bo_address addr;
RECT src_rect;
src_rect.left = 0;
src_rect.top = 0;
src_rect.right = surface->resource.width;
src_rect.bottom = surface->resource.height;
addr.buffer_object = 0;
addr.addr = data->data;
wined3d_surface_upload_data(surface, context->gl_info, surface->container->resource.format,
&src_rect, data->row_pitch, &dst_point, FALSE, &addr);
}
/* Context activation is done by the caller. */
static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
{
UINT sub_count = texture->level_count * texture->layer_count;
const struct wined3d_format *format = texture->resource.format;
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_color_key_conversion *conversion;
GLenum internal;
UINT i;
TRACE("texture %p, format %s.\n", texture, debug_d3dformat(format->id));
if (format->convert)
{
texture->flags |= WINED3D_TEXTURE_CONVERTED;
}
else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
{
texture->flags |= WINED3D_TEXTURE_CONVERTED;
format = wined3d_get_format(gl_info, conversion->dst_format);
TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id));
}
wined3d_texture_bind_and_dirtify(texture, context, srgb);
if (srgb)
internal = format->glGammaInternal;
else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
&& wined3d_resource_is_offscreen(&texture->resource))
internal = format->rtInternal;
else
internal = format->glInternal;
if (!internal)
FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType);
for (i = 0; i < sub_count; ++i)
{
struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]);
GLsizei height = surface->pow2Height;
GLsizei width = surface->pow2Width;
const BYTE *mem = NULL;
if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
{
height *= format->height_scale.numerator;
height /= format->height_scale.denominator;
}
TRACE("surface %p, target %#x, level %d, width %d, height %d.\n",
surface, surface->texture_target, surface->texture_level, width, height);
if (gl_info->supported[APPLE_CLIENT_STORAGE])
{
if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION)
|| texture->flags & WINED3D_TEXTURE_CONVERTED
|| !surface->resource.heap_memory)
{
/* In some cases we want to disable client storage.
* SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches
* SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues...
* WINED3D_TEXTURE_CONVERTED: The conversion destination memory is freed after loading the surface
* heap_memory == NULL: Not defined in the extension. Seems to disable client storage effectively
*/
surface->flags &= ~SFLAG_CLIENT;
}
else
{
surface->flags |= SFLAG_CLIENT;
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)");
}
}
if (format->flags & WINED3DFMT_FLAG_COMPRESSED && mem)
{
GL_EXTCALL(glCompressedTexImage2D(surface->texture_target, surface->texture_level,
internal, width, height, 0, surface->resource.size, mem));
checkGLcall("glCompressedTexImage2D");
}
else
{
gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
internal, width, height, 0, format->glFormat, format->glType, mem);
checkGLcall("glTexImage2D");
}
if (mem)
{
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
}
}
}
static const struct wined3d_texture_ops texture2d_ops =
{
texture2d_sub_resource_load,
texture2d_sub_resource_add_dirty_region,
texture2d_sub_resource_cleanup,
texture2d_sub_resource_invalidate_location,
texture2d_sub_resource_validate_location,
texture2d_sub_resource_upload_data,
texture2d_prepare_texture,
};
static ULONG texture_resource_incref(struct wined3d_resource *resource)
@ -794,6 +974,7 @@ static void wined3d_texture_unload(struct wined3d_resource *resource)
sub_resource->resource_ops->resource_unload(sub_resource);
}
wined3d_texture_force_reload(texture);
wined3d_texture_unload_gl_texture(texture);
}
@ -836,18 +1017,11 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi
return WINED3DERR_INVALIDCALL;
}
if (levels > 1)
if (levels != 1)
{
WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n");
WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n");
return WINED3DERR_INVALIDCALL;
}
levels = 1;
}
else if (!levels)
{
levels = wined3d_log2i(desc->width) + 1;
TRACE("Calculated levels = %u.\n", levels);
}
if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
@ -871,8 +1045,8 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi
}
}
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels,
desc, device, parent, parent_ops, &texture_resource_ops)))
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels, desc,
surface_flags, device, parent, parent_ops, &texture_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x\n", hr);
return hr;
@ -982,22 +1156,15 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
return WINED3DERR_INVALIDCALL;
}
if (levels > 1)
if (levels != 1)
{
WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning WINED3DERR_INVALIDCALL.\n");
WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n");
return WINED3DERR_INVALIDCALL;
}
levels = 1;
}
else if (!levels)
{
levels = wined3d_log2i(max(desc->width, desc->height)) + 1;
TRACE("Calculated levels = %u.\n", levels);
}
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels,
desc, device, parent, parent_ops, &texture_resource_ops)))
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels, desc,
surface_flags, device, parent, parent_ops, &texture_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
return hr;
@ -1013,7 +1180,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
texture->pow2_matrix[15] = 1.0f;
texture->target = GL_TEXTURE_2D;
texture->flags |= WINED3D_TEXTURE_COND_NP2;
texture->min_mip_lookup = minMipLookup_noFilter;
}
else if (gl_info->supported[ARB_TEXTURE_RECTANGLE]
&& (desc->width != pow2_width || desc->height != pow2_height))
@ -1024,12 +1190,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
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
texture->min_mip_lookup = minMipLookup_noFilter;
texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS);
}
else
{
@ -1095,11 +1256,84 @@ static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource
wined3d_volume_destroy(volume);
}
static void texture3d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location)
{
struct wined3d_volume *volume = volume_from_resource(sub_resource);
wined3d_volume_invalidate_location(volume, location);
}
static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location)
{
struct wined3d_volume *volume = volume_from_resource(sub_resource);
wined3d_volume_validate_location(volume, location);
}
static void texture3d_sub_resource_upload_data(struct wined3d_resource *sub_resource,
const struct wined3d_context *context, const struct wined3d_sub_resource_data *data)
{
struct wined3d_volume *volume = volume_from_resource(sub_resource);
struct wined3d_const_bo_address addr;
unsigned int row_pitch, slice_pitch;
wined3d_volume_get_pitch(volume, &row_pitch, &slice_pitch);
if (row_pitch != data->row_pitch || slice_pitch != data->slice_pitch)
FIXME("Ignoring row/slice pitch (%u/%u).\n", data->row_pitch, data->slice_pitch);
addr.buffer_object = 0;
addr.addr = data->data;
wined3d_volume_upload_data(volume, context, &addr);
}
static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
const struct wined3d_format *format = texture->resource.format;
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int i;
wined3d_texture_bind_and_dirtify(texture, context, srgb);
for (i = 0; i < sub_count; ++i)
{
struct wined3d_volume *volume = volume_from_resource(texture->sub_resources[i]);
void *mem = NULL;
if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert
&& volume_prepare_system_memory(volume))
{
TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume);
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
mem = volume->resource.heap_memory;
volume->flags |= WINED3D_VFLAG_CLIENT_STORAGE;
}
GL_EXTCALL(glTexImage3D(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, mem));
checkGLcall("glTexImage3D");
if (mem)
{
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
}
}
}
static const struct wined3d_texture_ops texture3d_ops =
{
texture3d_sub_resource_load,
texture3d_sub_resource_add_dirty_region,
texture3d_sub_resource_cleanup,
texture3d_sub_resource_invalidate_location,
texture3d_sub_resource_validate_location,
texture3d_sub_resource_upload_data,
texture3d_prepare_texture,
};
static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
@ -1133,18 +1367,11 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
return WINED3DERR_INVALIDCALL;
}
if (levels > 1)
if (levels != 1)
{
WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n");
WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n");
return WINED3DERR_INVALIDCALL;
}
levels = 1;
}
else if (!levels)
{
levels = wined3d_log2i(max(max(desc->width, desc->height), desc->depth)) + 1;
TRACE("Calculated levels = %u.\n", levels);
}
if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
@ -1175,8 +1402,8 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
}
}
if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels,
desc, device, parent, parent_ops, &texture_resource_ops)))
if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels, desc,
0, device, parent, parent_ops, &texture_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
return hr;
@ -1214,14 +1441,20 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
}
HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_texture **texture)
UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
{
struct wined3d_texture *object;
HRESULT hr;
TRACE("device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.\n",
device, desc, level_count, surface_flags, parent, parent_ops, texture);
TRACE("device %p, desc %p, level_count %u, surface_flags %#x, data %p, parent %p, parent_ops %p, texture %p.\n",
device, desc, level_count, surface_flags, data, parent, parent_ops, texture);
if (!level_count)
{
WARN("Invalid level count.\n");
return WINED3DERR_INVALIDCALL;
}
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
@ -1253,6 +1486,11 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
return hr;
}
/* FIXME: We'd like to avoid ever allocating system memory for the texture
* in this case. */
if (data)
wined3d_texture_upload_data(object, data);
TRACE("Created texture %p.\n", object);
*texture = object;

View file

@ -128,6 +128,7 @@ static const struct wined3d_format_channels formats[] =
{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_ATI1N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{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},
@ -174,6 +175,7 @@ static const struct wined3d_format_base_flags format_base_flags[] =
{WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_ATI1N, WINED3DFMT_FLAG_BROKEN_PITCH},
{WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH},
{WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
{WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
@ -202,6 +204,7 @@ static const struct wined3d_format_block_info format_block_info[] =
{WINED3DFMT_DXT3, 4, 4, 16, TRUE},
{WINED3DFMT_DXT4, 4, 4, 16, TRUE},
{WINED3DFMT_DXT5, 4, 4, 16, TRUE},
{WINED3DFMT_ATI1N, 4, 4, 8, FALSE},
{WINED3DFMT_ATI2N, 4, 4, 16, FALSE},
{WINED3DFMT_YUY2, 2, 1, 4, FALSE},
{WINED3DFMT_UYVY, 2, 1, 4, FALSE},
@ -611,6 +614,207 @@ static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_p
}
}
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
* makes more sense to compare the individual channels. */
return color >= color_key->color_space_low_value
&& color <= color_key->color_space_high_value;
}
static void convert_p8_uint_b8g8r8a8_unorm(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const BYTE *src_row;
unsigned int x, y;
DWORD *dst_row;
if (!palette)
{
/* FIXME: This should probably use the system palette. */
FIXME("P8 surface loaded without a palette.\n");
for (y = 0; y < height; ++y)
{
memset(&dst[dst_pitch * y], 0, width * 4);
}
return;
}
for (y = 0; y < height; ++y)
{
src_row = &src[src_pitch * y];
dst_row = (DWORD *)&dst[dst_pitch * y];
for (x = 0; x < width; ++x)
{
BYTE src_color = src_row[x];
dst_row[x] = 0xff000000
| (palette->colors[src_color].rgbRed << 16)
| (palette->colors[src_color].rgbGreen << 8)
| palette->colors[src_color].rgbBlue;
}
}
}
static void convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const WORD *src_row;
unsigned int x, y;
WORD *dst_row;
for (y = 0; y < height; ++y)
{
src_row = (WORD *)&src[src_pitch * y];
dst_row = (WORD *)&dst[dst_pitch * y];
for (x = 0; x < width; ++x)
{
WORD src_color = src_row[x];
if (!color_in_range(color_key, src_color))
dst_row[x] = 0x8000 | ((src_color & 0xffc0) >> 1) | (src_color & 0x1f);
else
dst_row[x] = ((src_color & 0xffc0) >> 1) | (src_color & 0x1f);
}
}
}
static void convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const WORD *src_row;
unsigned int x, y;
WORD *dst_row;
for (y = 0; y < height; ++y)
{
src_row = (WORD *)&src[src_pitch * y];
dst_row = (WORD *)&dst[dst_pitch * y];
for (x = 0; x < width; ++x)
{
WORD src_color = src_row[x];
if (color_in_range(color_key, src_color))
dst_row[x] = src_color & ~0x8000;
else
dst_row[x] = src_color | 0x8000;
}
}
}
static void convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const BYTE *src_row;
unsigned int x, y;
DWORD *dst_row;
for (y = 0; y < height; ++y)
{
src_row = &src[src_pitch * y];
dst_row = (DWORD *)&dst[dst_pitch * y];
for (x = 0; x < width; ++x)
{
DWORD src_color = (src_row[x * 3 + 2] << 16) | (src_row[x * 3 + 1] << 8) | src_row[x * 3];
if (!color_in_range(color_key, src_color))
dst_row[x] = src_color | 0xff000000;
}
}
}
static void convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const DWORD *src_row;
unsigned int x, y;
DWORD *dst_row;
for (y = 0; y < height; ++y)
{
src_row = (DWORD *)&src[src_pitch * y];
dst_row = (DWORD *)&dst[dst_pitch * y];
for (x = 0; x < width; ++x)
{
DWORD src_color = src_row[x];
if (color_in_range(color_key, src_color))
dst_row[x] = src_color & ~0xff000000;
else
dst_row[x] = src_color | 0xff000000;
}
}
}
static void convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const DWORD *src_row;
unsigned int x, y;
DWORD *dst_row;
for (y = 0; y < height; ++y)
{
src_row = (DWORD *)&src[src_pitch * y];
dst_row = (DWORD *)&dst[dst_pitch * y];
for (x = 0; x < width; ++x)
{
DWORD src_color = src_row[x];
if (color_in_range(color_key, src_color))
src_color &= ~0xff000000;
dst_row[x] = src_color;
}
}
}
const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(
const struct wined3d_texture *texture, BOOL need_alpha_ck)
{
const struct wined3d_format *format = texture->resource.format;
unsigned int i;
static const struct
{
enum wined3d_format_id src_format;
struct wined3d_color_key_conversion conversion;
}
color_key_info[] =
{
{WINED3DFMT_B5G6R5_UNORM, {WINED3DFMT_B5G5R5A1_UNORM, convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key }},
{WINED3DFMT_B5G5R5X1_UNORM, {WINED3DFMT_B5G5R5A1_UNORM, convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key }},
{WINED3DFMT_B8G8R8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key }},
{WINED3DFMT_B8G8R8X8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key }},
{WINED3DFMT_B8G8R8A8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key }},
};
static const struct wined3d_color_key_conversion convert_p8 =
{
WINED3DFMT_B8G8R8A8_UNORM, convert_p8_uint_b8g8r8a8_unorm
};
if (need_alpha_ck && (texture->flags & WINED3D_TEXTURE_COLOR_KEY))
{
for (i = 0; i < sizeof(color_key_info) / sizeof(*color_key_info); ++i)
{
if (color_key_info[i].src_format == format->id)
return &color_key_info[i].conversion;
}
FIXME("Color-keying not supported with format %s.\n", debug_d3dformat(format->id));
}
/* FIXME: This should check if the blitter backend can do P8 conversion,
* instead of checking for ARB_fragment_program. */
if (format->id == WINED3DFMT_P8_UINT
&& !(texture->resource.device->adapter->gl_info.supported[ARB_FRAGMENT_PROGRAM]
&& texture->swapchain && texture == texture->swapchain->front_buffer))
return &convert_p8;
return NULL;
}
/* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
*
* These are never supported on native.
@ -982,6 +1186,11 @@ static const struct wined3d_format_texture_info format_texture_info[] =
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
/* Vendor-specific formats */
{WINED3DFMT_ATI1N, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0,
GL_RED, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_COMPRESSED,
ARB_TEXTURE_COMPRESSION_RGTC, NULL},
{WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
@ -1816,8 +2025,12 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
*/
}
if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC])
{
idx = getFmtIdx(WINED3DFMT_ATI1N);
gl_info->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X);
idx = getFmtIdx(WINED3DFMT_ATI2N);
gl_info->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
@ -2114,6 +2327,7 @@ const char *debug_d3dformat(enum wined3d_format_id format_id)
FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
FMT_TO_STR(WINED3DFMT_VERTEXDATA);
FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
FMT_TO_STR(WINED3DFMT_ATI1N);
FMT_TO_STR(WINED3DFMT_ATI2N);
FMT_TO_STR(WINED3DFMT_NVDB);
FMT_TO_STR(WINED3DFMT_NVHU);
@ -2686,6 +2900,8 @@ const char *debug_d3dstate(DWORD state)
return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(state - STATE_SHADER(0)));
if (STATE_IS_CONSTANT_BUFFER(state))
return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(state - STATE_CONSTANT_BUFFER(0)));
if (STATE_IS_SHADER_RESOURCE_BINDING(state))
return "STATE_SHADER_RESOURCE_BINDING";
if (STATE_IS_TRANSFORM(state))
return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
if (STATE_IS_STREAMSRC(state))
@ -3310,7 +3526,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
{
if (texture->color_key_flags & WINEDDSD_CKSRCBLT && !texture->resource.format->alpha_size)
if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size)
{
if (aop == WINED3D_TOP_DISABLE)
{
@ -3714,32 +3930,6 @@ const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions =
wined3d_ffp_vertex_program_key_compare,
};
UINT wined3d_log2i(UINT32 x)
{
static const UINT l[] =
{
~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
};
UINT32 i;
return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
}
const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
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)

View file

@ -214,6 +214,19 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara
return E_FAIL;
}
if (e->offset == WINED3D_APPEND_ALIGNED_ELEMENT)
{
if (!i)
{
e->offset = 0;
}
else
{
struct wined3d_vertex_declaration_element *prev = &declaration->elements[i - 1];
e->offset = (prev->offset + prev->format->byte_count + 3) & ~3;
}
}
if (e->offset & 0x3)
{
WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);

View file

@ -173,7 +173,10 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v
if (!refcount)
{
/* Call wined3d_object_destroyed() before releasing the resource,
* since releasing the resource may end up destroying the parent. */
view->parent_ops->wined3d_object_destroyed(view->parent);
wined3d_resource_decref(view->resource);
HeapFree(GetProcessHeap(), 0, view);
}
@ -187,8 +190,8 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader
return view->parent;
}
HRESULT CDECL wined3d_shader_resource_view_create(void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_shader_resource_view **view)
HRESULT CDECL wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view)
{
struct wined3d_shader_resource_view *object;
@ -198,6 +201,8 @@ HRESULT CDECL wined3d_shader_resource_view_create(void *parent, const struct win
return E_OUTOFMEMORY;
object->refcount = 1;
object->resource = resource;
wined3d_resource_incref(resource);
object->parent = parent;
object->parent_ops = parent_ops;

View file

@ -25,11 +25,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
#define WINED3D_VFLAG_ALLOCATED 0x00000001
#define WINED3D_VFLAG_SRGB_ALLOCATED 0x00000002
#define WINED3D_VFLAG_CLIENT_STORAGE 0x00000004
static BOOL volume_prepare_system_memory(struct wined3d_volume *volume)
BOOL volume_prepare_system_memory(struct wined3d_volume *volume)
{
if (volume->resource.heap_memory)
return TRUE;
@ -42,39 +38,7 @@ static BOOL volume_prepare_system_memory(struct wined3d_volume *volume)
return TRUE;
}
/* Context activation is done by the caller. */
static void wined3d_volume_allocate_texture(struct wined3d_volume *volume,
const struct wined3d_context *context, BOOL srgb)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_format *format = volume->resource.format;
void *mem = NULL;
if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert
&& volume_prepare_system_memory(volume))
{
TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume);
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
mem = volume->resource.heap_memory;
volume->flags |= WINED3D_VFLAG_CLIENT_STORAGE;
}
GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, volume->texture_level,
srgb ? format->glGammaInternal : format->glInternal,
volume->resource.width, volume->resource.height, volume->resource.depth,
0, format->glFormat, format->glType, mem));
checkGLcall("glTexImage3D");
if (mem)
{
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
}
}
static void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch,
UINT *slice_pitch)
void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch)
{
const struct wined3d_format *format = volume->resource.format;
@ -100,14 +64,15 @@ static void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *
/* 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)
const struct wined3d_const_bo_address *data)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_format *format = volume->resource.format;
UINT width = volume->resource.width;
UINT height = volume->resource.height;
UINT depth = volume->resource.depth;
BYTE *mem = data->addr;
const void *mem = data->addr;
void *converted_mem = NULL;
TRACE("volume %p, context %p, level %u, format %s (%#x).\n",
volume, context, volume->texture_level, debug_d3dformat(format->id),
@ -117,7 +82,6 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
{
UINT dst_row_pitch, dst_slice_pitch;
UINT src_row_pitch, src_slice_pitch;
UINT alignment = volume->resource.device->surface_alignment;
if (data->buffer_object)
ERR("Loading a converted volume from a PBO.\n");
@ -125,38 +89,37 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
ERR("Converting a block-based format.\n");
dst_row_pitch = width * format->conv_byte_count;
dst_row_pitch = (dst_row_pitch + alignment - 1) & ~(alignment - 1);
dst_slice_pitch = dst_row_pitch * height;
wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch);
mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth);
format->convert(data->addr, mem, src_row_pitch, src_slice_pitch,
converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth);
format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch,
dst_row_pitch, dst_slice_pitch, width, height, depth);
mem = converted_mem;
}
if (data->buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, data->buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
checkGLcall("glBindBuffer");
}
GL_EXTCALL(glTexSubImage3DEXT(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0,
GL_EXTCALL(glTexSubImage3D(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0,
width, height, depth,
format->glFormat, format->glType, mem));
checkGLcall("glTexSubImage3D");
if (data->buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
checkGLcall("glBindBuffer");
}
if (mem != data->addr)
HeapFree(GetProcessHeap(), 0, mem);
HeapFree(GetProcessHeap(), 0, converted_mem);
}
static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location)
void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location)
{
TRACE("Volume %p, setting %s.\n", volume, wined3d_debug_location(location));
volume->locations |= location;
@ -186,8 +149,8 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume,
if (data->buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data->buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
checkGLcall("glBindBuffer");
}
gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, volume->texture_level,
@ -196,8 +159,8 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume,
if (data->buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
checkGLcall("glBindBuffer");
}
}
@ -250,7 +213,7 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
wined3d_texture_bind_and_dirtify(volume->container, context, !dest_is_srgb);
wined3d_volume_download_data(volume, context, &data);
wined3d_texture_bind_and_dirtify(volume->container, context, dest_is_srgb);
wined3d_volume_upload_data(volume, context, &data);
wined3d_volume_upload_data(volume, context, wined3d_const_bo_address(&data));
HeapFree(GetProcessHeap(), 0, data.addr);
}
@ -295,9 +258,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
case WINED3D_LOCATION_TEXTURE_RGB:
case WINED3D_LOCATION_TEXTURE_SRGB:
if ((location == WINED3D_LOCATION_TEXTURE_RGB
&& !(volume->flags & WINED3D_VFLAG_ALLOCATED))
&& !(volume->container->flags & WINED3D_TEXTURE_RGB_ALLOCATED))
|| (location == WINED3D_LOCATION_TEXTURE_SRGB
&& !(volume->flags & WINED3D_VFLAG_SRGB_ALLOCATED)))
&& !(volume->container->flags & WINED3D_TEXTURE_SRGB_ALLOCATED)))
ERR("Trying to load (s)RGB texture without prior allocation.\n");
if (volume->locations & WINED3D_LOCATION_DISCARDED)
@ -307,12 +270,12 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
}
else if (volume->locations & WINED3D_LOCATION_SYSMEM)
{
struct wined3d_bo_address data = {0, volume->resource.heap_memory};
struct wined3d_const_bo_address data = {0, volume->resource.heap_memory};
wined3d_volume_upload_data(volume, context, &data);
}
else if (volume->locations & WINED3D_LOCATION_BUFFER)
{
struct wined3d_bo_address data = {volume->pbo, NULL};
struct wined3d_const_bo_address data = {volume->pbo, NULL};
wined3d_volume_upload_data(volume, context, &data);
}
else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
@ -403,28 +366,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
/* Context activation is done by the caller. */
void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode)
{
wined3d_texture_bind_and_dirtify(volume->container, 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);
}
wined3d_texture_prepare_texture(volume->container, context, srgb_mode);
wined3d_volume_load_location(volume, context,
srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB);
}
/* Context activation is done by the caller. */
@ -435,10 +379,10 @@ static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct win
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));
GL_EXTCALL(glGenBuffers(1, &volume->pbo));
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, volume->resource.size, NULL, GL_STREAM_DRAW));
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
checkGLcall("Create PBO");
TRACE("Created PBO %u for volume %p.\n", volume->pbo, volume);
@ -450,8 +394,8 @@ static void wined3d_volume_free_pbo(struct wined3d_volume *volume)
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");
GL_EXTCALL(glDeleteBuffers(1, &volume->pbo));
checkGLcall("glDeleteBuffers");
volume->pbo = 0;
context_release(context);
}
@ -503,8 +447,7 @@ static void volume_unload(struct wined3d_resource *resource)
}
/* The texture name is managed by the container. */
volume->flags &= ~(WINED3D_VFLAG_ALLOCATED | WINED3D_VFLAG_SRGB_ALLOCATED
| WINED3D_VFLAG_CLIENT_STORAGE);
volume->flags &= ~WINED3D_VFLAG_CLIENT_STORAGE;
resource_unload(resource);
}
@ -640,22 +583,22 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
else
wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 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,
base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,
0, volume->resource.size, mapflags));
}
else
{
GLenum access = wined3d_resource_gl_legacy_map_flags(flags);
base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, access));
base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access));
}
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
checkGLcall("Map PBO");
context_release(context);
@ -757,9 +700,9 @@ HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume)
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));
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
checkGLcall("Unmap PBO");
context_release(context);

View file

@ -194,21 +194,21 @@
@ cdecl wined3d_rendertarget_view_incref(ptr)
@ cdecl wined3d_rendertarget_view_set_parent(ptr ptr)
@ cdecl wined3d_sampler_create(ptr ptr)
@ cdecl wined3d_sampler_create(ptr ptr ptr ptr)
@ cdecl wined3d_sampler_decref(ptr)
@ cdecl wined3d_sampler_get_parent(ptr)
@ cdecl wined3d_sampler_incref(ptr)
@ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr ptr long)
@ cdecl wined3d_shader_create_ps(ptr ptr ptr ptr ptr ptr long)
@ cdecl wined3d_shader_create_vs(ptr ptr ptr ptr ptr ptr long)
@ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr)
@ cdecl wined3d_shader_create_ps(ptr ptr ptr ptr ptr)
@ cdecl wined3d_shader_create_vs(ptr ptr ptr ptr ptr)
@ cdecl wined3d_shader_decref(ptr)
@ cdecl wined3d_shader_get_byte_code(ptr ptr ptr)
@ cdecl wined3d_shader_get_parent(ptr)
@ cdecl wined3d_shader_incref(ptr)
@ cdecl wined3d_shader_set_local_constants_float(ptr long ptr long)
@ cdecl wined3d_shader_resource_view_create(ptr ptr ptr)
@ cdecl wined3d_shader_resource_view_create(ptr ptr ptr ptr)
@ cdecl wined3d_shader_resource_view_decref(ptr)
@ cdecl wined3d_shader_resource_view_get_parent(ptr)
@ cdecl wined3d_shader_resource_view_incref(ptr)
@ -219,6 +219,8 @@
@ cdecl wined3d_stateblock_decref(ptr)
@ cdecl wined3d_stateblock_incref(ptr)
@ cdecl wined3d_strictdrawing_set(long)
@ cdecl wined3d_surface_blt(ptr ptr ptr ptr long ptr long)
@ cdecl wined3d_surface_decref(ptr)
@ cdecl wined3d_surface_from_resource(ptr)
@ -238,7 +240,6 @@
@ cdecl wined3d_surface_restore(ptr)
@ cdecl wined3d_surface_set_overlay_position(ptr long long)
@ cdecl wined3d_surface_unmap(ptr)
@ cdecl wined3d_surface_update_desc(ptr long long long long long ptr long)
@ cdecl wined3d_surface_update_overlay(ptr ptr ptr ptr long ptr)
@ cdecl wined3d_surface_update_overlay_z_order(ptr long ptr)
@ -259,7 +260,7 @@
@ cdecl wined3d_swapchain_set_window(ptr ptr)
@ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
@ cdecl wined3d_texture_create(ptr ptr long long ptr ptr ptr)
@ cdecl wined3d_texture_create(ptr ptr long long ptr ptr ptr ptr)
@ cdecl wined3d_texture_decref(ptr)
@ cdecl wined3d_texture_generate_mipmaps(ptr)
@ cdecl wined3d_texture_get_autogen_filter_type(ptr)
@ -273,6 +274,7 @@
@ cdecl wined3d_texture_set_autogen_filter_type(ptr long)
@ cdecl wined3d_texture_set_color_key(ptr long ptr)
@ cdecl wined3d_texture_set_lod(ptr long)
@ cdecl wined3d_texture_update_desc(ptr long long long long long ptr long)
@ cdecl wined3d_vertex_declaration_create(ptr ptr long ptr ptr ptr)
@ cdecl wined3d_vertex_declaration_create_from_fvf(ptr long ptr ptr ptr)
@ -288,3 +290,11 @@
@ cdecl wined3d_volume_map(ptr ptr ptr long)
@ cdecl wined3d_volume_preload(ptr)
@ cdecl wined3d_volume_unmap(ptr)
@ cdecl wined3d_dxtn_supported()
@ cdecl wined3d_dxt1_decode(ptr ptr long long long long long)
@ cdecl wined3d_dxt1_encode(ptr ptr long long long long long)
@ cdecl wined3d_dxt3_decode(ptr ptr long long long long long)
@ cdecl wined3d_dxt3_encode(ptr ptr long long long long long)
@ cdecl wined3d_dxt5_decode(ptr ptr long long long long long)
@ cdecl wined3d_dxt5_encode(ptr ptr long long long long long)

View file

@ -25,6 +25,7 @@
#define __WINE_WINED3D_GL_H
#include "wine/wgl.h"
#include "wine/wglext.h"
#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 /* not in the gl spec */
@ -47,7 +48,6 @@ enum wined3d_gl_extension
ARB_COLOR_BUFFER_FLOAT,
ARB_DEBUG_OUTPUT,
ARB_DEPTH_BUFFER_FLOAT,
ARB_DEPTH_CLAMP,
ARB_DEPTH_TEXTURE,
ARB_DRAW_BUFFERS,
ARB_DRAW_ELEMENTS_BASE_VERTEX,
@ -70,6 +70,7 @@ enum wined3d_gl_extension
ARB_POINT_PARAMETERS,
ARB_POINT_SPRITE,
ARB_PROVOKING_VERTEX,
ARB_SAMPLER_OBJECTS,
ARB_SHADER_BIT_ENCODING,
ARB_SHADER_OBJECTS,
ARB_SHADER_TEXTURE_LOD,
@ -135,7 +136,6 @@ enum wined3d_gl_extension
EXT_TEXTURE_SRGB_DECODE,
EXT_VERTEX_ARRAY_BGRA,
/* NVIDIA */
NV_DEPTH_CLAMP,
NV_FENCE,
NV_FOG_DISTANCE,
NV_FRAGMENT_PROGRAM,
@ -167,439 +167,4 @@ enum wined3d_gl_extension
WINED3D_GL_EXT_COUNT,
};
#include "wine/wglext.h"
#define GL_EXT_FUNCS_GEN \
/* GL_APPLE_fence */ \
USE_GL_FUNC(glDeleteFencesAPPLE) \
USE_GL_FUNC(glFinishFenceAPPLE) \
USE_GL_FUNC(glFinishObjectAPPLE) \
USE_GL_FUNC(glGenFencesAPPLE) \
USE_GL_FUNC(glIsFenceAPPLE) \
USE_GL_FUNC(glSetFenceAPPLE) \
USE_GL_FUNC(glTestFenceAPPLE) \
USE_GL_FUNC(glTestObjectAPPLE) \
/* GL_APPLE_flush_buffer_range */ \
USE_GL_FUNC(glBufferParameteriAPPLE) \
USE_GL_FUNC(glFlushMappedBufferRangeAPPLE) \
/* GL_ARB_blend_func_extended */ \
USE_GL_FUNC(glBindFragDataLocationIndexed) \
USE_GL_FUNC(glGetFragDataIndex) \
/* 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(glDrawElementsBaseVertex) \
USE_GL_FUNC(glDrawElementsInstancedBaseVertex) \
USE_GL_FUNC(glDrawRangeElementsBaseVertex) \
USE_GL_FUNC(glMultiDrawElementsBaseVertex) \
/* GL_ARB_draw_instanced */ \
USE_GL_FUNC(glDrawArraysInstancedARB) \
USE_GL_FUNC(glDrawElementsInstancedARB) \
/* GL_ARB_framebuffer_object */ \
USE_GL_FUNC(glBindFramebuffer) \
USE_GL_FUNC(glBindRenderbuffer) \
USE_GL_FUNC(glBlitFramebuffer) \
USE_GL_FUNC(glCheckFramebufferStatus) \
USE_GL_FUNC(glDeleteFramebuffers) \
USE_GL_FUNC(glDeleteRenderbuffers) \
USE_GL_FUNC(glFramebufferRenderbuffer) \
USE_GL_FUNC(glFramebufferTexture1D) \
USE_GL_FUNC(glFramebufferTexture2D) \
USE_GL_FUNC(glFramebufferTexture3D) \
USE_GL_FUNC(glFramebufferTextureLayer) \
USE_GL_FUNC(glGenFramebuffers) \
USE_GL_FUNC(glGenRenderbuffers) \
USE_GL_FUNC(glGenerateMipmap) \
USE_GL_FUNC(glGetFramebufferAttachmentParameteriv) \
USE_GL_FUNC(glGetRenderbufferParameteriv) \
USE_GL_FUNC(glIsFramebuffer) \
USE_GL_FUNC(glIsRenderbuffer) \
USE_GL_FUNC(glRenderbufferStorage) \
USE_GL_FUNC(glRenderbufferStorageMultisample) \
/* GL_ARB_geometry_shader4 */ \
USE_GL_FUNC(glFramebufferTextureARB) \
USE_GL_FUNC(glFramebufferTextureFaceARB) \
USE_GL_FUNC(glFramebufferTextureLayerARB) \
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) \
/* GL_ARB_multisample */ \
USE_GL_FUNC(glSampleCoverageARB) \
/* GL_ARB_multitexture */ \
USE_GL_FUNC(glActiveTextureARB) \
USE_GL_FUNC(glClientActiveTextureARB) \
USE_GL_FUNC(glMultiTexCoord1fARB) \
USE_GL_FUNC(glMultiTexCoord1fvARB) \
USE_GL_FUNC(glMultiTexCoord2fARB) \
USE_GL_FUNC(glMultiTexCoord2fvARB) \
USE_GL_FUNC(glMultiTexCoord2svARB) \
USE_GL_FUNC(glMultiTexCoord3fARB) \
USE_GL_FUNC(glMultiTexCoord3fvARB) \
USE_GL_FUNC(glMultiTexCoord4fARB) \
USE_GL_FUNC(glMultiTexCoord4fvARB) \
USE_GL_FUNC(glMultiTexCoord4svARB) \
/* GL_ARB_occlusion_query */ \
USE_GL_FUNC(glBeginQueryARB) \
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) \
/* GL_ARB_provoking_vertex */ \
USE_GL_FUNC(glProvokingVertex) \
/* GL_ARB_shader_objects */ \
USE_GL_FUNC(glAttachObjectARB) \
USE_GL_FUNC(glBindAttribLocationARB) \
USE_GL_FUNC(glCompileShaderARB) \
USE_GL_FUNC(glCreateProgramObjectARB) \
USE_GL_FUNC(glCreateShaderObjectARB) \
USE_GL_FUNC(glDeleteObjectARB) \
USE_GL_FUNC(glDetachObjectARB) \
USE_GL_FUNC(glGetActiveUniformARB) \
USE_GL_FUNC(glGetAttachedObjectsARB) \
USE_GL_FUNC(glGetAttribLocationARB) \
USE_GL_FUNC(glGetHandleARB) \
USE_GL_FUNC(glGetInfoLogARB) \
USE_GL_FUNC(glGetObjectParameterfvARB) \
USE_GL_FUNC(glGetObjectParameterivARB) \
USE_GL_FUNC(glGetShaderSourceARB) \
USE_GL_FUNC(glGetUniformLocationARB) \
USE_GL_FUNC(glGetUniformfvARB) \
USE_GL_FUNC(glGetUniformivARB) \
USE_GL_FUNC(glLinkProgramARB) \
USE_GL_FUNC(glShaderSourceARB) \
USE_GL_FUNC(glUniform1fARB) \
USE_GL_FUNC(glUniform1fvARB) \
USE_GL_FUNC(glUniform1iARB) \
USE_GL_FUNC(glUniform1ivARB) \
USE_GL_FUNC(glUniform2fARB) \
USE_GL_FUNC(glUniform2fvARB) \
USE_GL_FUNC(glUniform2iARB) \
USE_GL_FUNC(glUniform2ivARB) \
USE_GL_FUNC(glUniform3fARB) \
USE_GL_FUNC(glUniform3fvARB) \
USE_GL_FUNC(glUniform3iARB) \
USE_GL_FUNC(glUniform3ivARB) \
USE_GL_FUNC(glUniform4fARB) \
USE_GL_FUNC(glUniform4fvARB) \
USE_GL_FUNC(glUniform4iARB) \
USE_GL_FUNC(glUniform4ivARB) \
USE_GL_FUNC(glUniformMatrix2fvARB) \
USE_GL_FUNC(glUniformMatrix3fvARB) \
USE_GL_FUNC(glUniformMatrix4fvARB) \
USE_GL_FUNC(glUseProgramObjectARB) \
USE_GL_FUNC(glValidateProgramARB) \
/* GL_ARB_sync */ \
USE_GL_FUNC(glClientWaitSync) \
USE_GL_FUNC(glDeleteSync) \
USE_GL_FUNC(glFenceSync) \
USE_GL_FUNC(glGetInteger64v) \
USE_GL_FUNC(glGetSynciv) \
USE_GL_FUNC(glIsSync) \
USE_GL_FUNC(glWaitSync) \
/* GL_ARB_texture_compression */ \
USE_GL_FUNC(glCompressedTexImage2DARB) \
USE_GL_FUNC(glCompressedTexImage3DARB) \
USE_GL_FUNC(glCompressedTexSubImage2DARB) \
USE_GL_FUNC(glCompressedTexSubImage3DARB) \
USE_GL_FUNC(glGetCompressedTexImageARB) \
/* GL_ARB_timer_query */ \
USE_GL_FUNC(glQueryCounter) \
USE_GL_FUNC(glGetQueryObjectui64v) \
/* GL_ARB_uniform_buffer_object */ \
USE_GL_FUNC(glBindBufferBase) \
USE_GL_FUNC(glBindBufferRange) \
USE_GL_FUNC(glGetActiveUniformBlockName) \
USE_GL_FUNC(glGetActiveUniformBlockiv) \
USE_GL_FUNC(glGetActiveUniformName) \
USE_GL_FUNC(glGetActiveUniformsiv) \
USE_GL_FUNC(glGetIntegeri_v) \
USE_GL_FUNC(glGetUniformBlockIndex) \
USE_GL_FUNC(glGetUniformIndices) \
USE_GL_FUNC(glUniformBlockBinding) \
/* GL_ARB_vertex_blend */ \
USE_GL_FUNC(glVertexBlendARB) \
USE_GL_FUNC(glWeightPointerARB) \
USE_GL_FUNC(glWeightbvARB) \
USE_GL_FUNC(glWeightdvARB) \
USE_GL_FUNC(glWeightfvARB) \
USE_GL_FUNC(glWeightivARB) \
USE_GL_FUNC(glWeightsvARB) \
USE_GL_FUNC(glWeightubvARB) \
USE_GL_FUNC(glWeightuivARB) \
USE_GL_FUNC(glWeightusvARB) \
/* GL_ARB_vertex_buffer_object */ \
USE_GL_FUNC(glBindBufferARB) \
USE_GL_FUNC(glBufferDataARB) \
USE_GL_FUNC(glBufferSubDataARB) \
USE_GL_FUNC(glDeleteBuffersARB) \
USE_GL_FUNC(glGenBuffersARB) \
USE_GL_FUNC(glGetBufferParameterivARB) \
USE_GL_FUNC(glGetBufferPointervARB) \
USE_GL_FUNC(glGetBufferSubDataARB) \
USE_GL_FUNC(glIsBufferARB) \
USE_GL_FUNC(glMapBufferARB) \
USE_GL_FUNC(glUnmapBufferARB) \
/* GL_ARB_vertex_program */ \
USE_GL_FUNC(glBindProgramARB) \
USE_GL_FUNC(glDeleteProgramsARB) \
USE_GL_FUNC(glDisableVertexAttribArrayARB) \
USE_GL_FUNC(glEnableVertexAttribArrayARB) \
USE_GL_FUNC(glGenProgramsARB) \
USE_GL_FUNC(glGetProgramivARB) \
USE_GL_FUNC(glProgramEnvParameter4fvARB) \
USE_GL_FUNC(glProgramLocalParameter4fvARB) \
USE_GL_FUNC(glProgramStringARB) \
USE_GL_FUNC(glVertexAttrib1dARB) \
USE_GL_FUNC(glVertexAttrib1dvARB) \
USE_GL_FUNC(glVertexAttrib1fARB) \
USE_GL_FUNC(glVertexAttrib1fvARB) \
USE_GL_FUNC(glVertexAttrib1sARB) \
USE_GL_FUNC(glVertexAttrib1svARB) \
USE_GL_FUNC(glVertexAttrib2dARB) \
USE_GL_FUNC(glVertexAttrib2dvARB) \
USE_GL_FUNC(glVertexAttrib2fARB) \
USE_GL_FUNC(glVertexAttrib2fvARB) \
USE_GL_FUNC(glVertexAttrib2sARB) \
USE_GL_FUNC(glVertexAttrib2svARB) \
USE_GL_FUNC(glVertexAttrib3dARB) \
USE_GL_FUNC(glVertexAttrib3dvARB) \
USE_GL_FUNC(glVertexAttrib3fARB) \
USE_GL_FUNC(glVertexAttrib3fvARB) \
USE_GL_FUNC(glVertexAttrib3sARB) \
USE_GL_FUNC(glVertexAttrib3svARB) \
USE_GL_FUNC(glVertexAttrib4NbvARB) \
USE_GL_FUNC(glVertexAttrib4NivARB) \
USE_GL_FUNC(glVertexAttrib4NsvARB) \
USE_GL_FUNC(glVertexAttrib4NubARB) \
USE_GL_FUNC(glVertexAttrib4NubvARB) \
USE_GL_FUNC(glVertexAttrib4NuivARB) \
USE_GL_FUNC(glVertexAttrib4NusvARB) \
USE_GL_FUNC(glVertexAttrib4bvARB) \
USE_GL_FUNC(glVertexAttrib4dARB) \
USE_GL_FUNC(glVertexAttrib4dvARB) \
USE_GL_FUNC(glVertexAttrib4fARB) \
USE_GL_FUNC(glVertexAttrib4fvARB) \
USE_GL_FUNC(glVertexAttrib4ivARB) \
USE_GL_FUNC(glVertexAttrib4sARB) \
USE_GL_FUNC(glVertexAttrib4svARB) \
USE_GL_FUNC(glVertexAttrib4ubvARB) \
USE_GL_FUNC(glVertexAttrib4uivARB) \
USE_GL_FUNC(glVertexAttrib4usvARB) \
USE_GL_FUNC(glVertexAttribPointerARB) \
/* GL_ATI_fragment_shader */ \
USE_GL_FUNC(glAlphaFragmentOp1ATI) \
USE_GL_FUNC(glAlphaFragmentOp2ATI) \
USE_GL_FUNC(glAlphaFragmentOp3ATI) \
USE_GL_FUNC(glBeginFragmentShaderATI) \
USE_GL_FUNC(glBindFragmentShaderATI) \
USE_GL_FUNC(glColorFragmentOp1ATI) \
USE_GL_FUNC(glColorFragmentOp2ATI) \
USE_GL_FUNC(glColorFragmentOp3ATI) \
USE_GL_FUNC(glDeleteFragmentShaderATI) \
USE_GL_FUNC(glEndFragmentShaderATI) \
USE_GL_FUNC(glGenFragmentShadersATI) \
USE_GL_FUNC(glPassTexCoordATI) \
USE_GL_FUNC(glSampleMapATI) \
USE_GL_FUNC(glSetFragmentShaderConstantATI) \
/* GL_ATI_separate_stencil */ \
USE_GL_FUNC(glStencilOpSeparateATI) \
USE_GL_FUNC(glStencilFuncSeparateATI) \
/* GL_EXT_blend_color */ \
USE_GL_FUNC(glBlendColorEXT) \
/* GL_EXT_blend_equation_separate */ \
USE_GL_FUNC(glBlendFuncSeparateEXT) \
/* GL_EXT_blend_func_separate */ \
USE_GL_FUNC(glBlendEquationSeparateEXT) \
/* GL_EXT_blend_minmax */ \
USE_GL_FUNC(glBlendEquationEXT) \
/* GL_EXT_depth_bounds_test */ \
USE_GL_FUNC(glDepthBoundsEXT) \
/* GL_EXT_draw_buffers2 */ \
USE_GL_FUNC(glColorMaskIndexedEXT) \
USE_GL_FUNC(glDisableIndexedEXT) \
USE_GL_FUNC(glEnableIndexedEXT) \
USE_GL_FUNC(glGetBooleanIndexedvEXT) \
USE_GL_FUNC(glGetIntegerIndexedvEXT) \
USE_GL_FUNC(glIsEnabledIndexedEXT) \
/* GL_EXT_fog_coord */ \
USE_GL_FUNC(glFogCoordPointerEXT) \
USE_GL_FUNC(glFogCoorddEXT) \
USE_GL_FUNC(glFogCoorddvEXT) \
USE_GL_FUNC(glFogCoordfEXT) \
USE_GL_FUNC(glFogCoordfvEXT) \
/* GL_EXT_framebuffer_blit */ \
USE_GL_FUNC(glBlitFramebufferEXT) \
/* GL_EXT_framebuffer_multisample */ \
USE_GL_FUNC(glRenderbufferStorageMultisampleEXT) \
/* GL_EXT_framebuffer_object */ \
USE_GL_FUNC(glBindFramebufferEXT) \
USE_GL_FUNC(glBindRenderbufferEXT) \
USE_GL_FUNC(glCheckFramebufferStatusEXT) \
USE_GL_FUNC(glDeleteFramebuffersEXT) \
USE_GL_FUNC(glDeleteRenderbuffersEXT) \
USE_GL_FUNC(glFramebufferRenderbufferEXT) \
USE_GL_FUNC(glFramebufferTexture1DEXT) \
USE_GL_FUNC(glFramebufferTexture2DEXT) \
USE_GL_FUNC(glFramebufferTexture3DEXT) \
USE_GL_FUNC(glGenFramebuffersEXT) \
USE_GL_FUNC(glGenRenderbuffersEXT) \
USE_GL_FUNC(glGenerateMipmapEXT) \
USE_GL_FUNC(glGetFramebufferAttachmentParameterivEXT) \
USE_GL_FUNC(glGetRenderbufferParameterivEXT) \
USE_GL_FUNC(glIsFramebufferEXT) \
USE_GL_FUNC(glIsRenderbufferEXT) \
USE_GL_FUNC(glRenderbufferStorageEXT) \
/* GL_EXT_gpu_program_parameters */ \
USE_GL_FUNC(glProgramEnvParameters4fvEXT) \
USE_GL_FUNC(glProgramLocalParameters4fvEXT) \
/* GL_EXT_gpu_shader4 */\
USE_GL_FUNC(glBindFragDataLocationEXT) \
USE_GL_FUNC(glGetFragDataLocationEXT) \
USE_GL_FUNC(glGetUniformuivEXT) \
USE_GL_FUNC(glGetVertexAttribIivEXT) \
USE_GL_FUNC(glGetVertexAttribIuivEXT) \
USE_GL_FUNC(glUniform1uiEXT) \
USE_GL_FUNC(glUniform1uivEXT) \
USE_GL_FUNC(glUniform2uiEXT) \
USE_GL_FUNC(glUniform2uivEXT) \
USE_GL_FUNC(glUniform3uiEXT) \
USE_GL_FUNC(glUniform3uivEXT) \
USE_GL_FUNC(glUniform4uiEXT) \
USE_GL_FUNC(glUniform4uivEXT) \
USE_GL_FUNC(glVertexAttribI1iEXT) \
USE_GL_FUNC(glVertexAttribI1ivEXT) \
USE_GL_FUNC(glVertexAttribI1uiEXT) \
USE_GL_FUNC(glVertexAttribI1uivEXT) \
USE_GL_FUNC(glVertexAttribI2iEXT) \
USE_GL_FUNC(glVertexAttribI2ivEXT) \
USE_GL_FUNC(glVertexAttribI2uiEXT) \
USE_GL_FUNC(glVertexAttribI2uivEXT) \
USE_GL_FUNC(glVertexAttribI3iEXT) \
USE_GL_FUNC(glVertexAttribI3ivEXT) \
USE_GL_FUNC(glVertexAttribI3uiEXT) \
USE_GL_FUNC(glVertexAttribI3uivEXT) \
USE_GL_FUNC(glVertexAttribI4bvEXT) \
USE_GL_FUNC(glVertexAttribI4iEXT) \
USE_GL_FUNC(glVertexAttribI4ivEXT) \
USE_GL_FUNC(glVertexAttribI4svEXT) \
USE_GL_FUNC(glVertexAttribI4ubvEXT) \
USE_GL_FUNC(glVertexAttribI4uiEXT) \
USE_GL_FUNC(glVertexAttribI4uivEXT) \
USE_GL_FUNC(glVertexAttribI4usvEXT) \
USE_GL_FUNC(glVertexAttribIPointerEXT) \
/* GL_EXT_point_parameters */ \
USE_GL_FUNC(glPointParameterfEXT) \
USE_GL_FUNC(glPointParameterfvEXT) \
/* GL_EXT_provoking_vertex */ \
USE_GL_FUNC(glProvokingVertexEXT) \
/* GL_EXT_secondary_color */ \
USE_GL_FUNC(glSecondaryColor3fEXT) \
USE_GL_FUNC(glSecondaryColor3fvEXT) \
USE_GL_FUNC(glSecondaryColor3ubEXT) \
USE_GL_FUNC(glSecondaryColor3ubvEXT) \
USE_GL_FUNC(glSecondaryColorPointerEXT) \
/* GL_EXT_stencil_two_side */ \
USE_GL_FUNC(glActiveStencilFaceEXT) \
/* GL_EXT_texture3D */ \
USE_GL_FUNC(glTexImage3D) \
USE_GL_FUNC(glTexImage3DEXT) \
USE_GL_FUNC(glTexSubImage3D) \
USE_GL_FUNC(glTexSubImage3DEXT) \
/* GL_NV_fence */ \
USE_GL_FUNC(glDeleteFencesNV) \
USE_GL_FUNC(glFinishFenceNV) \
USE_GL_FUNC(glGenFencesNV) \
USE_GL_FUNC(glGetFenceivNV) \
USE_GL_FUNC(glIsFenceNV) \
USE_GL_FUNC(glSetFenceNV) \
USE_GL_FUNC(glTestFenceNV) \
/* GL_NV_half_float */ \
USE_GL_FUNC(glColor3hNV) \
USE_GL_FUNC(glColor3hvNV) \
USE_GL_FUNC(glColor4hNV) \
USE_GL_FUNC(glColor4hvNV) \
USE_GL_FUNC(glFogCoordhNV) \
USE_GL_FUNC(glFogCoordhvNV) \
USE_GL_FUNC(glMultiTexCoord1hNV) \
USE_GL_FUNC(glMultiTexCoord1hvNV) \
USE_GL_FUNC(glMultiTexCoord2hNV) \
USE_GL_FUNC(glMultiTexCoord2hvNV) \
USE_GL_FUNC(glMultiTexCoord3hNV) \
USE_GL_FUNC(glMultiTexCoord3hvNV) \
USE_GL_FUNC(glMultiTexCoord4hNV) \
USE_GL_FUNC(glMultiTexCoord4hvNV) \
USE_GL_FUNC(glNormal3hNV) \
USE_GL_FUNC(glNormal3hvNV) \
USE_GL_FUNC(glSecondaryColor3hNV) \
USE_GL_FUNC(glSecondaryColor3hvNV) \
USE_GL_FUNC(glTexCoord1hNV) \
USE_GL_FUNC(glTexCoord1hvNV) \
USE_GL_FUNC(glTexCoord2hNV) \
USE_GL_FUNC(glTexCoord2hvNV) \
USE_GL_FUNC(glTexCoord3hNV) \
USE_GL_FUNC(glTexCoord3hvNV) \
USE_GL_FUNC(glTexCoord4hNV) \
USE_GL_FUNC(glTexCoord4hvNV) \
USE_GL_FUNC(glVertex2hNV) \
USE_GL_FUNC(glVertex2hvNV) \
USE_GL_FUNC(glVertex3hNV) \
USE_GL_FUNC(glVertex3hvNV) \
USE_GL_FUNC(glVertex4hNV) \
USE_GL_FUNC(glVertex4hvNV) \
USE_GL_FUNC(glVertexAttrib1hNV) \
USE_GL_FUNC(glVertexAttrib1hvNV) \
USE_GL_FUNC(glVertexAttrib2hNV) \
USE_GL_FUNC(glVertexAttrib2hvNV) \
USE_GL_FUNC(glVertexAttrib3hNV) \
USE_GL_FUNC(glVertexAttrib3hvNV) \
USE_GL_FUNC(glVertexAttrib4hNV) \
USE_GL_FUNC(glVertexAttrib4hvNV) \
USE_GL_FUNC(glVertexAttribs1hvNV) \
USE_GL_FUNC(glVertexAttribs2hvNV) \
USE_GL_FUNC(glVertexAttribs3hvNV) \
USE_GL_FUNC(glVertexAttribs4hvNV) \
USE_GL_FUNC(glVertexWeighthNV) \
USE_GL_FUNC(glVertexWeighthvNV) \
/* GL_NV_point_sprite */ \
USE_GL_FUNC(glPointParameteri) \
USE_GL_FUNC(glPointParameteriNV) \
USE_GL_FUNC(glPointParameteriv) \
USE_GL_FUNC(glPointParameterivNV) \
/* GL_NV_register_combiners */ \
USE_GL_FUNC(glCombinerInputNV) \
USE_GL_FUNC(glCombinerOutputNV) \
USE_GL_FUNC(glCombinerParameterfNV) \
USE_GL_FUNC(glCombinerParameterfvNV) \
USE_GL_FUNC(glCombinerParameteriNV) \
USE_GL_FUNC(glCombinerParameterivNV) \
USE_GL_FUNC(glFinalCombinerInputNV) \
/* WGL extensions */ \
USE_GL_FUNC(wglChoosePixelFormatARB) \
USE_GL_FUNC(wglGetExtensionsStringARB) \
USE_GL_FUNC(wglGetPixelFormatAttribfvARB) \
USE_GL_FUNC(wglGetPixelFormatAttribivARB) \
USE_GL_FUNC(wglSetPixelFormatWINE) \
USE_GL_FUNC(wglSwapIntervalEXT)
#endif /* __WINE_WINED3D_GL */

View file

@ -307,6 +307,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
if (appkey) RegCloseKey( appkey );
if (hkey) RegCloseKey( hkey );
wined3d_dxtn_init();
return TRUE;
}
@ -338,6 +340,9 @@ static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
DeleteCriticalSection(&wined3d_wndproc_cs);
DeleteCriticalSection(&wined3d_cs);
wined3d_dxtn_free();
return TRUE;
}
@ -503,6 +508,11 @@ void wined3d_unregister_window(HWND window)
wined3d_wndproc_mutex_unlock();
}
void wined3d_strictdrawing_set(int value)
{
wined3d_settings.strict_draw_ordering = value;
}
/* At process attach */
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
{

View file

@ -61,6 +61,10 @@
#include "wined3d_gl.h"
#include <wine/wgl_driver.h>
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
#endif
/* Driver quirks */
#define WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT 0x00000001
#define WINED3D_QUIRK_SET_TEXCOORD_W 0x00000002
@ -100,14 +104,14 @@ enum complex_fixup
#include <pshpack2.h>
struct color_fixup_desc
{
unsigned x_sign_fixup : 1;
unsigned x_source : 3;
unsigned y_sign_fixup : 1;
unsigned y_source : 3;
unsigned z_sign_fixup : 1;
unsigned z_source : 3;
unsigned w_sign_fixup : 1;
unsigned w_source : 3;
unsigned short x_sign_fixup : 1;
unsigned short x_source : 3;
unsigned short y_sign_fixup : 1;
unsigned short y_source : 3;
unsigned short z_sign_fixup : 1;
unsigned short z_source : 3;
unsigned short w_sign_fixup : 1;
unsigned short w_source : 3;
};
#include <poppack.h>
@ -150,6 +154,14 @@ static inline BOOL is_complex_fixup(struct color_fixup_desc fixup)
return fixup.x_source == CHANNEL_SOURCE_COMPLEX0 || fixup.x_source == CHANNEL_SOURCE_COMPLEX1;
}
static inline BOOL is_same_fixup(struct color_fixup_desc f1, struct color_fixup_desc f2)
{
return f1.x_sign_fixup == f2.x_sign_fixup && f1.x_source == f2.x_source
&& f1.y_sign_fixup == f2.y_sign_fixup && f1.y_source == f2.y_source
&& f1.z_sign_fixup == f2.z_sign_fixup && f1.z_source == f2.z_source
&& f1.w_sign_fixup == f2.w_sign_fixup && f1.w_source == f2.w_source;
}
static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup)
{
enum complex_fixup complex_fixup = 0;
@ -183,20 +195,19 @@ struct min_lookup
};
extern const struct min_lookup minMipLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
extern const struct min_lookup minMipLookup_noFilter[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
extern const struct min_lookup minMipLookup_noMip[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
extern const GLenum magLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
extern const GLenum magLookup_noFilter[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
static inline GLenum wined3d_gl_mag_filter(const GLenum mag_lookup[], enum wined3d_texture_filter_type mag_filter)
GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f) DECLSPEC_HIDDEN;
static inline GLenum wined3d_gl_mag_filter(enum wined3d_texture_filter_type mag_filter)
{
return mag_lookup[mag_filter];
return magLookup[mag_filter];
}
static inline GLenum wined3d_gl_min_mip_filter(const struct min_lookup min_mip_lookup[],
enum wined3d_texture_filter_type min_filter, enum wined3d_texture_filter_type mip_filter)
static inline GLenum wined3d_gl_min_mip_filter(enum wined3d_texture_filter_type min_filter,
enum wined3d_texture_filter_type mip_filter)
{
return min_mip_lookup[min_filter].mip[mip_filter];
return minMipLookup[min_filter].mip[mip_filter];
}
/* float_16_to_32() and float_32_to_16() (see implementation in
@ -280,13 +291,18 @@ struct wined3d_settings
extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN;
enum wined3d_sampler_texture_type
enum wined3d_shader_resource_type
{
WINED3DSTT_UNKNOWN = 0,
WINED3DSTT_1D = 1,
WINED3DSTT_2D = 2,
WINED3DSTT_CUBE = 3,
WINED3DSTT_VOLUME = 4,
WINED3D_SHADER_RESOURCE_NONE,
WINED3D_SHADER_RESOURCE_BUFFER,
WINED3D_SHADER_RESOURCE_TEXTURE_1D,
WINED3D_SHADER_RESOURCE_TEXTURE_2D,
WINED3D_SHADER_RESOURCE_TEXTURE_2DMS,
WINED3D_SHADER_RESOURCE_TEXTURE_3D,
WINED3D_SHADER_RESOURCE_TEXTURE_CUBE,
WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY,
WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY,
WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY,
};
#define WINED3D_SHADER_CONST_VS_F 0x00000001
@ -339,6 +355,8 @@ enum wined3d_data_type
WINED3D_DATA_RESOURCE,
WINED3D_DATA_SAMPLER,
WINED3D_DATA_UINT,
WINED3D_DATA_UNORM,
WINED3D_DATA_SNORM,
};
enum wined3d_immconst_type
@ -502,8 +520,10 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
WINED3DSIH_MOVA,
WINED3DSIH_MOVC,
WINED3DSIH_MUL,
WINED3DSIH_NE,
WINED3DSIH_NOP,
WINED3DSIH_NRM,
WINED3DSIH_OR,
WINED3DSIH_PHASE,
WINED3DSIH_POW,
WINED3DSIH_RCP,
@ -544,6 +564,7 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
WINED3DSIH_TEXREG2GB,
WINED3DSIH_TEXREG2RGB,
WINED3DSIH_UDIV,
WINED3DSIH_UGE,
WINED3DSIH_USHR,
WINED3DSIH_UTOF,
WINED3DSIH_XOR,
@ -565,6 +586,26 @@ struct wined3d_shader_version
BYTE minor;
};
struct wined3d_shader_resource_info
{
enum wined3d_shader_resource_type type;
enum wined3d_data_type data_type;
};
struct wined3d_shader_sampler_map_entry
{
unsigned int resource_idx;
unsigned int sampler_idx;
unsigned int bind_idx;
};
struct wined3d_shader_sampler_map
{
struct wined3d_shader_sampler_map_entry *entries;
size_t size;
size_t count;
};
#define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor))
struct wined3d_shader_reg_maps
@ -584,7 +625,8 @@ struct wined3d_shader_reg_maps
WORD local_bool_consts; /* MAX_CONST_B, 16 */
UINT cb_sizes[WINED3D_MAX_CBS];
enum wined3d_sampler_texture_type sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
struct wined3d_shader_resource_info resource_info[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
struct wined3d_shader_sampler_map sampler_map;
BYTE bumpmat; /* MAX_TEXTURES, 8 */
BYTE luminanceparams; /* MAX_TEXTURES, 8 */
@ -669,7 +711,8 @@ struct wined3d_shader_semantic
{
enum wined3d_decl_usage usage;
UINT usage_idx;
enum wined3d_sampler_texture_type sampler_type;
enum wined3d_shader_resource_type resource_type;
enum wined3d_data_type resource_data_type;
struct wined3d_shader_dst_param reg;
};
@ -930,6 +973,17 @@ struct wined3d_bo_address
BYTE *addr;
};
struct wined3d_const_bo_address
{
GLuint buffer_object;
const BYTE *addr;
};
static inline struct wined3d_const_bo_address *wined3d_const_bo_address(struct wined3d_bo_address *data)
{
return (struct wined3d_const_bo_address *)data;
}
struct wined3d_stream_info_element
{
const struct wined3d_format *format;
@ -974,7 +1028,10 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
#define STATE_CONSTANT_BUFFER(a) (STATE_SHADER(WINED3D_SHADER_TYPE_COUNT) + (a))
#define STATE_IS_CONSTANT_BUFFER(a) ((a) >= STATE_CONSTANT_BUFFER(0) && (a) < STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COUNT))
#define STATE_TRANSFORM(a) (STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COUNT) + (a) - 1)
#define STATE_SHADER_RESOURCE_BINDING (STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COUNT))
#define STATE_IS_SHADER_RESOURCE_BINDING(a) ((a) == STATE_SHADER_RESOURCE_BINDING)
#define STATE_TRANSFORM(a) (STATE_SHADER_RESOURCE_BINDING + (a))
#define STATE_IS_TRANSFORM(a) ((a) >= STATE_TRANSFORM(1) && (a) <= STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)))
#define STATE_STREAMSRC (STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)) + 1)
@ -1111,9 +1168,8 @@ struct wined3d_context
DWORD lowest_disabled_stage : 4; /* Max MAX_TEXTURES, 8 */
DWORD rebind_fbo : 1;
DWORD needs_set : 1;
DWORD hdc_is_private : 1;
DWORD hdc_has_format : 1; /* only meaningful if hdc_is_private */
DWORD padding : 16;
DWORD update_shader_resource_bindings : 1;
DWORD padding : 17;
DWORD shader_update_mask;
DWORD constant_update_mask;
DWORD numbered_array_mask;
@ -1131,7 +1187,6 @@ struct wined3d_context
HGLRC restore_ctx;
HDC restore_dc;
int restore_pf;
HWND restore_pf_win;
HGLRC glCtx;
HWND win_handle;
HDC hdc;
@ -1511,6 +1566,7 @@ enum wined3d_pci_device
CARD_NVIDIA_GEFORCE_GTX670 = 0x1189,
CARD_NVIDIA_GEFORCE_GTX670MX = 0x11a1,
CARD_NVIDIA_GEFORCE_GTX680 = 0x1180,
CARD_NVIDIA_GEFORCE_GT750M = 0x0fe9,
CARD_NVIDIA_GEFORCE_GTX750 = 0x1381,
CARD_NVIDIA_GEFORCE_GTX750TI = 0x1380,
CARD_NVIDIA_GEFORCE_GTX760 = 0x1187,
@ -1519,6 +1575,7 @@ enum wined3d_pci_device
CARD_NVIDIA_GEFORCE_GTX770 = 0x1184,
CARD_NVIDIA_GEFORCE_GTX780 = 0x1004,
CARD_NVIDIA_GEFORCE_GTX780TI = 0x100a,
CARD_NVIDIA_GEFORCE_GTX970 = 0x13c2,
CARD_VMWARE_SVGA3D = 0x0405,
@ -1964,6 +2021,7 @@ struct wined3d_device
struct list resources; /* a linked list to track resources created by the device */
struct list shaders; /* a linked list to track shaders (pixel and vertex) */
struct wine_rb_tree samplers;
/* Render Target Support */
struct wined3d_fb_state fb;
@ -2096,26 +2154,11 @@ void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DEC
/* Tests show that the start address of resources is 32 byte aligned */
#define RESOURCE_ALIGNMENT 16
enum wined3d_texture_state
{
WINED3DTEXSTA_ADDRESSU = 0,
WINED3DTEXSTA_ADDRESSV = 1,
WINED3DTEXSTA_ADDRESSW = 2,
WINED3DTEXSTA_BORDERCOLOR = 3,
WINED3DTEXSTA_MAGFILTER = 4,
WINED3DTEXSTA_MINFILTER = 5,
WINED3DTEXSTA_MIPFILTER = 6,
WINED3DTEXSTA_MAXMIPLEVEL = 7,
WINED3DTEXSTA_MAXANISOTROPY = 8,
WINED3DTEXSTA_SRGBTEXTURE = 9,
WINED3DTEXSTA_SHADOW = 10,
MAX_WINETEXTURESTATES = 11,
};
struct gl_texture
{
DWORD states[MAX_WINETEXTURESTATES];
GLuint name;
struct wined3d_sampler_desc sampler_desc;
unsigned int base_level;
GLuint name;
};
struct wined3d_texture_ops
@ -2125,13 +2168,26 @@ struct wined3d_texture_ops
void (*texture_sub_resource_add_dirty_region)(struct wined3d_resource *sub_resource,
const struct wined3d_box *dirty_region);
void (*texture_sub_resource_cleanup)(struct wined3d_resource *sub_resource);
void (*texture_sub_resource_invalidate_location)(struct wined3d_resource *sub_resource, DWORD location);
void (*texture_sub_resource_validate_location)(struct wined3d_resource *sub_resource, DWORD location);
void (*texture_sub_resource_upload_data)(struct wined3d_resource *sub_resource,
const struct wined3d_context *context, const struct wined3d_sub_resource_data *data);
void (*texture_prepare_texture)(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb);
};
#define WINED3D_TEXTURE_COND_NP2 0x00000001
#define WINED3D_TEXTURE_POW2_MAT_IDENT 0x00000002
#define WINED3D_TEXTURE_IS_SRGB 0x00000004
#define WINED3D_TEXTURE_RGB_VALID 0x00000008
#define WINED3D_TEXTURE_SRGB_VALID 0x00000010
#define WINED3D_TEXTURE_RGB_ALLOCATED 0x00000008
#define WINED3D_TEXTURE_RGB_VALID 0x00000010
#define WINED3D_TEXTURE_SRGB_ALLOCATED 0x00000020
#define WINED3D_TEXTURE_SRGB_VALID 0x00000040
#define WINED3D_TEXTURE_CONVERTED 0x00000080
#define WINED3D_TEXTURE_PIN_SYSMEM 0x00000100
#define WINED3D_TEXTURE_DYNAMIC_MAP 0x00000200
#define WINED3D_TEXTURE_NORMALIZED_COORDS 0x00000400
#define WINED3D_TEXTURE_COLOR_KEY 0x00000800
struct wined3d_texture
{
@ -2147,8 +2203,6 @@ struct wined3d_texture
enum wined3d_texture_filter_type filter_type;
DWORD sampler;
DWORD flags;
const struct min_lookup *min_mip_lookup;
const GLenum *mag_lookup;
GLenum target;
/* Color keys for DDraw */
@ -2156,6 +2210,7 @@ struct wined3d_texture
struct wined3d_color_key src_blt_color_key;
struct wined3d_color_key dst_overlay_color_key;
struct wined3d_color_key src_overlay_color_key;
struct wined3d_color_key gl_color_key;
DWORD color_key_flags;
};
@ -2170,15 +2225,17 @@ static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_t
return srgb ? &texture->texture_srgb : &texture->texture_rgb;
}
void wined3d_texture_apply_state_changes(struct wined3d_texture *texture,
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1],
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture,
const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_texture_bind(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void wined3d_texture_force_reload(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
void wined3d_texture_load(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void wined3d_texture_prepare_texture(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
@ -2196,6 +2253,8 @@ void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN;
#define WINED3D_VFLAG_CLIENT_STORAGE 0x00000001
struct wined3d_volume
{
struct wined3d_resource resource;
@ -2212,14 +2271,17 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc
return CONTAINING_RECORD(resource, struct wined3d_volume, resource);
}
BOOL volume_prepare_system_memory(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc,
unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN;
void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) DECLSPEC_HIDDEN;
void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context,
BOOL srgb_mode) DECLSPEC_HIDDEN;
void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN;
void wined3d_volume_validate_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;
const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
struct wined3d_surface_dib
{
@ -2282,8 +2344,6 @@ struct wined3d_surface
struct wined3d_surface_dib dib;
HDC hDC;
struct wined3d_color_key gl_color_key;
struct list renderbuffers;
const struct wined3d_renderbuffer_entry *current_renderbuffer;
SIZE ds_current_size;
@ -2323,12 +2383,12 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location) D
void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN;
void surface_prepare_rb(struct wined3d_surface *surface,
const struct wined3d_gl_info *gl_info, BOOL multisample) DECLSPEC_HIDDEN;
void surface_prepare_texture(struct wined3d_surface *surface,
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_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;
HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface,
const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) DECLSPEC_HIDDEN;
HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point,
struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN;
void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN;
@ -2337,59 +2397,38 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w
struct wined3d_surface **surface) DECLSPEC_HIDDEN;
void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point,
BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context,
const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) DECLSPEC_HIDDEN;
/* Surface flags: */
#define SFLAG_CONVERTED 0x00000001 /* Converted for color keying or palettized. */
#define SFLAG_DIBSECTION 0x00000001 /* Has a DIB section attached for GetDC. */
#define SFLAG_DISCARD 0x00000002 /* ??? */
#define SFLAG_NONPOW2 0x00000004 /* Surface sizes are not a power of 2 */
#define SFLAG_NORMCOORD 0x00000008 /* Set if GL texture coordinates are normalized (non-texture rectangle). */
#define SFLAG_DYNLOCK 0x00000010 /* Surface is often locked by the application. */
#define SFLAG_PIN_SYSMEM 0x00000020 /* Keep the surface in sysmem, at the same address. */
#define SFLAG_DCINUSE 0x00000040 /* Set between GetDC and ReleaseDC calls. */
#define SFLAG_LOST 0x00000080 /* Surface lost flag for ddraw. */
#define SFLAG_GLCKEY 0x00000100 /* The GL texture was created with a color key. */
#define SFLAG_CLIENT 0x00000200 /* GL_APPLE_client_storage is used with this surface. */
#define SFLAG_DIBSECTION 0x00000400 /* Has a DIB section attached for GetDC. */
#define SFLAG_ALLOCATED 0x00000800 /* A GL texture is allocated for this surface. */
#define SFLAG_SRGBALLOCATED 0x00001000 /* A sRGB GL texture is allocated for this surface. */
/* In some conditions the surface memory must not be freed:
* SFLAG_CONVERTED: Converting the data back would take too long
* SFLAG_DYNLOCK: Avoid freeing the data for performance
* SFLAG_CLIENT: OpenGL uses our memory as backup
*/
#define SFLAG_DONOTFREE (SFLAG_CONVERTED | \
SFLAG_DYNLOCK | \
SFLAG_CLIENT | \
SFLAG_PIN_SYSMEM)
enum wined3d_conversion_type
{
WINED3D_CT_NONE,
WINED3D_CT_PALETTED,
WINED3D_CT_CK_565,
WINED3D_CT_CK_5551,
WINED3D_CT_CK_RGB24,
WINED3D_CT_RGB32_888,
WINED3D_CT_CK_ARGB32,
};
#define SFLAG_LOST 0x00000008 /* Surface lost flag for ddraw. */
#define SFLAG_CLIENT 0x00000010 /* GL_APPLE_client_storage is used with this surface. */
#define SFLAG_DCINUSE 0x00000020 /* Set between GetDC and ReleaseDC calls. */
struct wined3d_sampler
{
struct wine_rb_entry entry;
LONG refcount;
struct wined3d_device *device;
void *parent;
struct wined3d_sampler_desc desc;
GLuint name;
};
struct wined3d_vertex_declaration_element
{
const struct wined3d_format *format;
BOOL ffp_valid;
WORD input_slot;
WORD offset;
unsigned int input_slot;
unsigned int offset;
UINT output_slot;
BYTE method;
BYTE usage;
@ -2669,6 +2708,7 @@ struct wined3d_shader_resource_view
{
LONG refcount;
struct wined3d_resource *resource;
void *parent;
const struct wined3d_parent_ops *parent_ops;
};
@ -2690,9 +2730,9 @@ struct wined3d_swapchain
struct wined3d_texture **back_buffers;
struct wined3d_texture *front_buffer;
struct wined3d_swapchain_desc desc;
struct wined3d_display_mode original_mode;
struct wined3d_display_mode original_mode, d3d_mode;
struct wined3d_gamma_ramp orig_gamma;
BOOL render_to_fbo;
BOOL render_to_fbo, reapply_mode;
const struct wined3d_format *ds_format;
struct wined3d_palette *palette;
@ -2710,6 +2750,7 @@ struct wined3d_swapchain
void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) DECLSPEC_HIDDEN;
void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN;
struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
@ -2814,7 +2855,6 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DE
/* Math utils */
void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
const struct wined3d_matrix *src2) DECLSPEC_HIDDEN;
UINT wined3d_log2i(UINT32 x) DECLSPEC_HIDDEN;
unsigned int count_bits(unsigned int mask) DECLSPEC_HIDDEN;
void wined3d_release_dc(HWND window, HDC dc) DECLSPEC_HIDDEN;
@ -2877,7 +2917,7 @@ struct wined3d_pixel_shader
struct wined3d_shader
{
LONG ref;
struct wined3d_shader_limits limits;
const struct wined3d_shader_limits *limits;
DWORD *function;
UINT functionLength;
BOOL load_local_constsF;
@ -2900,6 +2940,7 @@ struct wined3d_shader
struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
char *signature_strings;
/* Pointer to the parent device */
struct wined3d_device *device;
@ -2913,7 +2954,7 @@ struct wined3d_shader
} u;
};
void pixelshader_update_samplers(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN;
void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN;
void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
BOOL position_transformed, struct ps_compile_args *args,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
@ -3064,6 +3105,13 @@ struct wined3d_rational
UINT denominator;
};
struct wined3d_color_key_conversion
{
enum wined3d_format_id dst_format;
void (*convert)(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width,
unsigned int height, const struct wined3d_palette *palette, const struct wined3d_color_key *color_key);
};
struct wined3d_format
{
enum wined3d_format_id id;
@ -3111,6 +3159,8 @@ UINT wined3d_format_calculate_size(const struct wined3d_format *format,
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;
const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(
const struct wined3d_texture *texture, BOOL need_alpha_ck) DECLSPEC_HIDDEN;
static inline BOOL use_vs(const struct wined3d_state *state)
{
@ -3132,6 +3182,9 @@ static inline void context_apply_state(struct wined3d_context *context,
state_table[rep].apply(context, state, rep);
}
BOOL wined3d_dxtn_init(void) DECLSPEC_HIDDEN;
void wined3d_dxtn_free(void) DECLSPEC_HIDDEN;
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"

View file

@ -26,6 +26,10 @@
#ifndef __WINE_WINED3D_H
#define __WINE_WINED3D_H
#ifndef __WINE_CONFIG_H
# error You must include config.h to use this header
#endif
#include <wine/list.h>
#define WINED3D_OK S_OK
@ -241,6 +245,7 @@ enum wined3d_format_id
WINED3DFMT_MULTI2_ARGB8 = WINEMAKEFOURCC('M','E','T','1'),
WINED3DFMT_G8R8_G8B8 = WINEMAKEFOURCC('G','R','G','B'),
WINED3DFMT_R8G8_B8G8 = WINEMAKEFOURCC('R','G','B','G'),
WINED3DFMT_ATI1N = WINEMAKEFOURCC('A','T','I','1'),
WINED3DFMT_ATI2N = WINEMAKEFOURCC('A','T','I','2'),
WINED3DFMT_INST = WINEMAKEFOURCC('I','N','S','T'),
WINED3DFMT_NVDB = WINEMAKEFOURCC('N','V','D','B'),
@ -933,6 +938,12 @@ enum wined3d_display_rotation
#define WINED3DCREATE_MIXED_VERTEXPROCESSING 0x00000080
#define WINED3DCREATE_DISABLE_DRIVER_MANAGEMENT 0x00000100
#define WINED3DCREATE_ADAPTERGROUP_DEVICE 0x00000200
#define WINED3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX 0x00000400
#define WINED3DCREATE_NOWINDOWCHANGES 0x00000800
#define WINED3DCREATE_DISABLE_PSGP_THREADING 0x00002000
#define WINED3DCREATE_ENABLE_PRESENTSTATS 0x00004000
#define WINED3DCREATE_DISABLE_PRINTSCREEN 0x00008000
#define WINED3DCREATE_SCREENSAVER 0x10000000
/* VTF defines */
#define WINED3DDMAPSAMPLER 0x100
@ -1230,9 +1241,18 @@ enum wined3d_display_rotation
#define WINED3D_NO3D 0x00000002
#define WINED3D_VIDMEM_ACCOUNTING 0x00000004
#define WINED3D_PRESENT_CONVERSION 0x00000008
#define WINED3D_RESTORE_MODE_ON_ACTIVATE 0x00000010
#define WINED3D_FOCUS_MESSAGES 0x00000020
#define WINED3D_HANDLE_RESTORE 0x00000040
#define WINED3D_RESZ_CODE 0x7fa05000
#define WINED3D_CKEY_COLORSPACE 0x00000001
#define WINED3D_CKEY_DST_BLT 0x00000002
#define WINED3D_CKEY_DST_OVERLAY 0x00000004
#define WINED3D_CKEY_SRC_BLT 0x00000008
#define WINED3D_CKEY_SRC_OVERLAY 0x00000010
/* dwDDFX */
/* arithmetic stretching along y axis */
#define WINEDDBLTFX_ARITHSTRETCHY 0x00000001
@ -1283,35 +1303,6 @@ enum wined3d_display_rotation
#define WINEDDBLT_DONOTWAIT 0x08000000
#define WINEDDBLT_ALPHATEST 0x80000000
/* DDSURFACEDESC.dwFlags */
#define WINEDDSD_CAPS 0x00000001
#define WINEDDSD_HEIGHT 0x00000002
#define WINEDDSD_WIDTH 0x00000004
#define WINEDDSD_PITCH 0x00000008
#define WINEDDSD_BACKBUFFERCOUNT 0x00000020
#define WINEDDSD_ZBUFFERBITDEPTH 0x00000040
#define WINEDDSD_ALPHABITDEPTH 0x00000080
#define WINEDDSD_LPSURFACE 0x00000800
#define WINEDDSD_PIXELFORMAT 0x00001000
#define WINEDDSD_CKDESTOVERLAY 0x00002000
#define WINEDDSD_CKDESTBLT 0x00004000
#define WINEDDSD_CKSRCOVERLAY 0x00008000
#define WINEDDSD_CKSRCBLT 0x00010000
#define WINEDDSD_MIPMAPCOUNT 0x00020000
#define WINEDDSD_REFRESHRATE 0x00040000
#define WINEDDSD_LINEARSIZE 0x00080000
#define WINEDDSD_TEXTURESTAGE 0x00100000
#define WINEDDSD_FVF 0x00200000
#define WINEDDSD_SRCVBHANDLE 0x00400000
#define WINEDDSD_ALL 0x007ff9ee
/* Set/Get Colour Key Flags */
#define WINEDDCKEY_COLORSPACE 0x00000001 /* Struct is single colour space */
#define WINEDDCKEY_DESTBLT 0x00000002 /* To be used as dest for blt */
#define WINEDDCKEY_DESTOVERLAY 0x00000004 /* To be used as dest for CK overlays */
#define WINEDDCKEY_SRCBLT 0x00000008 /* To be used as src for blt */
#define WINEDDCKEY_SRCOVERLAY 0x00000010 /* To be used as src for CK overlays */
/* dwFlags for GetBltStatus */
#define WINEDDGBS_CANBLT 0x00000001
#define WINEDDGBS_ISBLTDONE 0x00000002
@ -1503,6 +1494,8 @@ enum wined3d_display_rotation
#define WINED3D_SURFACE_DISCARD 0x00000002
#define WINED3D_SURFACE_PIN_SYSMEM 0x00000004
#define WINED3D_APPEND_ALIGNED_ELEMENT 0xffffffff
struct wined3d_display_mode
{
UINT width;
@ -1679,8 +1672,8 @@ struct wined3d_clip_status
struct wined3d_vertex_element
{
enum wined3d_format_id format;
WORD input_slot;
WORD offset;
unsigned int input_slot;
unsigned int offset;
UINT output_slot; /* D3D 8 & 10 */
BYTE method;
BYTE usage;
@ -1708,6 +1701,13 @@ struct wined3d_map_desc
void *data;
};
struct wined3d_sub_resource_data
{
const void *data;
unsigned int row_pitch;
unsigned int slice_pitch;
};
struct wined3d_box
{
UINT left;
@ -1956,6 +1956,24 @@ struct wined3d_rendertarget_view_desc
} u;
};
struct wined3d_sampler_desc
{
enum wined3d_texture_address address_u;
enum wined3d_texture_address address_v;
enum wined3d_texture_address address_w;
float border_color[4];
enum wined3d_texture_filter_type mag_filter;
enum wined3d_texture_filter_type min_filter;
enum wined3d_texture_filter_type mip_filter;
float lod_bias;
float min_lod;
float max_lod;
unsigned int max_anisotropy;
BOOL compare;
enum wined3d_cmp_func comparison_func;
BOOL srgb_decode;
};
struct wined3d_shader_signature_element
{
const char *semantic_name;
@ -1970,7 +1988,14 @@ struct wined3d_shader_signature
{
UINT element_count;
struct wined3d_shader_signature_element *elements;
char *string_data;
};
struct wined3d_shader_desc
{
const DWORD *byte_code;
const struct wined3d_shader_signature *input_signature;
const struct wined3d_shader_signature *output_signature;
unsigned int max_version;
};
struct wined3d_parent_ops
@ -2407,20 +2432,18 @@ void * __cdecl wined3d_rendertarget_view_get_sub_resource_parent(const struct wi
ULONG __cdecl wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view);
void __cdecl wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent);
HRESULT __cdecl wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler);
HRESULT __cdecl wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
void *parent, struct wined3d_sampler **sampler);
ULONG __cdecl wined3d_sampler_decref(struct wined3d_sampler *sampler);
void * __cdecl wined3d_sampler_get_parent(const struct wined3d_sampler *sampler);
ULONG __cdecl wined3d_sampler_incref(struct wined3d_sampler *sampler);
HRESULT __cdecl wined3d_shader_create_gs(struct wined3d_device *device, const DWORD *byte_code,
const struct wined3d_shader_signature *output_signature, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
HRESULT __cdecl wined3d_shader_create_ps(struct wined3d_device *device, const DWORD *byte_code,
const struct wined3d_shader_signature *output_signature, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
HRESULT __cdecl wined3d_shader_create_vs(struct wined3d_device *device, const DWORD *byte_code,
const struct wined3d_shader_signature *output_signature, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
HRESULT __cdecl wined3d_shader_create_gs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
HRESULT __cdecl wined3d_shader_create_ps(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
HRESULT __cdecl wined3d_shader_create_vs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
ULONG __cdecl wined3d_shader_decref(struct wined3d_shader *shader);
HRESULT __cdecl wined3d_shader_get_byte_code(const struct wined3d_shader *shader,
void *byte_code, UINT *byte_code_size);
@ -2429,8 +2452,8 @@ ULONG __cdecl wined3d_shader_incref(struct wined3d_shader *shader);
HRESULT __cdecl wined3d_shader_set_local_constants_float(struct wined3d_shader *shader,
UINT start_idx, const float *src_data, UINT vector4f_count);
HRESULT __cdecl wined3d_shader_resource_view_create(void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_shader_resource_view **view);
HRESULT __cdecl wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view);
ULONG __cdecl wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view);
void * __cdecl wined3d_shader_resource_view_get_parent(const struct wined3d_shader_resource_view *view);
ULONG __cdecl wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view);
@ -2465,10 +2488,6 @@ HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC d
HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y);
HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_update_desc(struct wined3d_surface *surface,
UINT width, UINT height, enum wined3d_format_id format_id,
enum wined3d_multisample_type multisample_type, UINT multisample_quality,
void *mem, UINT pitch);
HRESULT __cdecl wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect,
struct wined3d_surface *dst_surface, const RECT *dst_rect, DWORD flags, const WINEDDOVERLAYFX *fx);
HRESULT __cdecl wined3d_surface_update_overlay_z_order(struct wined3d_surface *surface,
@ -2503,8 +2522,8 @@ void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, H
HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
UINT layer, const struct wined3d_box *dirty_region);
HRESULT __cdecl wined3d_texture_create(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);
UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, 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);
@ -2521,6 +2540,10 @@ HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *
HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture,
DWORD flags, const struct wined3d_color_key *color_key);
DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod);
HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture,
UINT width, UINT height, enum wined3d_format_id format_id,
enum wined3d_multisample_type multisample_type, UINT multisample_quality,
void *mem, UINT pitch);
HRESULT __cdecl wined3d_vertex_declaration_create(struct wined3d_device *device,
const struct wined3d_vertex_element *elements, UINT element_count, void *parent,
@ -2542,4 +2565,49 @@ HRESULT __cdecl wined3d_volume_map(struct wined3d_volume *volume,
void __cdecl wined3d_volume_preload(struct wined3d_volume *volume);
HRESULT __cdecl wined3d_volume_unmap(struct wined3d_volume *volume);
/* Return the integer base-2 logarithm of x. Undefined for x == 0. */
static inline unsigned int wined3d_log2i(unsigned int x)
{
#ifdef HAVE___BUILTIN_CLZ
return __builtin_clz(x) ^ 0x1f;
#else
static const unsigned int l[] =
{
~0u, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
};
unsigned int i;
return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
#endif
}
BOOL wined3d_dxt1_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h);
BOOL wined3d_dxt1_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h);
BOOL wined3d_dxt3_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h);
BOOL wined3d_dxt3_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h);
BOOL wined3d_dxt5_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h);
BOOL wined3d_dxt5_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
enum wined3d_format_id format, unsigned int w, unsigned int h);
BOOL wined3d_dxtn_supported(void);
#endif /* __WINE_WINED3D_H */

View file

@ -28,13 +28,13 @@ reactos/tools/wpp # Synced to Wine-1.7.27
The following libraries are shared with Wine.
reactos/dll/directx/wine/amstream # Synced to Wine-1.7.27
reactos/dll/directx/wine/d3d8 # Synced to Wine-1.7.27
reactos/dll/directx/wine/d3d9 # Synced to Wine-1.7.27
reactos/dll/directx/wine/d3d8 # Synced to WineStaging-1.7.37
reactos/dll/directx/wine/d3d9 # Synced to WineStaging-1.7.37
reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-1.7.37
reactos/dll/directx/wine/d3drm # Synced to WineStaging-1.7.37
reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-1.7.27
reactos/dll/directx/wine/d3dxof # Synced to WineStaging-1.7.37
reactos/dll/directx/wine/ddraw # Synced to Wine-1.7.27
reactos/dll/directx/wine/ddraw # Synced to WineStaging-1.7.37
reactos/dll/directx/wine/devenum # Synced to Wine-1.7.27
reactos/dll/directx/wine/dinput # Synced to WineStaging-1.7.37
reactos/dll/directx/wine/dinput8 # Synced to Wine-1.7.27
@ -47,7 +47,7 @@ reactos/dll/directx/wine/dxgi # Synced to Wine-1.7.27
reactos/dll/directx/wine/msdmo # Synced to Wine-1.7.27
reactos/dll/directx/wine/qedit # Synced to Wine-1.7.27
reactos/dll/directx/wine/quartz # Synced to Wine-1.7.27
reactos/dll/directx/wine/wined3d # Synced to Wine-1.7.27
reactos/dll/directx/wine/wined3d # Synced to WineStaging-1.7.37
reactos/dll/win32/activeds # Synced to Wine-1.7.27
reactos/dll/win32/actxprxy # Synced to Wine-1.7.27