diff --git a/dll/directx/wine/d3d8/CMakeLists.txt b/dll/directx/wine/d3d8/CMakeLists.txt index d3d49e2e76d..09d7a6c659d 100644 --- a/dll/directx/wine/d3d8/CMakeLists.txt +++ b/dll/directx/wine/d3d8/CMakeLists.txt @@ -19,7 +19,7 @@ list(APPEND SOURCE volume.c precomp.h) -add_library(d3d8 MODULE +add_library(d3d8 SHARED ${SOURCE} guid.c version.rc diff --git a/dll/directx/wine/d3d8/d3d8_private.h b/dll/directx/wine/d3d8/d3d8_private.h index 3fbc096b254..cba5dd647b4 100644 --- a/dll/directx/wine/d3d8/d3d8_private.h +++ b/dll/directx/wine/d3d8/d3d8_private.h @@ -166,11 +166,10 @@ struct d3d8_swapchain LONG refcount; struct wined3d_swapchain *wined3d_swapchain; IDirect3DDevice8 *parent_device; - unsigned int swap_interval; }; HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc, - unsigned int swap_interval, struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN; + struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN; struct d3d8_surface { diff --git a/dll/directx/wine/d3d8/device.c b/dll/directx/wine/d3d8/device.c index 616886bcafa..5daf6f46c2a 100644 --- a/dll/directx/wine/d3d8/device.c +++ b/dll/directx/wine/d3d8/device.c @@ -209,7 +209,7 @@ static D3DSWAPEFFECT d3dswapeffect_from_wined3dswapeffect(enum wined3d_swap_effe } static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, - const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) + const struct wined3d_swapchain_desc *swapchain_desc) { present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width; present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height; @@ -224,7 +224,7 @@ static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format); present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK; present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate; - present_parameters->FullScreen_PresentationInterval = presentation_interval; + present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval; } static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect) @@ -245,27 +245,6 @@ static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFE } } -static enum wined3d_swap_interval wined3dswapinterval_from_d3d(DWORD interval) -{ - switch (interval) - { - case D3DPRESENT_INTERVAL_IMMEDIATE: - return WINED3D_SWAP_INTERVAL_IMMEDIATE; - case D3DPRESENT_INTERVAL_ONE: - return WINED3D_SWAP_INTERVAL_ONE; - case D3DPRESENT_INTERVAL_TWO: - return WINED3D_SWAP_INTERVAL_TWO; - case D3DPRESENT_INTERVAL_THREE: - return WINED3D_SWAP_INTERVAL_THREE; - case D3DPRESENT_INTERVAL_FOUR: - return WINED3D_SWAP_INTERVAL_FOUR; - default: - FIXME("Unhandled presentation interval %#x.\n", interval); - case D3DPRESENT_INTERVAL_DEFAULT: - return WINED3D_SWAP_INTERVAL_DEFAULT; - } -} - static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc, const D3DPRESENT_PARAMETERS *present_parameters) { @@ -282,20 +261,6 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount); return FALSE; } - switch (present_parameters->FullScreen_PresentationInterval) - { - case D3DPRESENT_INTERVAL_DEFAULT: - case D3DPRESENT_INTERVAL_ONE: - case D3DPRESENT_INTERVAL_TWO: - case D3DPRESENT_INTERVAL_THREE: - case D3DPRESENT_INTERVAL_FOUR: - case D3DPRESENT_INTERVAL_IMMEDIATE: - break; - default: - WARN("Invalid presentation interval %#x.\n", - present_parameters->FullScreen_PresentationInterval); - return FALSE; - } swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth; swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight; @@ -313,6 +278,7 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch swapchain_desc->flags = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; + swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval; swapchain_desc->auto_restore_display_mode = TRUE; if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK) @@ -328,7 +294,7 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) caps->Caps = wined3d_caps->Caps; caps->Caps2 = wined3d_caps->Caps2; caps->Caps3 = wined3d_caps->Caps3; - caps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE; + caps->PresentationIntervals = wined3d_caps->PresentationIntervals; caps->CursorCaps = wined3d_caps->CursorCaps; caps->DevCaps = wined3d_caps->DevCaps; caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps; @@ -377,57 +343,6 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) caps->PixelShaderVersion = wined3d_caps->PixelShaderVersion; caps->MaxPixelShaderValue = wined3d_caps->PixelShader1xMaxValue; - caps->Caps2 &= D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_CANRENDERWINDOWED - | D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_FULLSCREENGAMMA - | D3DCAPS2_NO2DDURING3DSCENE | D3DCAPS2_RESERVED; - caps->Caps3 &= D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | D3DCAPS3_RESERVED; - caps->PrimitiveMiscCaps &= D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP - | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW - | D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPPLANESCALEDPOINTS - | D3DPMISCCAPS_CLIPTLVERTS | D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_BLENDOP - | D3DPMISCCAPS_NULLREFERENCE; - caps->RasterCaps &= D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST - | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_ANTIALIASEDGES - | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR - | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER - | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE - | D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE; - caps->SrcBlendCaps &= D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR - | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA - | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR - | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA - | D3DPBLENDCAPS_BOTHINVSRCALPHA; - caps->DestBlendCaps &= D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR - | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA - | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR - | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA - | D3DPBLENDCAPS_BOTHINVSRCALPHA; - caps->TextureCaps &= D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA - | D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE - | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_NONPOW2CONDITIONAL - | D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP - | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP - | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2; - caps->TextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR - | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT - | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR - | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC - | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC; - caps->CubeTextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR - | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT - | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR - | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC - | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC; - caps->VolumeTextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR - | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT - | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR - | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC - | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC; - caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED; - caps->VertexProcessingCaps &= D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 - | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER - | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_NO_VSDT_UBYTE4; - /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */ if (caps->PixelShaderVersion) caps->PixelShaderVersion = D3DPS_VERSION(1, 4); @@ -438,6 +353,8 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) else caps->VertexShaderVersion = D3DVS_VERSION(0, 0); caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); + + caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED; } /* Handle table functions */ @@ -781,8 +698,7 @@ 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; - unsigned int swap_interval; - unsigned int i, count; + UINT i, count; HRESULT hr; TRACE("iface %p, present_parameters %p, swapchain %p.\n", @@ -814,11 +730,9 @@ static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters)) return D3DERR_INVALIDCALL; - swap_interval = wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval); - if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, swap_interval, &object))) + if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object))) *swapchain = &object->IDirect3DSwapChain8_iface; - present_parameters_from_wined3d_swapchain_desc(present_parameters, - &desc, present_parameters->FullScreen_PresentationInterval); + present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc); return hr; } @@ -892,8 +806,6 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, NULL, reset_enum_callback, TRUE))) { present_parameters->BackBufferCount = swapchain_desc.backbuffer_count; - device->implicit_swapchain->swap_interval - = wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); @@ -1619,30 +1531,10 @@ static HRESULT WINAPI d3d8_device_MultiplyTransform(IDirect3DDevice8 *iface, static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); - struct wined3d_sub_resource_desc rt_desc; - struct wined3d_rendertarget_view *rtv; - struct d3d8_surface *surface; struct wined3d_viewport vp; TRACE("iface %p, viewport %p.\n", iface, viewport); - wined3d_mutex_lock(); - if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) - { - wined3d_mutex_unlock(); - return D3DERR_NOTFOUND; - } - surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); - wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); - - if (viewport->X > rt_desc.width || viewport->Width > rt_desc.width - viewport->X - || viewport->Y > rt_desc.height || viewport->Height > rt_desc.height - viewport->Y) - { - WARN("Invalid viewport, returning D3DERR_INVALIDCALL.\n"); - wined3d_mutex_unlock(); - return D3DERR_INVALIDCALL; - } - vp.x = viewport->X; vp.y = viewport->Y; vp.width = viewport->Width; @@ -1650,7 +1542,8 @@ static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3D vp.min_z = viewport->MinZ; vp.max_z = viewport->MaxZ; - wined3d_device_set_viewports(device->wined3d_device, 1, &vp); + wined3d_mutex_lock(); + wined3d_device_set_viewport(device->wined3d_device, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -1664,7 +1557,7 @@ static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8 *iface, D3DVIEWPO TRACE("iface %p, viewport %p.\n", iface, viewport); wined3d_mutex_lock(); - wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport); + wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); wined3d_mutex_unlock(); viewport->X = wined3d_viewport.x; @@ -2187,11 +2080,9 @@ static HRESULT WINAPI d3d8_device_ValidateDevice(IDirect3DDevice8 *iface, DWORD static HRESULT WINAPI d3d8_device_GetInfo(IDirect3DDevice8 *iface, DWORD info_id, void *info, DWORD info_size) { - TRACE("iface %p, info_id %#x, info %p, info_size %u.\n", iface, info_id, info, info_size); + FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface, info_id, info, info_size); - if (info_id < 4) - return E_FAIL; - return S_FALSE; + return D3D_OK; } static HRESULT WINAPI d3d8_device_SetPaletteEntries(IDirect3DDevice8 *iface, @@ -3271,40 +3162,40 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa InterlockedCompareExchange(&device->device_state, D3D8_DEVICE_STATE_NOT_RESET, D3D8_DEVICE_STATE_LOST); } -static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent, - enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, +static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops) { - TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops); + struct d3d8_surface *d3d_surface; - if (type == WINED3D_RTYPE_TEXTURE_2D) - { - struct d3d8_surface *d3d_surface; + TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); - if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) - return E_OUTOFMEMORY; + if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) + return E_OUTOFMEMORY; - surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); - *parent = d3d_surface; - TRACE("Created surface %p.\n", d3d_surface); - } - else if (type == WINED3D_RTYPE_TEXTURE_3D) - { - struct d3d8_volume *d3d_volume; + surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); + *parent = d3d_surface; + TRACE("Created surface %p.\n", d3d_surface); - if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume)))) - return E_OUTOFMEMORY; + return D3D_OK; +} - volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); - *parent = d3d_volume; - TRACE("Created volume %p.\n", d3d_volume); - } - else - { - ERR("Unhandled resource type %#x.\n", type); - return E_FAIL; - } +static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, + void **parent, const struct wined3d_parent_ops **parent_ops) +{ + struct d3d8_volume *d3d_volume; + + TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); + + if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume)))) + return E_OUTOFMEMORY; + + volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); + *parent = d3d_volume; + TRACE("Created volume %p.\n", d3d_volume); return D3D_OK; } @@ -3343,7 +3234,7 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain); - if (FAILED(hr = d3d8_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT, &d3d_swapchain))) + if (FAILED(hr = d3d8_swapchain_create(device, desc, &d3d_swapchain))) { WARN("Failed to create swapchain, hr %#x.\n", hr); *swapchain = NULL; @@ -3362,7 +3253,8 @@ static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops = device_parent_wined3d_device_created, device_parent_mode_changed, device_parent_activate, - device_parent_texture_sub_resource_created, + device_parent_surface_created, + device_parent_volume_created, device_parent_create_swapchain_texture, device_parent_create_swapchain, }; @@ -3464,8 +3356,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); wined3d_mutex_unlock(); - present_parameters_from_wined3d_swapchain_desc(parameters, - &swapchain_desc, parameters->FullScreen_PresentationInterval); + present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc); device->declArraySize = 16; if (!(device->decls = heap_alloc(device->declArraySize * sizeof(*device->decls)))) @@ -3477,8 +3368,6 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0); device->implicit_swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); - device->implicit_swapchain->swap_interval - = wined3dswapinterval_from_d3d(parameters->FullScreen_PresentationInterval); device->d3d_parent = &parent->IDirect3D8_iface; IDirect3D8_AddRef(device->d3d_parent); diff --git a/dll/directx/wine/d3d8/directx.c b/dll/directx/wine/d3d8/directx.c index 68300c0a655..6e8f93a25c6 100644 --- a/dll/directx/wine/d3d8/directx.c +++ b/dll/directx/wine/d3d8/directx.c @@ -417,7 +417,7 @@ BOOL d3d8_init(struct d3d8 *d3d8) DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART - | WINED3D_LEGACY_CUBEMAP_FILTERING; + | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT; d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl; d3d8->refcount = 1; diff --git a/dll/directx/wine/d3d8/swapchain.c b/dll/directx/wine/d3d8/swapchain.c index 39e3b238739..3a588b5e8c2 100644 --- a/dll/directx/wine/d3d8/swapchain.c +++ b/dll/directx/wine/d3d8/swapchain.c @@ -105,7 +105,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai wined3d_mutex_lock(); hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0); + src_rect, dst_rect, dst_window_override, 0, 0); wined3d_mutex_unlock(); return hr; @@ -167,13 +167,12 @@ static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops = }; static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_device *device, - struct wined3d_swapchain_desc *desc, unsigned int swap_interval) + struct wined3d_swapchain_desc *desc) { HRESULT hr; swapchain->refcount = 1; swapchain->IDirect3DSwapChain8_iface.lpVtbl = &d3d8_swapchain_vtbl; - swapchain->swap_interval = swap_interval; wined3d_mutex_lock(); hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, @@ -193,7 +192,7 @@ static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_devi } HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc, - unsigned int swap_interval, struct d3d8_swapchain **swapchain) + struct d3d8_swapchain **swapchain) { struct d3d8_swapchain *object; HRESULT hr; @@ -201,7 +200,7 @@ HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapcha if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = swapchain_init(object, device, desc, swap_interval))) + if (FAILED(hr = swapchain_init(object, device, desc))) { WARN("Failed to initialize swapchain, hr %#x.\n", hr); heap_free(object); diff --git a/dll/directx/wine/d3d9/CMakeLists.txt b/dll/directx/wine/d3d9/CMakeLists.txt index 14dd3e65320..223606b87ee 100644 --- a/dll/directx/wine/d3d9/CMakeLists.txt +++ b/dll/directx/wine/d3d9/CMakeLists.txt @@ -21,7 +21,7 @@ list(APPEND SOURCE volume.c precomp.h) -add_library(d3d9 MODULE +add_library(d3d9 SHARED ${SOURCE} guid.c version.rc diff --git a/dll/directx/wine/d3d9/d3d9_private.h b/dll/directx/wine/d3d9/d3d9_private.h index 408661306ad..094707a0d16 100644 --- a/dll/directx/wine/d3d9/d3d9_private.h +++ b/dll/directx/wine/d3d9/d3d9_private.h @@ -55,7 +55,7 @@ BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN; unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) DECLSPEC_HIDDEN; void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, - const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) DECLSPEC_HIDDEN; + const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN; void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN; struct d3d9 @@ -99,6 +99,7 @@ struct d3d9_device UINT index_buffer_size; UINT index_buffer_pos; + struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS]; struct d3d9_surface *render_targets[D3D_MAX_SIMULTANEOUS_RENDERTARGETS]; LONG device_state; @@ -148,11 +149,10 @@ struct d3d9_swapchain LONG refcount; struct wined3d_swapchain *wined3d_swapchain; IDirect3DDevice9Ex *parent_device; - unsigned int swap_interval; }; HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc, - unsigned int swap_interval, struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN; + struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN; struct d3d9_surface { diff --git a/dll/directx/wine/d3d9/device.c b/dll/directx/wine/d3d9/device.c index 2f3ad2880d6..bc73699e525 100644 --- a/dll/directx/wine/d3d9/device.c +++ b/dll/directx/wine/d3d9/device.c @@ -231,7 +231,7 @@ static D3DSWAPEFFECT d3dswapeffect_from_wined3dswapeffect(enum wined3d_swap_effe } void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, - const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) + const struct wined3d_swapchain_desc *swapchain_desc) { present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width; present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height; @@ -247,7 +247,7 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format); present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK; present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate; - present_parameters->PresentationInterval = presentation_interval; + present_parameters->PresentationInterval = swapchain_desc->swap_interval; } static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect) @@ -270,27 +270,6 @@ static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFE } } -static enum wined3d_swap_interval wined3dswapinterval_from_d3d(DWORD interval) -{ - switch (interval) - { - case D3DPRESENT_INTERVAL_IMMEDIATE: - return WINED3D_SWAP_INTERVAL_IMMEDIATE; - case D3DPRESENT_INTERVAL_ONE: - return WINED3D_SWAP_INTERVAL_ONE; - case D3DPRESENT_INTERVAL_TWO: - return WINED3D_SWAP_INTERVAL_TWO; - case D3DPRESENT_INTERVAL_THREE: - return WINED3D_SWAP_INTERVAL_THREE; - case D3DPRESENT_INTERVAL_FOUR: - return WINED3D_SWAP_INTERVAL_FOUR; - default: - FIXME("Unhandled presentation interval %#x.\n", interval); - case D3DPRESENT_INTERVAL_DEFAULT: - return WINED3D_SWAP_INTERVAL_DEFAULT; - } -} - static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc, const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended) { @@ -309,19 +288,6 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount); return FALSE; } - switch (present_parameters->PresentationInterval) - { - case D3DPRESENT_INTERVAL_DEFAULT: - case D3DPRESENT_INTERVAL_ONE: - case D3DPRESENT_INTERVAL_TWO: - case D3DPRESENT_INTERVAL_THREE: - case D3DPRESENT_INTERVAL_FOUR: - case D3DPRESENT_INTERVAL_IMMEDIATE: - break; - default: - WARN("Invalid presentation interval %#x.\n", present_parameters->PresentationInterval); - return FALSE; - } swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth; swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight; @@ -339,6 +305,7 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch swapchain_desc->flags = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; + swapchain_desc->swap_interval = present_parameters->PresentationInterval; swapchain_desc->auto_restore_display_mode = TRUE; if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK) @@ -363,7 +330,7 @@ void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) caps->Caps = wined3d_caps->Caps; caps->Caps2 = wined3d_caps->Caps2; caps->Caps3 = wined3d_caps->Caps3; - caps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE; + caps->PresentationIntervals = wined3d_caps->PresentationIntervals; caps->CursorCaps = wined3d_caps->CursorCaps; caps->DevCaps = wined3d_caps->DevCaps; caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps; @@ -776,8 +743,7 @@ 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; - unsigned int swap_interval; - unsigned int i, count; + UINT i, count; HRESULT hr; TRACE("iface %p, present_parameters %p, swapchain %p.\n", @@ -810,11 +776,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters, device->d3d_parent->extended)) return D3DERR_INVALIDCALL; - swap_interval = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval); - if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, swap_interval, &object))) + if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object))) *swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface; - present_parameters_from_wined3d_swapchain_desc(present_parameters, - &desc, present_parameters->PresentationInterval); + present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc); return hr; } @@ -970,8 +934,6 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, } else { - device->implicit_swapchains[0]->swap_interval - = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval); wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc); present_parameters->BackBufferWidth = swapchain_desc.backbuffer_width; present_parameters->BackBufferHeight = swapchain_desc.backbuffer_height; @@ -981,6 +943,10 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, device->device_state = D3D9_DEVICE_STATE_OK; } + if (!device->d3d_parent->extended) + for (i = 0; i < ARRAY_SIZE(device->textures); ++i) + device->textures[i] = NULL; + rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0); device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv); for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i) @@ -1010,8 +976,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex * const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - struct d3d9_swapchain *swapchain; - unsigned int i; + UINT i; HRESULT hr; TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n", @@ -1026,9 +991,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex * wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - swapchain = device->implicit_swapchains[i]; - if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0))) + if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, 0, 0))) { wined3d_mutex_unlock(); return hr; @@ -1536,7 +1500,7 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface, hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0, dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture), - src->sub_resource_idx, &src_box, 0); + src->sub_resource_idx, &src_box); if (SUCCEEDED(hr) && dst->texture) d3d9_texture_flag_auto_gen_mipmap(dst->texture); @@ -2068,7 +2032,7 @@ static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D vp.max_z = viewport->MaxZ; wined3d_mutex_lock(); - wined3d_device_set_viewports(device->wined3d_device, 1, &vp); + wined3d_device_set_viewport(device->wined3d_device, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -2082,7 +2046,7 @@ static HRESULT WINAPI d3d9_device_GetViewport(IDirect3DDevice9Ex *iface, D3DVIEW TRACE("iface %p, viewport %p.\n", iface, viewport); wined3d_mutex_lock(); - wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport); + wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); wined3d_mutex_unlock(); viewport->X = wined3d_viewport.x; @@ -2398,6 +2362,13 @@ static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD st wined3d_mutex_lock(); hr = wined3d_device_set_texture(device->wined3d_device, stage, texture_impl ? texture_impl->wined3d_texture : NULL); + if (SUCCEEDED(hr)) + { + unsigned int i = stage >= D3DVERTEXTEXTURESAMPLER0 ? stage - D3DVERTEXTEXTURESAMPLER0 + 16 : stage; + + if (stage < ARRAY_SIZE(device->textures)) + device->textures[i] = texture_impl; + } wined3d_mutex_unlock(); return hr; @@ -2564,7 +2535,7 @@ static HRESULT WINAPI d3d9_device_SetScissorRect(IDirect3DDevice9Ex *iface, cons TRACE("iface %p, rect %p.\n", iface, rect); wined3d_mutex_lock(); - wined3d_device_set_scissor_rects(device->wined3d_device, 1, rect); + wined3d_device_set_scissor_rect(device->wined3d_device, rect); wined3d_mutex_unlock(); return D3D_OK; @@ -2577,7 +2548,7 @@ static HRESULT WINAPI d3d9_device_GetScissorRect(IDirect3DDevice9Ex *iface, RECT TRACE("iface %p, rect %p.\n", iface, rect); wined3d_mutex_lock(); - wined3d_device_get_scissor_rects(device->wined3d_device, NULL, rect); + wined3d_device_get_scissor_rect(device->wined3d_device, rect); wined3d_mutex_unlock(); return D3D_OK; @@ -2641,15 +2612,11 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface) /* wined3d critical section must be taken by the caller. */ static void d3d9_generate_auto_mipmaps(struct d3d9_device *device) { - struct wined3d_texture *texture; - unsigned int i, stage; + unsigned int i; - for (i = 0; i < D3D9_MAX_TEXTURE_UNITS; ++i) - { - stage = i >= 16 ? i - 16 + D3DVERTEXTEXTURESAMPLER0 : i; - if ((texture = wined3d_device_get_texture(device->wined3d_device, stage))) - d3d9_texture_gen_auto_mipmap(wined3d_texture_get_parent(texture)); - } + for (i = 0; i < ARRAY_SIZE(device->textures); ++i) + if (device->textures[i]) + d3d9_texture_gen_auto_mipmap(device->textures[i]); } static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, @@ -3700,8 +3667,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex const RGNDATA *dirty_region, DWORD flags) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - struct d3d9_swapchain *swapchain; - unsigned int i; + UINT i; HRESULT hr; TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n", @@ -3717,9 +3683,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - swapchain = device->implicit_swapchains[i]; - if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags))) + if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, 0, flags))) { wined3d_mutex_unlock(); return hr; @@ -3762,31 +3727,21 @@ static HRESULT WINAPI d3d9_device_CheckResourceResidency(IDirect3DDevice9Ex *ifa static HRESULT WINAPI d3d9_device_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency) { - struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - TRACE("iface %p, max_latency %u.\n", iface, max_latency); - if (max_latency > 30) - return D3DERR_INVALIDCALL; - - wined3d_mutex_lock(); - wined3d_device_set_max_frame_latency(device->wined3d_device, max_latency); - wined3d_mutex_unlock(); + if (max_latency) + FIXME("Ignoring max_latency %u.\n", max_latency); return S_OK; } static HRESULT WINAPI d3d9_device_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency) { - struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + FIXME("iface %p, max_latency %p stub!\n", iface, max_latency); - TRACE("iface %p, max_latency %p.\n", iface, max_latency); + *max_latency = 2; - wined3d_mutex_lock(); - *max_latency = wined3d_device_get_max_frame_latency(device->wined3d_device); - wined3d_mutex_unlock(); - - return S_OK; + return E_NOTIMPL; } static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window) @@ -4095,40 +4050,40 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa InterlockedCompareExchange(&device->device_state, D3D9_DEVICE_STATE_NOT_RESET, D3D9_DEVICE_STATE_LOST); } -static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent, - enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, +static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops) { - TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops); + struct d3d9_surface *d3d_surface; - if (type == WINED3D_RTYPE_TEXTURE_2D) - { - struct d3d9_surface *d3d_surface; + TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); - if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) - return E_OUTOFMEMORY; + if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) + return E_OUTOFMEMORY; - surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); - *parent = d3d_surface; - TRACE("Created surface %p.\n", d3d_surface); - } - else if (type == WINED3D_RTYPE_TEXTURE_3D) - { - struct d3d9_volume *d3d_volume; + surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); + *parent = d3d_surface; + TRACE("Created surface %p.\n", d3d_surface); - if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume)))) - return E_OUTOFMEMORY; + return D3D_OK; +} - volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); - *parent = d3d_volume; - TRACE("Created volume %p.\n", d3d_volume); - } - else - { - ERR("Unhandled resource type %#x.\n", type); - return E_FAIL; - } +static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, + void **parent, const struct wined3d_parent_ops **parent_ops) +{ + struct d3d9_volume *d3d_volume; + + TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); + + if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume)))) + return E_OUTOFMEMORY; + + volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); + *parent = d3d_volume; + TRACE("Created volume %p.\n", d3d_volume); return D3D_OK; } @@ -4173,7 +4128,8 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent TRACE("device_parent %p, desc %p, swapchain %p\n", device_parent, desc, swapchain); - if (FAILED(hr = d3d9_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT, &d3d_swapchain))) + hr = d3d9_swapchain_create(device, desc, &d3d_swapchain); + if (FAILED(hr)) { WARN("Failed to create swapchain, hr %#x.\n", hr); *swapchain = NULL; @@ -4192,7 +4148,8 @@ static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops = device_parent_wined3d_device_created, device_parent_mode_changed, device_parent_activate, - device_parent_texture_sub_resource_created, + device_parent_surface_created, + device_parent_volume_created, device_parent_create_swapchain_texture, device_parent_create_swapchain, }; @@ -4315,16 +4272,10 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine wined3d_mutex_unlock(); return E_OUTOFMEMORY; } - for (i = 0; i < device->implicit_swapchain_count; ++i) - { - device->implicit_swapchains[i]->swap_interval - = wined3dswapinterval_from_d3d(parameters[i].PresentationInterval); - } for (i = 0; i < count; ++i) { - present_parameters_from_wined3d_swapchain_desc(¶meters[i], - &swapchain_desc[i], parameters[i].PresentationInterval); + present_parameters_from_wined3d_swapchain_desc(¶meters[i], &swapchain_desc[i]); } wined3d_mutex_unlock(); diff --git a/dll/directx/wine/d3d9/directx.c b/dll/directx/wine/d3d9/directx.c index 98f4a99c494..644766c2e97 100644 --- a/dll/directx/wine/d3d9/directx.c +++ b/dll/directx/wine/d3d9/directx.c @@ -254,12 +254,6 @@ static HRESULT WINAPI d3d9_CheckDeviceFormat(IDirect3D9Ex *iface, UINT adapter, TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n", iface, adapter, device_type, adapter_format, usage, resource_type, format); - if (!adapter_format) - { - WARN("Invalid adapter format.\n"); - return D3DERR_INVALIDCALL; - } - usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK); switch (resource_type) { @@ -585,7 +579,7 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING - | WINED3D_NORMALIZED_DEPTH_BIAS; + | WINED3D_NORMALIZED_DEPTH_BIAS | WINED3D_LIMIT_VIEWPORT; if (!extended) flags |= WINED3D_VIDMEM_ACCOUNTING; diff --git a/dll/directx/wine/d3d9/swapchain.c b/dll/directx/wine/d3d9/swapchain.c index d303f3f9564..dbb3f45b91d 100644 --- a/dll/directx/wine/d3d9/swapchain.c +++ b/dll/directx/wine/d3d9/swapchain.c @@ -25,27 +25,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d9); -static DWORD d3dpresentationinterval_from_wined3dswapinterval(enum wined3d_swap_interval interval) -{ - switch (interval) - { - case WINED3D_SWAP_INTERVAL_IMMEDIATE: - return D3DPRESENT_INTERVAL_IMMEDIATE; - case WINED3D_SWAP_INTERVAL_ONE: - return D3DPRESENT_INTERVAL_ONE; - case WINED3D_SWAP_INTERVAL_TWO: - return D3DPRESENT_INTERVAL_TWO; - case WINED3D_SWAP_INTERVAL_THREE: - return D3DPRESENT_INTERVAL_THREE; - case WINED3D_SWAP_INTERVAL_FOUR: - return D3DPRESENT_INTERVAL_FOUR; - default: - ERR("Invalid swap interval %#x.\n", interval); - case WINED3D_SWAP_INTERVAL_DEFAULT: - return D3DPRESENT_INTERVAL_DEFAULT; - } -} - static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9Ex(IDirect3DSwapChain9Ex *iface) { return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9Ex_iface); @@ -158,7 +137,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai wined3d_mutex_lock(); hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags); + src_rect, dst_rect, dst_window_override, 0, flags); wined3d_mutex_unlock(); return hr; @@ -272,15 +251,13 @@ static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9Ex { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); struct wined3d_swapchain_desc desc; - DWORD presentation_interval; TRACE("iface %p, parameters %p.\n", iface, parameters); wined3d_mutex_lock(); wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &desc); - presentation_interval = d3dpresentationinterval_from_wined3dswapinterval(swapchain->swap_interval); wined3d_mutex_unlock(); - present_parameters_from_wined3d_swapchain_desc(parameters, &desc, presentation_interval); + present_parameters_from_wined3d_swapchain_desc(parameters, &desc); return D3D_OK; } @@ -367,13 +344,12 @@ static const struct wined3d_parent_ops d3d9_swapchain_wined3d_parent_ops = }; static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_device *device, - struct wined3d_swapchain_desc *desc, unsigned int swap_interval) + struct wined3d_swapchain_desc *desc) { HRESULT hr; swapchain->refcount = 1; swapchain->IDirect3DSwapChain9Ex_iface.lpVtbl = &d3d9_swapchain_vtbl; - swapchain->swap_interval = swap_interval; wined3d_mutex_lock(); hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, @@ -393,7 +369,7 @@ static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_devi } HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc, - unsigned int swap_interval, struct d3d9_swapchain **swapchain) + struct d3d9_swapchain **swapchain) { struct d3d9_swapchain *object; HRESULT hr; @@ -401,7 +377,7 @@ HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapcha if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = swapchain_init(object, device, desc, swap_interval))) + if (FAILED(hr = swapchain_init(object, device, desc))) { WARN("Failed to initialize swapchain, hr %#x.\n", hr); heap_free(object); diff --git a/dll/directx/wine/d3d9/texture.c b/dll/directx/wine/d3d9/texture.c index 7b74ac5b9e8..c97fa6b0219 100644 --- a/dll/directx/wine/d3d9/texture.c +++ b/dll/directx/wine/d3d9/texture.c @@ -1339,22 +1339,9 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels); return D3DERR_INVALIDCALL; } - wined3d_mutex_lock(); - hr = wined3d_check_device_format(device->d3d_parent->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM, - WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_GENMIPMAP, WINED3D_RTYPE_TEXTURE_2D, wined3dformat_from_d3dformat(format)); - wined3d_mutex_unlock(); - if (hr == D3D_OK) - { - flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; - levels = 0; - } - else - { - WARN("D3DUSAGE_AUTOGENMIPMAP not supported on D3DFORMAT %#x, creating a texture " - "with a single level.\n", format); - levels = 1; - } + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; texture->autogen_filter_type = D3DTEXF_LINEAR; + levels = 0; } else { diff --git a/dll/directx/wine/d3dcompiler_43/CMakeLists.txt b/dll/directx/wine/d3dcompiler_43/CMakeLists.txt index 88d2383b7b6..7c5cb428400 100644 --- a/dll/directx/wine/d3dcompiler_43/CMakeLists.txt +++ b/dll/directx/wine/d3dcompiler_43/CMakeLists.txt @@ -3,19 +3,18 @@ add_definitions( -D__WINESRC__ -DDIRECT3D_VERSION=0x0900) -if(MSVC) - # error C4133: 'function': incompatible types - from 'D3D_CBUFFER_TYPE *' to 'DWORD *' - replace_compile_flags("/we4133" " ") -endif() - include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(d3dcompiler_43.dll d3dcompiler_43.spec ADD_IMPORTLIB) list(APPEND SOURCE asmparser.c + asmshader.tab.c + asmshader.yy.c blob.c bytecodewriter.c compiler.c + hlsl.tab.c + hlsl.yy.c main.c reflection.c utils.c @@ -24,10 +23,6 @@ list(APPEND SOURCE add_library(d3dcompiler_43 MODULE ${SOURCE} - asmshader.tab.c - asmshader.yy.c - hlsl.tab.c - hlsl.yy.c version.rc ${CMAKE_CURRENT_BINARY_DIR}/d3dcompiler_43.def) @@ -43,5 +38,5 @@ set_module_type(d3dcompiler_43 win32dll) target_link_libraries(d3dcompiler_43 dx10guid uuid wine wpp) add_importlibs(d3dcompiler_43 msvcrt kernel32 ntdll) add_dependencies(d3dcompiler_43 d3d_idl_headers) -add_pch(d3dcompiler_43 precomp.h SOURCE) +#add_pch(d3dcompiler_43 precomp.h SOURCE) add_cd_file(TARGET d3dcompiler_43 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/ddraw/CMakeLists.txt b/dll/directx/wine/ddraw/CMakeLists.txt index 03029bdc8f9..6141d630f3f 100644 --- a/dll/directx/wine/ddraw/CMakeLists.txt +++ b/dll/directx/wine/ddraw/CMakeLists.txt @@ -29,7 +29,7 @@ if(MSVC) set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/FIwine/typeof.h") endif() -add_library(ddraw MODULE +add_library(ddraw SHARED ${SOURCE} ddraw.rc ${CMAKE_CURRENT_BINARY_DIR}/ddraw.def) diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c index 6b5ccece46d..e5205c0d000 100644 --- a/dll/directx/wine/ddraw/ddraw.c +++ b/dll/directx/wine/ddraw/ddraw.c @@ -633,9 +633,8 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win swapchain_desc.backbuffer_width = mode.width; swapchain_desc.backbuffer_height = mode.height; swapchain_desc.backbuffer_format = mode.format_id; - swapchain_desc.backbuffer_usage = 0; - swapchain_desc.backbuffer_count = 1; - swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; + swapchain_desc.backbuffer_usage = WINED3DUSAGE_RENDERTARGET; + swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; swapchain_desc.device_window = window; swapchain_desc.windowed = windowed; swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; @@ -2100,7 +2099,7 @@ static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface) ddraw->flags |= DDRAW_GDI_FLIP; if (ddraw->primary) - ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE, 0); + ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE); return DD_OK; } @@ -4910,19 +4909,18 @@ void ddraw_update_lost_surfaces(struct ddraw *ddraw) ddraw->device_state = DDRAW_DEVICE_STATE_OK; } -static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent, - enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, +static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops) { struct ddraw *ddraw = ddraw_from_device_parent(device_parent); struct ddraw_surface *ddraw_surface; - TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops); + TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); /* We have a swapchain or wined3d internal texture. */ - if (type != WINED3D_RTYPE_TEXTURE_2D || !wined3d_texture_get_parent(wined3d_texture) - || wined3d_texture_get_parent(wined3d_texture) == ddraw) + if (!wined3d_texture_get_parent(wined3d_texture) || wined3d_texture_get_parent(wined3d_texture) == ddraw) { *parent = NULL; *parent_ops = &ddraw_null_wined3d_parent_ops; @@ -4947,6 +4945,19 @@ static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_d return DD_OK; } +static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, + void **parent, const struct wined3d_parent_ops **parent_ops) +{ + TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); + + *parent = NULL; + *parent_ops = &ddraw_null_wined3d_parent_ops; + + return DD_OK; +} + static void STDMETHODCALLTYPE ddraw_frontbuffer_destroyed(void *parent) { struct ddraw *ddraw = parent; @@ -4963,26 +4974,25 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic struct wined3d_texture **texture) { struct ddraw *ddraw = ddraw_from_device_parent(device_parent); - const struct wined3d_parent_ops *parent_ops; HRESULT hr; TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n", device_parent, container_parent, desc, texture_flags, texture); - if (!ddraw->wined3d_frontbuffer) - parent_ops = &ddraw_frontbuffer_parent_ops; - else - parent_ops = &ddraw_null_wined3d_parent_ops; + if (ddraw->wined3d_frontbuffer) + { + ERR("Frontbuffer already created.\n"); + return E_FAIL; + } if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, 1, - texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, parent_ops, texture))) + texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; } - if (!ddraw->wined3d_frontbuffer) - ddraw->wined3d_frontbuffer = *texture; + ddraw->wined3d_frontbuffer = *texture; return hr; } @@ -5013,7 +5023,8 @@ static const struct wined3d_device_parent_ops ddraw_wined3d_device_parent_ops = device_parent_wined3d_device_created, device_parent_mode_changed, device_parent_activate, - device_parent_texture_sub_resource_created, + device_parent_surface_created, + device_parent_volume_created, device_parent_create_swapchain_texture, device_parent_create_swapchain, }; diff --git a/dll/directx/wine/ddraw/ddraw_private.h b/dll/directx/wine/ddraw/ddraw_private.h index 1bba80cf261..cac38c57e92 100644 --- a/dll/directx/wine/ddraw/ddraw_private.h +++ b/dll/directx/wine/ddraw/ddraw_private.h @@ -57,15 +57,14 @@ struct FvfToDecl #define DDRAW_NO3D 0x00000008 #define DDRAW_SCL_DDRAW1 0x00000010 #define DDRAW_SCL_RECURSIVE 0x00000020 -#define DDRAW_SWAPPED 0x00000040 -#define DDRAW_GDI_FLIP 0x00000080 +#define DDRAW_GDI_FLIP 0x00000040 #define DDRAW_STRIDE_ALIGNMENT 8 #define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \ | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \ | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \ - | WINED3D_LEGACY_CUBEMAP_FILTERING) + | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT) enum ddraw_device_state { @@ -219,7 +218,7 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, - const RECT *rect, BOOL read, unsigned int swap_interval) DECLSPEC_HIDDEN; + const RECT *rect, BOOL read) DECLSPEC_HIDDEN; static inline struct ddraw_surface *impl_from_IDirect3DTexture(IDirect3DTexture *iface) { diff --git a/dll/directx/wine/ddraw/device.c b/dll/directx/wine/ddraw/device.c index 799b2bcaa00..24dbd3be505 100644 --- a/dll/directx/wine/ddraw/device.c +++ b/dll/directx/wine/ddraw/device.c @@ -5296,12 +5296,25 @@ static HRESULT WINAPI d3d_device7_Clear_FPUPreserve(IDirect3DDevice7 *iface, DWO return hr; } +/***************************************************************************** + * IDirect3DDevice7::SetViewport + * + * Sets the current viewport. + * + * Version 7 only, but IDirect3DViewport uses this call for older + * versions + * + * Params: + * Data: The new viewport to set + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * + *****************************************************************************/ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); - struct wined3d_sub_resource_desc rt_desc; - struct wined3d_rendertarget_view *rtv; - struct ddraw_surface *surface; struct wined3d_viewport vp; TRACE("iface %p, viewport %p.\n", iface, viewport); @@ -5309,23 +5322,6 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi if (!viewport) return DDERR_INVALIDPARAMS; - wined3d_mutex_lock(); - if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) - { - wined3d_mutex_unlock(); - return DDERR_INVALIDCAPS; - } - surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); - wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); - - if (viewport->dwX > rt_desc.width || viewport->dwWidth > rt_desc.width - viewport->dwX - || viewport->dwY > rt_desc.height || viewport->dwHeight > rt_desc.height - viewport->dwY) - { - WARN("Invalid viewport, returning E_INVALIDARG.\n"); - wined3d_mutex_unlock(); - return E_INVALIDARG; - } - vp.x = viewport->dwX; vp.y = viewport->dwY; vp.width = viewport->dwWidth; @@ -5333,7 +5329,8 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi vp.min_z = viewport->dvMinZ; vp.max_z = viewport->dvMaxZ; - wined3d_device_set_viewports(device->wined3d_device, 1, &vp); + wined3d_mutex_lock(); + wined3d_device_set_viewport(device->wined3d_device, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -5356,6 +5353,21 @@ static HRESULT WINAPI d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7 *ifac return hr; } +/***************************************************************************** + * IDirect3DDevice::GetViewport + * + * Returns the current viewport + * + * Version 7 + * + * Params: + * Data: D3D7Viewport structure to write the viewport information to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * + *****************************************************************************/ static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); @@ -5367,7 +5379,7 @@ static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport); + wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); wined3d_mutex_unlock(); viewport->dwX = wined3d_viewport.x; diff --git a/dll/directx/wine/ddraw/executebuffer.c b/dll/directx/wine/ddraw/executebuffer.c index e2c4fc11ab4..17bea2764c5 100644 --- a/dll/directx/wine/ddraw/executebuffer.c +++ b/dll/directx/wine/ddraw/executebuffer.c @@ -348,7 +348,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, ci->wDest * sizeof(D3DTLVERTEX), 0, 0, - wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box, 0); + wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box); break; default: @@ -610,16 +610,9 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * struct wined3d_map_desc map_desc; struct wined3d_box box = {0}; HRESULT hr; - DWORD buf_size = buffer->desc.dwBufferSize, copy_size; TRACE("iface %p, data %p.\n", iface, data); - if (data->dwSize != sizeof(*data)) - { - WARN("data->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", data->dwSize); - return DDERR_INVALIDPARAMS; - } - /* Skip past previous vertex data. */ buffer->src_vertex_pos += buffer->data.dwVertexCount; @@ -666,7 +659,7 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * buffer->src_vertex_pos = 0; } - if (data->dwVertexCount && (!buf_size || data->dwVertexOffset < buf_size)) + if (data->dwVertexCount) { box.left = buffer->src_vertex_pos * sizeof(D3DVERTEX); box.right = box.left + data->dwVertexCount * sizeof(D3DVERTEX); @@ -674,11 +667,8 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * 0, &map_desc, &box, WINED3D_MAP_WRITE))) return hr; - copy_size = data->dwVertexCount * sizeof(D3DVERTEX); - if (buf_size) - copy_size = min(copy_size, buf_size - data->dwVertexOffset); - - memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset, copy_size); + memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset, + data->dwVertexCount * sizeof(D3DVERTEX)); wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0); } @@ -706,11 +696,12 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * static HRESULT WINAPI d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer *iface, D3DEXECUTEDATA *data) { struct d3d_execute_buffer *buffer = impl_from_IDirect3DExecuteBuffer(iface); + DWORD dwSize; TRACE("iface %p, data %p.\n", iface, data); - /* Tests show that dwSize is ignored. */ - memcpy(data, &buffer->data, sizeof(*data)); + dwSize = data->dwSize; + memcpy(data, &buffer->data, dwSize); if (TRACE_ON(ddraw)) { diff --git a/dll/directx/wine/ddraw/palette.c b/dll/directx/wine/ddraw/palette.c index 87aec96443a..5148832cab6 100644 --- a/dll/directx/wine/ddraw/palette.c +++ b/dll/directx/wine/ddraw/palette.c @@ -176,7 +176,7 @@ static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette *iface, hr = wined3d_palette_set_entries(palette->wined3d_palette, flags, start, count, entries); if (SUCCEEDED(hr) && palette->flags & DDPCAPS_PRIMARYSURFACE) - ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE, 0); + ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE); wined3d_mutex_unlock(); diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c index df8d0380093..11a0e6ba8db 100644 --- a/dll/directx/wine/ddraw/surface.c +++ b/dll/directx/wine/ddraw/surface.c @@ -40,22 +40,15 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra * applications from drawing to the screen while we've locked the frontbuffer. * We'd like to do this in wined3d instead, but for that to work wined3d needs * to support windowless rendering first. */ -HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, - const RECT *rect, BOOL read, unsigned int swap_interval) +HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read) { - struct wined3d_texture *dst_texture; + struct ddraw *ddraw = surface->ddraw; HDC surface_dc, screen_dc; int x, y, w, h; HRESULT hr; BOOL ret; RECT r; - if (surface->ddraw->flags & DDRAW_SWAPPED && !read) - { - surface->ddraw->flags &= ~DDRAW_SWAPPED; - rect = NULL; - } - if (!rect) { SetRect(&r, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight); @@ -70,25 +63,15 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, if (w <= 0 || h <= 0) return DD_OK; - if (surface->ddraw->swapchain_window && !(surface->ddraw->flags & DDRAW_GDI_FLIP)) + if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP)) { /* Nothing to do, we control the frontbuffer, or at least the parts we * care about. */ if (read) return DD_OK; - if (swap_interval) - dst_texture = wined3d_swapchain_get_back_buffer(surface->ddraw->wined3d_swapchain, 0); - else - dst_texture = surface->ddraw->wined3d_frontbuffer; - - if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture, - surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval) - { - hr = wined3d_swapchain_present(surface->ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0); - surface->ddraw->flags |= DDRAW_SWAPPED; - } - return hr; + return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect, + surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT); } if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc))) @@ -491,7 +474,7 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD palette_impl->flags |= DDPCAPS_PRIMARYSURFACE; wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain, palette_impl ? palette_impl->wined3d_palette : NULL); - ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0); + ddraw_surface_update_frontbuffer(surface, NULL, FALSE); } if (palette_impl) IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface); @@ -1007,7 +990,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface, } if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0); + hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE); if (SUCCEEDED(hr)) hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, &map_desc, rect ? &box : NULL, @@ -1196,7 +1179,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Unlock(IDirectDrawSurface wined3d_mutex_lock(); hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE, 0); + hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE); wined3d_mutex_unlock(); return hr; @@ -1241,24 +1224,6 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Unlock(IDirectDrawSurface return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL); } -static unsigned int ddraw_swap_interval_from_flags(DWORD flags) -{ - if (flags & DDFLIP_NOVSYNC) - return 0; - - switch (flags & (DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4)) - { - case DDFLIP_INTERVAL2: - return 2; - case DDFLIP_INTERVAL3: - return 3; - case DDFLIP_INTERVAL4: - return 4; - default: - return 1; - } -} - static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *src, DWORD flags) { @@ -1372,7 +1337,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture); src_impl->wined3d_texture = texture; - if (flags & ~(DDFLIP_NOVSYNC | DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4)) + if (flags) { static UINT once; if (!once++) @@ -1382,7 +1347,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 } if (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE, ddraw_swap_interval_from_flags(flags)); + hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE); else hr = DD_OK; @@ -1523,11 +1488,11 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (!dst_surface->clipper) { if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0); + hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE); if (SUCCEEDED(hr)) hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fill_colour, fx, filter); if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) - hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0); + hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE); return hr; } @@ -1570,7 +1535,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE, 0))) + if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE))) break; } } @@ -1581,7 +1546,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE, 0))) + if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE))) break; } } @@ -2254,7 +2219,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc) if (surface->dc) hr = DDERR_DCALREADYCREATED; else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0); + hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE); if (SUCCEEDED(hr)) hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); @@ -2358,7 +2323,7 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h { surface->dc = NULL; if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0); + hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE); } wined3d_mutex_unlock(); @@ -4326,12 +4291,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac } if (src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0); + hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE); if (SUCCEEDED(hr)) hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect, src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT); if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) - hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0); + hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE); wined3d_mutex_unlock(); switch(hr) diff --git a/dll/directx/wine/ddraw/utils.c b/dll/directx/wine/ddraw/utils.c index b0a028d4a57..65f24dc13fd 100644 --- a/dll/directx/wine/ddraw/utils.c +++ b/dll/directx/wine/ddraw/utils.c @@ -570,7 +570,7 @@ unsigned int wined3dmapflags_from_ddrawmapflags(unsigned int flags) unsigned int wined3d_flags; wined3d_flags = flags & handled; - if (!(flags & (DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS | DDLOCK_WRITEONLY))) + if (!(flags & (DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS))) wined3d_flags |= WINED3D_MAP_READ; if (!(flags & DDLOCK_READONLY)) wined3d_flags |= WINED3D_MAP_WRITE; @@ -578,7 +578,7 @@ unsigned int wined3dmapflags_from_ddrawmapflags(unsigned int flags) wined3d_flags |= WINED3D_MAP_READ | WINED3D_MAP_WRITE; if (flags & DDLOCK_NODIRTYUPDATE) wined3d_flags |= WINED3D_MAP_NO_DIRTY_UPDATE; - flags &= ~(handled | DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_WRITEONLY | DDLOCK_NODIRTYUPDATE); + flags &= ~(handled | DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_NODIRTYUPDATE); if (flags) FIXME("Unhandled flags %#x.\n", flags); diff --git a/dll/directx/wine/ddraw/viewport.c b/dll/directx/wine/ddraw/viewport.c index f2caf20858e..6ef3226c4d1 100644 --- a/dll/directx/wine/ddraw/viewport.c +++ b/dll/directx/wine/ddraw/viewport.c @@ -249,118 +249,109 @@ static HRESULT WINAPI d3d_viewport_Initialize(IDirect3DViewport3 *iface, IDirect return DDERR_ALREADYINITIALIZED; } -static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *vp) +/***************************************************************************** + * IDirect3DViewport3::GetViewport + * + * Returns the viewport data assigned to this viewport interface + * + * Params: + * Data: Address to store the data + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * + *****************************************************************************/ +static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData) { - struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); - DWORD size; + struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); + DWORD dwSize; - TRACE("iface %p, vp %p.\n", iface, vp); - - if (!vp) - return DDERR_INVALIDPARAMS; + TRACE("iface %p, data %p.\n", iface, lpData); wined3d_mutex_lock(); - size = vp->dwSize; - if (!viewport->use_vp2) - { - memcpy(vp, &viewport->viewports.vp1, size); - } - else - { + dwSize = lpData->dwSize; + if (!This->use_vp2) + memcpy(lpData, &(This->viewports.vp1), dwSize); + else { D3DVIEWPORT vp1; - vp1.dwSize = sizeof(vp1); - vp1.dwX = viewport->viewports.vp2.dwX; - vp1.dwY = viewport->viewports.vp2.dwY; - vp1.dwWidth = viewport->viewports.vp2.dwWidth; - vp1.dwHeight = viewport->viewports.vp2.dwHeight; + vp1.dwX = This->viewports.vp2.dwX; + vp1.dwY = This->viewports.vp2.dwY; + vp1.dwWidth = This->viewports.vp2.dwWidth; + vp1.dwHeight = This->viewports.vp2.dwHeight; vp1.dvMaxX = 0.0; vp1.dvMaxY = 0.0; vp1.dvScaleX = 0.0; vp1.dvScaleY = 0.0; - vp1.dvMinZ = viewport->viewports.vp2.dvMinZ; - vp1.dvMaxZ = viewport->viewports.vp2.dvMaxZ; - memcpy(vp, &vp1, size); + vp1.dvMinZ = This->viewports.vp2.dvMinZ; + vp1.dvMaxZ = This->viewports.vp2.dvMaxZ; + memcpy(lpData, &vp1, dwSize); } if (TRACE_ON(ddraw)) { TRACE(" returning D3DVIEWPORT :\n"); - _dump_D3DVIEWPORT(vp); + _dump_D3DVIEWPORT(lpData); } wined3d_mutex_unlock(); - return D3D_OK; + return DD_OK; } -static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *vp) +/***************************************************************************** + * IDirect3DViewport3::SetViewport + * + * Sets the viewport information for this interface + * + * Params: + * lpData: Viewport to set + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * + *****************************************************************************/ +static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData) { - struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); - struct d3d_device *device = viewport->active_device; - struct wined3d_sub_resource_desc rt_desc; - struct wined3d_rendertarget_view *rtv; + struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); IDirect3DViewport3 *current_viewport; - struct ddraw_surface *surface; - TRACE("iface %p, vp %p.\n", iface, vp); - - if (!vp) - return DDERR_INVALIDPARAMS; + TRACE("iface %p, data %p.\n", iface, lpData); if (TRACE_ON(ddraw)) { TRACE(" getting D3DVIEWPORT :\n"); - _dump_D3DVIEWPORT(vp); - } - - if (!device) - { - WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n"); - return D3DERR_VIEWPORTHASNODEVICE; + _dump_D3DVIEWPORT(lpData); } wined3d_mutex_lock(); - if (device->version > 1) + This->use_vp2 = 0; + memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1)); + memcpy(&(This->viewports.vp1), lpData, lpData->dwSize); + + /* Tests on two games show that these values are never used properly so override + them with proper ones :-) + */ + This->viewports.vp1.dvMinZ = 0.0; + This->viewports.vp1.dvMaxZ = 1.0; + + if (This->active_device) { - if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) + IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface; + if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, ¤t_viewport))) { - wined3d_mutex_unlock(); - return DDERR_INVALIDCAPS; + if (current_viewport == iface) viewport_activate(This, FALSE); + IDirect3DViewport3_Release(current_viewport); } - surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); - wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); - - if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX - || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY) - { - WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n"); - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; - } - } - - viewport->use_vp2 = 0; - memset(&viewport->viewports.vp1, 0, sizeof(viewport->viewports.vp1)); - memcpy(&viewport->viewports.vp1, vp, vp->dwSize); - - /* Empirical testing on a couple of d3d1 games showed that these values - * should be ignored. */ - viewport->viewports.vp1.dvMinZ = 0.0; - viewport->viewports.vp1.dvMaxZ = 1.0; - - if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport))) - { - if (current_viewport == iface) - viewport_activate(viewport, FALSE); - IDirect3DViewport3_Release(current_viewport); } wined3d_mutex_unlock(); - return D3D_OK; + return DD_OK; } /***************************************************************************** @@ -891,44 +882,53 @@ static HRESULT WINAPI d3d_viewport_NextLight(IDirect3DViewport3 *iface, * IDirect3DViewport2 Methods. *****************************************************************************/ -static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *vp) +/***************************************************************************** + * IDirect3DViewport3::GetViewport2 + * + * Returns the currently set viewport in a D3DVIEWPORT2 structure. + * Similar to IDirect3DViewport3::GetViewport + * + * Params: + * lpData: Pointer to the structure to fill + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if the viewport was set with + * IDirect3DViewport3::SetViewport + * DDERR_INVALIDPARAMS if Data is NULL + * + *****************************************************************************/ +static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData) { - struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); - DWORD size; + struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); + DWORD dwSize; - TRACE("iface %p, vp %p.\n", iface, vp); - - if (!vp) - return DDERR_INVALIDPARAMS; + TRACE("iface %p, data %p.\n", iface, lpData); wined3d_mutex_lock(); - size = vp->dwSize; - if (viewport->use_vp2) - { - memcpy(vp, &viewport->viewports.vp2, size); - } - else - { + dwSize = lpData->dwSize; + if (This->use_vp2) + memcpy(lpData, &(This->viewports.vp2), dwSize); + else { D3DVIEWPORT2 vp2; - vp2.dwSize = sizeof(vp2); - vp2.dwX = viewport->viewports.vp1.dwX; - vp2.dwY = viewport->viewports.vp1.dwY; - vp2.dwWidth = viewport->viewports.vp1.dwWidth; - vp2.dwHeight = viewport->viewports.vp1.dwHeight; + vp2.dwX = This->viewports.vp1.dwX; + vp2.dwY = This->viewports.vp1.dwY; + vp2.dwWidth = This->viewports.vp1.dwWidth; + vp2.dwHeight = This->viewports.vp1.dwHeight; vp2.dvClipX = 0.0; vp2.dvClipY = 0.0; vp2.dvClipWidth = 0.0; vp2.dvClipHeight = 0.0; - vp2.dvMinZ = viewport->viewports.vp1.dvMinZ; - vp2.dvMaxZ = viewport->viewports.vp1.dvMaxZ; - memcpy(vp, &vp2, size); + vp2.dvMinZ = This->viewports.vp1.dvMinZ; + vp2.dvMaxZ = This->viewports.vp1.dvMaxZ; + memcpy(lpData, &vp2, dwSize); } if (TRACE_ON(ddraw)) { TRACE(" returning D3DVIEWPORT2 :\n"); - _dump_D3DVIEWPORT2(vp); + _dump_D3DVIEWPORT2(lpData); } wined3d_mutex_unlock(); @@ -936,62 +936,45 @@ static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVI return D3D_OK; } -static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *vp) +/***************************************************************************** + * IDirect3DViewport3::SetViewport2 + * + * Sets the viewport from a D3DVIEWPORT2 structure + * + * Params: + * lpData: Viewport to set + * + * Returns: + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData) { - struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); - struct d3d_device *device = viewport->active_device; - struct wined3d_sub_resource_desc rt_desc; - struct wined3d_rendertarget_view *rtv; + struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); IDirect3DViewport3 *current_viewport; - struct ddraw_surface *surface; - TRACE("iface %p, vp %p.\n", iface, vp); - - if (!vp) - return DDERR_INVALIDPARAMS; + TRACE("iface %p, data %p.\n", iface, lpData); if (TRACE_ON(ddraw)) { TRACE(" getting D3DVIEWPORT2 :\n"); - _dump_D3DVIEWPORT2(vp); - } - - if (!device) - { - WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n"); - return D3DERR_VIEWPORTHASNODEVICE; + _dump_D3DVIEWPORT2(lpData); } wined3d_mutex_lock(); - if (device->version > 1) + This->use_vp2 = 1; + memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2)); + memcpy(&(This->viewports.vp2), lpData, lpData->dwSize); + + if (This->active_device) { - if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) + IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface; + if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, ¤t_viewport))) { - wined3d_mutex_unlock(); - return DDERR_INVALIDCAPS; + if (current_viewport == iface) viewport_activate(This, FALSE); + IDirect3DViewport3_Release(current_viewport); } - surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); - wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); - - if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX - || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY) - { - WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n"); - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; - } - } - - viewport->use_vp2 = 1; - memset(&viewport->viewports.vp2, 0, sizeof(viewport->viewports.vp2)); - memcpy(&viewport->viewports.vp2, vp, vp->dwSize); - - if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport))) - { - if (current_viewport == iface) - viewport_activate(viewport, FALSE); - IDirect3DViewport3_Release(current_viewport); } wined3d_mutex_unlock(); diff --git a/dll/directx/wine/wined3d/CMakeLists.txt b/dll/directx/wine/wined3d/CMakeLists.txt index 6a6bf74e108..235adab9027 100644 --- a/dll/directx/wine/wined3d/CMakeLists.txt +++ b/dll/directx/wine/wined3d/CMakeLists.txt @@ -7,11 +7,6 @@ add_definitions( include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -if(MSVC) - # error C4312: 'type cast': conversion from 'LONG' to 'void *' of greater size - replace_compile_flags("/we4312" " ") -endif() - # We name this d3dwine.dll, because the Virtualbox additions ship with a custom wined3d.dll # and it breaks everything if it is installed. spec2def(d3dwine.dll wined3d.spec ADD_IMPORTLIB) @@ -46,7 +41,7 @@ list(APPEND SOURCE wined3d_main.c precomp.h) -add_library(d3dwine MODULE +add_library(d3dwine SHARED ${SOURCE} version.rc ${CMAKE_CURRENT_BINARY_DIR}/d3dwine.def) diff --git a/dll/directx/wine/wined3d/arb_program_shader.c b/dll/directx/wine/wined3d/arb_program_shader.c index 4fbb3a59ecd..f86c167b606 100644 --- a/dll/directx/wine/wined3d/arb_program_shader.c +++ b/dll/directx/wine/wined3d/arb_program_shader.c @@ -611,7 +611,7 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g unsigned char i; /* Upload the position fixup */ - shader_get_position_fixup(context, state, 1, position_fixup); + shader_get_position_fixup(context, state, position_fixup); GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->pos_fixup, position_fixup)); if (!gl_shader->num_int_consts) return; @@ -1061,7 +1061,7 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction /* This is better than nothing for now */ sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset); } - else if(ctx->cur_ps_args->super.vp_mode != WINED3D_VP_MODE_SHADER) + else if(ctx->cur_ps_args->super.vp_mode != vertexshader) { /* This is problematic because we'd have to consult the ctx->ps_input strings * for where to find the varying. Some may be "0.0", others can be texcoords or @@ -1416,6 +1416,9 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; const char *mod; BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type); + const struct wined3d_shader *shader; + const struct wined3d_device *device; + const struct wined3d_gl_info *gl_info; const char *tex_dst = dst_str; struct color_fixup_masks masks; @@ -1429,8 +1432,12 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD break; case WINED3D_SHADER_RESOURCE_TEXTURE_2D: + shader = ins->ctx->shader; + device = shader->device; + gl_info = &device->adapter->gl_info; + if (pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx) - && ins->ctx->gl_info->supported[ARB_TEXTURE_RECTANGLE]) + && gl_info->supported[ARB_TEXTURE_RECTANGLE]) tex_type = "RECT"; else tex_type = "2D"; @@ -3415,68 +3422,73 @@ static void init_ps_input(const struct wined3d_shader *shader, const char *semantic_name; DWORD semantic_idx; - if (args->super.vp_mode == WINED3D_VP_MODE_SHADER) + switch(args->super.vp_mode) { - /* That one is easy. The vertex shaders provide v0-v7 in - * fragment.texcoord and v8 and v9 in fragment.color. */ - for (i = 0; i < 8; ++i) - { - priv->ps_input[i] = texcoords[i]; - } - priv->ps_input[8] = "fragment.color.primary"; - priv->ps_input[9] = "fragment.color.secondary"; - return; - } + case pretransformed: + case fixedfunction: + /* The pixelshader has to collect the varyings on its own. In any case properly load + * color0 and color1. In the case of pretransformed vertices also load texcoords. Set + * other attribs to 0.0. + * + * For fixedfunction this behavior is correct, according to the tests. For pretransformed + * we'd either need a replacement shader that can load other attribs like BINORMAL, or + * load the texcoord attrib pointers to match the pixel shader signature + */ + for (i = 0; i < shader->input_signature.element_count; ++i) + { + input = &shader->input_signature.elements[i]; + if (!(semantic_name = input->semantic_name)) + continue; + semantic_idx = input->semantic_idx; - /* The fragment shader has to collect the varyings on its own. In any case - * properly load color0 and color1. In the case of pre-transformed - * vertices also load texture coordinates. Set other attributes to 0.0. - * - * For fixed-function this behavior is correct, according to the tests. - * For pre-transformed we'd either need a replacement shader that can load - * other attributes like BINORMAL, or load the texture coordinate - * attribute pointers to match the fragment shader signature. */ - for (i = 0; i < shader->input_signature.element_count; ++i) - { - input = &shader->input_signature.elements[i]; - if (!(semantic_name = input->semantic_name)) - continue; - semantic_idx = input->semantic_idx; + if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR)) + { + if (!semantic_idx) + priv->ps_input[input->register_idx] = "fragment.color.primary"; + else if (semantic_idx == 1) + priv->ps_input[input->register_idx] = "fragment.color.secondary"; + else + priv->ps_input[input->register_idx] = "0.0"; + } + else if (args->super.vp_mode == fixedfunction) + { + priv->ps_input[input->register_idx] = "0.0"; + } + else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) + { + if (semantic_idx < 8) + priv->ps_input[input->register_idx] = texcoords[semantic_idx]; + else + priv->ps_input[input->register_idx] = "0.0"; + } + else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG)) + { + if (!semantic_idx) + priv->ps_input[input->register_idx] = "fragment.fogcoord"; + else + priv->ps_input[input->register_idx] = "0.0"; + } + else + { + priv->ps_input[input->register_idx] = "0.0"; + } - if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR)) - { - if (!semantic_idx) - priv->ps_input[input->register_idx] = "fragment.color.primary"; - else if (semantic_idx == 1) - priv->ps_input[input->register_idx] = "fragment.color.secondary"; - else - priv->ps_input[input->register_idx] = "0.0"; - } - else if (args->super.vp_mode == WINED3D_VP_MODE_FF) - { - priv->ps_input[input->register_idx] = "0.0"; - } - else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) - { - if (semantic_idx < 8) - priv->ps_input[input->register_idx] = texcoords[semantic_idx]; - else - priv->ps_input[input->register_idx] = "0.0"; - } - else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG)) - { - if (!semantic_idx) - priv->ps_input[input->register_idx] = "fragment.fogcoord"; - else - priv->ps_input[input->register_idx] = "0.0"; - } - else - { - priv->ps_input[input->register_idx] = "0.0"; - } + TRACE("v%u, semantic %s%u is %s\n", input->register_idx, + semantic_name, semantic_idx, priv->ps_input[input->register_idx]); + } + break; - TRACE("v%u, semantic %s%u is %s\n", input->register_idx, - semantic_name, semantic_idx, priv->ps_input[input->register_idx]); + case vertexshader: + /* That one is easy. The vertex shaders provide v0-v7 in fragment.texcoord and v8 and v9 in + * fragment.color + */ + for(i = 0; i < 8; i++) + { + priv->ps_input[i] = texcoords[i]; + } + priv->ps_input[8] = "fragment.color.primary"; + priv->ps_input[9] = "fragment.color.secondary"; + break; } } @@ -6072,19 +6084,17 @@ static const char *get_argreg(struct wined3d_string_buffer *buffer, DWORD argnum } static void gen_ffp_instr(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color, - BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) + BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) { const char *dstmask, *dstreg, *arg0, *arg1, *arg2; unsigned int mul = 1; - if (color && alpha) - dstmask = ""; - else if (color) - dstmask = ".xyz"; - else - dstmask = ".w"; + if(color && alpha) dstmask = ""; + else if(color) dstmask = ".xyz"; + else dstmask = ".w"; - dstreg = tmp_dst ? "tempreg" : "ret"; + if(dst == tempreg) dstreg = "tempreg"; + else dstreg = "ret"; arg0 = get_argreg(buffer, 0, stage, dw_arg0); arg1 = get_argreg(buffer, 1, stage, dw_arg1); @@ -6263,7 +6273,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE) tex_read |= 1u << stage; - if (settings->op[stage].tmp_dst) + if (settings->op[stage].dst == tempreg) tempreg_used = TRUE; if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) tempreg_used = TRUE; @@ -6381,17 +6391,12 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con textype = arbfp_texture_target(settings->op[stage].tex_type); - if (settings->op[stage].projected == WINED3D_PROJECTION_NONE) - { + if(settings->op[stage].projected == proj_none) { instr = "TEX"; - } - else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4 - || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3) - { + } else if(settings->op[stage].projected == proj_count4 || + settings->op[stage].projected == proj_count3) { instr = "TXP"; - } - else - { + } else { FIXME("Unexpected projection mode %d\n", settings->op[stage].projected); instr = "TXP"; } @@ -6405,27 +6410,18 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con shader_addline(&buffer, "SWZ arg1, bumpmat%u, y, w, 0, 0;\n", stage - 1); shader_addline(&buffer, "DP3 ret.y, arg1, tex%u;\n", stage - 1); - /* With projective textures, texbem only divides the static - * texture coordinate, not the displacement, so multiply the - * displacement with the dividing parameter before passing it to - * TXP. */ - if (settings->op[stage].projected != WINED3D_PROJECTION_NONE) - { - if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4) - { + /* with projective textures, texbem only divides the static texture coord, not the displacement, + * so multiply the displacement with the dividing parameter before passing it to TXP + */ + if (settings->op[stage].projected != proj_none) { + if(settings->op[stage].projected == proj_count4) { shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].w;\n", stage); - shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n", - stage, stage); - } - else - { + shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n", stage, stage); + } else { shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].z;\n", stage); - shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n", - stage, stage); + shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n", stage, stage); } - } - else - { + } else { shader_addline(&buffer, "ADD ret, ret, fragment.texcoord[%u];\n", stage); } @@ -6437,16 +6433,12 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con stage - 1, stage - 1, stage - 1); shader_addline(&buffer, "MUL tex%u, tex%u, ret.x;\n", stage, stage); } - } - else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3) - { + } else if(settings->op[stage].projected == proj_count3) { shader_addline(&buffer, "MOV ret, fragment.texcoord[%u];\n", stage); shader_addline(&buffer, "MOV ret.w, ret.z;\n"); shader_addline(&buffer, "%s tex%u, ret, texture[%u], %s;\n", instr, stage, stage, textype); - } - else - { + } else { shader_addline(&buffer, "%s tex%u, fragment.texcoord[%u], texture[%u], %s;\n", instr, stage, stage, stage, textype); } @@ -6495,23 +6487,23 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con if (settings->op[stage].aop == WINED3D_TOP_DISABLE) { - gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst, + gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } else if (op_equal) { - gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst, + gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE) { - gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst, + gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); - gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst, + gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].dst, settings->op[stage].aop, settings->op[stage].aarg0, settings->op[stage].aarg1, settings->op[stage].aarg2); } @@ -6936,8 +6928,8 @@ static void arbfp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3 heap_free(arbfp_blitter); } -static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer, - const struct arbfp_blit_type *type, char *luminance) +static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type, + char *luminance) { char chroma; const char *tex, *texinstr = "TXP"; @@ -6985,12 +6977,13 @@ static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer, shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n"); shader_addline(buffer, "ADD texcrd.x, texcrd.x, coef.y;\n"); - /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25 - * and 0.75 for the even and odd pixels respectively. */ + /* Divide the x coordinate by 0.5 and get the fraction. This gives 0.25 and 0.75 for the + * even and odd pixels respectively + */ shader_addline(buffer, "MUL texcrd2, texcrd, coef.y;\n"); shader_addline(buffer, "FRC texcrd2, texcrd2;\n"); - /* Sample Pixel 1. */ + /* Sample Pixel 1 */ shader_addline(buffer, "%s luminance, texcrd, texture[0], %s;\n", texinstr, tex); /* Put the value into either of the chroma values */ @@ -7019,10 +7012,12 @@ static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer, /* This gives the correctly filtered luminance value */ shader_addline(buffer, "TEX luminance, fragment.texcoord[0], texture[0], %s;\n", tex); + + return TRUE; } -static void gen_yv12_read(struct wined3d_string_buffer *buffer, - const struct arbfp_blit_type *type, char *luminance) +static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type, + char *luminance) { const char *tex; static const float yv12_coef[] @@ -7084,6 +7079,7 @@ static void gen_yv12_read(struct wined3d_string_buffer *buffer, */ if (type->res_type == WINED3D_GL_RES_TYPE_TEX_2D) { + shader_addline(buffer, "RCP chroma.w, size.y;\n"); shader_addline(buffer, "MUL texcrd2.y, texcrd.y, size.y;\n"); @@ -7091,7 +7087,7 @@ static void gen_yv12_read(struct wined3d_string_buffer *buffer, shader_addline(buffer, "FLR texcrd2.y, texcrd2.y;\n"); shader_addline(buffer, "MAD texcrd.y, texcrd.y, yv12_coef.y, yv12_coef.x;\n"); - /* Read odd lines from the right side (add size * 0.5 to the x coordinate). */ + /* Read odd lines from the right side(add size * 0.5 to the x coordinate */ shader_addline(buffer, "ADD texcrd2.x, texcrd2.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */ shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n"); shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n"); @@ -7105,11 +7101,11 @@ static void gen_yv12_read(struct wined3d_string_buffer *buffer, } else { - /* The y coordinate for V is in the range [size, size + size / 4). */ + /* Read from [size - size+size/4] */ shader_addline(buffer, "FLR texcrd.y, texcrd.y;\n"); shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.w, size.y;\n"); - /* Read odd lines from the right side (add size * 0.5 to the x coordinate). */ + /* Read odd lines from the right side(add size * 0.5 to the x coordinate */ shader_addline(buffer, "ADD texcrd2.x, texcrd.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */ shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n"); shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n"); @@ -7165,10 +7161,12 @@ static void gen_yv12_read(struct wined3d_string_buffer *buffer, shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex); } *luminance = 'a'; + + return TRUE; } -static void gen_nv12_read(struct wined3d_string_buffer *buffer, - const struct arbfp_blit_type *type, char *luminance) +static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type, + char *luminance) { const char *tex; static const float nv12_coef[] @@ -7244,7 +7242,7 @@ static void gen_nv12_read(struct wined3d_string_buffer *buffer, } else { - /* The y coordinate for chroma is in the range [size, size + size / 2). */ + /* Read from [size - size+size/2] */ shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.y, size.y;\n"); shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n"); @@ -7299,6 +7297,8 @@ static void gen_nv12_read(struct wined3d_string_buffer *buffer, shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex); } *luminance = 'a'; + + return TRUE; } /* Context activation is done by the caller. */ @@ -7464,15 +7464,27 @@ static GLuint gen_yuv_shader(const struct wined3d_gl_info *gl_info, const struct { case COMPLEX_FIXUP_UYVY: case COMPLEX_FIXUP_YUY2: - gen_packed_yuv_read(&buffer, type, &luminance_component); + if (!gen_planar_yuv_read(&buffer, type, &luminance_component)) + { + string_buffer_free(&buffer); + return 0; + } break; case COMPLEX_FIXUP_YV12: - gen_yv12_read(&buffer, type, &luminance_component); + if (!gen_yv12_read(&buffer, type, &luminance_component)) + { + string_buffer_free(&buffer); + return 0; + } break; case COMPLEX_FIXUP_NV12: - gen_nv12_read(&buffer, type, &luminance_component); + if (!gen_nv12_read(&buffer, type, &luminance_component)) + { + string_buffer_free(&buffer); + return 0; + } break; default: @@ -7698,7 +7710,7 @@ static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const struct wine enum complex_fixup src_fixup; BOOL decompress; - if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) + if (!context->gl_info->supported[ARB_FRAGMENT_PROGRAM]) return FALSE; if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id) @@ -7783,105 +7795,59 @@ static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const struct wine } static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, - unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) { + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; struct wined3d_device *device = dst_texture->resource.device; - struct wined3d_texture *staging_texture = NULL; struct wined3d_arbfp_blitter *arbfp_blitter; struct wined3d_color_key alpha_test_key; struct wined3d_blitter *next; - unsigned int src_level; RECT s, d; - TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", - blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), - wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), - wine_dbgstr_rect(dst_rect), color_key, debug_d3dtexturefiltertype(filter)); - if (!arbfp_blit_supported(op, context, &src_texture->resource, src_location, &dst_texture->resource, dst_location)) { - if (!(next = blitter->next)) - { - ERR("No blitter to handle blit op %#x.\n", op); - return dst_location; - } - - TRACE("Forwarding to blitter %p.\n", next); - return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter); + if ((next = blitter->next)) + return next->ops->blitter_blit(next, op, context, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect, color_key, filter); } arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter); - if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) - { - struct wined3d_resource_desc desc; - struct wined3d_box upload_box; - HRESULT hr; - - TRACE("Source texture is not GPU accessible, creating a staging texture.\n"); - - src_level = src_sub_resource_idx % src_texture->level_count; - desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - desc.format = src_texture->resource.format->id; - desc.multisample_type = src_texture->resource.multisample_type; - desc.multisample_quality = src_texture->resource.multisample_quality; - desc.usage = WINED3DUSAGE_PRIVATE; - desc.access = WINED3D_RESOURCE_ACCESS_GPU; - desc.width = wined3d_texture_get_level_width(src_texture, src_level); - desc.height = wined3d_texture_get_level_height(src_texture, src_level); - desc.depth = 1; - desc.size = 0; - - if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0, - NULL, NULL, &wined3d_null_parent_ops, &staging_texture))) - { - ERR("Failed to create staging texture, hr %#x.\n", hr); - return dst_location; - } - - wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth); - wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0, - src_texture, src_sub_resource_idx, &upload_box); - - src_texture = staging_texture; - src_sub_resource_idx = 0; - } - else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && (src_texture->sub_resources[src_sub_resource_idx].locations - & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) == WINED3D_LOCATION_DRAWABLE + /* Now load the surface */ + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO + && (surface_get_sub_resource(src_surface)->locations + & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) + == WINED3D_LOCATION_DRAWABLE && !wined3d_resource_is_offscreen(&src_texture->resource)) { + unsigned int src_level = src_sub_resource_idx % src_texture->level_count; /* Without FBO blits transferring from the drawable to the texture is * expensive, because we have to flip the data in sysmem. Since we can * flip in the blitter, we don't actually need that flip anyway. So we * use the surface's texture as scratch texture, and flip the source * rectangle instead. */ - texture2d_load_fb_texture(src_texture, src_sub_resource_idx, FALSE, context); + surface_load_fb_texture(src_surface, FALSE, context); s = *src_rect; - src_level = src_sub_resource_idx % src_texture->level_count; s.top = wined3d_texture_get_level_height(src_texture, src_level) - s.top; s.bottom = wined3d_texture_get_level_height(src_texture, src_level) - s.bottom; src_rect = &s; } else - { wined3d_texture_load(src_texture, context, FALSE); - } - context_apply_ffp_blit_state(context, device); + context_apply_blit_state(context, device); if (dst_location == WINED3D_LOCATION_DRAWABLE) { d = *dst_rect; - wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &d); + surface_translate_drawable_coords(dst_surface, context->win_handle, &d); dst_rect = &d; } @@ -7891,16 +7857,15 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl if (dst_location == WINED3D_LOCATION_DRAWABLE) { - TRACE("Destination texture %p is onscreen.\n", dst_texture); + TRACE("Destination surface %p is onscreen.\n", dst_surface); buffer = wined3d_texture_get_gl_buffer(dst_texture); } else { - TRACE("Destination texture %p is offscreen.\n", dst_texture); + TRACE("Destination surface %p is offscreen.\n", dst_surface); buffer = GL_COLOR_ATTACHMENT0; } - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, - &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location); + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location); context_set_draw_buffer(context, buffer); context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); @@ -7917,16 +7882,14 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl arbfp_blit_set(arbfp_blitter, context, src_texture, src_sub_resource_idx, color_key); /* Draw a textured quad */ - context_draw_textured_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter); + draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter); /* Leave the opengl state valid for blitting */ arbfp_blit_unset(context->gl_info); - if (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture)) - context->gl_info->gl_ops.gl.p_glFlush(); - - if (staging_texture) - wined3d_texture_decref(staging_texture); + if (wined3d_settings.strict_draw_ordering + || (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture))) + context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ return dst_location; } diff --git a/dll/directx/wine/wined3d/ati_fragment_shader.c b/dll/directx/wine/wined3d/ati_fragment_shader.c index 9a1cae34cd7..9d6837a2f22 100644 --- a/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -341,8 +341,9 @@ static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES]) lowest_read = i; } - if (lowest_write == -1 && op[i].tmp_dst) + if(lowest_write == -1 && op[i].dst == tempreg) { lowest_write = i; + } if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE || op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) { @@ -504,13 +505,16 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], TRACE("glSampleMapATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, GL_SWIZZLE_STR_ATI)\n", stage, stage); - GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage, GL_TEXTURE0_ARB + stage, GL_SWIZZLE_STR_ATI)); - if (op[stage + 1].projected == WINED3D_PROJECTION_NONE) + GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage, + GL_TEXTURE0_ARB + stage, + GL_SWIZZLE_STR_ATI)); + if(op[stage + 1].projected == proj_none) { swizzle = GL_SWIZZLE_STR_ATI; - else if (op[stage + 1].projected == WINED3D_PROJECTION_COUNT4) + } else if(op[stage + 1].projected == proj_count4) { swizzle = GL_SWIZZLE_STQ_DQ_ATI; - else + } else { swizzle = GL_SWIZZLE_STR_DR_ATI; + } TRACE("glPassTexCoordATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, %s)\n", stage + 1, stage + 1, debug_swizzle(swizzle)); GL_EXTCALL(glPassTexCoordATI(GL_REG_0_ATI + stage + 1, @@ -575,12 +579,13 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], if (op[stage].cop == WINED3D_TOP_DISABLE) break; - if (op[stage].projected == WINED3D_PROJECTION_NONE) + if(op[stage].projected == proj_none) { swizzle = GL_SWIZZLE_STR_ATI; - else if (op[stage].projected == WINED3D_PROJECTION_COUNT3) + } else if(op[stage].projected == proj_count3) { swizzle = GL_SWIZZLE_STR_DR_ATI; - else + } else { swizzle = GL_SWIZZLE_STQ_DQ_ATI; + } if (op_reads_texture(&op[stage])) { @@ -619,18 +624,14 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], break; } - if (op[stage].tmp_dst) - { - /* If we're writing to D3DTA_TEMP, but never reading from it we - * don't have to write there in the first place. Skip the entire - * stage, this saves some GPU time. */ - if (tmparg == GL_NONE) - continue; + if(op[stage].dst == tempreg) { + /* If we're writing to D3DTA_TEMP, but never reading from it we don't have to write there in the first place. + * skip the entire stage, this saves some GPU time + */ + if(tmparg == GL_NONE) continue; dstreg = tmparg; - } - else - { + } else { dstreg = GL_REG_0_ATI; } diff --git a/dll/directx/wine/wined3d/buffer.c b/dll/directx/wine/wined3d/buffer.c index 9baf0556dda..cae7ef87885 100644 --- a/dll/directx/wine/wined3d/buffer.c +++ b/dll/directx/wine/wined3d/buffer.c @@ -615,7 +615,10 @@ static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, return TRUE; if (!wined3d_resource_allocate_sysmem(&buffer->resource)) + { + ERR("Failed to allocate system memory.\n"); return FALSE; + } return TRUE; case WINED3D_LOCATION_BUFFER: @@ -1180,6 +1183,8 @@ static void wined3d_buffer_unmap(struct wined3d_buffer *buffer) } 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); buffer_clear_dirty_areas(buffer); @@ -1375,9 +1380,6 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device buffer->bind_flags = bind_flags; buffer->locations = WINED3D_LOCATION_SYSMEM; - if (!wined3d_resource_allocate_sysmem(&buffer->resource)) - return E_OUTOFMEMORY; - TRACE("buffer %p, size %#x, usage %#x, format %s, memory @ %p.\n", buffer, buffer->resource.size, buffer->resource.usage, debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory); @@ -1426,7 +1428,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device if (data) wined3d_device_update_sub_resource(device, &buffer->resource, - 0, NULL, data->data, data->row_pitch, data->slice_pitch, 0); + 0, NULL, data->data, data->row_pitch, data->slice_pitch); return WINED3D_OK; } diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c index 0ee5b65bc1c..8a8d952c3ff 100644 --- a/dll/directx/wine/wined3d/context.c +++ b/dll/directx/wine/wined3d/context.c @@ -148,8 +148,8 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context, gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment, resource->object, resource->level); } - else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY - || resource->target == GL_TEXTURE_3D) + else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY || + resource->target == GL_TEXTURE_3D) { if (!gl_info->fbo_ops.glFramebufferTextureLayer) { @@ -164,6 +164,7 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context, { gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment, resource->target, resource->object, resource->level); + checkGLcall("glFramebufferTexture1D()"); } else { @@ -252,8 +253,6 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G } texture_type[] = { - {GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D, "1d", WINED3D_GL_EXT_NONE}, - {GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BINDING_1D_ARRAY, "1d-array", EXT_TEXTURE_ARRAY}, {GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, "2d", WINED3D_GL_EXT_NONE}, {GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BINDING_RECTANGLE_ARB, "rectangle", ARB_TEXTURE_RECTANGLE}, {GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BINDING_2D_ARRAY, "2d-array" , EXT_TEXTURE_ARRAY}, @@ -457,15 +456,19 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co } texture = wined3d_texture_from_resource(resource); - if (texture->current_renderbuffer) + if (resource->type == WINED3D_RTYPE_TEXTURE_2D) { - key->objects[idx].object = texture->current_renderbuffer->id; - key->objects[idx].target = 0; - key->objects[idx].level = key->objects[idx].layer = 0; - key->rb_namespace |= 1 << idx; - return; - } + struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; + if (surface->current_renderbuffer) + { + key->objects[idx].object = surface->current_renderbuffer->id; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; + key->rb_namespace |= 1 << idx; + return; + } + } key->objects[idx].target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); key->objects[idx].level = sub_resource_idx % texture->level_count; key->objects[idx].layer = sub_resource_idx / texture->level_count; @@ -612,7 +615,10 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, } else if (depth_stencil->resource->type == WINED3D_RTYPE_TEXTURE_2D) { - wined3d_texture_set_compatible_renderbuffer(ds_texture, ds_level, &render_targets[0]); + struct wined3d_surface *surface; + + surface = ds_texture->sub_resources[depth_stencil->sub_resource_idx].u.surface; + surface_set_compatible_renderbuffer(surface, &render_targets[0]); } } @@ -755,8 +761,8 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ /* Context activation is done by the caller. */ static void context_apply_fbo_state(struct wined3d_context *context, GLenum target, - const struct wined3d_rendertarget_info *render_targets, - const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location) + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, + DWORD color_location, DWORD ds_location) { struct fbo_entry *entry, *entry2; @@ -778,35 +784,32 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ } else { + struct wined3d_rendertarget_info ds = {{0}}; + + if (depth_stencil) + { + ds.resource = &depth_stencil->container->resource; + ds.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil); + ds.layer_count = 1; + } context->current_fbo = context_find_fbo_entry(context, target, - render_targets, depth_stencil, color_location, ds_location); + render_targets, &ds, color_location, ds_location); context_apply_fbo_entry(context, target, context->current_fbo); } } /* Context activation is done by the caller. */ void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, - struct wined3d_resource *rt, unsigned int rt_sub_resource_idx, - struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, DWORD location) + struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) { - struct wined3d_rendertarget_info ds_info = {{0}}; - memset(context->blit_targets, 0, sizeof(context->blit_targets)); - if (rt) + if (render_target) { - context->blit_targets[0].resource = rt; - context->blit_targets[0].sub_resource_idx = rt_sub_resource_idx; + context->blit_targets[0].resource = &render_target->container->resource; + context->blit_targets[0].sub_resource_idx = surface_get_sub_resource_idx(render_target); context->blit_targets[0].layer_count = 1; } - - if (ds) - { - ds_info.resource = ds; - ds_info.sub_resource_idx = ds_sub_resource_idx; - ds_info.layer_count = 1; - } - - context_apply_fbo_state(context, target, context->blit_targets, &ds_info, location, location); + context_apply_fbo_state(context, target, context->blit_targets, depth_stencil, location, location); } /* Context activation is done by the caller. */ @@ -1067,22 +1070,34 @@ static void context_queue_fbo_entry_destruction(struct wined3d_context *context, list_add_head(&context->fbo_destroy_list, &entry->entry); } -void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource) +void context_resource_released(const struct wined3d_device *device, + struct wined3d_resource *resource, enum wined3d_resource_type type) { - unsigned int i; + struct wined3d_texture *texture; + UINT i; if (!device->d3d_initialized) return; - for (i = 0; i < device->context_count; ++i) + switch (type) { - struct wined3d_context *context = device->contexts[i]; + case WINED3D_RTYPE_TEXTURE_2D: + case WINED3D_RTYPE_TEXTURE_3D: + texture = texture_from_resource(resource); - if (&context->current_rt.texture->resource == resource) - { - context->current_rt.texture = NULL; - context->current_rt.sub_resource_idx = 0; - } + for (i = 0; i < device->context_count; ++i) + { + struct wined3d_context *context = device->contexts[i]; + if (context->current_rt.texture == texture) + { + context->current_rt.texture = NULL; + context->current_rt.sub_resource_idx = 0; + } + } + break; + + default: + break; } } @@ -1092,7 +1107,7 @@ void context_gl_resource_released(struct wined3d_device *device, context_enum_fbo_entries(device, name, rb_namespace, context_queue_fbo_entry_destruction); } -void context_texture_update(struct wined3d_context *context, const struct wined3d_texture *texture) +void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) { const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry = context->current_fbo; @@ -1102,10 +1117,10 @@ void context_texture_update(struct wined3d_context *context, const struct wined3 for (i = 0; i < gl_info->limits.buffers + 1; ++i) { - if (texture->texture_rgb.name == entry->key.objects[i].object - || texture->texture_srgb.name == entry->key.objects[i].object) + if (surface->container->texture_rgb.name == entry->key.objects[i].object + || surface->container->texture_srgb.name == entry->key.objects[i].object) { - TRACE("Updated texture %p is bound as attachment %u to the current FBO.\n", texture, i); + TRACE("Updated surface %p is bound as attachment %u to the current FBO.\n", surface, i); context->rebind_fbo = TRUE; return; } @@ -1451,9 +1466,6 @@ static void context_destroy_gl_resources(struct wined3d_context *context) } } - if (context->blit_vbo) - GL_EXTCALL(glDeleteBuffers(1, &context->blit_vbo)); - checkGLcall("context cleanup"); } @@ -1591,12 +1603,14 @@ void context_release(struct wined3d_context *context) /* This is used when a context for render target A is active, but a separate context is * needed to access the WGL framebuffer for render target B. Re-acquire a context for rt * A to avoid breaking caller code. */ -void context_restore(struct wined3d_context *context, struct wined3d_texture *texture, unsigned int sub_resource_idx) +void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) { - if (context->current_rt.texture != texture || context->current_rt.sub_resource_idx != sub_resource_idx) + if (context->current_rt.texture != restore->container + || context->current_rt.sub_resource_idx != surface_get_sub_resource_idx(restore)) { context_release(context); - context = context_acquire(texture->resource.device, texture, sub_resource_idx); + context = context_acquire(restore->container->resource.device, + restore->container, surface_get_sub_resource_idx(restore)); } context_release(context); @@ -1777,7 +1791,6 @@ void context_bind_dummy_textures(const struct wined3d_device *device, const stru gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array); gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array); } - if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer); @@ -1853,6 +1866,8 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version >> 16; ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_MINOR_VERSION_ARB; ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version & 0xffff; + if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2)) + ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (ctx_flags) { ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB; @@ -1862,20 +1877,9 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs))) { - if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2)) + if (ctx_flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) { - if (ctx_flags) - { - ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - ctx_attribs[ctx_attrib_idx - 1] = ctx_flags; - } - else - { - ctx_flags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB; - ctx_attribs[ctx_attrib_idx++] = ctx_flags; - ctx_attribs[ctx_attrib_idx] = 0; - } + ctx_attribs[ctx_attrib_idx - 1] &= ~WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs))) WARN("Failed to create a WGL context with wglCreateContextAttribsARB, last error %#x.\n", GetLastError()); @@ -2172,6 +2176,15 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, 1);"); + if (gl_info->supported[ARB_VERTEX_BLEND]) + { + /* Direct3D always uses n-1 weights for n world matrices and uses + * 1 - sum for the last one this is equal to GL_WEIGHT_SUM_UNITY_ARB. + * Enabling it doesn't do anything unless GL_VERTEX_BLEND_ARB isn't + * enabled as well. */ + gl_info->gl_ops.gl.p_glEnable(GL_WEIGHT_SUM_UNITY_ARB); + checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)"); + } if (gl_info->supported[NV_TEXTURE_SHADER2]) { /* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d @@ -2257,10 +2270,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, if (device->dummy_textures.tex_2d) context_bind_dummy_textures(device, ret); - /* Initialise all rectangles to avoid resetting unused ones later. */ - gl_info->gl_ops.gl.p_glScissor(0, 0, 0, 0); - checkGLcall("glScissor"); - TRACE("Created context %p.\n", ret); return ret; @@ -2359,6 +2368,28 @@ const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context, return context->tex_unit_map; } +/* Context activation is done by the caller. */ +static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width, UINT height) +{ + const GLdouble projection[] = + { + 2.0 / width, 0.0, 0.0, 0.0, + 0.0, 2.0 / height, 0.0, 0.0, + 0.0, 0.0, 2.0, 0.0, + -1.0, -1.0, -1.0, 1.0, + }; + + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION); + checkGLcall("glMatrixMode(GL_PROJECTION)"); + gl_info->gl_ops.gl.p_glLoadMatrixd(projection); + checkGLcall("glLoadMatrixd"); + } + gl_info->gl_ops.gl.p_glViewport(0, 0, width, height); + checkGLcall("glViewport"); +} + static void context_get_rt_size(const struct wined3d_context *context, SIZE *size) { const struct wined3d_texture *rt = context->current_rt.texture; @@ -2407,6 +2438,206 @@ void context_enable_clip_distances(struct wined3d_context *context, unsigned int checkGLcall("toggle clip distances"); } +/***************************************************************************** + * SetupForBlit + * + * Sets up a context for DirectDraw blitting. + * All texture units are disabled, texture unit 0 is set as current unit + * fog, lighting, blending, alpha test, z test, scissor test, culling disabled + * color writing enabled for all channels + * register combiners disabled, shaders disabled + * world matrix is set to identity, texture matrix 0 too + * projection matrix is setup for drawing screen coordinates + * + * Params: + * This: Device to activate the context for + * context: Context to setup + * + *****************************************************************************/ +/* Context activation is done by the caller. */ +static void SetupForBlit(const struct wined3d_device *device, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + DWORD sampler; + SIZE rt_size; + int i; + + TRACE("Setting up context %p for blitting\n", context); + + context_get_rt_size(context, &rt_size); + + if (context->last_was_blit) + { + if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy) + { + set_blit_dimension(gl_info, rt_size.cx, rt_size.cy); + context->blit_w = rt_size.cx; + context->blit_h = rt_size.cy; + /* No need to dirtify here, the states are still dirtified because + * they weren't applied since the last SetupForBlit() call. */ + } + TRACE("Context is already set up for blitting, nothing to do\n"); + return; + } + context->last_was_blit = TRUE; + + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + /* Disable all textures. The caller can then bind a texture it wants to blit + * from + * + * The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed + * function texture unit. No need to care for higher samplers + */ + for (i = gl_info->limits.textures - 1; i > 0 ; --i) + { + sampler = context->rev_tex_unit_map[i]; + context_active_texture(context, gl_info, i); + + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB"); + } + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable GL_TEXTURE_3D"); + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB"); + } + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable GL_TEXTURE_2D"); + + gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);"); + + if (sampler != WINED3D_UNMAPPED_STAGE) + { + if (sampler < MAX_TEXTURES) + context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)); + context_invalidate_state(context, STATE_SAMPLER(sampler)); + } + } + + context_active_texture(context, gl_info, 0); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB"); + } + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable GL_TEXTURE_3D"); + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB"); + } + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable GL_TEXTURE_2D"); + + gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE); + checkGLcall("glMatrixMode(GL_TEXTURE)"); + gl_info->gl_ops.gl.p_glLoadIdentity(); + checkGLcall("glLoadIdentity()"); + + 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, 0.0f); + checkGLcall("glTexEnvf GL_TEXTURE_LOD_BIAS_EXT ..."); + } + + /* Setup transforms */ + gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); + checkGLcall("glMatrixMode(GL_MODELVIEW)"); + gl_info->gl_ops.gl.p_glLoadIdentity(); + checkGLcall("glLoadIdentity()"); + context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))); + + /* Other misc states */ + gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); + checkGLcall("glDisable(GL_ALPHA_TEST)"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE)); + gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING); + checkGLcall("glDisable GL_LIGHTING"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING)); + glDisableWINE(GL_FOG); + checkGLcall("glDisable GL_FOG"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE)); + } + + 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]; + if (sampler != WINED3D_UNMAPPED_STAGE) + { + if (sampler < MAX_TEXTURES) + { + context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler)); + context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)); + } + context_invalidate_state(context, STATE_SAMPLER(sampler)); + } + + /* Other misc states */ + gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); + checkGLcall("glDisable GL_DEPTH_TEST"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE)); + gl_info->gl_ops.gl.p_glDisable(GL_BLEND); + checkGLcall("glDisable GL_BLEND"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); + gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE); + checkGLcall("glDisable GL_CULL_FACE"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE)); + gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); + checkGLcall("glDisable GL_STENCIL_TEST"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE)); + gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); + checkGLcall("glDisable GL_SCISSOR_TEST"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); + if (gl_info->supported[ARB_POINT_SPRITE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB); + checkGLcall("glDisable GL_POINT_SPRITE_ARB"); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE)); + } + gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE); + checkGLcall("glColorMask"); + for (i = 0; i < MAX_RENDER_TARGETS; ++i) + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); + if (gl_info->supported[EXT_SECONDARY_COLOR]) + { + gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); + checkGLcall("glDisable(GL_COLOR_SUM_EXT)"); + } + + context->last_was_rhw = TRUE; + context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ + + context_enable_clip_distances(context, 0); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING)); + + /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */ + if (gl_info->supported[ARB_CLIP_CONTROL]) + GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE)); + + set_blit_dimension(gl_info, rt_size.cx, rt_size.cy); + + /* Disable shaders */ + device->shader_backend->shader_disable(device->shader_priv, context); + + context->blit_w = rt_size.cx; + context->blit_h = rt_size.cy; + context_invalidate_state(context, STATE_VIEWPORT); + context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); +} + static inline BOOL is_rt_mask_onscreen(DWORD rt_mask) { return rt_mask & (1u << 31); @@ -2525,9 +2756,11 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint break; case GL_TEXTURE_1D: gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d); + checkGLcall("glBindTexture"); break; case GL_TEXTURE_1D_ARRAY: gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array); + checkGLcall("glBindTexture"); break; case GL_TEXTURE_2D: gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d); @@ -2667,7 +2900,7 @@ static void context_set_render_offscreen(struct wined3d_context *context, BOOL o context_invalidate_state(context, STATE_SCISSORRECT); if (!context->gl_info->supported[ARB_CLIP_CONTROL]) { - context_invalidate_state(context, STATE_RASTERIZER); + context_invalidate_state(context, STATE_FRONTFACE); context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN); context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); } @@ -2734,12 +2967,12 @@ GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) } } -static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, struct wined3d_resource *rt) +static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, struct wined3d_texture *rt) { - if (!rt || rt->format->id == WINED3DFMT_NULL) + if (!rt || rt->resource.format->id == WINED3DFMT_NULL) return 0; - else if (rt->type != WINED3D_RTYPE_BUFFER && texture_from_resource(rt)->swapchain) - return context_generate_rt_mask_from_resource(rt); + else if (rt->swapchain) + return context_generate_rt_mask_from_resource(&rt->resource); else return context_generate_rt_mask(context_get_offscreen_gl_buffer(context)); } @@ -2747,13 +2980,9 @@ static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *conte /* Context activation is done by the caller. */ void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) { - const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_texture *rt = context->current_rt.texture; + struct wined3d_surface *surface; DWORD rt_mask, *cur_mask; - unsigned int i, sampler; - SIZE rt_size; - - TRACE("Setting up context %p for blitting.\n", context); if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { @@ -2761,8 +2990,8 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine { wined3d_texture_load(rt, context, FALSE); - context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, &rt->resource, - context->current_rt.sub_resource_idx, NULL, 0, rt->resource.draw_binding); + surface = rt->sub_resources[context->current_rt.sub_resource_idx].u.surface; + context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, surface, NULL, rt->resource.draw_binding); if (rt->resource.format->id != WINED3DFMT_NULL) rt_mask = 1; else @@ -2777,7 +3006,7 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine } else { - rt_mask = context_generate_rt_mask_no_fbo(context, &rt->resource); + rt_mask = context_generate_rt_mask_no_fbo(context, rt); } cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; @@ -2792,193 +3021,9 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine { context_check_fbo_status(context, GL_FRAMEBUFFER); } + + SetupForBlit(device, context); context_invalidate_state(context, STATE_FRAMEBUFFER); - - context_get_rt_size(context, &rt_size); - - if (context->last_was_blit) - { - if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy) - { - gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy); - context->viewport_count = WINED3D_MAX_VIEWPORTS; - context->blit_w = rt_size.cx; - context->blit_h = rt_size.cy; - /* No need to dirtify here, the states are still dirtified because - * they weren't applied since the last context_apply_blit_state() - * call. */ - } - checkGLcall("blit state application"); - TRACE("Context is already set up for blitting, nothing to do.\n"); - return; - } - context->last_was_blit = TRUE; - - 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]; - if (sampler != WINED3D_UNMAPPED_STAGE) - { - if (sampler < MAX_TEXTURES) - { - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler)); - context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)); - } - context_invalidate_state(context, STATE_SAMPLER(sampler)); - } - - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - { - gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE)); - } - gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE)); - gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); - gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE)); - gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE)); - gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); - if (gl_info->supported[ARB_POINT_SPRITE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE)); - } - if (gl_info->supported[ARB_FRAMEBUFFER_SRGB]) - { - gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); - } - gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - for (i = 0; i < MAX_RENDER_TARGETS; ++i) - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); - - context->last_was_rhw = TRUE; - context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ - - context_enable_clip_distances(context, 0); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING)); - - /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */ - if (gl_info->supported[ARB_CLIP_CONTROL]) - GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE)); - gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy); - context->viewport_count = WINED3D_MAX_VIEWPORTS; - context_invalidate_state(context, STATE_VIEWPORT); - - device->shader_backend->shader_disable(device->shader_priv, context); - - context->blit_w = rt_size.cx; - context->blit_h = rt_size.cy; - - checkGLcall("blit state application"); -} - -static void context_apply_blit_projection(const struct wined3d_context *context, unsigned int w, unsigned int h) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - const GLdouble projection[] = - { - 2.0 / w, 0.0, 0.0, 0.0, - 0.0, 2.0 / h, 0.0, 0.0, - 0.0, 0.0, 2.0, 0.0, - -1.0, -1.0, -1.0, 1.0, - }; - - gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION); - gl_info->gl_ops.gl.p_glLoadMatrixd(projection); -} - -/* Setup OpenGL states for fixed-function blitting. */ -/* Context activation is done by the caller. */ -void context_apply_ffp_blit_state(struct wined3d_context *context, const struct wined3d_device *device) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int i, sampler; - - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - ERR("Applying fixed-function state without legacy context support.\n"); - - if (context->last_was_ffp_blit) - { - SIZE rt_size; - - context_get_rt_size(context, &rt_size); - if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy) - context_apply_blit_projection(context, rt_size.cx, rt_size.cy); - context_apply_blit_state(context, device); - - checkGLcall("ffp blit state application"); - return; - } - context->last_was_ffp_blit = TRUE; - - context_apply_blit_state(context, device); - - /* Disable all textures. The caller can then bind a texture it wants to blit - * from. */ - for (i = gl_info->limits.textures - 1; i > 0 ; --i) - { - context_active_texture(context, gl_info, i); - - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - - gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - sampler = context->rev_tex_unit_map[i]; - if (sampler != WINED3D_UNMAPPED_STAGE) - { - if (sampler < MAX_TEXTURES) - context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)); - context_invalidate_state(context, STATE_SAMPLER(sampler)); - } - } - - context_active_texture(context, gl_info, 0); - - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - - gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - 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, 0.0f); - - gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE); - gl_info->gl_ops.gl.p_glLoadIdentity(); - - /* Setup transforms. */ - gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); - gl_info->gl_ops.gl.p_glLoadIdentity(); - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))); - context_apply_blit_projection(context, context->blit_w, context->blit_h); - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); - - /* Other misc states. */ - gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING)); - glDisableWINE(GL_FOG); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE)); - - if (gl_info->supported[EXT_SECONDARY_COLOR]) - { - gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); - } - checkGLcall("ffp blit state application"); } static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts, @@ -3019,8 +3064,6 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - struct wined3d_rendertarget_info ds_info = {{0}}; - context_validate_onscreen_formats(context, dsv); if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource)) @@ -3038,22 +3081,14 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL) rt_mask |= (1u << i); } - - if (dsv) - { - ds_info.gl_view = dsv->gl_view; - ds_info.resource = dsv->resource; - ds_info.sub_resource_idx = dsv->sub_resource_idx; - ds_info.layer_count = dsv->layer_count; - } - - context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, &ds_info, + context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, + wined3d_rendertarget_view_get_surface(dsv), rt_count ? rts[0]->resource->draw_binding : 0, dsv ? dsv->resource->draw_binding : 0); } else { - context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, &ds_info, + context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE); rt_mask = context_generate_rt_mask_from_resource(rts[0]->resource); } @@ -3065,7 +3100,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win } else { - rt_mask = context_generate_rt_mask_no_fbo(context, rt_count ? rts[0]->resource : NULL); + rt_mask = context_generate_rt_mask_no_fbo(context, + rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL); } } else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO @@ -3079,7 +3115,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win } else { - rt_mask = context_generate_rt_mask_no_fbo(context, rt_count ? rts[0]->resource : NULL); + rt_mask = context_generate_rt_mask_no_fbo(context, + rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL); } cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; @@ -3097,7 +3134,6 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win } context->last_was_blit = FALSE; - context->last_was_ffp_blit = FALSE; /* Blending and clearing should be orthogonal, but tests on the nvidia * driver show that disabling blending when clearing improves the clearing @@ -3129,7 +3165,7 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const unsigned int i; if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) - return context_generate_rt_mask_no_fbo(context, rts[0]->resource); + return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])->container); else if (!context->render_offscreen) return context_generate_rt_mask_from_resource(rts[0]->resource); @@ -3166,11 +3202,9 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - struct wined3d_rendertarget_info ds_info = {{0}}; - if (!context->render_offscreen) { - context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, &ds_info, + context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE); } else @@ -3191,16 +3225,8 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat if (!color_location) color_location = fb->render_targets[i]->resource->draw_binding; } - - if (fb->depth_stencil) - { - ds_info.gl_view = fb->depth_stencil->gl_view; - ds_info.resource = fb->depth_stencil->resource; - ds_info.sub_resource_idx = fb->depth_stencil->sub_resource_idx; - ds_info.layer_count = fb->depth_stencil->layer_count; - } - - context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, &ds_info, + context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, + wined3d_rendertarget_view_get_surface(fb->depth_stencil), color_location, fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0); } } @@ -4027,7 +4053,6 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, context->numDirtyEntries = 0; /* This makes the whole list clean */ context->last_was_blit = FALSE; - context->last_was_ffp_blit = FALSE; return TRUE; } @@ -4089,7 +4114,6 @@ static void context_apply_compute_state(struct wined3d_context *context, context_invalidate_state(context, STATE_FRAMEBUFFER); context->last_was_blit = FALSE; - context->last_was_ffp_blit = FALSE; } static BOOL use_transform_feedback(const struct wined3d_state *state) @@ -4353,6 +4377,9 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS)); checkGLcall("glMemoryBarrier"); + if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + context_release(context); } @@ -4538,7 +4565,6 @@ static const BYTE *software_vertex_blending(struct wined3d_context *context, case WINED3D_FFP_EMIT_FLOAT4: vector[3] = data[3]; case WINED3D_FFP_EMIT_FLOAT3: vector[2] = data[2]; case WINED3D_FFP_EMIT_FLOAT2: vector[1] = data[1]; - case WINED3D_FFP_EMIT_FLOAT1: vector[0] = data[0]; break; default: FIXME("unsupported value format: %u\n", SI_FORMAT(element_idx)); return (BYTE *)data; @@ -5026,12 +5052,13 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n"); emulation = TRUE; } - else if (use_indexed_vertex_blending(state, stream_info) && use_software_vertex_processing(context->device)) + else if (use_indexed_vertex_blending(state, stream_info) && use_software_vertex_processing(context->device)) { WARN_(d3d_perf)("Using software emulation because application requested SVP.\n"); emulation = TRUE; } + if (emulation) { si_emulated = context->stream_info; @@ -5059,9 +5086,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s } else if (!context->transform_feedback_active) { - enum wined3d_primitive_type primitive_type = shader->u.gs.output_type - ? shader->u.gs.output_type : d3d_primitive_type_from_gl(state->gl_primitive_type); - GLenum mode = gl_tfb_primitive_type_from_d3d(primitive_type); + GLenum mode = gl_tfb_primitive_type_from_d3d(shader->u.gs.output_type); GL_EXTCALL(glBeginTransformFeedback(mode)); checkGLcall("glBeginTransformFeedback"); context->transform_feedback_active = 1; @@ -5116,663 +5141,8 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s for (i = 0; i < context->buffer_fence_count; ++i) wined3d_fence_issue(context->buffer_fences[i], device); + if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + context_release(context); } - -void context_unload_tex_coords(const struct wined3d_context *context) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int texture_idx; - - for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx) - { - gl_info->gl_ops.ext.p_glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx); - gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -void context_load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si, - GLuint *current_bo, const struct wined3d_state *state) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int mapped_stage = 0; - unsigned int texture_idx; - - for (texture_idx = 0; texture_idx < context->d3d_info->limits.ffp_blend_stages; ++texture_idx) - { - unsigned int coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX]; - - if ((mapped_stage = context->tex_unit_map[texture_idx]) == WINED3D_UNMAPPED_STAGE) - continue; - - if (mapped_stage >= gl_info->limits.texture_coords) - { - FIXME("Attempted to load unsupported texture coordinate %u.\n", mapped_stage); - continue; - } - - if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))) - { - const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx]; - - TRACE("Setting up texture %u, idx %d, coord_idx %u, data {%#x:%p}.\n", - texture_idx, mapped_stage, coord_idx, e->data.buffer_object, e->data.addr); - - if (*current_bo != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - *current_bo = e->data.buffer_object; - } - - GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); - checkGLcall("glClientActiveTextureARB"); - - /* The coords to supply depend completely on the fvf/vertex shader. */ - gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else - { - GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1)); - } - } - if (gl_info->supported[NV_REGISTER_COMBINERS]) - { - /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */ - for (texture_idx = mapped_stage + 1; texture_idx < gl_info->limits.textures; ++texture_idx) - { - GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1)); - } - } - - checkGLcall("loadTexCoords"); -} - -/* This should match any arrays loaded in context_load_vertex_data(). */ -static void context_unload_vertex_data(struct wined3d_context *context) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - - if (!context->namedArraysLoaded) - return; - gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY); - gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY); - gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY); - if (gl_info->supported[EXT_SECONDARY_COLOR]) - gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); - context_unload_tex_coords(context); - context->namedArraysLoaded = FALSE; -} - -static void context_load_vertex_data(struct wined3d_context *context, - const struct wined3d_stream_info *si, const struct wined3d_state *state) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_stream_info_element *e; - GLuint current_bo; - - TRACE("context %p, si %p, state %p.\n", context, si, state); - - /* This is used for the fixed-function pipeline only, and the - * fixed-function pipeline doesn't do instancing. */ - context->instance_count = 0; - current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0; - - /* Blend data */ - if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT)) - || si->use_map & (1u << WINED3D_FFP_BLENDINDICES)) - { - /* TODO: Support vertex blending in immediate mode draws. No need to - * write a FIXME here, this is done after the general vertex - * declaration decoding. */ - WARN("Vertex blending not supported.\n"); - } - - /* Point Size */ - if (si->use_map & (1u << WINED3D_FFP_PSIZE)) - { - /* No such functionality in the fixed-function GL pipeline. */ - WARN("Per-vertex point size not supported.\n"); - } - - /* Position */ - if (si->use_map & (1u << WINED3D_FFP_POSITION)) - { - e = &si->elements[WINED3D_FFP_POSITION]; - - if (current_bo != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - current_bo = e->data.buffer_object; - } - - TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n", - e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - checkGLcall("glVertexPointer(...)"); - gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY); - checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)"); - } - - /* Normals */ - if (si->use_map & (1u << WINED3D_FFP_NORMAL)) - { - e = &si->elements[WINED3D_FFP_NORMAL]; - - if (current_bo != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - current_bo = e->data.buffer_object; - } - - TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - checkGLcall("glNormalPointer(...)"); - gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY); - checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); - - } - else - { - gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0); - checkGLcall("glNormal3f(0, 0, 0)"); - } - - /* Diffuse colour */ - if (si->use_map & (1u << WINED3D_FFP_DIFFUSE)) - { - e = &si->elements[WINED3D_FFP_DIFFUSE]; - - if (current_bo != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - current_bo = e->data.buffer_object; - } - - TRACE("glColorPointer(%#x, %#x %#x, %p);\n", - e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); - gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY); - checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); - - } - else - { - gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - checkGLcall("glColor4f(1, 1, 1, 1)"); - } - - /* Specular colour */ - if (si->use_map & (1u << WINED3D_FFP_SPECULAR)) - { - TRACE("Setting specular colour.\n"); - - e = &si->elements[WINED3D_FFP_SPECULAR]; - - if (gl_info->supported[EXT_SECONDARY_COLOR]) - { - GLenum type = e->format->gl_vtx_type; - GLint format = e->format->gl_vtx_format; - - if (current_bo != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - current_bo = e->data.buffer_object; - } - - if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA)) - { - /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha - * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function - * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts - * 4 component secondary colors use it - */ - TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride)); - checkGLcall("glSecondaryColorPointerEXT(format, type, ...)"); - } - else - { - switch (type) - { - case GL_UNSIGNED_BYTE: - TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride)); - checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)"); - break; - - default: - FIXME("Add 4 component specular colour pointers for type %#x.\n", type); - /* Make sure that the right colour component is dropped. */ - TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride)); - checkGLcall("glSecondaryColorPointerEXT(3, type, ...)"); - } - } - gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); - checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - } - else - { - WARN("Specular colour is not supported in this GL implementation.\n"); - } - } - else - { - if (gl_info->supported[EXT_SECONDARY_COLOR]) - { - GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); - checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); - } - else - { - WARN("Specular colour is not supported in this GL implementation.\n"); - } - } - - /* Texture coordinates */ - context_load_tex_coords(context, si, ¤t_bo, state); -} - -static void context_unload_numbered_array(struct wined3d_context *context, unsigned int i) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - - GL_EXTCALL(glDisableVertexAttribArray(i)); - checkGLcall("glDisableVertexAttribArray"); - if (gl_info->supported[ARB_INSTANCED_ARRAYS]) - GL_EXTCALL(glVertexAttribDivisor(i, 0)); - - context->numbered_array_mask &= ~(1u << i); -} - -static void context_unload_numbered_arrays(struct wined3d_context *context) -{ - unsigned int i; - - while (context->numbered_array_mask) - { - i = wined3d_bit_scan(&context->numbered_array_mask); - context_unload_numbered_array(context, i); - } -} - -static void context_load_numbered_arrays(struct wined3d_context *context, - const struct wined3d_stream_info *stream_info, const struct wined3d_state *state) -{ - const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; - const struct wined3d_gl_info *gl_info = context->gl_info; - GLuint current_bo; - unsigned int i; - - /* Default to no instancing. */ - context->instance_count = 0; - current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0; - - for (i = 0; i < MAX_ATTRIBS; ++i) - { - const struct wined3d_stream_info_element *element = &stream_info->elements[i]; - const struct wined3d_stream_state *stream; - - if (!(stream_info->use_map & (1u << i))) - { - if (context->numbered_array_mask & (1u << i)) - context_unload_numbered_array(context, i); - if (!use_vs(state) && i == WINED3D_FFP_DIFFUSE) - GL_EXTCALL(glVertexAttrib4f(i, 1.0f, 1.0f, 1.0f, 1.0f)); - else - GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f)); - continue; - } - - stream = &state->streams[element->stream_idx]; - - if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count) - context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1; - - if (gl_info->supported[ARB_INSTANCED_ARRAYS]) - { - GL_EXTCALL(glVertexAttribDivisor(i, element->divisor)); - } - else if (element->divisor) - { - /* Unload instanced arrays, they will be loaded using immediate - * mode instead. */ - if (context->numbered_array_mask & (1u << i)) - context_unload_numbered_array(context, i); - continue; - } - - TRACE("Loading array %u [VBO=%u].\n", i, element->data.buffer_object); - - if (element->stride) - { - if (current_bo != element->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object)); - checkGLcall("glBindBuffer"); - current_bo = element->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 - * current_bo will be 0. If there is a vertex buffer but no vbo we - * won't be load converted attributes anyway. */ - if (vs && vs->reg_maps.shader_version.major >= 4 - && (element->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_INTEGER)) - { - GL_EXTCALL(glVertexAttribIPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type, - element->stride, element->data.addr + state->load_base_vertex_index * element->stride)); - } - else - { - GL_EXTCALL(glVertexAttribPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type, - element->format->gl_normalized, element->stride, - element->data.addr + state->load_base_vertex_index * element->stride)); - } - - if (!(context->numbered_array_mask & (1u << i))) - { - GL_EXTCALL(glEnableVertexAttribArray(i)); - context->numbered_array_mask |= (1u << i); - } - } - else - { - /* Stride = 0 means always the same values. - * 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 = element->data.addr; - if (element->data.buffer_object) - ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context); - - if (context->numbered_array_mask & (1u << i)) - context_unload_numbered_array(context, i); - - switch (element->format->id) - { - case WINED3DFMT_R32_FLOAT: - GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr)); - break; - case WINED3DFMT_R32G32_FLOAT: - GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr)); - break; - case WINED3DFMT_R32G32B32_FLOAT: - GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr)); - break; - case WINED3DFMT_R32G32B32A32_FLOAT: - GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr)); - break; - case WINED3DFMT_R8G8B8A8_UINT: - GL_EXTCALL(glVertexAttrib4ubv(i, ptr)); - break; - case WINED3DFMT_B8G8R8A8_UNORM: - if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) - { - const DWORD *src = (const DWORD *)ptr; - DWORD c = *src & 0xff00ff00u; - c |= (*src & 0xff0000u) >> 16; - c |= (*src & 0xffu) << 16; - GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c)); - break; - } - /* else fallthrough */ - case WINED3DFMT_R8G8B8A8_UNORM: - GL_EXTCALL(glVertexAttrib4Nubv(i, ptr)); - break; - case WINED3DFMT_R16G16_SINT: - GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr)); - break; - case WINED3DFMT_R16G16B16A16_SINT: - 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(glVertexAttrib4Nsv(i, s)); - break; - } - case WINED3DFMT_R16G16_UNORM: - { - const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1}; - GL_EXTCALL(glVertexAttrib4Nusv(i, s)); - break; - } - case WINED3DFMT_R16G16B16A16_SNORM: - GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr)); - break; - case WINED3DFMT_R16G16B16A16_UNORM: - GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr)); - break; - case WINED3DFMT_R10G10B10X2_UINT: - FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n"); - /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */ - break; - case WINED3DFMT_R10G10B10X2_SNORM: - FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n"); - /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */ - break; - case WINED3DFMT_R16G16_FLOAT: - if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) - { - /* Not supported by GL_ARB_half_float_vertex. */ - GL_EXTCALL(glVertexAttrib2hvNV(i, (const GLhalfNV *)ptr)); - } - else - { - float x = float_16_to_32(((const unsigned short *)ptr) + 0); - float y = float_16_to_32(((const unsigned short *)ptr) + 1); - GL_EXTCALL(glVertexAttrib2f(i, x, y)); - } - break; - case WINED3DFMT_R16G16B16A16_FLOAT: - if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) - { - /* Not supported by GL_ARB_half_float_vertex. */ - GL_EXTCALL(glVertexAttrib4hvNV(i, (const GLhalfNV *)ptr)); - } - else - { - float x = float_16_to_32(((const unsigned short *)ptr) + 0); - 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(glVertexAttrib4f(i, x, y, z, w)); - } - break; - default: - ERR("Unexpected declaration in stride 0 attributes.\n"); - break; - - } - } - } - checkGLcall("Loading numbered arrays"); -} - -void context_update_stream_sources(struct wined3d_context *context, const struct wined3d_state *state) -{ - - if (context->use_immediate_mode_draw) - return; - - context_unload_vertex_data(context); - if (context->d3d_info->ffp_generic_attributes || use_vs(state)) - { - TRACE("Loading numbered arrays.\n"); - context_load_numbered_arrays(context, &context->stream_info, state); - return; - } - - TRACE("Loading named arrays.\n"); - context_unload_numbered_arrays(context); - context_load_vertex_data(context, &context->stream_info, state); - context->namedArraysLoaded = TRUE; -} - -static void apply_texture_blit_state(const struct wined3d_gl_info *gl_info, struct gl_texture *texture, - GLenum target, unsigned int level, enum wined3d_texture_filter_type filter) -{ - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter)); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, - wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE)); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, level); - - /* We changed the filtering settings on the texture. Make sure they get - * reset on subsequent draws. */ - texture->sampler_desc.mag_filter = WINED3D_TEXF_POINT; - texture->sampler_desc.min_filter = WINED3D_TEXF_POINT; - texture->sampler_desc.mip_filter = WINED3D_TEXF_NONE; - texture->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP; - texture->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP; - texture->sampler_desc.srgb_decode = FALSE; - texture->base_level = level; -} - -/* Context activation is done by the caller. */ -void context_draw_shaded_quad(struct wined3d_context *context, struct wined3d_texture *texture, - unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect, - enum wined3d_texture_filter_type filter) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_blt_info info; - unsigned int level, w, h, i; - SIZE dst_size; - struct blit_vertex - { - float x, y; - struct wined3d_vec3 texcoord; - } - quad[4]; - - texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info); - - level = sub_resource_idx % texture->level_count; - context_bind_texture(context, info.bind_target, texture->texture_rgb.name); - apply_texture_blit_state(gl_info, &texture->texture_rgb, info.bind_target, level, filter); - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level); - - context_get_rt_size(context, &dst_size); - w = dst_size.cx; - h = dst_size.cy; - - quad[0].x = dst_rect->left * 2.0f / w - 1.0f; - quad[0].y = dst_rect->top * 2.0f / h - 1.0f; - quad[0].texcoord = info.texcoords[0]; - - quad[1].x = dst_rect->right * 2.0f / w - 1.0f; - quad[1].y = dst_rect->top * 2.0f / h - 1.0f; - quad[1].texcoord = info.texcoords[1]; - - quad[2].x = dst_rect->left * 2.0f / w - 1.0f; - quad[2].y = dst_rect->bottom * 2.0f / h - 1.0f; - quad[2].texcoord = info.texcoords[2]; - - quad[3].x = dst_rect->right * 2.0f / w - 1.0f; - quad[3].y = dst_rect->bottom * 2.0f / h - 1.0f; - quad[3].texcoord = info.texcoords[3]; - - /* Draw a quad. */ - if (gl_info->supported[ARB_VERTEX_BUFFER_OBJECT]) - { - if (!context->blit_vbo) - GL_EXTCALL(glGenBuffers(1, &context->blit_vbo)); - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, context->blit_vbo)); - - context_unload_vertex_data(context); - context_unload_numbered_arrays(context); - - GL_EXTCALL(glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW)); - GL_EXTCALL(glVertexAttribPointer(0, 2, GL_FLOAT, FALSE, sizeof(*quad), NULL)); - GL_EXTCALL(glVertexAttribPointer(1, 3, GL_FLOAT, FALSE, sizeof(*quad), - (void *)FIELD_OFFSET(struct blit_vertex, texcoord))); - - GL_EXTCALL(glEnableVertexAttribArray(0)); - GL_EXTCALL(glEnableVertexAttribArray(1)); - - gl_info->gl_ops.gl.p_glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, 0)); - GL_EXTCALL(glDisableVertexAttribArray(1)); - GL_EXTCALL(glDisableVertexAttribArray(0)); - } - else - { - gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); - - for (i = 0; i < ARRAY_SIZE(quad); ++i) - { - GL_EXTCALL(glVertexAttrib3fv(1, &quad[i].texcoord.x)); - GL_EXTCALL(glVertexAttrib2fv(0, &quad[i].x)); - } - - gl_info->gl_ops.gl.p_glEnd(); - } - checkGLcall("draw"); - - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1); - context_bind_texture(context, info.bind_target, 0); -} - -/* Context activation is done by the caller. */ -void context_draw_textured_quad(struct wined3d_context *context, struct wined3d_texture *texture, - unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect, - enum wined3d_texture_filter_type filter) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_blt_info info; - unsigned int level; - - texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info); - - gl_info->gl_ops.gl.p_glEnable(info.bind_target); - checkGLcall("glEnable(bind_target)"); - - level = sub_resource_idx % texture->level_count; - context_bind_texture(context, info.bind_target, texture->texture_rgb.name); - apply_texture_blit_state(gl_info, &texture->texture_rgb, info.bind_target, level, filter); - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level); - gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - checkGLcall("glTexEnvi"); - - /* Draw a quad. */ - gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); - gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top); - - gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top); - - gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom); - - gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom); - gl_info->gl_ops.gl.p_glEnd(); - - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1); - context_bind_texture(context, info.bind_target, 0); -} diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c index eb24d94e9a7..460fe12c7dc 100644 --- a/dll/directx/wine/wined3d/cs.c +++ b/dll/directx/wine/wined3d/cs.c @@ -33,8 +33,8 @@ enum wined3d_cs_op WINED3D_CS_OP_DRAW, WINED3D_CS_OP_FLUSH, WINED3D_CS_OP_SET_PREDICATION, - WINED3D_CS_OP_SET_VIEWPORTS, - WINED3D_CS_OP_SET_SCISSOR_RECTS, + WINED3D_CS_OP_SET_VIEWPORT, + WINED3D_CS_OP_SET_SCISSOR_RECT, WINED3D_CS_OP_SET_RENDERTARGET_VIEW, WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW, WINED3D_CS_OP_SET_VERTEX_DECLARATION, @@ -94,7 +94,7 @@ struct wined3d_cs_present struct wined3d_swapchain *swapchain; RECT src_rect; RECT dst_rect; - unsigned int swap_interval; + DWORD swap_interval; DWORD flags; }; @@ -138,18 +138,16 @@ struct wined3d_cs_set_predication BOOL value; }; -struct wined3d_cs_set_viewports +struct wined3d_cs_set_viewport { enum wined3d_cs_op opcode; - unsigned int viewport_count; - struct wined3d_viewport viewports[1]; + struct wined3d_viewport viewport; }; -struct wined3d_cs_set_scissor_rects +struct wined3d_cs_set_scissor_rect { enum wined3d_cs_op opcode; - unsigned int rect_count; - RECT rects[1]; + RECT rect; }; struct wined3d_cs_set_rendertarget_view @@ -408,7 +406,9 @@ struct wined3d_cs_update_sub_resource unsigned int sub_resource_idx; struct wined3d_box box; struct wined3d_sub_resource_data data; +#if defined(STAGING_CSMT) BYTE copy_data[1]; +#endif /* STAGING_CSMT */ }; struct wined3d_cs_add_dirty_texture_region @@ -456,7 +456,12 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) swapchain = op->swapchain; wined3d_swapchain_set_window(swapchain, op->dst_window_override); - wined3d_swapchain_set_swap_interval(swapchain, op->swap_interval); + + if (op->swap_interval && swapchain->desc.swap_interval != op->swap_interval) + { + swapchain->desc.swap_interval = op->swap_interval; + swapchain_update_swap_interval(swapchain); + } swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags); @@ -471,7 +476,7 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - unsigned int swap_interval, DWORD flags) + DWORD swap_interval, DWORD flags) { struct wined3d_cs_present *op; unsigned int i; @@ -497,8 +502,9 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); /* Limit input latency by limiting the number of presents that we can get - * ahead of the worker thread. */ - while (pending >= swapchain->max_frame_latency) + * ahead of the worker thread. We have a constant limit here, but + * IDXGIDevice1 allows tuning this. */ + while (pending > 1) { wined3d_pause(); pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); @@ -532,24 +538,19 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * { unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers; const struct wined3d_state *state = &cs->device->state; - const struct wined3d_viewport *vp = &state->viewports[0]; - struct wined3d_rendertarget_view *view; + const struct wined3d_viewport *vp = &state->viewport; struct wined3d_cs_clear *op; - RECT view_rect; unsigned int i; op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_CLEAR; op->flags = flags; - if (flags & WINED3DCLEAR_TARGET) - op->rt_count = rt_count; - else - op->rt_count = 0; + op->rt_count = rt_count; op->fb = &cs->fb; SetRect(&op->draw_rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height); if (state->render_states[WINED3D_RS_SCISSORTESTENABLE]) - IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rects[0]); + IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rect); op->color = *color; op->depth = depth; op->stencil = stencil; @@ -560,21 +561,12 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * { for (i = 0; i < rt_count; ++i) { - if ((view = state->fb->render_targets[i])) - { - SetRect(&view_rect, 0, 0, view->width, view->height); - IntersectRect(&op->draw_rect, &op->draw_rect, &view_rect); - wined3d_resource_acquire(view->resource); - } + if (state->fb->render_targets[i]) + wined3d_resource_acquire(state->fb->render_targets[i]->resource); } } if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - { - view = state->fb->depth_stencil; - SetRect(&view_rect, 0, 0, view->width, view->height); - IntersectRect(&op->draw_rect, &op->draw_rect, &view_rect); - wined3d_resource_acquire(view->resource); - } + wined3d_resource_acquire(state->fb->depth_stencil->resource); cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } @@ -782,7 +774,6 @@ void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs, static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) { const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; - const struct wined3d_shader *geometry_shader; struct wined3d_state *state = &cs->state; const struct wined3d_cs_draw *op = data; int load_base_vertex_idx; @@ -802,8 +793,6 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) if (state->gl_primitive_type != op->primitive_type) { - if ((geometry_shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) && !geometry_shader->function) - device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY)); if (state->gl_primitive_type == GL_POINTS || op->primitive_type == GL_POINTS) device_invalidate_state(cs->device, STATE_POINT_ENABLE); state->gl_primitive_type = op->primitive_type; @@ -969,53 +958,40 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -static void wined3d_cs_exec_set_viewports(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_viewports *op = data; + const struct wined3d_cs_set_viewport *op = data; - if (op->viewport_count) - memcpy(cs->state.viewports, op->viewports, op->viewport_count * sizeof(*op->viewports)); - else - memset(cs->state.viewports, 0, sizeof(*cs->state.viewports)); - cs->state.viewport_count = op->viewport_count; + cs->state.viewport = op->viewport; device_invalidate_state(cs->device, STATE_VIEWPORT); } -void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count, - const struct wined3d_viewport *viewports) +void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) { - struct wined3d_cs_set_viewports *op; + struct wined3d_cs_set_viewport *op; - op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_viewports, viewports[viewport_count]), - WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_VIEWPORTS; - memcpy(op->viewports, viewports, viewport_count * sizeof(*viewports)); - op->viewport_count = viewport_count; + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_VIEWPORT; + op->viewport = *viewport; cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -static void wined3d_cs_exec_set_scissor_rects(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_scissor_rects *op = data; + const struct wined3d_cs_set_scissor_rect *op = data; - if (op->rect_count) - memcpy(cs->state.scissor_rects, op->rects, op->rect_count * sizeof(*op->rects)); - else - SetRectEmpty(cs->state.scissor_rects); - cs->state.scissor_rect_count = op->rect_count; + cs->state.scissor_rect = op->rect; device_invalidate_state(cs->device, STATE_SCISSORRECT); } -void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_count, const RECT *rects) +void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) { - struct wined3d_cs_set_scissor_rects *op; + struct wined3d_cs_set_scissor_rect *op; - op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_scissor_rects, rects[rect_count]), - WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECTS; - memcpy(op->rects, rects, rect_count * sizeof(*rects)); - op->rect_count = rect_count; + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; + op->rect = *rect; cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } @@ -1047,14 +1023,16 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const struct wined3d_device *device = cs->device; struct wined3d_rendertarget_view *prev; - if ((prev = cs->state.fb->depth_stencil) && prev->resource->type != WINED3D_RTYPE_BUFFER) + if ((prev = cs->state.fb->depth_stencil)) { - struct wined3d_texture *prev_texture = texture_from_resource(prev->resource); + struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev); - if (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL - || prev_texture->flags & WINED3D_TEXTURE_DISCARD) - wined3d_texture_validate_location(prev_texture, + if (prev_surface && (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL + || prev_surface->container->flags & WINED3D_TEXTURE_DISCARD)) + { + wined3d_texture_validate_location(prev_surface->container, prev->sub_resource_idx, WINED3D_LOCATION_DISCARDED); + } } cs->fb.depth_stencil = op->view; @@ -1492,7 +1470,7 @@ static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const vo const struct wined3d_cs_set_rasterizer_state *op = data; cs->state.rasterizer_state = op->state; - device_invalidate_state(cs->device, STATE_RASTERIZER); + device_invalidate_state(cs->device, STATE_FRONTFACE); } void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs, @@ -2081,6 +2059,23 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * buffer_from_resource(op->src_resource), op->src_box.left, op->src_box.right - op->src_box.left); } + else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D) + { + struct wined3d_surface *dst_surface, *src_surface; + struct wined3d_texture *dst_texture, *src_texture; + RECT dst_rect, src_rect; + + dst_texture = texture_from_resource(op->dst_resource); + src_texture = texture_from_resource(op->src_resource); + dst_surface = dst_texture->sub_resources[op->dst_sub_resource_idx].u.surface; + src_surface = src_texture->sub_resources[op->src_sub_resource_idx].u.surface; + SetRect(&dst_rect, op->dst_box.left, op->dst_box.top, op->dst_box.right, op->dst_box.bottom); + SetRect(&src_rect, op->src_box.left, op->src_box.top, op->src_box.right, op->src_box.bottom); + + if (FAILED(wined3d_surface_blt(dst_surface, &dst_rect, src_surface, + &src_rect, op->flags, &op->fx, op->filter))) + FIXME("Blit failed.\n"); + } else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_3D) { struct wined3d_texture *src_texture, *dst_texture; @@ -2115,6 +2110,13 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * goto error; } + if (op->src_box.left || op->src_box.top || op->src_box.front) + { + FIXME("Source box %s not supported for %s resources.\n", + debug_box(&op->src_box), debug_d3dresourcetype(op->dst_resource->type)); + goto error; + } + dst_texture = texture_from_resource(op->dst_resource); src_texture = texture_from_resource(op->src_resource); @@ -2149,9 +2151,8 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * &row_pitch, &slice_pitch); wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); - wined3d_texture_upload_data(dst_texture, op->dst_sub_resource_idx, context, - dst_texture->resource.format, &op->src_box, wined3d_const_bo_address(&addr), - row_pitch, slice_pitch, op->dst_box.left, op->dst_box.top, op->dst_box.front, FALSE); + wined3d_texture_upload_data(dst_texture, op->dst_sub_resource_idx, context, &op->dst_box, + wined3d_const_bo_address(&addr), row_pitch, slice_pitch); wined3d_texture_validate_location(dst_texture, op->dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_invalidate_location(dst_texture, op->dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); @@ -2159,10 +2160,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * } else { - if (FAILED(texture2d_blt(texture_from_resource(op->dst_resource), op->dst_sub_resource_idx, - &op->dst_box, texture_from_resource(op->src_resource), op->src_sub_resource_idx, - &op->src_box, op->flags, &op->fx, op->filter))) - FIXME("Blit failed.\n"); + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(op->dst_resource->type)); } error: @@ -2211,7 +2209,6 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi struct wined3d_const_bo_address addr; struct wined3d_context *context; struct wined3d_texture *texture; - struct wined3d_box src_box; context = context_acquire(cs->device, NULL, 0); @@ -2248,9 +2245,8 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi wined3d_texture_load_location(texture, op->sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_bind_and_dirtify(texture, context, FALSE); - wined3d_box_set(&src_box, 0, 0, box->right - box->left, box->bottom - box->top, 0, box->back - box->front); - wined3d_texture_upload_data(texture, op->sub_resource_idx, context, texture->resource.format, &src_box, - &addr, op->data.row_pitch, op->data.slice_pitch, box->left, box->top, box->front, FALSE); + wined3d_texture_upload_data(texture, op->sub_resource_idx, context, + box, &addr, op->data.row_pitch, op->data.slice_pitch); wined3d_texture_validate_location(texture, op->sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_invalidate_location(texture, op->sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); @@ -2266,6 +2262,7 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r unsigned int slice_pitch) { struct wined3d_cs_update_sub_resource *op; +#if defined(STAGING_CSMT) size_t data_size, size; if (resource->type != WINED3D_RTYPE_BUFFER && resource->format_flags & WINED3DFMT_FLAG_BLOCKS) @@ -2311,6 +2308,7 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r no_async: wined3d_resource_wait_idle(resource); +#endif /* STAGING_CSMT */ op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; @@ -2324,6 +2322,10 @@ no_async: wined3d_resource_acquire(resource); cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); +#if !defined(STAGING_CSMT) + /* The data pointer may go away, so we need to wait until it is read. + * Copying the data may be faster if it's small. */ +#endif /* STAGING_CSMT */ cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); } @@ -2464,8 +2466,8 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, /* WINED3D_CS_OP_FLUSH */ wined3d_cs_exec_flush, /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, - /* WINED3D_CS_OP_SET_VIEWPORTS */ wined3d_cs_exec_set_viewports, - /* WINED3D_CS_OP_SET_SCISSOR_RECTS */ wined3d_cs_exec_set_scissor_rects, + /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, + /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, @@ -2506,11 +2508,13 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_GENERATE_MIPMAPS */ wined3d_cs_exec_generate_mipmaps, }; +#if defined(STAGING_CSMT) static BOOL wined3d_cs_st_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { return TRUE; } +#endif /* STAGING_CSMT */ static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { if (size > (cs->data_size - cs->end)) @@ -2564,7 +2568,9 @@ static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id static const struct wined3d_cs_ops wined3d_cs_st_ops = { +#if defined(STAGING_CSMT) wined3d_cs_st_check_space, +#endif /* STAGING_CSMT */ wined3d_cs_st_require_space, wined3d_cs_st_submit, wined3d_cs_st_finish, @@ -2601,6 +2607,7 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id wined3d_cs_queue_submit(&cs->queue[queue_id], cs); } +#if defined(STAGING_CSMT) static BOOL wined3d_cs_queue_check_space(struct wined3d_cs_queue *queue, size_t size) { size_t queue_size = ARRAY_SIZE(queue->data); @@ -2614,6 +2621,7 @@ static BOOL wined3d_cs_queue_check_space(struct wined3d_cs_queue *queue, size_t return (remaining >= packet_size); } +#endif /* STAGING_CSMT */ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size, struct wined3d_cs *cs) { size_t queue_size = ARRAY_SIZE(queue->data); @@ -2675,6 +2683,7 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size return packet->data; } +#if defined(STAGING_CSMT) static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { if (cs->thread_id == GetCurrentThreadId()) @@ -2683,6 +2692,7 @@ static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum w return wined3d_cs_queue_check_space(&cs->queue[queue_id], size); } +#endif /* STAGING_CSMT */ static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { if (cs->thread_id == GetCurrentThreadId()) @@ -2705,7 +2715,9 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id static const struct wined3d_cs_ops wined3d_cs_mt_ops = { +#if defined(STAGING_CSMT) wined3d_cs_mt_check_space, +#endif /* STAGING_CSMT */ wined3d_cs_mt_require_space, wined3d_cs_mt_submit, wined3d_cs_mt_finish, diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c index 8b4b3f9bb2c..e2b27e0cf43 100644 --- a/dll/directx/wine/wined3d/device.c +++ b/dll/directx/wine/wined3d/device.c @@ -99,7 +99,7 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) } } -enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type) +static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type) { switch (primitive_type) { @@ -226,11 +226,11 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c float depth, DWORD stencil) { struct wined3d_rendertarget_view *rtv = rt_count ? fb->render_targets[0] : NULL; + struct wined3d_surface *target = rtv ? wined3d_rendertarget_view_get_surface(rtv) : NULL; struct wined3d_rendertarget_view *dsv = fb->depth_stencil; + struct wined3d_surface *depth_stencil = dsv ? wined3d_rendertarget_view_get_surface(dsv) : NULL; const struct wined3d_state *state = &device->cs->state; - struct wined3d_texture *depth_stencil = NULL; const struct wined3d_gl_info *gl_info; - struct wined3d_texture *target = NULL; UINT drawable_width, drawable_height; struct wined3d_color corrected_color; struct wined3d_context *context; @@ -238,19 +238,10 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c BOOL render_offscreen; unsigned int i; - if (rtv && rtv->resource->type != WINED3D_RTYPE_BUFFER) - { - target = texture_from_resource(rtv->resource); - context = context_acquire(device, target, rtv->sub_resource_idx); - } + if (target) + context = context_acquire(device, target->container, rtv->sub_resource_idx); else - { context = context_acquire(device, NULL, 0); - } - - if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER) - depth_stencil = texture_from_resource(dsv->resource); - if (!context->valid) { context_release(context); @@ -290,11 +281,11 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c } else { - unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->level_count; + unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->container->level_count; render_offscreen = TRUE; - drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil, ds_level); - drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil, ds_level); + drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil->container, ds_level); + drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil->container, ds_level); } if (depth_stencil) @@ -411,7 +402,9 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c gl_info->gl_ops.gl.p_glScissor(draw_rect->left, drawable_height - draw_rect->bottom, draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top); } + checkGLcall("glScissor"); gl_info->gl_ops.gl.p_glClear(clear_mask); + checkGLcall("glClear"); } else { @@ -446,14 +439,16 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c gl_info->gl_ops.gl.p_glScissor(current_rect.left, drawable_height - current_rect.bottom, current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); } + checkGLcall("glScissor"); + gl_info->gl_ops.gl.p_glClear(clear_mask); + checkGLcall("glClear"); } } - context->scissor_rect_count = WINED3D_MAX_VIEWPORTS; - checkGLcall("clear"); - if (flags & WINED3DCLEAR_TARGET && target->swapchain && target->swapchain->front_buffer == target) - gl_info->gl_ops.gl.p_glFlush(); + if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET + && target->container->swapchain && target->container->swapchain->front_buffer == target->container)) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); } @@ -682,11 +677,12 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_ if (gl_info->supported[EXT_TEXTURE_ARRAY]) { + gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d_array); TRACE("Dummy 1D array texture given name %u.\n", textures->tex_1d_array); gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array); gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA8, 1, 1, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d_array); TRACE("Dummy 2D array texture given name %u.\n", textures->tex_2d_array); @@ -756,8 +752,8 @@ static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d if (gl_info->supported[EXT_TEXTURE_ARRAY]) { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array); gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d_array); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array); } if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY]) @@ -1040,8 +1036,7 @@ static void wined3d_device_create_primary_opengl_context_cs(void *object) return; } wined3d_ffp_blitter_create(&device->blitter, &device->adapter->gl_info); - if (!wined3d_glsl_blitter_create(&device->blitter, device)) - wined3d_arbfp_blitter_create(&device->blitter, device); + wined3d_arbfp_blitter_create(&device->blitter, device); wined3d_fbo_blitter_create(&device->blitter, &device->adapter->gl_info); wined3d_raw_blitter_create(&device->blitter, &device->adapter->gl_info); @@ -1089,7 +1084,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, goto err_out; } - if (swapchain_desc->backbuffer_count && swapchain_desc->backbuffer_usage & WINED3DUSAGE_RENDERTARGET) + if (swapchain_desc->backbuffer_count) { struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource; struct wined3d_view_desc view_desc; @@ -1125,7 +1120,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, TRACE("All defaults now set up.\n"); /* Clear the screen */ - if (device->back_buffer_view) + if (swapchain->back_buffers && swapchain->back_buffers[0]) clear_flags |= WINED3DCLEAR_TARGET; if (swapchain_desc->enable_auto_depth_stencil) clear_flags |= WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL; @@ -1217,7 +1212,9 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) wine_rb_clear(&device->samplers, device_free_sampler, NULL); +#if defined(STAGING_CSMT) context_set_current(NULL); +#endif /* STAGING_CSMT */ wined3d_device_delete_opengl_contexts(device); if (device->fb.depth_stencil) @@ -1931,24 +1928,13 @@ INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *devi return device->state.base_vertex_index; } -void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count, - const struct wined3d_viewport *viewports) +void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport) { - unsigned int i; + TRACE("device %p, viewport %p.\n", device, viewport); + TRACE("x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n", + viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z); - TRACE("device %p, viewport_count %u, viewports %p.\n", device, viewport_count, viewports); - - for (i = 0; i < viewport_count; ++i) - { - TRACE("%u: x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n", i, viewports[i].x, viewports[i].y, - viewports[i].width, viewports[i].height, viewports[i].min_z, viewports[i].max_z); - } - - if (viewport_count) - memcpy(device->update_state->viewports, viewports, viewport_count * sizeof(*viewports)); - else - memset(device->update_state->viewports, 0, sizeof(device->update_state->viewports)); - device->update_state->viewport_count = viewport_count; + device->update_state->viewport = *viewport; /* Handle recording of state blocks */ if (device->recording) @@ -1958,21 +1944,14 @@ void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned return; } - wined3d_cs_emit_set_viewports(device->cs, viewport_count, viewports); + wined3d_cs_emit_set_viewport(device->cs, viewport); } -void CDECL wined3d_device_get_viewports(const struct wined3d_device *device, unsigned int *viewport_count, - struct wined3d_viewport *viewports) +void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport) { - unsigned int count; + TRACE("device %p, viewport %p.\n", device, viewport); - TRACE("device %p, viewport_count %p, viewports %p.\n", device, viewport_count, viewports); - - count = viewport_count ? min(*viewport_count, device->state.viewport_count) : 1; - if (count && viewports) - memcpy(viewports, device->state.viewports, count * sizeof(*viewports)); - if (viewport_count) - *viewport_count = device->state.viewport_count; + *viewport = device->state.viewport; } static void resolve_depth_buffer(struct wined3d_device *device) @@ -2144,33 +2123,19 @@ DWORD CDECL wined3d_device_get_sampler_state(const struct wined3d_device *device return device->state.sampler_states[sampler_idx][state]; } -void CDECL wined3d_device_set_scissor_rects(struct wined3d_device *device, unsigned int rect_count, - const RECT *rects) +void CDECL wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect) { - unsigned int i; - - TRACE("device %p, rect_count %u, rects %p.\n", device, rect_count, rects); - - for (i = 0; i < rect_count; ++i) - { - TRACE("%u: %s\n", i, wine_dbgstr_rect(&rects[i])); - } + TRACE("device %p, rect %s.\n", device, wine_dbgstr_rect(rect)); if (device->recording) device->recording->changed.scissorRect = TRUE; - if (device->update_state->scissor_rect_count == rect_count - && !memcmp(device->update_state->scissor_rects, rects, rect_count * sizeof(*rects))) + if (EqualRect(&device->update_state->scissor_rect, rect)) { - TRACE("App is setting the old scissor rectangles over, nothing to do.\n"); + TRACE("App is setting the old scissor rectangle over, nothing to do.\n"); return; } - - if (rect_count) - memcpy(device->update_state->scissor_rects, rects, rect_count * sizeof(*rects)); - else - memset(device->update_state->scissor_rects, 0, sizeof(device->update_state->scissor_rects)); - device->update_state->scissor_rect_count = rect_count; + CopyRect(&device->update_state->scissor_rect, rect); if (device->recording) { @@ -2178,20 +2143,15 @@ void CDECL wined3d_device_set_scissor_rects(struct wined3d_device *device, unsig return; } - wined3d_cs_emit_set_scissor_rects(device->cs, rect_count, rects); + wined3d_cs_emit_set_scissor_rect(device->cs, rect); } -void CDECL wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count, RECT *rects) +void CDECL wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect) { - unsigned int count; + TRACE("device %p, rect %p.\n", device, rect); - TRACE("device %p, rect_count %p, rects %p.\n", device, rect_count, rects); - - count = rect_count ? min(*rect_count, device->state.scissor_rect_count) : 1; - if (count && rects) - memcpy(rects, device->state.scissor_rects, count * sizeof(*rects)); - if (rect_count) - *rect_count = device->state.scissor_rect_count; + *rect = device->state.scissor_rect; + TRACE("Returning rect %s.\n", wine_dbgstr_rect(rect)); } void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device, @@ -3105,23 +3065,6 @@ struct wined3d_unordered_access_view * CDECL wined3d_device_get_unordered_access return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx); } -void CDECL wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int latency) -{ - unsigned int i; - - if (!latency) - latency = 3; - - device->max_frame_latency = latency; - for (i = 0; i < device->swapchain_count; ++i) - swapchain_set_max_frame_latency(device->swapchains[i], device); -} - -unsigned int CDECL wined3d_device_get_max_frame_latency(const struct wined3d_device *device) -{ - return device->max_frame_latency; -} - /* Context activation is done by the caller. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount, @@ -3203,8 +3146,8 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO TRACE("%.8e %.8e %.8e %.8e\n", world_mat._41, world_mat._42, world_mat._43, world_mat._44); /* Get the viewport */ - wined3d_device_get_viewports(device, NULL, &vp); - TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n", + wined3d_device_get_viewport(device, &vp); + TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n", vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z); multiply_matrix(&mat,&view_mat,&world_mat); @@ -3919,9 +3862,12 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, level_count = min(src_level_count, dst_level_count); src_size = max(src_texture->resource.width, src_texture->resource.height); - src_size = max(src_size, src_texture->resource.depth); dst_size = max(dst_texture->resource.width, dst_texture->resource.height); - dst_size = max(dst_size, dst_texture->resource.depth); + if (type == WINED3D_RTYPE_TEXTURE_3D) + { + src_size = max(src_size, src_texture->resource.depth); + dst_size = max(dst_size, dst_texture->resource.depth); + } while (src_size > dst_size) { src_size >>= 1; @@ -4175,17 +4121,14 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device, HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *device, struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource, - unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, unsigned int flags) + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) { struct wined3d_box dst_box, b; TRACE("device %p, dst_resource %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, " - "src_resource %p, src_sub_resource_idx %u, src_box %s, flags %#x.\n", + "src_resource %p, src_sub_resource_idx %u, src_box %s.\n", device, dst_resource, dst_sub_resource_idx, dst_x, dst_y, dst_z, - src_resource, src_sub_resource_idx, debug_box(src_box), flags); - - if (flags) - FIXME("Ignoring flags %#x.\n", flags); + src_resource, src_sub_resource_idx, debug_box(src_box)); if (src_resource == dst_resource && src_sub_resource_idx == dst_sub_resource_idx) { @@ -4250,7 +4193,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev wined3d_box_set(&dst_box, dst_x, 0, dst_x + (src_box->right - src_box->left), 1, 0, 1); } - else + else if (dst_resource->type == WINED3D_RTYPE_TEXTURE_2D) { struct wined3d_texture *dst_texture = texture_from_resource(dst_resource); struct wined3d_texture *src_texture = texture_from_resource(src_resource); @@ -4268,6 +4211,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev return WINED3DERR_INVALIDCALL; } +#if !defined(STAGING_CSMT) if (dst_texture->sub_resources[dst_sub_resource_idx].map_count) { WARN("Destination sub-resource %u is mapped.\n", dst_sub_resource_idx); @@ -4278,22 +4222,33 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev { WARN("Source sub-resource %u is mapped.\n", src_sub_resource_idx); return WINED3DERR_INVALIDCALL; +#else /* STAGING_CSMT */ + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count || + src_texture->sub_resources[src_sub_resource_idx].map_count) + { + struct wined3d_device *device = dst_texture->resource.device; + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count || + src_texture->sub_resources[src_sub_resource_idx].map_count) + { + WARN("Destination or source sub-resource is mapped.\n"); + return WINEDDERR_SURFACEBUSY; + } +#endif /* STAGING_CSMT */ } if (!src_box) { - unsigned int src_w, src_h, src_d, dst_w, dst_h, dst_d, dst_level; + unsigned int src_w, src_h, dst_w, dst_h, dst_level; src_w = wined3d_texture_get_level_width(src_texture, src_level); src_h = wined3d_texture_get_level_height(src_texture, src_level); - src_d = wined3d_texture_get_level_depth(src_texture, src_level); dst_level = dst_sub_resource_idx % dst_texture->level_count; dst_w = wined3d_texture_get_level_width(dst_texture, dst_level) - dst_x; dst_h = wined3d_texture_get_level_height(dst_texture, dst_level) - dst_y; - dst_d = wined3d_texture_get_level_depth(dst_texture, dst_level) - dst_z; - wined3d_box_set(&b, 0, 0, min(src_w, dst_w), min(src_h, dst_h), 0, min(src_d, dst_d)); + wined3d_box_set(&b, 0, 0, min(src_w, dst_w), min(src_h, dst_h), 0, 1); src_box = &b; } else if (FAILED(wined3d_texture_check_box_dimensions(src_texture, src_level, src_box))) @@ -4303,7 +4258,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev } wined3d_box_set(&dst_box, dst_x, dst_y, dst_x + (src_box->right - src_box->left), - dst_y + (src_box->bottom - src_box->top), dst_z, dst_z + (src_box->back - src_box->front)); + dst_y + (src_box->bottom - src_box->top), 0, 1); if (FAILED(wined3d_texture_check_box_dimensions(dst_texture, dst_sub_resource_idx % dst_texture->level_count, &dst_box))) { @@ -4311,6 +4266,11 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev return WINED3DERR_INVALIDCALL; } } + else + { + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type)); + return WINED3DERR_INVALIDCALL; + } wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box, src_resource, src_sub_resource_idx, src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT); @@ -4320,17 +4280,13 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, - unsigned int depth_pitch, unsigned int flags) + unsigned int depth_pitch) { unsigned int width, height, depth; struct wined3d_box b; - TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u, " - "flags %#x.\n", - device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch, flags); - - if (flags) - FIXME("Ignoring flags %#x.\n", flags); + TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u.\n", + device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch); if (resource->type == WINED3D_RTYPE_BUFFER) { @@ -4344,7 +4300,8 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str height = 1; depth = 1; } - else + else if (resource->type == WINED3D_RTYPE_TEXTURE_1D || + resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D) { struct wined3d_texture *texture = texture_from_resource(resource); unsigned int level; @@ -4360,6 +4317,11 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str height = wined3d_texture_get_level_height(texture, level); depth = wined3d_texture_get_level_depth(texture, level); } + else + { + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); + return; + } if (!box) { @@ -4374,6 +4336,10 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str return; } +#if !defined(STAGING_CSMT) + wined3d_resource_wait_idle(resource); + +#endif /* STAGING_CSMT */ wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); } @@ -4437,7 +4403,7 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi return WINED3D_OK; resource = view->resource; - if (resource->type != WINED3D_RTYPE_TEXTURE_1D && resource->type != WINED3D_RTYPE_TEXTURE_2D) + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) { FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); return WINED3DERR_INVALIDCALL; @@ -4526,20 +4492,19 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device { struct wined3d_state *state = &device->state; - state->viewports[0].x = 0; - state->viewports[0].y = 0; - state->viewports[0].width = view->width; - state->viewports[0].height = view->height; - state->viewports[0].min_z = 0.0f; - state->viewports[0].max_z = 1.0f; - state->viewport_count = 1; - wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports); + state->viewport.x = 0; + state->viewport.y = 0; + state->viewport.width = view->width; + state->viewport.height = view->height; + state->viewport.min_z = 0.0f; + state->viewport.max_z = 1.0f; + wined3d_cs_emit_set_viewport(device->cs, &state->viewport); - SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height); - state->scissor_rect_count = 1; - wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects); + SetRect(&state->scissor_rect, 0, 0, view->width, view->height); + wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); } + prev = device->fb.render_targets[view_idx]; if (view == prev) return WINED3D_OK; @@ -4871,9 +4836,10 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, TRACE("auto_depth_stencil_format %s\n", debug_d3dformat(swapchain_desc->auto_depth_stencil_format)); TRACE("flags %#x\n", swapchain_desc->flags); TRACE("refresh_rate %u\n", swapchain_desc->refresh_rate); + TRACE("swap_interval %u\n", swapchain_desc->swap_interval); TRACE("auto_restore_display_mode %#x\n", swapchain_desc->auto_restore_display_mode); - if (swapchain_desc->backbuffer_usage && swapchain_desc->backbuffer_usage != WINED3DUSAGE_RENDERTARGET) + if (swapchain_desc->backbuffer_usage != WINED3DUSAGE_RENDERTARGET) FIXME("Got unexpected backbuffer usage %#x.\n", swapchain_desc->backbuffer_usage); if (swapchain_desc->swap_effect != WINED3D_SWAP_EFFECT_DISCARD @@ -4887,6 +4853,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, swapchain->desc.auto_depth_stencil_format = swapchain_desc->auto_depth_stencil_format; swapchain->desc.flags = swapchain_desc->flags; swapchain->desc.refresh_rate = swapchain_desc->refresh_rate; + swapchain->desc.swap_interval = swapchain_desc->swap_interval; swapchain->desc.auto_restore_display_mode = swapchain_desc->auto_restore_display_mode; if (swapchain_desc->device_window @@ -4988,7 +4955,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_rendertarget_view_decref(device->back_buffer_view); device->back_buffer_view = NULL; } - if (swapchain->desc.backbuffer_count && swapchain->desc.backbuffer_usage & WINED3DUSAGE_RENDERTARGET) + if (swapchain->desc.backbuffer_count) { struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource; @@ -5039,22 +5006,21 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_device_set_rendertarget_view(device, 0, view, FALSE); /* Note the min_z / max_z is not reset. */ - state->viewports[0].x = 0; - state->viewports[0].y = 0; - state->viewports[0].width = view->width; - state->viewports[0].height = view->height; - state->viewport_count = 1; - wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports); + state->viewport.x = 0; + state->viewport.y = 0; + state->viewport.width = view->width; + state->viewport.height = view->height; + wined3d_cs_emit_set_viewport(device->cs, &state->viewport); - SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height); - state->scissor_rect_count = 1; - wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects); + SetRect(&state->scissor_rect, 0, 0, view->width, view->height); + wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); } if (device->d3d_initialized) { if (reset_state) hr = wined3d_device_create_primary_opengl_context(device); + swapchain_update_swap_interval(swapchain); } /* All done. There is no need to reload resources or shaders, this will happen automatically on the @@ -5157,49 +5123,55 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso case WINED3D_RTYPE_TEXTURE_3D: for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) { - if (&device->state.textures[i]->resource == resource) + struct wined3d_texture *texture = texture_from_resource(resource); + + if (device->state.textures[i] == texture) { - ERR("Texture resource %p is still in use, stage %u.\n", resource, i); + ERR("Texture %p is still in use, stage %u.\n", texture, i); device->state.textures[i] = NULL; } - if (device->recording && &device->update_state->textures[i]->resource == resource) + if (device->recording && device->update_state->textures[i] == texture) { - ERR("Texture resource %p is still in use by recording stateblock %p, stage %u.\n", - resource, device->recording, i); + ERR("Texture %p is still in use by recording stateblock %p, stage %u.\n", + texture, device->recording, i); device->update_state->textures[i] = NULL; } } break; case WINED3D_RTYPE_BUFFER: - for (i = 0; i < MAX_STREAMS; ++i) { - if (&device->state.streams[i].buffer->resource == resource) + struct wined3d_buffer *buffer = buffer_from_resource(resource); + + for (i = 0; i < MAX_STREAMS; ++i) { - ERR("Buffer resource %p is still in use, stream %u.\n", resource, i); - device->state.streams[i].buffer = NULL; + if (device->state.streams[i].buffer == buffer) + { + ERR("Buffer %p is still in use, stream %u.\n", buffer, i); + device->state.streams[i].buffer = NULL; + } + + if (device->recording && device->update_state->streams[i].buffer == buffer) + { + ERR("Buffer %p is still in use by stateblock %p, stream %u.\n", + buffer, device->recording, i); + device->update_state->streams[i].buffer = NULL; + } } - if (device->recording && &device->update_state->streams[i].buffer->resource == resource) + if (device->state.index_buffer == buffer) { - ERR("Buffer resource %p is still in use by stateblock %p, stream %u.\n", - resource, device->recording, i); - device->update_state->streams[i].buffer = NULL; + ERR("Buffer %p is still in use as index buffer.\n", buffer); + device->state.index_buffer = NULL; } - } - if (&device->state.index_buffer->resource == resource) - { - ERR("Buffer resource %p is still in use as index buffer.\n", resource); - device->state.index_buffer = NULL; - } - - if (device->recording && &device->update_state->index_buffer->resource == resource) - { - ERR("Buffer resource %p is still in use by stateblock %p as index buffer.\n", - resource, device->recording); - device->update_state->index_buffer = NULL; + if (device->recording && device->update_state->index_buffer == buffer) + { + ERR("Buffer %p is still in use by stateblock %p as index buffer.\n", + buffer, device->recording); + device->update_state->index_buffer = NULL; + } } break; @@ -5268,8 +5240,6 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); device->update_state = &device->state; - device->max_frame_latency = 3; - if (!(device->cs = wined3d_cs_create(device))) { WARN("Failed to create command stream.\n"); @@ -5369,3 +5339,58 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL else return CallWindowProcA(proc, window, message, wparam, lparam); } +#if defined(STAGING_CSMT) + +/* Context activation is done by the caller */ +struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, + GLenum type_hint, struct wined3d_context *context) +{ + struct wined3d_gl_bo *ret; + const struct wined3d_gl_info *gl_info; + + TRACE("device %p, size %u, gl_usage %u, type_hint %u\n", device, size, gl_usage, + type_hint); + + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)); + if(!ret) + return NULL; + ret->type_hint = type_hint; + ret->size = size; + ret->usage = gl_usage; + + gl_info = context->gl_info; + + GL_EXTCALL(glGenBuffers(1, &ret->name)); + if (type_hint == GL_ELEMENT_ARRAY_BUFFER) + context_invalidate_state(context, STATE_INDEXBUFFER); + GL_EXTCALL(glBindBuffer(type_hint, ret->name)); + GL_EXTCALL(glBufferData(type_hint, size, NULL, gl_usage)); + GL_EXTCALL(glBindBuffer(type_hint, 0)); + checkGLcall("Create buffer object"); + + TRACE("Successfully created and set up buffer %u\n", ret->name); + return ret; +} + +/* Context activation is done by the caller */ +static void wined3d_device_destroy_bo(struct wined3d_device *device, const struct wined3d_context *context, + struct wined3d_gl_bo *bo) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name); + + GL_EXTCALL(glDeleteBuffers(1, &bo->name)); + checkGLcall("glDeleteBuffers"); + + HeapFree(GetProcessHeap(), 0, bo); +} + +/* Context activation is done by the caller */ +void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, + const struct wined3d_context *context) +{ + TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name); + + wined3d_device_destroy_bo(device, context, bo); +} +#endif /* STAGING_CSMT */ diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c index baeb287b5c8..d82a6713434 100644 --- a/dll/directx/wine/wined3d/directx.c +++ b/dll/directx/wine/wined3d/directx.c @@ -156,7 +156,6 @@ 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_sample_shading", ARB_SAMPLE_SHADING }, {"GL_ARB_sampler_objects", ARB_SAMPLER_OBJECTS }, {"GL_ARB_seamless_cube_map", ARB_SEAMLESS_CUBE_MAP }, {"GL_ARB_shader_atomic_counters", ARB_SHADER_ATOMIC_COUNTERS }, @@ -164,7 +163,6 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_shader_image_load_store", ARB_SHADER_IMAGE_LOAD_STORE }, {"GL_ARB_shader_image_size", ARB_SHADER_IMAGE_SIZE }, {"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT}, - {"GL_ARB_shader_texture_image_samples", ARB_SHADER_TEXTURE_IMAGE_SAMPLES}, {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD }, {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100 }, {"GL_ARB_shading_language_420pack", ARB_SHADING_LANGUAGE_420PACK }, @@ -203,6 +201,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_transform_feedback3", ARB_TRANSFORM_FEEDBACK3 }, {"GL_ARB_uniform_buffer_object", ARB_UNIFORM_BUFFER_OBJECT }, {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA }, + {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND }, {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT }, {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM }, {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER }, @@ -679,7 +678,7 @@ static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, struc GLenum error; DWORD data[16]; - if (!gl_info->supported[EXT_SECONDARY_COLOR] || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + if (!gl_info->supported[EXT_SECONDARY_COLOR]) return FALSE; while (gl_info->gl_ops.gl.p_glGetError()); @@ -859,8 +858,6 @@ static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, struct w return FALSE; if (!gl_info->supported[ARB_FRAGMENT_PROGRAM]) return FALSE; - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - return FALSE; gl_info->gl_ops.gl.p_glGenTextures(1, &tex); gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex); @@ -1401,13 +1398,11 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX980, "NVIDIA GeForce GTX 980", DRIVER_NVIDIA_GEFORCE8, 4096}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX980TI, "NVIDIA GeForce GTX 980 Ti", DRIVER_NVIDIA_GEFORCE8, 6144}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1050, "NVIDIA GeForce GTX 1050", DRIVER_NVIDIA_GEFORCE8, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1050TI, "NVIDIA GeForce GTX 1050 Ti", DRIVER_NVIDIA_GEFORCE8, 4096}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1060, "NVIDIA GeForce GTX 1060", DRIVER_NVIDIA_GEFORCE8, 6144}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1070, "NVIDIA GeForce GTX 1070", DRIVER_NVIDIA_GEFORCE8, 8192}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1080, "NVIDIA GeForce GTX 1080", DRIVER_NVIDIA_GEFORCE8, 8192}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1080TI, "NVIDIA GeForce GTX 1080 Ti", DRIVER_NVIDIA_GEFORCE8, 11264}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_TITANX_PASCAL, "NVIDIA TITAN X (Pascal)", DRIVER_NVIDIA_GEFORCE8, 12288}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_TITANV, "NVIDIA TITAN V", DRIVER_NVIDIA_GEFORCE8, 12288}, /* AMD cards */ {HW_VENDOR_AMD, CARD_AMD_RAGE_128PRO, "ATI Rage Fury", DRIVER_AMD_RAGE_128PRO, 16 }, @@ -1708,11 +1703,13 @@ static void init_driver_info(struct wined3d_driver_info *driver_info, * In order to avoid this application bug we limit the amount of video memory * to LONG_MAX for older Windows versions. */ +#ifdef __i386__ if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX) { TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX); driver_info->vram_bytes = LONG_MAX; } +#endif /* Try to obtain driver version information for the current Windows version. This fails in * some cases: @@ -1906,13 +1903,11 @@ static const struct wined3d_renderer_table cards_nvidia_binary[] = { /* Direct 3D 11 */ - {"TITAN V", CARD_NVIDIA_TITANV}, /* GeForce 1000 - highend */ {"TITAN X (Pascal)", CARD_NVIDIA_TITANX_PASCAL}, /* GeForce 1000 - highend */ {"GTX 1080 Ti", CARD_NVIDIA_GEFORCE_GTX1080TI}, /* GeForce 1000 - highend */ {"GTX 1080", CARD_NVIDIA_GEFORCE_GTX1080}, /* GeForce 1000 - highend */ {"GTX 1070", CARD_NVIDIA_GEFORCE_GTX1070}, /* GeForce 1000 - highend */ {"GTX 1060", CARD_NVIDIA_GEFORCE_GTX1060}, /* GeForce 1000 - midend high */ - {"GTX 1050 Ti", CARD_NVIDIA_GEFORCE_GTX1050TI}, /* GeForce 1000 - midend */ {"GTX 1050", CARD_NVIDIA_GEFORCE_GTX1050}, /* GeForce 1000 - midend */ {"GTX 980 Ti", CARD_NVIDIA_GEFORCE_GTX980TI}, /* GeForce 900 - highend */ {"GTX 980", CARD_NVIDIA_GEFORCE_GTX980}, /* GeForce 900 - highend */ @@ -2230,7 +2225,9 @@ cards_intel[] = {"830M", CARD_INTEL_830M}, }, /* 20101109 - These are never returned by current Gallium radeon - * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351. */ + * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351. + * + * These are returned but not handled: RC410, RV380. */ cards_amd_mesa[] = { /* Polaris 10/11 */ @@ -2308,12 +2305,10 @@ cards_amd_mesa[] = {"RS482", CARD_AMD_RADEON_XPRESS_200M}, {"RS480", CARD_AMD_RADEON_XPRESS_200M}, {"RS400", CARD_AMD_RADEON_XPRESS_200M}, - {"RC410", CARD_AMD_RADEON_XPRESS_200M}, /* R300 */ {"R360", CARD_AMD_RADEON_9500}, {"R350", CARD_AMD_RADEON_9500}, {"R300", CARD_AMD_RADEON_9500}, - {"RV380", CARD_AMD_RADEON_9500}, {"RV370", CARD_AMD_RADEON_9500}, {"RV360", CARD_AMD_RADEON_9500}, {"RV351", CARD_AMD_RADEON_9500}, @@ -2827,8 +2822,6 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glPointParameterfvARB) /* GL_ARB_provoking_vertex */ USE_GL_FUNC(glProvokingVertex) - /* GL_ARB_sample_shading */ - USE_GL_FUNC(glMinSampleShadingARB) /* GL_ARB_sampler_objects */ USE_GL_FUNC(glGenSamplers) USE_GL_FUNC(glDeleteSamplers) @@ -2955,6 +2948,17 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) 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) @@ -3422,7 +3426,6 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT); MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB); MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB); - MAP_GL_FUNCTION(glMinSampleShading, glMinSampleShadingARB); MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB); MAP_GL_FUNCTION(glTexBuffer, glTexBufferARB); MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT); @@ -3476,6 +3479,7 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) GLfloat gl_floatv[2]; GLint gl_max; + gl_info->limits.blends = 1; gl_info->limits.buffers = 1; gl_info->limits.textures = 0; gl_info->limits.texture_coords = 0; @@ -3631,6 +3635,12 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) gl_info->limits.texture_coords = 1; } + if (gl_info->supported[ARB_VERTEX_BLEND]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max); + gl_info->limits.blends = gl_max; + TRACE("Max blends: %u.\n", gl_info->limits.blends); + } if (gl_info->supported[EXT_TEXTURE3D]) { gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max); @@ -3900,7 +3910,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, {EXT_TEXTURE_SNORM, MAKEDWORD_VERSION(3, 1)}, /* We don't need or want GL_ARB_texture_rectangle (core in 3.1). */ - {ARB_DEPTH_CLAMP, MAKEDWORD_VERSION(3, 2)}, {ARB_DRAW_ELEMENTS_BASE_VERTEX, MAKEDWORD_VERSION(3, 2)}, /* ARB_geometry_shader4 exposes a somewhat different API compared to 3.2 * core geometry shaders so it's not really correct to expose the @@ -3924,7 +3933,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, {ARB_DRAW_INDIRECT, MAKEDWORD_VERSION(4, 0)}, {ARB_GPU_SHADER5, MAKEDWORD_VERSION(4, 0)}, - {ARB_SAMPLE_SHADING, MAKEDWORD_VERSION(4, 0)}, {ARB_TESSELLATION_SHADER, MAKEDWORD_VERSION(4, 0)}, {ARB_TEXTURE_CUBE_MAP_ARRAY, MAKEDWORD_VERSION(4, 0)}, {ARB_TEXTURE_GATHER, MAKEDWORD_VERSION(4, 0)}, @@ -3966,7 +3974,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, {ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)}, {ARB_CULL_DISTANCE, MAKEDWORD_VERSION(4, 5)}, {ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)}, - {ARB_SHADER_TEXTURE_IMAGE_SAMPLES, MAKEDWORD_VERSION(4, 5)}, {ARB_PIPELINE_STATISTICS_QUERY, MAKEDWORD_VERSION(4, 6)}, {ARB_TEXTURE_FILTER_ANISOTROPIC, MAKEDWORD_VERSION(4, 6)}, @@ -4080,11 +4087,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, gl_info->supported[WINED3D_GL_BLEND_EQUATION] = TRUE; if (gl_version >= MAKEDWORD_VERSION(2, 0)) - { gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE; - /* We want to use the core APIs for two-sided stencil in GL 2.0. */ - gl_info->supported[EXT_STENCIL_TWO_SIDE] = FALSE; - } if (gl_version >= MAKEDWORD_VERSION(3, 2)) gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE; @@ -5357,7 +5360,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad case WINED3D_RTYPE_NONE: allowed_usage = WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_RENDERTARGET; - gl_type = WINED3D_GL_RES_TYPE_TEX_2D; + gl_type = WINED3D_GL_RES_TYPE_TEX_1D; gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D; break; @@ -5366,7 +5369,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad | WINED3DUSAGE_SOFTWAREPROCESSING | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER - | WINED3DUSAGE_QUERY_GENMIPMAP | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING | WINED3DUSAGE_QUERY_SRGBREAD | WINED3DUSAGE_QUERY_SRGBWRITE @@ -5431,6 +5433,12 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D; break; + case WINED3D_RTYPE_BUFFER: + allowed_usage = WINED3DUSAGE_DYNAMIC + | WINED3DUSAGE_QUERY_VERTEXTEXTURE; + gl_type = gl_type_end = WINED3D_GL_RES_TYPE_BUFFER; + break; + default: FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type)); return WINED3DERR_NOTAVAILABLE; @@ -5679,6 +5687,9 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DCAPS3_COPY_TO_VIDMEM | WINED3DCAPS3_COPY_TO_SYSTEMMEM; + caps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE | + WINED3DPRESENT_INTERVAL_ONE; + caps->CursorCaps = WINED3DCURSORCAPS_COLOR | WINED3DCURSORCAPS_LOWRES; @@ -6608,16 +6619,28 @@ static DWORD get_max_gl_version(const struct wined3d_gl_info *gl_info, DWORD fla { const char *gl_vendor, *gl_renderer; - if (wined3d_settings.explicit_gl_version) + if (wined3d_settings.explicit_gl_version || (flags & WINED3D_PIXEL_CENTER_INTEGER)) return wined3d_settings.max_gl_version; gl_vendor = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR); gl_renderer = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER); if (!gl_vendor || !gl_renderer || wined3d_guess_card_vendor(gl_vendor, gl_renderer) == HW_VENDOR_NVIDIA) - return MAKEDWORD_VERSION(1, 0); + return wined3d_settings.max_gl_version; - return wined3d_settings.max_gl_version; + return MAKEDWORD_VERSION(4, 4); +} + +static BOOL has_extension(const char *list, const char *ext) +{ + size_t len = strlen(ext); + while (list) + { + while (*list == ' ') list++; + if (!strncmp(list, ext, len) && (!list[len] || list[len] == ' ')) return TRUE; + list = strchr(list, ' '); + } + return FALSE; } static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags) @@ -6678,6 +6701,17 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, } max_gl_version = get_max_gl_version(gl_info, wined3d_creation_flags); + + if (wined3d_creation_flags & WINED3D_REQUEST_D3D10) + { + const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS); + if (!has_extension(gl_extensions, "GL_ARB_compatibility")) + { + ERR_(winediag)("GL_ARB_compatibility not supported, requesting context with GL version 3.2.\n"); + max_gl_version = MAKEDWORD_VERSION(3, 2); + } + } + for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i) { if (supported_gl_versions[i] <= max_gl_version) diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c index 41bd1fd0552..4c879f9fc5e 100644 --- a/dll/directx/wine/wined3d/glsl_shader.c +++ b/dll/directx/wine/wined3d/glsl_shader.c @@ -91,6 +91,7 @@ struct glsl_sample_function enum wined3d_data_type data_type; BOOL output_single_component; unsigned int offset_size; + enum wined3d_shader_resource_type emulate_lod; }; enum heap_node_op @@ -804,12 +805,11 @@ static void append_transform_feedback_skip_components(const char **varyings, } } -static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc, +static void shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc, struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count, char *strings, unsigned int *strings_length, GLenum buffer_mode) { unsigned int i, buffer_idx, count, length, highest_output_slot, stride; - BOOL have_varyings_to_record = FALSE; count = length = 0; highest_output_slot = 0; @@ -859,8 +859,6 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3 string_buffer_sprintf(buffer, "shader_in_out.reg%u", e->register_idx); append_transform_feedback_varying(varyings, &count, &strings, &length, buffer); } - - have_varyings_to_record = TRUE; } if (buffer_idx < so_desc->buffer_stride_count @@ -885,12 +883,10 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3 *varying_count = count; if (strings_length) *strings_length = length; - - return have_varyings_to_record; } static void shader_glsl_init_transform_feedback(const struct wined3d_context *context, - struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader) + struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader) { const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc; const struct wined3d_gl_info *gl_info = context->gl_info; @@ -946,13 +942,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co buffer = string_buffer_get(&priv->string_buffers); - if (!shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode)) - { - FIXME("No varyings to record, disabling transform feedback.\n"); - shader->u.gs.so_desc.element_count = 0; - string_buffer_release(&priv->string_buffers, buffer); - return; - } + shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode); if (!(varyings = heap_calloc(count, sizeof(*varyings)))) { @@ -1470,7 +1460,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_priv *priv = shader_priv; - float position_fixup[4 * WINED3D_MAX_VIEWPORTS]; + float position_fixup[4]; float normal[3 * 3]; DWORD update_mask; @@ -1508,11 +1498,9 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP) { - unsigned int fixup_count = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ? - max(state->viewport_count, 1) : 1; - shader_get_position_fixup(context, state, fixup_count, position_fixup); + shader_get_position_fixup(context, state, position_fixup); if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) - GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, fixup_count, position_fixup)); + GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup)); else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN]) GL_EXTCALL(glUniform4fv(prog->ds.pos_fixup_location, 1, position_fixup)); else @@ -1969,11 +1957,6 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_ } } -static const char *get_fragment_output(const struct wined3d_gl_info *gl_info) -{ - return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" : "ps_out"; -} - static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) { switch (primitive_type) @@ -2956,10 +2939,6 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * sprintf(register_name, "vpc[%u]", reg->idx[0].offset); break; - case WINED3DSPR_SAMPLEMASK: - sprintf(register_name, "sample_mask"); - break; - default: FIXME("Unhandled register type %#x.\n", reg->type); sprintf(register_name, "unrecognized_register"); @@ -3264,6 +3243,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type; struct shader_glsl_ctx_priv *priv = ctx->backend_data; const struct wined3d_gl_info *gl_info = ctx->gl_info; + BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx); BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL @@ -3276,6 +3256,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context unsigned int coord_size, deriv_size; sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type; + sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE; if (resource_type >= ARRAY_SIZE(resource_type_info)) { @@ -3287,7 +3268,30 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) projected = FALSE; - if (needs_legacy_glsl_syntax(gl_info)) + if (shadow && lod) + { + switch (resource_type) + { + /* emulate textureLod(sampler2DArrayShadow, ...) using textureGradOffset */ + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: + sample_function->emulate_lod = resource_type; + grad = offset = TRUE; + lod = FALSE; + break; + + /* emulate textureLod(samplerCubeShadow, ...) using shadowCubeGrad */ + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + sample_function->emulate_lod = resource_type; + grad = legacy_syntax = TRUE; + lod = FALSE; + break; + + default: + break; + } + } + + if (legacy_syntax) { if (shadow) base = "shadow"; @@ -3327,7 +3331,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context sample_function->offset_size = offset ? deriv_size : 0; sample_function->coord_mask = (1u << coord_size) - 1; sample_function->deriv_mask = (1u << deriv_size) - 1; - sample_function->output_single_component = shadow && !needs_legacy_glsl_syntax(gl_info); + sample_function->output_single_component = shadow && !legacy_syntax; } static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx, @@ -3448,6 +3452,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset, const char *coord_reg_fmt, ...) { + static const struct wined3d_shader_texel_offset dummy_offset = {0, 0, 0}; const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version; char dst_swizzle[6]; struct color_fixup_desc fixup; @@ -3516,6 +3521,26 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ break; } } + if (sample_function->emulate_lod) + { + if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod level %s\n", bias); + switch (sample_function->emulate_lod) + { + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: + if (!dx) dx = "vec2(0.0, 0.0)"; + if (!dy) dy = "vec2(0.0, 0.0)"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + if (!dx) dx = "vec3(0.0, 0.0, 0.0)"; + if (!dy) dy = "vec3(0.0, 0.0, 0.0)"; + break; + + default: + break; + } + if (!offset) offset = &dummy_offset; + } if (dx && dy) shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy); else if (bias) @@ -3537,7 +3562,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ shader_glsl_color_correction(ins, fixup); } -static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOOL use_viewport_index) +static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer) { /* Write the final position. * @@ -3546,16 +3571,8 @@ static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOO * pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering * upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow * a MAD. */ - if (use_viewport_index) - { - shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup[gl_ViewportIndex].y;\n"); - shader_addline(buffer, "gl_Position.xy += pos_fixup[gl_ViewportIndex].zw * gl_Position.ww;\n"); - } - else - { - shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n"); - shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n"); - } + shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n"); + shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n"); /* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix() * in utils.c @@ -4881,11 +4898,10 @@ static void shader_glsl_else(const struct wined3d_shader_instruction *ins) static void shader_glsl_emit(const struct wined3d_shader_instruction *ins) { unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset; - const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n"); if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL]) - shader_glsl_fixup_position(ins->ctx->buffer, reg_maps->viewport_array); + shader_glsl_fixup_position(ins->ctx->buffer); if (!stream) shader_addline(ins->ctx->buffer, "EmitVertex();\n"); @@ -5740,71 +5756,6 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins) shader_addline(buffer, ")%s);\n", dst_swizzle); } -static void shader_glsl_sample_info(const struct wined3d_shader_instruction *ins) -{ - const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; - struct wined3d_string_buffer *buffer = ins->ctx->buffer; - const struct wined3d_shader_dst_param *dst = ins->dst; - const struct wined3d_shader_src_param *src = ins->src; - enum wined3d_shader_resource_type resource_type; - enum wined3d_data_type dst_data_type; - unsigned int resource_idx, bind_idx; - char dst_swizzle[6]; - DWORD write_mask; - - dst_data_type = dst->reg.data_type; - if (ins->flags == WINED3DSI_SAMPLE_INFO_UINT) - dst_data_type = WINED3D_DATA_UINT; - else if (ins->flags) - FIXME("Unhandled flags %#x.\n", ins->flags); - - write_mask = shader_glsl_append_dst_ext(buffer, ins, dst, dst_data_type); - shader_glsl_get_swizzle(src, FALSE, write_mask, dst_swizzle); - - if (dst_data_type == WINED3D_DATA_UINT) - shader_addline(buffer, "uvec4("); - else - shader_addline(buffer, "vec4("); - - if (src->reg.type == WINED3DSPR_RASTERIZER) - { - if (gl_info->supported[ARB_SAMPLE_SHADING]) - { - shader_addline(buffer, "gl_NumSamples"); - } - else - { - FIXME("OpenGL implementation does not support ARB_sample_shading.\n"); - shader_addline(buffer, "1"); - } - } - else - { - resource_idx = src->reg.idx[0].offset; - resource_type = reg_maps->resource_info[resource_idx].type; - if (resource_type >= ARRAY_SIZE(resource_type_info)) - { - ERR("Unexpected resource type %#x.\n", resource_type); - return; - } - bind_idx = shader_glsl_find_sampler(®_maps->sampler_map, resource_idx, WINED3D_SAMPLER_DEFAULT); - - if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES]) - { - shader_addline(buffer, "textureSamples(%s_sampler%u)", - shader_glsl_get_prefix(reg_maps->shader_version.type), bind_idx); - } - else - { - FIXME("textureSamples() is not supported.\n"); - shader_addline(buffer, "1"); - } - } - - shader_addline(buffer, ", 0, 0, 0)%s);\n", dst_swizzle); -} - static void shader_glsl_ld(const struct wined3d_shader_instruction *ins) { const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; @@ -6547,7 +6498,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w semantic_idx = input->semantic_idx; shader_glsl_write_mask_to_str(input->mask, reg_mask); - if (args->vp_mode == WINED3D_VP_MODE_SHADER) + if (args->vp_mode == vertexshader) { if (input->sysval_semantic == WINED3D_SV_POSITION && !semantic_idx) { @@ -6563,14 +6514,6 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w shader_addline(buffer, "ps_in[%u]%s = uintBitsToFloat(gl_FrontFacing ? 0xffffffffu : 0u);\n", input->register_idx, reg_mask); } - else if (input->sysval_semantic == WINED3D_SV_SAMPLE_INDEX) - { - if (gl_info->supported[ARB_SAMPLE_SHADING]) - shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_SampleID);\n", - input->register_idx, reg_mask); - else - FIXME("ARB_sample_shading is not supported.\n"); - } else if (input->sysval_semantic == WINED3D_SV_RENDER_TARGET_ARRAY_INDEX && !semantic_idx) { if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT]) @@ -6579,14 +6522,6 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w else FIXME("ARB_fragment_layer_viewport is not supported.\n"); } - else if (input->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx) - { - if (gl_info->supported[ARB_VIEWPORT_ARRAY]) - shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_ViewportIndex);\n", - input->register_idx, reg_mask); - else - FIXME("ARB_viewport_array is not supported.\n"); - } else { if (input->sysval_semantic) @@ -6602,7 +6537,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w if (args->pointsprite) shader_addline(buffer, "ps_in[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", shader->u.ps.input_reg_map[input->register_idx]); - else if (args->vp_mode == WINED3D_VP_MODE_NONE && args->texcoords_initialized & (1u << semantic_idx)) + else if (args->vp_mode == pretransformed && args->texcoords_initialized & (1u << semantic_idx)) shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n", shader->u.ps.input_reg_map[input->register_idx], reg_mask, needs_legacy_glsl_syntax(gl_info) @@ -6878,11 +6813,6 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv shader_addline(buffer, "gl_Layer = floatBitsToInt(outputs[%u])%s;\n", output->register_idx, reg_mask); } - else if (output->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx) - { - shader_addline(buffer, "gl_ViewportIndex = floatBitsToInt(outputs[%u])%s;\n", - output->register_idx, reg_mask); - } else if (output->sysval_semantic == WINED3D_SV_CLIP_DISTANCE) { shader_glsl_generate_clip_or_cull_distances(buffer, output, reg_maps_out->clip_distance_mask); @@ -7307,8 +7237,6 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, shader_addline(buffer, "#extension GL_ARB_shader_image_size : enable\n"); if (gl_info->supported[ARB_SHADER_STORAGE_BUFFER_OBJECT]) shader_addline(buffer, "#extension GL_ARB_shader_storage_buffer_object : enable\n"); - if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES]) - shader_addline(buffer, "#extension GL_ARB_shader_texture_image_samples : enable\n"); if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n"); if (gl_info->supported[ARB_SHADING_LANGUAGE_PACKING]) @@ -7321,8 +7249,6 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n"); - if (gl_info->supported[ARB_VIEWPORT_ARRAY]) - shader_addline(buffer, "#extension GL_ARB_viewport_array : enable\n"); if (gl_info->supported[EXT_GPU_SHADER4]) shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n"); if (gl_info->supported[EXT_TEXTURE_ARRAY]) @@ -7348,9 +7274,6 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in shader_glsl_generate_fog_code(buffer, gl_info, args->fog); shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1); - - if (reg_maps->sample_mask) - shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n"); } /* Context activation is done by the caller. */ @@ -7387,8 +7310,6 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "#extension GL_ARB_fragment_coord_conventions : enable\n"); if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT]) shader_addline(buffer, "#extension GL_ARB_fragment_layer_viewport : enable\n"); - if (gl_info->supported[ARB_SAMPLE_SHADING]) - shader_addline(buffer, "#extension GL_ARB_sample_shading : enable\n"); if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n"); /* The spec says that it doesn't have to be explicitly enabled, but the @@ -7441,7 +7362,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts); } - if (version->major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER) + if (version->major < 3 || args->vp_mode != vertexshader) { shader_addline(buffer, "uniform struct\n{\n"); shader_addline(buffer, " vec4 color;\n"); @@ -7475,7 +7396,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context { unsigned int in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); - if (args->vp_mode == WINED3D_VP_MODE_SHADER && reg_maps->input_registers) + if (args->vp_mode == vertexshader && reg_maps->input_registers) shader_glsl_declare_shader_inputs(gl_info, buffer, in_count, shader->u.ps.interpolation_mode, version->major >= 4); shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); @@ -7561,9 +7482,6 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "void main()\n{\n"); - if (reg_maps->sample_mask) - shader_addline(buffer, "float sample_mask = uintBitsToFloat(0xffffffffu);\n"); - /* Direct3D applications expect integer vPos values, while OpenGL drivers * add approximately 0.5. This causes off-by-one problems as spotted by * the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly @@ -7592,7 +7510,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n"); } - if (reg_maps->shader_version.major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER) + if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader) { unsigned int i; WORD map = reg_maps->texcoord; @@ -7686,7 +7604,7 @@ static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_in shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n"); if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) - shader_glsl_fixup_position(buffer, FALSE); + shader_glsl_fixup_position(buffer); } /* Context activation is done by the caller. */ @@ -7924,7 +7842,7 @@ static void shader_glsl_generate_ds_epilogue(const struct wined3d_gl_info *gl_in shader_addline(buffer, "setup_ds_output(ds_out);\n"); if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) - shader_glsl_fixup_position(buffer, FALSE); + shader_glsl_fixup_position(buffer); } static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *context, @@ -8028,11 +7946,7 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; struct wined3d_string_buffer *buffer = &priv->shader_buffer; const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_shader_signature_element *output; - enum wined3d_primitive_type primitive_type; struct shader_glsl_ctx_priv priv_ctx; - unsigned int max_vertices; - unsigned int i, j; GLuint shader_id; memset(&priv_ctx, 0, sizeof(priv_ctx)); @@ -8044,42 +7958,16 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); - primitive_type = shader->u.gs.input_type ? shader->u.gs.input_type : args->primitive_type; - shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(primitive_type)); + shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(shader->u.gs.input_type)); if (shader->u.gs.instance_count > 1) shader_addline(buffer, ", invocations = %u", shader->u.gs.instance_count); shader_addline(buffer, ") in;\n"); - - primitive_type = shader->u.gs.output_type ? shader->u.gs.output_type : args->primitive_type; - if (!(max_vertices = shader->u.gs.vertices_out)) - { - switch (args->primitive_type) - { - case WINED3D_PT_POINTLIST: - max_vertices = 1; - break; - case WINED3D_PT_LINELIST: - max_vertices = 2; - break; - case WINED3D_PT_TRIANGLELIST: - max_vertices = 3; - break; - default: - FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(args->primitive_type)); - break; - } - } shader_addline(buffer, "layout(%s, max_vertices = %u) out;\n", - glsl_primitive_type_from_d3d(primitive_type), max_vertices); + glsl_primitive_type_from_d3d(shader->u.gs.output_type), shader->u.gs.vertices_out); shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input); if (!gl_info->supported[ARB_CLIP_CONTROL]) - { - shader_addline(buffer, "uniform vec4 pos_fixup"); - if (reg_maps->viewport_array) - shader_addline(buffer, "[%u]", WINED3D_MAX_VIEWPORTS); - shader_addline(buffer, ";\n"); - } + shader_addline(buffer, "uniform vec4 pos_fixup;\n"); if (is_rasterization_disabled(shader)) { @@ -8090,29 +7978,9 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info, TRUE, args->interpolation_mode); } - shader_addline(buffer, "void main()\n{\n"); - if (shader->function) - { - if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) - return 0; - } - else - { - for (i = 0; i < max_vertices; ++i) - { - for (j = 0; j < shader->output_signature.element_count; ++j) - { - output = &shader->output_signature.elements[j]; - shader_addline(buffer, "gs_out[%u] = shader_in[%u].reg[%u];\n", - output->register_idx, i, output->register_idx); - } - shader_addline(buffer, "setup_gs_output(gs_out);\n"); - if (!gl_info->supported[ARB_CLIP_CONTROL]) - shader_glsl_fixup_position(buffer, FALSE); - shader_addline(buffer, "EmitVertex();\n"); - } - } + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) + return 0; shader_addline(buffer, "}\n"); shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER)); @@ -9042,7 +8910,7 @@ static const char *shader_glsl_get_ffp_fragment_op_arg(struct wined3d_string_buf } static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color, - BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) + BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) { const char *dstmask, *dstreg, *arg0, *arg1, *arg2; @@ -9053,7 +8921,10 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un else dstmask = ".w"; - dstreg = tmp_dst ? "temp_reg" : "ret"; + if (dst == tempreg) + dstreg = "temp_reg"; + else + dstreg = "ret"; arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, dw_arg0); arg1 = shader_glsl_get_ffp_fragment_op_arg(buffer, 1, stage, dw_arg1); @@ -9223,7 +9094,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * tfactor_used = TRUE; if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) tempreg_used = TRUE; - if (settings->op[stage].tmp_dst) + if (settings->op[stage].dst == tempreg) tempreg_used = TRUE; if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT) tss_const_map |= 1u << stage; @@ -9419,12 +9290,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * if (!(tex_map & (1u << stage))) continue; - if (settings->op[stage].projected == WINED3D_PROJECTION_NONE) + if (settings->op[stage].projected == proj_none) { proj = FALSE; } - else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4 - || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3) + else if (settings->op[stage].projected == proj_count4 + || settings->op[stage].projected == proj_count3) { proj = TRUE; } @@ -9507,12 +9378,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "ret.xy = bumpenv_mat%u * tex%u.xy;\n", stage - 1, stage - 1); /* With projective textures, texbem only divides the static - * texture coordinate, not the displacement, so multiply the + * texture coord, not the displacement, so multiply the * displacement with the dividing parameter before passing it to * TXP. */ - if (settings->op[stage].projected != WINED3D_PROJECTION_NONE) + if (settings->op[stage].projected != proj_none) { - if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4) + if (settings->op[stage].projected == proj_count4) { shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].w) + ffp_texcoord[%u].xy;\n", stage, stage); @@ -9537,7 +9408,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n", stage, stage - 1, stage - 1, stage - 1); } - else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3) + else if (settings->op[stage].projected == proj_count3) { shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].xyz);\n", stage, texture_function, stage, stage); @@ -9589,23 +9460,23 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * if (settings->op[stage].aop == WINED3D_TOP_DISABLE) { - shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst, + shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } else if (op_equal) { - shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst, + shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE) { - shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst, + shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); - shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst, + shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].dst, settings->op[stage].aop, settings->op[stage].aarg0, settings->op[stage].aarg1, settings->op[stage].aarg2); } @@ -10905,7 +10776,6 @@ static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *g && gl_info->supported[ARB_SHADER_IMAGE_SIZE] && gl_info->supported[ARB_SHADING_LANGUAGE_PACKING] && gl_info->supported[ARB_TESSELLATION_SHADER] - && gl_info->supported[ARB_TEXTURE_COMPRESSION_BPTC] && gl_info->supported[ARB_TEXTURE_GATHER] && gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) return 5; @@ -11163,7 +11033,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_SAMPLE_C */ shader_glsl_sample_c, /* WINED3DSIH_SAMPLE_C_LZ */ shader_glsl_sample_c, /* WINED3DSIH_SAMPLE_GRAD */ shader_glsl_sample, - /* WINED3DSIH_SAMPLE_INFO */ shader_glsl_sample_info, + /* WINED3DSIH_SAMPLE_INFO */ NULL, /* WINED3DSIH_SAMPLE_LOD */ shader_glsl_sample, /* WINED3DSIH_SAMPLE_POS */ NULL, /* WINED3DSIH_SETP */ NULL, @@ -12108,854 +11978,3 @@ const struct fragment_pipeline glsl_fragment_pipe = shader_glsl_color_fixup_supported, glsl_fragment_pipe_state_template, }; - -struct glsl_blitter_args -{ - GLenum texture_type; - struct color_fixup_desc fixup; - unsigned short padding; -}; - -struct glsl_blitter_program -{ - struct wine_rb_entry entry; - struct glsl_blitter_args args; - GLuint id; -}; - -struct wined3d_glsl_blitter -{ - struct wined3d_blitter blitter; - struct wined3d_string_buffer_list string_buffers; - struct wine_rb_tree programs; - GLuint palette_texture; -}; - -static int glsl_blitter_args_compare(const void *key, const struct wine_rb_entry *entry) -{ - const struct glsl_blitter_args *a = key; - const struct glsl_blitter_args *b = &WINE_RB_ENTRY_VALUE(entry, const struct glsl_blitter_program, entry)->args; - - return memcmp(a, b, sizeof(*a)); -} - -/* Context activation is done by the caller. */ -static void glsl_free_blitter_program(struct wine_rb_entry *entry, void *ctx) -{ - struct glsl_blitter_program *program = WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry); - struct wined3d_context *context = ctx; - const struct wined3d_gl_info *gl_info = context->gl_info; - - GL_EXTCALL(glDeleteProgram(program->id)); - checkGLcall("glDeleteProgram()"); - heap_free(program); -} - -/* Context activation is done by the caller. */ -static void glsl_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_glsl_blitter *glsl_blitter; - struct wined3d_blitter *next; - - if ((next = blitter->next)) - next->ops->blitter_destroy(next, context); - - glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter); - - if (glsl_blitter->palette_texture) - gl_info->gl_ops.gl.p_glDeleteTextures(1, &glsl_blitter->palette_texture); - - wine_rb_destroy(&glsl_blitter->programs, glsl_free_blitter_program, context); - string_buffer_list_cleanup(&glsl_blitter->string_buffers); - - heap_free(glsl_blitter); -} - -static void glsl_blitter_generate_p8_shader(struct wined3d_string_buffer *buffer, - const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args, - const char *output, const char *tex_type, const char *swizzle) -{ - shader_addline(buffer, "uniform sampler1D sampler_palette;\n"); - shader_addline(buffer, "\nvoid main()\n{\n"); - /* The alpha-component contains the palette index. */ - shader_addline(buffer, " float index = texture%s(sampler, out_texcoord.%s).%c;\n", - needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle, - gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x'); - /* Scale the index by 255/256 and add a bias of 0.5 in order to sample in - * the middle. */ - shader_addline(buffer, " index = (index * 255.0 + 0.5) / 256.0;\n"); - shader_addline(buffer, " %s = texture%s(sampler_palette, index);\n", - output, needs_legacy_glsl_syntax(gl_info) ? "1D" : ""); - shader_addline(buffer, "}\n"); -} - -static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer, - const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args, - const char *tex_type) -{ - enum complex_fixup complex_fixup = get_complex_fixup(args->fixup); - char chroma, luminance; - const char *tex; - - /* The YUY2 and UYVY formats contain two pixels packed into a 32 bit - * macropixel, giving effectively 16 bits per pixel. The color consists of - * a luminance(Y) and two chroma(U and V) values. Each macropixel has two - * luminance values, one for each single pixel it contains, and one U and - * one V value shared between both pixels. - * - * The data is loaded into an A8L8 texture. With YUY2, the luminance - * component contains the luminance and alpha the chroma. With UYVY it is - * vice versa. Thus take the format into account when generating the read - * swizzles - * - * Reading the Y value is straightforward - just sample the texture. The - * hardware takes care of filtering in the horizontal and vertical - * direction. - * - * Reading the U and V values is harder. We have to avoid filtering - * horizontally, because that would mix the U and V values of one pixel or - * two adjacent pixels. Thus floor the texture coordinate and add 0.5 to - * get an unfiltered read, regardless of the filtering setting. Vertical - * filtering works automatically though - the U and V values of two rows - * are mixed nicely. - * - * Apart of avoiding filtering issues, the code has to know which value it - * just read, and where it can find the other one. To determine this, it - * checks if it sampled an even or odd pixel, and shifts the 2nd read - * accordingly. - * - * Handling horizontal filtering of U and V values requires reading a 2nd - * pair of pixels, extracting U and V and mixing them. This is not - * implemented yet. - * - * An alternative implementation idea is to load the texture as A8R8G8B8 - * texture, with width / 2. This way one read gives all 3 values, finding - * U and V is easy in an unfiltered situation. Finding the luminance on - * the other hand requires finding out if it is an odd or even pixel. The - * real drawback of this approach is filtering. This would have to be - * emulated completely in the shader, reading up two 2 packed pixels in up - * to 2 rows and interpolating both horizontally and vertically. Beyond - * that it would require adjustments to the texture handling code to deal - * with the width scaling. */ - - if (complex_fixup == COMPLEX_FIXUP_UYVY) - { - chroma = 'x'; - luminance = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y'; - } - else - { - chroma = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y'; - luminance = 'x'; - } - - tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : ""; - - /* First we have to read the chroma values. This means we need at least - * two pixels (no filtering), or 4 pixels (with filtering). To get the - * unmodified chroma, we have to rid ourselves of the filtering when we - * sample the texture. */ - shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); - /* We must not allow filtering between pixel x and x+1, this would mix U - * and V. Vertical filtering is ok. However, bear in mind that the pixel - * center is at 0.5, so add 0.5. */ - shader_addline(buffer, " texcoord.x = (floor(texcoord.x * size.x) + 0.5) / size.x;\n"); - shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma); - - /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25 - * and 0.75 for the even and odd pixels respectively. */ - /* Put the value into either of the chroma values. */ - shader_addline(buffer, " bool even = fract(texcoord.x * size.x * 0.5) < 0.5;\n"); - shader_addline(buffer, " if (even)\n"); - shader_addline(buffer, " chroma.y = luminance;\n"); - shader_addline(buffer, " else\n"); - shader_addline(buffer, " chroma.x = luminance;\n"); - - /* Sample pixel 2. If we read an even pixel, sample the pixel right to the - * current one. Otherwise, sample the left pixel. */ - shader_addline(buffer, " texcoord.x += even ? 1.0 / size.x : -1.0 / size.x;\n"); - shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma); - - /* Put the value into the other chroma. */ - shader_addline(buffer, " if (even)\n"); - shader_addline(buffer, " chroma.x = luminance;\n"); - shader_addline(buffer, " else\n"); - shader_addline(buffer, " chroma.y = luminance;\n"); - - /* TODO: If filtering is enabled, sample a 2nd pair of pixels left or right of - * the current one and lerp the two U and V values. */ - - /* This gives the correctly filtered luminance value. */ - shader_addline(buffer, " luminance = texture%s(sampler, out_texcoord.xy).%c;\n", tex, luminance); -} - -static void gen_yv12_read(struct wined3d_string_buffer *buffer, - const struct wined3d_gl_info *gl_info, const char *tex_type) -{ - char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x'; - const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : ""; - - /* YV12 surfaces contain a WxH sized luminance plane, followed by a - * (W/2)x(H/2) V and a (W/2)x(H/2) U plane, each with 8 bit per pixel. So - * the effective bitdepth is 12 bits per pixel. Since the U and V planes - * have only half the pitch of the luminance plane, the packing into the - * gl texture is a bit unfortunate. If the whole texture is interpreted as - * luminance data it looks approximately like this: - * - * +----------------------------------+---- - * | | - * | | - * | | - * | | - * | | 2 - * | LUMINANCE | - - * | | 3 - * | | - * | | - * | | - * | | - * +----------------+-----------------+---- - * | | | - * | V even rows | V odd rows | - * | | | 1 - * +----------------+------------------ - - * | | | 3 - * | U even rows | U odd rows | - * | | | - * +----------------+-----------------+---- - * | | | - * | 0.5 | 0.5 | - * - * So it appears as if there are 4 chroma images, but in fact the odd rows - * in the chroma images are in the same row as the even ones. So it is - * kinda tricky to read. */ - - /* First sample the chroma values. */ - shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); - /* The chroma planes have only half the width. */ - shader_addline(buffer, " texcoord.x *= 0.5;\n"); - - /* The first value is between 2/3 and 5/6 of the texture's height, so - * scale+bias the coordinate. Also read the right side of the image when - * reading odd lines. - * - * Don't forget to clamp the y values in into the range, otherwise we'll - * get filtering bleeding. */ - - /* Read odd lines from the right side (add 0.5 to the x coordinate). */ - shader_addline(buffer, " if (fract(floor(texcoord.y * size.y) * 0.5 + 1.0 / 6.0) >= 0.5)\n"); - shader_addline(buffer, " texcoord.x += 0.5;\n"); - - /* Clamp, keep the half pixel origin in mind. */ - shader_addline(buffer, " texcoord.y = clamp(2.0 / 3.0 + texcoord.y / 6.0, " - "2.0 / 3.0 + 0.5 / size.y, 5.0 / 6.0 - 0.5 / size.y);\n"); - - shader_addline(buffer, " chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component); - - /* The other chroma value is 1/6th of the texture lower, from 5/6th to - * 6/6th No need to clamp because we're just reusing the already clamped - * value from above. */ - shader_addline(buffer, " texcoord.y += 1.0 / 6.0;\n"); - shader_addline(buffer, " chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component); - - /* Sample the luminance value. It is in the top 2/3rd of the texture, so - * scale the y coordinate. Clamp the y coordinate to prevent the chroma - * values from bleeding into the sampled luminance values due to - * filtering. */ - shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); - /* Multiply the y coordinate by 2/3 and clamp it. */ - shader_addline(buffer, " texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n"); - shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component); -} - -static void gen_nv12_read(struct wined3d_string_buffer *buffer, - const struct wined3d_gl_info *gl_info, const char *tex_type) -{ - char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x'; - const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : ""; - - /* NV12 surfaces contain a WxH sized luminance plane, followed by a - * (W/2)x(H/2) sized plane where each component is an UV pair. So the - * effective bitdepth is 12 bits per pixel. If the whole texture is - * interpreted as luminance data it looks approximately like this: - * - * +----------------------------------+---- - * | | - * | | - * | | - * | | - * | | 2 - * | LUMINANCE | - - * | | 3 - * | | - * | | - * | | - * | | - * +----------------------------------+---- - * |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV| - * |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV| - * | | 1 - * | | - - * | | 3 - * | | - * | | - * +----------------------------------+---- */ - - /* First sample the chroma values. */ - shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); - /* We only have half the number of chroma pixels. */ - shader_addline(buffer, " texcoord.x *= 0.5;\n"); - shader_addline(buffer, " texcoord.y = (texcoord.y + 2.0) / 3.0;\n"); - - /* We must not allow filtering horizontally, this would mix U and V. - * Vertical filtering is ok. However, bear in mind that the pixel center - * is at 0.5, so add 0.5. */ - - /* Convert to non-normalised coordinates so we can find the individual - * pixel. */ - shader_addline(buffer, " texcoord.x = floor(texcoord.x * size.x);\n"); - /* Multiply by 2 since chroma components are stored in UV pixel pairs, add - * 0.5 to hit the center of the pixel. Then convert back to normalised - * coordinates. */ - shader_addline(buffer, " texcoord.x = (texcoord.x * 2.0 + 0.5) / size.x;\n"); - /* Clamp, keep the half pixel origin in mind. */ - shader_addline(buffer, " texcoord.y = max(texcoord.y, 2.0 / 3.0 + 0.5 / size.y);\n"); - - shader_addline(buffer, " chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component); - /* Add 1.0 / size.x to sample the adjacent texel. */ - shader_addline(buffer, " texcoord.x += 1.0 / size.x;\n"); - shader_addline(buffer, " chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component); - - /* Sample the luminance value. It is in the top 2/3rd of the texture, so - * scale the y coordinate. Clamp the y coordinate to prevent the chroma - * values from bleeding into the sampled luminance values due to - * filtering. */ - shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); - /* Multiply the y coordinate by 2/3 and clamp it. */ - shader_addline(buffer, " texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n"); - shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component); -} - -static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffer, - const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args, - const char *output, const char *tex_type, const char *swizzle) -{ - enum complex_fixup complex_fixup = get_complex_fixup(args->fixup); - - shader_addline(buffer, "const vec4 yuv_coef = vec4(1.403, -0.344, -0.714, 1.770);\n"); - shader_addline(buffer, "float luminance;\n"); - shader_addline(buffer, "vec2 texcoord;\n"); - shader_addline(buffer, "vec2 chroma;\n"); - shader_addline(buffer, "uniform vec2 size;\n"); - - shader_addline(buffer, "\nvoid main()\n{\n"); - - switch (complex_fixup) - { - case COMPLEX_FIXUP_UYVY: - case COMPLEX_FIXUP_YUY2: - gen_packed_yuv_read(buffer, gl_info, args, tex_type); - break; - - case COMPLEX_FIXUP_YV12: - gen_yv12_read(buffer, gl_info, tex_type); - break; - - case COMPLEX_FIXUP_NV12: - gen_nv12_read(buffer, gl_info, tex_type); - break; - - default: - FIXME("Unsupported fixup %#x.\n", complex_fixup); - string_buffer_free(buffer); - return; - } - - /* Calculate the final result. Formula is taken from - * http://www.fourcc.org/fccyvrgb.php. Note that the chroma - * ranges from -0.5 to 0.5. */ - shader_addline(buffer, "\n chroma.xy -= 0.5;\n"); - - shader_addline(buffer, " %s.x = luminance + chroma.x * yuv_coef.x;\n", output); - shader_addline(buffer, " %s.y = luminance + chroma.y * yuv_coef.y + chroma.x * yuv_coef.z;\n", output); - shader_addline(buffer, " %s.z = luminance + chroma.y * yuv_coef.w;\n", output); - - shader_addline(buffer, "}\n"); -} - -static void glsl_blitter_generate_plain_shader(struct wined3d_string_buffer *buffer, - const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args, - const char *output, const char *tex_type, const char *swizzle) -{ - shader_addline(buffer, "\nvoid main()\n{\n"); - shader_addline(buffer, " %s = texture%s(sampler, out_texcoord.%s);\n", - output, needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle); - shader_glsl_color_correction_ext(buffer, output, WINED3DSP_WRITEMASK_ALL, args->fixup); - shader_addline(buffer, "}\n"); -} - -/* Context activation is done by the caller. */ -static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter, - const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args) -{ - static const struct - { - GLenum texture_target; - const char texture_type[7]; - const char texcoord_swizzle[4]; - } - texture_data[] = - { - {GL_TEXTURE_2D, "2D", "xy"}, - {GL_TEXTURE_CUBE_MAP, "Cube", "xyz"}, - {GL_TEXTURE_RECTANGLE_ARB, "2DRect", "xy"}, - }; - static const char vshader_main[] = - "\n" - "void main()\n" - "{\n" - " gl_Position = vec4(pos, 0.0, 1.0);\n" - " out_texcoord = texcoord;\n" - "}\n"; - enum complex_fixup complex_fixup = get_complex_fixup(args->fixup); - struct wined3d_string_buffer *buffer, *output; - GLuint program, vshader_id, fshader_id; - const char *tex_type, *swizzle, *ptr; - unsigned int i; - GLint loc; - - for (i = 0; i < ARRAY_SIZE(texture_data); ++i) - { - if (args->texture_type == texture_data[i].texture_target) - { - tex_type = texture_data[i].texture_type; - swizzle = texture_data[i].texcoord_swizzle; - break; - } - } - if (i == ARRAY_SIZE(texture_data)) - { - FIXME("Unsupported texture type %#x.\n", args->texture_type); - return 0; - } - - program = GL_EXTCALL(glCreateProgram()); - - vshader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); - - buffer = string_buffer_get(&blitter->string_buffers); - shader_glsl_add_version_declaration(buffer, gl_info); - shader_addline(buffer, "%s vec2 pos;\n", get_attribute_keyword(gl_info)); - shader_addline(buffer, "%s vec3 texcoord;\n", get_attribute_keyword(gl_info)); - declare_out_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n"); - shader_addline(buffer, vshader_main); - - ptr = buffer->buffer; - GL_EXTCALL(glShaderSource(vshader_id, 1, &ptr, NULL)); - GL_EXTCALL(glAttachShader(program, vshader_id)); - GL_EXTCALL(glDeleteShader(vshader_id)); - - fshader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); - - string_buffer_clear(buffer); - shader_glsl_add_version_declaration(buffer, gl_info); - shader_addline(buffer, "uniform sampler%s sampler;\n", tex_type); - declare_in_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n"); - if (!needs_legacy_glsl_syntax(gl_info)) - shader_addline(buffer, "out vec4 ps_out[1];\n"); - - output = string_buffer_get(&blitter->string_buffers); - string_buffer_sprintf(output, "%s[0]", get_fragment_output(gl_info)); - - switch (complex_fixup) - { - case COMPLEX_FIXUP_P8: - glsl_blitter_generate_p8_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle); - break; - case COMPLEX_FIXUP_YUY2: - case COMPLEX_FIXUP_UYVY: - case COMPLEX_FIXUP_YV12: - case COMPLEX_FIXUP_NV12: - glsl_blitter_generate_yuv_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle); - break; - case COMPLEX_FIXUP_NONE: - glsl_blitter_generate_plain_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle); - } - - string_buffer_release(&blitter->string_buffers, output); - - ptr = buffer->buffer; - GL_EXTCALL(glShaderSource(fshader_id, 1, &ptr, NULL)); - string_buffer_release(&blitter->string_buffers, buffer); - GL_EXTCALL(glAttachShader(program, fshader_id)); - GL_EXTCALL(glDeleteShader(fshader_id)); - - GL_EXTCALL(glBindAttribLocation(program, 0, "pos")); - GL_EXTCALL(glBindAttribLocation(program, 1, "texcoord")); - - if (!needs_legacy_glsl_syntax(gl_info)) - GL_EXTCALL(glBindFragDataLocation(program, 0, "ps_out")); - - GL_EXTCALL(glCompileShader(vshader_id)); - print_glsl_info_log(gl_info, vshader_id, FALSE); - GL_EXTCALL(glCompileShader(fshader_id)); - print_glsl_info_log(gl_info, fshader_id, FALSE); - GL_EXTCALL(glLinkProgram(program)); - shader_glsl_validate_link(gl_info, program); - - GL_EXTCALL(glUseProgram(program)); - loc = GL_EXTCALL(glGetUniformLocation(program, "sampler")); - GL_EXTCALL(glUniform1i(loc, 0)); - if (complex_fixup == COMPLEX_FIXUP_P8) - { - loc = GL_EXTCALL(glGetUniformLocation(program, "sampler_palette")); - GL_EXTCALL(glUniform1i(loc, 1)); - } - - return program; -} - -/* Context activation is done by the caller. */ -static void glsl_blitter_upload_palette(struct wined3d_glsl_blitter *blitter, - struct wined3d_context *context, const struct wined3d_texture *texture) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_palette *palette; - - palette = texture->swapchain ? texture->swapchain->palette : NULL; - - if (!blitter->palette_texture) - gl_info->gl_ops.gl.p_glGenTextures(1, &blitter->palette_texture); - - context_active_texture(context, gl_info, 1); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, blitter->palette_texture); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - - if (palette) - { - gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_BGRA, - GL_UNSIGNED_INT_8_8_8_8_REV, palette->colors); - } - else - { - static const DWORD black; - - FIXME("P8 texture loaded without a palette.\n"); - gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 1, 0, GL_BGRA, - GL_UNSIGNED_INT_8_8_8_8_REV, &black); - } - - context_active_texture(context, gl_info, 0); -} - -/* Context activation is done by the caller. */ -static struct glsl_blitter_program *glsl_blitter_get_program(struct wined3d_glsl_blitter *blitter, - struct wined3d_context *context, const struct wined3d_texture *texture) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - struct glsl_blitter_program *program; - struct glsl_blitter_args args; - struct wine_rb_entry *entry; - - memset(&args, 0, sizeof(args)); - args.texture_type = texture->target; - args.fixup = texture->resource.format->color_fixup; - - if ((entry = wine_rb_get(&blitter->programs, &args))) - return WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry); - - if (!(program = heap_alloc(sizeof(*program)))) - { - ERR("Failed to allocate blitter program memory.\n"); - return NULL; - } - - program->args = args; - if (!(program->id = glsl_blitter_generate_program(blitter, gl_info, &args))) - { - WARN("Failed to generate blitter program.\n"); - heap_free(program); - return NULL; - } - - if (wine_rb_put(&blitter->programs, &program->args, &program->entry) == -1) - { - ERR("Failed to store blitter program.\n"); - GL_EXTCALL(glDeleteProgram(program->id)); - heap_free(program); - return NULL; - } - - return program; -} - -static BOOL glsl_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_context *context, - const struct wined3d_texture *src_texture, DWORD src_location, - const struct wined3d_texture *dst_texture, DWORD dst_location) -{ - const struct wined3d_resource *src_resource = &src_texture->resource; - const struct wined3d_resource *dst_resource = &dst_texture->resource; - const struct wined3d_format *src_format = src_resource->format; - const struct wined3d_format *dst_format = dst_resource->format; - BOOL decompress; - - if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id) - { - if (dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) - blit_op = WINED3D_BLIT_OP_DEPTH_BLIT; - else - blit_op = WINED3D_BLIT_OP_COLOR_BLIT; - } - - if (blit_op != WINED3D_BLIT_OP_COLOR_BLIT) - { - TRACE("Unsupported blit_op %#x.\n", blit_op); - return FALSE; - } - - if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) - return FALSE; - - if (src_texture->target == GL_TEXTURE_2D_MULTISAMPLE - || dst_texture->target == GL_TEXTURE_2D_MULTISAMPLE - || src_texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY - || dst_texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) - { - TRACE("Multi-sample textures not supported.\n"); - return FALSE; - } - - /* We don't necessarily want to blit from resources without - * WINED3D_RESOURCE_ACCESS_GPU, but that may be the only way to decompress - * compressed textures. */ - decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) - && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED); - if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU)) - { - TRACE("Source or destination resource does not have GPU access.\n"); - return FALSE; - } - - if (!is_identity_fixup(dst_format->color_fixup) - && (dst_format->id != src_format->id || dst_location != WINED3D_LOCATION_DRAWABLE)) - { - TRACE("Destination fixups are not supported.\n"); - return FALSE; - } - - TRACE("Returning supported.\n"); - return TRUE; -} - -static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, - unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) -{ - struct wined3d_device *device = dst_texture->resource.device; - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_texture *staging_texture = NULL; - struct wined3d_glsl_blitter *glsl_blitter; - struct glsl_blitter_program *program; - struct wined3d_blitter *next; - unsigned int src_level; - GLint location; - RECT s, d; - - TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", - blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), - wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), - wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter)); - - if (!glsl_blitter_supported(op, context, src_texture, src_location, dst_texture, dst_location)) - { - if (!(next = blitter->next)) - { - ERR("No blitter to handle blit op %#x.\n", op); - return dst_location; - } - - TRACE("Forwarding to blitter %p.\n", next); - return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); - } - - glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter); - - if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) - { - struct wined3d_resource_desc desc; - struct wined3d_box upload_box; - HRESULT hr; - - TRACE("Source texture is not GPU accessible, creating a staging texture.\n"); - - src_level = src_sub_resource_idx % src_texture->level_count; - desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - desc.format = src_texture->resource.format->id; - desc.multisample_type = src_texture->resource.multisample_type; - desc.multisample_quality = src_texture->resource.multisample_quality; - desc.usage = WINED3DUSAGE_PRIVATE; - desc.access = WINED3D_RESOURCE_ACCESS_GPU; - desc.width = wined3d_texture_get_level_width(src_texture, src_level); - desc.height = wined3d_texture_get_level_height(src_texture, src_level); - desc.depth = 1; - desc.size = 0; - - if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0, - NULL, NULL, &wined3d_null_parent_ops, &staging_texture))) - { - ERR("Failed to create staging texture, hr %#x.\n", hr); - return dst_location; - } - - wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth); - wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0, - src_texture, src_sub_resource_idx, &upload_box); - - src_texture = staging_texture; - src_sub_resource_idx = 0; - } - else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && (src_texture->sub_resources[src_sub_resource_idx].locations - & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) == WINED3D_LOCATION_DRAWABLE - && !wined3d_resource_is_offscreen(&src_texture->resource)) - { - - /* Without FBO blits transferring from the drawable to the texture is - * expensive, because we have to flip the data in sysmem. Since we can - * flip in the blitter, we don't actually need that flip anyway. So we - * use the surface's texture as scratch texture, and flip the source - * rectangle instead. */ - texture2d_load_fb_texture(src_texture, src_sub_resource_idx, FALSE, context); - - s = *src_rect; - src_level = src_sub_resource_idx % src_texture->level_count; - s.top = wined3d_texture_get_level_height(src_texture, src_level) - s.top; - s.bottom = wined3d_texture_get_level_height(src_texture, src_level) - s.bottom; - src_rect = &s; - } - else - { - wined3d_texture_load(src_texture, context, FALSE); - } - - context_apply_blit_state(context, device); - - if (dst_location == WINED3D_LOCATION_DRAWABLE) - { - d = *dst_rect; - wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &d); - dst_rect = &d; - } - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - GLenum buffer; - - if (dst_location == WINED3D_LOCATION_DRAWABLE) - { - TRACE("Destination texture %p is onscreen.\n", dst_texture); - buffer = wined3d_texture_get_gl_buffer(dst_texture); - } - else - { - TRACE("Destination texture %p is offscreen.\n", dst_texture); - buffer = GL_COLOR_ATTACHMENT0; - } - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, - &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location); - context_set_draw_buffer(context, buffer); - context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); - context_invalidate_state(context, STATE_FRAMEBUFFER); - } - - if (!(program = glsl_blitter_get_program(glsl_blitter, context, src_texture))) - { - ERR("Failed to get blitter program.\n"); - return dst_location; - } - GL_EXTCALL(glUseProgram(program->id)); - switch (get_complex_fixup(program->args.fixup)) - { - case COMPLEX_FIXUP_P8: - glsl_blitter_upload_palette(glsl_blitter, context, src_texture); - break; - - case COMPLEX_FIXUP_YUY2: - case COMPLEX_FIXUP_UYVY: - case COMPLEX_FIXUP_YV12: - case COMPLEX_FIXUP_NV12: - src_level = src_sub_resource_idx % src_texture->level_count; - location = GL_EXTCALL(glGetUniformLocation(program->id, "size")); - GL_EXTCALL(glUniform2f(location, wined3d_texture_get_level_pow2_width(src_texture, src_level), - wined3d_texture_get_level_pow2_height(src_texture, src_level))); - break; - - default: - break; - } - context_draw_shaded_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter); - GL_EXTCALL(glUseProgram(0)); - - if (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture)) - gl_info->gl_ops.gl.p_glFlush(); - - if (staging_texture) - wined3d_texture_decref(staging_texture); - - return dst_location; -} - -static void glsl_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device, - unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, - const RECT *draw_rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) -{ - struct wined3d_blitter *next; - - if ((next = blitter->next)) - next->ops->blitter_clear(next, device, rt_count, fb, rect_count, - clear_rects, draw_rect, flags, color, depth, stencil); -} - -static const struct wined3d_blitter_ops glsl_blitter_ops = -{ - glsl_blitter_destroy, - glsl_blitter_clear, - glsl_blitter_blit, -}; - -struct wined3d_blitter *wined3d_glsl_blitter_create(struct wined3d_blitter **next, - const struct wined3d_device *device) -{ - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_glsl_blitter *blitter; - - if (device->shader_backend != &glsl_shader_backend) - return NULL; - - if (!gl_info->supported[ARB_VERTEX_SHADER] || !gl_info->supported[ARB_FRAGMENT_SHADER]) - return NULL; - - if (!(blitter = heap_alloc(sizeof(*blitter)))) - { - ERR("Failed to allocate blitter.\n"); - return NULL; - } - - TRACE("Created blitter %p.\n", blitter); - - blitter->blitter.ops = &glsl_blitter_ops; - blitter->blitter.next = *next; - string_buffer_list_init(&blitter->string_buffers); - wine_rb_init(&blitter->programs, glsl_blitter_args_compare); - blitter->palette_texture = 0; - *next = &blitter->blitter; - - return *next; -} diff --git a/dll/directx/wine/wined3d/nvidia_texture_shader.c b/dll/directx/wine/wined3d/nvidia_texture_shader.c index 20db62739b5..0baa414e57d 100644 --- a/dll/directx/wine/wined3d/nvidia_texture_shader.c +++ b/dll/directx/wine/wined3d/nvidia_texture_shader.c @@ -69,9 +69,6 @@ static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD st gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB); checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)"); break; - default: - FIXME("Unhandled target %#x.\n", state->textures[stage]->target); - break; } } else diff --git a/dll/directx/wine/wined3d/resource.c b/dll/directx/wine/wined3d/resource.c index df73997c84c..8b7f17bb6bd 100644 --- a/dll/directx/wine/wined3d/resource.c +++ b/dll/directx/wine/wined3d/resource.c @@ -95,9 +95,6 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * return WINED3DERR_INVALIDCALL; } - if (!size) - ERR("Attempting to create a zero-sized resource.\n"); - for (i = 0; i < ARRAY_SIZE(resource_types); ++i) { if (resource_types[i].type != type @@ -194,7 +191,19 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource->parent_ops = parent_ops; resource->resource_ops = resource_ops; resource->map_binding = WINED3D_LOCATION_SYSMEM; - resource->heap_memory = NULL; + + if (size) + { + if (!wined3d_resource_allocate_sysmem(resource)) + { + ERR("Failed to allocate system memory.\n"); + return E_OUTOFMEMORY; + } + } + else + { + resource->heap_memory = NULL; + } if (!(usage & WINED3DUSAGE_PRIVATE)) { @@ -203,7 +212,8 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * { if (size > wined3d_device_get_available_texture_mem(device)) { - ERR("Out of adapter memory.\n"); + ERR("Out of adapter memory\n"); + wined3d_resource_free_sysmem(resource); return WINED3DERR_OUTOFVIDEOMEMORY; } adapter_adjust_memory(device->adapter, size); @@ -220,7 +230,7 @@ static void wined3d_resource_destroy_object(void *object) struct wined3d_resource *resource = object; wined3d_resource_free_sysmem(resource); - context_resource_released(resource->device, resource); + context_resource_released(resource->device, resource, resource->type); wined3d_resource_release(resource); } @@ -481,10 +491,7 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) void *mem; if (!(mem = heap_alloc_zero(resource->size + align))) - { - ERR("Failed to allocate system memory.\n"); return FALSE; - } p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; *p = mem; diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c index 9075fc7ebc6..0513c9e2053 100644 --- a/dll/directx/wine/wined3d/shader.c +++ b/dll/directx/wine/wined3d/shader.c @@ -419,15 +419,6 @@ static const struct wined3d_shader_frontend *shader_select_frontend(enum wined3d } } -static enum wined3d_shader_type shader_get_shader_type(const struct wined3d_shader_desc *desc) -{ - if (desc->format == WINED3D_SHADER_BYTE_CODE_FORMAT_SM4) - return wined3d_get_sm4_shader_type(desc->byte_code, desc->byte_code_size); - - FIXME("Could not get shader type for byte code format %#x.\n", desc->format); - return WINED3D_SHADER_TYPE_INVALID; -} - void string_buffer_clear(struct wined3d_string_buffer *buffer) { buffer->buffer[0] = '\0'; @@ -810,10 +801,6 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w reg_maps->vocp = 1; break; - case WINED3DSPR_SAMPLEMASK: - reg_maps->sample_mask = 1; - break; - default: TRACE("Not recording register of type %#x and [%#x][%#x].\n", reg->type, reg->idx[0].offset, reg->idx[1].offset); @@ -996,49 +983,13 @@ static void wined3d_insert_interpolation_mode(DWORD *packed_interpolation_mode, register_idx * WINED3D_PACKED_INTERPOLATION_BIT_COUNT, WINED3D_PACKED_INTERPOLATION_BIT_COUNT, mode); } -static HRESULT shader_scan_output_signature(struct wined3d_shader *shader) -{ - const struct wined3d_shader_signature *output_signature = &shader->output_signature; - struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - unsigned int i; - HRESULT hr; - - for (i = 0; i < output_signature->element_count; ++i) - { - const struct wined3d_shader_signature_element *e = &output_signature->elements[i]; - unsigned int mask; - - reg_maps->output_registers |= 1u << e->register_idx; - if (e->sysval_semantic == WINED3D_SV_CLIP_DISTANCE) - { - if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask))) - return hr; - reg_maps->clip_distance_mask |= mask; - } - else if (e->sysval_semantic == WINED3D_SV_CULL_DISTANCE) - { - if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask))) - return hr; - reg_maps->cull_distance_mask |= mask; - } - else if (e->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX) - { - reg_maps->viewport_array = 1; - } - } - - return WINED3D_OK; -} - /* Note that this does not count the loop register as an address register. */ -static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size) +static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe, + struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature *input_signature, + struct wined3d_shader_signature *output_signature, DWORD constf_size) { struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)]; struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT]; - struct wined3d_shader_signature *output_signature = &shader->output_signature; - struct wined3d_shader_signature *input_signature = &shader->input_signature; - struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - const struct wined3d_shader_frontend *fe = shader->frontend; unsigned int cur_loop_depth = 0, max_loop_depth = 0; struct wined3d_shader_version shader_version; struct wined3d_shader_phase *phase = NULL; @@ -1716,8 +1667,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co shader_record_sample(reg_maps, ins.src[2].reg.idx[0].offset, ins.src[3].reg.idx[0].offset, reg_maps->sampler_map.count); } - else if ((ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE) - || (ins.handler_idx == WINED3DSIH_SAMPLE_INFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE)) + else if (ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE) { shader_record_sample(reg_maps, ins.src[0].reg.idx[0].offset, WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count); @@ -1830,8 +1780,25 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co if (output_signature->elements) { - if (FAILED(hr = shader_scan_output_signature(shader))) - return hr; + for (i = 0; i < output_signature->element_count; ++i) + { + const struct wined3d_shader_signature_element *e = &output_signature->elements[i]; + unsigned int mask; + + reg_maps->output_registers |= 1u << e->register_idx; + if (e->sysval_semantic == WINED3D_SV_CLIP_DISTANCE) + { + if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask))) + return hr; + reg_maps->clip_distance_mask |= mask; + } + else if (e->sysval_semantic == WINED3D_SV_CULL_DISTANCE) + { + if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask))) + return hr; + reg_maps->cull_distance_mask |= mask; + } + } } else if (reg_maps->output_registers) { @@ -1922,23 +1889,6 @@ static void shader_dump_sync_flags(struct wined3d_string_buffer *buffer, DWORD s shader_addline(buffer, "_unknown_flags(%#x)", sync_flags); } -static void shader_dump_precise_flags(struct wined3d_string_buffer *buffer, DWORD flags) -{ - if (!(flags & WINED3DSI_PRECISE_XYZW)) - return; - - shader_addline(buffer, " [precise"); - if (flags != WINED3DSI_PRECISE_XYZW) - { - shader_addline(buffer, "(%s%s%s%s)", - flags & WINED3DSI_PRECISE_X ? "x" : "", - flags & WINED3DSI_PRECISE_Y ? "y" : "", - flags & WINED3DSI_PRECISE_Z ? "z" : "", - flags & WINED3DSI_PRECISE_W ? "w" : ""); - } - shader_addline(buffer, "]"); -} - static void shader_dump_uav_flags(struct wined3d_string_buffer *buffer, DWORD uav_flags) { if (uav_flags & WINED3DSUF_GLOBALLY_COHERENT) @@ -2341,10 +2291,6 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer, shader_addline(buffer, "null"); break; - case WINED3DSPR_RASTERIZER: - shader_addline(buffer, "rasterizer"); - break; - case WINED3DSPR_RESOURCE: shader_addline(buffer, "t"); break; @@ -3106,10 +3052,6 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe { shader_dump_sync_flags(&buffer, ins.flags); } - else - { - shader_dump_precise_flags(&buffer, ins.flags); - } if (wined3d_shader_instruction_has_texel_offset(&ins)) shader_addline(&buffer, "(%d,%d,%d)", ins.texel_offset.u, ins.texel_offset.v, ins.texel_offset.w); @@ -3324,11 +3266,11 @@ const struct wined3d_shader_backend_ops none_shader_backend = static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_const_count, enum wined3d_shader_type type, unsigned int max_version) { - const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; const struct wined3d_shader_frontend *fe; - unsigned int backend_version; HRESULT hr; + unsigned int backend_version; + const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; TRACE("shader %p, float_const_count %u, type %#x, max_version %u.\n", shader, float_const_count, type, max_version); @@ -3346,7 +3288,8 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_co shader_trace_init(fe, shader->frontend_data); /* Second pass: figure out which registers are used, what the semantics are, etc. */ - if (FAILED(hr = shader_get_registers_used(shader, float_const_count))) + if (FAILED(hr = shader_get_registers_used(shader, fe, reg_maps, &shader->input_signature, + &shader->output_signature, float_const_count))) return hr; if (reg_maps->shader_version.type != type) @@ -3648,6 +3591,9 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device TRACE("byte_code %p, byte_code_size %#lx, format %#x, max_version %#x.\n", desc->byte_code, (long)desc->byte_code_size, desc->format, desc->max_version); + if (!desc->byte_code) + return WINED3DERR_INVALIDCALL; + if (!(shader->frontend = shader_select_frontend(desc->format))) { FIXME("Unable to find frontend for shader.\n"); @@ -3722,39 +3668,25 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr); } - if (desc->byte_code && byte_code_size) + if (!(shader->function = heap_alloc(byte_code_size))) { - if (!(shader->function = heap_alloc(byte_code_size))) - { - shader_cleanup(shader); - return E_OUTOFMEMORY; - } - memcpy(shader->function, desc->byte_code, byte_code_size); - shader->functionLength = byte_code_size; - - if (FAILED(hr = shader_set_function(shader, float_const_count, type, desc->max_version))) - { - WARN("Failed to set function, hr %#x.\n", hr); - shader_cleanup(shader); - return hr; - } + shader_cleanup(shader); + return E_OUTOFMEMORY; } - else - { - shader->reg_maps.shader_version.type = type; - shader->reg_maps.shader_version.major = 4; - shader->reg_maps.shader_version.minor = 0; - shader_set_limits(shader); + memcpy(shader->function, desc->byte_code, byte_code_size); + shader->functionLength = byte_code_size; - if (FAILED(hr = shader_scan_output_signature(shader))) - { - shader_cleanup(shader); - return hr; - } + if (FAILED(hr = shader_set_function(shader, float_const_count, type, desc->max_version))) + { + WARN("Failed to set function, hr %#x.\n", hr); + shader_cleanup(shader); + return hr; } shader->load_local_constsF = shader->lconst_inf_or_nan; + wined3d_cs_init_object(shader->device->cs, wined3d_shader_init_object, shader); + return hr; } @@ -3791,40 +3723,20 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3 const struct wined3d_shader_desc *desc, const struct wined3d_stream_output_desc *so_desc, void *parent, const struct wined3d_parent_ops *parent_ops) { - struct wined3d_shader_desc shader_desc = *desc; - struct wined3d_stream_output_element *elements; - enum wined3d_shader_type shader_type; + struct wined3d_stream_output_element *elements = NULL; HRESULT hr; - if (so_desc) + if (so_desc && !(elements = heap_calloc(so_desc->element_count, sizeof(*elements)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops))) { - shader_type = shader_get_shader_type(desc); - switch (shader_type) - { - case WINED3D_SHADER_TYPE_VERTEX: - shader_desc.byte_code = NULL; - shader_desc.byte_code_size = 0; - break; - case WINED3D_SHADER_TYPE_DOMAIN: - FIXME("Stream output not supported for %s.\n", debug_shader_type(shader_type)); - return E_NOTIMPL; - default: - break; - } + heap_free(elements); + return hr; } - if (FAILED(hr = shader_init(shader, device, &shader_desc, 0, - WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops))) - return hr; - if (so_desc) { - if (!(elements = heap_calloc(so_desc->element_count, sizeof(*elements)))) - { - shader_cleanup(shader); - return E_OUTOFMEMORY; - } - shader->u.gs.so_desc = *so_desc; shader->u.gs.so_desc.elements = elements; memcpy(elements, so_desc->elements, so_desc->element_count * sizeof(*elements)); @@ -3864,9 +3776,6 @@ void find_gs_compile_args(const struct wined3d_state *state, const struct wined3 args->output_count = pixel_shader ? pixel_shader->limits->packed_input : shader->limits->packed_output; - if (!(args->primitive_type = shader->u.gs.input_type)) - args->primitive_type = d3d_primitive_type_from_gl(state->gl_primitive_type); - init_interpolation_compile_args(args->interpolation_mode, pixel_shader, gl_info); } @@ -3964,7 +3873,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 switch (texture->target) { /* RECT textures are distinguished from 2D textures via np2_fixup */ - default: + case GL_TEXTURE_RECTANGLE_ARB: + case GL_TEXTURE_2D: break; case GL_TEXTURE_3D: @@ -4016,16 +3926,16 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 if (shader->reg_maps.shader_version.major >= 3) { if (position_transformed) - args->vp_mode = WINED3D_VP_MODE_NONE; + args->vp_mode = pretransformed; else if (use_vs(state)) - args->vp_mode = WINED3D_VP_MODE_SHADER; + args->vp_mode = vertexshader; else - args->vp_mode = WINED3D_VP_MODE_FF; + args->vp_mode = fixedfunction; args->fog = WINED3D_FFP_PS_FOG_OFF; } else { - args->vp_mode = WINED3D_VP_MODE_SHADER; + args->vp_mode = vertexshader; if (state->render_states[WINED3D_RS_FOGENABLE]) { switch (state->render_states[WINED3D_RS_FOGTABLEMODE]) @@ -4200,9 +4110,6 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n", device, desc, parent, parent_ops, shader); - if (!desc->byte_code) - return WINED3DERR_INVALIDCALL; - if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; @@ -4213,8 +4120,6 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru return hr; } - wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); - TRACE("Created compute shader %p.\n", object); *shader = object; @@ -4230,9 +4135,6 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n", device, desc, parent, parent_ops, shader); - if (!desc->byte_code) - return WINED3DERR_INVALIDCALL; - if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; @@ -4243,8 +4145,6 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru return hr; } - wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); - TRACE("Created domain shader %p.\n", object); *shader = object; @@ -4261,9 +4161,6 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const stru TRACE("device %p, desc %p, so_desc %p, parent %p, parent_ops %p, shader %p.\n", device, desc, so_desc, parent, parent_ops, shader); - if (!desc->byte_code) - return WINED3DERR_INVALIDCALL; - if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; @@ -4274,8 +4171,6 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const stru return hr; } - wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); - TRACE("Created geometry shader %p.\n", object); *shader = object; @@ -4291,9 +4186,6 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n", device, desc, parent, parent_ops, shader); - if (!desc->byte_code) - return WINED3DERR_INVALIDCALL; - if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; @@ -4304,8 +4196,6 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru return hr; } - wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); - TRACE("Created hull shader %p.\n", object); *shader = object; @@ -4321,9 +4211,6 @@ HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const stru TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n", device, desc, parent, parent_ops, shader); - if (!desc->byte_code) - return WINED3DERR_INVALIDCALL; - if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; @@ -4334,8 +4221,6 @@ HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const stru return hr; } - wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); - TRACE("Created pixel shader %p.\n", object); *shader = object; @@ -4351,9 +4236,6 @@ HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const stru TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n", device, desc, parent, parent_ops, shader); - if (!desc->byte_code) - return WINED3DERR_INVALIDCALL; - if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; @@ -4364,8 +4246,6 @@ HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const stru return hr; } - wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); - TRACE("Created vertex shader %p.\n", object); *shader = object; diff --git a/dll/directx/wine/wined3d/shader_sm4.c b/dll/directx/wine/wined3d/shader_sm4.c index b119e8feaa8..8eac746ac50 100644 --- a/dll/directx/wine/wined3d/shader_sm4.c +++ b/dll/directx/wine/wined3d/shader_sm4.c @@ -61,9 +61,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode); #define WINED3D_SM4_GLOBAL_FLAGS_SHIFT 11 #define WINED3D_SM4_GLOBAL_FLAGS_MASK (0xffu << WINED3D_SM4_GLOBAL_FLAGS_SHIFT) -#define WINED3D_SM5_PRECISE_SHIFT 19 -#define WINED3D_SM5_PRECISE_MASK (0xfu << WINED3D_SM5_PRECISE_SHIFT) - #define WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT 11 #define WINED3D_SM5_CONTROL_POINT_COUNT_MASK (0xffu << WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT) @@ -318,7 +315,6 @@ enum wined3d_sm4_register_type WINED3D_SM4_RT_PRIMID = 0x0b, WINED3D_SM4_RT_DEPTHOUT = 0x0c, WINED3D_SM4_RT_NULL = 0x0d, - WINED3D_SM4_RT_RASTERIZER = 0x0e, WINED3D_SM4_RT_OMASK = 0x0f, WINED3D_SM5_RT_STREAM = 0x10, WINED3D_SM5_RT_FUNCTION_BODY = 0x11, @@ -1133,7 +1129,7 @@ static const enum wined3d_shader_register_type register_type_table[] = /* WINED3D_SM4_RT_PRIMID */ WINED3DSPR_PRIMID, /* WINED3D_SM4_RT_DEPTHOUT */ WINED3DSPR_DEPTHOUT, /* WINED3D_SM4_RT_NULL */ WINED3DSPR_NULL, - /* WINED3D_SM4_RT_RASTERIZER */ WINED3DSPR_RASTERIZER, + /* UNKNOWN */ ~0u, /* WINED3D_SM4_RT_OMASK */ WINED3DSPR_SAMPLEMASK, /* WINED3D_SM5_RT_STREAM */ WINED3DSPR_STREAM, /* WINED3D_SM5_RT_FUNCTION_BODY */ WINED3DSPR_FUNCTIONBODY, @@ -1222,43 +1218,6 @@ static enum wined3d_data_type map_data_type(char t) } } -enum wined3d_shader_type wined3d_get_sm4_shader_type(const DWORD *byte_code, size_t byte_code_size) -{ - DWORD shader_type; - - if (byte_code_size / sizeof(*byte_code) < 1) - { - WARN("Invalid byte code size %lu.\n", (long)byte_code_size); - return WINED3D_SHADER_TYPE_INVALID; - } - - shader_type = byte_code[0] >> 16; - switch (shader_type) - { - case WINED3D_SM4_PS: - return WINED3D_SHADER_TYPE_PIXEL; - break; - case WINED3D_SM4_VS: - return WINED3D_SHADER_TYPE_VERTEX; - break; - case WINED3D_SM4_GS: - return WINED3D_SHADER_TYPE_GEOMETRY; - break; - case WINED3D_SM5_HS: - return WINED3D_SHADER_TYPE_HULL; - break; - case WINED3D_SM5_DS: - return WINED3D_SHADER_TYPE_DOMAIN; - break; - case WINED3D_SM5_CS: - return WINED3D_SHADER_TYPE_COMPUTE; - break; - default: - FIXME("Unrecognised shader type %#x.\n", shader_type); - return WINED3D_SHADER_TYPE_INVALID; - } -} - static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size, const struct wined3d_shader_signature *output_signature) { @@ -1292,13 +1251,35 @@ static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size, priv->start = &byte_code[2]; priv->end = &byte_code[token_count]; - priv->shader_version.type = wined3d_get_sm4_shader_type(byte_code, byte_code_size); - if (priv->shader_version.type == WINED3D_SHADER_TYPE_INVALID) + switch (version_token >> 16) { - heap_free(priv); - return NULL; - } + case WINED3D_SM4_PS: + priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL; + break; + case WINED3D_SM4_VS: + priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX; + break; + + case WINED3D_SM4_GS: + priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; + break; + + case WINED3D_SM5_HS: + priv->shader_version.type = WINED3D_SHADER_TYPE_HULL; + break; + + case WINED3D_SM5_DS: + priv->shader_version.type = WINED3D_SHADER_TYPE_DOMAIN; + break; + + case WINED3D_SM5_CS: + priv->shader_version.type = WINED3D_SHADER_TYPE_COMPUTE; + break; + + default: + FIXME("Unrecognised shader type %#x.\n", version_token >> 16); + } priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token); priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token); @@ -1647,7 +1628,6 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi unsigned int i, len; SIZE_T remaining; const DWORD *p; - DWORD precise; list_move_head(&priv->src_free, &priv->src); @@ -1722,13 +1702,12 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi shader_sm4_read_instruction_modifier(previous_token = *p++, ins); ins->flags = (opcode_token & WINED3D_SM4_INSTRUCTION_FLAGS_MASK) >> WINED3D_SM4_INSTRUCTION_FLAGS_SHIFT; + if (ins->flags & WINED3D_SM4_INSTRUCTION_FLAG_SATURATE) { ins->flags &= ~WINED3D_SM4_INSTRUCTION_FLAG_SATURATE; instruction_dst_modifier = WINED3DSPDM_SATURATE; } - precise = (opcode_token & WINED3D_SM5_PRECISE_MASK) >> WINED3D_SM5_PRECISE_SHIFT; - ins->flags |= precise << WINED3DSI_PRECISE_SHIFT; for (i = 0; i < ins->dst_count; ++i) { diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c index 1bd38632b82..2f506c36d16 100644 --- a/dll/directx/wine/wined3d/state.c +++ b/dll/directx/wine/wined3d/state.c @@ -36,6 +36,7 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); ULONG CDECL wined3d_blend_state_incref(struct wined3d_blend_state *state) { @@ -1013,7 +1014,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ } } -static void state_stencilwrite2s_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; const struct wined3d_gl_info *gl_info = context->gl_info; @@ -1830,6 +1831,28 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 checkGLcall("depth bias"); } +static void state_depthclip(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (state->render_states[WINED3D_RS_DEPTHCLIP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP); + checkGLcall("glDisable(GL_DEPTH_CLAMP)"); + } + else + { + gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP); + checkGLcall("glEnable(GL_DEPTH_CLAMP)"); + } +} + +static void state_depthclip_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + if (!state->render_states[WINED3D_RS_DEPTHCLIP]) + FIXME("Depth clamping not supported by GL.\n"); +} + static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { if (state->render_states[WINED3D_RS_ZVISIBLE]) @@ -3311,6 +3334,76 @@ static void transform_texture(struct wined3d_context *context, const struct wine checkGLcall("glLoadMatrixf"); } +static void unload_tex_coords(const struct wined3d_gl_info *gl_info) +{ + unsigned int texture_idx; + + for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx) + { + GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx)); + gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } +} + +static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si, + GLuint *curVBO, const struct wined3d_state *state) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int mapped_stage = 0; + unsigned int textureNo; + + for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo) + { + int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX]; + + mapped_stage = context->tex_unit_map[textureNo]; + if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue; + + if (mapped_stage >= gl_info->limits.texture_coords) + { + FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage); + continue; + } + + if (coordIdx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coordIdx)))) + { + const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx]; + + TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n", + textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr); + + if (*curVBO != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + *curVBO = e->data.buffer_object; + } + + GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); + checkGLcall("glClientActiveTextureARB"); + + /* The coords to supply depend completely on the fvf / vertex shader */ + gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + else + { + GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1)); + } + } + if (gl_info->supported[NV_REGISTER_COMBINERS]) + { + /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */ + for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo) + { + GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1)); + } + } + + checkGLcall("loadTexCoords"); +} + static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); @@ -3481,8 +3574,8 @@ static void tex_coordindex(struct wined3d_context *context, const struct wined3d */ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; - context_unload_tex_coords(context); - context_load_tex_coords(context, &context->stream_info, &curVBO, state); + unload_tex_coords(gl_info); + load_tex_coords(context, &context->stream_info, &curVBO, state); } } @@ -3772,9 +3865,41 @@ void clipplane(struct wined3d_context *context, const struct wined3d_state *stat static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - unsigned int matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)); + UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)); + const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum glMat; - WARN("Unsupported world matrix %u set.\n", matrix); + TRACE("Setting world matrix %d\n", matrix); + + if (matrix >= gl_info->limits.blends) + { + WARN("Unsupported blend matrix set\n"); + return; + } + + if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW))) + return; + + /* GL_MODELVIEW0_ARB: 0x1700 + * GL_MODELVIEW1_ARB: 0x850a + * GL_MODELVIEW2_ARB: 0x8722 + * GL_MODELVIEW3_ARB: 0x8723 + * etc + * GL_MODELVIEW31_ARB: 0x873f + */ + if(matrix == 1) glMat = GL_MODELVIEW1_ARB; + else glMat = GL_MODELVIEW2_ARB - 2 + matrix; + + gl_info->gl_ops.gl.p_glMatrixMode(glMat); + checkGLcall("glMatrixMode(glMat)"); + + /* World matrix 0 is multiplied with the view matrix because d3d uses 3 + * matrices while gl uses only 2. To avoid weighting the view matrix + * incorrectly it has to be multiplied into every GL modelview matrix. */ + gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW]._11); + checkGLcall("glLoadMatrixf"); + gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)]._11); + checkGLcall("glMultMatrixf"); } static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -3789,6 +3914,50 @@ static void state_vertexblend_w(struct wined3d_context *context, const struct wi else WARN("Vertex blend flags %#x not supported.\n", f); } +static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND]; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; + static unsigned int once; + + switch (val) + { + case WINED3D_VBF_1WEIGHTS: + case WINED3D_VBF_2WEIGHTS: + case WINED3D_VBF_3WEIGHTS: + gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB); + checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)"); + + /* D3D adds one more matrix which has weight (1 - sum(weights)). + * This is enabled at context creation with enabling + * GL_WEIGHT_SUM_UNITY_ARB. */ + GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1)); + + if (!device->vertexBlendUsed) + { + unsigned int i; + for (i = 1; i < gl_info->limits.blends; ++i) + { + if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)))) + transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))); + } + device->vertexBlendUsed = TRUE; + } + break; + + case WINED3D_VBF_TWEENING: + case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */ + if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val); + else WARN("Vertex blend flags %#x not supported.\n", val); + /* Fall through. */ + case WINED3D_VBF_DISABLE: + gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB); + checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)"); + break; + } +} + static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -3839,6 +4008,16 @@ static void transform_view(struct wined3d_context *context, const struct wined3d * No need to do it here if the state is scheduled for update. */ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))) transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))); + + /* Avoid looping over a number of matrices if the app never used the functionality */ + if (context->device->vertexBlendUsed) + { + for (k = 1; k < gl_info->limits.blends; ++k) + { + if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)))) + transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))); + } + } } static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -3854,18 +4033,518 @@ static void transform_projection(struct wined3d_context *context, const struct w checkGLcall("glLoadMatrixf"); } +/* This should match any arrays loaded in load_vertex_data. + * TODO: Only load / unload arrays if we have to. */ +static void unload_vertex_data(const struct wined3d_gl_info *gl_info) +{ + gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY); + gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY); + gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY); + if (gl_info->supported[EXT_SECONDARY_COLOR]) + gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); + if (gl_info->supported[ARB_VERTEX_BLEND]) + gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB); + unload_tex_coords(gl_info); +} + +static inline void unload_numbered_array(struct wined3d_context *context, int i) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + GL_EXTCALL(glDisableVertexAttribArray(i)); + checkGLcall("glDisableVertexAttribArray"); + if (gl_info->supported[ARB_INSTANCED_ARRAYS]) + GL_EXTCALL(glVertexAttribDivisor(i, 0)); + + context->numbered_array_mask &= ~(1u << i); +} + +/* This should match any arrays loaded in loadNumberedArrays + * TODO: Only load / unload arrays if we have to. */ +static void unload_numbered_arrays(struct wined3d_context *context) +{ + /* disable any attribs (this is the same for both GLSL and ARB modes) */ + int i; + + for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) { + unload_numbered_array(context, i); + } +} + +static void load_numbered_arrays(struct wined3d_context *context, + const struct wined3d_stream_info *stream_info, const struct wined3d_state *state) +{ + const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; + const struct wined3d_gl_info *gl_info = context->gl_info; + GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; + unsigned int i; + + /* Default to no instancing */ + context->instance_count = 0; + + for (i = 0; i < MAX_ATTRIBS; ++i) + { + const struct wined3d_stream_info_element *element = &stream_info->elements[i]; + const struct wined3d_stream_state *stream; + + if (!(stream_info->use_map & (1u << i))) + { + if (context->numbered_array_mask & (1u << i)) + unload_numbered_array(context, i); + if (!use_vs(state) && i == WINED3D_FFP_DIFFUSE) + GL_EXTCALL(glVertexAttrib4f(i, 1.0f, 1.0f, 1.0f, 1.0f)); + else + GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f)); + continue; + } + + stream = &state->streams[element->stream_idx]; + + if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count) + context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1; + + if (gl_info->supported[ARB_INSTANCED_ARRAYS]) + { + GL_EXTCALL(glVertexAttribDivisor(i, element->divisor)); + } + else if (element->divisor) + { + /* Unload instanced arrays, they will be loaded using + * immediate mode instead. */ + if (context->numbered_array_mask & (1u << i)) + unload_numbered_array(context, i); + continue; + } + + TRACE_(d3d_shader)("Loading array %u [VBO=%u].\n", i, element->data.buffer_object); + + if (element->stride) + { + if (curVBO != element->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object)); + checkGLcall("glBindBuffer"); + curVBO = element->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. */ + if (vs && vs->reg_maps.shader_version.major >= 4 + && (element->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_INTEGER)) + { + GL_EXTCALL(glVertexAttribIPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type, + element->stride, element->data.addr + state->load_base_vertex_index * element->stride)); + } + else + { + GL_EXTCALL(glVertexAttribPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type, + element->format->gl_normalized, element->stride, + element->data.addr + state->load_base_vertex_index * element->stride)); + } + + if (!(context->numbered_array_mask & (1u << i))) + { + GL_EXTCALL(glEnableVertexAttribArray(i)); + context->numbered_array_mask |= (1u << i); + } + } + else + { + /* Stride = 0 means always the same values. + * 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 = element->data.addr; + if (element->data.buffer_object) + ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context); + + if (context->numbered_array_mask & (1u << i)) + unload_numbered_array(context, i); + + switch (element->format->id) + { + case WINED3DFMT_R32_FLOAT: + GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr)); + break; + case WINED3DFMT_R32G32_FLOAT: + GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr)); + break; + case WINED3DFMT_R32G32B32_FLOAT: + GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr)); + break; + case WINED3DFMT_R32G32B32A32_FLOAT: + GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr)); + break; + + case WINED3DFMT_R8G8B8A8_UINT: + GL_EXTCALL(glVertexAttrib4ubv(i, ptr)); + break; + case WINED3DFMT_B8G8R8A8_UNORM: + if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) + { + const DWORD *src = (const DWORD *)ptr; + DWORD c = *src & 0xff00ff00u; + c |= (*src & 0xff0000u) >> 16; + c |= (*src & 0xffu) << 16; + GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c)); + break; + } + /* else fallthrough */ + case WINED3DFMT_R8G8B8A8_UNORM: + GL_EXTCALL(glVertexAttrib4Nubv(i, ptr)); + break; + + case WINED3DFMT_R16G16_SINT: + GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr)); + break; + case WINED3DFMT_R16G16B16A16_SINT: + 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(glVertexAttrib4Nsv(i, s)); + break; + } + case WINED3DFMT_R16G16_UNORM: + { + const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1}; + GL_EXTCALL(glVertexAttrib4Nusv(i, s)); + break; + } + case WINED3DFMT_R16G16B16A16_SNORM: + GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr)); + break; + case WINED3DFMT_R16G16B16A16_UNORM: + GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr)); + break; + + case WINED3DFMT_R10G10B10X2_UINT: + FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n"); + /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */ + break; + case WINED3DFMT_R10G10B10X2_SNORM: + FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n"); + /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */ + break; + + case WINED3DFMT_R16G16_FLOAT: + if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) + { + /* Not supported by GL_ARB_half_float_vertex. */ + GL_EXTCALL(glVertexAttrib2hvNV(i, (const GLhalfNV *)ptr)); + } + else + { + float x = float_16_to_32(((const unsigned short *)ptr) + 0); + float y = float_16_to_32(((const unsigned short *)ptr) + 1); + GL_EXTCALL(glVertexAttrib2f(i, x, y)); + } + break; + case WINED3DFMT_R16G16B16A16_FLOAT: + if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) + { + /* Not supported by GL_ARB_half_float_vertex. */ + GL_EXTCALL(glVertexAttrib4hvNV(i, (const GLhalfNV *)ptr)); + } + else + { + float x = float_16_to_32(((const unsigned short *)ptr) + 0); + 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(glVertexAttrib4f(i, x, y, z, w)); + } + break; + + default: + ERR("Unexpected declaration in stride 0 attributes.\n"); + break; + + } + } + } + checkGLcall("Loading numbered arrays"); +} + +static void load_vertex_data(struct wined3d_context *context, + const struct wined3d_stream_info *si, const struct wined3d_state *state) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; + const struct wined3d_stream_info_element *e; + + TRACE("Using fast vertex array code\n"); + + /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */ + context->instance_count = 0; + + /* Blend Data ---------------------------------------------- */ + if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT)) + || si->use_map & (1u << WINED3D_FFP_BLENDINDICES)) + { + e = &si->elements[WINED3D_FFP_BLENDWEIGHT]; + + if (gl_info->supported[ARB_VERTEX_BLEND]) + { + TRACE("Blend %u %p %u\n", e->format->component_count, + e->data.addr + state->load_base_vertex_index * e->stride, e->stride); + + gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB); + checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)"); + + GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1)); + + if (curVBO != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + curVBO = e->data.buffer_object; + } + + TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n", + e->format->gl_vtx_format, + e->format->gl_vtx_type, + e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride)); + + checkGLcall("glWeightPointerARB"); + + if (si->use_map & (1u << WINED3D_FFP_BLENDINDICES)) + { + static BOOL warned; + if (!warned) + { + FIXME("blendMatrixIndices support\n"); + warned = TRUE; + } + } + } + else + { + /* TODO: Support vertex blending in immediate mode draws. No need + * to write a FIXME here, this is done after the general vertex + * declaration decoding. */ + WARN("Vertex blending not supported.\n"); + } + } + else + { + if (gl_info->supported[ARB_VERTEX_BLEND]) + { + static const GLbyte one = 1; + GL_EXTCALL(glWeightbvARB(1, &one)); + checkGLcall("glWeightbvARB(gl_info->max_blends, weights)"); + } + } + + /* Point Size ----------------------------------------------*/ + if (si->use_map & (1u << WINED3D_FFP_PSIZE)) + { + /* no such functionality in the fixed function GL pipeline */ + TRACE("Cannot change ptSize here in openGl\n"); + /* TODO: Implement this function in using shaders if they are available */ + } + + /* Vertex Pointers -----------------------------------------*/ + if (si->use_map & (1u << WINED3D_FFP_POSITION)) + { + e = &si->elements[WINED3D_FFP_POSITION]; + + if (curVBO != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + curVBO = e->data.buffer_object; + } + + TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n", + e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + checkGLcall("glVertexPointer(...)"); + gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY); + checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)"); + } + + /* Normals -------------------------------------------------*/ + if (si->use_map & (1u << WINED3D_FFP_NORMAL)) + { + e = &si->elements[WINED3D_FFP_NORMAL]; + + if (curVBO != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + curVBO = e->data.buffer_object; + } + + TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + checkGLcall("glNormalPointer(...)"); + gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY); + checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); + + } + else + { + gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0); + checkGLcall("glNormal3f(0, 0, 0)"); + } + + /* Diffuse Colour --------------------------------------------*/ + if (si->use_map & (1u << WINED3D_FFP_DIFFUSE)) + { + e = &si->elements[WINED3D_FFP_DIFFUSE]; + + if (curVBO != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + curVBO = e->data.buffer_object; + } + + TRACE("glColorPointer(%#x, %#x %#x, %p);\n", + e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); + gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY); + checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); + + } + else + { + gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + checkGLcall("glColor4f(1, 1, 1, 1)"); + } + + /* Specular Colour ------------------------------------------*/ + if (si->use_map & (1u << WINED3D_FFP_SPECULAR)) + { + TRACE("setting specular colour\n"); + + e = &si->elements[WINED3D_FFP_SPECULAR]; + + if (gl_info->supported[EXT_SECONDARY_COLOR]) + { + GLenum type = e->format->gl_vtx_type; + GLint format = e->format->gl_vtx_format; + + if (curVBO != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + curVBO = e->data.buffer_object; + } + + if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA)) + { + /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha + * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function + * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts + * 4 component secondary colors use it + */ + TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride)); + checkGLcall("glSecondaryColorPointerEXT(format, type, ...)"); + } + else + { + switch(type) + { + case GL_UNSIGNED_BYTE: + TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride)); + checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)"); + break; + + default: + FIXME("Add 4 component specular color pointers for type %x\n", type); + /* Make sure that the right color component is dropped */ + TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride)); + checkGLcall("glSecondaryColorPointerEXT(3, type, ...)"); + } + } + gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); + checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); + } + } + else + { + if (gl_info->supported[EXT_SECONDARY_COLOR]) + { + GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); + checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); + } + } + + /* Texture coords -------------------------------------------*/ + load_tex_coords(context, si, &curVBO, state); +} + static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - if (isStateDirty(context, STATE_VDECL)) - return; - context_update_stream_sources(context, state); + BOOL load_numbered = context->d3d_info->ffp_generic_attributes + || (use_vs(state) && !context->use_immediate_mode_draw); + BOOL load_named = !context->d3d_info->ffp_generic_attributes + && !use_vs(state) && !context->use_immediate_mode_draw; + + if (isStateDirty(context, STATE_VDECL)) return; + if (context->numberedArraysLoaded && !load_numbered) + { + unload_numbered_arrays(context); + context->numberedArraysLoaded = FALSE; + context->numbered_array_mask = 0; + } + else if (context->namedArraysLoaded) + { + unload_vertex_data(context->gl_info); + context->namedArraysLoaded = FALSE; + } + + if (load_numbered) + { + TRACE("Loading numbered arrays\n"); + load_numbered_arrays(context, &context->stream_info, state); + context->numberedArraysLoaded = TRUE; + } + else if (load_named) + { + TRACE("Loading vertex data\n"); + load_vertex_data(context, &context->stream_info, state); + context->namedArraysLoaded = TRUE; + } } static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { if (isStateDirty(context, STATE_STREAMSRC)) return; - context_update_stream_sources(context, state); + streamsrc(context, state, STATE_STREAMSRC); } static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4003,18 +4682,30 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine } } -static void get_viewports(struct wined3d_context *context, const struct wined3d_state *state, - unsigned int viewport_count, struct wined3d_viewport *viewports) +static void get_viewport(struct wined3d_context *context, const struct wined3d_state *state, + struct wined3d_viewport *viewport) { const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil; const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; - unsigned int width, height, i; + unsigned int width, height; - for (i = 0; i < viewport_count; ++i) - viewports[i] = state->viewports[i]; + *viewport = state->viewport; - /* Note: GL uses a lower left origin while DirectX uses upper left. This - * is reversed when using offscreen rendering. */ + if (target) + { + if (context->d3d_info->wined3d_creation_flags & WINED3D_LIMIT_VIEWPORT) + { + if (viewport->width > target->width) + viewport->width = target->width; + if (viewport->height > target->height) + viewport->height = target->height; + } + } + + /* + * Note: GL requires lower left, DirectX supplies upper left. This is + * reversed when using offscreen rendering. + */ if (context->render_offscreen) return; @@ -4032,53 +4723,22 @@ static void get_viewports(struct wined3d_context *context, const struct wined3d_ return; } - for (i = 0; i < viewport_count; ++i) - viewports[i].y = height - (viewports[i].y + viewports[i].height); + viewport->y = height - (viewport->y + viewport->height); } static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS]; + struct wined3d_viewport vp; + + get_viewport(context, state, &vp); + + gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); if (gl_info->supported[ARB_VIEWPORT_ARRAY]) - { - GLdouble depth_ranges[2 * WINED3D_MAX_VIEWPORTS]; - GLfloat viewports[4 * WINED3D_MAX_VIEWPORTS]; - - unsigned int i, reset_count = 0; - - get_viewports(context, state, state->viewport_count, vp); - for (i = 0; i < state->viewport_count; ++i) - { - depth_ranges[i * 2] = vp[i].min_z; - depth_ranges[i * 2 + 1] = vp[i].max_z; - - viewports[i * 4] = vp[i].x; - viewports[i * 4 + 1] = vp[i].y; - viewports[i * 4 + 2] = vp[i].width; - viewports[i * 4 + 3] = vp[i].height; - } - - if (context->viewport_count > state->viewport_count) - reset_count = context->viewport_count - state->viewport_count; - - if (reset_count) - { - memset(&depth_ranges[state->viewport_count * 2], 0, reset_count * 2 * sizeof(*depth_ranges)); - memset(&viewports[state->viewport_count * 4], 0, reset_count * 4 * sizeof(*viewports)); - } - - GL_EXTCALL(glDepthRangeArrayv(0, state->viewport_count + reset_count, depth_ranges)); - GL_EXTCALL(glViewportArrayv(0, state->viewport_count + reset_count, viewports)); - context->viewport_count = state->viewport_count; - } + GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height)); else - { - get_viewports(context, state, 1, vp); - gl_info->gl_ops.gl.p_glDepthRange(vp[0].min_z, vp[0].max_z); - gl_info->gl_ops.gl.p_glViewport(vp[0].x, vp[0].y, vp[0].width, vp[0].height); - } + gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height); checkGLcall("setting clip space and viewport"); } @@ -4089,39 +4749,16 @@ static void viewport_miscpart_cc(struct wined3d_context *context, float pixel_center_offset = context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f; const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS]; - GLdouble depth_ranges[2 * WINED3D_MAX_VIEWPORTS]; - GLfloat viewports[4 * WINED3D_MAX_VIEWPORTS]; - unsigned int i, reset_count = 0; + struct wined3d_viewport vp; - get_viewports(context, state, state->viewport_count, vp); + get_viewport(context, state, &vp); + vp.x += pixel_center_offset; + vp.y += pixel_center_offset; + + gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); GL_EXTCALL(glClipControl(context->render_offscreen ? GL_UPPER_LEFT : GL_LOWER_LEFT, GL_ZERO_TO_ONE)); - - for (i = 0; i < state->viewport_count; ++i) - { - depth_ranges[i * 2] = vp[i].min_z; - depth_ranges[i * 2 + 1] = vp[i].max_z; - - viewports[i * 4] = vp[i].x + pixel_center_offset; - viewports[i * 4 + 1] = vp[i].y + pixel_center_offset; - viewports[i * 4 + 2] = vp[i].width; - viewports[i * 4 + 3] = vp[i].height; - } - - if (context->viewport_count > state->viewport_count) - reset_count = context->viewport_count - state->viewport_count; - - if (reset_count) - { - memset(&depth_ranges[state->viewport_count * 2], 0, reset_count * 2 * sizeof(*depth_ranges)); - memset(&viewports[state->viewport_count * 4], 0, reset_count * 4 * sizeof(*viewports)); - } - - GL_EXTCALL(glDepthRangeArrayv(0, state->viewport_count + reset_count, depth_ranges)); - GL_EXTCALL(glViewportArrayv(0, state->viewport_count + reset_count, viewports)); - context->viewport_count = state->viewport_count; - + GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height)); checkGLcall("setting clip space and viewport"); } @@ -4262,53 +4899,27 @@ static void light(struct wined3d_context *context, const struct wined3d_state *s static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int height = 0; - const RECT *r; + const RECT *r = &state->scissor_rect; /* Warning: glScissor uses window coordinates, not viewport coordinates, * so our viewport correction does not apply. Warning2: Even in windowed * mode the coords are relative to the window, not the screen. */ + TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r)); - if (!context->render_offscreen) + if (context->render_offscreen) { - const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; - unsigned int width; - - wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height); - } - - if (gl_info->supported[ARB_VIEWPORT_ARRAY]) - { - GLint sr[4 * WINED3D_MAX_VIEWPORTS]; - unsigned int i, reset_count = 0; - - for (i = 0; i < state->scissor_rect_count; ++i) - { - r = &state->scissor_rects[i]; - - sr[i * 4] = r->left; - sr[i * 4 + 1] = height ? height - r->top : r->top; - sr[i * 4 + 2] = r->right - r->left; - sr[i * 4 + 3] = r->bottom - r->top; - } - - if (context->scissor_rect_count > state->scissor_rect_count) - reset_count = context->scissor_rect_count - state->scissor_rect_count; - - if (reset_count) - memset(&sr[state->scissor_rect_count * 4], 0, reset_count * 4 * sizeof(GLint)); - - GL_EXTCALL(glScissorArrayv(0, state->scissor_rect_count + reset_count, sr)); - checkGLcall("glScissorArrayv"); - context->scissor_rect_count = state->scissor_rect_count; + gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top); } else { - r = &state->scissor_rects[0]; - gl_info->gl_ops.gl.p_glScissor(r->left, height ? height - r->top : r->top, - r->right - r->left, r->bottom - r->top); - checkGLcall("glScissor"); + const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; + UINT height; + UINT width; + + wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height); + gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top); } + checkGLcall("glScissor"); } static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4327,23 +4938,7 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st } } -static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) -{ - if (!gl_info->supported[ARB_DEPTH_CLAMP]) - { - if (r && !r->desc.depth_clip) - FIXME("Depth clamp not supported by this GL implementation.\n"); - return; - } - - if (r && !r->desc.depth_clip) - gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP); - else - gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP); - checkGLcall("depth clip"); -} - -static void rasterizer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; GLenum mode; @@ -4354,10 +4949,9 @@ static void rasterizer(struct wined3d_context *context, const struct wined3d_sta gl_info->gl_ops.gl.p_glFrontFace(mode); checkGLcall("glFrontFace"); - depth_clip(state->rasterizer_state, gl_info); } -static void rasterizer_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void frontface_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; GLenum mode; @@ -4366,7 +4960,6 @@ static void rasterizer_cc(struct wined3d_context *context, const struct wined3d_ gl_info->gl_ops.gl.p_glFrontFace(mode); checkGLcall("glFrontFace"); - depth_clip(state->rasterizer_state, gl_info); } static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4536,8 +5129,8 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_BLEND, { STATE_BLEND, state_blend_object }, WINED3D_GL_EXT_NONE }, { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE }, - { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer_cc }, ARB_CLIP_CONTROL }, - { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer }, WINED3D_GL_EXT_NONE }, + { STATE_FRONTFACE, { STATE_FRONTFACE, frontface_cc }, ARB_CLIP_CONTROL }, + { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE }, { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE }, { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, state_nop }, ARB_CLIP_CONTROL }, { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 }, @@ -4630,7 +5223,7 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s_ext}, EXT_STENCIL_TWO_SIDE }, + { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE }, { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, @@ -4697,6 +5290,8 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DEPTHBIASCLAMP), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_DEPTHCLIP), { STATE_RENDER(WINED3D_RS_DEPTHCLIP), state_depthclip }, ARB_DEPTH_CLAMP }, + { STATE_RENDER(WINED3D_RS_DEPTHCLIP), { STATE_RENDER(WINED3D_RS_DEPTHCLIP), state_depthclip_w }, WINED3D_GL_EXT_NONE }, /* Samplers */ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE }, @@ -5055,6 +5650,7 @@ static const struct StateEntryTemplate vp_ffp_states[] = { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND }, { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, @@ -5227,7 +5823,7 @@ static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3 caps->xyzrhw = FALSE; caps->ffp_generic_attributes = FALSE; caps->max_active_lights = gl_info->limits.lights; - caps->max_vertex_blend_matrices = 1; + caps->max_vertex_blend_matrices = gl_info->limits.blends; caps->max_vertex_blend_matrix_index = 0; caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS | WINED3DVTXPCAPS_MATERIALSOURCE7 @@ -5485,7 +6081,7 @@ static void validate_state_table(struct StateEntry *state_table) STATE_VIEWPORT, STATE_LIGHT_TYPE, STATE_SCISSORRECT, - STATE_RASTERIZER, + STATE_FRONTFACE, STATE_POINTSPRITECOORDORIGIN, STATE_BASEVERTEXINDEX, STATE_FRAMEBUFFER, diff --git a/dll/directx/wine/wined3d/stateblock.c b/dll/directx/wine/wined3d/stateblock.c index 397ddaac95c..c9b3527d891 100644 --- a/dll/directx/wine/wined3d/stateblock.c +++ b/dll/directx/wine/wined3d/stateblock.c @@ -94,6 +94,7 @@ static const DWORD pixel_states_render[] = WINED3D_RS_ZENABLE, WINED3D_RS_ZFUNC, WINED3D_RS_ZWRITEENABLE, + WINED3D_RS_DEPTHCLIP, }; static const DWORD pixel_states_texture[] = @@ -814,33 +815,20 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) stateblock->state.material = src_state->material; } - assert(src_state->viewport_count <= 1); - if (stateblock->changed.viewport - && (src_state->viewport_count != stateblock->state.viewport_count - || memcmp(src_state->viewports, stateblock->state.viewports, - src_state->viewport_count * sizeof(*stateblock->state.viewports)))) + && memcmp(&src_state->viewport, &stateblock->state.viewport, sizeof(stateblock->state.viewport))) { - TRACE("Updating viewports.\n"); + TRACE("Updating viewport.\n"); - if ((stateblock->state.viewport_count = src_state->viewport_count)) - memcpy(stateblock->state.viewports, src_state->viewports, sizeof(src_state->viewports)); - else - memset(stateblock->state.viewports, 0, sizeof(*stateblock->state.viewports)); + stateblock->state.viewport = src_state->viewport; } - if (stateblock->changed.scissorRect - && (src_state->scissor_rect_count != stateblock->state.scissor_rect_count - || memcmp(src_state->scissor_rects, stateblock->state.scissor_rects, - src_state->scissor_rect_count * sizeof(*stateblock->state.scissor_rects)))) + if (stateblock->changed.scissorRect && memcmp(&src_state->scissor_rect, + &stateblock->state.scissor_rect, sizeof(stateblock->state.scissor_rect))) { - TRACE("Updating scissor rects.\n"); + TRACE("Updating scissor rect.\n"); - if ((stateblock->state.scissor_rect_count = src_state->scissor_rect_count)) - memcpy(stateblock->state.scissor_rects, src_state->scissor_rects, - src_state->scissor_rect_count * sizeof(*src_state->scissor_rects)); - else - SetRectEmpty(stateblock->state.scissor_rects); + stateblock->state.scissor_rect = src_state->scissor_rect; } map = stateblock->changed.streamSource; @@ -1072,11 +1060,10 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) wined3d_device_set_material(device, &stateblock->state.material); if (stateblock->changed.viewport) - wined3d_device_set_viewports(device, stateblock->state.viewport_count, stateblock->state.viewports); + wined3d_device_set_viewport(device, &stateblock->state.viewport); if (stateblock->changed.scissorRect) - wined3d_device_set_scissor_rects(device, stateblock->state.scissor_rect_count, - stateblock->state.scissor_rects); + wined3d_device_set_scissor_rect(device, &stateblock->state.scissor_rect); map = stateblock->changed.streamSource; for (i = 0; map; map >>= 1, ++i) @@ -1259,6 +1246,7 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d state->render_states[WINED3D_RS_DEPTHBIAS] = 0; tmpfloat.f = 0.0f; state->render_states[WINED3D_RS_DEPTHBIASCLAMP] = tmpfloat.d; + state->render_states[WINED3D_RS_DEPTHCLIP] = TRUE; state->render_states[WINED3D_RS_WRAP8] = 0; state->render_states[WINED3D_RS_WRAP9] = 0; state->render_states[WINED3D_RS_WRAP10] = 0; diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c index baad32e1daf..ae32235a9e6 100644 --- a/dll/directx/wine/wined3d/surface.c +++ b/dll/directx/wine/wined3d/surface.c @@ -36,6 +36,208 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER; +struct blt_info +{ + GLenum binding; + GLenum bind_target; + enum wined3d_gl_resource_type tex_type; + struct wined3d_vec3 texcoords[4]; +}; + +struct float_rect +{ + float l; + float t; + float r; + float b; +}; + +static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f) +{ + f->l = ((r->left * 2.0f) / w) - 1.0f; + f->t = ((r->top * 2.0f) / h) - 1.0f; + f->r = ((r->right * 2.0f) / w) - 1.0f; + f->b = ((r->bottom * 2.0f) / h) - 1.0f; +} + +static void texture2d_get_blt_info(const struct wined3d_texture *texture, + unsigned int sub_resource_idx, const RECT *rect, struct blt_info *info) +{ + struct wined3d_vec3 *coords = info->texcoords; + struct float_rect f; + unsigned int level; + GLenum target; + GLsizei w, h; + + level = sub_resource_idx % texture->level_count; + w = wined3d_texture_get_level_pow2_width(texture, level); + h = wined3d_texture_get_level_pow2_height(texture, level); + target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); + + switch (target) + { + default: + FIXME("Unsupported texture target %#x.\n", target); + /* Fall back to GL_TEXTURE_2D */ + case GL_TEXTURE_2D: + info->binding = GL_TEXTURE_BINDING_2D; + info->bind_target = GL_TEXTURE_2D; + info->tex_type = WINED3D_GL_RES_TYPE_TEX_2D; + coords[0].x = (float)rect->left / w; + coords[0].y = (float)rect->top / h; + coords[0].z = 0.0f; + + coords[1].x = (float)rect->right / w; + coords[1].y = (float)rect->top / h; + coords[1].z = 0.0f; + + coords[2].x = (float)rect->left / w; + coords[2].y = (float)rect->bottom / h; + coords[2].z = 0.0f; + + coords[3].x = (float)rect->right / w; + coords[3].y = (float)rect->bottom / h; + coords[3].z = 0.0f; + break; + + case GL_TEXTURE_RECTANGLE_ARB: + info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; + info->bind_target = GL_TEXTURE_RECTANGLE_ARB; + info->tex_type = WINED3D_GL_RES_TYPE_TEX_RECT; + coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f; + coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f; + coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f; + coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; + cube_coords_float(rect, w, h, &f); + + coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l; + coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r; + coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l; + coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; + cube_coords_float(rect, w, h, &f); + + coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l; + coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r; + coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l; + coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; + cube_coords_float(rect, w, h, &f); + + coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t; + coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t; + coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b; + coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; + cube_coords_float(rect, w, h, &f); + + coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t; + coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t; + coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b; + coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; + cube_coords_float(rect, w, h, &f); + + coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f; + coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f; + coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f; + coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; + cube_coords_float(rect, w, h, &f); + + coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f; + coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f; + coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f; + coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f; + break; + } +} + +/* Context activation is done by the caller. */ +void draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect, + enum wined3d_texture_filter_type filter) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct blt_info info; + + texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info); + + gl_info->gl_ops.gl.p_glEnable(info.bind_target); + checkGLcall("glEnable(bind_target)"); + + 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(filter)); + checkGLcall("glTexParameteri"); + gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER, + 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_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); + checkGLcall("glTexEnvi"); + + /* Draw a quad */ + gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x); + gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top); + + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x); + gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top); + + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x); + gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom); + + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x); + gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom); + gl_info->gl_ops.gl.p_glEnd(); + + /* Unbind the texture */ + context_bind_texture(context, info.bind_target, 0); + + /* We changed the filtering settings on the texture. Inform the + * container about this to get the filters reset properly next draw. */ + 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. */ static void get_color_masks(const struct wined3d_format *format, DWORD *masks) { @@ -57,19 +259,24 @@ static BOOL texture2d_is_full_rect(const struct wined3d_texture *texture, unsign return TRUE; } -static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct wined3d_context *context, - struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, - const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - DWORD dst_location, const RECT *dst_rect) +static void surface_depth_blt_fbo(const struct wined3d_device *device, + struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect, + struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect) { - const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture *src_texture = src_surface->container; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; DWORD src_mask, dst_mask; GLbitfield gl_mask; - TRACE("device %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s.\n", device, - src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), - dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); + TRACE("device %p\n", device); + TRACE("src_surface %p, src_location %s, src_rect %s,\n", + src_surface, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect)); + TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n", + dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); src_mask = src_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); dst_mask = dst_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); @@ -95,6 +302,14 @@ static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct if (src_mask & WINED3DFMT_FLAG_STENCIL) gl_mask |= GL_STENCIL_BUFFER_BIT; + context = context_acquire(device, NULL, 0); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping blit.\n"); + return; + } + /* Make sure the locations are up-to-date. Loading the destination * surface isn't required if the entire surface is overwritten. */ wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location); @@ -103,12 +318,12 @@ static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct else wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); - context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, 0, - &src_texture->resource, src_sub_resource_idx, src_location); + gl_info = context->gl_info; + + context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, src_surface, src_location); context_check_fbo_status(context, GL_READ_FRAMEBUFFER); - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, NULL, 0, - &dst_texture->resource, dst_sub_resource_idx, dst_location); + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, NULL, dst_surface, dst_location); context_set_draw_buffer(context, GL_NONE); context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); @@ -135,6 +350,11 @@ static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, gl_mask, GL_NEAREST); checkGLcall("glBlitFramebuffer()"); + + if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); } static BOOL is_multisample_location(const struct wined3d_texture *texture, DWORD location) @@ -148,25 +368,31 @@ static BOOL is_multisample_location(const struct wined3d_texture *texture, DWORD /* Blit between surface locations. Onscreen on different swapchains is not supported. * Depth / stencil is not supported. Context activation is done by the caller. */ -static void texture2d_blt_fbo(const struct wined3d_device *device, struct wined3d_context *context, - enum wined3d_texture_filter_type filter, struct wined3d_texture *src_texture, - unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, - struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, - const RECT *dst_rect) +static void surface_blt_fbo(const struct wined3d_device *device, + struct wined3d_context *old_ctx, enum wined3d_texture_filter_type filter, + struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect_in, + struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect_in) { - struct wined3d_texture *required_texture, *restore_texture; - unsigned int required_idx, restore_idx; + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture *src_texture = src_surface->container; const struct wined3d_gl_info *gl_info; + struct wined3d_context *context = old_ctx; + struct wined3d_surface *required_rt, *restore_rt = NULL; + RECT src_rect, dst_rect; GLenum gl_filter; GLenum buffer; - RECT s, d; int i; - TRACE("device %p, context %p, filter %s, src_texture %p, src_sub_resource_idx %u, src_location %s, " - "src_rect %s, dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s.\n", - device, context, debug_d3dtexturefiltertype(filter), src_texture, src_sub_resource_idx, - wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), dst_texture, - dst_sub_resource_idx, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); + TRACE("device %p, filter %s,\n", device, debug_d3dtexturefiltertype(filter)); + TRACE("src_surface %p, src_location %s, src_rect %s,\n", + src_surface, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect_in)); + TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n", + dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect_in)); + + src_rect = *src_rect_in; + dst_rect = *dst_rect_in; switch (filter) { @@ -185,43 +411,31 @@ static void texture2d_blt_fbo(const struct wined3d_device *device, struct wined3 /* Resolve the source surface first if needed. */ if (is_multisample_location(src_texture, src_location) && (src_texture->resource.format->id != dst_texture->resource.format->id - || abs(src_rect->bottom - src_rect->top) != abs(dst_rect->bottom - dst_rect->top) - || abs(src_rect->right - src_rect->left) != abs(dst_rect->right - dst_rect->left))) + || abs(src_rect.bottom - src_rect.top) != abs(dst_rect.bottom - dst_rect.top) + || abs(src_rect.right - src_rect.left) != abs(dst_rect.right - dst_rect.left))) src_location = WINED3D_LOCATION_RB_RESOLVED; /* Make sure the locations are up-to-date. Loading the destination * surface isn't required if the entire surface is overwritten. (And is * in fact harmful if we're being called by surface_load_location() with * the purpose of loading the destination surface.) */ - wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location); - if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, dst_rect)) - wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location); + wined3d_texture_load_location(src_texture, src_sub_resource_idx, old_ctx, src_location); + if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, &dst_rect)) + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location); else - wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); + wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location); - if (src_location == WINED3D_LOCATION_DRAWABLE) - { - required_texture = src_texture; - required_idx = src_sub_resource_idx; - } - else if (dst_location == WINED3D_LOCATION_DRAWABLE) - { - required_texture = dst_texture; - required_idx = dst_sub_resource_idx; - } - else - { - required_texture = NULL; - required_idx = 0; - } + if (src_location == WINED3D_LOCATION_DRAWABLE) required_rt = src_surface; + else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface; + else required_rt = NULL; - restore_texture = context->current_rt.texture; - restore_idx = context->current_rt.sub_resource_idx; - if (restore_texture != required_texture || restore_idx != required_idx) - context = context_acquire(device, required_texture, required_idx); + restore_rt = context_get_rt_surface(old_ctx); + if (restore_rt != required_rt) + context = context_acquire(device, required_rt ? required_rt->container : NULL, + required_rt ? surface_get_sub_resource_idx(required_rt) : 0); else - restore_texture = NULL; + restore_rt = NULL; if (!context->valid) { @@ -234,40 +448,34 @@ static void texture2d_blt_fbo(const struct wined3d_device *device, struct wined3 if (src_location == WINED3D_LOCATION_DRAWABLE) { - TRACE("Source texture %p is onscreen.\n", src_texture); + TRACE("Source surface %p is onscreen.\n", src_surface); buffer = wined3d_texture_get_gl_buffer(src_texture); - s = *src_rect; - wined3d_texture_translate_drawable_coords(src_texture, context->win_handle, &s); - src_rect = &s; + surface_translate_drawable_coords(src_surface, context->win_handle, &src_rect); } else { - TRACE("Source texture %p is offscreen.\n", src_texture); + TRACE("Source surface %p is offscreen.\n", src_surface); buffer = GL_COLOR_ATTACHMENT0; } - context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, - &src_texture->resource, src_sub_resource_idx, NULL, 0, src_location); + context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, src_surface, NULL, src_location); gl_info->gl_ops.gl.p_glReadBuffer(buffer); checkGLcall("glReadBuffer()"); context_check_fbo_status(context, GL_READ_FRAMEBUFFER); if (dst_location == WINED3D_LOCATION_DRAWABLE) { - TRACE("Destination texture %p is onscreen.\n", dst_texture); + TRACE("Destination surface %p is onscreen.\n", dst_surface); buffer = wined3d_texture_get_gl_buffer(dst_texture); - d = *dst_rect; - wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &d); - dst_rect = &d; + surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect); } else { - TRACE("Destination texture %p is offscreen.\n", dst_texture); + TRACE("Destination surface %p is offscreen.\n", dst_surface); buffer = GL_COLOR_ATTACHMENT0; } - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, - &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location); + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location); context_set_draw_buffer(context, buffer); context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); @@ -279,15 +487,16 @@ static void texture2d_blt_fbo(const struct wined3d_device *device, struct wined3 gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); - gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, - dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, GL_COLOR_BUFFER_BIT, gl_filter); + gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, + dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter); checkGLcall("glBlitFramebuffer()"); - if (dst_location == WINED3D_LOCATION_DRAWABLE && dst_texture->swapchain->front_buffer == dst_texture) + if (wined3d_settings.strict_draw_ordering || (dst_location == WINED3D_LOCATION_DRAWABLE + && dst_texture->swapchain->front_buffer == dst_texture)) gl_info->gl_ops.gl.p_glFlush(); - if (restore_texture) - context_restore(context, restore_texture, restore_idx); + if (restore_rt) + context_restore(context, restore_rt); } static BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_gl_info *gl_info, @@ -304,9 +513,6 @@ static BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct win if (!(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU)) return FALSE; - if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) - return FALSE; - switch (blit_op) { case WINED3D_BLIT_OP_COLOR_BLIT: @@ -344,11 +550,12 @@ static BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct win /* This call just downloads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -static void texture2d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, DWORD dst_location) +static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, + DWORD dst_location) { + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; const struct wined3d_format *format = texture->resource.format; - const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_texture_sub_resource *sub_resource; unsigned int dst_row_pitch, dst_slice_pitch; unsigned int src_row_pitch, src_slice_pitch; @@ -358,11 +565,10 @@ static void texture2d_download_data(struct wined3d_texture *texture, unsigned in GLenum target; void *mem; - /* Only support read back of converted P8 textures. */ + /* Only support read back of converted P8 surfaces. */ if (texture->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT && !format->download) { - ERR("Trying to read back converted texture %p, %u with format %s.\n", - texture, sub_resource_idx, debug_d3dformat(format->id)); + ERR("Trying to read back converted surface %p with format %s.\n", surface, debug_d3dformat(format->id)); return; } @@ -382,7 +588,7 @@ static void texture2d_download_data(struct wined3d_texture *texture, unsigned in if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) ERR("Array texture %p uses NP2 emulation.\n", texture); - WARN_(d3d_perf)("Downloading all miplevel layers to get the data for a single sub-resource.\n"); + WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n"); if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size))) { @@ -425,8 +631,7 @@ static void texture2d_download_data(struct wined3d_texture *texture, unsigned in if (data.buffer_object) ERR("Converted texture %p uses PBO unexpectedly.\n", texture); - WARN_(d3d_perf)("Downloading converted texture %p, %u with format %s.\n", - texture, sub_resource_idx, debug_d3dformat(format->id)); + WARN_(d3d_perf)("Downloading converted surface %p with format %s.\n", surface, debug_d3dformat(format->id)); f = *format; f.byte_count = format->conv_byte_count; @@ -460,16 +665,16 @@ static void texture2d_download_data(struct wined3d_texture *texture, unsigned in if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) { - TRACE("Downloading compressed texture %p, %u, level %u, format %#x, type %#x, data %p.\n", - texture, sub_resource_idx, level, format->glFormat, format->glType, mem); + TRACE("Downloading compressed surface %p, level %u, format %#x, type %#x, data %p.\n", + surface, level, format->glFormat, format->glType, mem); GL_EXTCALL(glGetCompressedTexImage(target, level, mem)); checkGLcall("glGetCompressedTexImage"); } else { - TRACE("Downloading texture %p, %u, level %u, format %#x, type %#x, data %p.\n", - texture, sub_resource_idx, level, format->glFormat, format->glType, mem); + TRACE("Downloading surface %p, level %u, format %#x, type %#x, data %p.\n", + surface, level, format->glFormat, format->glType, mem); gl_info->gl_ops.gl.p_glGetTexImage(target, level, format->glFormat, format->glType, mem); checkGLcall("glGetTexImage"); @@ -568,6 +773,291 @@ static void texture2d_download_data(struct wined3d_texture *texture, unsigned in heap_free(temporary_mem); } +/* This call just uploads data, the caller is responsible for binding the + * correct texture. */ +/* Context activation is done by the caller. */ +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) +{ + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; + UINT update_w = src_rect->right - src_rect->left; + UINT update_h = src_rect->bottom - src_rect->top; + unsigned int level, layer; + GLenum target; + + TRACE("surface %p, gl_info %p, format %s, src_rect %s, src_pitch %u, dst_point %s, srgb %#x, data {%#x:%p}.\n", + surface, gl_info, debug_d3dformat(format->id), wine_dbgstr_rect(src_rect), src_pitch, + wine_dbgstr_point(dst_point), srgb, data->buffer_object, data->addr); + + if (texture->sub_resources[sub_resource_idx].map_count) + { + WARN("Uploading a surface that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n"); + texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM; + } + + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) + { + update_h *= format->height_scale.numerator; + update_h /= format->height_scale.denominator; + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + } + + target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); + level = sub_resource_idx % texture->level_count; + layer = sub_resource_idx / texture->level_count; + + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + { + unsigned int dst_row_pitch, dst_slice_pitch; + const BYTE *addr = data->addr; + GLenum internal; + + addr += (src_rect->top / format->block_height) * src_pitch; + addr += (src_rect->left / format->block_width) * format->block_byte_count; + + 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; + + wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch); + + TRACE("Uploading compressed data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, " + "format %#x, image_size %#x, addr %p.\n", + target, level, layer, dst_point->x, dst_point->y, + update_w, update_h, internal, dst_slice_pitch, addr); + + if (dst_row_pitch == src_pitch) + { + if (target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_point->x, dst_point->y, + layer, update_w, update_h, 1, internal, dst_slice_pitch, addr)); + } + else + { + GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_point->x, dst_point->y, + update_w, update_h, internal, dst_slice_pitch, addr)); + } + } + else + { + UINT row_count = (update_h + format->block_height - 1) / format->block_height; + UINT row, y; + + /* 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) + { + if (target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_point->x, y, + layer, update_w, format->block_height, 1, internal, dst_row_pitch, addr)); + } + else + { + GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_point->x, y, + update_w, format->block_height, internal, dst_row_pitch, addr)); + } + + y += format->block_height; + addr += src_pitch; + } + } + checkGLcall("Upload compressed surface data"); + } + else + { + const BYTE *addr = data->addr; + + addr += src_rect->top * src_pitch; + addr += src_rect->left * format->byte_count; + + TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, " + "format %#x, type %#x, addr %p.\n", + target, level, layer, dst_point->x, dst_point->y, + update_w, update_h, format->glFormat, format->glType, addr); + + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count); + if (target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glTexSubImage3D(target, level, dst_point->x, dst_point->y, + layer, update_w, update_h, 1, format->glFormat, format->glType, addr)); + } + else + { + gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_point->x, dst_point->y, + update_w, update_h, format->glFormat, format->glType, addr); + } + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + checkGLcall("Upload surface data"); + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); + + if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) + { + struct wined3d_device *device = texture->resource.device; + unsigned int i; + + for (i = 0; i < device->context_count; ++i) + { + context_surface_update(device->contexts[i], surface); + } + } +} + +static HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, + struct wined3d_surface *src_surface, const RECT *src_rect) +{ + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; + unsigned int src_row_pitch, src_slice_pitch; + const struct wined3d_gl_info *gl_info; + unsigned int src_level, dst_level; + struct wined3d_context *context; + struct wined3d_bo_address data; + UINT update_w, update_h; + + TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n", + dst_surface, wine_dbgstr_point(dst_point), + src_surface, wine_dbgstr_rect(src_rect)); + + context = context_acquire(dst_texture->resource.device, NULL, 0); + gl_info = context->gl_info; + + /* Only load the surface for partial updates. For newly allocated texture + * the texture wouldn't be the current location, and we'd upload zeroes + * just to overwrite them again. */ + update_w = src_rect->right - src_rect->left; + update_h = src_rect->bottom - src_rect->top; + dst_level = dst_sub_resource_idx % dst_texture->level_count; + if (update_w == wined3d_texture_get_level_width(dst_texture, dst_level) + && update_h == wined3d_texture_get_level_height(dst_texture, dst_level)) + wined3d_texture_prepare_texture(dst_texture, context, FALSE); + else + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); + + src_level = src_sub_resource_idx % src_texture->level_count; + wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data, + src_texture->sub_resources[src_sub_resource_idx].locations); + wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch); + + wined3d_surface_upload_data(dst_surface, gl_info, src_texture->resource.format, src_rect, + src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data)); + + context_release(context); + + wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); + + return WINED3D_OK; +} + +/* 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. */ +/* Context activation is done by the caller. */ +void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt) +{ + unsigned int sub_resource_idx, width, height, level; + struct wined3d_renderbuffer_entry *entry; + const struct wined3d_texture *texture; + const struct wined3d_gl_info *gl_info; + unsigned int src_width, src_height; + GLuint renderbuffer = 0; + + texture = surface->container; + gl_info = &texture->resource.device->adapter->gl_info; + sub_resource_idx = surface_get_sub_resource_idx(surface); + level = sub_resource_idx % texture->level_count; + + if (rt && rt->resource->format->id != WINED3DFMT_NULL) + { + struct wined3d_texture *rt_texture; + unsigned int rt_level; + + if (rt->resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type)); + return; + } + rt_texture = wined3d_texture_from_resource(rt->resource); + rt_level = rt->sub_resource_idx % rt_texture->level_count; + + width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level); + height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level); + } + else + { + width = wined3d_texture_get_level_pow2_width(texture, level); + height = wined3d_texture_get_level_pow2_height(texture, level); + } + + src_width = wined3d_texture_get_level_pow2_width(texture, level); + src_height = wined3d_texture_get_level_pow2_height(texture, level); + + /* A depth stencil smaller than the render target is not valid */ + if (width > src_width || height > src_height) return; + + /* Remove any renderbuffer set if the sizes match */ + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] + || (width == src_width && height == src_height)) + { + surface->current_renderbuffer = NULL; + return; + } + + /* Look if we've already got a renderbuffer of the correct dimensions */ + LIST_FOR_EACH_ENTRY(entry, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) + { + if (entry->width == width && entry->height == height) + { + renderbuffer = entry->id; + surface->current_renderbuffer = entry; + break; + } + } + + if (!renderbuffer) + { + gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, + texture->resource.format->glInternal, width, height); + + entry = heap_alloc(sizeof(*entry)); + entry->width = width; + entry->height = height; + entry->id = renderbuffer; + list_add_head(&surface->renderbuffers, &entry->entry); + + surface->current_renderbuffer = entry; + } + + checkGLcall("set_compatible_renderbuffer"); +} + /* See also float_16_to_32() in wined3d_private.h */ static inline unsigned short float_32_to_16(const float *in) { @@ -990,6 +1480,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr const struct wined3d_format *src_format = src_texture->resource.format; struct wined3d_device *device = src_texture->resource.device; const struct d3dfmt_converter_desc *conv = NULL; + const struct wined3d_gl_info *gl_info = NULL; unsigned int src_row_pitch, src_slice_pitch; struct wined3d_context *context = NULL; struct wined3d_texture *dst_texture; @@ -1027,7 +1518,10 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr } if (device->d3d_initialized) + { context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + } map_binding = src_texture->resource.map_binding; if (!wined3d_texture_load_location(src_texture, sub_resource_idx, context, map_binding)) @@ -1061,14 +1555,15 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr } else { - struct wined3d_box src_box = {0, 0, desc.width, desc.height, 0, 1}; + RECT src_rect = {0, 0, desc.width, desc.height}; + POINT dst_point = {0, 0}; TRACE("Using upload conversion.\n"); wined3d_texture_prepare_texture(dst_texture, context, FALSE); wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); - wined3d_texture_upload_data(dst_texture, 0, context, src_format, &src_box, - wined3d_const_bo_address(&src_data), src_row_pitch, src_slice_pitch, 0, 0, 0, FALSE); + wined3d_surface_upload_data(dst_texture->sub_resources[0].u.surface, gl_info, src_format, + &src_rect, src_row_pitch, &dst_point, FALSE, wined3d_const_bo_address(&src_data)); wined3d_texture_validate_location(dst_texture, 0, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_invalidate_location(dst_texture, 0, ~WINED3D_LOCATION_TEXTURE_RGB); @@ -1080,16 +1575,18 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr return dst_texture; } -static void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD src_location, DWORD dst_location) +static void read_from_framebuffer(struct wined3d_surface *surface, + struct wined3d_context *old_ctx, DWORD src_location, DWORD dst_location) { + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; struct wined3d_device *device = texture->resource.device; - struct wined3d_texture *restore_texture; + struct wined3d_context *context = old_ctx; + struct wined3d_surface *restore_rt = NULL; const struct wined3d_gl_info *gl_info; unsigned int row_pitch, slice_pitch; unsigned int width, height, level; struct wined3d_bo_address data; - unsigned int restore_idx; BYTE *row, *top, *bottom; BOOL src_is_upside_down; unsigned int i; @@ -1097,18 +1594,16 @@ static void texture2d_read_from_framebuffer(struct wined3d_texture *texture, uns wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); - restore_texture = context->current_rt.texture; - restore_idx = context->current_rt.sub_resource_idx; - if (restore_texture != texture || restore_idx != sub_resource_idx) + restore_rt = context_get_rt_surface(old_ctx); + if (restore_rt != surface) context = context_acquire(device, texture, sub_resource_idx); else - restore_texture = NULL; + restore_rt = NULL; gl_info = context->gl_info; if (src_location != texture->resource.draw_binding) { - context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, - &texture->resource, sub_resource_idx, NULL, 0, src_location); + context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, surface, NULL, src_location); context_check_fbo_status(context, GL_READ_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); } @@ -1202,8 +1697,8 @@ error: checkGLcall("glBindBuffer"); } - if (restore_texture) - context_restore(context, restore_texture, restore_idx); + if (restore_rt) + context_restore(context, restore_rt); } /* Read the framebuffer contents into a texture. Note that this function @@ -1212,21 +1707,22 @@ error: * * Context activation is done by the caller. This function may temporarily * switch to a different context and restore the original one before return. */ -void texture2d_load_fb_texture(struct wined3d_texture *texture, - unsigned int sub_resource_idx, BOOL srgb, struct wined3d_context *context) +void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *old_ctx) { + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; struct wined3d_device *device = texture->resource.device; - struct wined3d_texture *restore_texture; const struct wined3d_gl_info *gl_info; - unsigned int restore_idx, level; + struct wined3d_context *context = old_ctx; + struct wined3d_surface *restore_rt = NULL; + unsigned int level; GLenum target; - restore_texture = context->current_rt.texture; - restore_idx = context->current_rt.sub_resource_idx; - if (restore_texture != texture || restore_idx != sub_resource_idx) + restore_rt = context_get_rt_surface(old_ctx); + if (restore_rt != surface) context = context_acquire(device, texture, sub_resource_idx); else - restore_texture = NULL; + restore_rt = NULL; gl_info = context->gl_info; device_invalidate_state(device, STATE_FRAMEBUFFER); @@ -1234,7 +1730,7 @@ void texture2d_load_fb_texture(struct wined3d_texture *texture, wined3d_texture_prepare_texture(texture, context, srgb); wined3d_texture_bind_and_dirtify(texture, context, srgb); - TRACE("Reading back offscreen render target %p, %u.\n", texture, sub_resource_idx); + TRACE("Reading back offscreen render target %p.\n", surface); if (wined3d_resource_is_offscreen(&texture->resource)) gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context)); @@ -1249,16 +1745,19 @@ void texture2d_load_fb_texture(struct wined3d_texture *texture, wined3d_texture_get_level_height(texture, level)); checkGLcall("glCopyTexSubImage2D"); - if (restore_texture) - context_restore(context, restore_texture, restore_idx); + if (restore_rt) + context_restore(context, restore_rt); } /* Does a direct frame buffer -> texture copy. Stretching is done with single * pixel copy calls. */ -static void fb_copy_to_texture_direct(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - const RECT *dst_rect_in, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - const RECT *src_rect, enum wined3d_texture_filter_type filter) +static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface, + const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter) { + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; struct wined3d_device *device = dst_texture->resource.device; unsigned int src_height, src_level, dst_level; const struct wined3d_gl_info *gl_info; @@ -1372,11 +1871,14 @@ static void fb_copy_to_texture_direct(struct wined3d_texture *dst_texture, unsig } /* Uses the hardware to stretch and flip the image */ -static void fb_copy_to_texture_hwstretch(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - const RECT *dst_rect_in, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - const RECT *src_rect, enum wined3d_texture_filter_type filter) +static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface, + const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter) { unsigned int src_width, src_height, src_pow2_width, src_pow2_height, src_level; + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; struct wined3d_device *device = dst_texture->resource.device; GLenum src_target, dst_target, texture_target; GLuint src, backup = 0; @@ -1398,7 +1900,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_texture *dst_texture, un /* Activate the Proper context for reading from the source surface, set it up for blitting */ context = context_acquire(device, src_texture, src_sub_resource_idx); gl_info = context->gl_info; - context_apply_ffp_blit_state(context, device); + context_apply_blit_state(context, device); wined3d_texture_load(dst_texture, context, FALSE); offscreen_buffer = context_get_offscreen_gl_buffer(context); @@ -1448,7 +1950,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_texture *dst_texture, un checkGLcall("glEnable(texture_target)"); /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ - src_texture->sub_resources[src_sub_resource_idx].locations &= ~WINED3D_LOCATION_TEXTURE_RGB; + surface_get_sub_resource(src_surface)->locations &= ~WINED3D_LOCATION_TEXTURE_RGB; } /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag @@ -1644,6 +2146,9 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_texture *dst_texture, un checkGLcall("glDeleteTextures(1, &backup)"); } + if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + context_release(context); /* The texture is now most up to date - If the surface is a render target @@ -1652,24 +2157,47 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_texture *dst_texture, un wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); } -static HRESULT wined3d_texture_blt_special(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) +/* Front buffer coordinates are always full screen coordinates, but our GL + * drawable is limited to the window's client area. The sysmem and texture + * copies do have the full screen size. Note that GL has a bottom-left + * origin, while D3D has a top-left origin. */ +void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) { - struct wined3d_swapchain *src_swapchain, *dst_swapchain; - const struct wined3d_rendertarget_view *rtv; + struct wined3d_texture *texture = surface->container; + POINT offset = {0, 0}; + UINT drawable_height; + RECT windowsize; - TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, " - "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture, src_sub_resource_idx, - wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); + if (!texture->swapchain) + return; - if (dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) + if (texture == texture->swapchain->front_buffer) { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_texture->resource.type)); - return WINED3DERR_INVALIDCALL; + ScreenToClient(window, &offset); + OffsetRect(rect, offset.x, offset.y); } + GetClientRect(window, &windowsize); + drawable_height = windowsize.bottom - windowsize.top; + + rect->top = drawable_height - rect->top; + rect->bottom = drawable_height - rect->bottom; +} + +static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RECT *dst_rect, + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) +{ + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_device *device = dst_texture->resource.device; + const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]); + struct wined3d_swapchain *src_swapchain, *dst_swapchain; + struct wined3d_texture *src_texture; + + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), + flags, fx, debug_d3dtexturefiltertype(filter)); + /* Get the swapchain. One of the surfaces has to be a primary surface. */ if (!(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) { @@ -1677,19 +2205,27 @@ static HRESULT wined3d_texture_blt_special(struct wined3d_texture *dst_texture, return WINED3DERR_INVALIDCALL; } - if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) - { - WARN("Source resource is not GPU accessible, rejecting GL blit.\n"); - return WINED3DERR_INVALIDCALL; - } - - src_swapchain = src_texture->swapchain; dst_swapchain = dst_texture->swapchain; + if (src_surface) + { + src_texture = src_surface->container; + if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + WARN("Source resource is not GPU accessible, rejecting GL blit.\n"); + return WINED3DERR_INVALIDCALL; + } + + src_swapchain = src_texture->swapchain; + } + else + { + src_texture = NULL; + src_swapchain = NULL; + } + /* Early sort out of cases where no render target is used */ - if (!(rtv = dst_texture->resource.device->fb.render_targets[0]) || (!src_swapchain && !dst_swapchain - && (&src_texture->resource != rtv->resource || src_sub_resource_idx != rtv->sub_resource_idx) - && (&dst_texture->resource != rtv->resource || dst_sub_resource_idx != rtv->sub_resource_idx))) + if (!dst_swapchain && !src_swapchain && src_surface != rt && dst_surface != rt) { TRACE("No surface is render target, not using hardware blit.\n"); return WINED3DERR_INVALIDCALL; @@ -1718,18 +2254,16 @@ static HRESULT wined3d_texture_blt_special(struct wined3d_texture *dst_texture, if (dst_swapchain) { /* Handled with regular texture -> swapchain blit */ - if (&src_texture->resource == rtv->resource && src_sub_resource_idx == rtv->sub_resource_idx) + if (src_surface == rt) TRACE("Blit from active render target to a swapchain\n"); } - else if (src_swapchain && &dst_texture->resource == rtv->resource - && dst_sub_resource_idx == rtv->sub_resource_idx) + else if (src_swapchain && dst_surface == rt) { FIXME("Implement blit from a swapchain to the active render target\n"); return WINED3DERR_INVALIDCALL; } - if (!dst_swapchain && (src_swapchain || (&src_texture->resource == rtv->resource - && src_sub_resource_idx == rtv->sub_resource_idx))) + if ((src_swapchain || src_surface == rt) && !dst_swapchain) { unsigned int src_level, src_width, src_height; /* Blit from render target to texture */ @@ -1765,21 +2299,19 @@ static HRESULT wined3d_texture_blt_special(struct wined3d_texture *dst_texture, * back buffer. This is slower than reading line per line, thus not used for flipping * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied * pixel by pixel. */ - src_level = src_sub_resource_idx % src_texture->level_count; + src_level = surface_get_sub_resource_idx(src_surface) % src_texture->level_count; src_width = wined3d_texture_get_level_width(src_texture, src_level); src_height = wined3d_texture_get_level_height(src_texture, src_level); if (!stretchx || dst_rect->right - dst_rect->left > src_width || dst_rect->bottom - dst_rect->top > src_height) { TRACE("No stretching in x direction, using direct framebuffer -> texture copy.\n"); - fb_copy_to_texture_direct(dst_texture, dst_sub_resource_idx, dst_rect, - src_texture, src_sub_resource_idx, src_rect, filter); + fb_copy_to_texture_direct(dst_surface, src_surface, src_rect, dst_rect, filter); } else { TRACE("Using hardware stretching to flip / stretch the texture.\n"); - fb_copy_to_texture_hwstretch(dst_texture, dst_sub_resource_idx, dst_rect, - src_texture, src_sub_resource_idx, src_rect, filter); + fb_copy_to_texture_hwstretch(dst_surface, src_surface, src_rect, dst_rect, filter); } return WINED3D_OK; @@ -1791,9 +2323,12 @@ static HRESULT wined3d_texture_blt_special(struct wined3d_texture *dst_texture, } /* Context activation is done by the caller. */ -BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_resource_idx, +static BOOL surface_load_sysmem(struct wined3d_surface *surface, struct wined3d_context *context, DWORD dst_location) { + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_texture *texture = surface->container; struct wined3d_texture_sub_resource *sub_resource; sub_resource = &texture->sub_resources[sub_resource_idx]; @@ -1803,8 +2338,7 @@ BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_res if (is_multisample_location(texture, WINED3D_LOCATION_TEXTURE_RGB)) { wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_RB_RESOLVED); - texture2d_read_from_framebuffer(texture, sub_resource_idx, context, - WINED3D_LOCATION_RB_RESOLVED, dst_location); + read_from_framebuffer(surface, context, WINED3D_LOCATION_RB_RESOLVED, dst_location); return TRUE; } else @@ -1812,12 +2346,12 @@ BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_res if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); - /* Download the sub-resource to system memory. */ + /* Download the surface to system memory. */ if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { wined3d_texture_bind_and_dirtify(texture, context, !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)); - texture2d_download_data(texture, sub_resource_idx, context, dst_location); + surface_download_data(surface, gl_info, dst_location); ++texture->download_count; return TRUE; @@ -1827,23 +2361,23 @@ BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_res if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) { - texture2d_read_from_framebuffer(texture, sub_resource_idx, context, - texture->resource.draw_binding, dst_location); + read_from_framebuffer(surface, context, texture->resource.draw_binding, dst_location); return TRUE; } - FIXME("Can't load texture %p, %u with location flags %s into sysmem.\n", - texture, sub_resource_idx, wined3d_debug_location(sub_resource->locations)); + FIXME("Can't load surface %p with location flags %s into sysmem.\n", + surface, wined3d_debug_location(sub_resource->locations)); return FALSE; } /* Context activation is done by the caller. */ -BOOL texture2d_load_drawable(struct wined3d_texture *texture, - unsigned int sub_resource_idx, struct wined3d_context *context) +static BOOL surface_load_drawable(struct wined3d_surface *surface, + struct wined3d_context *context) { - struct wined3d_texture *restore_texture; + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; + struct wined3d_surface *restore_rt = NULL; struct wined3d_device *device; - unsigned int restore_idx; unsigned int level; RECT r; @@ -1858,55 +2392,57 @@ BOOL texture2d_load_drawable(struct wined3d_texture *texture, if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && wined3d_resource_is_offscreen(&texture->resource)) { - ERR("Trying to load offscreen texture into WINED3D_LOCATION_DRAWABLE.\n"); + ERR("Trying to load offscreen surface into WINED3D_LOCATION_DRAWABLE.\n"); return FALSE; } device = texture->resource.device; - restore_texture = context->current_rt.texture; - restore_idx = context->current_rt.sub_resource_idx; - if (restore_texture != texture || restore_idx != sub_resource_idx) + restore_rt = context_get_rt_surface(context); + if (restore_rt != surface) context = context_acquire(device, texture, sub_resource_idx); else - restore_texture = NULL; + restore_rt = NULL; level = sub_resource_idx % texture->level_count; SetRect(&r, 0, 0, wined3d_texture_get_level_width(texture, level), wined3d_texture_get_level_height(texture, level)); wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, - texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &r, - texture, sub_resource_idx, WINED3D_LOCATION_DRAWABLE, &r, + surface, WINED3D_LOCATION_TEXTURE_RGB, &r, + surface, WINED3D_LOCATION_DRAWABLE, &r, NULL, WINED3D_TEXF_POINT); - if (restore_texture) - context_restore(context, restore_texture, restore_idx); + if (restore_rt) + context_restore(context, restore_rt); return TRUE; } -BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx, +static BOOL surface_load_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) { unsigned int width, height, level, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_texture *texture = surface->container; struct wined3d_device *device = texture->resource.device; const struct wined3d_color_key_conversion *conversion; struct wined3d_texture_sub_resource *sub_resource; - const struct wined3d_format *format; struct wined3d_bo_address data; BYTE *src_mem, *dst_mem = NULL; - struct wined3d_box src_box; + struct wined3d_format format; + POINT dst_point = {0, 0}; + RECT src_rect; BOOL depth; depth = texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL; - sub_resource = &texture->sub_resources[sub_resource_idx]; + sub_resource = surface_get_sub_resource(surface); if (!depth && wined3d_settings.offscreen_rendering_mode != ORM_FBO && wined3d_resource_is_offscreen(&texture->resource) && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) { - texture2d_load_fb_texture(texture, sub_resource_idx, srgb, context); + surface_load_fb_texture(surface, srgb, context); return TRUE; } @@ -1914,7 +2450,7 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re level = sub_resource_idx % texture->level_count; width = wined3d_texture_get_level_width(texture, level); height = wined3d_texture_get_level_height(texture, level); - wined3d_box_set(&src_box, 0, 0, width, height, 0, 1); + SetRect(&src_rect, 0, 0, width, height); if (!depth && sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) && (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) @@ -1922,17 +2458,12 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re &texture->resource, WINED3D_LOCATION_TEXTURE_RGB, &texture->resource, WINED3D_LOCATION_TEXTURE_SRGB)) { - RECT src_rect; - - SetRect(&src_rect, 0, 0, width, height); if (srgb) - texture2d_blt_fbo(device, context, WINED3D_TEXF_POINT, - texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect, - texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect); + surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB, + &src_rect, surface, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect); else - texture2d_blt_fbo(device, context, WINED3D_TEXF_POINT, - texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect, - texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect); + surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_SRGB, + &src_rect, surface, WINED3D_LOCATION_TEXTURE_RGB, &src_rect); return TRUE; } @@ -1943,13 +2474,11 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re DWORD src_location = sub_resource->locations & WINED3D_LOCATION_RB_RESOLVED ? WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE; DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; - RECT src_rect; - SetRect(&src_rect, 0, 0, width, height); if (fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info, &texture->resource, src_location, &texture->resource, dst_location)) - texture2d_blt_fbo(device, context, WINED3D_TEXF_POINT, texture, sub_resource_idx, - src_location, &src_rect, texture, sub_resource_idx, dst_location, &src_rect); + surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location, + &src_rect, surface, dst_location, &src_rect); return TRUE; } @@ -1961,7 +2490,7 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | texture->resource.map_binding)) == WINED3D_LOCATION_TEXTURE_RGB) { - FIXME_(d3d_perf)("Downloading RGB texture %p, %u to reload it as sRGB.\n", texture, sub_resource_idx); + FIXME_(d3d_perf)("Downloading RGB surface %p to reload it as sRGB.\n", surface); wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); } } @@ -1970,7 +2499,7 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | texture->resource.map_binding)) == WINED3D_LOCATION_TEXTURE_SRGB) { - FIXME_(d3d_perf)("Downloading sRGB texture %p, %u to reload it as RGB.\n", texture, sub_resource_idx); + FIXME_(d3d_perf)("Downloading sRGB surface %p to reload it as RGB.\n", surface); wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); } } @@ -1986,25 +2515,54 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re wined3d_texture_bind_and_dirtify(texture, context, srgb); wined3d_texture_get_pitch(texture, level, &src_row_pitch, &src_slice_pitch); - format = texture->resource.format; + format = *texture->resource.format; if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE))) - format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage); + format = *wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage); /* Don't use PBOs for converted surfaces. During PBO conversion we look at * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is * getting called. */ - if (conversion && sub_resource->buffer_object) +#if !defined(STAGING_CSMT) + if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer_object) +#else /* STAGING_CSMT */ + if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer) +#endif /* STAGING_CSMT */ { - TRACE("Removing the pbo attached to texture %p, %u.\n", texture, sub_resource_idx); + TRACE("Removing the pbo attached to surface %p.\n", surface); wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM); wined3d_texture_set_map_binding(texture, WINED3D_LOCATION_SYSMEM); } wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->locations); - if (conversion) + if (format.conv_byte_count) { - wined3d_format_calculate_pitch(format, device->surface_alignment, + /* This code is entered for texture formats which need a fixup. */ + format.byte_count = format.conv_byte_count; + wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch); + + src_mem = context_map_bo_address(context, &data, src_slice_pitch, + GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ); + if (!(dst_mem = heap_alloc(dst_slice_pitch))) + { + ERR("Out of memory (%u).\n", dst_slice_pitch); + context_release(context); + return FALSE; + } + format.upload(src_mem, dst_mem, src_row_pitch, src_slice_pitch, + dst_row_pitch, dst_slice_pitch, width, height, 1); + src_row_pitch = dst_row_pitch; + context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + + data.buffer_object = 0; + data.addr = dst_mem; + } + else if (conversion) + { + /* This code is only entered for color keying fixups */ + struct wined3d_palette *palette = NULL; + + wined3d_format_calculate_pitch(&format, device->surface_alignment, width, height, &dst_row_pitch, &dst_slice_pitch); src_mem = context_map_bo_address(context, &data, src_slice_pitch, @@ -2015,18 +2573,19 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re context_release(context); return FALSE; } + if (texture->swapchain && texture->swapchain->palette) + palette = texture->swapchain->palette; conversion->convert(src_mem, src_row_pitch, dst_mem, dst_row_pitch, - width, height, &texture->async.gl_color_key); + width, height, palette, &texture->async.gl_color_key); src_row_pitch = dst_row_pitch; - src_slice_pitch = dst_slice_pitch; context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); data.buffer_object = 0; data.addr = dst_mem; } - wined3d_texture_upload_data(texture, sub_resource_idx, context, format, &src_box, - wined3d_const_bo_address(&data), src_row_pitch, src_slice_pitch, 0, 0, 0, srgb); + wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, + src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); heap_free(dst_mem); @@ -2034,18 +2593,17 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re } /* Context activation is done by the caller. */ -BOOL texture2d_load_renderbuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD dst_location) +static BOOL surface_load_renderbuffer(struct wined3d_surface *surface, struct wined3d_context *context, + DWORD dst_location) { - unsigned int level = sub_resource_idx % texture->level_count; + struct wined3d_texture *texture = surface->container; + unsigned int level = surface_get_sub_resource_idx(surface) % texture->level_count; const RECT rect = {0, 0, wined3d_texture_get_level_width(texture, level), wined3d_texture_get_level_height(texture, level)}; - struct wined3d_texture_sub_resource *sub_resource; - DWORD src_location, locations; + DWORD locations = surface_get_sub_resource(surface)->locations; + DWORD src_location; - sub_resource = &texture->sub_resources[sub_resource_idx]; - locations = sub_resource->locations; if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) { FIXME("Unimplemented copy from %s for depth/stencil buffers.\n", @@ -2059,19 +2617,45 @@ BOOL texture2d_load_renderbuffer(struct wined3d_texture *texture, unsigned int s src_location = WINED3D_LOCATION_RB_RESOLVED; else if (locations & WINED3D_LOCATION_TEXTURE_SRGB) src_location = WINED3D_LOCATION_TEXTURE_SRGB; - else if (locations & WINED3D_LOCATION_TEXTURE_RGB) - src_location = WINED3D_LOCATION_TEXTURE_RGB; - else if (locations & WINED3D_LOCATION_DRAWABLE) - src_location = WINED3D_LOCATION_DRAWABLE; - else /* texture2d_blt_fbo() will load the source location if necessary. */ + else /* surface_blt_fbo will load the source location if necessary. */ src_location = WINED3D_LOCATION_TEXTURE_RGB; - texture2d_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT, texture, - sub_resource_idx, src_location, &rect, texture, sub_resource_idx, dst_location, &rect); + surface_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT, + surface, src_location, &rect, surface, dst_location, &rect); return TRUE; } +/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */ +BOOL surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) +{ + TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); + + switch (location) + { + case WINED3D_LOCATION_USER_MEMORY: + case WINED3D_LOCATION_SYSMEM: + case WINED3D_LOCATION_BUFFER: + return surface_load_sysmem(surface, context, location); + + case WINED3D_LOCATION_DRAWABLE: + return surface_load_drawable(surface, context); + + case WINED3D_LOCATION_RB_RESOLVED: + case WINED3D_LOCATION_RB_MULTISAMPLE: + return surface_load_renderbuffer(surface, context, location); + + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: + return surface_load_texture(surface, context, + location == WINED3D_LOCATION_TEXTURE_SRGB); + + default: + ERR("Don't know how to handle location %#x.\n", location); + return FALSE; + } +} + /* Context activation is done by the caller. */ static void fbo_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) { @@ -2095,27 +2679,16 @@ static void fbo_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de } static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, - unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) { - struct wined3d_resource *src_resource, *dst_resource; + struct wined3d_resource *src_resource = &src_surface->container->resource; + struct wined3d_resource *dst_resource = &dst_surface->container->resource; + struct wined3d_device *device = dst_resource->device; enum wined3d_blit_op blit_op = op; - struct wined3d_device *device; struct wined3d_blitter *next; - TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", - blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), - wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), - wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter)); - - src_resource = &src_texture->resource; - dst_resource = &dst_texture->resource; - - device = dst_resource->device; - if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_resource->format->id == src_resource->format->id) { if (dst_resource->format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) @@ -2127,30 +2700,23 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit if (!fbo_blitter_supported(blit_op, context->gl_info, src_resource, src_location, dst_resource, dst_location)) { - if (!(next = blitter->next)) - { - ERR("No blitter to handle blit op %#x.\n", op); - return dst_location; - } - - TRACE("Forwarding to blitter %p.\n", next); - return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); + if ((next = blitter->next)) + return next->ops->blitter_blit(next, op, context, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect, colour_key, filter); } if (blit_op == WINED3D_BLIT_OP_COLOR_BLIT) { TRACE("Colour blit.\n"); - texture2d_blt_fbo(device, context, filter, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect); + surface_blt_fbo(device, context, filter, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect); return dst_location; } if (blit_op == WINED3D_BLIT_OP_DEPTH_BLIT) { TRACE("Depth/stencil blit.\n"); - texture2d_depth_blt_fbo(device, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect); + surface_depth_blt_fbo(device, src_surface, src_location, src_rect, dst_surface, dst_location, dst_rect); return dst_location; } @@ -2213,17 +2779,21 @@ static void raw_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de /* Context activation is done by the caller. */ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, - unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) { const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int src_sub_resource_idx, dst_sub_resource_idx; unsigned int src_level, src_layer, dst_level, dst_layer; + struct wined3d_texture *src_texture, *dst_texture; struct wined3d_blitter *next; GLuint src_name, dst_name; DWORD location; + src_texture = src_surface->container; + dst_texture = dst_surface->container; + /* If we would need to copy from a renderbuffer or drawable, we'd probably * be better of using the FBO blitter directly, since we'd need to use it * to copy the resource contents to the texture anyway. */ @@ -2239,15 +2809,17 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit } TRACE("Forwarding to blitter %p.\n", next); - return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); + return next->ops->blitter_blit(next, op, context, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect, colour_key, filter); } TRACE("Blit using ARB_copy_image.\n"); + src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); src_level = src_sub_resource_idx % src_texture->level_count; src_layer = src_sub_resource_idx / src_texture->level_count; + dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); dst_level = dst_sub_resource_idx % dst_texture->level_count; dst_layer = dst_sub_resource_idx / dst_texture->level_count; @@ -2332,9 +2904,6 @@ static BOOL ffp_blit_supported(enum wined3d_blit_op blit_op, const struct wined3 const struct wined3d_format *dst_format = dst_resource->format; BOOL decompress; - if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) - return FALSE; - decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED); if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU)) @@ -2469,14 +3038,15 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de } static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, - unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) { + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_resource *src_resource, *dst_resource; - struct wined3d_texture *staging_texture = NULL; struct wined3d_color_key old_blt_key; struct wined3d_device *device; struct wined3d_blitter *next; @@ -2490,66 +3060,28 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit if (!ffp_blit_supported(op, context, src_resource, src_location, dst_resource, dst_location)) { if ((next = blitter->next)) - return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter); + return next->ops->blitter_blit(next, op, context, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect, color_key, filter); } - TRACE("Blt from texture %p, %u to rendertarget %p, %u.\n", - src_texture, src_sub_resource_idx, dst_texture, dst_sub_resource_idx); + TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface); old_blt_key = src_texture->async.src_blt_color_key; old_color_key_flags = src_texture->async.color_key_flags; wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT, color_key); - if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) - { - struct wined3d_resource_desc desc; - struct wined3d_box upload_box; - unsigned int src_level; - HRESULT hr; + /* Make sure the surface is up-to-date. This should probably use + * surface_load_location() and worry about the destination surface too, + * unless we're overwriting it completely. */ + wined3d_texture_load(src_texture, context, FALSE); - TRACE("Source texture is not GPU accessible, creating a staging texture.\n"); - - src_level = src_sub_resource_idx % src_texture->level_count; - desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - desc.format = src_texture->resource.format->id; - desc.multisample_type = src_texture->resource.multisample_type; - desc.multisample_quality = src_texture->resource.multisample_quality; - desc.usage = WINED3DUSAGE_PRIVATE; - desc.access = WINED3D_RESOURCE_ACCESS_GPU; - desc.width = wined3d_texture_get_level_width(src_texture, src_level); - desc.height = wined3d_texture_get_level_height(src_texture, src_level); - desc.depth = 1; - desc.size = 0; - - if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0, - NULL, NULL, &wined3d_null_parent_ops, &staging_texture))) - { - ERR("Failed to create staging texture, hr %#x.\n", hr); - return dst_location; - } - - wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth); - wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0, - src_texture, src_sub_resource_idx, &upload_box); - - src_texture = staging_texture; - src_sub_resource_idx = 0; - } - else - { - /* Make sure the surface is up-to-date. This should probably use - * surface_load_location() and worry about the destination surface - * too, unless we're overwriting it completely. */ - wined3d_texture_load(src_texture, context, FALSE); - } - - context_apply_ffp_blit_state(context, device); + /* Activate the destination context, set it up for blitting. */ + context_apply_blit_state(context, device); if (dst_location == WINED3D_LOCATION_DRAWABLE) { r = *dst_rect; - wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &r); + surface_translate_drawable_coords(dst_surface, context->win_handle, &r); dst_rect = &r; } @@ -2559,16 +3091,15 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit if (dst_location == WINED3D_LOCATION_DRAWABLE) { - TRACE("Destination texture %p is onscreen.\n", dst_texture); + TRACE("Destination surface %p is onscreen.\n", dst_surface); buffer = wined3d_texture_get_gl_buffer(dst_texture); } else { - TRACE("Destination texture %p is offscreen.\n", dst_texture); + TRACE("Destination surface %p is offscreen.\n", dst_surface); buffer = GL_COLOR_ATTACHMENT0; } - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, - dst_resource, dst_sub_resource_idx, NULL, 0, dst_location); + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location); context_set_draw_buffer(context, buffer); context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); @@ -2596,7 +3127,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit checkGLcall("glAlphaFunc"); } - context_draw_textured_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter); + draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter); if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key) { @@ -2604,6 +3135,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit checkGLcall("glDisable(GL_ALPHA_TEST)"); } + /* Leave the OpenGL state valid for blitting. */ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) @@ -2617,16 +3149,14 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); } - if (dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture) - gl_info->gl_ops.gl.p_glFlush(); + if (wined3d_settings.strict_draw_ordering + || (dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture)) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ /* Restore the color key parameters */ wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT, (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); - if (staging_texture) - wined3d_texture_decref(staging_texture); - return dst_location; } @@ -3402,13 +3932,16 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de } static DWORD cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, - unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) { struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture *src_texture = src_surface->container; struct wined3d_blt_fx fx; DWORD flags = 0; @@ -3462,12 +3995,17 @@ struct wined3d_blitter *wined3d_cpu_blitter_create(void) return blitter; } -HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - const struct wined3d_box *src_box, DWORD flags, const struct wined3d_blt_fx *fx, - enum wined3d_texture_filter_type filter) +HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) { + struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; + struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); struct wined3d_texture_sub_resource *src_sub_resource, *dst_sub_resource; + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture *src_texture = src_surface->container; struct wined3d_device *device = dst_texture->resource.device; struct wined3d_swapchain *src_swapchain, *dst_swapchain; const struct wined3d_color_key *colour_key = NULL; @@ -3476,17 +4014,15 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ struct wined3d_context *context; enum wined3d_blit_op blit_op; BOOL scale, convert, resolve; - RECT src_rect, dst_rect; static const DWORD simple_blit = WINED3D_BLT_SRC_CKEY | WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_ALPHA_TEST | WINED3D_BLT_RAW; - TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_box %s, src_texture %p, " - "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s.\n", - dst_texture, dst_sub_resource_idx, debug_box(dst_box), src_texture, src_sub_resource_idx, - debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter)); + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), + flags, fx, debug_d3dtexturefiltertype(filter)); TRACE("Usage is %s.\n", debug_d3dusage(dst_texture->resource.usage)); if (fx) @@ -3500,9 +4036,6 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ fx->src_color_key.color_space_high_value); } - SetRect(&src_rect, src_box->left, src_box->top, src_box->right, src_box->bottom); - SetRect(&dst_rect, dst_box->left, dst_box->top, dst_box->right, dst_box->bottom); - if (!fx || !(fx->fx)) flags &= ~WINED3D_BLT_FX; @@ -3523,6 +4056,16 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ goto cpu; } + /* We want to avoid invalidating the sysmem location for converted + * surfaces, since otherwise we'd have to convert the data back when + * locking them. */ + if (dst_texture->flags & WINED3D_TEXTURE_CONVERTED || dst_texture->resource.format->conv_byte_count + || wined3d_format_get_color_key_conversion(dst_texture, TRUE)) + { + WARN_(d3d_perf)("Converted surface, using CPU blit.\n"); + goto cpu; + } + if (flags & ~simple_blit) { WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags); @@ -3543,8 +4086,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ goto fallback; } - scale = src_box->right - src_box->left != dst_box->right - dst_box->left - || src_box->bottom - src_box->top != dst_box->bottom - dst_box->top; + scale = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left + || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top; convert = src_texture->resource.format->id != dst_texture->resource.format->id; resolve = src_texture->resource.multisample_type != dst_texture->resource.multisample_type; @@ -3565,8 +4108,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ context = context_acquire(device, dst_texture, dst_sub_resource_idx); valid_locations = device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_DEPTH_BLIT, context, - src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect, - dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, NULL, filter); + src_surface, src_texture->resource.draw_binding, src_rect, + dst_surface, dst_location, dst_rect, NULL, filter); context_release(context); wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, valid_locations); @@ -3620,16 +4163,19 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ TRACE("Not doing upload because the destination format needs conversion.\n"); else { - wined3d_texture_upload_from_texture(dst_texture, dst_sub_resource_idx, dst_box->left, - dst_box->top, dst_box->front, src_texture, src_sub_resource_idx, src_box); - if (!wined3d_resource_is_offscreen(&dst_texture->resource)) + POINT dst_point = {dst_rect->left, dst_rect->top}; + + if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, src_rect))) { - context = context_acquire(device, dst_texture, dst_sub_resource_idx); - wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, - context, dst_texture->resource.draw_binding); - context_release(context); + if (!wined3d_resource_is_offscreen(&dst_texture->resource)) + { + context = context_acquire(device, dst_texture, dst_sub_resource_idx); + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, + context, dst_texture->resource.draw_binding); + context_release(context); + } + return WINED3D_OK; } - return WINED3D_OK; } } else if (dst_swapchain && dst_swapchain->back_buffers @@ -3649,8 +4195,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ /* Set the swap effect to COPY, we don't want the backbuffer to become * undefined. */ dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; - wined3d_swapchain_present(dst_swapchain, NULL, NULL, - dst_swapchain->win_handle, dst_swapchain->swap_interval, 0); + wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, 0, 0); dst_swapchain->desc.swap_effect = swap_effect; return WINED3D_OK; @@ -3667,8 +4212,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ context = context_acquire(device, dst_texture, dst_sub_resource_idx); valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context, - src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect, - dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, colour_key, filter); + src_surface, src_texture->resource.draw_binding, src_rect, + dst_surface, dst_location, dst_rect, colour_key, filter); context_release(context); wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, valid_locations); @@ -3678,11 +4223,10 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ fallback: /* Special cases for render targets. */ - if (SUCCEEDED(wined3d_texture_blt_special(dst_texture, dst_sub_resource_idx, &dst_rect, - src_texture, src_sub_resource_idx, &src_rect, flags, fx, filter))) + if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter))) return WINED3D_OK; cpu: - return surface_cpu_blt(dst_texture, dst_sub_resource_idx, dst_box, - src_texture, src_sub_resource_idx, src_box, flags, fx, filter); + return surface_cpu_blt(dst_texture, dst_sub_resource_idx, &dst_box, + src_texture, src_sub_resource_idx, &src_box, flags, fx, filter); } diff --git a/dll/directx/wine/wined3d/swapchain.c b/dll/directx/wine/wined3d/swapchain.c index 7fee86692e0..8c67a0d42be 100644 --- a/dll/directx/wine/wined3d/swapchain.c +++ b/dll/directx/wine/wined3d/swapchain.c @@ -151,20 +151,24 @@ void CDECL wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWN HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - unsigned int swap_interval, DWORD flags) + DWORD swap_interval, DWORD flags) { + static DWORD notified_flags = 0; RECT s, d; TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, flags %#x.\n", swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, 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) { - WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL.\n"); + WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n"); return WINED3DERR_INVALIDCALL; } @@ -314,6 +318,7 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect) { struct wined3d_texture *texture = swapchain->back_buffers[0]; + struct wined3d_surface *back_buffer = texture->sub_resources[0].u.surface; struct wined3d_device *device = swapchain->device; enum wined3d_texture_filter_type filter; DWORD location; @@ -333,8 +338,8 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, location = WINED3D_LOCATION_RB_RESOLVED; wined3d_texture_validate_location(texture, 0, WINED3D_LOCATION_DRAWABLE); - device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, texture, 0, - location, src_rect, texture, 0, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter); + device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, back_buffer, + location, src_rect, back_buffer, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter); wined3d_texture_invalidate_location(texture, 0, WINED3D_LOCATION_DRAWABLE); } @@ -390,7 +395,6 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, { struct wined3d_texture *back_buffer = swapchain->back_buffers[0]; const struct wined3d_fb_state *fb = &swapchain->device->cs->fb; - struct wined3d_rendertarget_view *dsv = fb->depth_stencil; const struct wined3d_gl_info *gl_info; struct wined3d_texture *logo_texture; struct wined3d_context *context; @@ -476,7 +480,11 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, if (swapchain->render_to_fbo) swapchain_blit(swapchain, context, src_rect, dst_rect); +#if !defined(STAGING_CSMT) if (swapchain->num_contexts > 1) +#else /* STAGING_CSMT */ + if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded) +#endif /* STAGING_CSMT */ gl_info->gl_ops.gl.p_glFinish(); /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ @@ -515,13 +523,14 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, wined3d_texture_validate_location(swapchain->back_buffers[swapchain->desc.backbuffer_count - 1], 0, WINED3D_LOCATION_DISCARDED); - if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER) + if (fb->depth_stencil) { - struct wined3d_texture *ds = texture_from_resource(dsv->resource); + struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil); - if ((swapchain->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL - || ds->flags & WINED3D_TEXTURE_DISCARD)) - wined3d_texture_validate_location(ds, dsv->sub_resource_idx, WINED3D_LOCATION_DISCARDED); + if (ds && (swapchain->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL + || ds->container->flags & WINED3D_TEXTURE_DISCARD)) + wined3d_texture_validate_location(ds->container, + fb->depth_stencil->sub_resource_idx, WINED3D_LOCATION_DISCARDED); } context_release(context); @@ -546,7 +555,7 @@ static const struct wined3d_swapchain_ops swapchain_gl_ops = static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchain) { - struct wined3d_dc_info *front; + struct wined3d_surface *front; POINT offset = {0, 0}; HDC src_dc, dst_dc; RECT draw_rect; @@ -554,11 +563,11 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai TRACE("swapchain %p.\n", swapchain); - front = &swapchain->front_buffer->dc_info[0]; + front = swapchain->front_buffer->sub_resources[0].u.surface; if (swapchain->palette) wined3d_palette_apply_to_dc(swapchain->palette, front->dc); - if (swapchain->front_buffer->resource.map_count) + if (front->container->resource.map_count) ERR("Trying to blit a mapped surface.\n"); TRACE("Copying surface %p to screen.\n", front); @@ -589,26 +598,26 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, DWORD flags) { - struct wined3d_dc_info *front, *back; + struct wined3d_surface *front, *back; HBITMAP bitmap; void *data; HDC dc; - front = &swapchain->front_buffer->dc_info[0]; - back = &swapchain->back_buffers[0]->dc_info[0]; + front = swapchain->front_buffer->sub_resources[0].u.surface; + back = swapchain->back_buffers[0]->sub_resources[0].u.surface; /* Flip the surface data. */ dc = front->dc; bitmap = front->bitmap; - data = swapchain->front_buffer->resource.heap_memory; + data = front->container->resource.heap_memory; front->dc = back->dc; front->bitmap = back->bitmap; - swapchain->front_buffer->resource.heap_memory = swapchain->back_buffers[0]->resource.heap_memory; + front->container->resource.heap_memory = back->container->resource.heap_memory; back->dc = dc; back->bitmap = bitmap; - swapchain->back_buffers[0]->resource.heap_memory = data; + back->container->resource.heap_memory = data; /* FPS support */ if (TRACE_ON(fps)) @@ -677,26 +686,44 @@ static void wined3d_swapchain_apply_sample_count_override(const struct wined3d_s *quality = 0; } -void wined3d_swapchain_set_swap_interval(struct wined3d_swapchain *swapchain, - unsigned int swap_interval) +static void wined3d_swapchain_update_swap_interval_cs(void *object) { + struct wined3d_swapchain *swapchain = object; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - - swap_interval = swap_interval <= 4 ? swap_interval : 1; - if (swapchain->swap_interval == swap_interval) - return; - - swapchain->swap_interval = swap_interval; + int swap_interval; context = context_acquire(swapchain->device, swapchain->front_buffer, 0); gl_info = context->gl_info; + switch (swapchain->desc.swap_interval) + { + case WINED3DPRESENT_INTERVAL_IMMEDIATE: + swap_interval = 0; + break; + case WINED3DPRESENT_INTERVAL_DEFAULT: + case WINED3DPRESENT_INTERVAL_ONE: + swap_interval = 1; + break; + case WINED3DPRESENT_INTERVAL_TWO: + swap_interval = 2; + break; + case WINED3DPRESENT_INTERVAL_THREE: + swap_interval = 3; + break; + case WINED3DPRESENT_INTERVAL_FOUR: + swap_interval = 4; + break; + default: + FIXME("Unhandled present interval %#x.\n", swapchain->desc.swap_interval); + swap_interval = 1; + } + if (gl_info->supported[WGL_EXT_SWAP_CONTROL]) { if (!GL_EXTCALL(wglSwapIntervalEXT(swap_interval))) - ERR("wglSwapIntervalEXT failed to set swap interval %d for context %p, last error %#x.\n", - swap_interval, context, GetLastError()); + ERR("wglSwapIntervalEXT failed to set swap interval %d for context %p, last error %#x\n", + swap_interval, context, GetLastError()); } context_release(context); @@ -742,12 +769,8 @@ static void wined3d_swapchain_cs_init(void *object) FIXME("Add OpenGL context recreation support.\n"); context_release(swapchain->context[0]); -} -void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, const struct wined3d_device *device) -{ - /* Subtract 1 for the implicit OpenGL latency. */ - swapchain->max_frame_latency = device->max_frame_latency >= 2 ? device->max_frame_latency - 1 : 1; + wined3d_swapchain_update_swap_interval_cs(swapchain); } static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, @@ -758,9 +781,9 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 BOOL displaymode_set = FALSE; DWORD texture_flags = 0; RECT client_rect; - unsigned int i; HWND window; HRESULT hr; + UINT i; if (desc->backbuffer_count > 1) { @@ -786,8 +809,6 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 swapchain->ref = 1; swapchain->win_handle = window; swapchain->device_window = window; - swapchain->swap_interval = WINED3D_SWAP_INTERVAL_DEFAULT; - swapchain_set_max_frame_latency(swapchain, device); if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, adapter->ordinal, &swapchain->original_mode, NULL))) @@ -800,16 +821,15 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 GetClientRect(window, &client_rect); if (desc->windowed) { - TRACE("Client rect %s.\n", wine_dbgstr_rect(&client_rect)); - if (!desc->backbuffer_width) { - desc->backbuffer_width = client_rect.right ? client_rect.right : 8; + desc->backbuffer_width = client_rect.right; TRACE("Updating width to %u.\n", desc->backbuffer_width); } + if (!desc->backbuffer_height) { - desc->backbuffer_height = client_rect.bottom ? client_rect.bottom : 8; + desc->backbuffer_height = client_rect.bottom; TRACE("Updating height to %u.\n", desc->backbuffer_height); } @@ -1121,6 +1141,11 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) } } +void swapchain_update_swap_interval(struct wined3d_swapchain *swapchain) +{ + wined3d_cs_init_object(swapchain->device->cs, wined3d_swapchain_update_swap_interval_cs, swapchain); +} + void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) { struct wined3d_device *device = swapchain->device; diff --git a/dll/directx/wine/wined3d/texture.c b/dll/directx/wine/wined3d/texture.c index bee7f35e2bc..e6af0c75088 100644 --- a/dll/directx/wine/wined3d/texture.c +++ b/dll/directx/wine/wined3d/texture.c @@ -30,20 +30,6 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); #define WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD 50 -struct wined3d_texture_idx -{ - struct wined3d_texture *texture; - unsigned int sub_resource_idx; -}; - -struct wined3d_rect_f -{ - float l; - float t; - float r; - float b; -}; - static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info) { return !(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU) @@ -62,32 +48,6 @@ static BOOL wined3d_texture_use_immutable_storage(const struct wined3d_texture * && !(texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE); } -/* Front buffer coordinates are always full screen coordinates, but our GL - * drawable is limited to the window's client area. The sysmem and texture - * copies do have the full screen size. Note that GL has a bottom-left - * origin, while D3D has a top-left origin. */ -void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture, HWND window, RECT *rect) -{ - unsigned int drawable_height; - POINT offset = {0, 0}; - RECT windowsize; - - if (!texture->swapchain) - return; - - if (texture == texture->swapchain->front_buffer) - { - ScreenToClient(window, &offset); - OffsetRect(rect, offset.x, offset.y); - } - - GetClientRect(window, &windowsize); - drawable_height = windowsize.bottom - windowsize.top; - - rect->top = drawable_height - rect->top; - rect->bottom = drawable_height - rect->bottom; -} - GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) { const struct wined3d_swapchain *swapchain = texture->swapchain; @@ -141,120 +101,9 @@ static DWORD wined3d_resource_access_from_location(DWORD location) } } -static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct wined3d_rect_f *f) +static BOOL is_power_of_two(UINT x) { - f->l = ((r->left * 2.0f) / w) - 1.0f; - f->t = ((r->top * 2.0f) / h) - 1.0f; - f->r = ((r->right * 2.0f) / w) - 1.0f; - f->b = ((r->bottom * 2.0f) / h) - 1.0f; -} - -void texture2d_get_blt_info(const struct wined3d_texture *texture, - unsigned int sub_resource_idx, const RECT *rect, struct wined3d_blt_info *info) -{ - struct wined3d_vec3 *coords = info->texcoords; - struct wined3d_rect_f f; - unsigned int level; - GLenum target; - GLsizei w, h; - - level = sub_resource_idx % texture->level_count; - w = wined3d_texture_get_level_pow2_width(texture, level); - h = wined3d_texture_get_level_pow2_height(texture, level); - target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - - switch (target) - { - default: - FIXME("Unsupported texture target %#x.\n", target); - /* Fall back to GL_TEXTURE_2D */ - case GL_TEXTURE_2D: - info->bind_target = GL_TEXTURE_2D; - coords[0].x = (float)rect->left / w; - coords[0].y = (float)rect->top / h; - coords[0].z = 0.0f; - - coords[1].x = (float)rect->right / w; - coords[1].y = (float)rect->top / h; - coords[1].z = 0.0f; - - coords[2].x = (float)rect->left / w; - coords[2].y = (float)rect->bottom / h; - coords[2].z = 0.0f; - - coords[3].x = (float)rect->right / w; - coords[3].y = (float)rect->bottom / h; - coords[3].z = 0.0f; - break; - - case GL_TEXTURE_RECTANGLE_ARB: - info->bind_target = GL_TEXTURE_RECTANGLE_ARB; - coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f; - coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f; - coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f; - coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(rect, w, h, &f); - - coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l; - coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r; - coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l; - coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(rect, w, h, &f); - - coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l; - coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r; - coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l; - coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(rect, w, h, &f); - - coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t; - coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t; - coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b; - coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(rect, w, h, &f); - - coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t; - coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t; - coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b; - coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(rect, w, h, &f); - - coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f; - coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f; - coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f; - coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(rect, w, h, &f); - - coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f; - coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f; - coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f; - coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f; - break; - } + return (x != 0) && !(x & (x - 1)); } static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture) @@ -445,7 +294,11 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su if (locations & WINED3D_LOCATION_BUFFER) { data->addr = NULL; +#if !defined(STAGING_CSMT) data->buffer_object = sub_resource->buffer_object; +#else /* STAGING_CSMT */ + data->buffer_object = sub_resource->buffer->name; +#endif /* STAGING_CSMT */ return; } if (locations & WINED3D_LOCATION_USER_MEMORY) @@ -467,8 +320,93 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su data->buffer_object = 0; } +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, DWORD flags, + struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops, + const struct wined3d_resource_ops *resource_ops) +{ + unsigned int i, j, size, offset = 0; + const struct wined3d_format *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, access %s, width %u, height %u, depth %u, " + "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), wined3d_debug_resource_access(desc->access), + desc->width, desc->height, desc->depth, flags, device, parent, parent_ops, resource_ops); + + if (!desc->width || !desc->height || !desc->depth) + return WINED3DERR_INVALIDCALL; + + format = wined3d_get_format(&device->adapter->gl_info, desc->format, desc->usage); + + for (i = 0; i < layer_count; ++i) + { + for (j = 0; j < level_count; ++j) + { + unsigned int idx = i * level_count + j; + + size = wined3d_format_calculate_size(format, device->surface_alignment, + max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j)); + texture->sub_resources[idx].offset = offset; + texture->sub_resources[idx].size = size; + offset += size; + } + offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1); + } + + if (!offset) + return WINED3DERR_INVALIDCALL; + + if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format, + desc->multisample_type, desc->multisample_quality, desc->usage, desc->access, + desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops))) + { + static unsigned int once; + + /* DXTn 3D textures are not supported. Do not write the ERR for them. */ + if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3 + || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5) + && !(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE) + && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++) + ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n"); + + WARN("Failed to initialize resource, returning %#x\n", hr); + return hr; + } + wined3d_resource_update_draw_binding(&texture->resource); + if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE) + texture->resource.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + + texture->texture_ops = texture_ops; + + texture->layer_count = layer_count; + texture->level_count = level_count; + texture->lod = 0; + texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; + if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT) + texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_GET_DC_LENIENT; + if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)) + texture->flags |= WINED3D_TEXTURE_GET_DC; + if (flags & WINED3D_TEXTURE_CREATE_DISCARD) + texture->flags |= WINED3D_TEXTURE_DISCARD; + if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS) + { + if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP)) + WARN("Format doesn't support mipmaps generation, " + "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n"); + else + texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS; + } + + return WINED3D_OK; +} + /* Context activation is done by the caller. */ static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture, +#if !defined(STAGING_CSMT) unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) { GLuint *buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object; @@ -481,6 +419,19 @@ static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER); *buffer_object = 0; +#else /* STAGING_CSMT */ + unsigned int sub_resource_idx, struct wined3d_context *context) +{ + struct wined3d_gl_bo *buffer = texture->sub_resources[sub_resource_idx].buffer; + GLuint name = buffer->name; + + wined3d_device_release_bo(texture->resource.device, buffer, context); + texture->sub_resources[sub_resource_idx].buffer = NULL; + wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER); + + TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n", + name, texture, sub_resource_idx); +#endif /* STAGING_CSMT */ } static void wined3d_texture_update_map_binding(struct wined3d_texture *texture) @@ -500,7 +451,11 @@ static void wined3d_texture_update_map_binding(struct wined3d_texture *texture) && !wined3d_texture_load_location(texture, i, context, map_binding)) ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding)); if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER) +#if !defined(STAGING_CSMT) wined3d_texture_remove_buffer_object(texture, i, context->gl_info); +#else /* STAGING_CSMT */ + wined3d_texture_remove_buffer_object(texture, i, context); +#endif /* STAGING_CSMT */ } if (context) @@ -565,14 +520,11 @@ static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture * const struct wined3d_gl_info *gl_info) { unsigned int level, level_count, layer, layer_count; - GLsizei width, height, depth; + GLsizei width, height; GLenum target; level_count = texture->level_count; - if (texture->target == GL_TEXTURE_1D_ARRAY || texture->target == GL_TEXTURE_2D_ARRAY) - layer_count = 1; - else - layer_count = texture->layer_count; + layer_count = texture->target == GL_TEXTURE_2D_ARRAY ? 1 : texture->layer_count; for (layer = 0; layer < layer_count; ++layer) { @@ -591,24 +543,16 @@ static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture * TRACE("texture %p, layer %u, level %u, target %#x, width %u, height %u.\n", texture, layer, level, target, width, height); - if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY) + if (texture->target == GL_TEXTURE_2D_ARRAY) { - depth = wined3d_texture_get_level_depth(texture, level); GL_EXTCALL(glTexImage3D(target, level, gl_internal_format, width, height, - target == GL_TEXTURE_2D_ARRAY ? texture->layer_count : depth, 0, - format->glFormat, format->glType, NULL)); + texture->layer_count, 0, format->glFormat, format->glType, NULL)); checkGLcall("glTexImage3D"); } - else if (target == GL_TEXTURE_1D) - { - gl_info->gl_ops.gl.p_glTexImage1D(target, level, gl_internal_format, - width, 0, format->glFormat, format->glType, NULL); - } else { - gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format, width, - target == GL_TEXTURE_1D_ARRAY ? texture->layer_count : height, 0, - format->glFormat, format->glType, NULL); + gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format, + width, height, 0, format->glFormat, format->glType, NULL); checkGLcall("glTexImage2D"); } } @@ -626,10 +570,6 @@ static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture switch (texture->target) { - case GL_TEXTURE_3D: - GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count, - gl_internal_format, width, height, wined3d_texture_get_level_depth(texture, 0))); - break; case GL_TEXTURE_2D_ARRAY: GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count, gl_internal_format, width, height, texture->layer_count)); @@ -642,13 +582,6 @@ static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture GL_EXTCALL(glTexStorage3DMultisample(texture->target, samples, gl_internal_format, width, height, texture->layer_count, GL_FALSE)); break; - case GL_TEXTURE_1D_ARRAY: - GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, - gl_internal_format, width, texture->layer_count)); - break; - case GL_TEXTURE_1D: - GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, gl_internal_format, width)); - break; default: GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, gl_internal_format, width, height)); @@ -718,185 +651,56 @@ static void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *text } } -static void wined3d_texture_create_dc(void *object) -{ - const struct wined3d_texture_idx *idx = object; - struct wined3d_context *context = NULL; - unsigned int sub_resource_idx, level; - const struct wined3d_format *format; - unsigned int row_pitch, slice_pitch; - struct wined3d_texture *texture; - struct wined3d_dc_info *dc_info; - struct wined3d_bo_address data; - D3DKMT_CREATEDCFROMMEMORY desc; - struct wined3d_device *device; - NTSTATUS status; - - TRACE("texture %p, sub_resource_idx %u.\n", idx->texture, idx->sub_resource_idx); - - texture = idx->texture; - sub_resource_idx = idx->sub_resource_idx; - level = sub_resource_idx % texture->level_count; - device = texture->resource.device; - - format = texture->resource.format; - if (!format->ddi_format) - { - WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id)); - return; - } - - if (!texture->dc_info) - { - unsigned int sub_count = texture->level_count * texture->layer_count; - - if (!(texture->dc_info = heap_calloc(sub_count, sizeof(*texture->dc_info)))) - { - ERR("Failed to allocate DC info.\n"); - return; - } - } - - if (device->d3d_initialized) - context = context_acquire(device, NULL, 0); - - wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); - wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding); - wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch); - wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); - desc.pMemory = context_map_bo_address(context, &data, - texture->sub_resources[sub_resource_idx].size, - GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ | WINED3D_MAP_WRITE); - - if (context) - context_release(context); - - desc.Format = format->ddi_format; - desc.Width = wined3d_texture_get_level_width(texture, level); - desc.Height = wined3d_texture_get_level_height(texture, level); - desc.Pitch = row_pitch; - desc.hDeviceDc = CreateCompatibleDC(NULL); - desc.pColorTable = NULL; - - status = D3DKMTCreateDCFromMemory(&desc); - DeleteDC(desc.hDeviceDc); - if (status) - { - WARN("Failed to create DC, status %#x.\n", status); - return; - } - - dc_info = &texture->dc_info[sub_resource_idx]; - dc_info->dc = desc.hDc; - dc_info->bitmap = desc.hBitmap; - - TRACE("Created DC %p, bitmap %p for texture %p, %u.\n", dc_info->dc, dc_info->bitmap, texture, sub_resource_idx); -} - -static void wined3d_texture_destroy_dc(void *object) -{ - const struct wined3d_texture_idx *idx = object; - D3DKMT_DESTROYDCFROMMEMORY destroy_desc; - struct wined3d_context *context = NULL; - struct wined3d_texture *texture; - struct wined3d_dc_info *dc_info; - struct wined3d_bo_address data; - unsigned int sub_resource_idx; - struct wined3d_device *device; - NTSTATUS status; - - texture = idx->texture; - sub_resource_idx = idx->sub_resource_idx; - device = texture->resource.device; - dc_info = &texture->dc_info[sub_resource_idx]; - - if (!dc_info->dc) - { - ERR("Sub-resource {%p, %u} has no DC.\n", texture, sub_resource_idx); - return; - } - - TRACE("dc %p, bitmap %p.\n", dc_info->dc, dc_info->bitmap); - - destroy_desc.hDc = dc_info->dc; - destroy_desc.hBitmap = dc_info->bitmap; - if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc))) - ERR("Failed to destroy dc, status %#x.\n", status); - dc_info->dc = NULL; - dc_info->bitmap = NULL; - - if (device->d3d_initialized) - context = context_acquire(device, NULL, 0); - - wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); - context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); - - if (context) - context_release(context); -} - static void wined3d_texture_cleanup(struct wined3d_texture *texture) { unsigned int sub_count = texture->level_count * texture->layer_count; struct wined3d_device *device = texture->resource.device; - struct wined3d_renderbuffer_entry *entry, *entry2; - const struct wined3d_gl_info *gl_info = NULL; struct wined3d_context *context = NULL; - struct wined3d_dc_info *dc_info; +#if !defined(STAGING_CSMT) + const struct wined3d_gl_info *gl_info; GLuint buffer_object; +#else /* STAGING_CSMT */ + struct wined3d_gl_bo *buffer; +#endif /* STAGING_CSMT */ unsigned int i; TRACE("texture %p.\n", texture); for (i = 0; i < sub_count; ++i) { +#if !defined(STAGING_CSMT) if (!(buffer_object = texture->sub_resources[i].buffer_object)) continue; TRACE("Deleting buffer object %u.\n", buffer_object); +#else /* STAGING_CSMT */ + if (!(buffer = texture->sub_resources[i].buffer)) + continue; + + TRACE("Deleting buffer object %u.\n", buffer->name); +#endif /* STAGING_CSMT */ /* We may not be able to get a context in wined3d_texture_cleanup() in * general, but if a buffer object was previously created we can. */ if (!context) +#if !defined(STAGING_CSMT) { context = context_acquire(device, NULL, 0); gl_info = context->gl_info; } GL_EXTCALL(glDeleteBuffers(1, &buffer_object)); - } +#else /* STAGING_CSMT */ + context = context_acquire(device, NULL, 0); - if (!context && !list_empty(&texture->renderbuffers)) - { - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; + wined3d_device_release_bo(device, buffer, context); + texture->sub_resources[i].buffer = NULL; +#endif /* STAGING_CSMT */ } - - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry) - { - TRACE("Deleting renderbuffer %u.\n", entry->id); - context_gl_resource_released(device, entry->id, TRUE); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); - heap_free(entry); - } - if (context) context_release(context); - if ((dc_info = texture->dc_info)) - { - for (i = 0; i < sub_count; ++i) - { - if (dc_info[i].dc) - { - struct wined3d_texture_idx texture_idx = {texture, i}; - - wined3d_texture_destroy_dc(&texture_idx); - } - } - heap_free(dc_info); - } - + texture->texture_ops->texture_cleanup_sub_resources(texture); if (texture->overlay_info) { for (i = 0; i < sub_count; ++i) @@ -1448,87 +1252,105 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture, return WINED3D_OK; } -/* 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. */ -/* Context activation is done by the caller. */ -void wined3d_texture_set_compatible_renderbuffer(struct wined3d_texture *texture, - unsigned int level, const struct wined3d_rendertarget_info *rt) +static void texture2d_create_dc(void *object) { - struct wined3d_renderbuffer_entry *entry; - const struct wined3d_gl_info *gl_info; - unsigned int src_width, src_height; - unsigned int width, height; - GLuint renderbuffer = 0; + struct wined3d_surface *surface = object; + struct wined3d_context *context = NULL; + const struct wined3d_format *format; + unsigned int row_pitch, slice_pitch; + struct wined3d_texture *texture; + struct wined3d_bo_address data; + D3DKMT_CREATEDCFROMMEMORY desc; + unsigned int sub_resource_idx; + struct wined3d_device *device; + NTSTATUS status; - gl_info = &texture->resource.device->adapter->gl_info; - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) - return; + TRACE("surface %p.\n", surface); - if (rt && rt->resource->format->id != WINED3DFMT_NULL) + texture = surface->container; + sub_resource_idx = surface_get_sub_resource_idx(surface); + device = texture->resource.device; + + format = texture->resource.format; + if (!format->ddi_format) { - struct wined3d_texture *rt_texture; - unsigned int rt_level; - - if (rt->resource->type == WINED3D_RTYPE_BUFFER) - { - FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type)); - return; - } - rt_texture = wined3d_texture_from_resource(rt->resource); - rt_level = rt->sub_resource_idx % rt_texture->level_count; - - width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level); - height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level); - } - else - { - width = wined3d_texture_get_level_pow2_width(texture, level); - height = wined3d_texture_get_level_pow2_height(texture, level); - } - - src_width = wined3d_texture_get_level_pow2_width(texture, level); - src_height = wined3d_texture_get_level_pow2_height(texture, level); - - /* A depth stencil smaller than the render target is not valid */ - if (width > src_width || height > src_height) - return; - - /* Remove any renderbuffer set if the sizes match */ - if (width == src_width && height == src_height) - { - texture->current_renderbuffer = NULL; + WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id)); return; } - /* Look if we've already got a renderbuffer of the correct dimensions */ - LIST_FOR_EACH_ENTRY(entry, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry) + if (device->d3d_initialized) + context = context_acquire(device, NULL, 0); + + wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); + wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding); + wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch); + wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + desc.pMemory = context_map_bo_address(context, &data, + texture->sub_resources[sub_resource_idx].size, + GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ | WINED3D_MAP_WRITE); + + if (context) + context_release(context); + + desc.Format = format->ddi_format; + desc.Width = wined3d_texture_get_level_width(texture, surface->texture_level); + desc.Height = wined3d_texture_get_level_height(texture, surface->texture_level); + desc.Pitch = row_pitch; + desc.hDeviceDc = CreateCompatibleDC(NULL); + desc.pColorTable = NULL; + + status = D3DKMTCreateDCFromMemory(&desc); + DeleteDC(desc.hDeviceDc); + if (status) { - if (entry->width == width && entry->height == height) - { - renderbuffer = entry->id; - texture->current_renderbuffer = entry; - break; - } + WARN("Failed to create DC, status %#x.\n", status); + return; } - if (!renderbuffer) + surface->dc = desc.hDc; + surface->bitmap = desc.hBitmap; + + TRACE("Created DC %p, bitmap %p for surface %p.\n", surface->dc, surface->bitmap, surface); +} + +static void texture2d_destroy_dc(void *object) +{ + struct wined3d_surface *surface = object; + D3DKMT_DESTROYDCFROMMEMORY destroy_desc; + struct wined3d_context *context = NULL; + struct wined3d_texture *texture; + struct wined3d_bo_address data; + unsigned int sub_resource_idx; + struct wined3d_device *device; + NTSTATUS status; + + texture = surface->container; + sub_resource_idx = surface_get_sub_resource_idx(surface); + device = texture->resource.device; + + if (!surface->dc) { - gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer); - gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, - texture->resource.format->glInternal, width, height); - - entry = heap_alloc(sizeof(*entry)); - entry->width = width; - entry->height = height; - entry->id = renderbuffer; - list_add_head(&texture->renderbuffers, &entry->entry); - - texture->current_renderbuffer = entry; + ERR("Surface %p has no DC.\n", surface); + return; } - checkGLcall("set_compatible_renderbuffer"); + TRACE("dc %p, bitmap %p.\n", surface->dc, surface->bitmap); + + destroy_desc.hDc = surface->dc; + destroy_desc.hBitmap = surface->bitmap; + if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc))) + ERR("Failed to destroy dc, status %#x.\n", status); + surface->dc = NULL; + surface->bitmap = NULL; + + if (device->d3d_initialized) + context = context_acquire(device, NULL, 0); + + wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + + if (context) + context_release(context); } HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height, @@ -1540,6 +1362,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, texture->resource.usage); UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1); struct wined3d_texture_sub_resource *sub_resource; + struct wined3d_surface *surface; DWORD valid_location = 0; BOOL create_dib = FALSE; @@ -1562,6 +1385,12 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT return WINED3DERR_INVALIDCALL; } + if (texture->resource.type == WINED3D_RTYPE_TEXTURE_1D) + { + FIXME("Not yet supported for 1D textures.\n"); + return WINED3DERR_INVALIDCALL; + } + if (texture->resource.map_count) { WARN("Texture is mapped.\n"); @@ -1586,11 +1415,10 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT wined3d_resource_wait_idle(&texture->resource); sub_resource = &texture->sub_resources[0]; - if (texture->dc_info && texture->dc_info[0].dc) + surface = sub_resource->u.surface; + if (surface->dc) { - struct wined3d_texture_idx texture_idx = {texture, 0}; - - wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx); + wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface); device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); create_dib = TRUE; } @@ -1618,7 +1446,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT else texture->target = GL_TEXTURE_2D; - if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] + if ((!is_power_of_two(width) || !is_power_of_two(height)) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) { texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; @@ -1658,9 +1486,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT if (create_dib) { - struct wined3d_texture_idx texture_idx = {texture, 0}; - - wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx); + wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); } @@ -1669,11 +1495,16 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT /* Context activation is done by the caller. */ static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture, +#if !defined(STAGING_CSMT) unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) +#else /* STAGING_CSMT */ + unsigned int sub_resource_idx, struct wined3d_context *context) +#endif /* STAGING_CSMT */ { struct wined3d_texture_sub_resource *sub_resource; sub_resource = &texture->sub_resources[sub_resource_idx]; +#if !defined(STAGING_CSMT) if (sub_resource->buffer_object) return; @@ -1685,6 +1516,16 @@ static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *textur TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", sub_resource->buffer_object, texture, sub_resource_idx); +#else /* STAGING_CSMT */ + if (sub_resource->buffer) + return; + + sub_resource->buffer = wined3d_device_get_bo(texture->resource.device, + sub_resource->size, GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); + + TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", + sub_resource->buffer->name, texture, sub_resource_idx); +#endif /* STAGING_CSMT */ } static void wined3d_texture_force_reload(struct wined3d_texture *texture) @@ -1702,17 +1543,10 @@ static void wined3d_texture_force_reload(struct wined3d_texture *texture) } } -/* Context activation is done by the caller. */ 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; - const struct wined3d_format *format = texture->resource.format; const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_color_key_conversion *conversion; - GLenum internal; - - TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id)); if (!d3d_info->shader_color_key && !(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY) @@ -1727,36 +1561,7 @@ void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct win if (texture->flags & alloc_flag) return; - if (format->conv_byte_count) - { - 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, texture->resource.usage); - 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); - - if (wined3d_texture_use_immutable_storage(texture, gl_info)) - wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info); - else - wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info); + texture->texture_ops->texture_prepare_texture(texture, context, srgb); texture->flags |= alloc_flag; } @@ -1807,7 +1612,10 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned return TRUE; if (!wined3d_resource_allocate_sysmem(&texture->resource)) + { + ERR("Failed to allocate system memory.\n"); return FALSE; + } return TRUE; case WINED3D_LOCATION_USER_MEMORY: @@ -1816,7 +1624,11 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned return TRUE; case WINED3D_LOCATION_BUFFER: +#if !defined(STAGING_CSMT) wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context->gl_info); +#else /* STAGING_CSMT */ + wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context); +#endif /* STAGING_CSMT */ return TRUE; case WINED3D_LOCATION_TEXTURE_RGB: @@ -1881,260 +1693,518 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, return WINED3D_OK; } +void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) +{ + texture->texture_ops->texture_upload_data(texture, sub_resource_idx, + context, box, data, row_pitch, slice_pitch); +} + + /* This call just uploads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box, - const struct wined3d_const_bo_address *data, unsigned int src_row_pitch, unsigned int src_slice_pitch, - unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb) +static void texture1d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, const struct wined3d_const_bo_address *data, + unsigned int row_pitch, unsigned int slice_pitch) { + struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; + const struct wined3d_format *format = texture->resource.format; + unsigned int level = sub_resource_idx % texture->level_count; const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int update_w = src_box->right - src_box->left; - unsigned int update_h = src_box->bottom - src_box->top; - unsigned int update_d = src_box->back - src_box->front; - struct wined3d_bo_address bo; + const void *mem = data->addr; void *converted_mem = NULL; - struct wined3d_format f; - unsigned int level; + unsigned int width, x, update_w; GLenum target; - TRACE("texture %p, sub_resource_idx %u, context %p, format %s, src_box %s, data {%#x:%p}, " - "src_row_pitch %#x, src_slice_pitch %#x, dst_x %u, dst_y %u, dst_z %u, srgb %#x.\n", - texture, sub_resource_idx, context, debug_d3dformat(format->id), debug_box(src_box), - data->buffer_object, data->addr, src_row_pitch, src_slice_pitch, dst_x, dst_y, dst_z, srgb); + TRACE("texture %p, sub_resource_idx %u, context %p, box %p, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n", + texture, sub_resource_idx, context, box, data->buffer_object, data->addr, row_pitch, slice_pitch); - if (texture->sub_resources[sub_resource_idx].map_count) + width = wined3d_texture_get_level_width(texture, level); + + if (!box) { - WARN("Uploading a texture that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n"); - texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM; - } - - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) - { - update_h *= format->height_scale.numerator; - update_h /= format->height_scale.denominator; - } - - target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - level = sub_resource_idx % texture->level_count; - - switch (target) - { - case GL_TEXTURE_1D_ARRAY: - dst_y = sub_resource_idx / texture->level_count; - update_h = 1; - break; - case GL_TEXTURE_2D_ARRAY: - dst_z = sub_resource_idx / texture->level_count; - update_d = 1; - break; - case GL_TEXTURE_2D_MULTISAMPLE: - case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - FIXME("Not supported for multisample textures.\n"); - return; - } - - bo.buffer_object = data->buffer_object; - bo.addr = (BYTE *)data->addr + src_box->front * src_slice_pitch; - if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) - { - bo.addr += (src_box->top / format->block_height) * src_row_pitch; - bo.addr += (src_box->left / format->block_width) * format->block_byte_count; + x = 0; + update_w = width; } else { - bo.addr += src_box->top * src_row_pitch; - bo.addr += src_box->left * format->byte_count; + x = box->left; + update_w = box->right - box->left; } if (format->upload) { - unsigned int dst_row_pitch, dst_slice_pitch; - void *src_mem; + unsigned int dst_row_pitch; + if (data->buffer_object) + ERR("Loading a converted texture from a PBO.\n"); if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) ERR("Converting a block-based format.\n"); - f = *format; - f.byte_count = format->conv_byte_count; - format = &f; + dst_row_pitch = update_w * format->conv_byte_count; - wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch); - - if (!(converted_mem = heap_calloc(update_d, dst_slice_pitch))) - { - ERR("Failed to allocate upload buffer.\n"); - return; - } - - src_mem = context_map_bo_address(context, &bo, src_slice_pitch, - GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ); - format->upload(src_mem, converted_mem, src_row_pitch, src_slice_pitch, - dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d); - context_unmap_bo_address(context, &bo, GL_PIXEL_UNPACK_BUFFER); - - bo.buffer_object = 0; - bo.addr = converted_mem; - src_row_pitch = dst_row_pitch; - src_slice_pitch = dst_slice_pitch; + converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_row_pitch); + format->upload(data->addr, converted_mem, row_pitch, slice_pitch, dst_row_pitch, dst_row_pitch, update_w, 1, 1); + mem = converted_mem; } - if (bo.buffer_object) + if (data->buffer_object) { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bo.buffer_object)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); checkGLcall("glBindBuffer"); } - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); + if (target == GL_TEXTURE_1D_ARRAY) { - unsigned int dst_row_pitch, dst_slice_pitch; - const BYTE *addr = bo.addr; - GLenum internal; + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, row_pitch / format->byte_count); - 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; + gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, x, surface->texture_layer, update_w, 1, format->glFormat, format->glType, mem); + checkGLcall("glTexSubImage2D"); - wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch); - - TRACE("Uploading compressed data, target %#x, level %u, x %u, y %u, z %u, " - "w %u, h %u, d %u, format %#x, image_size %#x, addr %p.\n", - target, level, dst_x, dst_y, dst_z, update_w, update_h, - update_d, internal, dst_slice_pitch, addr); - - if (target == GL_TEXTURE_1D) - { - GL_EXTCALL(glCompressedTexSubImage1D(target, level, dst_x, - update_w, internal, dst_row_pitch, addr)); - } - else if (dst_row_pitch == src_row_pitch) - { - if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D) - { - GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_x, dst_y, dst_z, - update_w, update_h, update_d, internal, dst_slice_pitch * update_d, addr)); - } - else - { - GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_x, dst_y, - update_w, update_h, internal, dst_slice_pitch, addr)); - } - } - else - { - unsigned int row_count = (update_h + format->block_height - 1) / format->block_height; - unsigned int row, y, z; - - /* glCompressedTexSubImage2D() ignores pixel store state, so we - * can't use the unpack row length like for glTexSubImage2D. */ - for (z = dst_z; z < dst_z + update_d; ++z) - { - for (row = 0, y = dst_y; row < row_count; ++row) - { - if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D) - { - GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_x, y, z, - update_w, format->block_height, 1, internal, dst_row_pitch, addr)); - } - else - { - GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_x, y, - update_w, format->block_height, internal, dst_row_pitch, addr)); - } - - y += format->block_height; - addr += src_row_pitch; - } - } - } - checkGLcall("Upload compressed texture data"); + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else { - TRACE("Uploading data, target %#x, level %u, x %u, y %u, z %u, " - "w %u, h %u, d %u, format %#x, type %#x, addr %p.\n", - target, level, dst_x, dst_y, dst_z, update_w, update_h, - update_d, format->glFormat, format->glType, bo.addr); - - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_row_pitch / format->byte_count); - if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D) - { - GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y, dst_z, - update_w, update_h, update_d, format->glFormat, format->glType, bo.addr)); - } - else if (target == GL_TEXTURE_1D) - { - gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, dst_x, - update_w, format->glFormat, format->glType, bo.addr); - } - else - { - gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y, - update_w, update_h, format->glFormat, format->glType, bo.addr); - } - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - checkGLcall("Upload texture data"); + gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, x, update_w, format->glFormat, format->glType, mem); + checkGLcall("glTexSubImage1D"); } - if (bo.buffer_object) + if (data->buffer_object) { GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("glBindBuffer"); } - heap_free(converted_mem); - if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) + HeapFree(GetProcessHeap(), 0, converted_mem); +} + +/* Context activation is done by the caller. */ +static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_bo_address *data) +{ + struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; + const struct wined3d_format *format = texture->resource.format; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_texture_sub_resource *sub_resource; + BYTE *temporary_mem = NULL; + void *mem; + GLenum target; + + sub_resource = &texture->sub_resources[sub_resource_idx]; + + if (format->conv_byte_count) + { + FIXME("Attempting to download a converted 1d texture, format %s.\n", + debug_d3dformat(format->id)); + return; + } + + target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); + if (target == GL_TEXTURE_1D_ARRAY) + { + WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n"); + + if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size))) + { + ERR("Out of memory.\n"); + return; + } + + mem = temporary_mem; + } + else if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + mem = data->addr; + } + else + mem = data->addr; + + gl_info->gl_ops.gl.p_glGetTexImage(target, sub_resource_idx, + format->glFormat, format->glType, mem); + checkGLcall("glGetTexImage"); + + if (temporary_mem) + { + void *src_data = temporary_mem + surface->texture_layer * sub_resource->size; + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + GL_EXTCALL(glBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, src_data)); + checkGLcall("glBufferSubData"); + } + else + { + memcpy(data->addr, src_data, sub_resource->size); + } + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + HeapFree(GetProcessHeap(), 0, temporary_mem); +} + +/* Context activation is done by the caller. */ +static void texture1d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, BOOL dest_is_srgb) +{ + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + unsigned int row_pitch, slice_pitch; + struct wined3d_bo_address data; + + WARN_(d3d_perf)("Performing slow rgb/srgb 1d texture transfer.\n"); + data.buffer_object = 0; + if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size))) + return; + + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb); + texture1d_download_data(texture, sub_resource_idx, context, &data); + wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb); + texture1d_upload_data(texture, sub_resource_idx, context, NULL, + wined3d_const_bo_address(&data), row_pitch, slice_pitch); + + HeapFree(GetProcessHeap(), 0, data.addr); +} + +/* Context activation is done by the caller. */ +static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) +{ + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + DWORD required_access = wined3d_resource_access_from_location(location); + unsigned int row_pitch, slice_pitch; + + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + TRACE("Current resource location %s.\n", wined3d_debug_location(sub_resource->locations)); + + if ((sub_resource->locations & location) == location) + { + TRACE("Location(s) already up to date.\n"); + return TRUE; + } + + if ((texture->resource.access & required_access) != required_access) + { + ERR("Operation requires %#x access, but 1d texture only has %#x.\n", + required_access, texture->resource.access); + return FALSE; + } + + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) + return FALSE; + + if (sub_resource->locations & WINED3D_LOCATION_DISCARDED) + { + TRACE("1d texture previously discarded, nothing to do.\n"); + wined3d_texture_validate_location(texture, sub_resource_idx, location); + wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED); + goto done; + } + + switch (location) + { + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: + if (sub_resource->locations & WINED3D_LOCATION_SYSMEM) + { + struct wined3d_const_bo_address data = {0, texture->resource.heap_memory}; + data.addr += sub_resource->offset; + wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); + } + else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) + { +#if !defined(STAGING_CSMT) + struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; +#else /* STAGING_CSMT */ + struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL}; +#endif /* STAGING_CSMT */ + wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); + } + else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + { + texture1d_srgb_transfer(texture, sub_resource_idx, context, TRUE); + } + else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB) + { + texture1d_srgb_transfer(texture, sub_resource_idx, context, FALSE); + } + else + { + FIXME("Implement 1d texture loading from %s.\n", wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; + + case WINED3D_LOCATION_SYSMEM: + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { + struct wined3d_bo_address data = {0, texture->resource.heap_memory}; + + data.addr += sub_resource->offset; + if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + else + wined3d_texture_bind_and_dirtify(texture, context, TRUE); + + texture1d_download_data(texture, sub_resource_idx, context, &data); + ++texture->download_count; + } + else + { + FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; + + case WINED3D_LOCATION_BUFFER: + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { +#if !defined(STAGING_CSMT) + struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; +#else /* STAGING_CSMT */ + struct wined3d_bo_address data = {sub_resource->buffer->name, NULL}; +#endif /* STAGING_CSMT */ + + if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + else + wined3d_texture_bind_and_dirtify(texture, context, TRUE); + + texture1d_download_data(texture, sub_resource_idx, context, &data); + } + else + { + FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; + + default: + FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + +done: + wined3d_texture_validate_location(texture, sub_resource_idx, location); + + return TRUE; +} + +static void texture1d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) +{ + const struct wined3d_format *format = texture->resource.format; + unsigned int sub_count = texture->level_count * texture->layer_count; + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int width; + GLenum internal; + + 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 (wined3d_texture_use_immutable_storage(texture, gl_info)) + { + width = wined3d_texture_get_level_width(texture, 0); + + if (texture->target == GL_TEXTURE_1D_ARRAY) + { + GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, internal, width, texture->layer_count)); + checkGLcall("glTexStorage2D"); + } + else + { + GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, internal, width)); + checkGLcall("glTexStorage1D"); + } + } + else { - struct wined3d_device *device = texture->resource.device; unsigned int i; - for (i = 0; i < device->context_count; ++i) + for (i = 0; i < sub_count; ++i) { - context_texture_update(device->contexts[i], texture); + GLenum target; + struct wined3d_surface *surface = texture->sub_resources[i].u.surface; + width = wined3d_texture_get_level_width(texture, surface->texture_level); + target = wined3d_texture_get_sub_resource_target(texture, i); + + if (texture->target == GL_TEXTURE_1D_ARRAY) + { + gl_info->gl_ops.gl.p_glTexImage2D(target, surface->texture_level, + internal, width, texture->layer_count, 0, format->glFormat, format->glType, NULL); + checkGLcall("glTexImage2D"); + } + else + { + gl_info->gl_ops.gl.p_glTexImage1D(target, surface->texture_level, + internal, width, 0, format->glFormat, format->glType, NULL); + checkGLcall("glTexImage1D"); + } } } } -/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */ +static void texture1d_cleanup_sub_resources(struct wined3d_texture *texture) +{ +} + +static const struct wined3d_texture_ops texture1d_ops = +{ + texture1d_upload_data, + texture1d_load_location, + texture1d_prepare_texture, + texture1d_cleanup_sub_resources, +}; + +static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) +{ + unsigned int texture_level; + POINT dst_point; + RECT src_rect; + + src_rect.left = 0; + src_rect.top = 0; + if (box) + { + dst_point.x = box->left; + dst_point.y = box->top; + src_rect.right = box->right - box->left; + src_rect.bottom = box->bottom - box->top; + } + else + { + dst_point.x = dst_point.y = 0; + texture_level = sub_resource_idx % texture->level_count; + src_rect.right = wined3d_texture_get_level_width(texture, texture_level); + src_rect.bottom = wined3d_texture_get_level_height(texture, texture_level); + } + + wined3d_surface_upload_data(texture->sub_resources[sub_resource_idx].u.surface, context->gl_info, + texture->resource.format, &src_rect, row_pitch, &dst_point, FALSE, data); +} + static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) { - TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", - texture, sub_resource_idx, context, wined3d_debug_location(location)); + return surface_load_location(texture->sub_resources[sub_resource_idx].u.surface, context, location); +} - switch (location) +/* Context activation is done by the caller. */ +static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) +{ + 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; + + TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id)); + + if (format->conv_byte_count) { - case WINED3D_LOCATION_USER_MEMORY: - case WINED3D_LOCATION_SYSMEM: - case WINED3D_LOCATION_BUFFER: - return texture2d_load_sysmem(texture, sub_resource_idx, context, location); - - case WINED3D_LOCATION_DRAWABLE: - return texture2d_load_drawable(texture, sub_resource_idx, context); - - case WINED3D_LOCATION_RB_RESOLVED: - case WINED3D_LOCATION_RB_MULTISAMPLE: - return texture2d_load_renderbuffer(texture, sub_resource_idx, context, location); - - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - return texture2d_load_texture(texture, sub_resource_idx, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - - default: - ERR("Don't know how to handle location %#x.\n", location); - return FALSE; + 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, texture->resource.usage); + 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); + + if (wined3d_texture_use_immutable_storage(texture, gl_info)) + wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info); + else + wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info); +} + +static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture) +{ + unsigned int sub_count = texture->level_count * texture->layer_count; + struct wined3d_device *device = texture->resource.device; + struct wined3d_texture_sub_resource *sub_resource; + struct wined3d_renderbuffer_entry *entry, *entry2; + const struct wined3d_gl_info *gl_info = NULL; + struct wined3d_context *context = NULL; + struct wined3d_surface *surface; + unsigned int i; + + for (i = 0; i < sub_count; ++i) + { + sub_resource = &texture->sub_resources[i]; + if (!(surface = sub_resource->u.surface)) + continue; + + TRACE("surface %p.\n", surface); + + if (!context && !list_empty(&surface->renderbuffers)) + { + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + } + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) + { + TRACE("Deleting renderbuffer %u.\n", entry->id); + context_gl_resource_released(device, entry->id, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); + heap_free(entry); + } + + if (surface->dc) + texture2d_destroy_dc(surface); + } + if (context) + context_release(context); + heap_free(texture->sub_resources[0].u.surface); } static const struct wined3d_texture_ops texture2d_ops = { + texture2d_upload_data, texture2d_load_location, + texture2d_prepare_texture, + texture2d_cleanup_sub_resources, }; struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource) @@ -2166,7 +2236,6 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) { struct wined3d_texture *texture = texture_from_resource(resource); UINT sub_count = texture->level_count * texture->layer_count; - struct wined3d_renderbuffer_entry *entry, *entry2; struct wined3d_device *device = resource->device; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; @@ -2199,19 +2268,30 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED); } +#if !defined(STAGING_CSMT) if (sub_resource->buffer_object) wined3d_texture_remove_buffer_object(texture, i, context->gl_info); - } +#else /* STAGING_CSMT */ + if (sub_resource->buffer) + wined3d_texture_remove_buffer_object(texture, i, context); +#endif /* STAGING_CSMT */ - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry) - { - context_gl_resource_released(device, entry->id, TRUE); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); - list_remove(&entry->entry); - heap_free(entry); + if (resource->type == WINED3D_RTYPE_TEXTURE_2D) + { + struct wined3d_surface *surface = sub_resource->u.surface; + struct wined3d_renderbuffer_entry *entry, *entry2; + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) + { + context_gl_resource_released(device, entry->id, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); + list_remove(&entry->entry); + heap_free(entry); + } + list_init(&surface->renderbuffers); + surface->current_renderbuffer = NULL; + } } - list_init(&texture->renderbuffers); - texture->current_renderbuffer = NULL; context_release(context); @@ -2435,179 +2515,140 @@ static const struct wined3d_resource_ops texture_resource_ops = texture_resource_sub_resource_unmap, }; -/* Context activation is done by the caller. */ -static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_bo_address *data) -{ - const struct wined3d_format *format = texture->resource.format; - const struct wined3d_gl_info *gl_info = context->gl_info; - - if (format->conv_byte_count) - { - FIXME("Attempting to download a converted texture, format %s.\n", - debug_d3dformat(format->id)); - return; - } - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); - checkGLcall("glBindBuffer"); - } - - gl_info->gl_ops.gl.p_glGetTexImage(texture->target, sub_resource_idx, - format->glFormat, format->glType, data->addr); - checkGLcall("glGetTexImage"); - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } -} - -/* Context activation is done by the caller. */ -static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD location) -{ - struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; - unsigned int row_pitch, slice_pitch; - - TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", - texture, sub_resource_idx, context, wined3d_debug_location(location)); - - if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) - return FALSE; - - switch (location) - { - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - if (sub_resource->locations & WINED3D_LOCATION_SYSMEM) - { - struct wined3d_const_bo_address data = {0, texture->resource.heap_memory}; - struct wined3d_box src_box; - - data.addr += sub_resource->offset; - wined3d_texture_bind_and_dirtify(texture, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box); - wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format, - &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE); - } - else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) - { - struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; - struct wined3d_box src_box; - - wined3d_texture_bind_and_dirtify(texture, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box); - wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format, - &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE); - } - else - { - FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; - - case WINED3D_LOCATION_SYSMEM: - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {0, texture->resource.heap_memory}; - - data.addr += sub_resource->offset; - if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - else - wined3d_texture_bind_and_dirtify(texture, context, TRUE); - - texture1d_download_data(texture, sub_resource_idx, context, &data); - ++texture->download_count; - } - else - { - FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; - - case WINED3D_LOCATION_BUFFER: - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; - - if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - else - wined3d_texture_bind_and_dirtify(texture, context, TRUE); - - texture1d_download_data(texture, sub_resource_idx, context, &data); - } - else - { - FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; - - default: - FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - - return TRUE; -} - -static const struct wined3d_texture_ops texture1d_ops = -{ - texture1d_load_location, -}; - -static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, - unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device, - void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_texture_ops *texture_ops) +static HRESULT texture1d_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, + UINT layer_count, UINT level_count, struct wined3d_device *device, void *parent, + const struct wined3d_parent_ops *parent_ops) { struct wined3d_device_parent *device_parent = device->device_parent; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - unsigned int sub_count, i, j, size, offset = 0; - unsigned int pow2_width, pow2_height; - const struct wined3d_format *format; + struct wined3d_surface *surfaces; + unsigned int i, j; HRESULT hr; - TRACE("texture %p, resource_type %s, format %s, multisample_type %#x, multisample_quality %#x, " - "usage %s, access %s, width %u, height %u, depth %u, layer_count %u, level_count %u, " - "flags %#x, device %p, parent %p, parent_ops %p, texture_ops %p.\n", - texture, debug_d3dresourcetype(desc->resource_type), debug_d3dformat(desc->format), - desc->multisample_type, desc->multisample_quality, debug_d3dusage(desc->usage), - wined3d_debug_resource_access(desc->access), desc->width, desc->height, desc->depth, - layer_count, level_count, flags, device, parent, parent_ops, texture_ops); - - if (!desc->width || !desc->height || !desc->depth) - return WINED3DERR_INVALIDCALL; - - if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D) + if (layer_count > 1 && !gl_info->supported[EXT_TEXTURE_ARRAY]) { - if (layer_count != 1) - { - ERR("Invalid layer count for volume texture.\n"); - return E_INVALIDARG; - } + WARN("OpenGL implementation does not support array textures.\n"); + return WINED3DERR_INVALIDCALL; + } - if (!gl_info->supported[EXT_TEXTURE3D]) + /* TODO: It should only be possible to create textures for formats + * that are reported as supported. */ + if (WINED3DFMT_UNKNOWN >= desc->format) + { + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); + return WINED3DERR_INVALIDCALL; + } + + if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) + { + WARN("1d textures can not be used for cube mapping, returning D3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + } + + if ((desc->usage & WINED3DUSAGE_DYNAMIC && wined3d_resource_access_is_managed(desc->access)) + || (desc->usage & WINED3DUSAGE_SCRATCH)) + { + WARN("Attempted to create a DYNAMIC texture in pool %s.\n", wined3d_debug_resource_access(desc->access)); + return WINED3DERR_INVALIDCALL; + } + + if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && !is_power_of_two(desc->width)) + { + if (desc->usage & WINED3DUSAGE_SCRATCH) { - WARN("OpenGL implementation does not support 3D textures.\n"); + WARN("Creating a scratch NPOT 1d texture despite lack of HW support.\n"); + } + else + { + WARN("Attempted to create a NPOT 1d texture (%u, %u, %u) without GL support.\n", + desc->width, desc->height, desc->depth); return WINED3DERR_INVALIDCALL; } } + if (desc->usage & WINED3DUSAGE_QUERY_GENMIPMAP) + { + if (level_count != 1) + { + WARN("WINED3DUSAGE_QUERY_GENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + } + } + + if (FAILED(hr = wined3d_texture_init(texture, &texture1d_ops, layer_count, level_count, desc, + 0, device, parent, parent_ops, &texture_resource_ops))) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); + return hr; + } + + texture->pow2_matrix[0] = 1.0f; + texture->pow2_matrix[5] = 1.0f; + texture->pow2_matrix[10] = 1.0f; + texture->pow2_matrix[15] = 1.0f; + texture->target = (layer_count > 1) ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D; + + if (wined3d_texture_use_pbo(texture, gl_info)) + { + wined3d_resource_free_sysmem(&texture->resource); + texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + } + + if (level_count > ~(SIZE_T)0 / layer_count + || !(surfaces = heap_calloc(level_count * layer_count, sizeof(*surfaces)))) + { + wined3d_texture_cleanup_sync(texture); + return E_OUTOFMEMORY; + } + + /* Generate all the surfaces. */ + for (i = 0; i < texture->level_count; ++i) + { + for (j = 0; j < texture->layer_count; ++j) + { + struct wined3d_texture_sub_resource *sub_resource; + unsigned int idx = j * texture->level_count + i; + struct wined3d_surface *surface; + + surface = &surfaces[idx]; + surface->container = texture; + surface->texture_level = i; + surface->texture_layer = j; + list_init(&surface->renderbuffers); + + sub_resource = &texture->sub_resources[idx]; + sub_resource->locations = WINED3D_LOCATION_DISCARDED; + sub_resource->u.surface = surface; + + if (FAILED(hr = device_parent->ops->surface_created(device_parent, + texture, idx, &sub_resource->parent, &sub_resource->parent_ops))) + { + WARN("Failed to create texture1d parent, hr %#x.\n", hr); + sub_resource->parent = NULL; + wined3d_texture_cleanup_sync(texture); + return hr; + } + + TRACE("parent %p, parent_ops %p.\n", parent, parent_ops); + + TRACE("Created 1d texture surface level %u, layer %u @ %p.\n", i, j, surface); + } + } + + return WINED3D_OK; +} + +static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, + unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + struct wined3d_device_parent *device_parent = device->device_parent; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_surface *surfaces; + UINT pow2_width, pow2_height; + unsigned int i, j, sub_count; + HRESULT hr; + if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1 && !gl_info->supported[EXT_TEXTURE_ARRAY]) { @@ -2619,18 +2660,12 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc * that are reported as supported. */ if (WINED3DFMT_UNKNOWN >= desc->format) { - WARN("Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access) - || desc->usage & WINED3DUSAGE_SCRATCH)) - { - WARN("Attempted to create a dynamic texture with access %s and usage %s.\n", - wined3d_debug_resource_access(desc->access), debug_d3dusage(desc->usage)); + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); return WINED3DERR_INVALIDCALL; } + if (desc->usage & WINED3DUSAGE_DYNAMIC && wined3d_resource_access_is_managed(desc->access)) + FIXME("Trying to create a managed texture with dynamic usage.\n"); if (!(desc->usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)) && (flags & WINED3D_TEXTURE_CREATE_MAPPABLE)) WARN("Creating a mappable texture that doesn't specify dynamic usage.\n"); @@ -2639,16 +2674,15 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc pow2_width = desc->width; pow2_height = desc->height; - if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1)) || (desc->depth & (desc->depth - 1))) + if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) { /* level_count == 0 returns an error as well. */ - if (level_count != 1 || layer_count != 1 || desc->resource_type == WINED3D_RTYPE_TEXTURE_3D) + if (level_count != 1 || layer_count != 1) { if (!(desc->usage & WINED3DUSAGE_SCRATCH)) { - WARN("Attempted to create a mipmapped/cube/array/volume NPOT " - "texture without unconditional NPOT support.\n"); + WARN("Attempted to create a mipmapped/cube/array NPOT texture without unconditional NPOT support.\n"); return WINED3DERR_INVALIDCALL; } @@ -2656,8 +2690,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc } texture->flags |= WINED3D_TEXTURE_COND_NP2; - if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !gl_info->supported[ARB_TEXTURE_RECTANGLE] - && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) + if (!gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) { const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format, desc->usage); @@ -2705,107 +2738,12 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height); } - format = wined3d_get_format(&device->adapter->gl_info, desc->format, desc->usage); - for (i = 0; i < layer_count; ++i) + if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, + flags, device, parent, parent_ops, &texture_resource_ops))) { - for (j = 0; j < level_count; ++j) - { - unsigned int idx = i * level_count + j; - - size = wined3d_format_calculate_size(format, device->surface_alignment, - max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j)); - texture->sub_resources[idx].offset = offset; - texture->sub_resources[idx].size = size; - offset += size; - } - offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1); - } - - if (!offset) - return WINED3DERR_INVALIDCALL; - - if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format, - desc->multisample_type, desc->multisample_quality, desc->usage, desc->access, - desc->width, desc->height, desc->depth, offset, parent, parent_ops, &texture_resource_ops))) - { - static unsigned int once; - - /* DXTn 3D textures are not supported. Do not write the ERR for them. */ - if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3 - || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5) - && !(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE) - && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++) - ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n"); - - WARN("Failed to initialize resource, returning %#x\n", hr); + WARN("Failed to initialize texture, returning %#x.\n", hr); return hr; } - wined3d_resource_update_draw_binding(&texture->resource); - if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE) - texture->resource.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; - - texture->texture_ops = texture_ops; - - texture->layer_count = layer_count; - texture->level_count = level_count; - texture->lod = 0; - texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; - if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT) - texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_GET_DC_LENIENT; - if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)) - texture->flags |= WINED3D_TEXTURE_GET_DC; - if (flags & WINED3D_TEXTURE_CREATE_DISCARD) - texture->flags |= WINED3D_TEXTURE_DISCARD; - if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS) - { - if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP)) - WARN("Format doesn't support mipmaps generation, " - "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n"); - else - texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS; - } - - list_init(&texture->renderbuffers); - - switch (desc->resource_type) - { - case WINED3D_RTYPE_TEXTURE_1D: - if (layer_count > 1) - texture->target = GL_TEXTURE_1D_ARRAY; - else - texture->target = GL_TEXTURE_1D; - break; - - case WINED3D_RTYPE_TEXTURE_2D: - if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) - { - texture->target = GL_TEXTURE_CUBE_MAP_ARB; - } - else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) - { - if (layer_count > 1) - texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; - else - texture->target = GL_TEXTURE_2D_MULTISAMPLE; - } - else - { - if (layer_count > 1) - texture->target = GL_TEXTURE_2D_ARRAY; - else - texture->target = GL_TEXTURE_2D; - } - break; - - case WINED3D_RTYPE_TEXTURE_3D: - texture->target = GL_TEXTURE_3D; - break; - - default: - ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type)); - wined3d_texture_cleanup_sync(texture); - return WINED3DERR_INVALIDCALL; - } /* Precalculated scaling for 'faked' non power of two texture coords. */ if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT) @@ -2815,16 +2753,37 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS); texture->target = GL_TEXTURE_RECTANGLE_ARB; } - else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) - { - texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width)); - texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height)); - texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT; - } else { - texture->pow2_matrix[0] = 1.0f; - texture->pow2_matrix[5] = 1.0f; + if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + { + texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width)); + texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height)); + texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT; + } + else + { + texture->pow2_matrix[0] = 1.0f; + texture->pow2_matrix[5] = 1.0f; + } + if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) + { + texture->target = GL_TEXTURE_CUBE_MAP_ARB; + } + else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) + { + if (layer_count > 1) + texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; + else + texture->target = GL_TEXTURE_2D_MULTISAMPLE; + } + else + { + if (layer_count > 1) + texture->target = GL_TEXTURE_2D_ARRAY; + else + texture->target = GL_TEXTURE_2D; + } } texture->pow2_matrix[10] = 1.0f; texture->pow2_matrix[15] = 1.0f; @@ -2833,19 +2792,9 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc if (wined3d_texture_use_pbo(texture, gl_info)) texture->resource.map_binding = WINED3D_LOCATION_BUFFER; - if ((desc->resource_type != WINED3D_RTYPE_TEXTURE_3D - && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)) - || !wined3d_texture_use_pbo(texture, gl_info)) - { - if (!wined3d_resource_allocate_sysmem(&texture->resource)) - { - wined3d_texture_cleanup_sync(texture); - return E_OUTOFMEMORY; - } - } - sub_count = level_count * layer_count; - if (sub_count / layer_count != level_count) + if (sub_count / layer_count != level_count + || !(surfaces = heap_calloc(sub_count, sizeof(*surfaces)))) { wined3d_texture_cleanup_sync(texture); return E_OUTOFMEMORY; @@ -2855,6 +2804,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc { if (!(texture->overlay_info = heap_calloc(sub_count, sizeof(*texture->overlay_info)))) { + heap_free(surfaces); wined3d_texture_cleanup_sync(texture); return E_OUTOFMEMORY; } @@ -2866,44 +2816,52 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc } } - /* Generate all sub-resources. */ - for (i = 0; i < sub_count; ++i) + /* Generate all the surfaces. */ + for (i = 0; i < texture->level_count; ++i) { - struct wined3d_texture_sub_resource *sub_resource; - - sub_resource = &texture->sub_resources[i]; - sub_resource->locations = WINED3D_LOCATION_DISCARDED; - if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D - && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)) + for (j = 0; j < texture->layer_count; ++j) { - wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_SYSMEM); - wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM); - } + struct wined3d_texture_sub_resource *sub_resource; + unsigned int idx = j * texture->level_count + i; + struct wined3d_surface *surface; - if (FAILED(hr = device_parent->ops->texture_sub_resource_created(device_parent, - desc->resource_type, texture, i, &sub_resource->parent, &sub_resource->parent_ops))) - { - WARN("Failed to create sub-resource parent, hr %#x.\n", hr); - sub_resource->parent = NULL; - wined3d_texture_cleanup_sync(texture); - return hr; - } + surface = &surfaces[idx]; + surface->container = texture; + surface->texture_level = i; + surface->texture_layer = j; + list_init(&surface->renderbuffers); - TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops); - - TRACE("Created sub-resource %u (level %u, layer %u).\n", - i, i % texture->level_count, i / texture->level_count); - - if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D)) - { - struct wined3d_texture_idx texture_idx = {texture, i}; - - wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (!texture->dc_info || !texture->dc_info[i].dc) + sub_resource = &texture->sub_resources[idx]; + sub_resource->locations = WINED3D_LOCATION_DISCARDED; + sub_resource->u.surface = surface; + if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)) { + wined3d_texture_validate_location(texture, idx, WINED3D_LOCATION_SYSMEM); + wined3d_texture_invalidate_location(texture, idx, ~WINED3D_LOCATION_SYSMEM); + } + + if (FAILED(hr = device_parent->ops->surface_created(device_parent, + texture, idx, &sub_resource->parent, &sub_resource->parent_ops))) + { + WARN("Failed to create surface parent, hr %#x.\n", hr); + sub_resource->parent = NULL; wined3d_texture_cleanup_sync(texture); - return WINED3DERR_INVALIDCALL; + return hr; + } + + TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops); + + TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface); + + if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D)) + { + wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (!surface->dc) + { + wined3d_texture_cleanup_sync(texture); + return WINED3DERR_INVALIDCALL; + } } } } @@ -2911,6 +2869,88 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc return WINED3D_OK; } +/* This call just uploads data, the caller is responsible for binding the + * correct texture. */ +/* Context activation is done by the caller. */ +static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) +{ + const struct wined3d_format *format = texture->resource.format; + unsigned int level = sub_resource_idx % texture->level_count; + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int x, y, z, update_w, update_h, update_d; + unsigned int dst_row_pitch, dst_slice_pitch; + unsigned int width, height, depth; + const void *mem = data->addr; + void *converted_mem = NULL; + + TRACE("texture %p, sub_resource_idx %u, context %p, box %s, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n", + texture, sub_resource_idx, context, debug_box(box), + data->buffer_object, data->addr, row_pitch, slice_pitch); + + width = wined3d_texture_get_level_width(texture, level); + height = wined3d_texture_get_level_height(texture, level); + depth = wined3d_texture_get_level_depth(texture, level); + + if (!box) + { + x = y = z = 0; + update_w = width; + update_h = height; + update_d = depth; + } + else + { + x = box->left; + y = box->top; + z = box->front; + update_w = box->right - box->left; + update_h = box->bottom - box->top; + update_d = box->back - box->front; + } + + if (format->conv_byte_count) + { + if (data->buffer_object) + ERR("Loading a converted texture from a PBO.\n"); + if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) + ERR("Converting a block-based format.\n"); + + dst_row_pitch = update_w * format->conv_byte_count; + dst_slice_pitch = dst_row_pitch * update_h; + + converted_mem = heap_calloc(update_d, dst_slice_pitch); + format->upload(data->addr, converted_mem, row_pitch, slice_pitch, + dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d); + mem = converted_mem; + } + else + { + wined3d_texture_get_pitch(texture, sub_resource_idx, &dst_row_pitch, &dst_slice_pitch); + if (row_pitch != dst_row_pitch || slice_pitch != dst_slice_pitch) + FIXME("Ignoring row/slice pitch (%u/%u).\n", row_pitch, slice_pitch); + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + } + + GL_EXTCALL(glTexSubImage3D(GL_TEXTURE_3D, level, x, y, z, + update_w, update_h, update_d, format->glFormat, format->glType, mem)); + checkGLcall("glTexSubImage3D"); + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + heap_free(converted_mem); +} + /* Context activation is done by the caller. */ static void texture3d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_context *context, const struct wined3d_bo_address *data) @@ -2950,7 +2990,6 @@ static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned in struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; unsigned int row_pitch, slice_pitch; struct wined3d_bo_address data; - struct wined3d_box src_box; /* Optimisations are possible, but the effort should be put into either * implementing EXT_SRGB_DECODE in the driver or finding out why we @@ -2964,12 +3003,11 @@ static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned in return; wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box); wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb); texture3d_download_data(texture, sub_resource_idx, context, &data); wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb); - wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format, - &src_box, wined3d_const_bo_address(&data), row_pitch, slice_pitch, 0, 0, 0, FALSE); + texture3d_upload_data(texture, sub_resource_idx, context, + NULL, wined3d_const_bo_address(&data), row_pitch, slice_pitch); heap_free(data.addr); } @@ -2991,27 +3029,23 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in if (sub_resource->locations & WINED3D_LOCATION_SYSMEM) { struct wined3d_const_bo_address data = {0, texture->resource.heap_memory}; - struct wined3d_box src_box; - data.addr += sub_resource->offset; wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box); - wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format, - &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE); + texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); } else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) { +#if !defined(STAGING_CSMT) struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; - struct wined3d_box src_box; - +#else /* STAGING_CSMT */ + struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL}; +#endif /* STAGING_CSMT */ wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box); - wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format, - &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE); + texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); } else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) { @@ -3053,7 +3087,11 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in case WINED3D_LOCATION_BUFFER: if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { +#if !defined(STAGING_CSMT) struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; +#else /* STAGING_CSMT */ + struct wined3d_bo_address data = {sub_resource->buffer->name, NULL}; +#endif /* STAGING_CSMT */ if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) wined3d_texture_bind_and_dirtify(texture, context, FALSE); @@ -3079,11 +3117,148 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in return TRUE; } +static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) +{ + const struct wined3d_format *format = texture->resource.format; + GLenum internal = srgb ? format->glGammaInternal : format->glInternal; + unsigned int sub_count = texture->level_count * texture->layer_count; + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int i; + + wined3d_texture_bind_and_dirtify(texture, context, srgb); + + if (wined3d_texture_use_immutable_storage(texture, gl_info)) + { + GL_EXTCALL(glTexStorage3D(GL_TEXTURE_3D, texture->level_count, internal, + wined3d_texture_get_level_width(texture, 0), + wined3d_texture_get_level_height(texture, 0), + wined3d_texture_get_level_depth(texture, 0))); + checkGLcall("glTexStorage3D"); + } + else + { + for (i = 0; i < sub_count; ++i) + { + GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, i, internal, + wined3d_texture_get_level_width(texture, i), + wined3d_texture_get_level_height(texture, i), + wined3d_texture_get_level_depth(texture, i), + 0, format->glFormat, format->glType, NULL)); + checkGLcall("glTexImage3D"); + } + } +} + +static void texture3d_cleanup_sub_resources(struct wined3d_texture *texture) +{ +} + static const struct wined3d_texture_ops texture3d_ops = { + texture3d_upload_data, texture3d_load_location, + texture3d_prepare_texture, + texture3d_cleanup_sub_resources, }; +static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, + UINT layer_count, UINT level_count, DWORD flags, struct wined3d_device *device, void *parent, + const struct wined3d_parent_ops *parent_ops) +{ + struct wined3d_device_parent *device_parent = device->device_parent; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + unsigned int i; + HRESULT hr; + + if (layer_count != 1) + { + ERR("Invalid layer count for volume texture.\n"); + return E_INVALIDARG; + } + + /* TODO: It should only be possible to create textures for formats + * that are reported as supported. */ + if (WINED3DFMT_UNKNOWN >= desc->format) + { + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); + return WINED3DERR_INVALIDCALL; + } + + if (!gl_info->supported[EXT_TEXTURE3D]) + { + WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); + return WINED3DERR_INVALIDCALL; + } + + if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access) + || desc->usage & WINED3DUSAGE_SCRATCH)) + { + WARN("Attempted to create a DYNAMIC texture with access %s.\n", + wined3d_debug_resource_access(desc->access)); + return WINED3DERR_INVALIDCALL; + } + + if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) + { + if (!is_power_of_two(desc->width) || !is_power_of_two(desc->height) || !is_power_of_two(desc->depth)) + { + if (desc->usage & WINED3DUSAGE_SCRATCH) + { + WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n"); + } + else + { + WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n", + desc->width, desc->height, desc->depth); + return WINED3DERR_INVALIDCALL; + } + } + } + + if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, level_count, desc, + flags, device, parent, parent_ops, &texture_resource_ops))) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); + return hr; + } + + texture->pow2_matrix[0] = 1.0f; + texture->pow2_matrix[5] = 1.0f; + texture->pow2_matrix[10] = 1.0f; + texture->pow2_matrix[15] = 1.0f; + texture->target = GL_TEXTURE_3D; + + if (wined3d_texture_use_pbo(texture, gl_info)) + { + wined3d_resource_free_sysmem(&texture->resource); + texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + } + + /* Generate all the sub resources. */ + for (i = 0; i < texture->level_count; ++i) + { + struct wined3d_texture_sub_resource *sub_resource; + + sub_resource = &texture->sub_resources[i]; + sub_resource->locations = WINED3D_LOCATION_DISCARDED; + + if (FAILED(hr = device_parent->ops->volume_created(device_parent, + texture, i, &sub_resource->parent, &sub_resource->parent_ops))) + { + WARN("Failed to create volume parent, hr %#x.\n", hr); + sub_resource->parent = NULL; + wined3d_texture_cleanup_sync(texture); + return hr; + } + + TRACE("parent %p, parent_ops %p.\n", parent, parent_ops); + + TRACE("Created volume level %u.\n", i); + } + + return WINED3D_OK; +} + HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) @@ -3119,8 +3294,19 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned if (dst_texture->sub_resources[dst_sub_resource_idx].map_count || src_texture->sub_resources[src_sub_resource_idx].map_count) { +#if !defined(STAGING_CSMT) WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n"); return WINEDDERR_SURFACEBUSY; +#else /* STAGING_CSMT */ + struct wined3d_device *device = dst_texture->resource.device; + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count + || (src_texture && src_texture->sub_resources[src_sub_resource_idx].map_count)) + { + WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n"); + return WINEDDERR_SURFACEBUSY; + } +#endif /* STAGING_CSMT */ } if ((src_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) @@ -3151,7 +3337,7 @@ HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture } overlay = &texture->overlay_info[sub_resource_idx]; - if (!overlay->dst_texture) + if (!overlay->dst) { TRACE("Overlay not visible.\n"); *x = 0; @@ -3194,8 +3380,9 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, DWORD flags) { + struct wined3d_texture_sub_resource *sub_resource, *dst_sub_resource; + struct wined3d_surface *surface, *dst_surface; struct wined3d_overlay_info *overlay; - unsigned int level, dst_level; TRACE("texture %p, sub_resource_idx %u, src_rect %s, dst_texture %p, " "dst_sub_resource_idx %u, dst_rect %s, flags %#x.\n", @@ -3203,14 +3390,14 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), flags); if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY) || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D - || sub_resource_idx >= texture->level_count * texture->layer_count) + || !(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) { WARN("Invalid sub-resource specified.\n"); return WINEDDERR_NOTAOVERLAYSURFACE; } if (!dst_texture || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D - || dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count) + || !(dst_sub_resource = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx))) { WARN("Invalid destination sub-resource specified.\n"); return WINED3DERR_INVALIDCALL; @@ -3218,35 +3405,33 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un overlay = &texture->overlay_info[sub_resource_idx]; - level = sub_resource_idx % texture->level_count; + surface = sub_resource->u.surface; if (src_rect) overlay->src_rect = *src_rect; else SetRect(&overlay->src_rect, 0, 0, - wined3d_texture_get_level_width(texture, level), - wined3d_texture_get_level_height(texture, level)); + wined3d_texture_get_level_width(texture, surface->texture_level), + wined3d_texture_get_level_height(texture, surface->texture_level)); - dst_level = dst_sub_resource_idx % dst_texture->level_count; + dst_surface = dst_sub_resource->u.surface; if (dst_rect) overlay->dst_rect = *dst_rect; else SetRect(&overlay->dst_rect, 0, 0, - wined3d_texture_get_level_width(dst_texture, dst_level), - wined3d_texture_get_level_height(dst_texture, dst_level)); + wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level), + wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level)); - if (overlay->dst_texture && (overlay->dst_texture != dst_texture - || overlay->dst_sub_resource_idx != dst_sub_resource_idx || flags & WINEDDOVER_HIDE)) + if (overlay->dst && (overlay->dst != dst_surface || flags & WINEDDOVER_HIDE)) { - overlay->dst_texture = NULL; + overlay->dst = NULL; list_remove(&overlay->entry); } if (flags & WINEDDOVER_SHOW) { - if (overlay->dst_texture != dst_texture || overlay->dst_sub_resource_idx != dst_sub_resource_idx) + if (overlay->dst != dst_surface) { - overlay->dst_texture = dst_texture; - overlay->dst_sub_resource_idx = dst_sub_resource_idx; + overlay->dst = dst_surface; list_add_tail(&texture->overlay_info[dst_sub_resource_idx].overlays, &overlay->entry); } } @@ -3255,7 +3440,7 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un /* Tests show that the rectangles are erased on hide. */ SetRectEmpty(&overlay->src_rect); SetRectEmpty(&overlay->dst_rect); - overlay->dst_texture = NULL; + overlay->dst = NULL; } return WINED3D_OK; @@ -3327,7 +3512,6 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) { - const struct wined3d_texture_ops *texture_ops; struct wined3d_texture *object; HRESULT hr; @@ -3374,28 +3558,31 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct } } - switch (desc->resource_type) - { - case WINED3D_RTYPE_TEXTURE_1D: - texture_ops = &texture1d_ops; - break; - case WINED3D_RTYPE_TEXTURE_2D: - texture_ops = &texture2d_ops; - break; - case WINED3D_RTYPE_TEXTURE_3D: - texture_ops = &texture3d_ops; - break; - default: - ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type)); - return WINED3DERR_INVALIDCALL; - } - if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture, sub_resources[level_count * layer_count])))) return E_OUTOFMEMORY; - if (FAILED(hr = wined3d_texture_init(object, desc, layer_count, - level_count, flags, device, parent, parent_ops, texture_ops))) + switch (desc->resource_type) + { + case WINED3D_RTYPE_TEXTURE_1D: + hr = texture1d_init(object, desc, layer_count, level_count, device, parent, parent_ops); + break; + + case WINED3D_RTYPE_TEXTURE_2D: + hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); + break; + + case WINED3D_RTYPE_TEXTURE_3D: + hr = volumetexture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); + break; + + default: + ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type)); + hr = WINED3DERR_INVALIDCALL; + break; + } + + if (FAILED(hr)) { WARN("Failed to initialize texture, returning %#x.\n", hr); heap_free(object); @@ -3423,7 +3610,7 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct for (i = 0; i < sub_count; ++i) { wined3d_device_update_sub_resource(device, &object->resource, - i, NULL, data[i].data, data[i].row_pitch, data[i].slice_pitch, 0); + i, NULL, data[i].data, data[i].row_pitch, data[i].slice_pitch); } } @@ -3437,7 +3624,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i { struct wined3d_device *device = texture->resource.device; struct wined3d_texture_sub_resource *sub_resource; - struct wined3d_dc_info *dc_info; + struct wined3d_surface *surface; TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); @@ -3457,25 +3644,25 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i return WINED3DERR_INVALIDCALL; } + surface = sub_resource->u.surface; + if (texture->resource.map_count && !(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT)) return WINED3DERR_INVALIDCALL; - if (!(dc_info = texture->dc_info) || !dc_info[sub_resource_idx].dc) + if (!surface->dc) { - struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx}; - - wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx); + wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (!(dc_info = texture->dc_info) || !dc_info[sub_resource_idx].dc) - return WINED3DERR_INVALIDCALL; } + if (!surface->dc) + return WINED3DERR_INVALIDCALL; if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT)) texture->flags |= WINED3D_TEXTURE_DC_IN_USE; ++texture->resource.map_count; ++sub_resource->map_count; - *dc = dc_info[sub_resource_idx].dc; + *dc = surface->dc; TRACE("Returning dc %p.\n", *dc); return WINED3D_OK; @@ -3485,7 +3672,7 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign { struct wined3d_device *device = texture->resource.device; struct wined3d_texture_sub_resource *sub_resource; - struct wined3d_dc_info *dc_info; + struct wined3d_surface *surface; TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); @@ -3498,21 +3685,20 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign return WINED3DERR_INVALIDCALL; } + surface = sub_resource->u.surface; + if (!(texture->flags & (WINED3D_TEXTURE_GET_DC_LENIENT | WINED3D_TEXTURE_DC_IN_USE))) return WINED3DERR_INVALIDCALL; - if (!(dc_info = texture->dc_info) || dc_info[sub_resource_idx].dc != dc) + if (surface->dc != dc) { - WARN("Application tries to release invalid DC %p, sub-resource DC is %p.\n", - dc, dc_info ? dc_info[sub_resource_idx].dc : NULL); + WARN("Application tries to release invalid DC %p, surface DC is %p.\n", dc, surface->dc); return WINED3DERR_INVALIDCALL; } if (!(texture->resource.usage & WINED3DUSAGE_OWNDC) && !(device->wined3d->flags & WINED3D_NO3D)) { - struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx}; - - wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx); + wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface); device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); } @@ -3524,49 +3710,3 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign return WINED3D_OK; } - -void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_texture *src_texture, - unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) -{ - unsigned int src_row_pitch, src_slice_pitch; - unsigned int update_w, update_h, update_d; - unsigned int src_level, dst_level; - struct wined3d_context *context; - struct wined3d_bo_address data; - - TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, " - "src_texture %p, src_sub_resource_idx %u, src_box %s.\n", - dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z, - src_texture, src_sub_resource_idx, debug_box(src_box)); - - context = context_acquire(dst_texture->resource.device, NULL, 0); - - /* Only load the sub-resource for partial updates. For newly allocated - * textures the texture wouldn't be the current location, and we'd upload - * zeroes just to overwrite them again. */ - update_w = src_box->right - src_box->left; - update_h = src_box->bottom - src_box->top; - update_d = src_box->back - src_box->front; - dst_level = dst_sub_resource_idx % dst_texture->level_count; - if (update_w == wined3d_texture_get_level_width(dst_texture, dst_level) - && update_h == wined3d_texture_get_level_height(dst_texture, dst_level) - && update_d == wined3d_texture_get_level_depth(dst_texture, dst_level)) - wined3d_texture_prepare_texture(dst_texture, context, FALSE); - else - wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); - - src_level = src_sub_resource_idx % src_texture->level_count; - wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data, - src_texture->sub_resources[src_sub_resource_idx].locations); - wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch); - - wined3d_texture_upload_data(dst_texture, dst_sub_resource_idx, context, src_texture->resource.format, - src_box, wined3d_const_bo_address(&data), src_row_pitch, src_slice_pitch, dst_x, dst_y, dst_z, FALSE); - - context_release(context); - - wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); -} diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c index 91960389587..b48293eabb3 100644 --- a/dll/directx/wine/wined3d/utils.c +++ b/dll/directx/wine/wined3d/utils.c @@ -122,6 +122,7 @@ static const struct wined3d_format_channels formats[] = /* Bump mapping stuff */ {WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0}, {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0}, + {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0}, {WINED3DFMT_R10G10B10X2_UINT, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, {WINED3DFMT_R10G10B10X2_SNORM, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, @@ -132,6 +133,8 @@ static const struct wined3d_format_channels formats[] = {WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1}, {WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0}, {WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4}, + {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0}, + {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0}, {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8}, /* Vendor-specific formats */ {WINED3DFMT_ATI1N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, @@ -892,9 +895,45 @@ static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD colo && 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_color_key *color_key) + const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) { const WORD *src_row; unsigned int x, y; @@ -917,7 +956,7 @@ static void convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsig 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_color_key *color_key) + const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) { const WORD *src_row; unsigned int x, y; @@ -940,7 +979,7 @@ static void convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, uns 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_color_key *color_key) + const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) { const BYTE *src_row; unsigned int x, y; @@ -961,7 +1000,7 @@ static void convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsig 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_color_key *color_key) + const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) { const DWORD *src_row; unsigned int x, y; @@ -984,7 +1023,7 @@ static void convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, uns 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_color_key *color_key) + const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) { const DWORD *src_row; unsigned int x, y; @@ -1023,6 +1062,10 @@ const struct wined3d_color_key_conversion * wined3d_format_get_color_key_convers {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->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)) { @@ -1035,6 +1078,13 @@ const struct wined3d_color_key_conversion * wined3d_format_get_color_key_convers 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; } @@ -1634,6 +1684,10 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_RGBA_INTEGER, GL_INT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, EXT_TEXTURE_INTEGER, NULL}, + {WINED3DFMT_R24_UNORM_X8_TYPELESS, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH, + ARB_DEPTH_TEXTURE, NULL}, /* Vendor-specific formats */ {WINED3DFMT_ATI1N, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0, GL_RED, GL_UNSIGNED_BYTE, 0, @@ -2753,7 +2807,7 @@ static void query_internal_format(struct wined3d_adapter *adapter, struct wined3d_format *format, const struct wined3d_format_texture_info *texture_info, struct wined3d_gl_info *gl_info, BOOL srgb_write_supported, BOOL srgb_format) { - GLint count, multisample_types[8]; + GLint count, multisample_types[MAX_MULTISAMPLE_TYPES]; unsigned int i, max_log2; GLenum target; @@ -2832,9 +2886,7 @@ static void query_internal_format(struct wined3d_adapter *adapter, count = 0; GL_EXTCALL(glGetInternalformativ(target, format->glInternal, GL_NUM_SAMPLE_COUNTS, 1, &count)); - if (count > ARRAY_SIZE(multisample_types)) - FIXME("Unexpectedly high number of multisample types %d.\n", count); - count = min(count, ARRAY_SIZE(multisample_types)); + count = min(count, MAX_MULTISAMPLE_TYPES); GL_EXTCALL(glGetInternalformativ(target, format->glInternal, GL_SAMPLES, count, multisample_types)); checkGLcall("query sample counts"); @@ -3222,8 +3274,8 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); } - if (!gl_info->supported[APPLE_YCBCR_422] && (gl_info->supported[ARB_FRAGMENT_PROGRAM] - || (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER]))) + if (!gl_info->supported[APPLE_YCBCR_422] && gl_info->supported[ARB_FRAGMENT_PROGRAM] + && gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) { idx = get_format_idx(WINED3DFMT_YUY2); gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2); @@ -3232,7 +3284,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY); } else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM] - && (!gl_info->supported[ARB_FRAGMENT_SHADER] || !gl_info->supported[ARB_VERTEX_SHADER]))) + || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])) { idx = get_format_idx(WINED3DFMT_YUY2); gl_info->formats[idx].glInternal = 0; @@ -3241,8 +3293,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ gl_info->formats[idx].glInternal = 0; } - if (gl_info->supported[ARB_FRAGMENT_PROGRAM] - || (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER])) + if (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) { idx = get_format_idx(WINED3DFMT_YV12); format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE); @@ -3291,7 +3342,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE); } - if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER]) + if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) { idx = get_format_idx(WINED3DFMT_P8_UINT); gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); @@ -4445,6 +4496,7 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA); D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA); D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA); + D3DSTATE_TO_STR(WINED3D_RS_DEPTHCLIP); #undef D3DSTATE_TO_STR default: FIXME("Unrecognized %u render state!\n", state); @@ -4663,8 +4715,8 @@ const char *debug_d3dstate(DWORD state) return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0)); if (STATE_IS_MATERIAL(state)) return "STATE_MATERIAL"; - if (STATE_IS_RASTERIZER(state)) - return "STATE_RASTERIZER"; + if (STATE_IS_FRONTFACE(state)) + return "STATE_FRONTFACE"; if (STATE_IS_POINTSPRITECOORDORIGIN(state)) return "STATE_POINTSPRITECOORDORIGIN"; if (STATE_IS_BASEVERTEXINDEX(state)) @@ -4876,10 +4928,10 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w if (context->last_was_rhw) { /* Transform D3D RHW coordinates to OpenGL clip coordinates. */ - float x = state->viewports[0].x; - float y = state->viewports[0].y; - float w = state->viewports[0].width; - float h = state->viewports[0].height; + float x = state->viewport.x; + float y = state->viewport.y; + float w = state->viewport.width; + float h = state->viewport.height; float x_scale = 2.0f / w; float x_offset = (center_offset - (2.0f * x) - w) / w; float y_scale = flip ? 2.0f / h : 2.0f / -h; @@ -4903,10 +4955,10 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w else { float y_scale = flip ? -1.0f : 1.0f; - float x_offset = center_offset / state->viewports[0].width; + float x_offset = center_offset / state->viewport.width; float y_offset = flip - ? center_offset / state->viewports[0].height - : -center_offset / state->viewports[0].height; + ? center_offset / state->viewport.height + : -center_offset / state->viewport.height; float z_scale = clip_control ? 1.0f : 2.0f; float z_offset = clip_control ? 0.0f : -1.0f; const struct wined3d_matrix projection = @@ -5106,10 +5158,9 @@ void get_pointsize(const struct wined3d_context *context, const struct wined3d_s b.d = state->render_states[WINED3D_RS_POINTSCALE_B]; c.d = state->render_states[WINED3D_RS_POINTSCALE_C]; - /* Always use first viewport, this path does not apply to d3d10/11 multiple viewports case. */ if (state->render_states[WINED3D_RS_POINTSCALEENABLE]) { - float scale_factor = state->viewports[0].height * state->viewports[0].height; + float scale_factor = state->viewport.height * state->viewport.height; out_att[0] = a.f / scale_factor; out_att[1] = b.f / scale_factor; @@ -5746,9 +5797,9 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED; settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED; settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; - settings->op[i].tmp_dst = 0; + settings->op[i].dst = resultreg; settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; - settings->op[i].projected = WINED3D_PROJECTION_NONE; + settings->op[i].projected = proj_none; i++; break; } @@ -5872,15 +5923,15 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d { ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS]; if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3)) - settings->op[i].projected = WINED3D_PROJECTION_COUNT3; + settings->op[i].projected = proj_count3; else if (ttff & WINED3D_TTFF_PROJECTED) - settings->op[i].projected = WINED3D_PROJECTION_COUNT4; + settings->op[i].projected = proj_count4; else - settings->op[i].projected = WINED3D_PROJECTION_NONE; + settings->op[i].projected = proj_none; } else { - settings->op[i].projected = WINED3D_PROJECTION_NONE; + settings->op[i].projected = proj_none; } settings->op[i].cop = cop; @@ -5891,7 +5942,11 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d settings->op[i].aarg0 = aarg0; settings->op[i].aarg1 = aarg1; settings->op[i].aarg2 = aarg2; - settings->op[i].tmp_dst = state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP; + + if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP) + settings->op[i].dst = tempreg; + else + settings->op[i].dst = resultreg; } /* Clear unsupported stages */ @@ -6038,7 +6093,27 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st { switch (texture->target) { + case GL_TEXTURE_1D: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable(GL_TEXTURE_2D)"); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable(GL_TEXTURE_3D)"); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } + gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_1D); + checkGLcall("glEnable(GL_TEXTURE_1D)"); + break; case GL_TEXTURE_2D: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); checkGLcall("glDisable(GL_TEXTURE_3D)"); if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) @@ -6055,6 +6130,8 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st checkGLcall("glEnable(GL_TEXTURE_2D)"); break; case GL_TEXTURE_RECTANGLE_ARB: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); @@ -6078,12 +6155,16 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); } + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D); checkGLcall("glEnable(GL_TEXTURE_3D)"); break; case GL_TEXTURE_CUBE_MAP_ARB: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); @@ -6100,6 +6181,8 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st } else { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); checkGLcall("glEnable(GL_TEXTURE_2D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); diff --git a/dll/directx/wine/wined3d/view.c b/dll/directx/wine/wined3d/view.c index 5edaef8b352..bed39dbc5fc 100644 --- a/dll/directx/wine/wined3d/view.c +++ b/dll/directx/wine/wined3d/view.c @@ -48,6 +48,11 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info, {GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_RECTANGLE}, {GL_TEXTURE_3D, 0, GL_TEXTURE_3D}, + {GL_TEXTURE_1D, 0, GL_TEXTURE_1D}, + {GL_TEXTURE_1D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, + {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D}, + {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, + {GL_TEXTURE_2D, 0, GL_TEXTURE_2D}, {GL_TEXTURE_2D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY}, {GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_2D}, @@ -59,11 +64,6 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info, {GL_TEXTURE_2D_MULTISAMPLE, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY}, {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0, GL_TEXTURE_2D_MULTISAMPLE}, {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY}, - - {GL_TEXTURE_1D, 0, GL_TEXTURE_1D}, - {GL_TEXTURE_1D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, - {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D}, - {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, }; unsigned int i; @@ -750,8 +750,10 @@ static void wined3d_shader_resource_view_cs_init(void *object) debug_d3dformat(resource->format->id), debug_d3dformat(view_format->id)); } } +#if defined(STAGING_CSMT) wined3d_resource_release(resource); +#endif /* STAGING_CSMT */ } static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_view *view, @@ -768,7 +770,9 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_ wined3d_resource_incref(view->resource = resource); +#if defined(STAGING_CSMT) wined3d_resource_acquire(resource); +#endif /* STAGING_CSMT */ wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_cs_init, view); return WINED3D_OK; @@ -1121,8 +1125,10 @@ static void wined3d_unordered_access_view_cs_init(void *object) desc, texture, view->format); } } +#if defined(STAGING_CSMT) wined3d_resource_release(resource); +#endif /* STAGING_CSMT */ } static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_access_view *view, @@ -1139,7 +1145,9 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces wined3d_resource_incref(view->resource = resource); +#if defined(STAGING_CSMT) wined3d_resource_acquire(resource); +#endif /* STAGING_CSMT */ wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_cs_init, view); return WINED3D_OK; diff --git a/dll/directx/wine/wined3d/wined3d.spec b/dll/directx/wine/wined3d/wined3d.spec index 449d98712e4..3022e20edbe 100644 --- a/dll/directx/wine/wined3d/wined3d.spec +++ b/dll/directx/wine/wined3d/wined3d.spec @@ -40,7 +40,7 @@ @ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr long ptr float long) @ cdecl wined3d_device_clear_unordered_access_view_uint(ptr ptr ptr) @ cdecl wined3d_device_copy_resource(ptr ptr ptr) -@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr long) +@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr) @ cdecl wined3d_device_copy_uav_counter(ptr ptr long ptr) @ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr) @ cdecl wined3d_device_decref(ptr) @@ -86,7 +86,6 @@ @ cdecl wined3d_device_get_light(ptr long ptr) @ cdecl wined3d_device_get_light_enable(ptr long ptr) @ cdecl wined3d_device_get_material(ptr ptr) -@ cdecl wined3d_device_get_max_frame_latency(ptr) @ cdecl wined3d_device_get_npatch_mode(ptr) @ cdecl wined3d_device_get_pixel_shader(ptr) @ cdecl wined3d_device_get_predication(ptr ptr) @@ -102,7 +101,7 @@ @ cdecl wined3d_device_get_render_state(ptr long) @ cdecl wined3d_device_get_rendertarget_view(ptr long) @ cdecl wined3d_device_get_sampler_state(ptr long long) -@ cdecl wined3d_device_get_scissor_rects(ptr ptr ptr) +@ cdecl wined3d_device_get_scissor_rect(ptr ptr) @ cdecl wined3d_device_get_software_vertex_processing(ptr) @ cdecl wined3d_device_get_stream_output(ptr long ptr) @ cdecl wined3d_device_get_stream_source(ptr long ptr ptr ptr) @@ -115,7 +114,7 @@ @ cdecl wined3d_device_get_unordered_access_view(ptr long) @ cdecl wined3d_device_get_vertex_declaration(ptr) @ cdecl wined3d_device_get_vertex_shader(ptr) -@ cdecl wined3d_device_get_viewports(ptr ptr ptr) +@ cdecl wined3d_device_get_viewport(ptr ptr) @ cdecl wined3d_device_get_vs_cb(ptr long) @ cdecl wined3d_device_get_vs_consts_b(ptr long long ptr) @ cdecl wined3d_device_get_vs_consts_f(ptr long long ptr) @@ -162,7 +161,6 @@ @ cdecl wined3d_device_set_light(ptr long ptr) @ cdecl wined3d_device_set_light_enable(ptr long long) @ cdecl wined3d_device_set_material(ptr ptr) -@ cdecl wined3d_device_set_max_frame_latency(ptr long) @ cdecl wined3d_device_set_multithreaded(ptr) @ cdecl wined3d_device_set_npatch_mode(ptr float) @ cdecl wined3d_device_set_pixel_shader(ptr ptr) @@ -178,7 +176,7 @@ @ cdecl wined3d_device_set_render_state(ptr long long) @ cdecl wined3d_device_set_rendertarget_view(ptr long ptr long) @ cdecl wined3d_device_set_sampler_state(ptr long long long) -@ cdecl wined3d_device_set_scissor_rects(ptr long ptr) +@ cdecl wined3d_device_set_scissor_rect(ptr ptr) @ cdecl wined3d_device_set_software_vertex_processing(ptr long) @ cdecl wined3d_device_set_stream_output(ptr long ptr long) @ cdecl wined3d_device_set_stream_source(ptr long ptr long long) @@ -189,7 +187,7 @@ @ cdecl wined3d_device_set_unordered_access_view(ptr long ptr long) @ cdecl wined3d_device_set_vertex_declaration(ptr ptr) @ cdecl wined3d_device_set_vertex_shader(ptr ptr) -@ cdecl wined3d_device_set_viewports(ptr long ptr) +@ cdecl wined3d_device_set_viewport(ptr ptr) @ cdecl wined3d_device_set_vs_cb(ptr long ptr) @ cdecl wined3d_device_set_vs_consts_b(ptr long long ptr) @ cdecl wined3d_device_set_vs_consts_f(ptr long long ptr) @@ -200,7 +198,7 @@ @ cdecl wined3d_device_show_cursor(ptr long) @ cdecl wined3d_device_uninit_3d(ptr) @ cdecl wined3d_device_uninit_gdi(ptr) -@ cdecl wined3d_device_update_sub_resource(ptr ptr long ptr ptr long long long) +@ cdecl wined3d_device_update_sub_resource(ptr ptr long ptr ptr long long) @ cdecl wined3d_device_update_texture(ptr ptr ptr) @ cdecl wined3d_device_validate_device(ptr ptr) @@ -274,6 +272,8 @@ @ cdecl wined3d_stateblock_decref(ptr) @ cdecl wined3d_stateblock_incref(ptr) +@ cdecl wined3d_strictdrawing_set(long) + @ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_swapchain_decref(ptr) @ cdecl wined3d_swapchain_get_back_buffer(ptr long) diff --git a/dll/directx/wine/wined3d/wined3d_gl.h b/dll/directx/wine/wined3d/wined3d_gl.h index 14f8a497344..87283c850e1 100644 --- a/dll/directx/wine/wined3d/wined3d_gl.h +++ b/dll/directx/wine/wined3d/wined3d_gl.h @@ -89,7 +89,6 @@ enum wined3d_gl_extension ARB_POINT_PARAMETERS, ARB_POINT_SPRITE, ARB_PROVOKING_VERTEX, - ARB_SAMPLE_SHADING, ARB_SAMPLER_OBJECTS, ARB_SEAMLESS_CUBE_MAP, ARB_SHADER_ATOMIC_COUNTERS, @@ -97,7 +96,6 @@ enum wined3d_gl_extension ARB_SHADER_IMAGE_LOAD_STORE, ARB_SHADER_IMAGE_SIZE, ARB_SHADER_STORAGE_BUFFER_OBJECT, - ARB_SHADER_TEXTURE_IMAGE_SAMPLES, ARB_SHADER_TEXTURE_LOD, ARB_SHADING_LANGUAGE_100, ARB_SHADING_LANGUAGE_420PACK, @@ -136,6 +134,7 @@ enum wined3d_gl_extension ARB_TRANSFORM_FEEDBACK3, ARB_UNIFORM_BUFFER_OBJECT, ARB_VERTEX_ARRAY_BGRA, + ARB_VERTEX_BLEND, ARB_VERTEX_BUFFER_OBJECT, ARB_VERTEX_PROGRAM, ARB_VERTEX_SHADER, diff --git a/dll/directx/wine/wined3d/wined3d_main.c b/dll/directx/wine/wined3d/wined3d_main.c index 604e6e4ed90..28e6fe60cfe 100644 --- a/dll/directx/wine/wined3d/wined3d_main.c +++ b/dll/directx/wine/wined3d/wined3d_main.c @@ -74,7 +74,7 @@ struct wined3d_settings wined3d_settings = { TRUE, /* Multithreaded CS by default. */ FALSE, /* explicit_gl_version */ - MAKEDWORD_VERSION(4, 4), /* Default to OpenGL 4.4 */ + MAKEDWORD_VERSION(1, 0), /* Default to legacy OpenGL */ TRUE, /* Use of GLSL enabled by default */ ORM_FBO, /* Use FBOs to do offscreen rendering */ PCI_VENDOR_NONE,/* PCI Vendor ID */ @@ -83,6 +83,7 @@ struct wined3d_settings wined3d_settings = NULL, /* No wine logo by default */ TRUE, /* Prefer multisample textures to multisample renderbuffers. */ ~0u, /* Don't force a specific sample count by default. */ + FALSE, /* No strict draw ordering. */ FALSE, /* Don't range check relative addressing indices in float constants. */ ~0U, /* No VS shader model limit by default. */ ~0U, /* No HS shader model limit by default. */ @@ -289,6 +290,13 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) if (!get_config_key_dword(hkey, appkey, "SampleCount", &wined3d_settings.sample_count)) ERR_(winediag)("Forcing sample count to %u. This may not be compatible with all applications.\n", wined3d_settings.sample_count); + if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size) + && !strcmp(buffer,"enabled")) + { + ERR_(winediag)("\"StrictDrawOrdering\" is deprecated, please use \"csmt\" instead.\n"); + TRACE("Enforcing strict draw ordering.\n"); + wined3d_settings.strict_draw_ordering = TRUE; + } if (!get_config_key(hkey, appkey, "CheckFloatConstants", buffer, size) && !strcmp(buffer, "enabled")) { @@ -508,6 +516,11 @@ void wined3d_unregister_window(HWND window) wined3d_wndproc_mutex_unlock(); } +void CDECL 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/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h index 3cf67482377..b127fa71faa 100644 --- a/dll/directx/wine/wined3d/wined3d_private.h +++ b/dll/directx/wine/wined3d/wined3d_private.h @@ -277,6 +277,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup #define MAX_TGSM_REGISTERS 8192 #define MAX_VERTEX_BLENDS 4 #define MAX_VERTEX_INDEX_BLENDS 9 +#define MAX_MULTISAMPLE_TYPES 8 #define MAX_RENDER_TARGETS 8 struct min_lookup @@ -401,6 +402,7 @@ struct wined3d_settings char *logo; unsigned int multisample_textures; unsigned int sample_count; + BOOL strict_draw_ordering; BOOL check_float_constants; unsigned int max_sm_vs; unsigned int max_sm_hs; @@ -504,7 +506,6 @@ enum wined3d_shader_register_type WINED3DSPR_GSINSTID, WINED3DSPR_DEPTHOUTGE, WINED3DSPR_DEPTHOUTLE, - WINED3DSPR_RASTERIZER, }; enum wined3d_data_type @@ -626,14 +627,6 @@ enum wined3d_tessellator_partitioning #define WINED3DSI_SAMPLE_INFO_UINT 0x1 #define WINED3DSI_SAMPLER_COMPARISON_MODE 0x1 -#define WINED3DSI_PRECISE_X 0x100 -#define WINED3DSI_PRECISE_Y 0x200 -#define WINED3DSI_PRECISE_Z 0x400 -#define WINED3DSI_PRECISE_W 0x800 -#define WINED3DSI_PRECISE_XYZW (WINED3DSI_PRECISE_X | WINED3DSI_PRECISE_Y \ - | WINED3DSI_PRECISE_Z | WINED3DSI_PRECISE_W) -#define WINED3DSI_PRECISE_SHIFT 8 - enum wined3d_shader_rel_op { WINED3D_SHADER_REL_OP_GT = 1, @@ -945,7 +938,6 @@ enum wined3d_shader_type WINED3D_SHADER_TYPE_COMPUTE = WINED3D_SHADER_TYPE_GRAPHICS_COUNT, WINED3D_SHADER_TYPE_COUNT, - WINED3D_SHADER_TYPE_INVALID = WINED3D_SHADER_TYPE_COUNT, }; struct wined3d_shader_version @@ -1046,9 +1038,7 @@ struct wined3d_shader_reg_maps DWORD point_size : 1; DWORD vocp : 1; DWORD input_rel_addressing : 1; - DWORD viewport_array : 1; - DWORD sample_mask : 1; - DWORD padding : 14; + DWORD padding : 16; DWORD rt_mask; /* Used render targets, 32 max. */ @@ -1284,9 +1274,6 @@ struct wined3d_shader_frontend extern const struct wined3d_shader_frontend sm1_shader_frontend DECLSPEC_HIDDEN; extern const struct wined3d_shader_frontend sm4_shader_frontend DECLSPEC_HIDDEN; -enum wined3d_shader_type wined3d_get_sm4_shader_type(const DWORD *byte_code, - size_t byte_code_size) DECLSPEC_HIDDEN; - typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *); #define WINED3D_SHADER_CAP_VS_CLIPPING 0x00000001 @@ -1322,11 +1309,10 @@ enum wined3d_gl_resource_type WINED3D_GL_RES_TYPE_COUNT = 7, }; -enum wined3d_vertex_processing_mode -{ - WINED3D_VP_MODE_FF, - WINED3D_VP_MODE_SHADER, - WINED3D_VP_MODE_NONE, +enum vertexprocessing_mode { + fixedfunction, + vertexshader, + pretransformed }; #define WINED3D_CONST_NUM_UNUSED ~0U @@ -1361,7 +1347,7 @@ enum wined3d_shader_tex_types struct ps_compile_args { struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS]; - enum wined3d_vertex_processing_mode vp_mode; + enum vertexprocessing_mode vp_mode; enum wined3d_ffp_ps_fog_mode fog; WORD tex_transform; /* ps 1.0-1.3, 4 textures */ WORD tex_types; /* ps 1.0 - 1.4, 6 textures */ @@ -1414,7 +1400,6 @@ struct ds_compile_args struct gs_compile_args { unsigned int output_count; - enum wined3d_primitive_type primitive_type; DWORD interpolation_mode[WINED3D_PACKED_INTERPOLATION_SIZE]; }; @@ -1648,10 +1633,10 @@ enum wined3d_pipeline #define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIP_DISTANCES)) #define STATE_IS_MATERIAL(a) ((a) == STATE_MATERIAL) -#define STATE_RASTERIZER (STATE_MATERIAL + 1) -#define STATE_IS_RASTERIZER(a) ((a) == STATE_RASTERIZER) +#define STATE_FRONTFACE (STATE_MATERIAL + 1) +#define STATE_IS_FRONTFACE(a) ((a) == STATE_FRONTFACE) -#define STATE_POINTSPRITECOORDORIGIN (STATE_RASTERIZER + 1) +#define STATE_POINTSPRITECOORDORIGIN (STATE_FRONTFACE + 1) #define STATE_IS_POINTSPRITECOORDORIGIN(a) ((a) == STATE_POINTSPRITECOORDORIGIN) #define STATE_BASEVERTEXINDEX (STATE_POINTSPRITECOORDORIGIN + 1) @@ -1907,7 +1892,7 @@ struct wined3d_context DWORD last_was_vshader : 1; DWORD last_was_normal : 1; DWORD namedArraysLoaded : 1; - DWORD last_was_ffp_blit : 1; + DWORD numberedArraysLoaded : 1; DWORD last_was_blit : 1; DWORD last_was_ckey : 1; DWORD fog_coord : 1; @@ -1916,7 +1901,6 @@ struct wined3d_context DWORD current : 1; DWORD destroyed : 1; DWORD valid : 1; - DWORD texShaderBumpMap : 8; /* MAX_TEXTURES, 8 */ DWORD lastWasPow2Texture : 8; /* MAX_TEXTURES, 8 */ DWORD fixed_function_usage_map : 8; /* MAX_TEXTURES, 8 */ @@ -1925,7 +1909,6 @@ struct wined3d_context 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 update_shader_resource_bindings : 1; DWORD update_compute_shader_resource_bindings : 1; @@ -1939,9 +1922,8 @@ struct wined3d_context DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */ DWORD last_was_dual_blend : 1; DWORD padding : 8; - DWORD constant_update_mask; - DWORD numbered_array_mask; + DWORD numbered_array_mask; GLenum tracking_parm; /* Which source is tracking current colour */ GLenum untracked_materials[2]; UINT blit_w, blit_h; @@ -2008,8 +1990,6 @@ struct wined3d_context struct wined3d_fence *buffer_fences[MAX_ATTRIBS]; unsigned int buffer_fence_count; - GLuint blit_vbo; - DWORD tex_unit_map[MAX_COMBINED_SAMPLERS]; DWORD rev_tex_unit_map[MAX_GL_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS]; @@ -2018,9 +1998,6 @@ struct wined3d_context GLfloat fog_coord_value; GLfloat color[4], fogstart, fogend, fogcolor[4]; GLuint dummy_arbfp_prog; - - unsigned int viewport_count; - unsigned int scissor_rect_count; }; struct wined3d_fb_state @@ -2116,6 +2093,8 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN; +struct wined3d_surface; + enum wined3d_blit_op { WINED3D_BLIT_OP_COLOR_BLIT, @@ -2140,10 +2119,9 @@ struct wined3d_blitter_ops unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil); DWORD (*blitter_blit)(struct wined3d_blitter *blitter, enum wined3d_blit_op op, struct wined3d_context *context, - struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, - const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *colour_key, - enum wined3d_texture_filter_type filter); + struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect, + struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter); }; void wined3d_arbfp_blitter_create(struct wined3d_blitter **next, @@ -2153,8 +2131,6 @@ void wined3d_fbo_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; void wined3d_ffp_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -struct wined3d_blitter *wined3d_glsl_blitter_create(struct wined3d_blitter **next, - const struct wined3d_device *device) DECLSPEC_HIDDEN; void wined3d_raw_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; @@ -2169,10 +2145,7 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state, UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, - struct wined3d_resource *rt, unsigned int rt_sub_resource_idx, - struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, DWORD location) DECLSPEC_HIDDEN; -void context_apply_ffp_blit_state(struct wined3d_context *context, - const struct wined3d_device *device) DECLSPEC_HIDDEN; + struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit) DECLSPEC_HIDDEN; void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint name) DECLSPEC_HIDDEN; @@ -2187,12 +2160,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, stru const struct wined3d_format *ds_format) DECLSPEC_HIDDEN; HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN; void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; -void context_draw_shaded_quad(struct wined3d_context *context, struct wined3d_texture *texture, - unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect, - enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -void context_draw_textured_quad(struct wined3d_context *context, struct wined3d_texture *texture, - unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect, - enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; void context_enable_clip_distances(struct wined3d_context *context, unsigned int mask) DECLSPEC_HIDDEN; void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN; void context_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN; @@ -2206,16 +2173,14 @@ void context_gl_resource_released(struct wined3d_device *device, GLuint name, BOOL rb_namespace) DECLSPEC_HIDDEN; void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN; void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN; -void context_load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si, - GLuint *current_bo, const struct wined3d_state *state) DECLSPEC_HIDDEN; void *context_map_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data, size_t size, GLenum binding, DWORD flags) DECLSPEC_HIDDEN; struct wined3d_context *context_reacquire(const struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN; -void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void context_restore(struct wined3d_context *context, struct wined3d_texture *texture, - unsigned int sub_resource_idx) DECLSPEC_HIDDEN; +void context_resource_released(const struct wined3d_device *device, + struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN; +void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) DECLSPEC_HIDDEN; BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN; void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN; void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN; @@ -2223,12 +2188,9 @@ void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; -void context_texture_update(struct wined3d_context *context, const struct wined3d_texture *texture) DECLSPEC_HIDDEN; -void context_unload_tex_coords(const struct wined3d_context *context) DECLSPEC_HIDDEN; +void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) DECLSPEC_HIDDEN; void context_unmap_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data, GLenum binding) DECLSPEC_HIDDEN; -void context_update_stream_sources(struct wined3d_context *context, - const struct wined3d_state *state) DECLSPEC_HIDDEN; /***************************************************************************** * Internal representation of a light @@ -2443,13 +2405,11 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_GTX980 = 0x13c0, CARD_NVIDIA_GEFORCE_GTX980TI = 0x17c8, CARD_NVIDIA_GEFORCE_GTX1050 = 0x1c81, - CARD_NVIDIA_GEFORCE_GTX1050TI = 0x1c82, CARD_NVIDIA_GEFORCE_GTX1060 = 0x1c03, CARD_NVIDIA_GEFORCE_GTX1070 = 0x1b81, CARD_NVIDIA_GEFORCE_GTX1080 = 0x1b80, CARD_NVIDIA_GEFORCE_GTX1080TI = 0x1b06, CARD_NVIDIA_TITANX_PASCAL = 0x1b00, - CARD_NVIDIA_TITANV = 0x1d81, CARD_VMWARE_SVGA3D = 0x0405, @@ -2577,6 +2537,7 @@ struct wined3d_gl_limits UINT texture3d_size; float pointsize_max; float pointsize_min; + UINT blends; UINT anisotropy; float shininess; UINT samples; @@ -2679,11 +2640,17 @@ BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx void install_gl_compat_wrapper(struct wined3d_gl_info *gl_info, enum wined3d_gl_extension ext) DECLSPEC_HIDDEN; -enum wined3d_projection_type +enum projection_types { - WINED3D_PROJECTION_NONE = 0, - WINED3D_PROJECTION_COUNT3 = 1, - WINED3D_PROJECTION_COUNT4 = 2 + proj_none = 0, + proj_count3 = 1, + proj_count4 = 2 +}; + +enum dst_arg +{ + resultreg = 0, + tempreg = 1 }; /***************************************************************************** @@ -2704,7 +2671,7 @@ struct texture_stage_op struct color_fixup_desc color_fixup; unsigned tex_type : 3; - unsigned tmp_dst : 1; + unsigned dst : 1; unsigned projected : 2; unsigned padding : 10; }; @@ -2890,10 +2857,8 @@ struct wined3d_state struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1]; struct wined3d_vec4 clip_planes[MAX_CLIP_DISTANCES]; struct wined3d_material material; - struct wined3d_viewport viewports[WINED3D_MAX_VIEWPORTS]; - unsigned int viewport_count; - RECT scissor_rects[WINED3D_MAX_VIEWPORTS]; - unsigned int scissor_rect_count; + struct wined3d_viewport viewport; + RECT scissor_rect; /* Light hashmap. Collisions are handled using linked lists. */ #define LIGHTMAP_SIZE 43 @@ -2924,19 +2889,29 @@ static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state, struct wined3d_dummy_textures { - GLuint tex_1d; GLuint tex_2d; + GLuint tex_1d; GLuint tex_rect; GLuint tex_3d; GLuint tex_cube; GLuint tex_cube_array; - GLuint tex_1d_array; GLuint tex_2d_array; + GLuint tex_1d_array; GLuint tex_buffer; GLuint tex_2d_ms; GLuint tex_2d_ms_array; }; +#if defined(STAGING_CSMT) +struct wined3d_gl_bo +{ + GLuint name; + GLenum usage; + GLenum type_hint; + UINT size; +}; + +#endif /* STAGING_CSMT */ #define WINED3D_UNMAPPED_STAGE ~0u /* Multithreaded flag. Removed from the public header to signal that @@ -2965,12 +2940,13 @@ struct wined3d_device APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1]; struct wined3d_blitter *blitter; + BYTE vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */ BYTE bCursorVisible : 1; BYTE d3d_initialized : 1; BYTE inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */ BYTE softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */ BYTE filter_messages : 1; - BYTE padding : 3; + BYTE padding : 2; unsigned char surface_alignment; /* Line Alignment of surfaces */ @@ -2987,7 +2963,6 @@ struct wined3d_device struct wined3d_rendertarget_view *back_buffer_view; struct wined3d_swapchain **swapchains; UINT swapchain_count; - unsigned int max_frame_latency; 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) */ @@ -3037,6 +3012,12 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) +struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, + GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN; +void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, + const struct wined3d_context *context) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) { @@ -3142,16 +3123,16 @@ struct gl_texture GLuint name; }; -struct wined3d_blt_info -{ - GLenum bind_target; - struct wined3d_vec3 texcoords[4]; -}; - struct wined3d_texture_ops { + void (*texture_upload_data)(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch); BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location); + void (*texture_prepare_texture)(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb); + void (*texture_cleanup_sub_resources)(struct wined3d_texture *texture); }; #define WINED3D_TEXTURE_COND_NP2 0x00000001 @@ -3217,32 +3198,30 @@ struct wined3d_texture { struct list entry; struct list overlays; - struct wined3d_texture *dst_texture; - unsigned int dst_sub_resource_idx; + struct wined3d_surface *dst; RECT src_rect; RECT dst_rect; } *overlay_info; - struct wined3d_dc_info - { - HBITMAP bitmap; - HDC dc; - } *dc_info; - - struct list renderbuffers; - const struct wined3d_renderbuffer_entry *current_renderbuffer; - struct wined3d_texture_sub_resource { void *parent; const struct wined3d_parent_ops *parent_ops; + union + { + struct wined3d_surface *surface; + } u; unsigned int offset; unsigned int size; unsigned int map_count; DWORD locations; +#if !defined(STAGING_CSMT) GLuint buffer_object; +#else /* STAGING_CSMT */ + struct wined3d_gl_bo *buffer; +#endif /* STAGING_CSMT */ } sub_resources[1]; }; @@ -3304,32 +3283,6 @@ static inline unsigned int wined3d_texture_get_level_pow2_height(const struct wi return max(1, texture->pow2_height >> level); } -static inline void wined3d_texture_get_level_box(const struct wined3d_texture *texture, - unsigned int level, struct wined3d_box *box) -{ - wined3d_box_set(box, 0, 0, - wined3d_texture_get_level_width(texture, level), - wined3d_texture_get_level_height(texture, level), - 0, wined3d_texture_get_level_depth(texture, level)); -} - -HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, - unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, - const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -void texture2d_get_blt_info(const struct wined3d_texture *texture, unsigned int sub_resource_idx, - const RECT *rect, struct wined3d_blt_info *info) DECLSPEC_HIDDEN; -BOOL texture2d_load_drawable(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context) DECLSPEC_HIDDEN; -void texture2d_load_fb_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx, - BOOL srgb, struct wined3d_context *context) DECLSPEC_HIDDEN; -BOOL texture2d_load_renderbuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD dst_location) DECLSPEC_HIDDEN; -BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD dst_location) DECLSPEC_HIDDEN; -BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; - void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context) DECLSPEC_HIDDEN; void wined3d_texture_bind(struct wined3d_texture *texture, @@ -3351,20 +3304,12 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -void wined3d_texture_set_compatible_renderbuffer(struct wined3d_texture *texture, - unsigned int level, const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN; void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding) DECLSPEC_HIDDEN; void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture, - HWND window, RECT *rect) DECLSPEC_HIDDEN; void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box, - const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch, - unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb) DECLSPEC_HIDDEN; -void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_texture *src_texture, - unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) DECLSPEC_HIDDEN; + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) DECLSPEC_HIDDEN; void wined3d_texture_validate_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN; @@ -3412,6 +3357,49 @@ struct fbo_entry } key; }; +struct wined3d_surface +{ + struct wined3d_texture *container; + + unsigned int texture_level; + unsigned int texture_layer; + + /* For GetDC */ + HBITMAP bitmap; + HDC dc; + + struct list renderbuffers; + const struct wined3d_renderbuffer_entry *current_renderbuffer; +}; + +static inline unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface) +{ + return surface->texture_layer * surface->container->level_count + surface->texture_level; +} + +static inline struct wined3d_texture_sub_resource *surface_get_sub_resource(struct wined3d_surface *surface) +{ + return &surface->container->sub_resources[surface_get_sub_resource_idx(surface)]; +} + +HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, + const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, + struct wined3d_context *context) DECLSPEC_HIDDEN; +BOOL surface_load_location(struct wined3d_surface *surface, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, + const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN; +void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) 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(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect, + enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + struct wined3d_sampler { struct wine_rb_entry entry; @@ -3562,7 +3550,9 @@ struct wined3d_cs_queue struct wined3d_cs_ops { +#if defined(STAGING_CSMT) BOOL (*check_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id); +#endif /* STAGING_CSMT */ void *(*require_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id); void (*submit)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id); void (*finish)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id); @@ -3622,7 +3612,7 @@ void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect, - const RECT *dst_rect, HWND dst_window_override, unsigned int swap_interval, DWORD flags) DECLSPEC_HIDDEN; + const RECT *dst_rect, HWND dst_window_override, DWORD swap_interval, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state) DECLSPEC_HIDDEN; @@ -3653,7 +3643,7 @@ void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type UINT sampler_idx, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, enum wined3d_sampler_state state, DWORD value) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_count, const RECT *rects) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, @@ -3672,7 +3662,7 @@ void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined unsigned int initial_count) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count, const struct wined3d_viewport *viewports) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, @@ -3780,6 +3770,19 @@ struct wined3d_rendertarget_view struct wined3d_view_desc desc; }; +static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface( + const struct wined3d_rendertarget_view *view) +{ + struct wined3d_texture *texture; + + if (!view || view->resource->type != WINED3D_RTYPE_TEXTURE_2D) + return NULL; + + texture = texture_from_resource(view->resource); + + return texture->sub_resources[view->sub_resource_idx].u.surface; +} + void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarget_view *view, const struct wined3d_context *context, unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_view *view, @@ -3858,8 +3861,6 @@ struct wined3d_swapchain const struct wined3d_format *ds_format; struct wined3d_palette *palette; RECT front_buffer_update; - unsigned int swap_interval; - unsigned int max_frame_latency; LONG prev_time, frames; /* Performance tracking */ @@ -3874,14 +3875,11 @@ struct wined3d_swapchain }; void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN; -void wined3d_swapchain_set_swap_interval(struct wined3d_swapchain *swapchain, - unsigned int swap_interval) 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; void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, - const struct wined3d_device *device) DECLSPEC_HIDDEN; +void swapchain_update_swap_interval(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; /***************************************************************************** * Utility function prototypes @@ -3956,7 +3954,6 @@ void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DECLSPEC_HIDDEN; -enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type) DECLSPEC_HIDDEN; /* Math utils */ void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1, @@ -4153,14 +4150,13 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) /* oPos */ return FALSE; - case WINED3DSPR_CONSTBOOL: /* b# */ case WINED3DSPR_DEPTHOUT: /* oDepth */ case WINED3DSPR_DEPTHOUTGE: case WINED3DSPR_DEPTHOUTLE: + case WINED3DSPR_CONSTBOOL: /* b# */ case WINED3DSPR_LOOP: /* aL */ case WINED3DSPR_PREDICATE: /* p0 */ case WINED3DSPR_PRIMID: /* primID */ - case WINED3DSPR_SAMPLEMASK: /* oMask */ return TRUE; case WINED3DSPR_MISCTYPE: @@ -4183,28 +4179,24 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) } static inline void shader_get_position_fixup(const struct wined3d_context *context, - const struct wined3d_state *state, unsigned int fixup_count, float *position_fixup) + const struct wined3d_state *state, float *position_fixup) { float center_offset; - unsigned int i; if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; - for (i = 0; i < fixup_count; ++i) - { - position_fixup[4 * i ] = 1.0f; - position_fixup[4 * i + 1] = 1.0f; - position_fixup[4 * i + 2] = center_offset / state->viewports[i].width; - position_fixup[4 * i + 3] = -center_offset / state->viewports[i].height; + position_fixup[0] = 1.0f; + position_fixup[1] = 1.0f; + position_fixup[2] = center_offset / state->viewport.width; + position_fixup[3] = -center_offset / state->viewport.height; - if (context->render_offscreen) - { - position_fixup[4 * i + 1] *= -1.0f; - position_fixup[4 * i + 3] *= -1.0f; - } + if (context->render_offscreen) + { + position_fixup[1] *= -1.0f; + position_fixup[3] *= -1.0f; } } @@ -4308,8 +4300,8 @@ struct wined3d_rational 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_color_key *colour_key); + 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 @@ -4527,6 +4519,15 @@ static inline void wined3d_insert_bits(DWORD *bitstream, } } +static inline struct wined3d_surface *context_get_rt_surface(const struct wined3d_context *context) +{ + struct wined3d_texture *texture = context->current_rt.texture; + + if (!texture) + return NULL; + return texture->sub_resources[context->current_rt.sub_resource_idx].u.surface; +} + static inline void wined3d_from_cs(const struct wined3d_cs *cs) { if (cs->thread) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 74f5027954f..c6f0d42d836 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -22,13 +22,13 @@ sdk/tools/wpp # Synced to WineStaging-2.9 The following libraries are shared with Wine. dll/directx/wine/amstream # Synced to WineStaging-3.9 -dll/directx/wine/d3d8 # Synced to WineStaging-3.9 -dll/directx/wine/d3d9 # Synced to WineStaging-3.9 -dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-4.0 +dll/directx/wine/d3d8 # Synced to WineStaging-3.3 +dll/directx/wine/d3d9 # Synced to WineStaging-3.3 +dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-3.3 dll/directx/wine/d3drm # Synced to WineStaging-4.0 dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-4.0 dll/directx/wine/d3dxof # Synced to WineStaging-3.17 -dll/directx/wine/ddraw # Synced to WineStaging-3.9 +dll/directx/wine/ddraw # Synced to WineStaging-3.3 dll/directx/wine/devenum # Synced to WineStaging-3.9 dll/directx/wine/dinput # Synced to WineStaging-4.0 dll/directx/wine/dinput8 # Synced to WineStaging-3.3 @@ -41,7 +41,7 @@ dll/directx/wine/dxdiagn # Synced to WineStaging-3.3 dll/directx/wine/msdmo # Synced to WineStaging-3.17 dll/directx/wine/qedit # Synced to WineStaging-3.17 dll/directx/wine/quartz # Synced to WineStaging-3.9 -dll/directx/wine/wined3d # Synced to WineStaging-3.9 +dll/directx/wine/wined3d # Synced to WineStaging-3.3 dll/win32/activeds # Synced to WineStaging-3.3 dll/win32/actxprxy # Synced to WineStaging-3.3 diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h index dab9371330d..1f8171d9c6b 100644 --- a/sdk/include/reactos/wine/wined3d.h +++ b/sdk/include/reactos/wine/wined3d.h @@ -388,11 +388,12 @@ enum wined3d_render_state WINED3D_RS_SRCBLENDALPHA = 207, WINED3D_RS_DESTBLENDALPHA = 208, WINED3D_RS_BLENDOPALPHA = 209, - WINED3D_RS_DEPTHBIASCLAMP = 210, - WINED3D_RS_COLORWRITEENABLE4 = 211, - WINED3D_RS_COLORWRITEENABLE5 = 212, - WINED3D_RS_COLORWRITEENABLE6 = 213, - WINED3D_RS_COLORWRITEENABLE7 = 214, + WINED3D_RS_DEPTHCLIP = 210, + WINED3D_RS_DEPTHBIASCLAMP = 211, + WINED3D_RS_COLORWRITEENABLE4 = 212, + WINED3D_RS_COLORWRITEENABLE5 = 213, + WINED3D_RS_COLORWRITEENABLE6 = 214, + WINED3D_RS_COLORWRITEENABLE7 = 215, }; #define WINEHIGHEST_RENDER_STATE WINED3D_RS_COLORWRITEENABLE7 @@ -530,16 +531,6 @@ enum wined3d_swap_effect WINED3D_SWAP_EFFECT_OVERLAY, }; -enum wined3d_swap_interval -{ - WINED3D_SWAP_INTERVAL_IMMEDIATE = 0, - WINED3D_SWAP_INTERVAL_ONE = 1, - WINED3D_SWAP_INTERVAL_TWO = 2, - WINED3D_SWAP_INTERVAL_THREE = 3, - WINED3D_SWAP_INTERVAL_FOUR = 4, - WINED3D_SWAP_INTERVAL_DEFAULT = ~0u, -}; - enum wined3d_sampler_state { WINED3D_SAMP_ADDRESS_U = 1, @@ -599,7 +590,7 @@ enum wined3d_texture_stage_state WINED3D_TSS_ALPHA_ARG0 = 15, WINED3D_TSS_RESULT_ARG = 16, WINED3D_TSS_CONSTANT = 17, - WINED3D_TSS_INVALID = ~0u, + WINED3D_TSS_INVALID = ~0U, }; #define WINED3D_HIGHEST_TEXTURE_STATE WINED3D_TSS_CONSTANT @@ -949,6 +940,13 @@ enum wined3d_shader_byte_code_format #define WINED3DPRESENT_RATE_DEFAULT 0x00000000 +#define WINED3DPRESENT_INTERVAL_DEFAULT 0x00000000 +#define WINED3DPRESENT_INTERVAL_ONE 0x00000001 +#define WINED3DPRESENT_INTERVAL_TWO 0x00000002 +#define WINED3DPRESENT_INTERVAL_THREE 0x00000004 +#define WINED3DPRESENT_INTERVAL_FOUR 0x00000008 +#define WINED3DPRESENT_INTERVAL_IMMEDIATE 0x80000000 + #define WINED3DCLIPPLANE0 (1u << 0) #define WINED3DCLIPPLANE1 (1u << 1) #define WINED3DCLIPPLANE2 (1u << 2) @@ -1328,6 +1326,8 @@ enum wined3d_shader_byte_code_format #define WINED3D_NO_PRIMITIVE_RESTART 0x00000800 #define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000 #define WINED3D_NORMALIZED_DEPTH_BIAS 0x00002000 +#define WINED3D_REQUEST_D3D10 0x00004000 +#define WINED3D_LIMIT_VIEWPORT 0x00008000 #define WINED3D_RESZ_CODE 0x7fa05000 @@ -1576,8 +1576,6 @@ enum wined3d_shader_byte_code_format #define WINED3D_VIEW_TEXTURE_CUBE 0x00000008 #define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010 -#define WINED3D_MAX_VIEWPORTS 16 - struct wined3d_display_mode { UINT width; @@ -1731,10 +1729,10 @@ struct wined3d_adapter_identifier struct wined3d_swapchain_desc { - unsigned int backbuffer_width; - unsigned int backbuffer_height; + UINT backbuffer_width; + UINT backbuffer_height; enum wined3d_format_id backbuffer_format; - unsigned int backbuffer_count; + UINT backbuffer_count; DWORD backbuffer_usage; enum wined3d_multisample_type multisample_type; DWORD multisample_quality; @@ -1744,7 +1742,8 @@ struct wined3d_swapchain_desc BOOL enable_auto_depth_stencil; enum wined3d_format_id auto_depth_stencil_format; DWORD flags; - unsigned int refresh_rate; + UINT refresh_rate; + UINT swap_interval; BOOL auto_restore_display_mode; }; @@ -1890,6 +1889,7 @@ typedef struct _WINED3DCAPS DWORD Caps; DWORD Caps2; DWORD Caps3; + DWORD PresentationIntervals; DWORD CursorCaps; DWORD DevCaps; @@ -2008,7 +2008,6 @@ struct wined3d_blend_state_desc struct wined3d_rasterizer_state_desc { BOOL front_ccw; - BOOL depth_clip; }; struct wined3d_sampler_desc @@ -2139,8 +2138,11 @@ struct wined3d_device_parent_ops void (__cdecl *wined3d_device_created)(struct wined3d_device_parent *device_parent, struct wined3d_device *device); void (__cdecl *mode_changed)(struct wined3d_device_parent *device_parent); void (__cdecl *activate)(struct wined3d_device_parent *device_parent, BOOL activate); - HRESULT (__cdecl *texture_sub_resource_created)(struct wined3d_device_parent *device_parent, - enum wined3d_resource_type type, struct wined3d_texture *texture, unsigned int sub_resource_idx, + HRESULT (__cdecl *surface_created)(struct wined3d_device_parent *device_parent, + struct wined3d_texture *texture, unsigned int sub_resource_idx, + void **parent, const struct wined3d_parent_ops **parent_ops); + HRESULT (__cdecl *volume_created)(struct wined3d_device_parent *device_parent, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops); HRESULT (__cdecl *create_swapchain_texture)(struct wined3d_device_parent *device_parent, void *parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, struct wined3d_texture **texture); @@ -2237,7 +2239,7 @@ void __cdecl wined3d_device_copy_resource(struct wined3d_device *device, HRESULT __cdecl wined3d_device_copy_sub_resource_region(struct wined3d_device *device, struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource, - unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, unsigned int flags); + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box); void __cdecl wined3d_device_copy_uav_counter(struct wined3d_device *device, struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav); HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, @@ -2304,7 +2306,6 @@ HRESULT __cdecl wined3d_device_get_light(const struct wined3d_device *device, UINT light_idx, struct wined3d_light *light); HRESULT __cdecl wined3d_device_get_light_enable(const struct wined3d_device *device, UINT light_idx, BOOL *enable); void __cdecl wined3d_device_get_material(const struct wined3d_device *device, struct wined3d_material *material); -unsigned int __cdecl wined3d_device_get_max_frame_latency(const struct wined3d_device *device); float __cdecl wined3d_device_get_npatch_mode(const struct wined3d_device *device); struct wined3d_shader * __cdecl wined3d_device_get_pixel_shader(const struct wined3d_device *device); struct wined3d_query * __cdecl wined3d_device_get_predication(struct wined3d_device *device, BOOL *value); @@ -2328,8 +2329,7 @@ struct wined3d_rendertarget_view * __cdecl wined3d_device_get_rendertarget_view( unsigned int view_idx); DWORD __cdecl wined3d_device_get_sampler_state(const struct wined3d_device *device, UINT sampler_idx, enum wined3d_sampler_state state); -void __cdecl wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count, - RECT *rect); +void __cdecl wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect); BOOL __cdecl wined3d_device_get_software_vertex_processing(const struct wined3d_device *device); struct wined3d_buffer * __cdecl wined3d_device_get_stream_output(struct wined3d_device *device, UINT idx, UINT *offset); @@ -2349,8 +2349,7 @@ struct wined3d_unordered_access_view * __cdecl wined3d_device_get_unordered_acce const struct wined3d_device *device, unsigned int idx); struct wined3d_vertex_declaration * __cdecl wined3d_device_get_vertex_declaration(const struct wined3d_device *device); struct wined3d_shader * __cdecl wined3d_device_get_vertex_shader(const struct wined3d_device *device); -void __cdecl wined3d_device_get_viewports(const struct wined3d_device *device, unsigned int *viewport_count, - struct wined3d_viewport *viewports); +void __cdecl wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport); struct wined3d_buffer * __cdecl wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx); HRESULT __cdecl wined3d_device_get_vs_consts_b(const struct wined3d_device *device, unsigned int start_idx, unsigned int count, BOOL *constants); @@ -2426,7 +2425,6 @@ HRESULT __cdecl wined3d_device_set_light(struct wined3d_device *device, UINT light_idx, const struct wined3d_light *light); HRESULT __cdecl wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable); void __cdecl wined3d_device_set_material(struct wined3d_device *device, const struct wined3d_material *material); -void __cdecl wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int max_frame_latency); void __cdecl wined3d_device_set_multithreaded(struct wined3d_device *device); HRESULT __cdecl wined3d_device_set_npatch_mode(struct wined3d_device *device, float segments); void __cdecl wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader); @@ -2452,8 +2450,7 @@ HRESULT __cdecl wined3d_device_set_rendertarget_view(struct wined3d_device *devi unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport); void __cdecl wined3d_device_set_sampler_state(struct wined3d_device *device, UINT sampler_idx, enum wined3d_sampler_state state, DWORD value); -void __cdecl wined3d_device_set_scissor_rects(struct wined3d_device *device, - unsigned int rect_count, const RECT *rect); +void __cdecl wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect); void __cdecl wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software); void __cdecl wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer, UINT offset); @@ -2470,8 +2467,7 @@ void __cdecl wined3d_device_set_unordered_access_view(struct wined3d_device *dev void __cdecl wined3d_device_set_vertex_declaration(struct wined3d_device *device, struct wined3d_vertex_declaration *declaration); void __cdecl wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader); -void __cdecl wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count, - const struct wined3d_viewport *viewports); +void __cdecl wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport); void __cdecl wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer); HRESULT __cdecl wined3d_device_set_vs_consts_b(struct wined3d_device *device, unsigned int start_idx, unsigned int count, const BOOL *constants); @@ -2488,7 +2484,7 @@ HRESULT __cdecl wined3d_device_uninit_3d(struct wined3d_device *device); HRESULT __cdecl wined3d_device_uninit_gdi(struct wined3d_device *device); void __cdecl wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, - unsigned int depth_pitch, unsigned int flags); + unsigned int depth_pitch); HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device, struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture); HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes); @@ -2689,8 +2685,8 @@ void __cdecl wined3d_swapchain_get_desc(const struct wined3d_swapchain *swapchai HRESULT __cdecl wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain, struct wined3d_raster_status *raster_status); ULONG __cdecl wined3d_swapchain_incref(struct wined3d_swapchain *swapchain); -HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, - const RECT *dst_rect, HWND dst_window_override, unsigned int swap_interval, DWORD flags); +HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, + const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD swap_interval, DWORD flags); HRESULT __cdecl wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count, unsigned int width, unsigned int height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality);