Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
5fc17b84
Commit
5fc17b84
authored
Apr 11, 2012
by
Henri Verbeet
Committed by
Alexandre Julliard
Apr 12, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
d3d9: Store wined3d vertex declarations in the fvf lookup table.
This also implicitly gets rid of the convFVF hack in IDirect3DVertexDeclaration9Impl_Release().
parent
ba67df7a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
103 additions
and
102 deletions
+103
-102
d3d9_private.h
dlls/d3d9/d3d9_private.h
+8
-3
device.c
dlls/d3d9/device.c
+85
-74
vertexdeclaration.c
dlls/d3d9/vertexdeclaration.c
+10
-25
No files found.
dlls/d3d9/d3d9_private.h
View file @
5fc17b84
...
...
@@ -156,6 +156,12 @@ typedef struct IDirect3D9Impl
void
filter_caps
(
D3DCAPS9
*
pCaps
)
DECLSPEC_HIDDEN
;
struct
fvf_declaration
{
struct
wined3d_vertex_declaration
*
decl
;
DWORD
fvf
;
};
/*****************************************************************************
* IDirect3DDevice9 implementation structure
*/
...
...
@@ -169,8 +175,8 @@ typedef struct IDirect3DDevice9Impl
/* Avoids recursion with nested ReleaseRef to 0 */
BOOL
inDestruction
;
IDirect3DVertexDeclaration9
**
convertedD
ecls
;
unsigned
int
numConvertedDecls
,
declArrayS
ize
;
struct
fvf_declaration
*
fvf_d
ecls
;
UINT
fvf_decl_count
,
fvf_decl_s
ize
;
BOOL
notreset
;
BOOL
in_scene
;
...
...
@@ -394,7 +400,6 @@ typedef struct IDirect3DVertexDeclaration9Impl {
LPDIRECT3DDEVICE9EX
parentDevice
;
}
IDirect3DVertexDeclaration9Impl
;
void
IDirect3DVertexDeclaration9Impl_Destroy
(
LPDIRECT3DVERTEXDECLARATION9
iface
)
DECLSPEC_HIDDEN
;
HRESULT
d3d9_vertex_declaration_create
(
IDirect3DDevice9Impl
*
device
,
const
D3DVERTEXELEMENT9
*
elements
,
IDirect3DVertexDeclaration9Impl
**
declaration
)
DECLSPEC_HIDDEN
;
...
...
dlls/d3d9/device.c
View file @
5fc17b84
...
...
@@ -234,36 +234,38 @@ static ULONG WINAPI IDirect3DDevice9Impl_AddRef(IDirect3DDevice9Ex *iface)
static
ULONG
WINAPI
DECLSPEC_HOTPATCH
IDirect3DDevice9Impl_Release
(
IDirect3DDevice9Ex
*
iface
)
{
IDirect3DDevice9Impl
*
This
=
impl_from_IDirect3DDevice9Ex
(
iface
);
IDirect3DDevice9Impl
*
device
=
impl_from_IDirect3DDevice9Ex
(
iface
);
ULONG
ref
;
if
(
This
->
inDestruction
)
return
0
;
ref
=
InterlockedDecrement
(
&
This
->
ref
);
if
(
device
->
inDestruction
)
return
0
;
ref
=
InterlockedDecrement
(
&
device
->
ref
);
TRACE
(
"%p decreasing refcount to %u.
\n
"
,
iface
,
ref
);
if
(
ref
==
0
)
{
unsigned
i
;
This
->
inDestruction
=
TRUE
;
if
(
!
ref
)
{
unsigned
i
;
device
->
inDestruction
=
TRUE
;
wined3d_mutex_lock
();
for
(
i
=
0
;
i
<
This
->
numConvertedDecls
;
i
++
)
{
/* Unless Wine is buggy or the app has a bug the refcount will be 0, because decls hold a reference to the
* device
*/
IDirect3DVertexDeclaration9Impl_Destroy
(
This
->
convertedDecls
[
i
]);
}
HeapFree
(
GetProcessHeap
(),
0
,
This
->
convertedDecls
);
wined3d_mutex_lock
();
for
(
i
=
0
;
i
<
device
->
fvf_decl_count
;
++
i
)
{
wined3d_vertex_declaration_decref
(
device
->
fvf_decls
[
i
].
decl
);
}
HeapFree
(
GetProcessHeap
(),
0
,
device
->
fvf_decls
);
wined3d_device_uninit_3d
(
This
->
wined3d_device
);
wined3d_device_release_focus_window
(
This
->
wined3d_device
);
wined3d_device_decref
(
This
->
wined3d_device
);
wined3d_mutex_unlock
();
wined3d_device_uninit_3d
(
device
->
wined3d_device
);
wined3d_device_release_focus_window
(
device
->
wined3d_device
);
wined3d_device_decref
(
device
->
wined3d_device
);
wined3d_mutex_unlock
();
IDirect3D9Ex_Release
(
&
This
->
d3d_parent
->
IDirect3D9Ex_iface
);
IDirect3D9Ex_Release
(
&
device
->
d3d_parent
->
IDirect3D9Ex_iface
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
HeapFree
(
GetProcessHeap
(),
0
,
device
);
}
return
ref
;
}
...
...
@@ -2136,91 +2138,100 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexDeclaration(IDirect3DDevice9
return
hr
;
}
static
IDirect3DVertexDeclaration9
*
getConvertedDecl
(
IDirect3DDevice9Impl
*
This
,
DWORD
fvf
)
{
HRESULT
hr
;
D3DVERTEXELEMENT9
*
elements
=
NULL
;
IDirect3DVertexDeclaration9
*
pDecl
=
NULL
;
static
struct
wined3d_vertex_declaration
*
device_get_fvf_declaration
(
IDirect3DDevice9Impl
*
device
,
DWORD
fvf
)
{
struct
wined3d_vertex_declaration
*
wined3d_declaration
;
struct
fvf_declaration
*
fvf_decls
=
device
->
fvf_decls
;
IDirect3DVertexDeclaration9Impl
*
d3d9_declaration
;
D3DVERTEXELEMENT9
*
elements
;
int
p
,
low
,
high
;
/* deliberately signed */
IDirect3DVertexDeclaration9
**
convertedDecls
=
This
->
convertedDecls
;
HRESULT
hr
;
TRACE
(
"Searching for declaration for fvf %08x... "
,
fvf
);
low
=
0
;
high
=
This
->
numConvertedDecls
-
1
;
while
(
low
<=
high
)
{
high
=
device
->
fvf_decl_count
-
1
;
while
(
low
<=
high
)
{
p
=
(
low
+
high
)
>>
1
;
TRACE
(
"%d "
,
p
);
if
(((
IDirect3DVertexDeclaration9Impl
*
)
convertedDecls
[
p
])
->
convFVF
==
fvf
)
{
TRACE
(
"found %p
\n
"
,
convertedDecls
[
p
]);
return
convertedDecls
[
p
];
}
else
if
(((
IDirect3DVertexDeclaration9Impl
*
)
convertedDecls
[
p
])
->
convFVF
<
fvf
)
{
if
(
fvf_decls
[
p
].
fvf
==
fvf
)
{
TRACE
(
"found %p.
\n
"
,
fvf_decls
[
p
].
decl
);
return
fvf_decls
[
p
].
decl
;
}
if
(
fvf_decls
[
p
].
fvf
<
fvf
)
low
=
p
+
1
;
}
else
{
else
high
=
p
-
1
;
}
}
TRACE
(
"not found. Creating and inserting at position %d.
\n
"
,
low
);
hr
=
vdecl_convert_fvf
(
fvf
,
&
elements
);
if
(
hr
!=
S_OK
)
return
NULL
;
hr
=
IDirect3DDevice9Impl_CreateVertexDeclaration
(
&
This
->
IDirect3DDevice9Ex_iface
,
elements
,
&
pDecl
);
HeapFree
(
GetProcessHeap
(),
0
,
elements
);
/* CreateVertexDeclaration makes a copy */
if
(
hr
!=
S_OK
)
return
NULL
;
if
(
This
->
declArraySize
==
This
->
numConvertedDecls
)
{
int
grow
=
max
(
This
->
declArraySize
/
2
,
8
);
convertedDecls
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
convertedDecls
,
sizeof
(
convertedDecls
[
0
])
*
(
This
->
numConvertedDecls
+
grow
));
if
(
!
convertedDecls
)
{
/* This will destroy it */
IDirect3DVertexDeclaration9_Release
(
pDecl
);
if
(
FAILED
(
hr
=
vdecl_convert_fvf
(
fvf
,
&
elements
)))
return
NULL
;
hr
=
d3d9_vertex_declaration_create
(
device
,
elements
,
&
d3d9_declaration
);
HeapFree
(
GetProcessHeap
(),
0
,
elements
);
if
(
FAILED
(
hr
))
return
NULL
;
if
(
device
->
fvf_decl_size
==
device
->
fvf_decl_count
)
{
UINT
grow
=
max
(
device
->
fvf_decl_size
/
2
,
8
);
fvf_decls
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
fvf_decls
,
sizeof
(
*
fvf_decls
)
*
(
device
->
fvf_decl_size
+
grow
));
if
(
!
fvf_decls
)
{
IDirect3DVertexDeclaration9_Release
((
IDirect3DVertexDeclaration9
*
)
d3d9_declaration
);
return
NULL
;
}
This
->
convertedDecls
=
convertedD
ecls
;
This
->
declArrayS
ize
+=
grow
;
device
->
fvf_decls
=
fvf_d
ecls
;
device
->
fvf_decl_s
ize
+=
grow
;
}
memmove
(
convertedDecls
+
low
+
1
,
convertedDecls
+
low
,
sizeof
(
IDirect3DVertexDeclaration9Impl
*
)
*
(
This
->
numConvertedDecls
-
low
));
convertedDecls
[
low
]
=
pDecl
;
This
->
numConvertedDecls
++
;
d3d9_declaration
->
convFVF
=
fvf
;
wined3d_declaration
=
d3d9_declaration
->
wineD3DVertexDeclaration
;
wined3d_vertex_declaration_incref
(
wined3d_declaration
);
IDirect3DVertexDeclaration9_Release
((
IDirect3DVertexDeclaration9
*
)
d3d9_declaration
);
memmove
(
fvf_decls
+
low
+
1
,
fvf_decls
+
low
,
sizeof
(
*
fvf_decls
)
*
(
device
->
fvf_decl_count
-
low
));
fvf_decls
[
low
].
decl
=
wined3d_declaration
;
fvf_decls
[
low
].
fvf
=
fvf
;
++
device
->
fvf_decl_count
;
/* Will prevent the decl from being destroyed */
((
IDirect3DVertexDeclaration9Impl
*
)
pDecl
)
->
convFVF
=
fvf
;
IDirect3DVertexDeclaration9_Release
(
pDecl
);
/* Does not destroy now */
TRACE
(
"Returning %p. %u declatations in array.
\n
"
,
wined3d_declaration
,
device
->
fvf_decl_count
);
TRACE
(
"Returning %p. %d decls in array
\n
"
,
pDecl
,
This
->
numConvertedDecls
);
return
pDecl
;
return
wined3d_declaration
;
}
static
HRESULT
WINAPI
IDirect3DDevice9Impl_SetFVF
(
IDirect3DDevice9Ex
*
iface
,
DWORD
FVF
)
static
HRESULT
WINAPI
IDirect3DDevice9Impl_SetFVF
(
IDirect3DDevice9Ex
*
iface
,
DWORD
fvf
)
{
IDirect3DDevice9Impl
*
This
=
impl_from_IDirect3DDevice9Ex
(
iface
);
IDirect3DVertexDeclaration9
*
decl
;
struct
wined3d_vertex_declaration
*
decl
;
HRESULT
hr
;
TRACE
(
"iface %p, fvf %#x.
\n
"
,
iface
,
FVF
);
TRACE
(
"iface %p, fvf %#x.
\n
"
,
iface
,
fvf
);
if
(
!
FVF
)
if
(
!
fvf
)
{
WARN
(
"%#x is not a valid FVF
\n
"
,
FVF
);
WARN
(
"%#x is not a valid FVF
.
\n
"
,
fvf
);
return
D3D_OK
;
}
wined3d_mutex_lock
();
decl
=
getConvertedDecl
(
This
,
FVF
);
wined3d_mutex_unlock
();
if
(
!
decl
)
if
(
!
(
decl
=
device_get_fvf_declaration
(
This
,
fvf
)))
{
/* Any situation when this should happen, except out of memory? */
ERR
(
"Failed to create a converted vertex declaration
\n
"
);
return
D3DERR_DRIVERINTERNALERROR
;
wined3d_mutex_unlock
();
ERR
(
"Failed to create a vertex declaration for fvf %#x.
\n
"
,
fvf
);
return
D3DERR_DRIVERINTERNALERROR
;
}
hr
=
IDirect3DDevice9Impl_SetVertexDeclaration
(
iface
,
decl
);
if
(
FAILED
(
hr
))
ERR
(
"Failed to set vertex declaration
\n
"
);
hr
=
wined3d_device_set_vertex_declaration
(
This
->
wined3d_device
,
decl
);
if
(
FAILED
(
hr
))
ERR
(
"Failed to set vertex declaration.
\n
"
);
wined3d_mutex_unlock
();
return
hr
;
}
...
...
@@ -3466,8 +3477,8 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IDirect3D9Impl *parent, struct
/* Initialize the converted declaration array. This creates a valid pointer
* and when adding decls HeapReAlloc() can be used without further checking. */
device
->
convertedD
ecls
=
HeapAlloc
(
GetProcessHeap
(),
0
,
0
);
if
(
!
device
->
convertedD
ecls
)
device
->
fvf_d
ecls
=
HeapAlloc
(
GetProcessHeap
(),
0
,
0
);
if
(
!
device
->
fvf_d
ecls
)
{
ERR
(
"Failed to allocate FVF vertex declaration map memory.
\n
"
);
wined3d_mutex_lock
();
...
...
dlls/d3d9/vertexdeclaration.c
View file @
5fc17b84
...
...
@@ -219,44 +219,29 @@ static ULONG WINAPI IDirect3DVertexDeclaration9Impl_AddRef(LPDIRECT3DVERTEXDECLA
TRACE
(
"%p increasing refcount to %u.
\n
"
,
iface
,
ref
);
if
(
ref
==
1
)
{
if
(
ref
==
1
)
{
IDirect3DDevice9Ex_AddRef
(
This
->
parentDevice
);
if
(
!
This
->
convFVF
)
{
wined3d_mutex_lock
();
wined3d_vertex_declaration_incref
(
This
->
wineD3DVertexDeclaration
);
wined3d_mutex_unlock
();
}
wined3d_mutex_lock
();
wined3d_vertex_declaration_incref
(
This
->
wineD3DVertexDeclaration
);
wined3d_mutex_unlock
();
}
return
ref
;
}
void
IDirect3DVertexDeclaration9Impl_Destroy
(
LPDIRECT3DVERTEXDECLARATION9
iface
)
{
IDirect3DVertexDeclaration9Impl
*
This
=
(
IDirect3DVertexDeclaration9Impl
*
)
iface
;
if
(
This
->
ref
!=
0
)
{
/* Should not happen unless wine has a bug or the application releases references it does not own */
ERR
(
"Destroying vdecl with ref != 0
\n
"
);
}
wined3d_mutex_lock
();
wined3d_vertex_declaration_decref
(
This
->
wineD3DVertexDeclaration
);
wined3d_mutex_unlock
();
}
static
ULONG
WINAPI
IDirect3DVertexDeclaration9Impl_Release
(
LPDIRECT3DVERTEXDECLARATION9
iface
)
{
IDirect3DVertexDeclaration9Impl
*
This
=
(
IDirect3DVertexDeclaration9Impl
*
)
iface
;
ULONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
TRACE
(
"%p decreasing refcount to %u.
\n
"
,
iface
,
ref
);
if
(
ref
==
0
)
{
if
(
!
ref
)
{
IDirect3DDevice9Ex
*
parentDevice
=
This
->
parentDevice
;
if
(
!
This
->
convFVF
)
{
IDirect3DVertexDeclaration9Impl_Destroy
(
iface
);
}
wined3d_mutex_lock
();
wined3d_vertex_declaration_decref
(
This
->
wineD3DVertexDeclaration
);
wined3d_mutex_unlock
();
/* Release the device last, as it may cause the device to be destroyed. */
IDirect3DDevice9Ex_Release
(
parentDevice
);
...
...
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