diff --git a/reactos/dll/directx/wine/d3d8/device.c b/reactos/dll/directx/wine/d3d8/device.c index 7516764c8d5..22c6d1efda6 100644 --- a/reactos/dll/directx/wine/d3d8/device.c +++ b/reactos/dll/directx/wine/d3d8/device.c @@ -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; diff --git a/reactos/dll/directx/wine/d3d8/directx.c b/reactos/dll/directx/wine/d3d8/directx.c index 10b4ea0a2df..57e007628f8 100644 --- a/reactos/dll/directx/wine/d3d8/directx.c +++ b/reactos/dll/directx/wine/d3d8/directx.c @@ -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; diff --git a/reactos/dll/directx/wine/d3d8/shader.c b/reactos/dll/directx/wine/d3d8/shader.c index 7453e01799c..1b568999d43 100644 --- a/reactos/dll/directx/wine/d3d8/shader.c +++ b/reactos/dll/directx/wine/d3d8/shader.c @@ -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)) { diff --git a/reactos/dll/directx/wine/d3d8/texture.c b/reactos/dll/directx/wine/d3d8/texture.c index 76c18cf6b46..da7d49415ab 100644 --- a/reactos/dll/directx/wine/d3d8/texture.c +++ b/reactos/dll/directx/wine/d3d8/texture.c @@ -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)) { diff --git a/reactos/dll/directx/wine/d3d9/device.c b/reactos/dll/directx/wine/d3d9/device.c index ff430d5fda4..4a82ca46e0c 100644 --- a/reactos/dll/directx/wine/d3d9/device.c +++ b/reactos/dll/directx/wine/d3d9/device.c @@ -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; diff --git a/reactos/dll/directx/wine/d3d9/directx.c b/reactos/dll/directx/wine/d3d9/directx.c index 6b68838ed08..957b5204ee2 100644 --- a/reactos/dll/directx/wine/d3d9/directx.c +++ b/reactos/dll/directx/wine/d3d9/directx.c @@ -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; diff --git a/reactos/dll/directx/wine/d3d9/shader.c b/reactos/dll/directx/wine/d3d9/shader.c index 94ec8292523..59ccd2dcd1a 100644 --- a/reactos/dll/directx/wine/d3d9/shader.c +++ b/reactos/dll/directx/wine/d3d9/shader.c @@ -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); } diff --git a/reactos/dll/directx/wine/d3d9/surface.c b/reactos/dll/directx/wine/d3d9/surface.c index 4a563d3d28c..df111819ec2 100644 --- a/reactos/dll/directx/wine/d3d9/surface.c +++ b/reactos/dll/directx/wine/d3d9/surface.c @@ -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); diff --git a/reactos/dll/directx/wine/d3d9/texture.c b/reactos/dll/directx/wine/d3d9/texture.c index 182f53c9b65..4072748d2be 100644 --- a/reactos/dll/directx/wine/d3d9/texture.c +++ b/reactos/dll/directx/wine/d3d9/texture.c @@ -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)) { diff --git a/reactos/dll/directx/wine/ddraw/ddraw.c b/reactos/dll/directx/wine/ddraw/ddraw.c index 44e535d889d..8824c56c1cb 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw.c +++ b/reactos/dll/directx/wine/ddraw/ddraw.c @@ -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))) diff --git a/reactos/dll/directx/wine/ddraw/ddraw_private.h b/reactos/dll/directx/wine/ddraw/ddraw_private.h index 1ad8c2c5e22..9b73e658c62 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw_private.h +++ b/reactos/dll/directx/wine/ddraw/ddraw_private.h @@ -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, diff --git a/reactos/dll/directx/wine/ddraw/executebuffer.c b/reactos/dll/directx/wine/ddraw/executebuffer.c index c645aedb32a..028b4bd9366 100644 --- a/reactos/dll/directx/wine/ddraw/executebuffer.c +++ b/reactos/dll/directx/wine/ddraw/executebuffer.c @@ -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: diff --git a/reactos/dll/directx/wine/ddraw/main.c b/reactos/dll/directx/wine/ddraw/main.c index bac39e8d2d8..55b92821f1c 100644 --- a/reactos/dll/directx/wine/ddraw/main.c +++ b/reactos/dll/directx/wine/ddraw/main.c @@ -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 diff --git a/reactos/dll/directx/wine/ddraw/surface.c b/reactos/dll/directx/wine/ddraw/surface.c index 49db2aa84c2..60639d28ac0 100644 --- a/reactos/dll/directx/wine/ddraw/surface.c +++ b/reactos/dll/directx/wine/ddraw/surface.c @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/CMakeLists.txt b/reactos/dll/directx/wine/wined3d/CMakeLists.txt index a35703fd731..d1192c7781b 100644 --- a/reactos/dll/directx/wine/wined3d/CMakeLists.txt +++ b/reactos/dll/directx/wine/wined3d/CMakeLists.txt @@ -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 diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index d1e2a3cf35e..5620af182c0 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -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)"); diff --git a/reactos/dll/directx/wine/wined3d/buffer.c b/reactos/dll/directx/wine/wined3d/buffer.c index 810771a680d..16e28ae4f41 100644 --- a/reactos/dll/directx/wine/wined3d/buffer.c +++ b/reactos/dll/directx/wine/wined3d/buffer.c @@ -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); diff --git a/reactos/dll/directx/wine/wined3d/context.c b/reactos/dll/directx/wine/wined3d/context.c index cbb5815ef9f..c319207df5d 100644 --- a/reactos/dll/directx/wine/wined3d/context.c +++ b/reactos/dll/directx/wine/wined3d/context.c @@ -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, ×tamp_query->id)); + GL_EXTCALL(glDeleteQueries(1, ×tamp_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); diff --git a/reactos/dll/directx/wine/wined3d/cs.c b/reactos/dll/directx/wine/wined3d/cs.c index 08dbbed7f5d..720999849bb 100644 --- a/reactos/dll/directx/wine/wined3d/cs.c +++ b/reactos/dll/directx/wine/wined3d/cs.c @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index 5513a0d5e27..6fac754d96c 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -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); diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index 267ed0bc26d..20909935b60 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -23,7 +23,6 @@ #include "wined3d_private.h" #include -#include #include @@ -34,10 +33,6 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); #define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024) #define DEFAULT_REFRESH_RATE 0 -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0])) -#endif - /* The driver names reflect the lowest GPU supported * by a certain driver, so DRIVER_AMD_R300 supports * R3xx, R4xx and R5xx GPUs. */ @@ -55,6 +50,7 @@ enum wined3d_display_driver DRIVER_NVIDIA_GEFORCE2MX, DRIVER_NVIDIA_GEFORCEFX, DRIVER_NVIDIA_GEFORCE6, + DRIVER_NVIDIA_GEFORCE8, DRIVER_VMWARE, DRIVER_UNKNOWN }; @@ -113,7 +109,6 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT }, {"GL_ARB_debug_output", ARB_DEBUG_OUTPUT }, {"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT }, - {"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP }, {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE }, {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS }, {"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX }, @@ -136,6 +131,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS }, {"GL_ARB_point_sprite", ARB_POINT_SPRITE }, {"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX }, + {"GL_ARB_sampler_objects", ARB_SAMPLER_OBJECTS }, {"GL_ARB_shader_bit_encoding", ARB_SHADER_BIT_ENCODING }, {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS }, {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD }, @@ -204,7 +200,6 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA }, /* NV */ - {"GL_NV_depth_clamp", NV_DEPTH_CLAMP }, {"GL_NV_fence", NV_FENCE }, {"GL_NV_fog_distance", NV_FOG_DISTANCE }, {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM }, @@ -248,34 +243,12 @@ const struct min_lookup minMipLookup[] = {{GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR}}, /* LINEAR */ }; -const struct min_lookup minMipLookup_noFilter[] = -{ - /* NONE POINT LINEAR */ - {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */ - {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */ - {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* LINEAR */ -}; - -const struct min_lookup minMipLookup_noMip[] = -{ - /* NONE POINT LINEAR */ - {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */ - {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */ - {{GL_LINEAR, GL_LINEAR, GL_LINEAR }}, /* LINEAR */ -}; - const GLenum magLookup[] = { /* NONE POINT LINEAR */ GL_NEAREST, GL_NEAREST, GL_LINEAR, }; -const GLenum magLookup_noFilter[] = -{ - /* NONE POINT LINEAR */ - GL_NEAREST, GL_NEAREST, GL_NEAREST, -}; - struct wined3d_caps_gl_ctx { HDC dc; @@ -571,15 +544,15 @@ static void test_pbo_functionality(struct wined3d_gl_info *gl_info) gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); checkGLcall("Specifying the PBO test texture"); - GL_EXTCALL(glGenBuffersARB(1, &pbo)); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo)); - GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB)); + GL_EXTCALL(glGenBuffers(1, &pbo)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo)); + GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(pattern), pattern, GL_STREAM_DRAW)); checkGLcall("Specifying the PBO test pbo"); gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); checkGLcall("Loading the PBO test texture"); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); gl_info->gl_ops.gl.p_glFinish(); /* just to be sure */ @@ -588,7 +561,7 @@ static void test_pbo_functionality(struct wined3d_gl_info *gl_info) checkGLcall("Reading back the PBO test texture"); gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture); - GL_EXTCALL(glDeleteBuffersARB(1, &pbo)); + GL_EXTCALL(glDeleteBuffers(1, &pbo)); checkGLcall("PBO test cleanup"); if (memcmp(check, pattern, sizeof(check))) @@ -1163,9 +1136,9 @@ static const struct driver_version_information driver_version_table[] = {DRIVER_AMD_RAGE_128PRO, DRIVER_MODEL_NT5X, "ati2dvaa.dll", 13, 3279, 0}, {DRIVER_AMD_R100, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6614}, {DRIVER_AMD_R300, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6764}, - {DRIVER_AMD_R600, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 8681}, + {DRIVER_AMD_R600, DRIVER_MODEL_NT5X, "ati2dvag.dll", 17, 10, 1280}, {DRIVER_AMD_R300, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 }, - {DRIVER_AMD_R600, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 }, + {DRIVER_AMD_R600, DRIVER_MODEL_NT6X, "atiumdag.dll", 17, 10, 1280 }, /* Intel * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp @@ -1179,7 +1152,8 @@ static const struct driver_version_information driver_version_table[] = {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT6X, "igdumd32.dll", 15, 10, 1666}, /* Nvidia - * - Geforce6 and newer cards are supported by the current driver (197.x) on XP-Win7 + * - Geforce8 and newer is supported by the current 340.52 driver on XP-Win8 + * - Geforce6 and 7 support is up to 307.83 on XP-Win8 * - GeforceFX support is up to 173.x on <= XP * - Geforce2MX/3/4 up to 96.x on <= XP * - TNT/Geforce1/2 up to 71.x on <= XP @@ -1187,8 +1161,10 @@ static const struct driver_version_information driver_version_table[] = {DRIVER_NVIDIA_TNT, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 7186}, {DRIVER_NVIDIA_GEFORCE2MX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 9371}, {DRIVER_NVIDIA_GEFORCEFX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 11, 7516}, - {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT5X, "nv4_disp.dll", 15, 12, 6658}, - {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT6X, "nvd3dum.dll", 15, 12, 6658}, + {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT5X, "nv4_disp.dll", 18, 13, 783}, + {DRIVER_NVIDIA_GEFORCE8, DRIVER_MODEL_NT5X, "nv4_disp.dll", 18, 13, 4052}, + {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT6X, "nvd3dum.dll", 18, 13, 783}, + {DRIVER_NVIDIA_GEFORCE8, DRIVER_MODEL_NT6X, "nvd3dum.dll", 18, 13, 4052}, /* VMware */ {DRIVER_VMWARE, DRIVER_MODEL_NT5X, "vm3dum.dll", 14, 1, 1134}, @@ -1226,70 +1202,72 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, "NVIDIA GeForce Go 7400", DRIVER_NVIDIA_GEFORCE6, 256 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, "NVIDIA GeForce 7600 GT", DRIVER_NVIDIA_GEFORCE6, 256 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, "NVIDIA GeForce 7800 GT", DRIVER_NVIDIA_GEFORCE6, 256 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, "NVIDIA GeForce 8300 GS", DRIVER_NVIDIA_GEFORCE6, 128 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8400GS, "NVIDIA GeForce 8400 GS", DRIVER_NVIDIA_GEFORCE6, 128 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, "NVIDIA GeForce 8600 GT", DRIVER_NVIDIA_GEFORCE6, 256 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, "NVIDIA GeForce 8600M GT", DRIVER_NVIDIA_GEFORCE6, 512 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, "NVIDIA GeForce 8800 GTS", DRIVER_NVIDIA_GEFORCE6, 320 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTX, "NVIDIA GeForce 8800 GTX", DRIVER_NVIDIA_GEFORCE6, 768 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9200, "NVIDIA GeForce 9200", DRIVER_NVIDIA_GEFORCE6, 256 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9300, "NVIDIA GeForce 9300", DRIVER_NVIDIA_GEFORCE6, 256 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400M, "NVIDIA GeForce 9400M", DRIVER_NVIDIA_GEFORCE6, 256 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", DRIVER_NVIDIA_GEFORCE6, 256 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", DRIVER_NVIDIA_GEFORCE6, 256 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", DRIVER_NVIDIA_GEFORCE6, 384 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", DRIVER_NVIDIA_GEFORCE6, 512 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_210, "NVIDIA GeForce 210", DRIVER_NVIDIA_GEFORCE6, 512 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT220, "NVIDIA GeForce GT 220", DRIVER_NVIDIA_GEFORCE6, 512 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT240, "NVIDIA GeForce GT 240", DRIVER_NVIDIA_GEFORCE6, 512 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", DRIVER_NVIDIA_GEFORCE6, 896 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_315M, "NVIDIA GeForce 315M", DRIVER_NVIDIA_GEFORCE6, 512 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_320M, "NVIDIA GeForce 320M", DRIVER_NVIDIA_GEFORCE6, 256}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_410M, "NVIDIA GeForce 410M", DRIVER_NVIDIA_GEFORCE6, 512}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT320M, "NVIDIA GeForce GT 320M", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT325M, "NVIDIA GeForce GT 325M", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT330, "NVIDIA GeForce GT 330", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS350M, "NVIDIA GeForce GTS 350M", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT420, "NVIDIA GeForce GT 420", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT430, "NVIDIA GeForce GT 430", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT440, "NVIDIA GeForce GT 440", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS450, "NVIDIA GeForce GTS 450", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX460, "NVIDIA GeForce GTX 460", DRIVER_NVIDIA_GEFORCE6, 768 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX460M, "NVIDIA GeForce GTX 460M", DRIVER_NVIDIA_GEFORCE6, 1536}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX465, "NVIDIA GeForce GTX 465", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX470, "NVIDIA GeForce GTX 470", DRIVER_NVIDIA_GEFORCE6, 1280}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX480, "NVIDIA GeForce GTX 480", DRIVER_NVIDIA_GEFORCE6, 1536}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT520, "NVIDIA GeForce GT 520", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT540M, "NVIDIA GeForce GT 540M", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX550, "NVIDIA GeForce GTX 550 Ti", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT555M, "NVIDIA GeForce GT 555M", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560TI, "NVIDIA GeForce GTX 560 Ti", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560, "NVIDIA GeForce GTX 560", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX570, "NVIDIA GeForce GTX 570", DRIVER_NVIDIA_GEFORCE6, 1280}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX580, "NVIDIA GeForce GTX 580", DRIVER_NVIDIA_GEFORCE6, 1536}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT610, "NVIDIA GeForce GT 610", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630, "NVIDIA GeForce GT 630", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630M, "NVIDIA GeForce GT 630M", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT640M, "NVIDIA GeForce GT 640M", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT650M, "NVIDIA GeForce GT 650M", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650, "NVIDIA GeForce GTX 650", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650TI, "NVIDIA GeForce GTX 650 Ti", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660, "NVIDIA GeForce GTX 660", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660M, "NVIDIA GeForce GTX 660M", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660TI, "NVIDIA GeForce GTX 660 Ti", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670, "NVIDIA GeForce GTX 670", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670MX, "NVIDIA GeForce GTX 670MX", DRIVER_NVIDIA_GEFORCE6, 3072}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX680, "NVIDIA GeForce GTX 680", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX750, "NVIDIA GeForce GTX 750", DRIVER_NVIDIA_GEFORCE6, 1024}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX750TI, "NVIDIA GeForce GTX 750 Ti", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX760, "NVIDIA Geforce GTX 760", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX765M, "NVIDIA GeForce GTX 765M", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770M, "NVIDIA GeForce GTX 770M", DRIVER_NVIDIA_GEFORCE6, 3072}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770, "NVIDIA GeForce GTX 770", DRIVER_NVIDIA_GEFORCE6, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780, "NVIDIA GeForce GTX 780", DRIVER_NVIDIA_GEFORCE6, 3072}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780TI, "NVIDIA GeForce GTX 780 Ti", DRIVER_NVIDIA_GEFORCE6, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, "NVIDIA GeForce 8300 GS", DRIVER_NVIDIA_GEFORCE8, 128 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8400GS, "NVIDIA GeForce 8400 GS", DRIVER_NVIDIA_GEFORCE8, 128 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, "NVIDIA GeForce 8600 GT", DRIVER_NVIDIA_GEFORCE8, 256 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, "NVIDIA GeForce 8600M GT", DRIVER_NVIDIA_GEFORCE8, 512 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, "NVIDIA GeForce 8800 GTS", DRIVER_NVIDIA_GEFORCE8, 320 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTX, "NVIDIA GeForce 8800 GTX", DRIVER_NVIDIA_GEFORCE8, 768 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9200, "NVIDIA GeForce 9200", DRIVER_NVIDIA_GEFORCE8, 256 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9300, "NVIDIA GeForce 9300", DRIVER_NVIDIA_GEFORCE8, 256 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400M, "NVIDIA GeForce 9400M", DRIVER_NVIDIA_GEFORCE8, 256 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", DRIVER_NVIDIA_GEFORCE8, 256 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", DRIVER_NVIDIA_GEFORCE8, 256 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", DRIVER_NVIDIA_GEFORCE8, 384 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", DRIVER_NVIDIA_GEFORCE8, 512 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_210, "NVIDIA GeForce 210", DRIVER_NVIDIA_GEFORCE8, 512 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT220, "NVIDIA GeForce GT 220", DRIVER_NVIDIA_GEFORCE8, 512 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT240, "NVIDIA GeForce GT 240", DRIVER_NVIDIA_GEFORCE8, 512 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", DRIVER_NVIDIA_GEFORCE8, 896 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_315M, "NVIDIA GeForce 315M", DRIVER_NVIDIA_GEFORCE8, 512 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_320M, "NVIDIA GeForce 320M", DRIVER_NVIDIA_GEFORCE8, 256}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_410M, "NVIDIA GeForce 410M", DRIVER_NVIDIA_GEFORCE8, 512}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT320M, "NVIDIA GeForce GT 320M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT325M, "NVIDIA GeForce GT 325M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT330, "NVIDIA GeForce GT 330", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS350M, "NVIDIA GeForce GTS 350M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT420, "NVIDIA GeForce GT 420", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT430, "NVIDIA GeForce GT 430", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT440, "NVIDIA GeForce GT 440", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS450, "NVIDIA GeForce GTS 450", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX460, "NVIDIA GeForce GTX 460", DRIVER_NVIDIA_GEFORCE8, 768 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX460M, "NVIDIA GeForce GTX 460M", DRIVER_NVIDIA_GEFORCE8, 1536}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX465, "NVIDIA GeForce GTX 465", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX470, "NVIDIA GeForce GTX 470", DRIVER_NVIDIA_GEFORCE8, 1280}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX480, "NVIDIA GeForce GTX 480", DRIVER_NVIDIA_GEFORCE8, 1536}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT520, "NVIDIA GeForce GT 520", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT540M, "NVIDIA GeForce GT 540M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX550, "NVIDIA GeForce GTX 550 Ti", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT555M, "NVIDIA GeForce GT 555M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560TI, "NVIDIA GeForce GTX 560 Ti", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560, "NVIDIA GeForce GTX 560", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX570, "NVIDIA GeForce GTX 570", DRIVER_NVIDIA_GEFORCE8, 1280}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX580, "NVIDIA GeForce GTX 580", DRIVER_NVIDIA_GEFORCE8, 1536}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT610, "NVIDIA GeForce GT 610", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630, "NVIDIA GeForce GT 630", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630M, "NVIDIA GeForce GT 630M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT640M, "NVIDIA GeForce GT 640M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT650M, "NVIDIA GeForce GT 650M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650, "NVIDIA GeForce GTX 650", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650TI, "NVIDIA GeForce GTX 650 Ti", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660, "NVIDIA GeForce GTX 660", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660M, "NVIDIA GeForce GTX 660M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660TI, "NVIDIA GeForce GTX 660 Ti", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670, "NVIDIA GeForce GTX 670", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670MX, "NVIDIA GeForce GTX 670MX", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX680, "NVIDIA GeForce GTX 680", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT750M, "NVIDIA GeForce GT 750M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX750, "NVIDIA GeForce GTX 750", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX750TI, "NVIDIA GeForce GTX 750 Ti", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX760, "NVIDIA Geforce GTX 760", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX765M, "NVIDIA GeForce GTX 765M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770M, "NVIDIA GeForce GTX 770M", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770, "NVIDIA GeForce GTX 770", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780, "NVIDIA GeForce GTX 780", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780TI, "NVIDIA GeForce GTX 780 Ti", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX970, "NVIDIA GeForce GTX 970", DRIVER_NVIDIA_GEFORCE8, 4096}, /* AMD cards */ {HW_VENDOR_AMD, CARD_AMD_RAGE_128PRO, "ATI Rage Fury", DRIVER_AMD_RAGE_128PRO, 16 }, @@ -1677,47 +1655,33 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s return HW_VENDOR_NVIDIA; } -static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info); -static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info, const struct wined3d_shader_backend_ops *shader_backend_ops); - -static enum wined3d_d3d_level d3d_level_from_gl_info(const struct wined3d_gl_info *gl_info) +static enum wined3d_d3d_level d3d_level_from_caps(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps, DWORD glsl_version) { - struct shader_caps shader_caps; - struct fragment_caps fragment_caps; - const struct wined3d_shader_backend_ops *shader_backend; - const struct fragment_pipeline *fragment_pipeline; - - shader_backend = select_shader_backend(gl_info); - shader_backend->shader_get_caps(gl_info, &shader_caps); - - if (shader_caps.vs_version >= 5) + if (shader_caps->vs_version >= 5) return WINED3D_D3D_LEVEL_11; - if (shader_caps.vs_version == 4) + if (shader_caps->vs_version == 4) { /* No backed supports SM 5 at the moment */ - if (gl_info->glsl_version >= MAKEDWORD_VERSION(4, 00)) + if (glsl_version >= MAKEDWORD_VERSION(4, 00)) return WINED3D_D3D_LEVEL_11; return WINED3D_D3D_LEVEL_10; } - if (shader_caps.vs_version == 3) + if (shader_caps->vs_version == 3) { - /* Wine can not use SM 4 on mesa drivers as the necessary functionality is not exposed - * on compatibility contexts */ - if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30)) + /* Wine cannot use SM 4 on mesa drivers as the necessary functionality + * is not exposed on compatibility contexts */ + if (glsl_version >= MAKEDWORD_VERSION(1, 30)) return WINED3D_D3D_LEVEL_10; return WINED3D_D3D_LEVEL_9_SM3; } - if (shader_caps.vs_version == 2) + if (shader_caps->vs_version == 2) return WINED3D_D3D_LEVEL_9_SM2; - if (shader_caps.vs_version == 1) + if (shader_caps->vs_version == 1) return WINED3D_D3D_LEVEL_8; - fragment_pipeline = select_fragment_implementation(gl_info, shader_backend); - fragment_pipeline->get_caps(gl_info, &fragment_caps); - - if (fragment_caps.TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3) + if (fragment_caps->TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3) return WINED3D_D3D_LEVEL_7; - if (fragment_caps.MaxSimultaneousTextures > 1) + if (fragment_caps->MaxSimultaneousTextures > 1) return WINED3D_D3D_LEVEL_6; return WINED3D_D3D_LEVEL_5; @@ -1731,6 +1695,7 @@ static const struct wined3d_renderer_table cards_nvidia_binary[] = { /* Direct 3D 11 */ + {"GTX 970", CARD_NVIDIA_GEFORCE_GTX970}, /* GeForce 900 - highend */ {"GTX 780 Ti", CARD_NVIDIA_GEFORCE_GTX780TI}, /* Geforce 700 - highend */ {"GTX 780", CARD_NVIDIA_GEFORCE_GTX780}, /* Geforce 700 - highend */ {"GTX 770M", CARD_NVIDIA_GEFORCE_GTX770M}, /* Geforce 700 - midend high mobile */ @@ -1739,6 +1704,7 @@ cards_nvidia_binary[] = {"GTX 760", CARD_NVIDIA_GEFORCE_GTX760}, /* Geforce 700 - midend high */ {"GTX 750 Ti", CARD_NVIDIA_GEFORCE_GTX750TI}, /* Geforce 700 - midend */ {"GTX 750", CARD_NVIDIA_GEFORCE_GTX750}, /* Geforce 700 - midend */ + {"GT 750M", CARD_NVIDIA_GEFORCE_GT750M}, /* Geforce 700 - midend mobile */ {"GTX 680", CARD_NVIDIA_GEFORCE_GTX680}, /* Geforce 600 - highend */ {"GTX 670MX", CARD_NVIDIA_GEFORCE_GTX670MX}, /* Geforce 600 - highend */ {"GTX 670", CARD_NVIDIA_GEFORCE_GTX670}, /* Geforce 600 - midend high */ @@ -2084,6 +2050,7 @@ cards_amd_mesa[] = cards_nvidia_mesa[] = { /* Maxwell */ + {"NV124", CARD_NVIDIA_GEFORCE_GTX970}, {"NV117", CARD_NVIDIA_GEFORCE_GTX750}, /* Kepler */ {"NVF1", CARD_NVIDIA_GEFORCE_GTX780TI}, @@ -2215,12 +2182,12 @@ card_fallback_amd[] = }, card_fallback_intel[] = { - CARD_INTEL_915G, /* D3D5 */ - CARD_INTEL_915G, /* D3D6 */ - CARD_INTEL_915G, /* D3D7 */ + CARD_INTEL_845G, /* D3D5 */ + CARD_INTEL_845G, /* D3D6 */ + CARD_INTEL_845G, /* D3D7 */ CARD_INTEL_915G, /* D3D8 */ CARD_INTEL_915G, /* D3D9_SM2 */ - CARD_INTEL_915G, /* D3D9_SM3 */ + CARD_INTEL_945G, /* D3D9_SM3 */ CARD_INTEL_G45, /* D3D10 */ CARD_INTEL_IVBD, /* D3D11 */ }; @@ -2278,8 +2245,8 @@ card_vendor_table[] = }; -static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor) +static enum wined3d_pci_device wined3d_guess_card(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps, + DWORD glsl_version, const char *gl_renderer, enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor) { /* A Direct3D device object contains the PCI id (vendor + device) of the * videocard which is used for rendering. Various applications use this @@ -2332,7 +2299,7 @@ static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info * * memory can be overruled using a registry setting. */ unsigned int i; - enum wined3d_d3d_level d3d_level = d3d_level_from_gl_info(gl_info); + enum wined3d_d3d_level d3d_level = d3d_level_from_caps(shader_caps, fragment_caps, glsl_version); enum wined3d_pci_device device; for (i = 0; i < (sizeof(card_vendor_table) / sizeof(*card_vendor_table)); ++i) @@ -2450,7 +2417,543 @@ static void parse_extension_string(struct wined3d_gl_info *gl_info, const char * static void load_gl_funcs(struct wined3d_gl_info *gl_info) { #define USE_GL_FUNC(pfn) gl_info->gl_ops.ext.p_##pfn = (void *)wglGetProcAddress(#pfn); - 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_sampler_objects */ + USE_GL_FUNC(glGenSamplers) + USE_GL_FUNC(glDeleteSamplers) + USE_GL_FUNC(glIsSampler) + USE_GL_FUNC(glBindSampler) + USE_GL_FUNC(glSamplerParameteri) + USE_GL_FUNC(glSamplerParameterf) + USE_GL_FUNC(glSamplerParameteriv) + USE_GL_FUNC(glSamplerParameterfv) + USE_GL_FUNC(glSamplerParameterIiv) + USE_GL_FUNC(glSamplerParameterIuiv) + USE_GL_FUNC(glGetSamplerParameteriv) + USE_GL_FUNC(glGetSamplerParameterfv) + USE_GL_FUNC(glGetSamplerParameterIiv) + USE_GL_FUNC(glGetSamplerParameterIuiv) + /* 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(glPointParameteriNV) + 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) + + /* Newer core functions */ + USE_GL_FUNC(glActiveTexture) /* OpenGL 1.3 */ + USE_GL_FUNC(glAttachShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glBeginQuery) /* OpenGL 1.5 */ + USE_GL_FUNC(glBindAttribLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glBindBuffer) /* OpenGL 1.5 */ + USE_GL_FUNC(glBlendColor) /* OpenGL 1.4 */ + USE_GL_FUNC(glBlendEquation) /* OpenGL 1.4 */ + USE_GL_FUNC(glBlendEquationSeparate) /* OpenGL 2.0 */ + USE_GL_FUNC(glBlendFuncSeparate) /* OpenGL 1.4 */ + USE_GL_FUNC(glBufferData) /* OpenGL 1.5 */ + USE_GL_FUNC(glBufferSubData) /* OpenGL 1.5 */ + USE_GL_FUNC(glColorMaski) /* OpenGL 3.0 */ + USE_GL_FUNC(glCompileShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glCompressedTexImage2D) /* OpenGL 1.3 */ + USE_GL_FUNC(glCompressedTexImage3D) /* OpenGL 1.3 */ + USE_GL_FUNC(glCompressedTexSubImage2D) /* OpenGL 1.3 */ + USE_GL_FUNC(glCompressedTexSubImage3D) /* OpenGL 1.3 */ + USE_GL_FUNC(glCreateProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glCreateShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glDeleteBuffers) /* OpenGL 1.5 */ + USE_GL_FUNC(glDeleteProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glDeleteQueries) /* OpenGL 1.5 */ + USE_GL_FUNC(glDeleteShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glDetachShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */ + USE_GL_FUNC(glDrawBuffers) /* OpenGL 2.0 */ + USE_GL_FUNC(glDrawElementsInstanced) /* OpenGL 3.1 */ + USE_GL_FUNC(glEnableVertexAttribArray) /* OpenGL 2.0 */ + USE_GL_FUNC(glEndQuery) /* OpenGL 1.5 */ + USE_GL_FUNC(glGenBuffers) /* OpenGL 1.5 */ + USE_GL_FUNC(glGenQueries) /* OpenGL 1.5 */ + USE_GL_FUNC(glGetActiveUniform) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetAttachedShaders) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetAttribLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetBufferSubData) /* OpenGL 1.5 */ + USE_GL_FUNC(glGetCompressedTexImage) /* OpenGL 1.3 */ + USE_GL_FUNC(glGetProgramInfoLog) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetProgramiv) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetQueryiv) /* OpenGL 1.5 */ + USE_GL_FUNC(glGetQueryObjectuiv) /* OpenGL 1.5 */ + USE_GL_FUNC(glGetShaderInfoLog) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetShaderiv) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetShaderSource) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetUniformfv) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetUniformiv) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetUniformLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glLinkProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glMapBuffer) /* OpenGL 1.5 */ + USE_GL_FUNC(glPointParameteri) /* OpenGL 1.4 */ + USE_GL_FUNC(glPointParameteriv) /* OpenGL 1.4 */ + USE_GL_FUNC(glShaderSource) /* OpenGL 2.0 */ + USE_GL_FUNC(glStencilFuncSeparate) /* OpenGL 2.0 */ + USE_GL_FUNC(glStencilOpSeparate) /* OpenGL 2.0 */ + USE_GL_FUNC(glTexImage3D) /* OpenGL 1.2 */ + USE_GL_FUNC(glTexSubImage3D) /* OpenGL 1.2 */ + USE_GL_FUNC(glUniform1f) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform1fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform1i) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform1iv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform2f) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform2fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform2i) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform2iv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform3f) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform3fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform3i) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform3iv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform4f) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform4fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform4i) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform4iv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniformMatrix2fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniformMatrix3fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniformMatrix4fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUnmapBuffer) /* OpenGL 1.5 */ + USE_GL_FUNC(glUseProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glValidateProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib1f) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib1fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib2f) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib2fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib3f) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib3fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4f) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4Nsv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4Nubv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4Nusv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4sv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4ubv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttribDivisor) /* OpenGL 3.3 */ + USE_GL_FUNC(glVertexAttribPointer) /* OpenGL 2.0 */ #undef USE_GL_FUNC #ifndef USE_WIN32_OPENGL @@ -2458,6 +2961,110 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) /* note that we still need the above wglGetProcAddress calls to initialize the table */ gl_info->gl_ops.ext = ((struct opengl_funcs *)NtCurrentTeb()->glTable)->ext; #endif + +#define MAP_GL_FUNCTION(core_func, ext_func) \ + do \ + { \ + if (!gl_info->gl_ops.ext.p_##core_func) \ + gl_info->gl_ops.ext.p_##core_func = gl_info->gl_ops.ext.p_##ext_func; \ + } while (0) +#define MAP_GL_FUNCTION_CAST(core_func, ext_func) \ + do \ + { \ + if (!gl_info->gl_ops.ext.p_##core_func) \ + gl_info->gl_ops.ext.p_##core_func = (void *)gl_info->gl_ops.ext.p_##ext_func; \ + } while (0) + + MAP_GL_FUNCTION(glActiveTexture, glActiveTextureARB); + MAP_GL_FUNCTION(glAttachShader, glAttachObjectARB); + MAP_GL_FUNCTION(glBeginQuery, glBeginQueryARB); + MAP_GL_FUNCTION(glBindAttribLocation, glBindAttribLocationARB); + MAP_GL_FUNCTION(glBindBuffer, glBindBufferARB); + MAP_GL_FUNCTION(glBlendColor, glBlendColorEXT); + MAP_GL_FUNCTION(glBlendEquation, glBlendEquationEXT); + MAP_GL_FUNCTION(glBlendEquationSeparate, glBlendEquationSeparateEXT); + MAP_GL_FUNCTION(glBlendFuncSeparate, glBlendFuncSeparateEXT); + MAP_GL_FUNCTION(glBufferData, glBufferDataARB); + MAP_GL_FUNCTION(glBufferSubData, glBufferSubDataARB); + MAP_GL_FUNCTION(glColorMaski, glColorMaskIndexedEXT); + MAP_GL_FUNCTION(glCompileShader, glCompileShaderARB); + MAP_GL_FUNCTION(glCompressedTexImage2D, glCompressedTexImage2DARB); + MAP_GL_FUNCTION(glCompressedTexImage3D, glCompressedTexImage3DARB); + MAP_GL_FUNCTION(glCompressedTexSubImage2D, glCompressedTexSubImage2DARB); + MAP_GL_FUNCTION(glCompressedTexSubImage3D, glCompressedTexSubImage3DARB); + MAP_GL_FUNCTION(glCreateProgram, glCreateProgramObjectARB); + MAP_GL_FUNCTION(glCreateShader, glCreateShaderObjectARB); + MAP_GL_FUNCTION(glDeleteBuffers, glDeleteBuffersARB); + MAP_GL_FUNCTION(glDeleteProgram, glDeleteObjectARB); + MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB); + MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB); + MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB); + MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB); + MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB); + MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB); + MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB); + MAP_GL_FUNCTION(glEndQuery, glEndQueryARB); + MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB); + MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB); + MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB); + MAP_GL_FUNCTION(glGetAttachedShaders, glGetAttachedObjectsARB); + MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB); + MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB); + MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB); + MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB); + MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB); + MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB); + MAP_GL_FUNCTION(glGetQueryObjectuiv, glGetQueryObjectuivARB); + MAP_GL_FUNCTION(glGetShaderInfoLog, glGetInfoLogARB); + MAP_GL_FUNCTION(glGetShaderiv, glGetObjectParameterivARB); + MAP_GL_FUNCTION(glGetShaderSource, glGetShaderSourceARB); + MAP_GL_FUNCTION(glGetUniformfv, glGetUniformfvARB); + MAP_GL_FUNCTION(glGetUniformiv, glGetUniformivARB); + MAP_GL_FUNCTION(glGetUniformLocation, glGetUniformLocationARB); + MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB); + MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB); + MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB); + MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT); + MAP_GL_FUNCTION(glTexSubImage3D, glTexSubImage3DEXT); + MAP_GL_FUNCTION(glUniform1f, glUniform1fARB); + MAP_GL_FUNCTION(glUniform1fv, glUniform1fvARB); + MAP_GL_FUNCTION(glUniform1i, glUniform1iARB); + MAP_GL_FUNCTION(glUniform1iv, glUniform1ivARB); + MAP_GL_FUNCTION(glUniform2f, glUniform2fARB); + MAP_GL_FUNCTION(glUniform2fv, glUniform2fvARB); + MAP_GL_FUNCTION(glUniform2i, glUniform2iARB); + MAP_GL_FUNCTION(glUniform2iv, glUniform2ivARB); + MAP_GL_FUNCTION(glUniform3f, glUniform3fARB); + MAP_GL_FUNCTION(glUniform3fv, glUniform3fvARB); + MAP_GL_FUNCTION(glUniform3i, glUniform3iARB); + MAP_GL_FUNCTION(glUniform3iv, glUniform3ivARB); + MAP_GL_FUNCTION(glUniform4f, glUniform4fARB); + MAP_GL_FUNCTION(glUniform4fv, glUniform4fvARB); + MAP_GL_FUNCTION(glUniform4i, glUniform4iARB); + MAP_GL_FUNCTION(glUniform4iv, glUniform4ivARB); + MAP_GL_FUNCTION(glUniformMatrix2fv, glUniformMatrix2fvARB); + MAP_GL_FUNCTION(glUniformMatrix3fv, glUniformMatrix3fvARB); + MAP_GL_FUNCTION(glUniformMatrix4fv, glUniformMatrix4fvARB); + MAP_GL_FUNCTION(glUnmapBuffer, glUnmapBufferARB); + MAP_GL_FUNCTION(glUseProgram, glUseProgramObjectARB); + MAP_GL_FUNCTION(glValidateProgram, glValidateProgramARB); + MAP_GL_FUNCTION(glVertexAttrib1f, glVertexAttrib1fARB); + MAP_GL_FUNCTION(glVertexAttrib1fv, glVertexAttrib1fvARB); + MAP_GL_FUNCTION(glVertexAttrib2f, glVertexAttrib2fARB); + MAP_GL_FUNCTION(glVertexAttrib2fv, glVertexAttrib2fvARB); + MAP_GL_FUNCTION(glVertexAttrib3f, glVertexAttrib3fARB); + MAP_GL_FUNCTION(glVertexAttrib3fv, glVertexAttrib3fvARB); + MAP_GL_FUNCTION(glVertexAttrib4f, glVertexAttrib4fARB); + MAP_GL_FUNCTION(glVertexAttrib4fv, glVertexAttrib4fvARB); + MAP_GL_FUNCTION(glVertexAttrib4Nsv, glVertexAttrib4NsvARB); + MAP_GL_FUNCTION(glVertexAttrib4Nubv, glVertexAttrib4NubvARB); + MAP_GL_FUNCTION(glVertexAttrib4Nusv, glVertexAttrib4NusvARB); + MAP_GL_FUNCTION(glVertexAttrib4sv, glVertexAttrib4svARB); + MAP_GL_FUNCTION(glVertexAttrib4ubv, glVertexAttrib4ubvARB); + MAP_GL_FUNCTION(glVertexAttribDivisor, glVertexAttribDivisorARB); + MAP_GL_FUNCTION(glVertexAttribPointer, glVertexAttribPointerARB); +#undef MAP_GL_FUNCTION +#undef MAP_GL_FUNCTION_CAST } static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) @@ -2776,16 +3383,12 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) if (!gl_info->supported[EXT_TEXTURE3D] && gl_version >= MAKEDWORD_VERSION(1, 2)) { TRACE("GL CORE: GL_EXT_texture3D support.\n"); - gl_info->gl_ops.ext.p_glTexImage3DEXT = (void *)gl_info->gl_ops.ext.p_glTexImage3D; - gl_info->gl_ops.ext.p_glTexSubImage3DEXT = gl_info->gl_ops.ext.p_glTexSubImage3D; gl_info->supported[EXT_TEXTURE3D] = TRUE; } if (!gl_info->supported[NV_POINT_SPRITE] && gl_version >= MAKEDWORD_VERSION(1, 4)) { TRACE("GL CORE: GL_NV_point_sprite support.\n"); - gl_info->gl_ops.ext.p_glPointParameterivNV = gl_info->gl_ops.ext.p_glPointParameteriv; - gl_info->gl_ops.ext.p_glPointParameteriNV = gl_info->gl_ops.ext.p_glPointParameteri; gl_info->supported[NV_POINT_SPRITE] = TRUE; } @@ -2838,11 +3441,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) TRACE(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n"); gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE; } - if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP]) - { - TRACE(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n"); - gl_info->supported[ARB_DEPTH_CLAMP] = TRUE; - } if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA]) { TRACE(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n"); @@ -2898,7 +3496,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) { GLint counter_bits; - GL_EXTCALL(glGetQueryivARB(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB, &counter_bits)); + GL_EXTCALL(glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &counter_bits)); TRACE("Occlusion query counter has %d bits.\n", counter_bits); if (!counter_bits) gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE; @@ -2907,7 +3505,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) { GLint counter_bits; - GL_EXTCALL(glGetQueryivARB(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS_ARB, &counter_bits)); + GL_EXTCALL(glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &counter_bits)); TRACE("Timestamp query counter has %d bits.\n", counter_bits); if (!counter_bits) gl_info->supported[ARB_TIMER_QUERY] = FALSE; @@ -3029,7 +3627,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str); TRACE("Found GL_VENDOR (%s)->(0x%04x/0x%04x).\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor); - device = wined3d_guess_card(gl_info, gl_renderer_str, &gl_vendor, &card_vendor); + device = wined3d_guess_card(&shader_caps, &fragment_caps, gl_info->glsl_version, gl_renderer_str, &gl_vendor, &card_vendor); TRACE("Found (fake) card: 0x%x (vendor id), 0x%x (device id).\n", card_vendor, device); gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT; @@ -3288,78 +3886,94 @@ HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UI HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, UINT adapter_idx, const struct wined3d_display_mode *mode) { - struct wined3d_display_mode current_mode; - const struct wined3d_format *format; struct wined3d_adapter *adapter; - DEVMODEW devmode; + DEVMODEW new_mode, current_mode; RECT clip_rc; - HRESULT hr; LONG ret; + enum wined3d_format_id new_format_id; - TRACE("wined3d %p, adapter_idx %u, mode %p (%ux%u@%u %s %#x).\n", wined3d, adapter_idx, mode, - mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id), - mode->scanline_ordering); + TRACE("wined3d %p, adapter_idx %u, mode %p.\n", wined3d, adapter_idx, mode); if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - adapter = &wined3d->adapters[adapter_idx]; - format = wined3d_get_format(&adapter->gl_info, mode->format_id); - memset(&devmode, 0, sizeof(devmode)); - devmode.dmSize = sizeof(devmode); - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - devmode.dmBitsPerPel = format->byte_count * CHAR_BIT; - devmode.dmPelsWidth = mode->width; - devmode.dmPelsHeight = mode->height; - - devmode.dmDisplayFrequency = mode->refresh_rate; - if (mode->refresh_rate) - devmode.dmFields |= DM_DISPLAYFREQUENCY; - - if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN) + memset(&new_mode, 0, sizeof(new_mode)); + new_mode.dmSize = sizeof(new_mode); + memset(¤t_mode, 0, sizeof(current_mode)); + current_mode.dmSize = sizeof(current_mode); + if (mode) { - devmode.dmFields |= DM_DISPLAYFLAGS; - if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED) - devmode.u2.dmDisplayFlags |= DM_INTERLACED; + const struct wined3d_format *format; + + TRACE("mode %ux%u@%u %s %#x.\n", mode->width, mode->height, mode->refresh_rate, + debug_d3dformat(mode->format_id), mode->scanline_ordering); + + format = wined3d_get_format(&adapter->gl_info, mode->format_id); + + new_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + new_mode.dmBitsPerPel = format->byte_count * CHAR_BIT; + new_mode.dmPelsWidth = mode->width; + new_mode.dmPelsHeight = mode->height; + + new_mode.dmDisplayFrequency = mode->refresh_rate; + if (mode->refresh_rate) + new_mode.dmFields |= DM_DISPLAYFREQUENCY; + + if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN) + { + new_mode.dmFields |= DM_DISPLAYFLAGS; + if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED) + new_mode.u2.dmDisplayFlags |= DM_INTERLACED; + } + new_format_id = mode->format_id; + } + else + { + if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_REGISTRY_SETTINGS, &new_mode)) + { + ERR("Failed to read mode from registry.\n"); + return WINED3DERR_NOTAVAILABLE; + } + new_format_id = pixelformat_for_depth(new_mode.dmBitsPerPel); } /* Only change the mode if necessary. */ - if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, ¤t_mode, NULL))) + if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, ¤t_mode)) { - ERR("Failed to get current display mode, hr %#x.\n", hr); + ERR("Failed to get current display mode.\n"); } - else if (current_mode.width == mode->width - && current_mode.height == mode->height - && current_mode.format_id == mode->format_id - && (current_mode.refresh_rate == mode->refresh_rate - || !mode->refresh_rate) - && (current_mode.scanline_ordering == mode->scanline_ordering - || mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_UNKNOWN)) + else if (current_mode.dmPelsWidth == new_mode.dmPelsWidth + && current_mode.dmPelsHeight == new_mode.dmPelsHeight + && current_mode.dmBitsPerPel == new_mode.dmBitsPerPel + && (current_mode.dmDisplayFrequency == new_mode.dmDisplayFrequency + || !(new_mode.dmFields & DM_DISPLAYFREQUENCY)) + && (current_mode.u2.dmDisplayFlags == new_mode.u2.dmDisplayFlags + || !(new_mode.dmFields & DM_DISPLAYFLAGS))) { TRACE("Skipping redundant mode setting call.\n"); return WINED3D_OK; } - ret = ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); + ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL); if (ret != DISP_CHANGE_SUCCESSFUL) { - if (devmode.dmDisplayFrequency) + if (new_mode.dmFields & DM_DISPLAYFREQUENCY) { WARN("ChangeDisplaySettingsExW failed, trying without the refresh rate.\n"); - devmode.dmFields &= ~DM_DISPLAYFREQUENCY; - devmode.dmDisplayFrequency = 0; - ret = ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); + new_mode.dmFields &= ~DM_DISPLAYFREQUENCY; + new_mode.dmDisplayFrequency = 0; + ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL); } if (ret != DISP_CHANGE_SUCCESSFUL) return WINED3DERR_NOTAVAILABLE; } /* Store the new values. */ - adapter->screen_format = mode->format_id; + adapter->screen_format = new_format_id; /* And finally clip mouse to our screen. */ - SetRect(&clip_rc, 0, 0, mode->width, mode->height); + SetRect(&clip_rc, 0, 0, new_mode.dmPelsWidth, new_mode.dmPelsHeight); ClipCursor(&clip_rc); return WINED3D_OK; @@ -4432,7 +5046,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->StencilCaps |= WINED3DSTENCILCAPS_DECR | WINED3DSTENCILCAPS_INCR; } - if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL]) + if (gl_info->supported[WINED3D_GL_VERSION_2_0] || gl_info->supported[EXT_STENCIL_TWO_SIDE] + || gl_info->supported[ATI_SEPARATE_STENCIL]) { caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED; } diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index 5c041192b4e..32616201422 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -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; diff --git a/reactos/dll/directx/wine/wined3d/dxtn.c b/reactos/dll/directx/wine/wined3d/dxtn.c new file mode 100644 index 00000000000..3dd2147bd45 --- /dev/null +++ b/reactos/dll/directx/wine/wined3d/dxtn.c @@ -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_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); +} diff --git a/reactos/dll/directx/wine/wined3d/gl_compat.c b/reactos/dll/directx/wine/wined3d/gl_compat.c index 74ad048e857..70131e0517f 100644 --- a/reactos/dll/directx/wine/wined3d/gl_compat.c +++ b/reactos/dll/directx/wine/wined3d/gl_compat.c @@ -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; diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index 85d82f2c22e..e44da894dcd 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -56,6 +56,7 @@ struct glsl_sample_function { const char *name; DWORD coord_mask; + enum wined3d_data_type data_type; }; enum heap_node_op @@ -86,8 +87,8 @@ struct shader_glsl_priv { struct constant_heap vconst_heap; struct constant_heap pconst_heap; unsigned char *stack; - GLhandleARB depth_blt_program_full[tex_type_count]; - GLhandleARB depth_blt_program_masked[tex_type_count]; + GLuint depth_blt_program_full[tex_type_count]; + GLuint depth_blt_program_masked[tex_type_count]; UINT next_constant_version; const struct wined3d_vertex_pipe_ops *vertex_pipe; @@ -100,7 +101,7 @@ struct shader_glsl_priv { struct glsl_vs_program { struct list shader_entry; - GLhandleARB id; + GLuint id; GLenum vertex_color_clamp; GLint *uniform_f_locations; GLint uniform_i_locations[MAX_CONST_I]; @@ -111,13 +112,13 @@ struct glsl_vs_program struct glsl_gs_program { struct list shader_entry; - GLhandleARB id; + GLuint id; }; struct glsl_ps_program { struct list shader_entry; - GLhandleARB id; + GLuint id; GLint *uniform_f_locations; GLint uniform_i_locations[MAX_CONST_I]; GLint uniform_b_locations[MAX_CONST_B]; @@ -139,16 +140,16 @@ struct glsl_shader_prog_link struct glsl_vs_program vs; struct glsl_gs_program gs; struct glsl_ps_program ps; - GLhandleARB programId; + GLuint id; DWORD constant_update_mask; UINT constant_version; }; struct glsl_program_key { - GLhandleARB vs_id; - GLhandleARB gs_id; - GLhandleARB ps_id; + GLuint vs_id; + GLuint gs_id; + GLuint ps_id; }; struct shader_glsl_ctx_priv { @@ -166,18 +167,18 @@ struct glsl_ps_compiled_shader { struct ps_compile_args args; struct ps_np2fixup_info np2fixup; - GLhandleARB prgId; + GLuint id; }; struct glsl_vs_compiled_shader { struct vs_compile_args args; - GLhandleARB prgId; + GLuint id; }; struct glsl_gs_compiled_shader { - GLhandleARB id; + GLuint id; }; struct glsl_shader_private @@ -194,14 +195,14 @@ struct glsl_shader_private struct glsl_ffp_vertex_shader { struct wined3d_ffp_vs_desc desc; - GLhandleARB id; + GLuint id; struct list linked_programs; }; struct glsl_ffp_fragment_shader { struct ffp_frag_desc entry; - GLhandleARB id; + GLuint id; struct list linked_programs; }; @@ -216,9 +217,9 @@ static const char *debug_gl_shader_type(GLenum type) switch (type) { #define WINED3D_TO_STR(u) case u: return #u - WINED3D_TO_STR(GL_VERTEX_SHADER_ARB); - WINED3D_TO_STR(GL_GEOMETRY_SHADER_ARB); - WINED3D_TO_STR(GL_FRAGMENT_SHADER_ARB); + WINED3D_TO_STR(GL_VERTEX_SHADER); + WINED3D_TO_STR(GL_GEOMETRY_SHADER); + WINED3D_TO_STR(GL_FRAGMENT_SHADER); #undef WINED3D_TO_STR default: return wine_dbg_sprintf("UNKNOWN(%#x)", type); @@ -275,80 +276,84 @@ static char *get_info_log_line(char **ptr) } /* Context activation is done by the caller. */ -static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleARB obj) +static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program) { - int infologLength = 0; - char *infoLog; + int length = 0; + char *log; if (!WARN_ON(d3d_shader) && !FIXME_ON(d3d_shader)) return; - GL_EXTCALL(glGetObjectParameterivARB(obj, - GL_OBJECT_INFO_LOG_LENGTH_ARB, - &infologLength)); + if (program) + GL_EXTCALL(glGetProgramiv(id, GL_INFO_LOG_LENGTH, &length)); + else + GL_EXTCALL(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length)); /* A size of 1 is just a null-terminated string, so the log should be bigger than * that if there are errors. */ - if (infologLength > 1) + if (length > 1) { char *ptr, *line; - infoLog = HeapAlloc(GetProcessHeap(), 0, infologLength); + log = HeapAlloc(GetProcessHeap(), 0, length); /* The info log is supposed to be zero-terminated, but at least some * versions of fglrx don't terminate the string properly. The reported * length does include the terminator, so explicitly set it to zero * here. */ - infoLog[infologLength - 1] = 0; - GL_EXTCALL(glGetInfoLogARB(obj, infologLength, NULL, infoLog)); + log[length - 1] = 0; + if (program) + GL_EXTCALL(glGetProgramInfoLog(id, length, NULL, log)); + else + GL_EXTCALL(glGetShaderInfoLog(id, length, NULL, log)); - ptr = infoLog; + ptr = log; if (gl_info->quirks & WINED3D_QUIRK_INFO_LOG_SPAM) { - WARN("Info log received from GLSL shader #%u:\n", obj); + WARN("Info log received from GLSL shader #%u:\n", id); while ((line = get_info_log_line(&ptr))) WARN(" %s\n", line); } else { - FIXME("Info log received from GLSL shader #%u:\n", obj); + FIXME("Info log received from GLSL shader #%u:\n", id); while ((line = get_info_log_line(&ptr))) FIXME(" %s\n", line); } - HeapFree(GetProcessHeap(), 0, infoLog); + HeapFree(GetProcessHeap(), 0, log); } } /* Context activation is done by the caller. */ -static void shader_glsl_compile(const struct wined3d_gl_info *gl_info, GLhandleARB shader, const char *src) +static void shader_glsl_compile(const struct wined3d_gl_info *gl_info, GLuint shader, const char *src) { TRACE("Compiling shader object %u.\n", shader); - GL_EXTCALL(glShaderSourceARB(shader, 1, &src, NULL)); - checkGLcall("glShaderSourceARB"); - GL_EXTCALL(glCompileShaderARB(shader)); - checkGLcall("glCompileShaderARB"); - print_glsl_info_log(gl_info, shader); + GL_EXTCALL(glShaderSource(shader, 1, &src, NULL)); + checkGLcall("glShaderSource"); + GL_EXTCALL(glCompileShader(shader)); + checkGLcall("glCompileShader"); + print_glsl_info_log(gl_info, shader, FALSE); } /* Context activation is done by the caller. */ -static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLhandleARB program) +static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLuint program) { - GLint i, object_count, source_size = -1; - GLhandleARB *objects; + GLint i, shader_count, source_size = -1; + GLuint *shaders; char *source = NULL; - GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_ATTACHED_OBJECTS_ARB, &object_count)); - objects = HeapAlloc(GetProcessHeap(), 0, object_count * sizeof(*objects)); - if (!objects) + GL_EXTCALL(glGetProgramiv(program, GL_ATTACHED_SHADERS, &shader_count)); + shaders = HeapAlloc(GetProcessHeap(), 0, shader_count * sizeof(*shaders)); + if (!shaders) { - ERR("Failed to allocate object array memory.\n"); + ERR("Failed to allocate shader array memory.\n"); return; } - GL_EXTCALL(glGetAttachedObjectsARB(program, object_count, NULL, objects)); - for (i = 0; i < object_count; ++i) + GL_EXTCALL(glGetAttachedShaders(program, shader_count, NULL, shaders)); + for (i = 0; i < shader_count; ++i) { char *ptr, *line; GLint tmp; - GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &tmp)); + GL_EXTCALL(glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &tmp)); if (source_size < tmp) { @@ -358,100 +363,92 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf if (!source) { ERR("Failed to allocate %d bytes for shader source.\n", tmp); - HeapFree(GetProcessHeap(), 0, objects); + HeapFree(GetProcessHeap(), 0, shaders); return; } source_size = tmp; } - FIXME("Object %u:\n", objects[i]); - GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SUBTYPE_ARB, &tmp)); - FIXME(" GL_OBJECT_SUBTYPE_ARB: %s.\n", debug_gl_shader_type(tmp)); - GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_COMPILE_STATUS_ARB, &tmp)); - FIXME(" GL_OBJECT_COMPILE_STATUS_ARB: %d.\n", tmp); + FIXME("Shader %u:\n", shaders[i]); + GL_EXTCALL(glGetShaderiv(shaders[i], GL_SHADER_TYPE, &tmp)); + FIXME(" GL_SHADER_TYPE: %s.\n", debug_gl_shader_type(tmp)); + GL_EXTCALL(glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &tmp)); + FIXME(" GL_COMPILE_STATUS: %d.\n", tmp); FIXME("\n"); ptr = source; - GL_EXTCALL(glGetShaderSourceARB(objects[i], source_size, NULL, source)); + GL_EXTCALL(glGetShaderSource(shaders[i], source_size, NULL, source)); while ((line = get_info_log_line(&ptr))) FIXME(" %s\n", line); FIXME("\n"); } HeapFree(GetProcessHeap(), 0, source); - HeapFree(GetProcessHeap(), 0, objects); + HeapFree(GetProcessHeap(), 0, shaders); } /* Context activation is done by the caller. */ -static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLhandleARB program) +static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program) { GLint tmp; - if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader)) return; + if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader)) + return; - GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_TYPE_ARB, &tmp)); - if (tmp == GL_PROGRAM_OBJECT_ARB) + GL_EXTCALL(glGetProgramiv(program, GL_LINK_STATUS, &tmp)); + if (!tmp) { - GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &tmp)); - if (!tmp) + FIXME("Program %u link status invalid.\n", program); + shader_glsl_dump_program_source(gl_info, program); + } + + print_glsl_info_log(gl_info, program, TRUE); +} + +/* Context activation is done by the caller. */ +static void shader_glsl_load_samplers(const struct wined3d_gl_info *gl_info, + const DWORD *tex_unit_map, GLuint program_id) +{ + unsigned int mapped_unit; + char sampler_name[20]; + const char *prefix; + unsigned int i, j; + GLint name_loc; + + static const struct + { + enum wined3d_shader_type type; + unsigned int base_idx; + unsigned int count; + } + sampler_info[] = + { + {WINED3D_SHADER_TYPE_PIXEL, 0, MAX_FRAGMENT_SAMPLERS}, + {WINED3D_SHADER_TYPE_VERTEX, MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS}, + }; + + for (i = 0; i < ARRAY_SIZE(sampler_info); ++i) + { + prefix = shader_glsl_get_prefix(sampler_info[i].type); + + for (j = 0; j < sampler_info[i].count; ++j) { - FIXME("Program %u link status invalid.\n", program); - shader_glsl_dump_program_source(gl_info, program); - } - } + snprintf(sampler_name, sizeof(sampler_name), "%s_sampler%u", prefix, j); + name_loc = GL_EXTCALL(glGetUniformLocation(program_id, sampler_name)); + if (name_loc == -1) + continue; - print_glsl_info_log(gl_info, program); -} - -/* Context activation is done by the caller. */ -static void shader_glsl_load_psamplers(const struct wined3d_gl_info *gl_info, - const DWORD *tex_unit_map, GLhandleARB programId) -{ - GLint name_loc; - char sampler_name[20]; - unsigned int i; - - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) - { - snprintf(sampler_name, sizeof(sampler_name), "ps_sampler%u", i); - name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name)); - if (name_loc != -1) { - DWORD mapped_unit = tex_unit_map[i]; - if (mapped_unit != WINED3D_UNMAPPED_STAGE && mapped_unit < gl_info->limits.fragment_samplers) + mapped_unit = tex_unit_map[sampler_info[i].base_idx + j]; + if (mapped_unit == WINED3D_UNMAPPED_STAGE || mapped_unit >= gl_info->limits.combined_samplers) { - TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit); - GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit)); - checkGLcall("glUniform1iARB"); - } else { - ERR("Trying to load sampler %s on unsupported unit %d\n", sampler_name, mapped_unit); - } - } - } -} - -/* Context activation is done by the caller. */ -static void shader_glsl_load_vsamplers(const struct wined3d_gl_info *gl_info, - const DWORD *tex_unit_map, GLhandleARB programId) -{ - GLint name_loc; - char sampler_name[20]; - unsigned int i; - - for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) - { - snprintf(sampler_name, sizeof(sampler_name), "vs_sampler%u", i); - name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name)); - if (name_loc != -1) { - DWORD mapped_unit = tex_unit_map[MAX_FRAGMENT_SAMPLERS + i]; - if (mapped_unit != WINED3D_UNMAPPED_STAGE && mapped_unit < gl_info->limits.combined_samplers) - { - TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit); - GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit)); - checkGLcall("glUniform1iARB"); - } else { - ERR("Trying to load sampler %s on unsupported unit %d\n", sampler_name, mapped_unit); + ERR("Trying to load sampler %s on unsupported unit %u.\n", sampler_name, mapped_unit); + continue; } + + TRACE("Loading sampler %s on unit %u.\n", sampler_name, mapped_unit); + GL_EXTCALL(glUniform1i(name_loc, mapped_unit)); } } + checkGLcall("glUniform1i"); } /* Context activation is done by the caller. */ @@ -524,7 +521,7 @@ static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, con } } if (start <= end) - GL_EXTCALL(glUniform4fvARB(constant_locations[start], end - start + 1, &constants[start * 4])); + GL_EXTCALL(glUniform4fv(constant_locations[start], end - start + 1, &constants[start * 4])); checkGLcall("walk_constant_heap()"); } @@ -540,7 +537,7 @@ static inline void apply_clamped_constant(const struct wined3d_gl_info *gl_info, clamped_constant[2] = data[2] < -1.0f ? -1.0f : data[2] > 1.0f ? 1.0f : data[2]; clamped_constant[3] = data[3] < -1.0f ? -1.0f : data[3] > 1.0f ? 1.0f : data[3]; - GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant)); + GL_EXTCALL(glUniform4fv(location, 1, clamped_constant)); } /* Context activation is done by the caller. */ @@ -624,9 +621,9 @@ static void shader_glsl_load_constantsF(const struct wined3d_shader *shader, con /* Immediate constants are clamped to [-1;1] at shader creation time if needed */ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) { - GL_EXTCALL(glUniform4fvARB(constant_locations[lconst->idx], 1, (const GLfloat *)lconst->value)); + GL_EXTCALL(glUniform4fv(constant_locations[lconst->idx], 1, (const GLfloat *)lconst->value)); } - checkGLcall("glUniform4fvARB()"); + checkGLcall("glUniform4fv()"); } /* Context activation is done by the caller. */ @@ -641,7 +638,7 @@ static void shader_glsl_load_constantsI(const struct wined3d_shader *shader, con if (!(constants_set & 1)) continue; /* We found this uniform name in the program - go ahead and send the data */ - GL_EXTCALL(glUniform4ivARB(locations[i], 1, &constants[i*4])); + GL_EXTCALL(glUniform4iv(locations[i], 1, &constants[i * 4])); } /* Load immediate constants */ @@ -653,10 +650,10 @@ static void shader_glsl_load_constantsI(const struct wined3d_shader *shader, con const GLint *values = (const GLint *)lconst->value; /* We found this uniform name in the program - go ahead and send the data */ - GL_EXTCALL(glUniform4ivARB(locations[idx], 1, values)); + GL_EXTCALL(glUniform4iv(locations[idx], 1, values)); ptr = list_next(&shader->constantsI, ptr); } - checkGLcall("glUniform4ivARB()"); + checkGLcall("glUniform4iv()"); } /* Context activation is done by the caller. */ @@ -670,7 +667,7 @@ static void shader_glsl_load_constantsB(const struct wined3d_shader *shader, con { if (!(constants_set & 1)) continue; - GL_EXTCALL(glUniform1ivARB(locations[i], 1, &constants[i])); + GL_EXTCALL(glUniform1iv(locations[i], 1, &constants[i])); } /* Load immediate constants */ @@ -681,10 +678,10 @@ static void shader_glsl_load_constantsB(const struct wined3d_shader *shader, con unsigned int idx = lconst->idx; const GLint *values = (const GLint *)lconst->value; - GL_EXTCALL(glUniform1ivARB(locations[idx], 1, values)); + GL_EXTCALL(glUniform1iv(locations[idx], 1, values)); ptr = list_next(&shader->constantsB, ptr); } - checkGLcall("glUniform1ivARB()"); + checkGLcall("glUniform1iv()"); } static void reset_program_constant_version(struct wine_rb_entry *entry, void *context) @@ -724,7 +721,7 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps } } - GL_EXTCALL(glUniform4fvARB(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, np2fixup_constants)); + GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, np2fixup_constants)); } /* Context activation is done by the caller (state handler). */ @@ -765,8 +762,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_VS_POS_FIXUP) { shader_get_position_fixup(context, state, position_fixup); - GL_EXTCALL(glUniform4fvARB(prog->vs.pos_fixup_location, 1, position_fixup)); - checkGLcall("glUniform4fvARB"); + GL_EXTCALL(glUniform4fv(prog->vs.pos_fixup_location, 1, position_fixup)); + checkGLcall("glUniform4fv"); } if (update_mask & WINED3D_SHADER_CONST_PS_F) @@ -788,14 +785,14 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (prog->ps.bumpenv_mat_location[i] == -1) continue; - GL_EXTCALL(glUniformMatrix2fvARB(prog->ps.bumpenv_mat_location[i], 1, 0, + GL_EXTCALL(glUniformMatrix2fv(prog->ps.bumpenv_mat_location[i], 1, 0, (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00])); if (prog->ps.bumpenv_lum_scale_location[i] != -1) { - GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_scale_location[i], 1, + GL_EXTCALL(glUniform1fv(prog->ps.bumpenv_lum_scale_location[i], 1, (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE])); - GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_offset_location[i], 1, + GL_EXTCALL(glUniform1fv(prog->ps.bumpenv_lum_offset_location[i], 1, (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET])); } } @@ -816,7 +813,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context correction_params[0] = (float) context->current_rt->resource.height; correction_params[1] = -1.0f; } - GL_EXTCALL(glUniform4fvARB(prog->ps.ycorrection_location, 1, correction_params)); + GL_EXTCALL(glUniform4fv(prog->ps.ycorrection_location, 1, correction_params)); } if (update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP) @@ -829,13 +826,13 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (prog->ps.tex_factor_location != -1) { D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col); - GL_EXTCALL(glUniform4fvARB(prog->ps.tex_factor_location, 1, col)); + GL_EXTCALL(glUniform4fv(prog->ps.tex_factor_location, 1, col)); } if (state->render_states[WINED3D_RS_SPECULARENABLE]) - GL_EXTCALL(glUniform4fARB(prog->ps.specular_enable_location, 1.0f, 1.0f, 1.0f, 0.0f)); + GL_EXTCALL(glUniform4f(prog->ps.specular_enable_location, 1.0f, 1.0f, 1.0f, 0.0f)); else - GL_EXTCALL(glUniform4fARB(prog->ps.specular_enable_location, 0.0f, 0.0f, 0.0f, 0.0f)); + GL_EXTCALL(glUniform4f(prog->ps.specular_enable_location, 0.0f, 0.0f, 0.0f, 0.0f)); for (i = 0; i < MAX_TEXTURES; ++i) { @@ -843,7 +840,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context continue; D3DCOLORTOGLFLOAT4(state->texture_states[i][WINED3D_TSS_CONSTANT], col); - GL_EXTCALL(glUniform4fvARB(prog->ps.tss_constant_location[i], 1, col)); + GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, col)); } checkGLcall("fixed function uniforms"); @@ -962,7 +959,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } /* Declare the constants (aka uniforms) */ - if (shader->limits.constant_float > 0) + if (shader->limits->constant_float > 0) { unsigned max_constantsF; @@ -1016,7 +1013,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont /* Set by driver quirks in directx.c */ max_constantsF -= gl_info->reserved_glsl_constants; - if (max_constantsF < shader->limits.constant_float) + if (max_constantsF < shader->limits->constant_float) { static unsigned int once; @@ -1032,18 +1029,18 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont max_constantsF = gl_info->limits.glsl_vs_float_constants; } } - max_constantsF = min(shader->limits.constant_float, max_constantsF); + max_constantsF = min(shader->limits->constant_float, max_constantsF); shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF); } /* Always declare the full set of constants, the compiler can remove the * unused ones because d3d doesn't (yet) support indirect int and bool * constant addressing. This avoids problems if the app uses e.g. i0 and i9. */ - if (shader->limits.constant_int > 0 && reg_maps->integer_constants) - shader_addline(buffer, "uniform ivec4 %s_i[%u];\n", prefix, shader->limits.constant_int); + if (shader->limits->constant_int > 0 && reg_maps->integer_constants) + shader_addline(buffer, "uniform ivec4 %s_i[%u];\n", prefix, shader->limits->constant_int); - if (shader->limits.constant_bool > 0 && reg_maps->boolean_constants) - shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits.constant_bool); + if (shader->limits->constant_bool > 0 && reg_maps->boolean_constants) + shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits->constant_bool); for (i = 0; i < WINED3D_MAX_CBS; ++i) { @@ -1053,55 +1050,68 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } /* Declare texture samplers */ - for (i = 0; i < shader->limits.sampler; ++i) + for (i = 0; i < reg_maps->sampler_map.count; ++i) { - if (reg_maps->sampler_type[i]) - { - BOOL shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << i)); - BOOL tex_rect; + struct wined3d_shader_sampler_map_entry *entry; + BOOL shadow_sampler, tex_rect; + const char *sampler_type; - switch (reg_maps->sampler_type[i]) - { - case WINED3DSTT_1D: - if (shadow_sampler) - shader_addline(buffer, "uniform sampler1DShadow %s_sampler%u;\n", prefix, i); - else - shader_addline(buffer, "uniform sampler1D %s_sampler%u;\n", prefix, i); - break; - case WINED3DSTT_2D: - tex_rect = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->np2_fixup & (1 << i)); - tex_rect = tex_rect && gl_info->supported[ARB_TEXTURE_RECTANGLE]; - if (shadow_sampler) - { - if (tex_rect) - shader_addline(buffer, "uniform sampler2DRectShadow %s_sampler%u;\n", prefix, i); - else - shader_addline(buffer, "uniform sampler2DShadow %s_sampler%u;\n", prefix, i); - } - else - { - if (tex_rect) - shader_addline(buffer, "uniform sampler2DRect %s_sampler%u;\n", prefix, i); - else - shader_addline(buffer, "uniform sampler2D %s_sampler%u;\n", prefix, i); - } - break; - case WINED3DSTT_CUBE: - if (shadow_sampler) - FIXME("Unsupported Cube shadow sampler.\n"); - shader_addline(buffer, "uniform samplerCube %s_sampler%u;\n", prefix, i); - break; - case WINED3DSTT_VOLUME: - if (shadow_sampler) - FIXME("Unsupported 3D shadow sampler.\n"); - shader_addline(buffer, "uniform sampler3D %s_sampler%u;\n", prefix, i); - break; - default: - shader_addline(buffer, "uniform unsupported_sampler %s_sampler%u;\n", prefix, i); - FIXME("Unrecognized sampler type: %#x\n", reg_maps->sampler_type[i]); - break; - } + entry = ®_maps->sampler_map.entries[i]; + + if (entry->resource_idx >= ARRAY_SIZE(reg_maps->resource_info)) + { + ERR("Invalid resource index %u.\n", entry->resource_idx); + continue; } + + shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << entry->sampler_idx)); + switch (reg_maps->resource_info[entry->resource_idx].type) + { + case WINED3D_SHADER_RESOURCE_TEXTURE_1D: + if (shadow_sampler) + sampler_type = "sampler1DShadow"; + else + sampler_type = "sampler1D"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_2D: + tex_rect = version->type == WINED3D_SHADER_TYPE_PIXEL + && (ps_args->np2_fixup & (1 << entry->resource_idx)) + && gl_info->supported[ARB_TEXTURE_RECTANGLE]; + if (shadow_sampler) + { + if (tex_rect) + sampler_type = "sampler2DRectShadow"; + else + sampler_type = "sampler2DShadow"; + } + else + { + if (tex_rect) + sampler_type = "sampler2DRect"; + else + sampler_type = "sampler2D"; + } + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_3D: + if (shadow_sampler) + FIXME("Unsupported 3D shadow sampler.\n"); + sampler_type = "sampler3D"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + if (shadow_sampler) + FIXME("Unsupported Cube shadow sampler.\n"); + sampler_type = "samplerCube"; + break; + + default: + sampler_type = "unsupported_sampler"; + FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[i].type); + break; + } + shader_addline(buffer, "uniform %s %s_sampler%u;\n", sampler_type, prefix, entry->bind_idx); } /* Declare uniforms for NP2 texcoord fixup: @@ -1119,19 +1129,18 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont * samplerNP2Fixup stores texture dimensions and is updated through * shader_glsl_load_np2fixup_constants when the sampler changes. */ - for (i = 0; i < shader->limits.sampler; ++i) + for (i = 0; i < shader->limits->sampler; ++i) { - if (reg_maps->sampler_type[i]) + if (!reg_maps->resource_info[i].type || !(ps_args->np2_fixup & (1 << i))) + continue; + + if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D) { - if (!(ps_args->np2_fixup & (1 << i))) continue; - - if (WINED3DSTT_2D != reg_maps->sampler_type[i]) { - FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n"); - continue; - } - - fixup->idx[i] = cur++; + FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n"); + continue; } + + fixup->idx[i] = cur++; } fixup->num_consts = (cur + 1) >> 1; @@ -1161,27 +1170,21 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } shader_addline(buffer, "uniform vec4 posFixup;\n"); - shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits.packed_output); + shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits->packed_output); } else if (version->type == WINED3D_SHADER_TYPE_GEOMETRY) { - shader_addline(buffer, "varying in vec4 gs_in[][%u];\n", shader->limits.packed_input); + shader_addline(buffer, "varying in vec4 gs_in[][%u];\n", shader->limits->packed_input); } else if (version->type == WINED3D_SHADER_TYPE_PIXEL) { if (version->major >= 3) { - UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits.packed_input); + UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); if (use_vs(state)) - shader_addline(buffer, "varying vec4 %s_in[%u];\n", prefix, in_count); - else - /* TODO: Write a replacement shader for the fixed function - * vertex pipeline, so this isn't needed. For fixed function - * vertex processing + 3.0 pixel shader we need a separate - * function in the pixel shader that reads the fixed function - * color into the packed input registers. */ - shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); + shader_addline(buffer, "varying vec4 %s_link[%u];\n", prefix, in_count); + shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); } for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i) @@ -1212,7 +1215,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } if (reg_maps->vpos || reg_maps->usesdsy) { - if (shader->limits.constant_float + extra_constants_needed + if (shader->limits->constant_float + extra_constants_needed + 1 < gl_info->limits.glsl_ps_float_constants) { shader_addline(buffer, "uniform vec4 ycorrection;\n"); @@ -1241,8 +1244,8 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } /* Declare output register temporaries */ - if (shader->limits.packed_output) - shader_addline(buffer, "vec4 %s_out[%u];\n", prefix, shader->limits.packed_output); + if (shader->limits->packed_output) + shader_addline(buffer, "vec4 %s_out[%u];\n", prefix, shader->limits->packed_output); /* Declare temporary variables */ for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i) @@ -1746,28 +1749,28 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i } else { - char param_str[200]; - - shader_glsl_gen_modifier(wined3d_src->modifiers, glsl_src->reg_name, swizzle_str, param_str); + char reg_name[200]; switch (wined3d_src->reg.data_type) { case WINED3D_DATA_FLOAT: - sprintf(glsl_src->param_str, "%s", param_str); + sprintf(reg_name, "%s", glsl_src->reg_name); break; case WINED3D_DATA_INT: - sprintf(glsl_src->param_str, "floatBitsToInt(%s)", param_str); + sprintf(reg_name, "floatBitsToInt(%s)", glsl_src->reg_name); break; case WINED3D_DATA_RESOURCE: case WINED3D_DATA_SAMPLER: case WINED3D_DATA_UINT: - sprintf(glsl_src->param_str, "floatBitsToUint(%s)", param_str); + sprintf(reg_name, "floatBitsToUint(%s)", glsl_src->reg_name); break; default: FIXME("Unhandled data type %#x.\n", wined3d_src->reg.data_type); - sprintf(glsl_src->param_str, "%s", param_str); + sprintf(reg_name, "%s", glsl_src->reg_name); break; } + + shader_glsl_gen_modifier(wined3d_src->modifiers, reg_name, swizzle_str, glsl_src->param_str); } } @@ -1788,14 +1791,15 @@ static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction * /* Append the destination part of the instruction to the buffer, return the effective write mask */ static DWORD shader_glsl_append_dst_ext(struct wined3d_shader_buffer *buffer, - const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst) + const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst, + enum wined3d_data_type data_type) { struct glsl_dst_param glsl_dst; DWORD mask; if ((mask = shader_glsl_add_dst_param(ins, dst, &glsl_dst))) { - switch (dst->reg.data_type) + switch (data_type) { case WINED3D_DATA_FLOAT: shader_addline(buffer, "%s%s = %s(", @@ -1812,7 +1816,7 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_shader_buffer *buffer, glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]); break; default: - FIXME("Unhandled data type %#x.\n", dst->reg.data_type); + FIXME("Unhandled data type %#x.\n", data_type); shader_addline(buffer, "%s%s = %s(", glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]); break; @@ -1825,7 +1829,7 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_shader_buffer *buffer, /* Append the destination part of the instruction to the buffer, return the effective write mask */ static DWORD shader_glsl_append_dst(struct wined3d_shader_buffer *buffer, const struct wined3d_shader_instruction *ins) { - return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]); + return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type); } /** Process GLSL instruction modifiers */ @@ -1876,20 +1880,23 @@ static const char *shader_glsl_get_rel_op(enum wined3d_shader_rel_op op) } static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx, - DWORD sampler_idx, DWORD flags, struct glsl_sample_function *sample_function) + DWORD resource_idx, DWORD flags, struct glsl_sample_function *sample_function) { - enum wined3d_sampler_texture_type sampler_type = ctx->reg_maps->sampler_type[sampler_idx]; + enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type; const struct wined3d_gl_info *gl_info = ctx->gl_info; BOOL shadow = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL - && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << sampler_idx)); + && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << resource_idx)); BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; BOOL texrect = flags & WINED3D_GLSL_SAMPLE_NPOT && gl_info->supported[ARB_TEXTURE_RECTANGLE]; BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD; BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD; + sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type; + /* Note that there's no such thing as a projected cube texture. */ - switch(sampler_type) { - case WINED3DSTT_1D: + switch (resource_type) + { + case WINED3D_SHADER_RESOURCE_TEXTURE_1D: if (shadow) { if (lod) @@ -1940,7 +1947,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context } break; - case WINED3DSTT_2D: + case WINED3D_SHADER_RESOURCE_TEXTURE_2D: if (shadow) { if (texrect) @@ -2043,40 +2050,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context } break; - case WINED3DSTT_CUBE: - if (shadow) - { - FIXME("Unsupported Cube shadow function.\n"); - sample_function->name = "unsupportedCubeShadow"; - sample_function->coord_mask = 0; - } - else - { - if (lod) - { - sample_function->name = "textureCubeLod"; - } - else if (grad) - { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = "textureCubeGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = "textureCubeGradARB"; - else - { - FIXME("Unsupported Cube grad function.\n"); - sample_function->name = "unsupportedCubeGrad"; - } - } - else - { - sample_function->name = "textureCube"; - } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; - } - break; - - case WINED3DSTT_VOLUME: + case WINED3D_SHADER_RESOURCE_TEXTURE_3D: if (shadow) { FIXME("Unsupported 3D shadow function.\n"); @@ -2109,10 +2083,43 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context } break; + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + if (shadow) + { + FIXME("Unsupported Cube shadow function.\n"); + sample_function->name = "unsupportedCubeShadow"; + sample_function->coord_mask = 0; + } + else + { + if (lod) + { + sample_function->name = "textureCubeLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = "textureCubeGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = "textureCubeGradARB"; + else + { + FIXME("Unsupported Cube grad function.\n"); + sample_function->name = "unsupportedCubeGrad"; + } + } + else + { + sample_function->name = "textureCube"; + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; + } + break; + default: sample_function->name = ""; sample_function->coord_mask = 0; - FIXME("Unrecognized sampler type: %#x;\n", sampler_type); + FIXME("Unhandled resource type %#x.\n", resource_type); break; } } @@ -2252,7 +2259,7 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s fixup = COLOR_FIXUP_IDENTITY; /* FIXME: Vshader color fixup */ } - shader_glsl_append_dst(ins->ctx->buffer, ins); + shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], sample_function->data_type); shader_addline(ins->ctx->buffer, "%s(%s_sampler%u, ", sample_function->name, shader_glsl_get_prefix(version->type), sampler); @@ -2303,6 +2310,7 @@ static void shader_glsl_binop(const struct wined3d_shader_instruction *ins) case WINED3DSIH_IADD: op = "+"; break; case WINED3DSIH_ISHL: op = "<<"; break; case WINED3DSIH_MUL: op = "*"; break; + case WINED3DSIH_OR: op = "|"; break; case WINED3DSIH_SUB: op = "-"; break; case WINED3DSIH_USHR: op = ">>"; break; case WINED3DSIH_XOR: op = "^"; break; @@ -2339,7 +2347,9 @@ static void shader_glsl_relop(const struct wined3d_shader_instruction *ins) case WINED3DSIH_EQ: op = "equal"; break; case WINED3DSIH_GE: op = "greaterThanEqual"; break; case WINED3DSIH_IGE: op = "greaterThanEqual"; break; + case WINED3DSIH_UGE: op = "greaterThanEqual"; break; case WINED3DSIH_LT: op = "lessThan"; break; + case WINED3DSIH_NE: op = "notEqual"; break; default: op = ""; ERR("Unhandled opcode %#x.\n", ins->handler_idx); @@ -2356,7 +2366,9 @@ static void shader_glsl_relop(const struct wined3d_shader_instruction *ins) case WINED3DSIH_EQ: op = "=="; break; case WINED3DSIH_GE: op = ">="; break; case WINED3DSIH_IGE: op = ">="; break; + case WINED3DSIH_UGE: op = ">="; break; case WINED3DSIH_LT: op = "<"; break; + case WINED3DSIH_NE: op = "!="; break; default: op = ""; ERR("Unhandled opcode %#x.\n", ins->handler_idx); @@ -2382,7 +2394,7 @@ static void shader_glsl_imul(const struct wined3d_shader_instruction *ins) if (ins->dst[1].reg.type != WINED3DSPR_NULL) { - write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]); + write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); @@ -2410,17 +2422,17 @@ static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins) shader_addline(buffer, "tmp0%s = %s / %s;\n", dst_mask, src0_param.param_str, src1_param.param_str); - write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]); + write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); shader_addline(buffer, "%s %% %s));\n", src0_param.param_str, src1_param.param_str); - shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]); + shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type); shader_addline(buffer, "tmp0%s);\n", dst_mask); } else { - write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]); + write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); shader_addline(buffer, "%s / %s);\n", src0_param.param_str, src1_param.param_str); @@ -2428,7 +2440,7 @@ static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins) } else if (ins->dst[1].reg.type != WINED3DSPR_NULL) { - write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]); + write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); shader_addline(buffer, "%s %% %s);\n", src0_param.param_str, src1_param.param_str); @@ -2588,6 +2600,7 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins) case WINED3DSIH_DSX: instruction = "dFdx"; break; case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break; case WINED3DSIH_ROUND_NI: instruction = "floor"; break; + case WINED3DSIH_SQRT: instruction = "sqrt"; break; default: instruction = ""; FIXME("Opcode %#x not yet handled in GLSL\n", ins->handler_idx); break; @@ -2892,7 +2905,7 @@ static void shader_glsl_conditional_move(const struct wined3d_shader_instruction continue; shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char); } - else if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst))) + else if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst, dst.reg.data_type))) continue; shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param); @@ -3170,23 +3183,23 @@ static void shader_glsl_sincos(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_addline(buffer, "tmp0%s = sin(%s);\n", dst_mask, src0_param.param_str); - write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]); + write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_addline(buffer, "cos(%s));\n", src0_param.param_str); - shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]); + shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type); shader_addline(buffer, "tmp0%s);\n", dst_mask); } else { - write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]); + write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_addline(buffer, "sin(%s));\n", src0_param.param_str); } } else if (ins->dst[1].reg.type != WINED3DSPR_NULL) { - write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]); + write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_addline(buffer, "cos(%s));\n", src0_param.param_str); } @@ -3351,7 +3364,7 @@ static void shader_glsl_if(const struct wined3d_shader_instruction *ins) struct glsl_src_param src0_param; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param); - shader_addline(ins->ctx->buffer, "if (%s) {\n", src0_param.param_str); + shader_addline(ins->ctx->buffer, "if (bool(%s)) {\n", src0_param.param_str); } static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins) @@ -3438,25 +3451,25 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) ins->ctx->reg_maps->shader_version.minor); struct glsl_sample_function sample_function; DWORD sample_flags = 0; - DWORD sampler_idx; + DWORD resource_idx; DWORD mask = 0, swizzle; const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; /* 1.0-1.4: Use destination register as sampler source. * 2.0+: Use provided sampler source. */ if (shader_version < WINED3D_SHADER_VERSION(2,0)) - sampler_idx = ins->dst[0].reg.idx[0].offset; + resource_idx = ins->dst[0].reg.idx[0].offset; else - sampler_idx = ins->src[1].reg.idx[0].offset; + resource_idx = ins->src[1].reg.idx[0].offset; if (shader_version < WINED3D_SHADER_VERSION(1,4)) { - DWORD flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT) + DWORD flags = (priv->cur_ps_args->tex_transform >> resource_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT) & WINED3D_PSARGS_TEXTRANSFORM_MASK; - enum wined3d_sampler_texture_type sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; + enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type; /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */ - if (flags & WINED3D_PSARGS_PROJECTED && sampler_type != WINED3DSTT_CUBE) + if (flags & WINED3D_PSARGS_PROJECTED && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) { sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; switch (flags & ~WINED3D_PSARGS_PROJECTED) @@ -3492,7 +3505,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) else { if ((ins->flags & WINED3DSI_TEXLD_PROJECT) - && ins->ctx->reg_maps->sampler_type[sampler_idx] != WINED3DSTT_CUBE) + && ins->ctx->reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) { /* ps 2.0 texldp instruction always divides by the fourth component. */ sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; @@ -3500,10 +3513,10 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) } } - if (priv->cur_ps_args->np2_fixup & (1 << sampler_idx)) + if (priv->cur_ps_args->np2_fixup & (1 << resource_idx)) sample_flags |= WINED3D_GLSL_SAMPLE_NPOT; - shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, resource_idx, sample_flags, &sample_function); mask |= sample_function.coord_mask; if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE; @@ -3515,8 +3528,8 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) { char coord_mask[6]; shader_glsl_write_mask_to_str(mask, coord_mask); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL, - "T%u%s", sampler_idx, coord_mask); + shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, + "T%u%s", resource_idx, coord_mask); } else { @@ -3526,10 +3539,10 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) { struct glsl_src_param bias; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, bias.param_str, + shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, bias.param_str, "%s", coord_param.param_str); } else { - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, "%s", coord_param.param_str); } } @@ -3597,6 +3610,37 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins) "%s", coord_param.param_str); } +static unsigned int shader_glsl_find_sampler(const struct wined3d_shader_sampler_map *sampler_map, + unsigned int resource_idx, unsigned int sampler_idx) +{ + struct wined3d_shader_sampler_map_entry *entries = sampler_map->entries; + unsigned int i; + + for (i = 0; i < sampler_map->count; ++i) + { + if (entries[i].resource_idx == resource_idx && entries[i].sampler_idx == sampler_idx) + return entries[i].bind_idx; + } + + ERR("No GLSL sampler found for resource %u / sampler %u.\n", resource_idx, sampler_idx); + + return ~0u; +} + +static void shader_glsl_sample(const struct wined3d_shader_instruction *ins) +{ + struct glsl_sample_function sample_function; + struct glsl_src_param coord_param; + unsigned int sampler_idx; + + shader_glsl_get_sample_function(ins->ctx, ins->src[1].reg.idx[0].offset, 0, &sample_function); + shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); + sampler_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, + ins->src[1].reg.idx[0].offset, ins->src[2].reg.idx[0].offset); + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, + NULL, NULL, NULL, "%s", coord_param.param_str); +} + static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins) { /* FIXME: Make this work for more than just 2D textures */ @@ -4100,7 +4144,16 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w semantic_idx = input_signature[i].semantic_idx; shader_glsl_write_mask_to_str(input_signature[i].mask, reg_mask); - if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) + if (vertexprocessing == vertexshader) + { + if (!strcmp(semantic_name, "SV_POSITION") && !semantic_idx) + shader_addline(buffer, "ps_in[%u]%s = vpos%s;\n", + shader->u.ps.input_reg_map[i], reg_mask, reg_mask); + else + shader_addline(buffer, "ps_in[%u]%s = ps_link[%u]%s;\n", + shader->u.ps.input_reg_map[i], reg_mask, shader->u.ps.input_reg_map[i], reg_mask); + } + else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) { if (semantic_idx < 8 && vertexprocessing == pretransformed) shader_addline(buffer, "ps_in[%u]%s = gl_TexCoord[%u]%s;\n", @@ -4148,7 +4201,7 @@ static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_sh } static struct glsl_shader_prog_link *get_glsl_program_entry(const struct shader_glsl_priv *priv, - GLhandleARB vs_id, GLhandleARB gs_id, GLhandleARB ps_id) + GLuint vs_id, GLuint gs_id, GLuint ps_id) { struct wine_rb_entry *entry; struct glsl_program_key key; @@ -4172,7 +4225,7 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struc key.ps_id = entry->ps.id; wine_rb_remove(&priv->program_lookup, &key); - GL_EXTCALL(glDeleteObjectARB(entry->programId)); + GL_EXTCALL(glDeleteProgram(entry->id)); if (entry->vs.id) list_remove(&entry->vs.shader_entry); if (entry->gs.id) @@ -4222,7 +4275,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer, else if (in_idx == in_count + 1) sprintf(destination, "gl_FrontSecondaryColor"); else - sprintf(destination, "ps_in[%u]", in_idx); + sprintf(destination, "ps_link[%u]", in_idx); semantic_name_in = input_signature[i].semantic_name; semantic_idx_in = input_signature[i].semantic_idx; @@ -4268,7 +4321,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer, else if (i == in_count + 1) sprintf(destination, "gl_FrontSecondaryColor"); else - sprintf(destination, "ps_in[%u]", i); + sprintf(destination, "ps_link[%u]", i); if (size == 1) shader_addline(buffer, "%s.%s = 0.0;\n", destination, reg_mask); else shader_addline(buffer, "%s.%s = vec%u(0.0);\n", destination, reg_mask, size); @@ -4278,11 +4331,11 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer, } /* Context activation is done by the caller. */ -static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer *buffer, +static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buffer, const struct wined3d_shader *vs, const struct wined3d_shader *ps, const struct wined3d_gl_info *gl_info) { - GLhandleARB ret = 0; + GLuint ret = 0; DWORD ps_major = ps ? ps->reg_maps.shader_version.major : 0; unsigned int i; const char *semantic_name; @@ -4297,7 +4350,7 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer if (ps_major < 3) { - shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits.packed_output); + shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output); for (i = 0; map; map >>= 1, ++i) { @@ -4319,7 +4372,7 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer shader_addline(buffer, "gl_FrontSecondaryColor%s = vs_out[%u]%s;\n", reg_mask, i, reg_mask); } - else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION)) + else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx) { shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n", reg_mask, i, reg_mask); @@ -4350,10 +4403,10 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer } else { - UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits.packed_input); + UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits->packed_input); /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */ - shader_addline(buffer, "varying vec4 ps_in[%u];\n", in_count); - shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits.packed_output); + shader_addline(buffer, "varying vec4 ps_link[%u];\n", in_count); + shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output); /* First, sort out position and point size. Those are not passed to the pixel shader */ for (i = 0; map; map >>= 1, ++i) @@ -4361,9 +4414,10 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer if (!(map & 1)) continue; semantic_name = output_signature[i].semantic_name; + semantic_idx = output_signature[i].semantic_idx; shader_glsl_write_mask_to_str(output_signature[i].mask, reg_mask); - if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION)) + if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx) { shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n", reg_mask, i, reg_mask); @@ -4381,8 +4435,8 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer shader_addline(buffer, "}\n"); } - ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); - checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)"); + ret = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); + checkGLcall("glCreateShader(GL_VERTEX_SHADER)"); shader_glsl_compile(gl_info, ret, buffer->buffer); return ret; @@ -4438,7 +4492,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context struct shader_glsl_ctx_priv priv_ctx; /* Create the hw GLSL shader object and assign it as the shader->prgId */ - GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); + GLuint shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); memset(&priv_ctx, 0, sizeof(priv_ctx)); priv_ctx.cur_ps_args = args; @@ -4463,7 +4517,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); /* Pack 3.0 inputs */ - if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader) + if (reg_maps->shader_version.major >= 3) shader_glsl_input_pack(shader, buffer, shader->input_signature, reg_maps, args->vp_mode); /* Base Shader Body */ @@ -4485,11 +4539,10 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "}\n"); - TRACE("Compiling shader object %u\n", shader_obj); - shader_glsl_compile(gl_info, shader_obj, buffer->buffer); + TRACE("Compiling shader object %u.\n", shader_id); + shader_glsl_compile(gl_info, shader_id, buffer->buffer); - /* Store the shader object */ - return shader_obj; + return shader_id; } /* Context activation is done by the caller. */ @@ -4503,7 +4556,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context struct shader_glsl_ctx_priv priv_ctx; /* Create the hw GLSL shader program and assign it as the shader->prgId */ - GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); + GLuint shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); shader_addline(buffer, "#version 120\n"); @@ -4560,23 +4613,23 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context shader_addline(buffer, "}\n"); - TRACE("Compiling shader object %u\n", shader_obj); - shader_glsl_compile(gl_info, shader_obj, buffer->buffer); + TRACE("Compiling shader object %u.\n", shader_id); + shader_glsl_compile(gl_info, shader_id, buffer->buffer); - return shader_obj; + return shader_id; } /* Context activation is done by the caller. */ -static GLhandleARB shader_glsl_generate_geometry_shader(const struct wined3d_context *context, +static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context *context, struct wined3d_shader_buffer *buffer, const struct wined3d_shader *shader) { const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; const struct wined3d_gl_info *gl_info = context->gl_info; const DWORD *function = shader->function; struct shader_glsl_ctx_priv priv_ctx; - GLhandleARB shader_id; + GLuint shader_id; - shader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_GEOMETRY_SHADER_ARB)); + shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER)); shader_addline(buffer, "#version 120\n"); @@ -4600,7 +4653,7 @@ static GLhandleARB shader_glsl_generate_geometry_shader(const struct wined3d_con return shader_id; } -static GLhandleARB find_glsl_pshader(const struct wined3d_context *context, +static GLuint find_glsl_pshader(const struct wined3d_context *context, struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader, const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info) { @@ -4609,7 +4662,7 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context, struct ps_np2fixup_info *np2fixup; UINT i; DWORD new_size; - GLhandleARB ret; + GLuint ret; if (!shader->backend_data) { @@ -4633,7 +4686,7 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context, { if (args->np2_fixup) *np2fixup_info = &gl_shaders[i].np2fixup; - return gl_shaders[i].prgId; + return gl_shaders[i].id; } } @@ -4666,11 +4719,11 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context, memset(np2fixup, 0, sizeof(*np2fixup)); *np2fixup_info = args->np2_fixup ? np2fixup : NULL; - pixelshader_update_samplers(shader, args->tex_types); + pixelshader_update_resource_types(shader, args->tex_types); shader_buffer_clear(buffer); ret = shader_glsl_generate_pshader(context, buffer, shader, args, np2fixup); - gl_shaders[shader_data->num_gl_shaders++].prgId = ret; + gl_shaders[shader_data->num_gl_shaders++].id = ret; return ret; } @@ -4682,7 +4735,7 @@ static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const str return stored->fog_src == new->fog_src; } -static GLhandleARB find_glsl_vshader(const struct wined3d_context *context, +static GLuint find_glsl_vshader(const struct wined3d_context *context, struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader, const struct vs_compile_args *args) { @@ -4691,7 +4744,7 @@ static GLhandleARB find_glsl_vshader(const struct wined3d_context *context, DWORD use_map = context->stream_info.use_map; struct glsl_vs_compiled_shader *gl_shaders, *new_array; struct glsl_shader_private *shader_data; - GLhandleARB ret; + GLuint ret; if (!shader->backend_data) { @@ -4712,7 +4765,7 @@ static GLhandleARB find_glsl_vshader(const struct wined3d_context *context, for (i = 0; i < shader_data->num_gl_shaders; ++i) { if (vs_args_equal(&gl_shaders[i].args, args, use_map)) - return gl_shaders[i].prgId; + return gl_shaders[i].id; } TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader); @@ -4743,17 +4796,17 @@ static GLhandleARB find_glsl_vshader(const struct wined3d_context *context, shader_buffer_clear(buffer); ret = shader_glsl_generate_vshader(context, buffer, shader, args); - gl_shaders[shader_data->num_gl_shaders++].prgId = ret; + gl_shaders[shader_data->num_gl_shaders++].id = ret; return ret; } -static GLhandleARB find_glsl_geometry_shader(const struct wined3d_context *context, +static GLuint find_glsl_geometry_shader(const struct wined3d_context *context, struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader) { struct glsl_gs_compiled_shader *gl_shaders; struct glsl_shader_private *shader_data; - GLhandleARB ret; + GLuint ret; if (!shader->backend_data) { @@ -4904,10 +4957,10 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_shader_buffer *buffer } /* Context activation is done by the caller. */ -static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffer *buffer, +static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffer *buffer, const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info) { - GLhandleARB shader_obj; + GLuint shader_obj; unsigned int i; shader_buffer_clear(buffer); @@ -4995,8 +5048,10 @@ static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_ if (settings->ortho_fog) /* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */ shader_addline(buffer, "gl_FogFragCoord = gl_Position.z * 0.5 + 0.5;\n"); - else + else if (settings->transformed) shader_addline(buffer, "gl_FogFragCoord = ec_pos.z;\n"); + else + shader_addline(buffer, "gl_FogFragCoord = abs(ec_pos.z);\n"); break; default: @@ -5014,7 +5069,7 @@ static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_ shader_addline(buffer, "}\n"); - shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); + shader_obj = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); shader_glsl_compile(gl_info, shader_obj, buffer->buffer); return shader_obj; @@ -5275,7 +5330,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf BOOL tempreg_used = FALSE, tfactor_used = FALSE; const char *final_combiner_src = "ret"; UINT lowest_disabled_stage; - GLhandleARB shader_obj; + GLuint shader_id; DWORD arg0, arg1, arg2; unsigned int stage; @@ -5615,9 +5670,9 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf shader_addline(buffer, "}\n"); - shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); - shader_glsl_compile(gl_info, shader_obj, buffer->buffer); - return shader_obj; + shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); + shader_glsl_compile(gl_info, shader_id, buffer->buffer); + return shader_id; } static struct glsl_ffp_vertex_shader *shader_glsl_find_ffp_vertex_shader(struct shader_glsl_priv *priv, @@ -5663,83 +5718,83 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info, - GLhandleARB program_id, struct glsl_vs_program *vs, unsigned int vs_c_count) + GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count) { unsigned int i; char name[32]; vs->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0, - sizeof(GLhandleARB) * gl_info->limits.glsl_vs_float_constants); + sizeof(GLuint) * gl_info->limits.glsl_vs_float_constants); for (i = 0; i < vs_c_count; ++i) { snprintf(name, sizeof(name), "vs_c[%u]", i); - vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); } memset(&vs->uniform_f_locations[vs_c_count], 0xff, - (gl_info->limits.glsl_vs_float_constants - vs_c_count) * sizeof(GLhandleARB)); + (gl_info->limits.glsl_vs_float_constants - vs_c_count) * sizeof(GLuint)); for (i = 0; i < MAX_CONST_I; ++i) { snprintf(name, sizeof(name), "vs_i[%u]", i); - vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); } for (i = 0; i < MAX_CONST_B; ++i) { snprintf(name, sizeof(name), "vs_b[%u]", i); - vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); } - vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "posFixup")); + vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "posFixup")); } static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info, - GLhandleARB program_id, struct glsl_ps_program *ps, unsigned int ps_c_count) + GLuint program_id, struct glsl_ps_program *ps, unsigned int ps_c_count) { unsigned int i; char name[32]; ps->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0, - sizeof(GLhandleARB) * gl_info->limits.glsl_ps_float_constants); + sizeof(GLuint) * gl_info->limits.glsl_ps_float_constants); for (i = 0; i < ps_c_count; ++i) { snprintf(name, sizeof(name), "ps_c[%u]", i); - ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); } memset(&ps->uniform_f_locations[ps_c_count], 0xff, - (gl_info->limits.glsl_ps_float_constants - ps_c_count) * sizeof(GLhandleARB)); + (gl_info->limits.glsl_ps_float_constants - ps_c_count) * sizeof(GLuint)); for (i = 0; i < MAX_CONST_I; ++i) { snprintf(name, sizeof(name), "ps_i[%u]", i); - ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); } for (i = 0; i < MAX_CONST_B; ++i) { snprintf(name, sizeof(name), "ps_b[%u]", i); - ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); } for (i = 0; i < MAX_TEXTURES; ++i) { snprintf(name, sizeof(name), "bumpenv_mat%u", i); - ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); snprintf(name, sizeof(name), "bumpenv_lum_scale%u", i); - ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); snprintf(name, sizeof(name), "bumpenv_lum_offset%u", i); - ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); snprintf(name, sizeof(name), "tss_const%u", i); - ps->tss_constant_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name)); + ps->tss_constant_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); } - ps->tex_factor_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "tex_factor")); - ps->specular_enable_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "specular_enable")); - ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "ps_samplerNP2Fixup")); - ps->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "ycorrection")); + ps->tex_factor_location = GL_EXTCALL(glGetUniformLocation(program_id, "tex_factor")); + ps->specular_enable_location = GL_EXTCALL(glGetUniformLocation(program_id, "specular_enable")); + ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "ps_samplerNP2Fixup")); + ps->ycorrection_location = GL_EXTCALL(glGetUniformLocation(program_id, "ycorrection")); } -static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, GLhandleARB program_id, +static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps, unsigned int base, unsigned int count) { const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type); @@ -5769,13 +5824,13 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const struct wined3d_shader *vshader = NULL; struct wined3d_shader *gshader = NULL; struct wined3d_shader *pshader = NULL; - GLhandleARB programId = 0; - GLhandleARB reorder_shader_id = 0; + GLuint program_id = 0; + GLuint reorder_shader_id = 0; unsigned int i; - GLhandleARB vs_id = 0; - GLhandleARB gs_id = 0; - GLhandleARB ps_id = 0; - struct list *ps_list, *vs_list; + GLuint vs_id = 0; + GLuint gs_id = 0; + GLuint ps_id = 0; + struct list *ps_list = NULL, *vs_list = NULL; if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_VERTEX))) { @@ -5852,12 +5907,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const } /* If we get to this point, then no matching program exists, so we create one */ - programId = GL_EXTCALL(glCreateProgramObjectARB()); - TRACE("Created new GLSL shader program %u\n", programId); + program_id = GL_EXTCALL(glCreateProgram()); + TRACE("Created new GLSL shader program %u.\n", program_id); /* Create the entry */ entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link)); - entry->programId = programId; + entry->id = program_id; entry->vs.id = vs_id; entry->gs.id = gs_id; entry->ps.id = ps_id; @@ -5872,9 +5927,9 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const /* Attach GLSL vshader */ if (vs_id) { - TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, programId); - GL_EXTCALL(glAttachObjectARB(programId, vs_id)); - checkGLcall("glAttachObjectARB"); + TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, program_id); + GL_EXTCALL(glAttachShader(program_id, vs_id)); + checkGLcall("glAttachShader"); list_add_head(vs_list, &entry->vs.shader_entry); } @@ -5885,13 +5940,13 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const char tmp_name[10]; reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info); - TRACE("Attaching GLSL shader object %u to program %u\n", reorder_shader_id, programId); - GL_EXTCALL(glAttachObjectARB(programId, reorder_shader_id)); - checkGLcall("glAttachObjectARB"); + TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id); + GL_EXTCALL(glAttachShader(program_id, reorder_shader_id)); + checkGLcall("glAttachShader"); /* Flag the reorder function for deletion, then it will be freed automatically when the program * is destroyed */ - GL_EXTCALL(glDeleteObjectARB(reorder_shader_id)); + GL_EXTCALL(glDeleteShader(reorder_shader_id)); /* Bind vertex attributes to a corresponding index number to match * the same index numbers as ARB_vertex_programs (makes loading @@ -5907,26 +5962,26 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (!(map & 1)) continue; snprintf(tmp_name, sizeof(tmp_name), "vs_in%u", i); - GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name)); + GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name)); } - checkGLcall("glBindAttribLocationARB"); + checkGLcall("glBindAttribLocation"); } if (gshader) { - TRACE("Attaching GLSL geometry shader object %u to program %u.\n", gs_id, programId); - GL_EXTCALL(glAttachObjectARB(programId, gs_id)); - checkGLcall("glAttachObjectARB"); + TRACE("Attaching GLSL geometry shader object %u to program %u.\n", gs_id, program_id); + GL_EXTCALL(glAttachShader(program_id, gs_id)); + checkGLcall("glAttachShader"); TRACE("input type %s, output type %s, vertices out %u.\n", debug_d3dprimitivetype(gshader->u.gs.input_type), debug_d3dprimitivetype(gshader->u.gs.output_type), gshader->u.gs.vertices_out); - GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_INPUT_TYPE_ARB, + GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_INPUT_TYPE_ARB, gl_primitive_type_from_d3d(gshader->u.gs.input_type))); - GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_OUTPUT_TYPE_ARB, + GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_OUTPUT_TYPE_ARB, gl_primitive_type_from_d3d(gshader->u.gs.output_type))); - GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_VERTICES_OUT_ARB, + GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_VERTICES_OUT_ARB, gshader->u.gs.vertices_out)); checkGLcall("glProgramParameteriARB"); @@ -5936,28 +5991,28 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const /* Attach GLSL pshader */ if (ps_id) { - TRACE("Attaching GLSL shader object %u to program %u.\n", ps_id, programId); - GL_EXTCALL(glAttachObjectARB(programId, ps_id)); - checkGLcall("glAttachObjectARB"); + TRACE("Attaching GLSL shader object %u to program %u.\n", ps_id, program_id); + GL_EXTCALL(glAttachShader(program_id, ps_id)); + checkGLcall("glAttachShader"); list_add_head(ps_list, &entry->ps.shader_entry); } /* Link the program */ - TRACE("Linking GLSL shader program %u\n", programId); - GL_EXTCALL(glLinkProgramARB(programId)); - shader_glsl_validate_link(gl_info, programId); + TRACE("Linking GLSL shader program %u.\n", program_id); + GL_EXTCALL(glLinkProgram(program_id)); + shader_glsl_validate_link(gl_info, program_id); - shader_glsl_init_vs_uniform_locations(gl_info, programId, &entry->vs, - vshader ? vshader->limits.constant_float : 0); - shader_glsl_init_ps_uniform_locations(gl_info, programId, &entry->ps, - pshader ? pshader->limits.constant_float : 0); + shader_glsl_init_vs_uniform_locations(gl_info, program_id, &entry->vs, + vshader ? min(vshader->limits->constant_float, gl_info->limits.glsl_vs_float_constants) : 0); + shader_glsl_init_ps_uniform_locations(gl_info, program_id, &entry->ps, + pshader ? min(pshader->limits->constant_float, gl_info->limits.glsl_ps_float_constants) : 0); checkGLcall("Find glsl program uniform locations"); if (pshader && pshader->reg_maps.shader_version.major >= 3 && pshader->u.ps.declared_in_count > vec4_varyings(3, gl_info)) { - TRACE("Shader %d needs vertex color clamping disabled\n", programId); + TRACE("Shader %d needs vertex color clamping disabled.\n", program_id); entry->vs.vertex_color_clamp = GL_FALSE; } else @@ -5966,8 +6021,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const } /* Set the shader to allow uniform loading on it */ - GL_EXTCALL(glUseProgramObjectARB(programId)); - checkGLcall("glUseProgramObjectARB(programId)"); + GL_EXTCALL(glUseProgram(program_id)); + checkGLcall("glUseProgram"); /* Load the vertex and pixel samplers now. The function that finds the mappings makes sure * that it stays the same for each vertexshader-pixelshader pair(=linked glsl program). If @@ -5975,10 +6030,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const * vertex shader with fixed function pixel processing is used we make sure that the card * supports enough samplers to allow the max number of vertex samplers with all possible * fixed function fragment processing setups. So once the program is linked these samplers - * won't change. - */ - shader_glsl_load_vsamplers(gl_info, context->tex_unit_map, programId); - shader_glsl_load_psamplers(gl_info, context->tex_unit_map, programId); + * won't change. */ + shader_glsl_load_samplers(gl_info, context->tex_unit_map, program_id); entry->constant_update_mask = 0; if (vshader) @@ -5990,12 +6043,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B; entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP; - shader_glsl_init_uniform_block_bindings(gl_info, programId, &vshader->reg_maps, + shader_glsl_init_uniform_block_bindings(gl_info, program_id, &vshader->reg_maps, 0, gl_info->limits.vertex_uniform_blocks); } if (gshader) - shader_glsl_init_uniform_block_bindings(gl_info, programId, &gshader->reg_maps, + shader_glsl_init_uniform_block_bindings(gl_info, program_id, &gshader->reg_maps, gl_info->limits.vertex_uniform_blocks, gl_info->limits.geometry_uniform_blocks); if (ps_id) @@ -6010,7 +6063,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (entry->ps.ycorrection_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR; - shader_glsl_init_uniform_block_bindings(gl_info, programId, &pshader->reg_maps, + shader_glsl_init_uniform_block_bindings(gl_info, program_id, &pshader->reg_maps, gl_info->limits.vertex_uniform_blocks + gl_info->limits.geometry_uniform_blocks, gl_info->limits.fragment_uniform_blocks); } @@ -6034,10 +6087,10 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const } /* Context activation is done by the caller. */ -static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked) +static GLuint create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked) { - GLhandleARB program_id; - GLhandleARB vshader_id, pshader_id; + GLuint program_id; + GLuint vshader_id, pshader_id; const char *blt_pshader; static const char blt_vshader[] = @@ -6122,24 +6175,24 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, return 0; } - vshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); + vshader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); shader_glsl_compile(gl_info, vshader_id, blt_vshader); - pshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); + pshader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); shader_glsl_compile(gl_info, pshader_id, blt_pshader); - program_id = GL_EXTCALL(glCreateProgramObjectARB()); - GL_EXTCALL(glAttachObjectARB(program_id, vshader_id)); - GL_EXTCALL(glAttachObjectARB(program_id, pshader_id)); - GL_EXTCALL(glLinkProgramARB(program_id)); + program_id = GL_EXTCALL(glCreateProgram()); + GL_EXTCALL(glAttachShader(program_id, vshader_id)); + GL_EXTCALL(glAttachShader(program_id, pshader_id)); + GL_EXTCALL(glLinkProgram(program_id)); shader_glsl_validate_link(gl_info, program_id); /* Once linked we can mark the shaders for deletion. They will be deleted once the program * is destroyed */ - GL_EXTCALL(glDeleteObjectARB(vshader_id)); - GL_EXTCALL(glDeleteObjectARB(pshader_id)); + GL_EXTCALL(glDeleteShader(vshader_id)); + GL_EXTCALL(glDeleteShader(pshader_id)); return program_id; } @@ -6150,7 +6203,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex struct glsl_context_data *ctx_data = context->shader_backend_data; const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_priv *priv = shader_priv; - GLhandleARB program_id = 0, prev_id = 0; + GLuint program_id = 0, prev_id = 0; GLenum old_vertex_color_clamp, current_vertex_color_clamp; priv->vertex_pipe->vp_enable(gl_info, !use_vs(state)); @@ -6158,7 +6211,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex if (ctx_data->glsl_program) { - prev_id = ctx_data->glsl_program->programId; + prev_id = ctx_data->glsl_program->id; old_vertex_color_clamp = ctx_data->glsl_program->vs.vertex_color_clamp; } else @@ -6171,7 +6224,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex if (ctx_data->glsl_program) { - program_id = ctx_data->glsl_program->programId; + program_id = ctx_data->glsl_program->id; current_vertex_color_clamp = ctx_data->glsl_program->vs.vertex_color_clamp; } else @@ -6197,8 +6250,8 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex if (prev_id != program_id) { - GL_EXTCALL(glUseProgramObjectARB(program_id)); - checkGLcall("glUseProgramObjectARB"); + GL_EXTCALL(glUseProgram(program_id)); + checkGLcall("glUseProgram"); if (program_id) context->constant_update_mask |= ctx_data->glsl_program->constant_update_mask; @@ -6223,8 +6276,8 @@ static void shader_glsl_disable(void *shader_priv, struct wined3d_context *conte struct shader_glsl_priv *priv = shader_priv; shader_glsl_invalidate_current_program(context); - GL_EXTCALL(glUseProgramObjectARB(0)); - checkGLcall("glUseProgramObjectARB"); + GL_EXTCALL(glUseProgram(0)); + checkGLcall("glUseProgram"); priv->vertex_pipe->vp_enable(gl_info, FALSE); priv->fragment_pipe->enable_extension(gl_info, FALSE); @@ -6242,26 +6295,26 @@ static void shader_glsl_select_depth_blt(void *shader_priv, const struct wined3d { BOOL masked = ds_mask_size->cx && ds_mask_size->cy; struct shader_glsl_priv *priv = shader_priv; - GLhandleARB *blt_program; + GLuint *blt_program; GLint loc; blt_program = masked ? &priv->depth_blt_program_masked[tex_type] : &priv->depth_blt_program_full[tex_type]; if (!*blt_program) { *blt_program = create_glsl_blt_shader(gl_info, tex_type, masked); - loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "sampler")); - GL_EXTCALL(glUseProgramObjectARB(*blt_program)); - GL_EXTCALL(glUniform1iARB(loc, 0)); + loc = GL_EXTCALL(glGetUniformLocation(*blt_program, "sampler")); + GL_EXTCALL(glUseProgram(*blt_program)); + GL_EXTCALL(glUniform1i(loc, 0)); } else { - GL_EXTCALL(glUseProgramObjectARB(*blt_program)); + GL_EXTCALL(glUseProgram(*blt_program)); } if (masked) { - loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "mask")); - GL_EXTCALL(glUniform4fARB(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy)); + loc = GL_EXTCALL(glGetUniformLocation(*blt_program, "mask")); + GL_EXTCALL(glUniform4f(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy)); } } @@ -6269,13 +6322,13 @@ static void shader_glsl_select_depth_blt(void *shader_priv, const struct wined3d static void shader_glsl_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info) { const struct glsl_context_data *ctx_data = context_get_current()->shader_backend_data; - GLhandleARB program_id; + GLuint program_id; - program_id = ctx_data->glsl_program ? ctx_data->glsl_program->programId : 0; + program_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; if (program_id) TRACE("Using GLSL program %u\n", program_id); - GL_EXTCALL(glUseProgramObjectARB(program_id)); - checkGLcall("glUseProgramObjectARB"); + GL_EXTCALL(glUseProgram(program_id)); + checkGLcall("glUseProgram"); } static void shader_glsl_invalidate_contexts_program(struct wined3d_device *device, @@ -6329,9 +6382,9 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) for (i = 0; i < shader_data->num_gl_shaders; ++i) { - TRACE("Deleting pixel shader %u.\n", gl_shaders[i].prgId); - GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId)); - checkGLcall("glDeleteObjectARB"); + TRACE("Deleting pixel shader %u.\n", gl_shaders[i].id); + GL_EXTCALL(glDeleteShader(gl_shaders[i].id)); + checkGLcall("glDeleteShader"); } HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ps); @@ -6351,9 +6404,9 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) for (i = 0; i < shader_data->num_gl_shaders; ++i) { - TRACE("Deleting vertex shader %u.\n", gl_shaders[i].prgId); - GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId)); - checkGLcall("glDeleteObjectARB"); + TRACE("Deleting vertex shader %u.\n", gl_shaders[i].id); + GL_EXTCALL(glDeleteShader(gl_shaders[i].id)); + checkGLcall("glDeleteShader"); } HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.vs); @@ -6374,8 +6427,8 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) for (i = 0; i < shader_data->num_gl_shaders; ++i) { TRACE("Deleting geometry shader %u.\n", gl_shaders[i].id); - GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].id)); - checkGLcall("glDeleteObjectARB"); + GL_EXTCALL(glDeleteShader(gl_shaders[i].id)); + checkGLcall("glDeleteShader"); } HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.gs); @@ -6545,11 +6598,11 @@ static void shader_glsl_free(struct wined3d_device *device) { if (priv->depth_blt_program_full[i]) { - GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_full[i])); + GL_EXTCALL(glDeleteProgram(priv->depth_blt_program_full[i])); } if (priv->depth_blt_program_masked[i]) { - GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_masked[i])); + GL_EXTCALL(glDeleteProgram(priv->depth_blt_program_masked[i])); } } @@ -6583,7 +6636,7 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s if (gl_info->supported[EXT_GPU_SHADER4] && gl_info->supported[ARB_SHADER_BIT_ENCODING] && gl_info->supported[ARB_GEOMETRY_SHADER4] && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50) && gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && gl_info->supported[ARB_DRAW_INSTANCED] - && gl_info->supported[ARB_TEXTURE_RG]) + && gl_info->supported[ARB_TEXTURE_RG] && gl_info->supported[ARB_SAMPLER_OBJECTS]) shader_model = 4; /* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3 * texldd and texldl instructions. */ @@ -6713,8 +6766,10 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_MOVA */ shader_glsl_mov, /* WINED3DSIH_MOVC */ shader_glsl_conditional_move, /* WINED3DSIH_MUL */ shader_glsl_binop, + /* WINED3DSIH_NE */ shader_glsl_relop, /* WINED3DSIH_NOP */ shader_glsl_nop, /* WINED3DSIH_NRM */ shader_glsl_nrm, + /* WINED3DSIH_OR */ shader_glsl_binop, /* WINED3DSIH_PHASE */ shader_glsl_nop, /* WINED3DSIH_POW */ shader_glsl_pow, /* WINED3DSIH_RCP */ shader_glsl_scalar_op, @@ -6722,7 +6777,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_RET */ shader_glsl_ret, /* WINED3DSIH_ROUND_NI */ shader_glsl_map2gl, /* WINED3DSIH_RSQ */ shader_glsl_scalar_op, - /* WINED3DSIH_SAMPLE */ NULL, + /* WINED3DSIH_SAMPLE */ shader_glsl_sample, /* WINED3DSIH_SAMPLE_GRAD */ NULL, /* WINED3DSIH_SAMPLE_LOD */ NULL, /* WINED3DSIH_SETP */ NULL, @@ -6730,7 +6785,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_SGN */ shader_glsl_sgn, /* WINED3DSIH_SINCOS */ shader_glsl_sincos, /* WINED3DSIH_SLT */ shader_glsl_compare, - /* WINED3DSIH_SQRT */ NULL, + /* WINED3DSIH_SQRT */ shader_glsl_map2gl, /* WINED3DSIH_SUB */ shader_glsl_binop, /* WINED3DSIH_TEX */ shader_glsl_tex, /* WINED3DSIH_TEXBEM */ shader_glsl_texbem, @@ -6755,6 +6810,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_TEXREG2GB */ shader_glsl_texreg2gb, /* WINED3DSIH_TEXREG2RGB */ shader_glsl_texreg2rgb, /* WINED3DSIH_UDIV */ shader_glsl_udiv, + /* WINED3DSIH_UGE */ shader_glsl_relop, /* WINED3DSIH_USHR */ shader_glsl_binop, /* WINED3DSIH_UTOF */ shader_glsl_to_float, /* WINED3DSIH_XOR */ shader_glsl_binop, @@ -6865,7 +6921,7 @@ static void shader_glsl_free_ffp_vertex_shader(struct wine_rb_entry *entry, void { delete_glsl_program_entry(ctx->priv, ctx->gl_info, program); } - ctx->gl_info->gl_ops.ext.p_glDeleteObjectARB(shader->id); + ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id); HeapFree(GetProcessHeap(), 0, shader); } @@ -7137,7 +7193,7 @@ static void shader_glsl_free_ffp_fragment_shader(struct wine_rb_entry *entry, vo { delete_glsl_program_entry(ctx->priv, ctx->gl_info, program); } - ctx->gl_info->gl_ops.ext.p_glDeleteObjectARB(shader->id); + ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id); HeapFree(GetProcessHeap(), 0, shader); } diff --git a/reactos/dll/directx/wine/wined3d/query.c b/reactos/dll/directx/wine/wined3d/query.c index 443626b82db..1ce9ba12353 100644 --- a/reactos/dll/directx/wine/wined3d/query.c +++ b/reactos/dll/directx/wine/wined3d/query.c @@ -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, ×tamp)); - checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)"); + GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); + checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); fill_query_data(data, size, ×tamp, sizeof(timestamp)); } diff --git a/reactos/dll/directx/wine/wined3d/resource.c b/reactos/dll/directx/wine/wined3d/resource.c index 9b73bfcacf7..d94fb76371a 100644 --- a/reactos/dll/directx/wine/wined3d/resource.c +++ b/reactos/dll/directx/wine/wined3d/resource.c @@ -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); diff --git a/reactos/dll/directx/wine/wined3d/sampler.c b/reactos/dll/directx/wine/wined3d/sampler.c index d82c4c90aa7..84ba74ae1e1 100644 --- a/reactos/dll/directx/wine/wined3d/sampler.c +++ b/reactos/dll/directx/wine/wined3d/sampler.c @@ -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; diff --git a/reactos/dll/directx/wine/wined3d/shader.c b/reactos/dll/directx/wine/wined3d/shader.c index 2bb945df0c4..9c0732efc1d 100644 --- a/reactos/dll/directx/wine/wined3d/shader.c +++ b/reactos/dll/directx/wine/wined3d/shader.c @@ -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 = ®_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, ®, shader_version.type); + if (!shader_record_register_usage(shader, reg_maps, ®, + 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); diff --git a/reactos/dll/directx/wine/wined3d/shader_sm1.c b/reactos/dll/directx/wine/wined3d/shader_sm1.c index da6641d8c9b..f5f0b66da93 100644 --- a/reactos/dll/directx/wine/wined3d/shader_sm1.c +++ b/reactos/dll/directx/wine/wined3d/shader_sm1.c @@ -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); } diff --git a/reactos/dll/directx/wine/wined3d/shader_sm4.c b/reactos/dll/directx/wine/wined3d/shader_sm4.c index 7a25e0235b0..4881cfa3a68 100644 --- a/reactos/dll/directx/wine/wined3d/shader_sm4.c +++ b/reactos/dll/directx/wine/wined3d/shader_sm4.c @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index 17162acb405..8f06177ba1d 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -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, diff --git a/reactos/dll/directx/wine/wined3d/stateblock.c b/reactos/dll/directx/wine/wined3d/stateblock.c index 3228c0f5b8d..5315a46c59d 100644 --- a/reactos/dll/directx/wine/wined3d/stateblock.c +++ b/reactos/dll/directx/wine/wined3d/stateblock.c @@ -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); + } + } } } diff --git a/reactos/dll/directx/wine/wined3d/surface.c b/reactos/dll/directx/wine/wined3d/surface.c index 5f1bc101ded..07122b384a3 100644 --- a/reactos/dll/directx/wine/wined3d/surface.c +++ b/reactos/dll/directx/wine/wined3d/surface.c @@ -57,7 +57,7 @@ static void surface_cleanup(struct wined3d_surface *surface) if (surface->pbo) { TRACE("Deleting PBO %u.\n", surface->pbo); - GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo)); + GL_EXTCALL(glDeleteBuffers(1, &surface->pbo)); } if (surface->rb_multisample) @@ -308,14 +308,13 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3 context_bind_texture(context, info.bind_target, texture->texture_rgb.name); /* Filtering for StretchRect */ - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, - wined3d_gl_mag_filter(magLookup, filter)); + gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter)); checkGLcall("glTexParameteri"); gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER, - wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE)); + wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE)); checkGLcall("glTexParameteri"); - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP); - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP); + gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); @@ -341,10 +340,10 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3 /* We changed the filtering settings on the texture. Inform the * container about this to get the filters reset properly next draw. */ - texture->texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT; - texture->texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; - texture->texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE; - texture->texture_rgb.states[WINED3DTEXSTA_SRGBTEXTURE] = FALSE; + texture->texture_rgb.sampler_desc.mag_filter = WINED3D_TEXF_POINT; + texture->texture_rgb.sampler_desc.min_filter = WINED3D_TEXF_POINT; + texture->texture_rgb.sampler_desc.mip_filter = WINED3D_TEXF_NONE; + texture->texture_rgb.sampler_desc.srgb_decode = FALSE; } /* Works correctly only for <= 4 bpp formats. */ @@ -520,22 +519,22 @@ static void surface_prepare_buffer(struct wined3d_surface *surface) context = context_acquire(surface->resource.device, NULL); gl_info = context->gl_info; - GL_EXTCALL(glGenBuffersARB(1, &surface->pbo)); + GL_EXTCALL(glGenBuffers(1, &surface->pbo)); error = gl_info->gl_ops.gl.p_glGetError(); if (!surface->pbo || error != GL_NO_ERROR) ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error); TRACE("Binding PBO %u.\n", surface->pbo); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); - checkGLcall("glBindBufferARB"); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); + checkGLcall("glBindBuffer"); - GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->resource.size + 4, - NULL, GL_STREAM_DRAW_ARB)); - checkGLcall("glBufferDataARB"); + GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4, + NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); - checkGLcall("glBindBufferARB"); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); context_release(context); } @@ -585,18 +584,19 @@ void surface_prepare_map_memory(struct wined3d_surface *surface) static void surface_evict_sysmem(struct wined3d_surface *surface) { - if (surface->resource.map_count || surface->flags & SFLAG_DONOTFREE) + /* In some conditions the surface memory must not be freed: + * WINED3D_TEXTURE_CONVERTED: Converting the data back would take too long + * WINED3D_TEXTURE_DYNAMIC_MAP: Avoid freeing the data for performance + * SFLAG_CLIENT: OpenGL uses our memory as backup */ + if (surface->resource.map_count || surface->flags & SFLAG_CLIENT + || surface->container->flags & (WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_PIN_SYSMEM + | WINED3D_TEXTURE_DYNAMIC_MAP)) return; wined3d_resource_free_sysmem(&surface->resource); surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); } -static void surface_force_reload(struct wined3d_surface *surface) -{ - surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); -} - static void surface_release_client_storage(struct wined3d_surface *surface) { struct wined3d_context *context = context_acquire(surface->resource.device, NULL); @@ -614,22 +614,22 @@ static void surface_release_client_storage(struct wined3d_surface *surface) gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); } + wined3d_texture_force_reload(surface->container); context_release(context); - - surface_invalidate_location(surface, WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB); - surface_force_reload(surface); } static BOOL surface_use_pbo(const struct wined3d_surface *surface) { const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; + struct wined3d_texture *texture = surface->container; - return surface->resource.pool == WINED3D_POOL_DEFAULT + return texture->resource.pool == WINED3D_POOL_DEFAULT && surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] - && !surface->resource.format->convert - && !(surface->flags & (SFLAG_NONPOW2 | SFLAG_PIN_SYSMEM)); + && !texture->resource.format->convert + && !(texture->flags & WINED3D_TEXTURE_PIN_SYSMEM) + && !(surface->flags & SFLAG_NONPOW2); } static HRESULT surface_private_setup(struct wined3d_surface *surface) @@ -730,10 +730,10 @@ static void surface_unmap(struct wined3d_surface *surface) context = context_acquire(device, NULL); gl_info = context->gl_info; - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); - GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); - checkGLcall("glUnmapBufferARB"); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); + GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("glUnmapBuffer"); context_release(context); break; @@ -1149,8 +1149,8 @@ HRESULT CDECL wined3d_surface_get_render_target_data(struct wined3d_surface *sur /* Context activation is done by the caller. */ static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) { - GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo)); - checkGLcall("glDeleteBuffersARB(1, &surface->pbo)"); + GL_EXTCALL(glDeleteBuffers(1, &surface->pbo)); + checkGLcall("glDeleteBuffers(1, &surface->pbo)"); surface->pbo = 0; surface_invalidate_location(surface, WINED3D_LOCATION_BUFFER); @@ -1204,7 +1204,6 @@ static void surface_unload(struct wined3d_resource *resource) surface_load_location(surface, surface->resource.map_binding); surface_invalidate_location(surface, ~surface->resource.map_binding); } - surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); context = context_acquire(device, NULL); gl_info = context->gl_info; @@ -1323,7 +1322,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct struct wined3d_bo_address data; /* Only support read back of converted P8 surfaces. */ - if (surface->flags & SFLAG_CONVERTED && format->id != WINED3DFMT_P8_UINT) + if (surface->container->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT) { ERR("Trying to read back converted surface %p with format %s.\n", surface, debug_d3dformat(format->id)); return; @@ -1333,23 +1332,23 @@ static void surface_download_data(struct wined3d_surface *surface, const struct if (format->flags & WINED3DFMT_FLAG_COMPRESSED) { - TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p.\n", + TRACE("(%p) : Calling glGetCompressedTexImage level %d, format %#x, type %#x, data %p.\n", surface, surface->texture_level, format->glFormat, format->glType, data.addr); if (data.buffer_object) { - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data.buffer_object)); - checkGLcall("glBindBufferARB"); - GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target, surface->texture_level, NULL)); - checkGLcall("glGetCompressedTexImageARB"); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); - checkGLcall("glBindBufferARB"); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object)); + checkGLcall("glBindBuffer"); + GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, surface->texture_level, NULL)); + checkGLcall("glGetCompressedTexImage"); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); } else { - GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target, + GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, surface->texture_level, data.addr)); - checkGLcall("glGetCompressedTexImageARB"); + checkGLcall("glGetCompressedTexImage"); } } else @@ -1378,15 +1377,15 @@ static void surface_download_data(struct wined3d_surface *surface, const struct 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(surface->texture_target, surface->texture_level, gl_format, gl_type, NULL); checkGLcall("glGetTexImage"); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); - checkGLcall("glBindBufferARB"); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); } else { @@ -1447,8 +1446,8 @@ static void surface_download_data(struct wined3d_surface *surface, const struct * get a boxed texture with width pow2width and not a texture of width resource.width. * * Performance should not be an issue, because applications normally do not lock the surfaces when - * rendering. If an app does, the SFLAG_DYNLOCK flag will kick in and the memory copy won't be released, - * and doesn't have to be re-read. */ + * rendering. If an app does, the WINED3D_TEXTURE_DYNAMIC_MAP flag will kick in and the memory copy + * won't be released, and doesn't have to be re-read. */ src_data = mem; dst_data = data.addr; TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch); @@ -1467,9 +1466,9 @@ static void surface_download_data(struct wined3d_surface *surface, const struct /* This call just uploads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -static void surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, +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_bo_address *data) + BOOL srgb, const struct wined3d_const_bo_address *data) { UINT update_w = src_rect->right - src_rect->left; UINT update_h = src_rect->bottom - src_rect->top; @@ -1480,8 +1479,8 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi if (surface->resource.map_count) { - WARN("Uploading a surface that is currently mapped, setting SFLAG_PIN_SYSMEM.\n"); - surface->flags |= SFLAG_PIN_SYSMEM; + WARN("Uploading a surface that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n"); + surface->container->flags |= WINED3D_TEXTURE_PIN_SYSMEM; } if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE) @@ -1492,8 +1491,8 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi 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"); } if (format->flags & WINED3DFMT_FLAG_COMPRESSED) @@ -1514,30 +1513,30 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi else internal = format->glInternal; - TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, " + TRACE("glCompressedTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, " "format %#x, image_size %#x, addr %p.\n", surface->texture_target, surface->texture_level, dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr); if (row_length == src_pitch) { - GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level, + GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr)); } else { UINT row, y; - /* glCompressedTexSubImage2DARB() ignores pixel store state, so we - * can't use the unpack row length like below. */ + /* glCompressedTexSubImage2D() ignores pixel store state, so we + * can't use the unpack row length like for glTexSubImage2D. */ for (row = 0, y = dst_point->y; row < row_count; ++row) { - GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level, + GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, dst_point->x, y, update_w, format->block_height, internal, row_length, addr)); y += format->block_height; addr += src_pitch; } } - checkGLcall("glCompressedTexSubImage2DARB"); + checkGLcall("glCompressedTexSubImage2D"); } else { @@ -1559,8 +1558,8 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi 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 (wined3d_settings.strict_draw_ordering) @@ -1578,132 +1577,6 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi } } -static HRESULT d3dfmt_get_conv(const struct wined3d_surface *surface, BOOL need_alpha_ck, BOOL use_texturing, - struct wined3d_format *format, enum wined3d_conversion_type *conversion_type) -{ - BOOL colorkey_active = need_alpha_ck && (surface->container->color_key_flags & WINEDDSD_CKSRCBLT); - const struct wined3d_device *device = surface->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - BOOL blit_supported = FALSE; - - /* Copy the default values from the surface. Below we might perform fixups */ - /* TODO: get rid of color keying desc fixups by using e.g. a table. */ - *format = *surface->resource.format; - *conversion_type = WINED3D_CT_NONE; - - /* Ok, now look if we have to do any conversion */ - switch (surface->resource.format->id) - { - case WINED3DFMT_P8_UINT: - /* Below the call to blit_supported is disabled for Wine 1.2 - * because the function isn't operating correctly yet. At the - * moment 8-bit blits are handled in software and if certain GL - * extensions are around, surface conversion is performed at - * upload time. The blit_supported call recognizes it as a - * destination fixup. This type of upload 'fixup' and 8-bit to - * 8-bit blits need to be handled by the blit_shader. - * TODO: get rid of this #if 0. */ -#if 0 - blit_supported = device->blitter->blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT, - &rect, surface->resource.usage, surface->resource.pool, surface->resource.format, - &rect, surface->resource.usage, surface->resource.pool, surface->resource.format); -#endif - blit_supported = gl_info->supported[ARB_FRAGMENT_PROGRAM]; - - /* Use conversion when the blit_shader backend supports it. It only supports this in case of - * texturing. Further also use conversion in case of color keying. - * Paletted textures can be emulated using shaders but only do that for 2D purposes e.g. situations - * in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which - * conflicts with this. - */ - if (!((blit_supported && surface->container->swapchain - && surface->container == surface->container->swapchain->front_buffer)) - || colorkey_active || !use_texturing) - { - format->glFormat = GL_RGBA; - format->glInternal = GL_RGBA; - format->glType = GL_UNSIGNED_BYTE; - format->conv_byte_count = 4; - *conversion_type = WINED3D_CT_PALETTED; - } - break; - - case WINED3DFMT_B2G3R3_UNORM: - /* ********************** - GL_UNSIGNED_BYTE_3_3_2 - ********************** */ - if (colorkey_active) { - /* This texture format will never be used.. So do not care about color keying - up until the point in time it will be needed :-) */ - FIXME(" ColorKeying not supported in the RGB 332 format !\n"); - } - break; - - case WINED3DFMT_B5G6R5_UNORM: - if (colorkey_active) - { - *conversion_type = WINED3D_CT_CK_565; - format->glFormat = GL_RGBA; - format->glInternal = GL_RGB5_A1; - format->glType = GL_UNSIGNED_SHORT_5_5_5_1; - format->conv_byte_count = 2; - } - break; - - case WINED3DFMT_B5G5R5X1_UNORM: - if (colorkey_active) - { - *conversion_type = WINED3D_CT_CK_5551; - format->glFormat = GL_BGRA; - format->glInternal = GL_RGB5_A1; - format->glType = GL_UNSIGNED_SHORT_1_5_5_5_REV; - format->conv_byte_count = 2; - } - break; - - case WINED3DFMT_B8G8R8_UNORM: - if (colorkey_active) - { - *conversion_type = WINED3D_CT_CK_RGB24; - format->glFormat = GL_RGBA; - format->glInternal = GL_RGBA8; - format->glType = GL_UNSIGNED_INT_8_8_8_8; - format->conv_byte_count = 4; - } - break; - - case WINED3DFMT_B8G8R8X8_UNORM: - if (colorkey_active) - { - *conversion_type = WINED3D_CT_RGB32_888; - format->glFormat = GL_RGBA; - format->glInternal = GL_RGBA8; - format->glType = GL_UNSIGNED_INT_8_8_8_8; - format->conv_byte_count = 4; - } - break; - - case WINED3DFMT_B8G8R8A8_UNORM: - if (colorkey_active) - { - *conversion_type = WINED3D_CT_CK_ARGB32; - format->conv_byte_count = 4; - } - break; - - default: - break; - } - - if (*conversion_type != WINED3D_CT_NONE) - { - format->rtInternal = format->glInternal; - format->glGammaInternal = format->glInternal; - } - - return WINED3D_OK; -} - static BOOL surface_check_block_align(struct wined3d_surface *surface, const RECT *rect) { UINT width_mask, height_mask; @@ -1731,10 +1604,8 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P const struct wined3d_format *src_format; const struct wined3d_format *dst_format; const struct wined3d_gl_info *gl_info; - enum wined3d_conversion_type convert; struct wined3d_context *context; struct wined3d_bo_address data; - struct wined3d_format format; UINT update_w, update_h; UINT dst_w, dst_h; RECT r, dst_rect; @@ -1808,8 +1679,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P } /* Use wined3d_surface_blt() instead of uploading directly if we need conversion. */ - d3dfmt_get_conv(dst_surface, FALSE, TRUE, &format, &convert); - if (convert != WINED3D_CT_NONE || format.convert) + if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); context = context_acquire(dst_surface->resource.device, NULL); @@ -1819,7 +1689,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P * the texture wouldn't be the current location, and we'd upload zeroes * just to overwrite them again. */ if (update_w == dst_w && update_h == dst_h) - surface_prepare_texture(dst_surface, context, FALSE); + wined3d_texture_prepare_texture(dst_surface->container, context, FALSE); else surface_load_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_bind(dst_surface->container, context, FALSE); @@ -1827,7 +1697,8 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P surface_get_memory(src_surface, &data, src_surface->locations); src_pitch = wined3d_surface_get_pitch(src_surface); - surface_upload_data(dst_surface, gl_info, src_format, src_rect, src_pitch, dst_point, FALSE, &data); + wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, + src_pitch, dst_point, FALSE, wined3d_const_bo_address(&data)); context_invalidate_active_texture(context); @@ -1839,83 +1710,6 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P return WINED3D_OK; } -/* This call just allocates the texture, the caller is responsible for binding - * the correct texture. */ -/* Context activation is done by the caller. */ -static void surface_allocate_surface(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, - const struct wined3d_format *format, BOOL srgb) -{ - BOOL disable_client_storage = FALSE; - GLsizei width = surface->pow2Width; - GLsizei height = surface->pow2Height; - const BYTE *mem = NULL; - GLenum internal; - - if (srgb) - internal = format->glGammaInternal; - else if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET - && wined3d_resource_is_offscreen(&surface->container->resource)) - internal = format->rtInternal; - else - internal = format->glInternal; - - if (!internal) - FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id)); - - if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE) - { - height *= format->height_scale.numerator; - height /= format->height_scale.denominator; - } - - TRACE("(%p) : Creating surface (target %#x) level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n", - surface, surface->texture_target, surface->texture_level, debug_d3dformat(format->id), - internal, width, height, format->glFormat, format->glType); - - if (gl_info->supported[APPLE_CLIENT_STORAGE]) - { - if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_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... - * SFLAG_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)"); - disable_client_storage = TRUE; - } - } - - if (format->flags & WINED3DFMT_FLAG_COMPRESSED && mem) - { - GL_EXTCALL(glCompressedTexImage2DARB(surface->texture_target, surface->texture_level, - internal, width, height, 0, surface->resource.size, mem)); - checkGLcall("glCompressedTexImage2DARB"); - } - 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 (disable_client_storage) - { - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); - checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)"); - } -} - /* In D3D the depth stencil dimensions have to be greater than or equal to the * render target dimensions. With FBOs, the dimensions have to be an exact match. */ /* TODO: We should synchronize the renderbuffer's content with the texture's content. */ @@ -2018,43 +1812,18 @@ GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) void surface_load(struct wined3d_surface *surface, BOOL srgb) { DWORD location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; - BOOL ck_changed; TRACE("surface %p, srgb %#x.\n", surface, srgb); if (surface->resource.pool == WINED3D_POOL_SCRATCH) ERR("Not supported on scratch surfaces.\n"); - ck_changed = !(surface->flags & SFLAG_GLCKEY) != !(surface->container->color_key_flags & WINEDDSD_CKSRCBLT); - - /* Reload if either the texture and sysmem have different ideas about the - * color key, or the actual key values changed. */ - if (ck_changed || ((surface->container->color_key_flags & WINEDDSD_CKSRCBLT) - && (surface->gl_color_key.color_space_low_value - != surface->container->src_blt_color_key.color_space_low_value - || surface->gl_color_key.color_space_high_value - != surface->container->src_blt_color_key.color_space_high_value))) - { - TRACE("Reloading because of color keying\n"); - /* To perform the color key conversion we need a sysmem copy of - * the surface. Make sure we have it. */ - - surface_prepare_map_memory(surface); - surface_load_location(surface, surface->resource.map_binding); - surface_invalidate_location(surface, ~surface->resource.map_binding); - /* Switching color keying on / off may change the internal format. */ - if (ck_changed) - surface_force_reload(surface); - } - else if (!(surface->locations & location)) - { - TRACE("Reloading because surface is dirty.\n"); - } - else + if (surface->locations & location) { TRACE("surface is already in texture\n"); return; } + TRACE("Reloading because surface is dirty.\n"); surface_load_location(surface, location); surface_evict_sysmem(surface); @@ -2361,35 +2130,14 @@ HRESULT CDECL wined3d_surface_update_overlay(struct wined3d_surface *surface, co return WINED3D_OK; } -HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface, - UINT width, UINT height, enum wined3d_format_id format_id, - enum wined3d_multisample_type multisample_type, UINT multisample_quality, - void *mem, UINT pitch) +HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, + const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) { - struct wined3d_device *device = surface->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, format_id); - UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1); - struct wined3d_texture *texture; + struct wined3d_resource *texture_resource = &surface->container->resource; + unsigned int width, height; BOOL create_dib = FALSE; - HRESULT hr; DWORD valid_location = 0; - - TRACE("surface %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, " - "mem %p, pitch %u.\n", - surface, width, height, debug_d3dformat(format_id), multisample_type, multisample_type, mem, pitch); - - if (!resource_size) - return WINED3DERR_INVALIDCALL; - - if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE)) - { - WARN("Surface is mapped or the DC is in use.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (device->d3d_initialized) - surface->resource.resource_ops->resource_unload(&surface->resource); + HRESULT hr; if (surface->flags & SFLAG_DIBSECTION) { @@ -2403,6 +2151,8 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface, surface->locations = 0; wined3d_resource_free_sysmem(&surface->resource); + width = texture_resource->width; + height = texture_resource->height; surface->resource.width = width; surface->resource.height = height; if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[ARB_TEXTURE_RECTANGLE] @@ -2425,20 +2175,26 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface, else surface->flags &= ~SFLAG_NONPOW2; - surface->user_memory = mem; - if (surface->user_memory) + if ((surface->user_memory = mem)) { surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; valid_location = WINED3D_LOCATION_USER_MEMORY; } surface->pitch = pitch; - surface->resource.format = format; - surface->resource.multisample_type = multisample_type; - surface->resource.multisample_quality = multisample_quality; + surface->resource.format = texture_resource->format; + surface->resource.multisample_type = texture_resource->multisample_type; + surface->resource.multisample_quality = texture_resource->multisample_quality; if (surface->pitch) + { surface->resource.size = height * surface->pitch; + } else - surface->resource.size = resource_size; + { + /* User memory surfaces don't have the regular surface alignment. */ + surface->resource.size = wined3d_format_calculate_size(texture_resource->format, + 1, width, height, 1); + surface->pitch = wined3d_format_calculate_pitch(texture_resource->format, width); + } /* The format might be changed to a format that needs conversion. * If the surface didn't use PBOs previously but could now, don't @@ -2447,13 +2203,6 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface, if (surface->resource.map_binding == WINED3D_LOCATION_BUFFER && !surface_use_pbo(surface)) surface->resource.map_binding = create_dib ? WINED3D_LOCATION_DIB : WINED3D_LOCATION_SYSMEM; - texture = surface->container; - texture->resource.format = format; - texture->resource.multisample_type = multisample_type; - texture->resource.multisample_quality = multisample_quality; - texture->resource.width = width; - texture->resource.height = height; - if (create_dib) { if (FAILED(hr = surface_create_dib_section(surface))) @@ -2645,6 +2394,126 @@ static void convert_yuy2_r5g6b5(const BYTE *src, BYTE *dst, } } +static void convert_dxt1_a8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} + +static void convert_dxt1_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} + +static void convert_dxt1_a4r4g4b4(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h); +} + +static void convert_dxt1_x4r4g4b4(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h); +} + +static void convert_dxt1_a1r5g5b5(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h); +} + +static void convert_dxt1_x1r5g5b5(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h); +} + +static void convert_dxt3_a8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} + +static void convert_dxt3_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} + +static void convert_dxt3_a4r4g4b4(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h); +} + +static void convert_dxt3_x4r4g4b4(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h); +} + +static void convert_dxt5_a8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt5_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} + +static void convert_dxt5_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt5_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} + +static void convert_a8r8g8b8_dxt1(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} + +static void convert_x8r8g8b8_dxt1(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} + +static void convert_a1r5g5b5_dxt1(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h); +} + +static void convert_x1r5g5b5_dxt1(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h); +} + +static void convert_a8r8g8b8_dxt3(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} + +static void convert_x8r8g8b8_dxt3(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} + +static void convert_a8r8g8b8_dxt5(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} + +static void convert_x8r8g8b8_dxt5(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} + struct d3dfmt_converter_desc { enum wined3d_format_id from, to; @@ -2661,6 +2530,33 @@ static const struct d3dfmt_converter_desc converters[] = {WINED3DFMT_YUY2, WINED3DFMT_B5G6R5_UNORM, convert_yuy2_r5g6b5}, }; +static const struct d3dfmt_converter_desc dxtn_converters[] = +{ + /* decode DXT */ + {WINED3DFMT_DXT1, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt1_a8r8g8b8}, + {WINED3DFMT_DXT1, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt1_x8r8g8b8}, + {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt1_a4r4g4b4}, + {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt1_x4r4g4b4}, + {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5A1_UNORM, convert_dxt1_a1r5g5b5}, + {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5X1_UNORM, convert_dxt1_x1r5g5b5}, + {WINED3DFMT_DXT3, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt3_a8r8g8b8}, + {WINED3DFMT_DXT3, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt3_x8r8g8b8}, + {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt3_a4r4g4b4}, + {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt3_x4r4g4b4}, + {WINED3DFMT_DXT5, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt5_a8r8g8b8}, + {WINED3DFMT_DXT5, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt5_x8r8g8b8}, + + /* encode DXT */ + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT1, convert_a8r8g8b8_dxt1}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT1, convert_x8r8g8b8_dxt1}, + {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_DXT1, convert_a1r5g5b5_dxt1}, + {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_DXT1, convert_x1r5g5b5_dxt1}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT3, convert_a8r8g8b8_dxt3}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT3, convert_x8r8g8b8_dxt3}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT5, convert_a8r8g8b8_dxt5}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT5, convert_x8r8g8b8_dxt5} +}; + static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from, enum wined3d_format_id to) { @@ -2672,6 +2568,12 @@ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_fo return &converters[i]; } + for (i = 0; i < (sizeof(dxtn_converters) / sizeof(*dxtn_converters)); ++i) + { + if (dxtn_converters[i].from == from && dxtn_converters[i].to == to) + return wined3d_dxtn_supported() ? &dxtn_converters[i] : NULL; + } + return NULL; } @@ -2698,7 +2600,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_surface *so desc.usage = 0; desc.pool = WINED3D_POOL_SCRATCH; if (FAILED(wined3d_texture_create(source->resource.device, &desc, 1, - WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, &wined3d_null_parent_ops, &ret))) + WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, NULL, &wined3d_null_parent_ops, &ret))) { ERR("Failed to create a destination surface for conversion.\n"); return NULL; @@ -2846,13 +2748,15 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, /* Performance optimization: Count how often a surface is mapped, if it is * mapped regularly do not throw away the system memory copy. This avoids * the need to download the surface from OpenGL all the time. The surface - * is still downloaded if the OpenGL texture is changed. */ - if (!(surface->flags & SFLAG_DYNLOCK) && surface->resource.map_binding == WINED3D_LOCATION_SYSMEM) + * is still downloaded if the OpenGL texture is changed. Note that this + * only really makes sense for managed textures.*/ + if (!(surface->container->flags & WINED3D_TEXTURE_DYNAMIC_MAP) + && surface->resource.map_binding == WINED3D_LOCATION_SYSMEM) { if (++surface->lockCount > MAXLOCKCOUNT) { TRACE("Surface is mapped regularly, not freeing the system memory copy any more.\n"); - surface->flags |= SFLAG_DYNLOCK; + surface->container->flags |= WINED3D_TEXTURE_DYNAMIC_MAP; } } @@ -2892,9 +2796,9 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, context = context_acquire(device, NULL); gl_info = context->gl_info; - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo)); - base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB)); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); + base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("map PBO"); context_release(context); @@ -2973,7 +2877,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) if (FAILED(hr)) return WINED3DERR_INVALIDCALL; if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || surface->flags & SFLAG_PIN_SYSMEM + || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM || surface->pbo)) surface->resource.map_binding = WINED3D_LOCATION_DIB; } @@ -3007,7 +2911,8 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) surface->resource.map_count--; surface->flags &= ~SFLAG_DCINUSE; - if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY || (surface->flags & SFLAG_PIN_SYSMEM + if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY + || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM && surface->resource.map_binding != WINED3D_LOCATION_DIB)) { /* The game Salammbo modifies the surface contents without mapping the surface between @@ -3065,12 +2970,13 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc 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"); } /* Setup pixel store pack state -- to glReadPixels into the correct place */ - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, surface->resource.width); + gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, + wined3d_surface_get_pitch(surface) / surface->resource.format->byte_count); checkGLcall("glPixelStorei"); gl_info->gl_ops.gl.p_glReadPixels(0, 0, @@ -3094,8 +3000,8 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc if (data.buffer_object) { - mem = GL_EXTCALL(glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_WRITE_ARB)); - checkGLcall("glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_WRITE_ARB)"); + mem = GL_EXTCALL(glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE)); + checkGLcall("glMapBuffer"); } else mem = data.addr; @@ -3113,14 +3019,14 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc HeapFree(GetProcessHeap(), 0, row); if (data.buffer_object) - GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB)); + GL_EXTCALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER)); } error: if (data.buffer_object) { - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); - checkGLcall("glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)"); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); } context_release(context); @@ -3139,7 +3045,7 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb) gl_info = context->gl_info; device_invalidate_state(device, STATE_FRAMEBUFFER); - surface_prepare_texture(surface, context, srgb); + wined3d_texture_prepare_texture(surface->container, context, srgb); wined3d_texture_bind_and_dirtify(surface->container, context, srgb); TRACE("Reading back offscreen render target %p.\n", surface); @@ -3157,44 +3063,6 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb) context_release(context); } -/* Context activation is done by the caller. */ -static void surface_prepare_texture_internal(struct wined3d_surface *surface, - struct wined3d_context *context, BOOL srgb) -{ - DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED; - enum wined3d_conversion_type convert; - struct wined3d_format format; - - if (surface->flags & alloc_flag) return; - - d3dfmt_get_conv(surface, TRUE, TRUE, &format, &convert); - if (convert != WINED3D_CT_NONE || format.convert) - surface->flags |= SFLAG_CONVERTED; - else surface->flags &= ~SFLAG_CONVERTED; - - wined3d_texture_bind_and_dirtify(surface->container, context, srgb); - surface_allocate_surface(surface, context->gl_info, &format, srgb); - surface->flags |= alloc_flag; -} - -/* Context activation is done by the caller. */ -void surface_prepare_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) -{ - struct wined3d_texture *texture = surface->container; - UINT sub_count = texture->level_count * texture->layer_count; - UINT i; - - TRACE("surface %p is a subresource of texture %p.\n", surface, texture); - - for (i = 0; i < sub_count; ++i) - { - struct wined3d_surface *s = surface_from_resource(texture->sub_resources[i]); - surface_prepare_texture_internal(s, context, srgb); - } - - return; -} - void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample) { if (multisample) @@ -3221,190 +3089,6 @@ void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl } } -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 HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height, - UINT outpitch, enum wined3d_conversion_type conversion_type, struct wined3d_surface *surface) -{ - const BYTE *source; - BYTE *dest; - - TRACE("src %p, dst %p, pitch %u, width %u, height %u, outpitch %u, conversion_type %#x, surface %p.\n", - src, dst, pitch, width, height, outpitch, conversion_type, surface); - - switch (conversion_type) - { - case WINED3D_CT_NONE: - { - memcpy(dst, src, pitch * height); - break; - } - - case WINED3D_CT_PALETTED: - if (surface->container->swapchain && surface->container->swapchain->palette) - { - unsigned int x, y; - const struct wined3d_palette *palette = surface->container->swapchain->palette; - for (y = 0; y < height; y++) - { - source = src + pitch * y; - dest = dst + outpitch * y; - for (x = 0; x < width; x++) - { - BYTE color = *source++; - *dest++ = palette->colors[color].rgbRed; - *dest++ = palette->colors[color].rgbGreen; - *dest++ = palette->colors[color].rgbBlue; - *dest++ = 0; - } - } - } - else - { - /* This should probably use the system palette, but unless - * the X server is running in P8 mode there is no such thing. - * The probably best solution is to set the fixed 20 colors - * from the default windows palette and set the rest to black, - * white, or some ugly pink. For now use black for the entire - * palette. Don't use pink everywhere. Age of Empires 2 draws - * a front buffer filled with zeroes without a palette when - * starting and we don't want the screen to flash in an ugly - * color. */ - FIXME("P8 surface loaded without a palette.\n"); - memset(dst, 0, height * outpitch); - } - - break; - - case WINED3D_CT_CK_565: - { - /* Converting the 565 format in 5551 packed to emulate color-keying. - - Note : in all these conversion, it would be best to average the averaging - pixels to get the color of the pixel that will be color-keyed to - prevent 'color bleeding'. This will be done later on if ever it is - too visible. - - Note2: Nvidia documents say that their driver does not support alpha + color keying - on the same surface and disables color keying in such a case - */ - unsigned int x, y; - const WORD *Source; - WORD *Dest; - - TRACE("Color keyed 565\n"); - - for (y = 0; y < height; y++) { - Source = (const WORD *)(src + y * pitch); - Dest = (WORD *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) { - WORD color = *Source++; - *Dest = ((color & 0xffc0) | ((color & 0x1f) << 1)); - if (!color_in_range(&surface->container->src_blt_color_key, color)) - *Dest |= 0x0001; - Dest++; - } - } - } - break; - - case WINED3D_CT_CK_5551: - { - /* Converting X1R5G5B5 format to R5G5B5A1 to emulate color-keying. */ - unsigned int x, y; - const WORD *Source; - WORD *Dest; - TRACE("Color keyed 5551\n"); - for (y = 0; y < height; y++) { - Source = (const WORD *)(src + y * pitch); - Dest = (WORD *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) { - WORD color = *Source++; - *Dest = color; - if (!color_in_range(&surface->container->src_blt_color_key, color)) - *Dest |= (1 << 15); - else - *Dest &= ~(1 << 15); - Dest++; - } - } - } - break; - - case WINED3D_CT_CK_RGB24: - { - /* Converting R8G8B8 format to R8G8B8A8 with color-keying. */ - unsigned int x, y; - for (y = 0; y < height; y++) - { - source = src + pitch * y; - dest = dst + outpitch * y; - for (x = 0; x < width; x++) { - DWORD color = ((DWORD)source[0] << 16) + ((DWORD)source[1] << 8) + (DWORD)source[2] ; - DWORD dstcolor = color << 8; - if (!color_in_range(&surface->container->src_blt_color_key, color)) - dstcolor |= 0xff; - *(DWORD*)dest = dstcolor; - source += 3; - dest += 4; - } - } - } - break; - - case WINED3D_CT_RGB32_888: - { - /* Converting X8R8G8B8 format to R8G8B8A8 with color-keying. */ - unsigned int x, y; - for (y = 0; y < height; y++) - { - source = src + pitch * y; - dest = dst + outpitch * y; - for (x = 0; x < width; x++) { - DWORD color = 0xffffff & *(const DWORD*)source; - DWORD dstcolor = color << 8; - if (!color_in_range(&surface->container->src_blt_color_key, color)) - dstcolor |= 0xff; - *(DWORD*)dest = dstcolor; - source += 4; - dest += 4; - } - } - } - break; - - case WINED3D_CT_CK_ARGB32: - { - unsigned int x, y; - for (y = 0; y < height; ++y) - { - source = src + pitch * y; - dest = dst + outpitch * y; - for (x = 0; x < width; ++x) - { - DWORD color = *(const DWORD *)source; - if (color_in_range(&surface->container->src_blt_color_key, color)) - color &= ~0xff000000; - *(DWORD*)dest = color; - source += 4; - dest += 4; - } - } - } - break; - - default: - ERR("Unsupported conversion type %#x.\n", conversion_type); - } - return WINED3D_OK; -} - void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) { if (front->container->level_count != 1 || front->container->layer_count != 1 @@ -3687,11 +3371,10 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st checkGLcall("glCopyTexSubImage2D"); /* No issue with overriding these - the sampler is dirty due to blit usage */ - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, - wined3d_gl_mag_filter(magLookup, filter)); + gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter)); checkGLcall("glTexParameteri"); gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, - wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE)); + wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE)); checkGLcall("glTexParameteri"); if (!src_surface->container->swapchain @@ -3747,7 +3430,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st bottom = src_surface->resource.height - src_rect->top; } - if (src_surface->flags & SFLAG_NORMCOORD) + if (src_surface->container->flags & WINED3D_TEXTURE_NORMALIZED_COORDS) { left /= src_surface->pow2Width; right /= src_surface->pow2Width; @@ -3756,8 +3439,8 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st } /* draw the source texture stretched and upside down. The correct surface is bound already */ - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP); - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP); + gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); context_set_draw_buffer(context, drawBuffer); gl_info->gl_ops.gl.p_glReadBuffer(drawBuffer); @@ -3932,7 +3615,7 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, * other cases pixels that should be masked away have alpha set to 0. */ if (src_surface->resource.format->id == WINED3DFMT_P8_UINT) gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, - (float)src_surface->container->src_blt_color_key.color_space_low_value / 256.0f); + (float)src_surface->container->src_blt_color_key.color_space_low_value / 255.0f); else gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f); checkGLcall("glAlphaFunc"); @@ -4135,13 +3818,12 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE else if (flags & WINEDDBLT_KEYSRCOVERRIDE) { /* Use color key from DDBltFx */ - src_surface->container->color_key_flags |= WINEDDSD_CKSRCBLT; - src_surface->container->src_blt_color_key = DDBltFx->ddckSrcColorkey; + wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, &DDBltFx->ddckSrcColorkey); } else { /* Do not use color key */ - src_surface->container->color_key_flags &= ~WINEDDSD_CKSRCBLT; + wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, NULL); } surface_blt_to_drawable(device, filter, @@ -4149,8 +3831,8 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE src_surface, src_rect, dst_surface, dst_rect); /* Restore the color key parameters */ - src_surface->container->color_key_flags = old_color_key_flags; - src_surface->container->src_blt_color_key = old_blt_key; + wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, + (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); @@ -4281,7 +3963,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co switch (location) { case WINED3D_LOCATION_TEXTURE_RGB: - surface_prepare_texture(surface, context, FALSE); + wined3d_texture_prepare_texture(surface->container, context, FALSE); break; case WINED3D_LOCATION_RB_MULTISAMPLE: surface_prepare_rb(surface, gl_info, TRUE); @@ -4453,9 +4135,9 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD { context = context_acquire(device, NULL); gl_info = context->gl_info; - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, dst.buffer_object)); - GL_EXTCALL(glBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, size, src.addr)); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); + GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("Upload PBO"); context_release(context); return; @@ -4464,9 +4146,9 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD { context = context_acquire(device, NULL); gl_info = context->gl_info; - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, src.buffer_object)); - GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_PACK_BUFFER_ARB, 0, size, dst.addr)); - GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); + GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); checkGLcall("Download PBO"); context_release(context); return; @@ -4539,7 +4221,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, { RECT src_rect = {0, 0, surface->resource.width, surface->resource.height}; struct wined3d_device *device = surface->resource.device; - enum wined3d_conversion_type convert; + const struct wined3d_color_key_conversion *conversion; + struct wined3d_texture *texture = surface->container; struct wined3d_context *context; UINT width, src_pitch, dst_pitch; struct wined3d_bo_address data; @@ -4548,7 +4231,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, BYTE *mem = NULL; if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && wined3d_resource_is_offscreen(&surface->container->resource) + && wined3d_resource_is_offscreen(&texture->resource) && (surface->locations & WINED3D_LOCATION_DRAWABLE)) { surface_load_fb_texture(surface, srgb); @@ -4591,9 +4274,6 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, /* Upload from system memory */ - d3dfmt_get_conv(surface, TRUE /* We need color keying */, - TRUE /* We will use textures */, &format, &convert); - if (srgb) { if ((surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding)) @@ -4628,23 +4308,20 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, /* TODO: Use already acquired context when possible. */ context = context_acquire(device, NULL); - surface_prepare_texture(surface, context, srgb); - wined3d_texture_bind_and_dirtify(surface->container, context, srgb); - - if (surface->container->color_key_flags & WINEDDSD_CKSRCBLT) - { - surface->flags |= SFLAG_GLCKEY; - surface->gl_color_key = surface->container->src_blt_color_key; - } - else surface->flags &= ~SFLAG_GLCKEY; + wined3d_texture_prepare_texture(texture, context, srgb); + wined3d_texture_bind_and_dirtify(texture, context, srgb); width = surface->resource.width; src_pitch = wined3d_surface_get_pitch(surface); + format = *texture->resource.format; + if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE))) + format = *wined3d_get_format(gl_info, conversion->dst_format); + /* Don't use PBOs for converted surfaces. During PBO conversion we look at - * SFLAG_CONVERTED but it isn't set (yet) in all cases it is getting - * called. */ - if ((convert != WINED3D_CT_NONE || format.convert) && surface->pbo) + * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is + * getting called. */ + if ((format.convert || conversion) && surface->pbo) { TRACE("Removing the pbo attached to surface %p.\n", surface); @@ -4664,9 +4341,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, /* This code is entered for texture formats which need a fixup. */ UINT height = surface->resource.height; - /* Stick to the alignment for the converted surface too, makes it easier to load the surface */ - dst_pitch = width * format.conv_byte_count; - dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); + format.byte_count = format.conv_byte_count; + dst_pitch = wined3d_format_calculate_pitch(&format, width); if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height))) { @@ -4676,17 +4352,16 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, } format.convert(data.addr, mem, src_pitch, src_pitch * height, dst_pitch, dst_pitch * height, width, height, 1); - format.byte_count = format.conv_byte_count; src_pitch = dst_pitch; data.addr = mem; } - else if (convert != WINED3D_CT_NONE) + else if (conversion) { /* This code is only entered for color keying fixups */ + struct wined3d_palette *palette = NULL; UINT height = surface->resource.height; - /* Stick to the alignment for the converted surface too, makes it easier to load the surface */ - dst_pitch = width * format.conv_byte_count; + dst_pitch = wined3d_format_calculate_pitch(&format, width); dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height))) @@ -4695,14 +4370,16 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, context_release(context); return E_OUTOFMEMORY; } - d3dfmt_convert_surface(data.addr, mem, src_pitch, - width, height, dst_pitch, convert, surface); - format.byte_count = format.conv_byte_count; + if (texture->swapchain && texture->swapchain->palette) + palette = texture->swapchain->palette; + conversion->convert(data.addr, src_pitch, mem, dst_pitch, + width, height, palette, &texture->gl_color_key); src_pitch = dst_pitch; data.addr = mem; } - surface_upload_data(surface, gl_info, &format, &src_rect, src_pitch, &dst_point, srgb, &data); + wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, + src_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); context_release(context); @@ -5624,8 +5301,6 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC DWORD src_ds_flags, dst_ds_flags; RECT src_rect, dst_rect; BOOL scale, convert; - enum wined3d_conversion_type dst_convert_type; - struct wined3d_format dst_conv_fmt; static const DWORD simple_blit = WINEDDBLT_ASYNC | WINEDDBLT_COLORFILL @@ -5740,8 +5415,9 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC /* We want to avoid invalidating the sysmem location for converted * surfaces, since otherwise we'd have to convert the data back when * locking them. */ - d3dfmt_get_conv(dst_surface, TRUE, TRUE, &dst_conv_fmt, &dst_convert_type); - if (dst_convert_type != WINED3D_CT_NONE || dst_conv_fmt.convert || dst_surface->flags & SFLAG_CONVERTED) + if (dst_surface->container->flags & WINED3D_TEXTURE_CONVERTED + || dst_surface->container->resource.format->convert + || wined3d_format_get_color_key_conversion(dst_surface->container, TRUE)) { WARN_(d3d_perf)("Converted surface, using CPU blit.\n"); goto cpu; @@ -5995,12 +5671,8 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text list_init(&surface->overlays); /* Flags */ - if (target != GL_TEXTURE_RECTANGLE_ARB) - surface->flags |= SFLAG_NORMCOORD; if (flags & WINED3D_SURFACE_DISCARD) surface->flags |= SFLAG_DISCARD; - if (flags & WINED3D_SURFACE_PIN_SYSMEM) - surface->flags |= SFLAG_PIN_SYSMEM; if (lockable || desc->format == WINED3DFMT_D16_LOCKABLE) surface->resource.access_flags |= WINED3D_RESOURCE_ACCESS_CPU; diff --git a/reactos/dll/directx/wine/wined3d/swapchain.c b/reactos/dll/directx/wine/wined3d/swapchain.c index 276fa3644eb..d9195728381 100644 --- a/reactos/dll/directx/wine/wined3d/swapchain.c +++ b/reactos/dll/directx/wine/wined3d/swapchain.c @@ -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; +} diff --git a/reactos/dll/directx/wine/wined3d/texture.c b/reactos/dll/directx/wine/wined3d/texture.c index fb8425cdaec..54ad91b45d2 100644 --- a/reactos/dll/directx/wine/wined3d/texture.c +++ b/reactos/dll/directx/wine/wined3d/texture.c @@ -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; diff --git a/reactos/dll/directx/wine/wined3d/utils.c b/reactos/dll/directx/wine/wined3d/utils.c index 18e5b21ca98..2591e119032 100644 --- a/reactos/dll/directx/wine/wined3d/utils.c +++ b/reactos/dll/directx/wine/wined3d/utils.c @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c index 1ffd3b9befe..b53b36bdd3e 100644 --- a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c +++ b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c @@ -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); diff --git a/reactos/dll/directx/wine/wined3d/view.c b/reactos/dll/directx/wine/wined3d/view.c index 2f79a60865c..7aa27d4295f 100644 --- a/reactos/dll/directx/wine/wined3d/view.c +++ b/reactos/dll/directx/wine/wined3d/view.c @@ -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; diff --git a/reactos/dll/directx/wine/wined3d/volume.c b/reactos/dll/directx/wine/wined3d/volume.c index f61825ad799..944996f98f1 100644 --- a/reactos/dll/directx/wine/wined3d/volume.c +++ b/reactos/dll/directx/wine/wined3d/volume.c @@ -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); diff --git a/reactos/dll/directx/wine/wined3d/wined3d.spec b/reactos/dll/directx/wine/wined3d/wined3d.spec index 615a85d49c1..4e6ebb7a8bb 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d.spec +++ b/reactos/dll/directx/wine/wined3d/wined3d.spec @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/wined3d_gl.h b/reactos/dll/directx/wine/wined3d/wined3d_gl.h index b02905e5734..3f0660164c2 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_gl.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_gl.h @@ -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 */ diff --git a/reactos/dll/directx/wine/wined3d/wined3d_main.c b/reactos/dll/directx/wine/wined3d/wined3d_main.c index 530287f3259..16a851eb3c0 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_main.c +++ b/reactos/dll/directx/wine/wined3d/wined3d_main.c @@ -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) { diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 81197174812..6e256e07815 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -61,6 +61,10 @@ #include "wined3d_gl.h" #include +#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 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 @@ -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" diff --git a/reactos/include/reactos/wine/wined3d.h b/reactos/include/reactos/wine/wined3d.h index fe90469e0ad..c0c438985cb 100644 --- a/reactos/include/reactos/wine/wined3d.h +++ b/reactos/include/reactos/wine/wined3d.h @@ -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 #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 */ diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index b72d3776cdf..f94215d9e77 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -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