https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7af3969e9fe68b5f55a08…
commit 7af3969e9fe68b5f55a088f93a6b69570822c733
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Sun May 27 03:52:04 2018 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Sun May 27 03:52:04 2018 +0100
[D3D8][D3D9][DDRAW][WINED3D] Sync with Wine Staging 3.9. CORE-14656
---
dll/directx/wine/d3d8/d3d8_private.h | 3 +-
dll/directx/wine/d3d8/device.c | 201 +-
dll/directx/wine/d3d8/directx.c | 2 +-
dll/directx/wine/d3d8/swapchain.c | 9 +-
dll/directx/wine/d3d9/d3d9_private.h | 6 +-
dll/directx/wine/d3d9/device.c | 189 +-
dll/directx/wine/d3d9/directx.c | 8 +-
dll/directx/wine/d3d9/swapchain.c | 34 +-
dll/directx/wine/d3d9/texture.c | 17 +-
dll/directx/wine/ddraw/ddraw.c | 49 +-
dll/directx/wine/ddraw/ddraw_private.h | 7 +-
dll/directx/wine/ddraw/device.c | 56 +-
dll/directx/wine/ddraw/executebuffer.c | 23 +-
dll/directx/wine/ddraw/palette.c | 2 +-
dll/directx/wine/ddraw/surface.c | 71 +-
dll/directx/wine/ddraw/utils.c | 4 +-
dll/directx/wine/ddraw/viewport.c | 257 +--
dll/directx/wine/wined3d/arb_program_shader.c | 359 ++--
dll/directx/wine/wined3d/ati_fragment_shader.c | 37 +-
dll/directx/wine/wined3d/buffer.c | 10 +-
dll/directx/wine/wined3d/context.c | 1402 ++++++++++----
dll/directx/wine/wined3d/cs.c | 180 +-
dll/directx/wine/wined3d/device.c | 373 ++--
dll/directx/wine/wined3d/directx.c | 88 +-
dll/directx/wine/wined3d/glsl_shader.c | 1159 +++++++++++-
dll/directx/wine/wined3d/nvidia_texture_shader.c | 3 +
dll/directx/wine/wined3d/resource.c | 25 +-
dll/directx/wine/wined3d/shader.c | 230 ++-
dll/directx/wine/wined3d/shader_sm4.c | 79 +-
dll/directx/wine/wined3d/state.c | 888 ++-------
dll/directx/wine/wined3d/stateblock.c | 34 +-
dll/directx/wine/wined3d/surface.c | 1252 ++++---------
dll/directx/wine/wined3d/swapchain.c | 111 +-
dll/directx/wine/wined3d/texture.c | 2188 ++++++++++------------
dll/directx/wine/wined3d/utils.c | 149 +-
dll/directx/wine/wined3d/view.c | 18 +-
dll/directx/wine/wined3d/wined3d.spec | 16 +-
dll/directx/wine/wined3d/wined3d_gl.h | 3 +-
dll/directx/wine/wined3d/wined3d_main.c | 15 +-
dll/directx/wine/wined3d/wined3d_private.h | 313 ++--
media/doc/README.WINE | 8 +-
sdk/include/reactos/wine/wined3d.h | 74 +-
42 files changed, 5257 insertions(+), 4695 deletions(-)
diff --git a/dll/directx/wine/d3d8/d3d8_private.h b/dll/directx/wine/d3d8/d3d8_private.h
index cba5dd647b..3fbc096b25 100644
--- a/dll/directx/wine/d3d8/d3d8_private.h
+++ b/dll/directx/wine/d3d8/d3d8_private.h
@@ -166,10 +166,11 @@ 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,
- struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN;
+ unsigned int swap_interval, 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 5daf6f46c2..616886bcaf 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)
+ const struct wined3d_swapchain_desc *swapchain_desc, DWORD
presentation_interval)
{
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 =
swapchain_desc->swap_interval;
+ present_parameters->FullScreen_PresentationInterval = presentation_interval;
}
static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT
effect)
@@ -245,6 +245,27 @@ 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)
{
@@ -261,6 +282,20 @@ 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;
@@ -278,7 +313,6 @@ 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)
@@ -294,7 +328,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 = wined3d_caps->PresentationIntervals;
+ caps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE |
D3DPRESENT_INTERVAL_ONE;
caps->CursorCaps = wined3d_caps->CursorCaps;
caps->DevCaps = wined3d_caps->DevCaps;
caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps;
@@ -343,6 +377,57 @@ 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);
@@ -353,8 +438,6 @@ 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 */
@@ -698,7 +781,8 @@ static HRESULT WINAPI
d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
struct wined3d_swapchain_desc desc;
struct d3d8_swapchain *object;
- UINT i, count;
+ unsigned int swap_interval;
+ unsigned int i, count;
HRESULT hr;
TRACE("iface %p, present_parameters %p, swapchain %p.\n",
@@ -730,9 +814,11 @@ static HRESULT WINAPI
d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if
if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters))
return D3DERR_INVALIDCALL;
- if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object)))
+ swap_interval =
wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval);
+ if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, swap_interval,
&object)))
*swapchain = &object->IDirect3DSwapChain8_iface;
- present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
+ present_parameters_from_wined3d_swapchain_desc(present_parameters,
+ &desc, present_parameters->FullScreen_PresentationInterval);
return hr;
}
@@ -806,6 +892,8 @@ 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);
@@ -1531,10 +1619,30 @@ 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;
@@ -1542,8 +1650,7 @@ static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8
*iface, const D3D
vp.min_z = viewport->MinZ;
vp.max_z = viewport->MaxZ;
- wined3d_mutex_lock();
- wined3d_device_set_viewport(device->wined3d_device, &vp);
+ wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
wined3d_mutex_unlock();
return D3D_OK;
@@ -1557,7 +1664,7 @@ static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8
*iface, D3DVIEWPO
TRACE("iface %p, viewport %p.\n", iface, viewport);
wined3d_mutex_lock();
- wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
+ wined3d_device_get_viewports(device->wined3d_device, NULL,
&wined3d_viewport);
wined3d_mutex_unlock();
viewport->X = wined3d_viewport.x;
@@ -2080,9 +2187,11 @@ 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)
{
- FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface,
info_id, info, info_size);
+ TRACE("iface %p, info_id %#x, info %p, info_size %u.\n", iface, info_id,
info, info_size);
- return D3D_OK;
+ if (info_id < 4)
+ return E_FAIL;
+ return S_FALSE;
}
static HRESULT WINAPI d3d8_device_SetPaletteEntries(IDirect3DDevice8 *iface,
@@ -3162,40 +3271,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_surface_created(struct wined3d_device_parent
*device_parent,
- struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+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,
void **parent, const struct wined3d_parent_ops **parent_ops)
{
- struct d3d8_surface *d3d_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);
-
- 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);
-
- return D3D_OK;
-}
+ if (type == WINED3D_RTYPE_TEXTURE_2D)
+ {
+ struct d3d8_surface *d3d_surface;
-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;
+ if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
+ return E_OUTOFMEMORY;
- 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);
+ 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;
- if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
- return E_OUTOFMEMORY;
+ 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);
+ 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;
+ }
return D3D_OK;
}
@@ -3234,7 +3343,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, &d3d_swapchain)))
+ if (FAILED(hr = d3d8_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT,
&d3d_swapchain)))
{
WARN("Failed to create swapchain, hr %#x.\n", hr);
*swapchain = NULL;
@@ -3253,8 +3362,7 @@ 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_surface_created,
- device_parent_volume_created,
+ device_parent_texture_sub_resource_created,
device_parent_create_swapchain_texture,
device_parent_create_swapchain,
};
@@ -3356,7 +3464,8 @@ 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);
+ present_parameters_from_wined3d_swapchain_desc(parameters,
+ &swapchain_desc, parameters->FullScreen_PresentationInterval);
device->declArraySize = 16;
if (!(device->decls = heap_alloc(device->declArraySize *
sizeof(*device->decls))))
@@ -3368,6 +3477,8 @@ 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 6e8f93a25c..68300c0a65 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_LIMIT_VIEWPORT;
+ | WINED3D_LEGACY_CUBEMAP_FILTERING;
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 3a588b5e8c..39e3b23873 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, 0, 0);
+ src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0);
wined3d_mutex_unlock();
return hr;
@@ -167,12 +167,13 @@ 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)
+ struct wined3d_swapchain_desc *desc, unsigned int swap_interval)
{
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,
@@ -192,7 +193,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,
- struct d3d8_swapchain **swapchain)
+ unsigned int swap_interval, struct d3d8_swapchain **swapchain)
{
struct d3d8_swapchain *object;
HRESULT hr;
@@ -200,7 +201,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)))
+ if (FAILED(hr = swapchain_init(object, device, desc, swap_interval)))
{
WARN("Failed to initialize swapchain, hr %#x.\n", hr);
heap_free(object);
diff --git a/dll/directx/wine/d3d9/d3d9_private.h b/dll/directx/wine/d3d9/d3d9_private.h
index ba19e5fb08..c50aabf593 100644
--- a/dll/directx/wine/d3d9/d3d9_private.h
+++ b/dll/directx/wine/d3d9/d3d9_private.h
@@ -57,7 +57,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) DECLSPEC_HIDDEN;
+ const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval)
DECLSPEC_HIDDEN;
void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps)
DECLSPEC_HIDDEN;
struct d3d9
@@ -101,7 +101,6 @@ 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;
@@ -151,10 +150,11 @@ 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,
- struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN;
+ unsigned int swap_interval, 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 bc73699e52..2f3ad2880d 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)
+ const struct wined3d_swapchain_desc *swapchain_desc, DWORD
presentation_interval)
{
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 = swapchain_desc->swap_interval;
+ present_parameters->PresentationInterval = presentation_interval;
}
static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT
effect)
@@ -270,6 +270,27 @@ 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)
{
@@ -288,6 +309,19 @@ 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;
@@ -305,7 +339,6 @@ 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)
@@ -330,7 +363,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 = wined3d_caps->PresentationIntervals;
+ caps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE |
D3DPRESENT_INTERVAL_ONE;
caps->CursorCaps = wined3d_caps->CursorCaps;
caps->DevCaps = wined3d_caps->DevCaps;
caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps;
@@ -743,7 +776,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d9_device_CreateAdditionalSwapChain(ID
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
struct wined3d_swapchain_desc desc;
struct d3d9_swapchain *object;
- UINT i, count;
+ unsigned int swap_interval;
+ unsigned int i, count;
HRESULT hr;
TRACE("iface %p, present_parameters %p, swapchain %p.\n",
@@ -776,9 +810,11 @@ 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;
- if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object)))
+ swap_interval =
wined3dswapinterval_from_d3d(present_parameters->PresentationInterval);
+ if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, swap_interval,
&object)))
*swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface;
- present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
+ present_parameters_from_wined3d_swapchain_desc(present_parameters,
+ &desc, present_parameters->PresentationInterval);
return hr;
}
@@ -934,6 +970,8 @@ 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;
@@ -943,10 +981,6 @@ 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)
@@ -976,7 +1010,8 @@ 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);
- UINT i;
+ struct d3d9_swapchain *swapchain;
+ unsigned int i;
HRESULT hr;
TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region
%p.\n",
@@ -991,8 +1026,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d9_device_Present(IDirect3DDevice9Ex *
wined3d_mutex_lock();
for (i = 0; i < device->implicit_swapchain_count; ++i)
{
- if (FAILED(hr =
wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
- src_rect, dst_rect, dst_window_override, 0, 0)))
+ 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)))
{
wined3d_mutex_unlock();
return hr;
@@ -1500,7 +1536,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);
+ src->sub_resource_idx, &src_box, 0);
if (SUCCEEDED(hr) && dst->texture)
d3d9_texture_flag_auto_gen_mipmap(dst->texture);
@@ -2032,7 +2068,7 @@ static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex
*iface, const D
vp.max_z = viewport->MaxZ;
wined3d_mutex_lock();
- wined3d_device_set_viewport(device->wined3d_device, &vp);
+ wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
wined3d_mutex_unlock();
return D3D_OK;
@@ -2046,7 +2082,7 @@ static HRESULT WINAPI d3d9_device_GetViewport(IDirect3DDevice9Ex
*iface, D3DVIEW
TRACE("iface %p, viewport %p.\n", iface, viewport);
wined3d_mutex_lock();
- wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
+ wined3d_device_get_viewports(device->wined3d_device, NULL,
&wined3d_viewport);
wined3d_mutex_unlock();
viewport->X = wined3d_viewport.x;
@@ -2362,13 +2398,6 @@ 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;
@@ -2535,7 +2564,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_rect(device->wined3d_device, rect);
+ wined3d_device_set_scissor_rects(device->wined3d_device, 1, rect);
wined3d_mutex_unlock();
return D3D_OK;
@@ -2548,7 +2577,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_rect(device->wined3d_device, rect);
+ wined3d_device_get_scissor_rects(device->wined3d_device, NULL, rect);
wined3d_mutex_unlock();
return D3D_OK;
@@ -2612,11 +2641,15 @@ 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)
{
- unsigned int i;
+ struct wined3d_texture *texture;
+ unsigned int i, stage;
- for (i = 0; i < ARRAY_SIZE(device->textures); ++i)
- if (device->textures[i])
- d3d9_texture_gen_auto_mipmap(device->textures[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));
+ }
}
static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
@@ -3667,7 +3700,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d9_device_PresentEx(IDirect3DDevice9Ex
const RGNDATA *dirty_region, DWORD flags)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
- UINT i;
+ struct d3d9_swapchain *swapchain;
+ unsigned int i;
HRESULT hr;
TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region
%p, flags %#x.\n",
@@ -3683,8 +3717,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d9_device_PresentEx(IDirect3DDevice9Ex
wined3d_mutex_lock();
for (i = 0; i < device->implicit_swapchain_count; ++i)
{
- if (FAILED(hr =
wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
- src_rect, dst_rect, dst_window_override, 0, flags)))
+ 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)))
{
wined3d_mutex_unlock();
return hr;
@@ -3727,21 +3762,31 @@ 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)
- FIXME("Ignoring max_latency %u.\n", 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();
return S_OK;
}
static HRESULT WINAPI d3d9_device_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT
*max_latency)
{
- FIXME("iface %p, max_latency %p stub!\n", iface, max_latency);
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
- *max_latency = 2;
+ TRACE("iface %p, max_latency %p.\n", iface, max_latency);
- return E_NOTIMPL;
+ wined3d_mutex_lock();
+ *max_latency = wined3d_device_get_max_frame_latency(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return S_OK;
}
static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND
dst_window)
@@ -4050,40 +4095,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_surface_created(struct wined3d_device_parent
*device_parent,
- struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+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,
void **parent, const struct wined3d_parent_ops **parent_ops)
{
- struct d3d9_surface *d3d_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);
-
- if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
- return E_OUTOFMEMORY;
+ if (type == WINED3D_RTYPE_TEXTURE_2D)
+ {
+ struct d3d9_surface *d3d_surface;
- surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
- *parent = d3d_surface;
- TRACE("Created surface %p.\n", d3d_surface);
+ if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
+ return E_OUTOFMEMORY;
- return D3D_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)
-{
- 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);
+ }
+ else if (type == WINED3D_RTYPE_TEXTURE_3D)
+ {
+ 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;
- 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);
+ 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;
+ }
return D3D_OK;
}
@@ -4128,8 +4173,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);
- hr = d3d9_swapchain_create(device, desc, &d3d_swapchain);
- if (FAILED(hr))
+ if (FAILED(hr = d3d9_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT,
&d3d_swapchain)))
{
WARN("Failed to create swapchain, hr %#x.\n", hr);
*swapchain = NULL;
@@ -4148,8 +4192,7 @@ 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_surface_created,
- device_parent_volume_created,
+ device_parent_texture_sub_resource_created,
device_parent_create_swapchain_texture,
device_parent_create_swapchain,
};
@@ -4272,10 +4315,16 @@ 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]);
+ present_parameters_from_wined3d_swapchain_desc(¶meters[i],
+ &swapchain_desc[i], parameters[i].PresentationInterval);
}
wined3d_mutex_unlock();
diff --git a/dll/directx/wine/d3d9/directx.c b/dll/directx/wine/d3d9/directx.c
index 644766c2e9..98f4a99c49 100644
--- a/dll/directx/wine/d3d9/directx.c
+++ b/dll/directx/wine/d3d9/directx.c
@@ -254,6 +254,12 @@ 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)
{
@@ -579,7 +585,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_LIMIT_VIEWPORT;
+ | WINED3D_NORMALIZED_DEPTH_BIAS;
if (!extended)
flags |= WINED3D_VIDMEM_ACCOUNTING;
diff --git a/dll/directx/wine/d3d9/swapchain.c b/dll/directx/wine/d3d9/swapchain.c
index dbb3f45b91..d303f3f956 100644
--- a/dll/directx/wine/d3d9/swapchain.c
+++ b/dll/directx/wine/d3d9/swapchain.c
@@ -25,6 +25,27 @@
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);
@@ -137,7 +158,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, 0, flags);
+ src_rect, dst_rect, dst_window_override, swapchain->swap_interval,
flags);
wined3d_mutex_unlock();
return hr;
@@ -251,13 +272,15 @@ 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);
+ present_parameters_from_wined3d_swapchain_desc(parameters, &desc,
presentation_interval);
return D3D_OK;
}
@@ -344,12 +367,13 @@ 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)
+ struct wined3d_swapchain_desc *desc, unsigned int swap_interval)
{
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,
@@ -369,7 +393,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,
- struct d3d9_swapchain **swapchain)
+ unsigned int swap_interval, struct d3d9_swapchain **swapchain)
{
struct d3d9_swapchain *object;
HRESULT hr;
@@ -377,7 +401,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)))
+ if (FAILED(hr = swapchain_init(object, device, desc, swap_interval)))
{
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 c97fa6b021..7b74ac5b9e 100644
--- a/dll/directx/wine/d3d9/texture.c
+++ b/dll/directx/wine/d3d9/texture.c
@@ -1339,9 +1339,22 @@ 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;
}
- flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
+ 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;
+ }
texture->autogen_filter_type = D3DTEXF_LINEAR;
- levels = 0;
}
else
{
diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c
index e5205c0d00..6b5ccece46 100644
--- a/dll/directx/wine/ddraw/ddraw.c
+++ b/dll/directx/wine/ddraw/ddraw.c
@@ -633,8 +633,9 @@ 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 = WINED3DUSAGE_RENDERTARGET;
- swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
+ swapchain_desc.backbuffer_usage = 0;
+ swapchain_desc.backbuffer_count = 1;
+ swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD;
swapchain_desc.device_window = window;
swapchain_desc.windowed = windowed;
swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
@@ -2099,7 +2100,7 @@ static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface)
ddraw->flags |= DDRAW_GDI_FLIP;
if (ddraw->primary)
- ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE);
+ ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE, 0);
return DD_OK;
}
@@ -4909,18 +4910,19 @@ void ddraw_update_lost_surfaces(struct ddraw *ddraw)
ddraw->device_state = DDRAW_DEVICE_STATE_OK;
}
-static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
*device_parent,
- struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+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,
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, wined3d_texture %p, sub_resource_idx %u, parent %p,
parent_ops %p.\n",
- device_parent, wined3d_texture, sub_resource_idx, parent, 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);
/* We have a swapchain or wined3d internal texture. */
- if (!wined3d_texture_get_parent(wined3d_texture) ||
wined3d_texture_get_parent(wined3d_texture) == ddraw)
+ if (type != WINED3D_RTYPE_TEXTURE_2D || !wined3d_texture_get_parent(wined3d_texture)
+ || wined3d_texture_get_parent(wined3d_texture) == ddraw)
{
*parent = NULL;
*parent_ops = &ddraw_null_wined3d_parent_ops;
@@ -4945,19 +4947,6 @@ static HRESULT CDECL device_parent_surface_created(struct
wined3d_device_parent
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;
@@ -4974,25 +4963,26 @@ 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)
- {
- ERR("Frontbuffer already created.\n");
- return E_FAIL;
- }
+ if (!ddraw->wined3d_frontbuffer)
+ parent_ops = &ddraw_frontbuffer_parent_ops;
+ else
+ parent_ops = &ddraw_null_wined3d_parent_ops;
if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, 1,
- texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw,
&ddraw_frontbuffer_parent_ops, texture)))
+ texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, parent_ops,
texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- ddraw->wined3d_frontbuffer = *texture;
+ if (!ddraw->wined3d_frontbuffer)
+ ddraw->wined3d_frontbuffer = *texture;
return hr;
}
@@ -5023,8 +5013,7 @@ 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_surface_created,
- device_parent_volume_created,
+ device_parent_texture_sub_resource_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 1454e8012a..9757008e92 100644
--- a/dll/directx/wine/ddraw/ddraw_private.h
+++ b/dll/directx/wine/ddraw/ddraw_private.h
@@ -59,14 +59,15 @@ struct FvfToDecl
#define DDRAW_NO3D 0x00000008
#define DDRAW_SCL_DDRAW1 0x00000010
#define DDRAW_SCL_RECURSIVE 0x00000020
-#define DDRAW_GDI_FLIP 0x00000040
+#define DDRAW_SWAPPED 0x00000040
+#define DDRAW_GDI_FLIP 0x00000080
#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_LIMIT_VIEWPORT)
+ | WINED3D_LEGACY_CUBEMAP_FILTERING)
enum ddraw_device_state
{
@@ -220,7 +221,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) DECLSPEC_HIDDEN;
+ const RECT *rect, BOOL read, unsigned int swap_interval) 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 24dbd3be50..799b2bcaa0 100644
--- a/dll/directx/wine/ddraw/device.c
+++ b/dll/directx/wine/ddraw/device.c
@@ -5296,25 +5296,12 @@ 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);
@@ -5322,6 +5309,23 @@ 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;
@@ -5329,8 +5333,7 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface,
D3DVIEWPORT7 *vi
vp.min_z = viewport->dvMinZ;
vp.max_z = viewport->dvMaxZ;
- wined3d_mutex_lock();
- wined3d_device_set_viewport(device->wined3d_device, &vp);
+ wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
wined3d_mutex_unlock();
return D3D_OK;
@@ -5353,21 +5356,6 @@ 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);
@@ -5379,7 +5367,7 @@ static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface,
D3DVIEWPORT7 *vi
return DDERR_INVALIDPARAMS;
wined3d_mutex_lock();
- wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
+ wined3d_device_get_viewports(device->wined3d_device, NULL,
&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 17bea2764c..e2c4fc11ab 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);
+
wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box, 0);
break;
default:
@@ -610,9 +610,16 @@ 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;
@@ -659,7 +666,7 @@ static HRESULT WINAPI
d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
buffer->src_vertex_pos = 0;
}
- if (data->dwVertexCount)
+ if (data->dwVertexCount && (!buf_size || data->dwVertexOffset <
buf_size))
{
box.left = buffer->src_vertex_pos * sizeof(D3DVERTEX);
box.right = box.left + data->dwVertexCount * sizeof(D3DVERTEX);
@@ -667,8 +674,11 @@ static HRESULT WINAPI
d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
0, &map_desc, &box, WINED3D_MAP_WRITE)))
return hr;
- memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) +
data->dwVertexOffset,
- data->dwVertexCount * sizeof(D3DVERTEX));
+ 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);
wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->src_vertex_buffer),
0);
}
@@ -696,12 +706,11 @@ 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);
- dwSize = data->dwSize;
- memcpy(data, &buffer->data, dwSize);
+ /* Tests show that dwSize is ignored. */
+ memcpy(data, &buffer->data, sizeof(*data));
if (TRACE_ON(ddraw))
{
diff --git a/dll/directx/wine/ddraw/palette.c b/dll/directx/wine/ddraw/palette.c
index 5148832cab..87aec96443 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);
+ ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE, 0);
wined3d_mutex_unlock();
diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c
index 5eefc228e6..e188396eb3 100644
--- a/dll/directx/wine/ddraw/surface.c
+++ b/dll/directx/wine/ddraw/surface.c
@@ -40,15 +40,22 @@ 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)
+HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
+ const RECT *rect, BOOL read, unsigned int swap_interval)
{
- struct ddraw *ddraw = surface->ddraw;
+ struct wined3d_texture *dst_texture;
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);
@@ -63,15 +70,25 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface
*surface, const RE
if (w <= 0 || h <= 0)
return DD_OK;
- if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP))
+ if (surface->ddraw->swapchain_window && !(surface->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;
- return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect,
- surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL,
WINED3D_TEXF_POINT);
+ 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;
}
if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture,
surface->sub_resource_idx, &surface_dc)))
@@ -474,7 +491,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);
+ ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
}
if (palette_impl)
IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface);
@@ -990,7 +1007,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);
+ hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0);
if (SUCCEEDED(hr))
hr =
wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture),
surface->sub_resource_idx, &map_desc, rect ? &box : NULL,
@@ -1179,7 +1196,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);
+ hr = ddraw_surface_update_frontbuffer(surface,
&surface->ddraw->primary_lock, FALSE, 0);
wined3d_mutex_unlock();
return hr;
@@ -1224,6 +1241,24 @@ 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)
{
@@ -1337,7 +1372,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)
+ if (flags & ~(DDFLIP_NOVSYNC | DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 |
DDFLIP_INTERVAL4))
{
static UINT once;
if (!once++)
@@ -1347,7 +1382,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);
+ hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE,
ddraw_swap_interval_from_flags(flags));
else
hr = DD_OK;
@@ -1488,11 +1523,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);
+ hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0);
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);
+ hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0);
return hr;
}
@@ -1535,7 +1570,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)))
+ if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface,
&src_rect_clipped, TRUE, 0)))
break;
}
}
@@ -1546,7 +1581,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)))
+ if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface,
&clip_rect[i], FALSE, 0)))
break;
}
}
@@ -2219,7 +2254,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);
+ hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0);
if (SUCCEEDED(hr))
hr = wined3d_texture_get_dc(surface->wined3d_texture,
surface->sub_resource_idx, dc);
@@ -2321,7 +2356,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);
+ hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
}
wined3d_mutex_unlock();
@@ -4289,12 +4324,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);
+ hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0);
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);
+ hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0);
wined3d_mutex_unlock();
switch(hr)
diff --git a/dll/directx/wine/ddraw/utils.c b/dll/directx/wine/ddraw/utils.c
index 65f24dc13f..b0a028d4a5 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)))
+ if (!(flags & (DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS | DDLOCK_WRITEONLY)))
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_NODIRTYUPDATE);
+ flags &= ~(handled | DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_WRITEONLY |
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 6ef3226c4d..f2caf20858 100644
--- a/dll/directx/wine/ddraw/viewport.c
+++ b/dll/directx/wine/ddraw/viewport.c
@@ -249,109 +249,118 @@ static HRESULT WINAPI d3d_viewport_Initialize(IDirect3DViewport3
*iface, IDirect
return DDERR_ALREADYINITIALIZED;
}
-/*****************************************************************************
- * 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)
+static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT
*vp)
{
- struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
- DWORD dwSize;
+ struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
+ DWORD size;
+
+ TRACE("iface %p, vp %p.\n", iface, vp);
- TRACE("iface %p, data %p.\n", iface, lpData);
+ if (!vp)
+ return DDERR_INVALIDPARAMS;
wined3d_mutex_lock();
- dwSize = lpData->dwSize;
- if (!This->use_vp2)
- memcpy(lpData, &(This->viewports.vp1), dwSize);
- else {
+ size = vp->dwSize;
+ if (!viewport->use_vp2)
+ {
+ memcpy(vp, &viewport->viewports.vp1, size);
+ }
+ else
+ {
D3DVIEWPORT vp1;
+
vp1.dwSize = sizeof(vp1);
- 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.dwX = viewport->viewports.vp2.dwX;
+ vp1.dwY = viewport->viewports.vp2.dwY;
+ vp1.dwWidth = viewport->viewports.vp2.dwWidth;
+ vp1.dwHeight = viewport->viewports.vp2.dwHeight;
vp1.dvMaxX = 0.0;
vp1.dvMaxY = 0.0;
vp1.dvScaleX = 0.0;
vp1.dvScaleY = 0.0;
- vp1.dvMinZ = This->viewports.vp2.dvMinZ;
- vp1.dvMaxZ = This->viewports.vp2.dvMaxZ;
- memcpy(lpData, &vp1, dwSize);
+ vp1.dvMinZ = viewport->viewports.vp2.dvMinZ;
+ vp1.dvMaxZ = viewport->viewports.vp2.dvMaxZ;
+ memcpy(vp, &vp1, size);
}
if (TRACE_ON(ddraw))
{
TRACE(" returning D3DVIEWPORT :\n");
- _dump_D3DVIEWPORT(lpData);
+ _dump_D3DVIEWPORT(vp);
}
wined3d_mutex_unlock();
- return DD_OK;
+ return D3D_OK;
}
-/*****************************************************************************
- * 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)
+static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT
*vp)
{
- struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
+ 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;
IDirect3DViewport3 *current_viewport;
+ struct ddraw_surface *surface;
- TRACE("iface %p, data %p.\n", iface, lpData);
+ TRACE("iface %p, vp %p.\n", iface, vp);
+
+ if (!vp)
+ return DDERR_INVALIDPARAMS;
if (TRACE_ON(ddraw))
{
TRACE(" getting D3DVIEWPORT :\n");
- _dump_D3DVIEWPORT(lpData);
+ _dump_D3DVIEWPORT(vp);
}
- wined3d_mutex_lock();
-
- This->use_vp2 = 0;
- memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
- memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
+ if (!device)
+ {
+ WARN("Viewport not bound to a device, returning
D3DERR_VIEWPORTHASNODEVICE.\n");
+ return D3DERR_VIEWPORTHASNODEVICE;
+ }
- /* 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;
+ wined3d_mutex_lock();
- if (This->active_device)
+ if (device->version > 1)
{
- IDirect3DDevice3 *d3d_device3 =
&This->active_device->IDirect3DDevice3_iface;
- if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3,
¤t_viewport)))
+ 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 (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width -
vp->dwX
+ || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height -
vp->dwY)
{
- if (current_viewport == iface) viewport_activate(This, FALSE);
- IDirect3DViewport3_Release(current_viewport);
+ 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 DD_OK;
+ return D3D_OK;
}
/*****************************************************************************
@@ -882,53 +891,44 @@ static HRESULT WINAPI d3d_viewport_NextLight(IDirect3DViewport3
*iface,
* IDirect3DViewport2 Methods.
*****************************************************************************/
-/*****************************************************************************
- * 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)
+static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2
*vp)
{
- struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
- DWORD dwSize;
+ struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
+ DWORD size;
- TRACE("iface %p, data %p.\n", iface, lpData);
+ TRACE("iface %p, vp %p.\n", iface, vp);
+
+ if (!vp)
+ return DDERR_INVALIDPARAMS;
wined3d_mutex_lock();
- dwSize = lpData->dwSize;
- if (This->use_vp2)
- memcpy(lpData, &(This->viewports.vp2), dwSize);
- else {
+ size = vp->dwSize;
+ if (viewport->use_vp2)
+ {
+ memcpy(vp, &viewport->viewports.vp2, size);
+ }
+ else
+ {
D3DVIEWPORT2 vp2;
+
vp2.dwSize = sizeof(vp2);
- 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.dwX = viewport->viewports.vp1.dwX;
+ vp2.dwY = viewport->viewports.vp1.dwY;
+ vp2.dwWidth = viewport->viewports.vp1.dwWidth;
+ vp2.dwHeight = viewport->viewports.vp1.dwHeight;
vp2.dvClipX = 0.0;
vp2.dvClipY = 0.0;
vp2.dvClipWidth = 0.0;
vp2.dvClipHeight = 0.0;
- vp2.dvMinZ = This->viewports.vp1.dvMinZ;
- vp2.dvMaxZ = This->viewports.vp1.dvMaxZ;
- memcpy(lpData, &vp2, dwSize);
+ vp2.dvMinZ = viewport->viewports.vp1.dvMinZ;
+ vp2.dvMaxZ = viewport->viewports.vp1.dvMaxZ;
+ memcpy(vp, &vp2, size);
}
if (TRACE_ON(ddraw))
{
TRACE(" returning D3DVIEWPORT2 :\n");
- _dump_D3DVIEWPORT2(lpData);
+ _dump_D3DVIEWPORT2(vp);
}
wined3d_mutex_unlock();
@@ -936,47 +936,64 @@ static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3
*iface, D3DVI
return D3D_OK;
}
-/*****************************************************************************
- * 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)
+static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2
*vp)
{
- struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
+ 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;
IDirect3DViewport3 *current_viewport;
+ struct ddraw_surface *surface;
+
+ TRACE("iface %p, vp %p.\n", iface, vp);
- TRACE("iface %p, data %p.\n", iface, lpData);
+ if (!vp)
+ return DDERR_INVALIDPARAMS;
if (TRACE_ON(ddraw))
{
TRACE(" getting D3DVIEWPORT2 :\n");
- _dump_D3DVIEWPORT2(lpData);
+ _dump_D3DVIEWPORT2(vp);
}
- wined3d_mutex_lock();
+ if (!device)
+ {
+ WARN("Viewport not bound to a device, returning
D3DERR_VIEWPORTHASNODEVICE.\n");
+ return D3DERR_VIEWPORTHASNODEVICE;
+ }
- This->use_vp2 = 1;
- memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
- memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
+ wined3d_mutex_lock();
- if (This->active_device)
+ if (device->version > 1)
{
- IDirect3DDevice3 *d3d_device3 =
&This->active_device->IDirect3DDevice3_iface;
- if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3,
¤t_viewport)))
+ 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 (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width -
vp->dwX
+ || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height -
vp->dwY)
{
- if (current_viewport == iface) viewport_activate(This, FALSE);
- IDirect3DViewport3_Release(current_viewport);
+ 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();
return D3D_OK;
diff --git a/dll/directx/wine/wined3d/arb_program_shader.c
b/dll/directx/wine/wined3d/arb_program_shader.c
index f86c167b60..4fbb3a59ec 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, position_fixup);
+ shader_get_position_fixup(context, state, 1, 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 != vertexshader)
+ else if(ctx->cur_ps_args->super.vp_mode !=
WINED3D_VP_MODE_SHADER)
{
/* 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,9 +1416,6 @@ 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;
@@ -1432,12 +1429,8 @@ 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)
- && gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ &&
ins->ctx->gl_info->supported[ARB_TEXTURE_RECTANGLE])
tex_type = "RECT";
else
tex_type = "2D";
@@ -3422,73 +3415,68 @@ static void init_ps_input(const struct wined3d_shader *shader,
const char *semantic_name;
DWORD semantic_idx;
- switch(args->super.vp_mode)
- {
- 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;
+ if (args->super.vp_mode == WINED3D_VP_MODE_SHADER)
+ {
+ /* 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;
+ }
- 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";
- }
+ /* 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;
- TRACE("v%u, semantic %s%u is %s\n", input->register_idx,
- semantic_name, semantic_idx,
priv->ps_input[input->register_idx]);
- }
- break;
+ 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";
+ }
- 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;
+ TRACE("v%u, semantic %s%u is %s\n", input->register_idx,
+ semantic_name, semantic_idx, priv->ps_input[input->register_idx]);
}
}
@@ -6084,17 +6072,19 @@ 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, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+ BOOL alpha, BOOL tmp_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";
- if(dst == tempreg) dstreg = "tempreg";
- else dstreg = "ret";
+ dstreg = tmp_dst ? "tempreg" : "ret";
arg0 = get_argreg(buffer, 0, stage, dw_arg0);
arg1 = get_argreg(buffer, 1, stage, dw_arg1);
@@ -6273,7 +6263,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].dst == tempreg)
+ if (settings->op[stage].tmp_dst)
tempreg_used = TRUE;
if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
tempreg_used = TRUE;
@@ -6391,12 +6381,17 @@ 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 == proj_none) {
+ if (settings->op[stage].projected == WINED3D_PROJECTION_NONE)
+ {
instr = "TEX";
- } else if(settings->op[stage].projected == proj_count4 ||
- settings->op[stage].projected == proj_count3) {
+ }
+ else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4
+ || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
+ {
instr = "TXP";
- } else {
+ }
+ else
+ {
FIXME("Unexpected projection mode %d\n",
settings->op[stage].projected);
instr = "TXP";
}
@@ -6410,18 +6405,27 @@ 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 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) {
+ /* 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)
+ {
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);
}
@@ -6433,12 +6437,16 @@ 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 == proj_count3) {
+ }
+ else if (settings->op[stage].projected == WINED3D_PROJECTION_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);
}
@@ -6487,23 +6495,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].dst,
+ gen_ffp_instr(&buffer, stage, TRUE, FALSE,
settings->op[stage].tmp_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].dst,
+ gen_ffp_instr(&buffer, stage, TRUE, TRUE,
settings->op[stage].tmp_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].dst,
+ gen_ffp_instr(&buffer, stage, TRUE, FALSE,
settings->op[stage].tmp_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].dst,
+ gen_ffp_instr(&buffer, stage, FALSE, TRUE,
settings->op[stage].tmp_dst,
settings->op[stage].aop, settings->op[stage].aarg0,
settings->op[stage].aarg1, settings->op[stage].aarg2);
}
@@ -6928,8 +6936,8 @@ static void arbfp_blitter_destroy(struct wined3d_blitter *blitter,
struct wined3
heap_free(arbfp_blitter);
}
-static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct
arbfp_blit_type *type,
- char *luminance)
+static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer,
+ const struct arbfp_blit_type *type, char *luminance)
{
char chroma;
const char *tex, *texinstr = "TXP";
@@ -6977,13 +6985,12 @@ static BOOL gen_planar_yuv_read(struct wined3d_string_buffer
*buffer, const stru
shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n");
shader_addline(buffer, "ADD texcrd.x, texcrd.x, coef.y;\n");
- /* 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
- */
+ /* 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. */
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 */
@@ -7012,12 +7019,10 @@ static BOOL gen_planar_yuv_read(struct wined3d_string_buffer
*buffer, const stru
/* This gives the correctly filtered luminance value */
shader_addline(buffer, "TEX luminance, fragment.texcoord[0], texture[0],
%s;\n", tex);
-
- return TRUE;
}
-static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct
arbfp_blit_type *type,
- char *luminance)
+static void gen_yv12_read(struct wined3d_string_buffer *buffer,
+ const struct arbfp_blit_type *type, char *luminance)
{
const char *tex;
static const float yv12_coef[]
@@ -7079,7 +7084,6 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer,
const struct arb
*/
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");
@@ -7087,7 +7091,7 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer,
const struct arb
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");
@@ -7101,11 +7105,11 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer,
const struct arb
}
else
{
- /* Read from [size - size+size/4] */
+ /* The y coordinate for V is in the range [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");
@@ -7161,12 +7165,10 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer,
const struct arb
shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n",
tex);
}
*luminance = 'a';
-
- return TRUE;
}
-static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer, const struct
arbfp_blit_type *type,
- char *luminance)
+static void gen_nv12_read(struct wined3d_string_buffer *buffer,
+ const struct arbfp_blit_type *type, char *luminance)
{
const char *tex;
static const float nv12_coef[]
@@ -7242,7 +7244,7 @@ static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer,
const struct arb
}
else
{
- /* Read from [size - size+size/2] */
+ /* The y coordinate for chroma is in the range [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");
@@ -7297,8 +7299,6 @@ static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer,
const struct arb
shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n",
tex);
}
*luminance = 'a';
-
- return TRUE;
}
/* Context activation is done by the caller. */
@@ -7464,27 +7464,15 @@ static GLuint gen_yuv_shader(const struct wined3d_gl_info
*gl_info, const struct
{
case COMPLEX_FIXUP_UYVY:
case COMPLEX_FIXUP_YUY2:
- if (!gen_planar_yuv_read(&buffer, type, &luminance_component))
- {
- string_buffer_free(&buffer);
- return 0;
- }
+ gen_packed_yuv_read(&buffer, type, &luminance_component);
break;
case COMPLEX_FIXUP_YV12:
- if (!gen_yv12_read(&buffer, type, &luminance_component))
- {
- string_buffer_free(&buffer);
- return 0;
- }
+ gen_yv12_read(&buffer, type, &luminance_component);
break;
case COMPLEX_FIXUP_NV12:
- if (!gen_nv12_read(&buffer, type, &luminance_component))
- {
- string_buffer_free(&buffer);
- return 0;
- }
+ gen_nv12_read(&buffer, type, &luminance_component);
break;
default:
@@ -7710,7 +7698,7 @@ static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const
struct wine
enum complex_fixup src_fixup;
BOOL decompress;
- if (!context->gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D)
return FALSE;
if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id ==
src_format->id)
@@ -7795,59 +7783,105 @@ 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_surface *src_surface, DWORD
src_location,
- const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location,
const RECT *dst_rect,
+ 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 *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))
- return next->ops->blitter_blit(next, op, context, src_surface,
src_location,
- src_rect, dst_surface, dst_location, dst_rect, color_key, filter);
+ 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);
}
arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter);
- /* 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
+ 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))
{
- 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. */
- surface_load_fb_texture(src_surface, FALSE, context);
+ 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);
+ context_apply_ffp_blit_state(context, device);
if (dst_location == WINED3D_LOCATION_DRAWABLE)
{
d = *dst_rect;
- surface_translate_drawable_coords(dst_surface, context->win_handle, &d);
+ wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle,
&d);
dst_rect = &d;
}
@@ -7857,15 +7891,16 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter,
enum wined3d_bl
if (dst_location == WINED3D_LOCATION_DRAWABLE)
{
- TRACE("Destination surface %p is onscreen.\n", dst_surface);
+ TRACE("Destination texture %p is onscreen.\n", dst_texture);
buffer = wined3d_texture_get_gl_buffer(dst_texture);
}
else
{
- TRACE("Destination surface %p is offscreen.\n", dst_surface);
+ TRACE("Destination texture %p is offscreen.\n", dst_texture);
buffer = GL_COLOR_ATTACHMENT0;
}
- context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL,
dst_location);
+ 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);
@@ -7882,14 +7917,16 @@ 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 */
- draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect,
filter);
+ context_draw_textured_quad(context, src_texture, src_sub_resource_idx, src_rect,
dst_rect, filter);
/* Leave the opengl state valid for blitting */
arbfp_blit_unset(context->gl_info);
- 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. */
+ 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);
return dst_location;
}
diff --git a/dll/directx/wine/wined3d/ati_fragment_shader.c
b/dll/directx/wine/wined3d/ati_fragment_shader.c
index 9d6837a2f2..9a1cae34cd 100644
--- a/dll/directx/wine/wined3d/ati_fragment_shader.c
+++ b/dll/directx/wine/wined3d/ati_fragment_shader.c
@@ -341,9 +341,8 @@ static GLuint find_tmpreg(const struct texture_stage_op
op[MAX_TEXTURES])
lowest_read = i;
}
- if(lowest_write == -1 && op[i].dst == tempreg) {
+ if (lowest_write == -1 && op[i].tmp_dst)
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) {
@@ -505,16 +504,13 @@ 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 == proj_none) {
+ GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage, GL_TEXTURE0_ARB + stage,
GL_SWIZZLE_STR_ATI));
+ if (op[stage + 1].projected == WINED3D_PROJECTION_NONE)
swizzle = GL_SWIZZLE_STR_ATI;
- } else if(op[stage + 1].projected == proj_count4) {
+ else if (op[stage + 1].projected == WINED3D_PROJECTION_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,
@@ -579,13 +575,12 @@ 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 == proj_none) {
+ if (op[stage].projected == WINED3D_PROJECTION_NONE)
swizzle = GL_SWIZZLE_STR_ATI;
- } else if(op[stage].projected == proj_count3) {
+ else if (op[stage].projected == WINED3D_PROJECTION_COUNT3)
swizzle = GL_SWIZZLE_STR_DR_ATI;
- } else {
+ else
swizzle = GL_SWIZZLE_STQ_DQ_ATI;
- }
if (op_reads_texture(&op[stage]))
{
@@ -624,14 +619,18 @@ static GLuint gen_ati_shader(const struct texture_stage_op
op[MAX_TEXTURES],
break;
}
- 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;
+ 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;
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 cae7ef8788..9baf0556dd 100644
--- a/dll/directx/wine/wined3d/buffer.c
+++ b/dll/directx/wine/wined3d/buffer.c
@@ -615,10 +615,7 @@ 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:
@@ -1183,8 +1180,6 @@ 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);
@@ -1380,6 +1375,9 @@ 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);
@@ -1428,7 +1426,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, NULL, data->data, data->row_pitch, data->slice_pitch, 0);
return WINED3D_OK;
}
diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c
index 8a8d952c3f..0ee5b65bc1 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,7 +164,6 @@ 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
{
@@ -253,6 +252,8 @@ 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},
@@ -456,19 +457,15 @@ static inline void context_set_fbo_key_for_render_target(const
struct wined3d_co
}
texture = wined3d_texture_from_resource(resource);
- if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
+ if (texture->current_renderbuffer)
{
- 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].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;
}
+
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;
@@ -615,10 +612,7 @@ static struct fbo_entry *context_find_fbo_entry(struct
wined3d_context *context,
}
else if (depth_stencil->resource->type == WINED3D_RTYPE_TEXTURE_2D)
{
- struct wined3d_surface *surface;
-
- surface =
ds_texture->sub_resources[depth_stencil->sub_resource_idx].u.surface;
- surface_set_compatible_renderbuffer(surface, &render_targets[0]);
+ wined3d_texture_set_compatible_renderbuffer(ds_texture, ds_level,
&render_targets[0]);
}
}
@@ -761,8 +755,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,
- struct wined3d_rendertarget_info *render_targets, struct wined3d_surface
*depth_stencil,
- DWORD color_location, DWORD ds_location)
+ const struct wined3d_rendertarget_info *render_targets,
+ const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location,
DWORD ds_location)
{
struct fbo_entry *entry, *entry2;
@@ -784,32 +778,35 @@ 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, &ds, color_location, ds_location);
+ render_targets, depth_stencil, 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_surface *render_target, struct wined3d_surface *depth_stencil,
DWORD location)
+ struct wined3d_resource *rt, unsigned int rt_sub_resource_idx,
+ struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, DWORD location)
{
+ struct wined3d_rendertarget_info ds_info = {{0}};
+
memset(context->blit_targets, 0, sizeof(context->blit_targets));
- if (render_target)
+ if (rt)
{
- 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].resource = rt;
+ context->blit_targets[0].sub_resource_idx = rt_sub_resource_idx;
context->blit_targets[0].layer_count = 1;
}
- context_apply_fbo_state(context, target, context->blit_targets, depth_stencil,
location, location);
+
+ 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 activation is done by the caller. */
@@ -1070,34 +1067,22 @@ 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, enum wined3d_resource_type type)
+void context_resource_released(const struct wined3d_device *device, struct
wined3d_resource *resource)
{
- struct wined3d_texture *texture;
- UINT i;
+ unsigned int i;
if (!device->d3d_initialized)
return;
- switch (type)
+ for (i = 0; i < device->context_count; ++i)
{
- case WINED3D_RTYPE_TEXTURE_2D:
- case WINED3D_RTYPE_TEXTURE_3D:
- texture = texture_from_resource(resource);
-
- 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;
+ struct wined3d_context *context = device->contexts[i];
- default:
- break;
+ if (&context->current_rt.texture->resource == resource)
+ {
+ context->current_rt.texture = NULL;
+ context->current_rt.sub_resource_idx = 0;
+ }
}
}
@@ -1107,7 +1092,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_surface_update(struct wined3d_context *context, const struct wined3d_surface
*surface)
+void context_texture_update(struct wined3d_context *context, const struct wined3d_texture
*texture)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
struct fbo_entry *entry = context->current_fbo;
@@ -1117,10 +1102,10 @@ void context_surface_update(struct wined3d_context *context, const
struct wined3
for (i = 0; i < gl_info->limits.buffers + 1; ++i)
{
- if (surface->container->texture_rgb.name ==
entry->key.objects[i].object
- || surface->container->texture_srgb.name ==
entry->key.objects[i].object)
+ if (texture->texture_rgb.name == entry->key.objects[i].object
+ || texture->texture_srgb.name == entry->key.objects[i].object)
{
- TRACE("Updated surface %p is bound as attachment %u to the current
FBO.\n", surface, i);
+ TRACE("Updated texture %p is bound as attachment %u to the current
FBO.\n", texture, i);
context->rebind_fbo = TRUE;
return;
}
@@ -1466,6 +1451,9 @@ static void context_destroy_gl_resources(struct wined3d_context
*context)
}
}
+ if (context->blit_vbo)
+ GL_EXTCALL(glDeleteBuffers(1, &context->blit_vbo));
+
checkGLcall("context cleanup");
}
@@ -1603,14 +1591,12 @@ 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_surface *restore)
+void context_restore(struct wined3d_context *context, struct wined3d_texture *texture,
unsigned int sub_resource_idx)
{
- if (context->current_rt.texture != restore->container
- || context->current_rt.sub_resource_idx !=
surface_get_sub_resource_idx(restore))
+ if (context->current_rt.texture != texture ||
context->current_rt.sub_resource_idx != sub_resource_idx)
{
context_release(context);
- context = context_acquire(restore->container->resource.device,
- restore->container, surface_get_sub_resource_idx(restore));
+ context = context_acquire(texture->resource.device, texture,
sub_resource_idx);
}
context_release(context);
@@ -1791,6 +1777,7 @@ 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);
@@ -1866,8 +1853,6 @@ 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;
@@ -1877,9 +1862,20 @@ 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 (ctx_flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
+ if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2))
{
- ctx_attribs[ctx_attrib_idx - 1] &=
~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;
+ }
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());
@@ -2176,15 +2172,6 @@ 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
@@ -2270,6 +2257,10 @@ 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;
@@ -2368,28 +2359,6 @@ 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;
@@ -2438,206 +2407,6 @@ 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);
@@ -2756,11 +2525,9 @@ 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);
@@ -2900,7 +2667,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_FRONTFACE);
+ context_invalidate_state(context, STATE_RASTERIZER);
context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN);
context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
}
@@ -2967,12 +2734,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_texture *rt)
+static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context,
struct wined3d_resource *rt)
{
- if (!rt || rt->resource.format->id == WINED3DFMT_NULL)
+ if (!rt || rt->format->id == WINED3DFMT_NULL)
return 0;
- else if (rt->swapchain)
- return context_generate_rt_mask_from_resource(&rt->resource);
+ else if (rt->type != WINED3D_RTYPE_BUFFER &&
texture_from_resource(rt)->swapchain)
+ return context_generate_rt_mask_from_resource(rt);
else
return context_generate_rt_mask(context_get_offscreen_gl_buffer(context));
}
@@ -2980,9 +2747,13 @@ 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)
{
@@ -2990,8 +2761,8 @@ void context_apply_blit_state(struct wined3d_context *context, const
struct wine
{
wined3d_texture_load(rt, context, FALSE);
- 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);
+ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, &rt->resource,
+ context->current_rt.sub_resource_idx, NULL, 0,
rt->resource.draw_binding);
if (rt->resource.format->id != WINED3DFMT_NULL)
rt_mask = 1;
else
@@ -3006,7 +2777,7 @@ void context_apply_blit_state(struct wined3d_context *context, const
struct wine
}
else
{
- rt_mask = context_generate_rt_mask_no_fbo(context, rt);
+ rt_mask = context_generate_rt_mask_no_fbo(context, &rt->resource);
}
cur_mask = context->current_fbo ? &context->current_fbo->rt_mask :
&context->draw_buffers_mask;
@@ -3021,76 +2792,270 @@ 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);
-}
-
-static BOOL have_framebuffer_attachment(unsigned int rt_count, struct
wined3d_rendertarget_view * const *rts,
- const struct wined3d_rendertarget_view *ds)
-{
- unsigned int i;
- if (ds)
- return TRUE;
+ context_get_rt_size(context, &rt_size);
- for (i = 0; i < rt_count; ++i)
+ if (context->last_was_blit)
{
- if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
- return TRUE;
+ 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;
- return FALSE;
-}
-
-/* Context activation is done by the caller. */
-BOOL context_apply_clear_state(struct wined3d_context *context, const struct
wined3d_state *state,
- UINT rt_count, const struct wined3d_fb_state *fb)
-{
- struct wined3d_rendertarget_view * const *rts = fb->render_targets;
- struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
- const struct wined3d_gl_info *gl_info = context->gl_info;
- DWORD rt_mask = 0, *cur_mask;
- unsigned int i;
+ if (gl_info->supported[ARB_SAMPLER_OBJECTS])
+ GL_EXTCALL(glBindSampler(0, 0));
+ context_active_texture(context, gl_info, 0);
- if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
- || rt_count != gl_info->limits.buffers)
+ sampler = context->rev_tex_unit_map[0];
+ if (sampler != WINED3D_UNMAPPED_STAGE)
{
- if (!have_framebuffer_attachment(rt_count, rts, dsv))
+ if (sampler < MAX_TEXTURES)
{
- WARN("Invalid render target config, need at least one
attachment.\n");
- return FALSE;
+ 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 (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
- {
- context_validate_onscreen_formats(context, dsv);
-
- if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))
- {
- memset(context->blit_targets, 0, sizeof(context->blit_targets));
- for (i = 0; i < rt_count; ++i)
- {
- if (rts[i])
- {
- context->blit_targets[i].gl_view = rts[i]->gl_view;
- context->blit_targets[i].resource = rts[i]->resource;
- context->blit_targets[i].sub_resource_idx =
rts[i]->sub_resource_idx;
- context->blit_targets[i].layer_count =
rts[i]->layer_count;
- }
- if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
- rt_mask |= (1u << i);
- }
- 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, NULL,
- WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE);
- rt_mask = context_generate_rt_mask_from_resource(rts[0]->resource);
+ 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,
+ const struct wined3d_rendertarget_view *ds)
+{
+ unsigned int i;
+
+ if (ds)
+ return TRUE;
+
+ for (i = 0; i < rt_count; ++i)
+ {
+ if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Context activation is done by the caller. */
+BOOL context_apply_clear_state(struct wined3d_context *context, const struct
wined3d_state *state,
+ UINT rt_count, const struct wined3d_fb_state *fb)
+{
+ struct wined3d_rendertarget_view * const *rts = fb->render_targets;
+ struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD rt_mask = 0, *cur_mask;
+ unsigned int i;
+
+ if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
+ || rt_count != gl_info->limits.buffers)
+ {
+ if (!have_framebuffer_attachment(rt_count, rts, dsv))
+ {
+ WARN("Invalid render target config, need at least one
attachment.\n");
+ return FALSE;
+ }
+
+ 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))
+ {
+ memset(context->blit_targets, 0, sizeof(context->blit_targets));
+ for (i = 0; i < rt_count; ++i)
+ {
+ if (rts[i])
+ {
+ context->blit_targets[i].gl_view = rts[i]->gl_view;
+ context->blit_targets[i].resource = rts[i]->resource;
+ context->blit_targets[i].sub_resource_idx =
rts[i]->sub_resource_idx;
+ context->blit_targets[i].layer_count =
rts[i]->layer_count;
+ }
+ 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,
+ 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,
+ WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE);
+ rt_mask = context_generate_rt_mask_from_resource(rts[0]->resource);
}
/* If the framebuffer is not the device's fb the device's fb has to
be reapplied
@@ -3100,8 +3065,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context,
const struct win
}
else
{
- rt_mask = context_generate_rt_mask_no_fbo(context,
- rt_count ?
wined3d_rendertarget_view_get_surface(rts[0])->container : NULL);
+ rt_mask = context_generate_rt_mask_no_fbo(context, rt_count ?
rts[0]->resource : NULL);
}
}
else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
@@ -3115,8 +3079,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context,
const struct win
}
else
{
- rt_mask = context_generate_rt_mask_no_fbo(context,
- rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container :
NULL);
+ rt_mask = context_generate_rt_mask_no_fbo(context, rt_count ? rts[0]->resource
: NULL);
}
cur_mask = context->current_fbo ? &context->current_fbo->rt_mask :
&context->draw_buffers_mask;
@@ -3134,6 +3097,7 @@ 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
@@ -3165,7 +3129,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,
wined3d_rendertarget_view_get_surface(rts[0])->container);
+ return context_generate_rt_mask_no_fbo(context, rts[0]->resource);
else if (!context->render_offscreen)
return context_generate_rt_mask_from_resource(rts[0]->resource);
@@ -3202,9 +3166,11 @@ 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, NULL,
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, &ds_info,
WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE);
}
else
@@ -3225,8 +3191,16 @@ void context_state_fb(struct wined3d_context *context, const struct
wined3d_stat
if (!color_location)
color_location =
fb->render_targets[i]->resource->draw_binding;
}
- context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
- wined3d_rendertarget_view_get_surface(fb->depth_stencil),
+
+ 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,
color_location, fb->depth_stencil ?
fb->depth_stencil->resource->draw_binding : 0);
}
}
@@ -4053,6 +4027,7 @@ 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;
}
@@ -4114,6 +4089,7 @@ 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)
@@ -4377,9 +4353,6 @@ 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);
}
@@ -4565,6 +4538,7 @@ 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;
@@ -5052,13 +5026,12 @@ 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;
@@ -5086,7 +5059,9 @@ void draw_primitive(struct wined3d_device *device, const struct
wined3d_state *s
}
else if (!context->transform_feedback_active)
{
- GLenum mode = gl_tfb_primitive_type_from_d3d(shader->u.gs.output_type);
+ 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);
GL_EXTCALL(glBeginTransformFeedback(mode));
checkGLcall("glBeginTransformFeedback");
context->transform_feedback_active = 1;
@@ -5141,8 +5116,663 @@ 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 460fe12c7d..eb24d94e9a 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_VIEWPORT,
- WINED3D_CS_OP_SET_SCISSOR_RECT,
+ WINED3D_CS_OP_SET_VIEWPORTS,
+ WINED3D_CS_OP_SET_SCISSOR_RECTS,
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;
- DWORD swap_interval;
+ unsigned int swap_interval;
DWORD flags;
};
@@ -138,16 +138,18 @@ struct wined3d_cs_set_predication
BOOL value;
};
-struct wined3d_cs_set_viewport
+struct wined3d_cs_set_viewports
{
enum wined3d_cs_op opcode;
- struct wined3d_viewport viewport;
+ unsigned int viewport_count;
+ struct wined3d_viewport viewports[1];
};
-struct wined3d_cs_set_scissor_rect
+struct wined3d_cs_set_scissor_rects
{
enum wined3d_cs_op opcode;
- RECT rect;
+ unsigned int rect_count;
+ RECT rects[1];
};
struct wined3d_cs_set_rendertarget_view
@@ -406,9 +408,7 @@ 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,12 +456,7 @@ 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);
-
- if (op->swap_interval && swapchain->desc.swap_interval !=
op->swap_interval)
- {
- swapchain->desc.swap_interval = op->swap_interval;
- swapchain_update_swap_interval(swapchain);
- }
+ wined3d_swapchain_set_swap_interval(swapchain, op->swap_interval);
swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect,
&op->dst_rect, op->flags);
@@ -476,7 +471,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,
- DWORD swap_interval, DWORD flags)
+ unsigned int swap_interval, DWORD flags)
{
struct wined3d_cs_present *op;
unsigned int i;
@@ -502,9 +497,8 @@ 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. We have a constant limit here, but
- * IDXGIDevice1 allows tuning this. */
- while (pending > 1)
+ * ahead of the worker thread. */
+ while (pending >= swapchain->max_frame_latency)
{
wined3d_pause();
pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0);
@@ -538,19 +532,24 @@ 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->viewport;
+ const struct wined3d_viewport *vp = &state->viewports[0];
+ struct wined3d_rendertarget_view *view;
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;
- op->rt_count = rt_count;
+ if (flags & WINED3DCLEAR_TARGET)
+ op->rt_count = rt_count;
+ else
+ op->rt_count = 0;
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_rect);
+ IntersectRect(&op->draw_rect, &op->draw_rect,
&state->scissor_rects[0]);
op->color = *color;
op->depth = depth;
op->stencil = stencil;
@@ -561,12 +560,21 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count,
const RECT *
{
for (i = 0; i < rt_count; ++i)
{
- if (state->fb->render_targets[i])
-
wined3d_resource_acquire(state->fb->render_targets[i]->resource);
+ 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 (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
- wined3d_resource_acquire(state->fb->depth_stencil->resource);
+ {
+ 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);
+ }
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
@@ -774,6 +782,7 @@ 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;
@@ -793,6 +802,8 @@ 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;
@@ -958,40 +969,53 @@ 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_viewport(struct wined3d_cs *cs, const void *data)
+static void wined3d_cs_exec_set_viewports(struct wined3d_cs *cs, const void *data)
{
- const struct wined3d_cs_set_viewport *op = data;
+ const struct wined3d_cs_set_viewports *op = data;
- cs->state.viewport = op->viewport;
+ 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;
device_invalidate_state(cs->device, STATE_VIEWPORT);
}
-void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport
*viewport)
+void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count,
+ const struct wined3d_viewport *viewports)
{
- struct wined3d_cs_set_viewport *op;
+ struct wined3d_cs_set_viewports *op;
- op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
- op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
- op->viewport = *viewport;
+ 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;
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
-static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data)
+static void wined3d_cs_exec_set_scissor_rects(struct wined3d_cs *cs, const void *data)
{
- const struct wined3d_cs_set_scissor_rect *op = data;
+ const struct wined3d_cs_set_scissor_rects *op = data;
- cs->state.scissor_rect = op->rect;
+ 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;
device_invalidate_state(cs->device, STATE_SCISSORRECT);
}
-void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
+void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_count,
const RECT *rects)
{
- struct wined3d_cs_set_scissor_rect *op;
+ struct wined3d_cs_set_scissor_rects *op;
- op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
- op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT;
- op->rect = *rect;
+ 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;
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
@@ -1023,16 +1047,14 @@ 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))
+ if ((prev = cs->state.fb->depth_stencil) && prev->resource->type
!= WINED3D_RTYPE_BUFFER)
{
- struct wined3d_surface *prev_surface =
wined3d_rendertarget_view_get_surface(prev);
+ struct wined3d_texture *prev_texture = texture_from_resource(prev->resource);
- 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,
+ if (device->swapchains[0]->desc.flags &
WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
+ || prev_texture->flags & WINED3D_TEXTURE_DISCARD)
+ wined3d_texture_validate_location(prev_texture,
prev->sub_resource_idx, WINED3D_LOCATION_DISCARDED);
- }
}
cs->fb.depth_stencil = op->view;
@@ -1470,7 +1492,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_FRONTFACE);
+ device_invalidate_state(cs->device, STATE_RASTERIZER);
}
void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs,
@@ -2059,23 +2081,6 @@ 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;
@@ -2110,13 +2115,6 @@ 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);
@@ -2151,8 +2149,9 @@ 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,
&op->dst_box,
- wined3d_const_bo_address(&addr), row_pitch, slice_pitch);
+ 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_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);
@@ -2160,7 +2159,10 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs,
const void *
}
else
{
- FIXME("Not implemented for %s resources.\n",
debug_d3dresourcetype(op->dst_resource->type));
+ 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");
}
error:
@@ -2209,6 +2211,7 @@ 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);
@@ -2245,8 +2248,9 @@ 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_texture_upload_data(texture, op->sub_resource_idx, context,
- box, &addr, op->data.row_pitch, op->data.slice_pitch);
+ 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_validate_location(texture, op->sub_resource_idx,
WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_invalidate_location(texture, op->sub_resource_idx,
~WINED3D_LOCATION_TEXTURE_RGB);
@@ -2262,7 +2266,6 @@ 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)
@@ -2308,7 +2311,6 @@ 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;
@@ -2322,10 +2324,6 @@ 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);
}
@@ -2466,8 +2464,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_VIEWPORT */ wined3d_cs_exec_set_viewport,
- /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
+ /* 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_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,
@@ -2508,13 +2506,11 @@ 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))
@@ -2568,9 +2564,7 @@ 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,
@@ -2607,7 +2601,6 @@ 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);
@@ -2621,7 +2614,6 @@ 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);
@@ -2683,7 +2675,6 @@ 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())
@@ -2692,7 +2683,6 @@ 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())
@@ -2715,9 +2705,7 @@ 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 e2b27e0cf4..8b4b3f9bb2 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)
}
}
-static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type)
+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,10 +238,19 @@ void device_clear_render_targets(struct wined3d_device *device, UINT
rt_count, c
BOOL render_offscreen;
unsigned int i;
- if (target)
- context = context_acquire(device, target->container,
rtv->sub_resource_idx);
+ if (rtv && rtv->resource->type != WINED3D_RTYPE_BUFFER)
+ {
+ target = texture_from_resource(rtv->resource);
+ context = context_acquire(device, target, 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);
@@ -281,11 +290,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->container->level_count;
+ unsigned int ds_level = dsv->sub_resource_idx %
depth_stencil->level_count;
render_offscreen = TRUE;
- 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);
+ drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil, ds_level);
+ drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil,
ds_level);
}
if (depth_stencil)
@@ -402,9 +411,7 @@ 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
{
@@ -439,16 +446,14 @@ 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 (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.
*/
+ if (flags & WINED3DCLEAR_TARGET && target->swapchain &&
target->swapchain->front_buffer == target)
+ gl_info->gl_ops.gl.p_glFlush();
context_release(context);
}
@@ -677,12 +682,11 @@ 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);
@@ -752,8 +756,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_1d_array);
gl_info->gl_ops.gl.p_glDeleteTextures(1,
&dummy_textures->tex_2d_array);
... 11015 lines suppressed ...