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
702eeb6b
Commit
702eeb6b
authored
Mar 05, 2009
by
Henri Verbeet
Committed by
Alexandre Julliard
Mar 05, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Add separate methods for setting the primitive type.
parent
3b07e705
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
217 additions
and
128 deletions
+217
-128
device.c
dlls/d3d10core/device.c
+10
-2
device.c
dlls/d3d8/device.c
+9
-5
device.c
dlls/d3d9/device.c
+9
-5
device.c
dlls/ddraw/device.c
+14
-22
device.c
dlls/wined3d/device.c
+139
-30
drawprim.c
dlls/wined3d/drawprim.c
+3
-48
stateblock.c
dlls/wined3d/stateblock.c
+13
-0
wined3d_private.h
dlls/wined3d/wined3d_private.h
+14
-10
wined3d.idl
include/wine/wined3d.idl
+6
-6
No files found.
dlls/d3d10core/device.c
View file @
702eeb6b
...
...
@@ -210,7 +210,11 @@ static void STDMETHODCALLTYPE d3d10_device_GSSetShader(ID3D10Device *iface, ID3D
static
void
STDMETHODCALLTYPE
d3d10_device_IASetPrimitiveTopology
(
ID3D10Device
*
iface
,
D3D10_PRIMITIVE_TOPOLOGY
topology
)
{
FIXME
(
"iface %p, topology %s stub!
\n
"
,
iface
,
debug_d3d10_primitive_topology
(
topology
));
struct
d3d10_device
*
This
=
(
struct
d3d10_device
*
)
iface
;
TRACE
(
"iface %p, topology %s
\n
"
,
iface
,
debug_d3d10_primitive_topology
(
topology
));
IWineD3DDevice_SetPrimitiveType
(
This
->
wined3d_device
,
(
WINED3DPRIMITIVETYPE
)
topology
);
}
static
void
STDMETHODCALLTYPE
d3d10_device_VSSetShaderResources
(
ID3D10Device
*
iface
,
...
...
@@ -424,7 +428,11 @@ static void STDMETHODCALLTYPE d3d10_device_GSGetShader(ID3D10Device *iface, ID3D
static
void
STDMETHODCALLTYPE
d3d10_device_IAGetPrimitiveTopology
(
ID3D10Device
*
iface
,
D3D10_PRIMITIVE_TOPOLOGY
*
topology
)
{
FIXME
(
"iface %p, topology %p stub!
\n
"
,
iface
,
topology
);
struct
d3d10_device
*
This
=
(
struct
d3d10_device
*
)
iface
;
TRACE
(
"iface %p, topology %p
\n
"
,
iface
,
topology
);
IWineD3DDevice_GetPrimitiveType
(
This
->
wined3d_device
,
(
WINED3DPRIMITIVETYPE
*
)
topology
);
}
static
void
STDMETHODCALLTYPE
d3d10_device_VSGetShaderResources
(
ID3D10Device
*
iface
,
...
...
dlls/d3d8/device.c
View file @
702eeb6b
...
...
@@ -1538,7 +1538,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface
TRACE
(
"(%p) Relay
\n
"
,
This
);
EnterCriticalSection
(
&
d3d8_cs
);
hr
=
IWineD3DDevice_DrawPrimitive
(
This
->
WineD3DDevice
,
PrimitiveType
,
StartVertex
,
IWineD3DDevice_SetPrimitiveType
(
This
->
WineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawPrimitive
(
This
->
WineD3DDevice
,
StartVertex
,
vertex_count_from_primitive_count
(
PrimitiveType
,
PrimitiveCount
));
LeaveCriticalSection
(
&
d3d8_cs
);
return
hr
;
...
...
@@ -1551,7 +1552,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE
TRACE
(
"(%p) Relay
\n
"
,
This
);
EnterCriticalSection
(
&
d3d8_cs
);
hr
=
IWineD3DDevice_DrawIndexedPrimitive
(
This
->
WineD3DDevice
,
PrimitiveType
,
MinVertexIndex
,
NumVertices
,
IWineD3DDevice_SetPrimitiveType
(
This
->
WineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawIndexedPrimitive
(
This
->
WineD3DDevice
,
MinVertexIndex
,
NumVertices
,
startIndex
,
vertex_count_from_primitive_count
(
PrimitiveType
,
primCount
));
LeaveCriticalSection
(
&
d3d8_cs
);
return
hr
;
...
...
@@ -1563,7 +1565,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 ifa
TRACE
(
"(%p) Relay
\n
"
,
This
);
EnterCriticalSection
(
&
d3d8_cs
);
hr
=
IWineD3DDevice_DrawPrimitiveUP
(
This
->
WineD3DDevice
,
PrimitiveType
,
IWineD3DDevice_SetPrimitiveType
(
This
->
WineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawPrimitiveUP
(
This
->
WineD3DDevice
,
vertex_count_from_primitive_count
(
PrimitiveType
,
PrimitiveCount
),
pVertexStreamZeroData
,
VertexStreamZeroStride
);
LeaveCriticalSection
(
&
d3d8_cs
);
...
...
@@ -1579,8 +1582,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVI
TRACE
(
"(%p) Relay
\n
"
,
This
);
EnterCriticalSection
(
&
d3d8_cs
);
hr
=
IWineD3DDevice_DrawIndexedPrimitiveUP
(
This
->
WineD3DDevice
,
PrimitiveType
,
MinVertexIndex
,
NumVertexIndices
,
vertex_count_from_primitive_count
(
PrimitiveType
,
PrimitiveCount
),
pIndexData
,
IWineD3DDevice_SetPrimitiveType
(
This
->
WineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawIndexedPrimitiveUP
(
This
->
WineD3DDevice
,
MinVertexIndex
,
NumVertexIndices
,
vertex_count_from_primitive_count
(
PrimitiveType
,
PrimitiveCount
),
pIndexData
,
wined3dformat_from_d3dformat
(
IndexDataFormat
),
pVertexStreamZeroData
,
VertexStreamZeroStride
);
LeaveCriticalSection
(
&
d3d8_cs
);
return
hr
;
...
...
dlls/d3d9/device.c
View file @
702eeb6b
...
...
@@ -1383,7 +1383,8 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(LPDIRECT3DDEVICE9EX ifa
TRACE
(
"(%p) Relay
\n
"
,
This
);
EnterCriticalSection
(
&
d3d9_cs
);
hr
=
IWineD3DDevice_DrawPrimitive
(
This
->
WineD3DDevice
,
PrimitiveType
,
StartVertex
,
IWineD3DDevice_SetPrimitiveType
(
This
->
WineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawPrimitive
(
This
->
WineD3DDevice
,
StartVertex
,
vertex_count_from_primitive_count
(
PrimitiveType
,
PrimitiveCount
));
LeaveCriticalSection
(
&
d3d9_cs
);
return
hr
;
...
...
@@ -1398,7 +1399,8 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVI
/* D3D8 passes the baseVertexIndex in SetIndices, and due to the stateblock functions wined3d has to work that way */
EnterCriticalSection
(
&
d3d9_cs
);
IWineD3DDevice_SetBaseVertexIndex
(
This
->
WineD3DDevice
,
BaseVertexIndex
);
hr
=
IWineD3DDevice_DrawIndexedPrimitive
(
This
->
WineD3DDevice
,
PrimitiveType
,
MinVertexIndex
,
NumVertices
,
IWineD3DDevice_SetPrimitiveType
(
This
->
WineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawIndexedPrimitive
(
This
->
WineD3DDevice
,
MinVertexIndex
,
NumVertices
,
startIndex
,
vertex_count_from_primitive_count
(
PrimitiveType
,
primCount
));
LeaveCriticalSection
(
&
d3d9_cs
);
return
hr
;
...
...
@@ -1410,7 +1412,8 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE9EX
TRACE
(
"(%p) Relay
\n
"
,
This
);
EnterCriticalSection
(
&
d3d9_cs
);
hr
=
IWineD3DDevice_DrawPrimitiveUP
(
This
->
WineD3DDevice
,
PrimitiveType
,
IWineD3DDevice_SetPrimitiveType
(
This
->
WineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawPrimitiveUP
(
This
->
WineD3DDevice
,
vertex_count_from_primitive_count
(
PrimitiveType
,
PrimitiveCount
),
pVertexStreamZeroData
,
VertexStreamZeroStride
);
LeaveCriticalSection
(
&
d3d9_cs
);
...
...
@@ -1425,8 +1428,9 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDE
TRACE
(
"(%p) Relay
\n
"
,
This
);
EnterCriticalSection
(
&
d3d9_cs
);
hr
=
IWineD3DDevice_DrawIndexedPrimitiveUP
(
This
->
WineD3DDevice
,
PrimitiveType
,
MinVertexIndex
,
NumVertexIndices
,
vertex_count_from_primitive_count
(
PrimitiveType
,
PrimitiveCount
),
pIndexData
,
IWineD3DDevice_SetPrimitiveType
(
This
->
WineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawIndexedPrimitiveUP
(
This
->
WineD3DDevice
,
MinVertexIndex
,
NumVertexIndices
,
vertex_count_from_primitive_count
(
PrimitiveType
,
PrimitiveCount
),
pIndexData
,
wined3dformat_from_d3dformat
(
IndexDataFormat
),
pVertexStreamZeroData
,
VertexStreamZeroStride
);
LeaveCriticalSection
(
&
d3d9_cs
);
return
hr
;
...
...
dlls/ddraw/device.c
View file @
702eeb6b
...
...
@@ -3484,11 +3484,8 @@ IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
}
/* This method translates to the user pointer draw of WineD3D */
hr
=
IWineD3DDevice_DrawPrimitiveUP
(
This
->
wineD3DDevice
,
PrimitiveType
,
VertexCount
,
Vertices
,
stride
);
IWineD3DDevice_SetPrimitiveType
(
This
->
wineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawPrimitiveUP
(
This
->
wineD3DDevice
,
VertexCount
,
Vertices
,
stride
);
LeaveCriticalSection
(
&
ddraw_cs
);
return
hr
;
}
...
...
@@ -3610,9 +3607,10 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
return
hr
;
}
hr
=
IWineD3DDevice_DrawIndexedPrimitiveUP
(
This
->
wineD3DDevice
,
PrimitiveType
,
0
/* MinVertexIndex */
,
VertexCount
/* UINT NumVertexIndex */
,
IndexCount
,
Indices
,
WINED3DFMT_R16_UINT
,
Vertices
,
get_flexible_vertex_size
(
VertexType
));
IWineD3DDevice_SetPrimitiveType
(
This
->
wineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawIndexedPrimitiveUP
(
This
->
wineD3DDevice
,
0
/* MinVertexIndex */
,
VertexCount
/* UINT NumVertexIndex */
,
IndexCount
,
Indices
,
WINED3DFMT_R16_UINT
,
Vertices
,
get_flexible_vertex_size
(
VertexType
));
LeaveCriticalSection
(
&
ddraw_cs
);
return
hr
;
}
...
...
@@ -3878,10 +3876,8 @@ IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
/* WineD3D doesn't need the FVF here */
EnterCriticalSection
(
&
ddraw_cs
);
hr
=
IWineD3DDevice_DrawPrimitiveStrided
(
This
->
wineD3DDevice
,
PrimitiveType
,
VertexCount
,
&
WineD3DStrided
);
IWineD3DDevice_SetPrimitiveType
(
This
->
wineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawPrimitiveStrided
(
This
->
wineD3DDevice
,
VertexCount
,
&
WineD3DStrided
);
LeaveCriticalSection
(
&
ddraw_cs
);
return
hr
;
}
...
...
@@ -4021,7 +4017,8 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
/* WineD3D doesn't need the FVF here */
EnterCriticalSection
(
&
ddraw_cs
);
hr
=
IWineD3DDevice_DrawIndexedPrimitiveStrided
(
This
->
wineD3DDevice
,
PrimitiveType
,
IWineD3DDevice_SetPrimitiveType
(
This
->
wineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawIndexedPrimitiveStrided
(
This
->
wineD3DDevice
,
IndexCount
,
&
WineD3DStrided
,
VertexCount
,
Indices
,
WINED3DFMT_R16_UINT
);
LeaveCriticalSection
(
&
ddraw_cs
);
return
hr
;
...
...
@@ -4153,10 +4150,8 @@ IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
}
/* Now draw the primitives */
hr
=
IWineD3DDevice_DrawPrimitive
(
This
->
wineD3DDevice
,
PrimitiveType
,
StartVertex
,
NumVertices
);
IWineD3DDevice_SetPrimitiveType
(
This
->
wineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawPrimitive
(
This
->
wineD3DDevice
,
StartVertex
,
NumVertices
);
LeaveCriticalSection
(
&
ddraw_cs
);
return
hr
;
}
...
...
@@ -4317,12 +4312,9 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
}
IWineD3DDevice_SetPrimitiveType
(
This
->
wineD3DDevice
,
PrimitiveType
);
hr
=
IWineD3DDevice_DrawIndexedPrimitive
(
This
->
wineD3DDevice
,
PrimitiveType
,
0
/* minIndex */
,
NumVertices
,
0
/* StartIndex */
,
IndexCount
);
0
/* minIndex */
,
NumVertices
,
0
/* StartIndex */
,
IndexCount
);
LeaveCriticalSection
(
&
ddraw_cs
);
return
hr
;
...
...
dlls/wined3d/device.c
View file @
702eeb6b
...
...
@@ -59,6 +59,89 @@ static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResour
**********************************************************/
const
float
identity
[
16
]
=
{
1
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
1
};
/* When needed for comparisons */
/* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these
* actually have the same values in GL and D3D. */
static
GLenum
gl_primitive_type_from_d3d
(
WINED3DPRIMITIVETYPE
primitive_type
)
{
switch
(
primitive_type
)
{
case
WINED3DPT_POINTLIST
:
return
GL_POINTS
;
case
WINED3DPT_LINELIST
:
return
GL_LINES
;
case
WINED3DPT_LINESTRIP
:
return
GL_LINE_STRIP
;
case
WINED3DPT_TRIANGLELIST
:
return
GL_TRIANGLES
;
case
WINED3DPT_TRIANGLESTRIP
:
return
GL_TRIANGLE_STRIP
;
case
WINED3DPT_TRIANGLEFAN
:
return
GL_TRIANGLE_FAN
;
case
WINED3DPT_LINELIST_ADJ
:
return
GL_LINES_ADJACENCY_ARB
;
case
WINED3DPT_LINESTRIP_ADJ
:
return
GL_LINE_STRIP_ADJACENCY_ARB
;
case
WINED3DPT_TRIANGLELIST_ADJ
:
return
GL_TRIANGLES_ADJACENCY_ARB
;
case
WINED3DPT_TRIANGLESTRIP_ADJ
:
return
GL_TRIANGLE_STRIP_ADJACENCY_ARB
;
default:
FIXME
(
"Unhandled primitive type %s
\n
"
,
debug_d3dprimitivetype
(
primitive_type
));
return
GL_NONE
;
}
}
static
WINED3DPRIMITIVETYPE
d3d_primitive_type_from_gl
(
GLenum
primitive_type
)
{
switch
(
primitive_type
)
{
case
GL_POINTS
:
return
WINED3DPT_POINTLIST
;
case
GL_LINES
:
return
WINED3DPT_LINELIST
;
case
GL_LINE_STRIP
:
return
WINED3DPT_LINESTRIP
;
case
GL_TRIANGLES
:
return
WINED3DPT_TRIANGLELIST
;
case
GL_TRIANGLE_STRIP
:
return
WINED3DPT_TRIANGLESTRIP
;
case
GL_TRIANGLE_FAN
:
return
WINED3DPT_TRIANGLEFAN
;
case
GL_LINES_ADJACENCY_ARB
:
return
WINED3DPT_LINELIST_ADJ
;
case
GL_LINE_STRIP_ADJACENCY_ARB
:
return
WINED3DPT_LINESTRIP_ADJ
;
case
GL_TRIANGLES_ADJACENCY_ARB
:
return
WINED3DPT_TRIANGLELIST_ADJ
;
case
GL_TRIANGLE_STRIP_ADJACENCY_ARB
:
return
WINED3DPT_TRIANGLESTRIP_ADJ
;
default:
FIXME
(
"Unhandled primitive type %s
\n
"
,
debug_d3dprimitivetype
(
primitive_type
));
return
WINED3DPT_UNDEFINED
;
}
}
/**********************************************************
* IUnknown parts follows
**********************************************************/
...
...
@@ -5301,13 +5384,35 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun
/*****
* Drawing functions
*****/
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawPrimitive
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
PrimitiveType
,
UINT
StartVertex
,
UINT
vertex_count
)
static
void
WINAPI
IWineD3DDeviceImpl_SetPrimitiveType
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
primitive_type
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
TRACE
(
"iface %p, primitive_type %s
\n
"
,
iface
,
debug_d3dprimitivetype
(
primitive_type
));
This
->
updateStateBlock
->
changed
.
primitive_type
=
TRUE
;
This
->
updateStateBlock
->
gl_primitive_type
=
gl_primitive_type_from_d3d
(
primitive_type
);
}
static
void
WINAPI
IWineD3DDeviceImpl_GetPrimitiveType
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
*
primitive_type
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
TRACE
(
"iface %p, primitive_type %p
\n
"
,
iface
,
primitive_type
);
*
primitive_type
=
d3d_primitive_type_from_gl
(
This
->
stateBlock
->
gl_primitive_type
);
TRACE
(
"Returning %s
\n
"
,
debug_d3dprimitivetype
(
*
primitive_type
));
}
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawPrimitive
(
IWineD3DDevice
*
iface
,
UINT
StartVertex
,
UINT
vertex_count
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
TRACE
(
"(%p) : type %u (%s), start %u, count %u
\n
"
,
This
,
PrimitiveType
,
debug_d3dprimitivetype
(
PrimitiveType
),
StartVertex
,
vertex_count
);
TRACE
(
"(%p) : start %u, count %u
\n
"
,
This
,
StartVertex
,
vertex_count
);
if
(
!
This
->
stateBlock
->
vertexDecl
)
{
WARN
(
"(%p) : Called without a valid vertex declaration set
\n
"
,
This
);
...
...
@@ -5325,13 +5430,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitive(IWineD3DDevice *iface,
IWineD3DDeviceImpl_MarkStateDirty
(
This
,
STATE_STREAMSRC
);
}
/* Account for the loading offset due to index buffers. Instead of reloading all sources correct it with the startvertex parameter */
drawPrimitive
(
iface
,
PrimitiveType
,
vertex_count
,
0
/* NumVertices */
,
StartVertex
/* start_idx */
,
drawPrimitive
(
iface
,
vertex_count
,
0
/* NumVertices */
,
StartVertex
/* start_idx */
,
0
/* indxSize */
,
NULL
/* indxData */
,
0
/* minIndex */
);
return
WINED3D_OK
;
}
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawIndexedPrimitive
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
PrimitiveType
,
UINT
minIndex
,
UINT
NumVertices
,
UINT
startIndex
,
UINT
index_count
)
UINT
minIndex
,
UINT
NumVertices
,
UINT
startIndex
,
UINT
index_count
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
UINT
idxStride
=
2
;
...
...
@@ -5360,8 +5465,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if
}
vbo
=
((
IWineD3DIndexBufferImpl
*
)
pIB
)
->
vbo
;
TRACE
(
"(%p) :
type %u (%s), min %u, vertex count %u, startIdx %u, index count %u
\n
"
,
This
,
PrimitiveType
,
debug_d3dprimitivetype
(
PrimitiveType
)
,
minIndex
,
NumVertices
,
startIndex
,
index_count
);
TRACE
(
"(%p) :
min %u, vertex count %u, startIdx %u, index count %u
\n
"
,
This
,
minIndex
,
NumVertices
,
startIndex
,
index_count
);
IWineD3DIndexBuffer_GetDesc
(
pIB
,
&
IdxBufDsc
);
if
(
IdxBufDsc
.
Format
==
WINED3DFMT_R16_UINT
)
{
...
...
@@ -5375,20 +5480,20 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if
IWineD3DDeviceImpl_MarkStateDirty
(
This
,
STATE_STREAMSRC
);
}
drawPrimitive
(
iface
,
PrimitiveType
,
index_count
,
NumVertices
,
startIndex
,
idxStride
,
vbo
?
NULL
:
((
IWineD3DIndexBufferImpl
*
)
pIB
)
->
resource
.
allocatedMemory
,
minIndex
);
drawPrimitive
(
iface
,
index_count
,
NumVertices
,
startIndex
,
idxStride
,
vbo
?
NULL
:
((
IWineD3DIndexBufferImpl
*
)
pIB
)
->
resource
.
allocatedMemory
,
minIndex
);
return
WINED3D_OK
;
}
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawPrimitiveUP
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
PrimitiveType
,
UINT
vertex_count
,
const
void
*
pVertexStreamZeroData
,
UINT
VertexStreamZeroStride
)
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawPrimitiveUP
(
IWineD3DDevice
*
iface
,
UINT
vertex_count
,
const
void
*
pVertexStreamZeroData
,
UINT
VertexStreamZeroStride
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
IWineD3DVertexBuffer
*
vb
;
TRACE
(
"(%p) :
type %u (%s), vertex count %u, pVtxData %p, stride %u
\n
"
,
This
,
PrimitiveType
,
debug_d3dprimitivetype
(
PrimitiveType
)
,
vertex_count
,
pVertexStreamZeroData
,
VertexStreamZeroStride
);
TRACE
(
"(%p) :
vertex count %u, pVtxData %p, stride %u
\n
"
,
This
,
vertex_count
,
pVertexStreamZeroData
,
VertexStreamZeroStride
);
if
(
!
This
->
stateBlock
->
vertexDecl
)
{
WARN
(
"(%p) : Called without a valid vertex declaration set
\n
"
,
This
);
...
...
@@ -5407,8 +5512,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface,
/* TODO: Only mark dirty if drawing from a different UP address */
IWineD3DDeviceImpl_MarkStateDirty
(
This
,
STATE_STREAMSRC
);
drawPrimitive
(
iface
,
PrimitiveType
,
vertex_count
,
0
/* NumVertices
*/
,
0
/*
start_idx */
,
0
/*
indxSize*/
,
NULL
/* indxData */
,
0
/* indxMin */
);
drawPrimitive
(
iface
,
vertex_count
,
0
/* NumVertices */
,
0
/* start_idx
*/
,
0
/* indxSize*/
,
NULL
/* indxData */
,
0
/* indxMin */
);
/* MSDN specifies stream zero settings must be set to NULL */
This
->
stateBlock
->
streamStride
[
0
]
=
0
;
...
...
@@ -5420,9 +5525,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface,
return
WINED3D_OK
;
}
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawIndexedPrimitiveUP
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
PrimitiveType
,
UINT
MinVertexIndex
,
UINT
NumVertices
,
UINT
index_count
,
const
void
*
pIndexData
,
WINED3DFORMAT
IndexDataFormat
,
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawIndexedPrimitiveUP
(
IWineD3DDevice
*
iface
,
UINT
MinVertexIndex
,
UINT
NumVertices
,
UINT
index_count
,
const
void
*
pIndexData
,
WINED3DFORMAT
IndexDataFormat
,
const
void
*
pVertexStreamZeroData
,
UINT
VertexStreamZeroStride
)
{
int
idxStride
;
...
...
@@ -5430,9 +5534,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
IWineD3DVertexBuffer
*
vb
;
IWineD3DIndexBuffer
*
ib
;
TRACE
(
"(%p) :
type %u (%s),
MinVtxIdx %u, NumVIdx %u, index count %u, pidxdata %p, IdxFmt %u, pVtxdata %p, stride=%u
\n
"
,
This
,
PrimitiveType
,
debug_d3dprimitivetype
(
PrimitiveType
),
MinVertexIndex
,
NumVertices
,
index_count
,
pIndexData
,
IndexDataFormat
,
pVertexStreamZeroData
,
VertexStreamZeroStride
);
TRACE
(
"(%p) : MinVtxIdx %u, NumVIdx %u, index count %u, pidxdata %p, IdxFmt %u, pVtxdata %p, stride=%u
\n
"
,
This
,
MinVertexIndex
,
NumVertices
,
index_count
,
pIndexData
,
IndexDataFormat
,
pVertexStreamZeroData
,
VertexStreamZeroStride
);
if
(
!
This
->
stateBlock
->
vertexDecl
)
{
WARN
(
"(%p) : Called without a valid vertex declaration set
\n
"
,
This
);
...
...
@@ -5460,8 +5564,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
IWineD3DDeviceImpl_MarkStateDirty
(
This
,
STATE_VDECL
);
IWineD3DDeviceImpl_MarkStateDirty
(
This
,
STATE_INDEXBUFFER
);
drawPrimitive
(
iface
,
PrimitiveType
,
index_count
,
NumVertices
,
0
/* start_idx */
,
idxStride
,
pIndexData
,
MinVertexIndex
);
drawPrimitive
(
iface
,
index_count
,
NumVertices
,
0
/* start_idx */
,
idxStride
,
pIndexData
,
MinVertexIndex
);
/* MSDN specifies stream zero settings and index buffer must be set to NULL */
This
->
stateBlock
->
streamSource
[
0
]
=
NULL
;
...
...
@@ -5479,7 +5583,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
}
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawPrimitiveStrided
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
PrimitiveType
,
UINT
vertex_count
,
const
WineDirect3DVertexStridedData
*
DrawPrimStrideData
)
UINT
vertex_count
,
const
WineDirect3DVertexStridedData
*
DrawPrimStrideData
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
...
...
@@ -5491,13 +5595,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided(IWineD3DDevice *if
IWineD3DDeviceImpl_MarkStateDirty
(
This
,
STATE_INDEXBUFFER
);
This
->
stateBlock
->
baseVertexIndex
=
0
;
This
->
up_strided
=
DrawPrimStrideData
;
drawPrimitive
(
iface
,
PrimitiveType
,
vertex_count
,
0
,
0
,
0
,
NULL
,
0
);
drawPrimitive
(
iface
,
vertex_count
,
0
,
0
,
0
,
NULL
,
0
);
This
->
up_strided
=
NULL
;
return
WINED3D_OK
;
}
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
PrimitiveType
,
UINT
vertex_count
,
const
WineDirect3DVertexStridedData
*
DrawPrimStrideData
,
UINT
vertex_count
,
const
WineDirect3DVertexStridedData
*
DrawPrimStrideData
,
UINT
NumVertices
,
const
void
*
pIndexData
,
WINED3DFORMAT
IndexDataFormat
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
...
...
@@ -5512,8 +5616,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided(IWineD3DDev
This
->
stateBlock
->
streamIsUP
=
TRUE
;
This
->
stateBlock
->
baseVertexIndex
=
0
;
This
->
up_strided
=
DrawPrimStrideData
;
drawPrimitive
(
iface
,
PrimitiveType
,
vertex_count
,
0
/* numindices */
,
0
/* start_idx */
,
idxSize
,
pIndexData
,
0
/* minindex */
);
drawPrimitive
(
iface
,
vertex_count
,
0
/* numindices */
,
0
/* start_idx */
,
idxSize
,
pIndexData
,
0
/* minindex */
);
This
->
up_strided
=
NULL
;
return
WINED3D_OK
;
}
...
...
@@ -6089,6 +6192,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
static
HRESULT
WINAPI
IWineD3DDeviceImpl_DrawRectPatch
(
IWineD3DDevice
*
iface
,
UINT
Handle
,
CONST
float
*
pNumSegs
,
CONST
WINED3DRECTPATCH_INFO
*
pRectPatchInfo
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
struct
WineD3DRectPatch
*
patch
;
GLenum
old_primitive_type
;
unsigned
int
i
;
struct
list
*
e
;
BOOL
found
;
...
...
@@ -6158,7 +6262,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawRectPatch(IWineD3DDevice *iface, UI
}
This
->
currentPatch
=
patch
;
IWineD3DDevice_DrawPrimitiveStrided
(
iface
,
WINED3DPT_TRIANGLELIST
,
patch
->
numSegs
[
0
]
*
patch
->
numSegs
[
1
]
*
2
,
&
patch
->
strided
);
old_primitive_type
=
This
->
stateBlock
->
gl_primitive_type
;
This
->
stateBlock
->
gl_primitive_type
=
GL_TRIANGLES
;
IWineD3DDevice_DrawPrimitiveStrided
(
iface
,
patch
->
numSegs
[
0
]
*
patch
->
numSegs
[
1
]
*
2
,
&
patch
->
strided
);
This
->
stateBlock
->
gl_primitive_type
=
old_primitive_type
;
This
->
currentPatch
=
NULL
;
/* Destroy uncached patches */
...
...
@@ -7762,6 +7869,8 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
IWineD3DDeviceImpl_Clear
,
IWineD3DDeviceImpl_ClearRendertargetView
,
/*** Drawing ***/
IWineD3DDeviceImpl_SetPrimitiveType
,
IWineD3DDeviceImpl_GetPrimitiveType
,
IWineD3DDeviceImpl_DrawPrimitive
,
IWineD3DDeviceImpl_DrawIndexedPrimitive
,
IWineD3DDeviceImpl_DrawPrimitiveUP
,
...
...
dlls/wined3d/drawprim.c
View file @
702eeb6b
...
...
@@ -32,48 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
#include <stdio.h>
#include <math.h>
/* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these
* actually have the same values in GL and D3D. */
static
GLenum
primitive_to_gl
(
WINED3DPRIMITIVETYPE
primitive_type
)
{
switch
(
primitive_type
)
{
case
WINED3DPT_POINTLIST
:
return
GL_POINTS
;
case
WINED3DPT_LINELIST
:
return
GL_LINES
;
case
WINED3DPT_LINESTRIP
:
return
GL_LINE_STRIP
;
case
WINED3DPT_TRIANGLELIST
:
return
GL_TRIANGLES
;
case
WINED3DPT_TRIANGLESTRIP
:
return
GL_TRIANGLE_STRIP
;
case
WINED3DPT_TRIANGLEFAN
:
return
GL_TRIANGLE_FAN
;
case
WINED3DPT_LINELIST_ADJ
:
return
GL_LINES_ADJACENCY_ARB
;
case
WINED3DPT_LINESTRIP_ADJ
:
return
GL_LINE_STRIP_ADJACENCY_ARB
;
case
WINED3DPT_TRIANGLELIST_ADJ
:
return
GL_TRIANGLES_ADJACENCY_ARB
;
case
WINED3DPT_TRIANGLESTRIP_ADJ
:
return
GL_TRIANGLE_STRIP_ADJACENCY_ARB
;
default:
FIXME
(
"Unhandled primitive type %s
\n
"
,
debug_d3dprimitivetype
(
primitive_type
));
return
GL_NONE
;
}
}
static
BOOL
fixed_get_input
(
BYTE
usage
,
BYTE
usage_idx
,
unsigned
int
*
regnum
)
{
...
...
@@ -819,8 +777,8 @@ static inline void remove_vbos(IWineD3DDeviceImpl *This, WineDirect3DVertexStrid
}
/* Routine common to the draw primitive and draw indexed primitive routines */
void
drawPrimitive
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
PrimitiveType
,
UINT
index_count
,
UINT
numberOfVertices
,
UINT
StartIdx
,
UINT
idxSize
,
const
void
*
idxData
,
UINT
minIndex
)
void
drawPrimitive
(
IWineD3DDevice
*
iface
,
UINT
index_count
,
UINT
numberOfVertices
,
UINT
StartIdx
,
UINT
idxSize
,
const
void
*
idxData
,
UINT
minIndex
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
...
...
@@ -854,13 +812,10 @@ void drawPrimitive(IWineD3DDevice *iface, WINED3DPRIMITIVETYPE PrimitiveType, UI
/* Ok, we will be updating the screen from here onwards so grab the lock */
ENTER_GL
();
{
GLenum
glPrimType
;
GLenum
glPrimType
=
This
->
stateBlock
->
gl_primitive_type
;
BOOL
emulation
=
FALSE
;
const
WineDirect3DVertexStridedData
*
strided
=
&
This
->
strided_streams
;
WineDirect3DVertexStridedData
stridedlcl
;
/* Ok, Work out which primitive is requested and how many vertexes that
will be */
glPrimType
=
primitive_to_gl
(
PrimitiveType
);
if
(
!
numberOfVertices
)
numberOfVertices
=
index_count
;
...
...
dlls/wined3d/stateblock.c
View file @
702eeb6b
...
...
@@ -77,6 +77,7 @@ static void stateblock_savedstates_copy(IWineD3DStateBlock* iface, SAVEDSTATES *
unsigned
bsize
=
sizeof
(
BOOL
);
/* Single values */
dest
->
primitive_type
=
source
->
primitive_type
;
dest
->
indices
=
source
->
indices
;
dest
->
material
=
source
->
material
;
dest
->
viewport
=
source
->
viewport
;
...
...
@@ -121,6 +122,7 @@ void stateblock_savedstates_set(
unsigned
bsize
=
sizeof
(
BOOL
);
/* Single values */
states
->
primitive_type
=
value
;
states
->
indices
=
value
;
states
->
material
=
value
;
states
->
viewport
=
value
;
...
...
@@ -188,6 +190,7 @@ void stateblock_copy(
stateblock_savedstates_copy
(
source
,
&
Dest
->
changed
,
&
This
->
changed
);
/* Single items */
Dest
->
gl_primitive_type
=
This
->
gl_primitive_type
;
Dest
->
vertexDecl
=
This
->
vertexDecl
;
Dest
->
vertexShader
=
This
->
vertexShader
;
Dest
->
streamIsUP
=
This
->
streamIsUP
;
...
...
@@ -499,6 +502,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
targetStateBlock
->
transforms
[
This
->
contained_transform_states
[
i
]];
}
if
(
This
->
changed
.
primitive_type
)
This
->
gl_primitive_type
=
targetStateBlock
->
gl_primitive_type
;
if
(
This
->
changed
.
indices
&&
((
This
->
pIndexData
!=
targetStateBlock
->
pIndexData
)
||
(
This
->
baseVertexIndex
!=
targetStateBlock
->
baseVertexIndex
)))
{
TRACE
(
"Updating pIndexData to %p, baseVertexIndex to %d
\n
"
,
...
...
@@ -628,6 +633,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
memcpy
(
This
->
vertexShaderConstantB
,
targetStateBlock
->
vertexShaderConstantB
,
sizeof
(
This
->
vertexShaderConstantI
));
memcpy
(
This
->
vertexShaderConstantI
,
targetStateBlock
->
vertexShaderConstantI
,
sizeof
(
This
->
vertexShaderConstantF
));
memcpy
(
This
->
vertexShaderConstantF
,
targetStateBlock
->
vertexShaderConstantF
,
sizeof
(
float
)
*
GL_LIMITS
(
vshader_constantsF
)
*
4
);
This
->
gl_primitive_type
=
targetStateBlock
->
gl_primitive_type
;
memcpy
(
This
->
streamStride
,
targetStateBlock
->
streamStride
,
sizeof
(
This
->
streamStride
));
memcpy
(
This
->
streamOffset
,
targetStateBlock
->
streamOffset
,
sizeof
(
This
->
streamOffset
));
memcpy
(
This
->
streamFreq
,
targetStateBlock
->
streamFreq
,
sizeof
(
This
->
streamFreq
));
...
...
@@ -827,6 +833,12 @@ should really perform a delta so that only the changes get updated*/
&
This
->
transforms
[
This
->
contained_transform_states
[
i
]]);
}
if
(
This
->
changed
.
primitive_type
)
{
This
->
wineD3DDevice
->
updateStateBlock
->
changed
.
primitive_type
=
TRUE
;
This
->
wineD3DDevice
->
updateStateBlock
->
gl_primitive_type
=
This
->
gl_primitive_type
;
}
if
(
This
->
changed
.
indices
)
{
IWineD3DDevice_SetIndices
(
pDevice
,
This
->
pIndexData
);
IWineD3DDevice_SetBaseVertexIndex
(
pDevice
,
This
->
baseVertexIndex
);
...
...
@@ -1009,6 +1021,7 @@ should really perform a delta so that only the changes get updated*/
for
(
i
=
1
;
i
<=
HIGHEST_TRANSFORMSTATE
;
i
++
)
{
IWineD3DDevice_SetTransform
(
pDevice
,
i
,
&
This
->
transforms
[
i
]);
}
This
->
wineD3DDevice
->
updateStateBlock
->
gl_primitive_type
=
This
->
gl_primitive_type
;
IWineD3DDevice_SetIndices
(
pDevice
,
This
->
pIndexData
);
IWineD3DDevice_SetBaseVertexIndex
(
pDevice
,
This
->
baseVertexIndex
);
IWineD3DDevice_SetVertexDeclaration
(
pDevice
,
This
->
vertexDecl
);
...
...
dlls/wined3d/wined3d_private.h
View file @
702eeb6b
...
...
@@ -653,8 +653,8 @@ extern LONG primCounter;
*/
/* Routine common to the draw primitive and draw indexed primitive routines */
void
drawPrimitive
(
IWineD3DDevice
*
iface
,
WINED3DPRIMITIVETYPE
PrimitiveType
,
UINT
index_count
,
UINT
numberOfVertices
,
UINT
start_idx
,
UINT
idxBytes
,
const
void
*
idxData
,
UINT
minIndex
);
void
drawPrimitive
(
IWineD3DDevice
*
iface
,
UINT
index_count
,
UINT
numberOfVertices
,
UINT
start_idx
,
UINT
idxBytes
,
const
void
*
idxData
,
UINT
minIndex
);
void
primitiveDeclarationConvertToStridedData
(
IWineD3DDevice
*
iface
,
...
...
@@ -1796,14 +1796,15 @@ typedef struct SAVEDSTATES {
WORD
vertexShaderConstantsB
;
/* MAX_CONST_B, 16 */
WORD
vertexShaderConstantsI
;
/* MAX_CONST_I, 16 */
BOOL
*
vertexShaderConstantsF
;
BYTE
indices
:
1
;
BYTE
material
:
1
;
BYTE
viewport
:
1
;
BYTE
vertexDecl
:
1
;
BYTE
pixelShader
:
1
;
BYTE
vertexShader
:
1
;
BYTE
scissorRect
:
1
;
BYTE
padding
:
1
;
WORD
primitive_type
:
1
;
WORD
indices
:
1
;
WORD
material
:
1
;
WORD
viewport
:
1
;
WORD
vertexDecl
:
1
;
WORD
pixelShader
:
1
;
WORD
vertexShader
:
1
;
WORD
scissorRect
:
1
;
WORD
padding
:
1
;
}
SAVEDSTATES
;
struct
StageState
{
...
...
@@ -1835,6 +1836,9 @@ struct IWineD3DStateBlockImpl
INT
vertexShaderConstantI
[
MAX_CONST_I
*
4
];
float
*
vertexShaderConstantF
;
/* primitive type */
GLenum
gl_primitive_type
;
/* Stream Source */
BOOL
streamIsUP
;
UINT
streamStride
[
MAX_STREAMS
];
...
...
include/wine/wined3d.idl
View file @
702eeb6b
...
...
@@ -3485,26 +3485,28 @@ interface IWineD3DDevice : IWineD3DBase
[
in
]
IWineD3DRendertargetView
*
rendertarget_view
,
[
in
]
const
float
color
[
4
]
)
;
void
SetPrimitiveType
(
[
in
]
WINED3DPRIMITIVETYPE
primitive_topology
)
;
void
GetPrimitiveType
(
[
out
]
WINED3DPRIMITIVETYPE
*
primitive_topology
)
;
HRESULT
DrawPrimitive
(
[
in
]
WINED3DPRIMITIVETYPE
primitive_type
,
[
in
]
UINT
start_vertex
,
[
in
]
UINT
vertex_count
)
;
HRESULT
DrawIndexedPrimitive
(
[
in
]
WINED3DPRIMITIVETYPE
primitive_type
,
[
in
]
UINT
min_vertex_idx
,
[
in
]
UINT
vertex_count
,
[
in
]
UINT
start_idx
,
[
in
]
UINT
index_count
)
;
HRESULT
DrawPrimitiveUP
(
[
in
]
WINED3DPRIMITIVETYPE
primitive_type
,
[
in
]
UINT
vertex_count
,
[
in
]
const
void
*
stream_data
,
[
in
]
UINT
stream_stride
)
;
HRESULT
DrawIndexedPrimitiveUP
(
[
in
]
WINED3DPRIMITIVETYPE
primitive_type
,
[
in
]
UINT
min_vertex_idx
,
[
in
]
UINT
vertex_count
,
[
in
]
UINT
index_count
,
...
...
@@ -3514,12 +3516,10 @@ interface IWineD3DDevice : IWineD3DBase
[
in
]
UINT
stream_stride
)
;
HRESULT
DrawPrimitiveStrided
(
[
in
]
WINED3DPRIMITIVETYPE
primitive_type
,
[
in
]
UINT
vertex_count
,
[
in
]
const
WineDirect3DVertexStridedData
*
strided_data
)
;
HRESULT
DrawIndexedPrimitiveStrided
(
[
in
]
WINED3DPRIMITIVETYPE
primitive_type
,
[
in
]
UINT
index_count
,
[
in
]
const
WineDirect3DVertexStridedData
*
strided_data
,
[
in
]
UINT
vertex_count
,
...
...
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