Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
80953d62
Commit
80953d62
authored
Jan 11, 2008
by
Stefan Dösinger
Committed by
Alexandre Julliard
Jan 14, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
d3d9: Reject IDirect3DDevice9::Reset with active default pool resources.
parent
8bb5d13f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
185 additions
and
8 deletions
+185
-8
device.c
dlls/d3d9/device.c
+97
-0
device.c
dlls/d3d9/tests/device.c
+61
-7
device.c
dlls/wined3d/device.c
+21
-1
wined3d_interface.h
include/wine/wined3d_interface.h
+6
-0
No files found.
dlls/d3d9/device.c
View file @
80953d62
...
...
@@ -230,13 +230,110 @@ static BOOL WINAPI IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9 iface,
return
ret
;
}
static
HRESULT
WINAPI
reset_enum_callback
(
IWineD3DResource
*
resource
,
void
*
data
)
{
BOOL
*
resources_ok
=
(
BOOL
*
)
data
;
WINED3DRESOURCETYPE
type
;
HRESULT
ret
=
S_OK
;
WINED3DSURFACE_DESC
surface_desc
;
WINED3DVOLUME_DESC
volume_desc
;
WINED3DINDEXBUFFER_DESC
index_desc
;
WINED3DVERTEXBUFFER_DESC
vertex_desc
;
WINED3DFORMAT
dummy_format
;
DWORD
dummy_dword
;
WINED3DPOOL
pool
=
WINED3DPOOL_SCRATCH
;
/* a harmless pool */
IUnknown
*
parent
;
type
=
IWineD3DResource_GetType
(
resource
);
switch
(
type
)
{
case
WINED3DRTYPE_SURFACE
:
surface_desc
.
Format
=
&
dummy_format
;
surface_desc
.
Type
=
&
type
;
surface_desc
.
Usage
=
&
dummy_dword
;
surface_desc
.
Pool
=
&
pool
;
surface_desc
.
Size
=
&
dummy_dword
;
surface_desc
.
MultiSampleType
=
&
dummy_dword
;
surface_desc
.
MultiSampleQuality
=
&
dummy_dword
;
surface_desc
.
Width
=
&
dummy_dword
;
surface_desc
.
Height
=
&
dummy_dword
;
IWineD3DSurface_GetDesc
((
IWineD3DSurface
*
)
resource
,
&
surface_desc
);
break
;
case
WINED3DRTYPE_VOLUME
:
volume_desc
.
Format
=
&
dummy_format
;
volume_desc
.
Type
=
&
type
;
volume_desc
.
Usage
=
&
dummy_dword
;
volume_desc
.
Pool
=
&
pool
;
volume_desc
.
Size
=
&
dummy_dword
;
volume_desc
.
Width
=
&
dummy_dword
;
volume_desc
.
Height
=
&
dummy_dword
;
volume_desc
.
Depth
=
&
dummy_dword
;
IWineD3DVolume_GetDesc
((
IWineD3DVolume
*
)
resource
,
&
volume_desc
);
break
;
case
WINED3DRTYPE_INDEXBUFFER
:
IWineD3DIndexBuffer_GetDesc
((
IWineD3DIndexBuffer
*
)
resource
,
&
index_desc
);
pool
=
index_desc
.
Pool
;
break
;
case
WINED3DRTYPE_VERTEXBUFFER
:
IWineD3DVertexBuffer_GetDesc
((
IWineD3DVertexBuffer
*
)
resource
,
&
vertex_desc
);
pool
=
index_desc
.
Pool
;
break
;
/* No need to check for textures. If there is a D3DPOOL_DEFAULT texture, there
* is a D3DPOOL_DEFAULT surface or volume as well
*/
default:
break
;
}
if
(
pool
==
WINED3DPOOL_DEFAULT
)
{
IWineD3DResource_GetParent
(
resource
,
&
parent
);
if
(
IUnknown_Release
(
parent
)
==
0
)
{
TRACE
(
"Parent %p is an implicit resource with ref 0
\n
"
,
parent
);
}
else
{
WARN
(
"Resource %p(wineD3D %p) with pool D3DPOOL_DEFAULT blocks the Reset call
\n
"
,
parent
,
resource
);
ret
=
S_FALSE
;
*
resources_ok
=
FALSE
;
}
}
IWineD3DResource_Release
(
resource
);
return
ret
;
}
static
HRESULT
WINAPI
IDirect3DDevice9Impl_Reset
(
LPDIRECT3DDEVICE9
iface
,
D3DPRESENT_PARAMETERS
*
pPresentationParameters
)
{
IDirect3DDevice9Impl
*
This
=
(
IDirect3DDevice9Impl
*
)
iface
;
WINED3DPRESENT_PARAMETERS
localParameters
;
HRESULT
hr
;
BOOL
resources_ok
=
TRUE
;
UINT
i
;
TRACE
(
"(%p) Relay pPresentationParameters(%p)
\n
"
,
This
,
pPresentationParameters
);
/* Reset states that hold a COM object. WineD3D holds an internal reference to set objects, because
* such objects can still be used for rendering after their external d3d9 object has been destroyed.
* These objects must not be enumerated. Unsetting them tells WineD3D that the application will not
* make use of the hidden reference and destroys the objects.
*
* Unsetting them is no problem, because the states are supposed to be reset anyway. If the validation
* below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
*/
IWineD3DDevice_SetIndices
(
This
->
WineD3DDevice
,
NULL
);
for
(
i
=
0
;
i
<
16
;
i
++
)
{
IWineD3DDevice_SetStreamSource
(
This
->
WineD3DDevice
,
i
,
NULL
,
0
,
0
);
}
for
(
i
=
0
;
i
<
16
;
i
++
)
{
IWineD3DDevice_SetTexture
(
This
->
WineD3DDevice
,
i
,
NULL
);
}
IWineD3DDevice_EnumResources
(
This
->
WineD3DDevice
,
reset_enum_callback
,
&
resources_ok
);
if
(
!
resources_ok
)
{
WARN
(
"The application is holding D3DPOOL_DEFAULT resources, rejecting reset
\n
"
);
return
WINED3DERR_INVALIDCALL
;
}
localParameters
.
BackBufferWidth
=
pPresentationParameters
->
BackBufferWidth
;
localParameters
.
BackBufferHeight
=
pPresentationParameters
->
BackBufferHeight
;
localParameters
.
BackBufferFormat
=
pPresentationParameters
->
BackBufferFormat
;
...
...
dlls/d3d9/tests/device.c
View file @
80953d62
...
...
@@ -279,6 +279,15 @@ static void test_swapchain(void)
DestroyWindow
(
hwnd
);
}
/* Shared between two functions */
static
const
DWORD
simple_vs
[]
=
{
0xFFFE0101
,
/* vs_1_1 */
0x0000001F
,
0x80000000
,
0x900F0000
,
/* dcl_position0 v0 */
0x00000009
,
0xC0010000
,
0x90E40000
,
0xA0E40000
,
/* dp4 oPos.x, v0, c0 */
0x00000009
,
0xC0020000
,
0x90E40000
,
0xA0E40001
,
/* dp4 oPos.y, v0, c1 */
0x00000009
,
0xC0040000
,
0x90E40000
,
0xA0E40002
,
/* dp4 oPos.z, v0, c2 */
0x00000009
,
0xC0080000
,
0x90E40000
,
0xA0E40003
,
/* dp4 oPos.w, v0, c3 */
0x0000FFFF
};
/* END */
static
void
test_refcount
(
void
)
{
HRESULT
hr
;
...
...
@@ -313,13 +322,6 @@ static void test_refcount(void)
{
D3DDECL_END
()
};
static
DWORD
simple_vs
[]
=
{
0xFFFE0101
,
/* vs_1_1 */
0x0000001F
,
0x80000000
,
0x900F0000
,
/* dcl_position0 v0 */
0x00000009
,
0xC0010000
,
0x90E40000
,
0xA0E40000
,
/* dp4 oPos.x, v0, c0 */
0x00000009
,
0xC0020000
,
0x90E40000
,
0xA0E40001
,
/* dp4 oPos.y, v0, c1 */
0x00000009
,
0xC0040000
,
0x90E40000
,
0xA0E40002
,
/* dp4 oPos.z, v0, c2 */
0x00000009
,
0xC0080000
,
0x90E40000
,
0xA0E40003
,
/* dp4 oPos.w, v0, c3 */
0x0000FFFF
};
/* END */
static
DWORD
simple_ps
[]
=
{
0xFFFF0101
,
/* ps_1_1 */
0x00000051
,
0xA00F0001
,
0x3F800000
,
0x00000000
,
0x00000000
,
0x00000000
,
/* def c1 = 1.0, 0.0, 0.0, 0.0 */
0x00000042
,
0xB00F0000
,
/* tex t0 */
...
...
@@ -719,6 +721,9 @@ static void test_reset(void)
DWORD
width
,
orig_width
=
GetSystemMetrics
(
SM_CXSCREEN
);
DWORD
height
,
orig_height
=
GetSystemMetrics
(
SM_CYSCREEN
);
IDirect3DSwapChain9
*
pSwapchain
;
IDirect3DSurface9
*
surface
;
IDirect3DTexture9
*
texture
;
IDirect3DVertexShader9
*
shader
;
pD3d
=
pDirect3DCreate9
(
D3D_SDK_VERSION
);
ok
(
pD3d
!=
NULL
,
"Failed to create IDirect3D9 object
\n
"
);
...
...
@@ -849,6 +854,55 @@ static void test_reset(void)
IDirect3DSwapChain9_Release
(
pSwapchain
);
}
ZeroMemory
(
&
d3dpp
,
sizeof
(
d3dpp
)
);
d3dpp
.
SwapEffect
=
D3DSWAPEFFECT_DISCARD
;
d3dpp
.
Windowed
=
TRUE
;
d3dpp
.
BackBufferWidth
=
400
;
d3dpp
.
BackBufferHeight
=
300
;
/* _Reset fails if there is a resource in the default pool */
hr
=
IDirect3DDevice9_CreateOffscreenPlainSurface
(
pDevice
,
16
,
16
,
D3DFMT_R5G6B5
,
D3DPOOL_DEFAULT
,
&
surface
,
NULL
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_CreateOffscreenPlainSurface returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_Reset
(
pDevice
,
&
d3dpp
);
ok
(
hr
==
D3DERR_INVALIDCALL
,
"IDirect3DDevice9_Reset failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
IDirect3DSurface9_Release
(
surface
);
/* Reset again to get the device out of the lost state */
hr
=
IDirect3DDevice9_Reset
(
pDevice
,
&
d3dpp
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_Reset failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
/* Scratch, sysmem and managed pools are fine */
hr
=
IDirect3DDevice9_CreateOffscreenPlainSurface
(
pDevice
,
16
,
16
,
D3DFMT_R5G6B5
,
D3DPOOL_SCRATCH
,
&
surface
,
NULL
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_CreateOffscreenPlainSurface returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_Reset
(
pDevice
,
&
d3dpp
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_Reset failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
IDirect3DSurface9_Release
(
surface
);
hr
=
IDirect3DDevice9_CreateOffscreenPlainSurface
(
pDevice
,
16
,
16
,
D3DFMT_R5G6B5
,
D3DPOOL_SYSTEMMEM
,
&
surface
,
NULL
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_CreateOffscreenPlainSurface returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_Reset
(
pDevice
,
&
d3dpp
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_Reset failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
IDirect3DSurface9_Release
(
surface
);
hr
=
IDirect3DDevice9_CreateTexture
(
pDevice
,
16
,
16
,
0
,
0
,
D3DFMT_R5G6B5
,
D3DPOOL_MANAGED
,
&
texture
,
NULL
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_CreateTexture returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_Reset
(
pDevice
,
&
d3dpp
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_Reset failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
IDirect3DTexture9_Release
(
texture
);
/* A reference held to an implicit surface causes failures as well */
hr
=
IDirect3DDevice9_GetBackBuffer
(
pDevice
,
0
,
0
,
D3DBACKBUFFER_TYPE_MONO
,
&
surface
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_GetBackBuffer returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_Reset
(
pDevice
,
&
d3dpp
);
ok
(
hr
==
D3DERR_INVALIDCALL
,
"IDirect3DDevice9_Reset failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
IDirect3DSurface9_Release
(
surface
);
hr
=
IDirect3DDevice9_Reset
(
pDevice
,
&
d3dpp
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_Reset failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
/* Shaders are fine as well */
hr
=
IDirect3DDevice9_CreateVertexShader
(
pDevice
,
simple_vs
,
&
shader
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_CreateVertexShader returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_Reset
(
pDevice
,
&
d3dpp
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_Reset failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
IDirect3DVertexShader9_Release
(
shader
);
cleanup:
if
(
pD3d
)
IDirect3D9_Release
(
pD3d
);
if
(
pDevice
)
IDirect3D9_Release
(
pDevice
);
...
...
dlls/wined3d/device.c
View file @
80953d62
...
...
@@ -6824,6 +6824,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
if
(
pPresentationParameters
->
EnableAutoDepthStencil
!=
swapchain
->
presentParms
.
EnableAutoDepthStencil
)
{
ERR
(
"What do do about a changed auto depth stencil parameter?
\n
"
);
}
TRACE
(
"Checks done
\n
"
);
if
(
pPresentationParameters
->
Windowed
)
{
mode
.
Width
=
swapchain
->
orig_width
;
...
...
@@ -7095,6 +7096,24 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW
}
static
HRESULT
WINAPI
IWineD3DDeviceImpl_EnumResources
(
IWineD3DDevice
*
iface
,
D3DCB_ENUMRESOURCES
pCallback
,
void
*
pData
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
IWineD3DResourceImpl
*
resource
,
*
cursor
;
HRESULT
ret
;
TRACE
(
"(%p)->(%p,%p)
\n
"
,
This
,
pCallback
,
pData
);
LIST_FOR_EACH_ENTRY_SAFE
(
resource
,
cursor
,
&
This
->
resources
,
IWineD3DResourceImpl
,
resource
.
resource_list_entry
)
{
TRACE
(
"enumerating resource %p
\n
"
,
resource
);
IWineD3DResource_AddRef
((
IWineD3DResource
*
)
resource
);
ret
=
pCallback
((
IWineD3DResource
*
)
resource
,
pData
);
if
(
ret
==
S_FALSE
)
{
TRACE
(
"Canceling enumeration
\n
"
);
break
;
}
}
return
WINED3D_OK
;
}
/**********************************************************
* IWineD3DDevice VTbl follows
**********************************************************/
...
...
@@ -7241,7 +7260,8 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
IWineD3DDeviceImpl_UpdateSurface
,
IWineD3DDeviceImpl_GetFrontBufferData
,
/*** object tracking ***/
IWineD3DDeviceImpl_ResourceReleased
IWineD3DDeviceImpl_ResourceReleased
,
IWineD3DDeviceImpl_EnumResources
};
...
...
include/wine/wined3d_interface.h
View file @
80953d62
...
...
@@ -247,6 +247,10 @@ typedef HRESULT (WINAPI *D3DCB_CREATEADDITIONALSWAPCHAIN) (IUnknown *pDevice,
struct
IWineD3DSwapChain
**
pSwapChain
);
typedef
HRESULT
(
WINAPI
*
D3DCB_ENUMRESOURCES
)
(
struct
IWineD3DResource
*
resource
,
void
*
pData
);
/*****************************************************************************
* Callback functions for custom implicit object destruction.
*/
...
...
@@ -482,6 +486,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
STDMETHOD
(
GetFrontBufferData
)(
THIS_
UINT
iSwapChain
,
struct
IWineD3DSurface
*
pSurface
)
PURE
;
/*** object tracking ***/
STDMETHOD_
(
void
,
ResourceReleased
)(
THIS_
struct
IWineD3DResource
*
resource
);
STDMETHOD
(
EnumResources
)(
THIS_
D3DCB_ENUMRESOURCES
pCallback
,
void
*
pData
);
};
#undef INTERFACE
...
...
@@ -621,6 +626,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
#define IWineD3DDevice_UpdateSurface(p,a,b,c,d) (p)->lpVtbl->UpdateSurface(p,a,b,c,d)
#define IWineD3DDevice_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b)
#define IWineD3DDevice_ResourceReleased(p,a) (p)->lpVtbl->ResourceReleased(p,a)
#define IWineD3DDevice_EnumResources(p,a,b) (p)->lpVtbl->EnumResources(p,a,b)
#endif
/*****************************************************************************
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment