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
f5aaabd1
Commit
f5aaabd1
authored
Dec 19, 2007
by
Alexander Dorofeyev
Committed by
Alexandre Julliard
Dec 21, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Rewrite IWineD3DSurfaceImpl_BltOverride colorfill codepath.
parent
343f2c1b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
179 additions
and
37 deletions
+179
-37
device.c
dlls/wined3d/device.c
+162
-0
surface.c
dlls/wined3d/surface.c
+14
-37
wined3d_private.h
dlls/wined3d/wined3d_private.h
+3
-0
No files found.
dlls/wined3d/device.c
View file @
f5aaabd1
...
...
@@ -4775,6 +4775,168 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Present(IWineD3DDevice *iface,
return
WINED3D_OK
;
}
/* Not called from the VTable (internal subroutine) */
HRESULT
IWineD3DDeviceImpl_ClearSurface
(
IWineD3DDeviceImpl
*
This
,
IWineD3DSurfaceImpl
*
target
,
DWORD
Count
,
CONST
WINED3DRECT
*
pRects
,
DWORD
Flags
,
WINED3DCOLOR
Color
,
float
Z
,
DWORD
Stencil
)
{
GLbitfield
glMask
=
0
;
unsigned
int
i
;
WINED3DRECT
curRect
;
RECT
vp_rect
;
WINED3DVIEWPORT
*
vp
=
&
This
->
stateBlock
->
viewport
;
UINT
drawable_width
,
drawable_height
;
/* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
* drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true
* for the cleared parts, and the untouched parts.
*
* If we're clearing the whole target there is no need to copy it into the drawable, it will be overwritten
* anyway. If we're not clearing the color buffer we don't have to copy either since we're not going to set
* the drawable up to date. We have to check all settings that limit the clear area though. Do not bother
* checking all this if the dest surface is in the drawable anyway.
*/
if
((
Flags
&
WINED3DCLEAR_TARGET
)
&&
!
(
target
->
Flags
&
SFLAG_INDRAWABLE
))
{
while
(
1
)
{
if
(
vp
->
X
!=
0
||
vp
->
Y
!=
0
||
vp
->
Width
<
target
->
currentDesc
.
Width
||
vp
->
Height
<
target
->
currentDesc
.
Height
)
{
IWineD3DSurface_LoadLocation
((
IWineD3DSurface
*
)
target
,
SFLAG_INDRAWABLE
,
NULL
);
break
;
}
if
(
This
->
stateBlock
->
renderState
[
WINED3DRS_SCISSORTESTENABLE
]
&&
(
This
->
stateBlock
->
scissorRect
.
left
>
0
||
This
->
stateBlock
->
scissorRect
.
top
>
0
||
This
->
stateBlock
->
scissorRect
.
right
<
target
->
currentDesc
.
Width
||
This
->
stateBlock
->
scissorRect
.
bottom
<
target
->
currentDesc
.
Height
))
{
IWineD3DSurface_LoadLocation
((
IWineD3DSurface
*
)
target
,
SFLAG_INDRAWABLE
,
NULL
);
break
;
}
if
(
Count
>
0
&&
pRects
&&
(
pRects
[
0
].
x1
>
0
||
pRects
[
0
].
y1
>
0
||
pRects
[
0
].
x2
<
target
->
currentDesc
.
Width
||
pRects
[
0
].
y2
<
target
->
currentDesc
.
Height
))
{
IWineD3DSurface_LoadLocation
((
IWineD3DSurface
*
)
target
,
SFLAG_INDRAWABLE
,
NULL
);
break
;
}
break
;
}
}
target
->
get_drawable_size
(
target
,
&
drawable_width
,
&
drawable_height
);
ActivateContext
(
This
,
(
IWineD3DSurface
*
)
target
,
CTXUSAGE_CLEAR
);
ENTER_GL
();
if
(
wined3d_settings
.
offscreen_rendering_mode
==
ORM_FBO
)
{
apply_fbo_state
((
IWineD3DDevice
*
)
This
);
}
/* Only set the values up once, as they are not changing */
if
(
Flags
&
WINED3DCLEAR_STENCIL
)
{
glClearStencil
(
Stencil
);
checkGLcall
(
"glClearStencil"
);
glMask
=
glMask
|
GL_STENCIL_BUFFER_BIT
;
glStencilMask
(
0xFFFFFFFF
);
}
if
(
Flags
&
WINED3DCLEAR_ZBUFFER
)
{
glDepthMask
(
GL_TRUE
);
glClearDepth
(
Z
);
checkGLcall
(
"glClearDepth"
);
glMask
=
glMask
|
GL_DEPTH_BUFFER_BIT
;
IWineD3DDeviceImpl_MarkStateDirty
(
This
,
STATE_RENDER
(
WINED3DRS_ZWRITEENABLE
));
}
if
(
Flags
&
WINED3DCLEAR_TARGET
)
{
TRACE
(
"Clearing screen with glClear to color %x
\n
"
,
Color
);
glClearColor
(
D3DCOLOR_R
(
Color
),
D3DCOLOR_G
(
Color
),
D3DCOLOR_B
(
Color
),
D3DCOLOR_A
(
Color
));
checkGLcall
(
"glClearColor"
);
/* Clear ALL colors! */
glColorMask
(
GL_TRUE
,
GL_TRUE
,
GL_TRUE
,
GL_TRUE
);
glMask
=
glMask
|
GL_COLOR_BUFFER_BIT
;
}
vp_rect
.
left
=
vp
->
X
;
vp_rect
.
top
=
vp
->
Y
;
vp_rect
.
right
=
vp
->
X
+
vp
->
Width
;
vp_rect
.
bottom
=
vp
->
Y
+
vp
->
Height
;
if
(
!
(
Count
>
0
&&
pRects
))
{
if
(
This
->
stateBlock
->
renderState
[
WINED3DRS_SCISSORTESTENABLE
])
{
IntersectRect
(
&
vp_rect
,
&
vp_rect
,
&
This
->
stateBlock
->
scissorRect
);
}
if
(
This
->
render_offscreen
)
{
glScissor
(
vp_rect
.
left
,
vp_rect
.
top
,
vp_rect
.
right
-
vp_rect
.
left
,
vp_rect
.
bottom
-
vp_rect
.
top
);
}
else
{
glScissor
(
vp_rect
.
left
,
drawable_height
-
vp_rect
.
bottom
,
vp_rect
.
right
-
vp_rect
.
left
,
vp_rect
.
bottom
-
vp_rect
.
top
);
}
checkGLcall
(
"glScissor"
);
glClear
(
glMask
);
checkGLcall
(
"glClear"
);
}
else
{
/* Now process each rect in turn */
for
(
i
=
0
;
i
<
Count
;
i
++
)
{
/* Note gl uses lower left, width/height */
IntersectRect
((
RECT
*
)
&
curRect
,
&
vp_rect
,
(
RECT
*
)
&
pRects
[
i
]);
if
(
This
->
stateBlock
->
renderState
[
WINED3DRS_SCISSORTESTENABLE
])
{
IntersectRect
((
RECT
*
)
&
curRect
,
(
RECT
*
)
&
curRect
,
&
This
->
stateBlock
->
scissorRect
);
}
TRACE
(
"(%p) Rect=(%d,%d)->(%d,%d) glRect=(%d,%d), len=%d, hei=%d
\n
"
,
This
,
pRects
[
i
].
x1
,
pRects
[
i
].
y1
,
pRects
[
i
].
x2
,
pRects
[
i
].
y2
,
curRect
.
x1
,
(
target
->
currentDesc
.
Height
-
curRect
.
y2
),
curRect
.
x2
-
curRect
.
x1
,
curRect
.
y2
-
curRect
.
y1
);
/* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently.
* The rectangle is not cleared, no error is returned, but further rectanlges are
* still cleared if they are valid
*/
if
(
curRect
.
x1
>
curRect
.
x2
||
curRect
.
y1
>
curRect
.
y2
)
{
TRACE
(
"Rectangle with negative dimensions, ignoring
\n
"
);
continue
;
}
if
(
This
->
render_offscreen
)
{
glScissor
(
curRect
.
x1
,
curRect
.
y1
,
curRect
.
x2
-
curRect
.
x1
,
curRect
.
y2
-
curRect
.
y1
);
}
else
{
glScissor
(
curRect
.
x1
,
drawable_height
-
curRect
.
y2
,
curRect
.
x2
-
curRect
.
x1
,
curRect
.
y2
-
curRect
.
y1
);
}
checkGLcall
(
"glScissor"
);
glClear
(
glMask
);
checkGLcall
(
"glClear"
);
}
}
/* Restore the old values (why..?) */
if
(
Flags
&
WINED3DCLEAR_STENCIL
)
{
glStencilMask
(
This
->
stateBlock
->
renderState
[
WINED3DRS_STENCILWRITEMASK
]);
}
if
(
Flags
&
WINED3DCLEAR_TARGET
)
{
DWORD
mask
=
This
->
stateBlock
->
renderState
[
WINED3DRS_COLORWRITEENABLE
];
glColorMask
(
mask
&
WINED3DCOLORWRITEENABLE_RED
?
GL_TRUE
:
GL_FALSE
,
mask
&
WINED3DCOLORWRITEENABLE_GREEN
?
GL_TRUE
:
GL_FALSE
,
mask
&
WINED3DCOLORWRITEENABLE_BLUE
?
GL_TRUE
:
GL_FALSE
,
mask
&
WINED3DCOLORWRITEENABLE_ALPHA
?
GL_TRUE
:
GL_FALSE
);
/* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists,
* it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it
*/
IWineD3DSurface_ModifyLocation
(
This
->
lastActiveRenderTarget
,
SFLAG_INDRAWABLE
,
TRUE
);
/* TODO: Move the fbo logic into ModifyLocation() */
if
(
This
->
render_offscreen
&&
wined3d_settings
.
offscreen_rendering_mode
==
ORM_FBO
)
{
target
->
Flags
|=
SFLAG_INTEXTURE
;
}
}
LEAVE_GL
();
return
WINED3D_OK
;
}
static
HRESULT
WINAPI
IWineD3DDeviceImpl_Clear
(
IWineD3DDevice
*
iface
,
DWORD
Count
,
CONST
WINED3DRECT
*
pRects
,
DWORD
Flags
,
WINED3DCOLOR
Color
,
float
Z
,
DWORD
Stencil
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
...
...
dlls/wined3d/surface.c
View file @
f5aaabd1
...
...
@@ -3253,6 +3253,15 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
TRACE
(
"Colorfill
\n
"
);
/* This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0] || dstSwapchain
must be true if we are here */
if
(
This
!=
(
IWineD3DSurfaceImpl
*
)
myDevice
->
render_targets
[
0
]
&&
!
(
This
==
(
IWineD3DSurfaceImpl
*
)
dstSwapchain
->
frontBuffer
||
(
dstSwapchain
->
backBuffer
&&
This
==
(
IWineD3DSurfaceImpl
*
)
dstSwapchain
->
backBuffer
[
0
])))
{
TRACE
(
"Surface is higher back buffer, falling back to software
\n
"
);
return
WINED3DERR_INVALIDCALL
;
}
/* The color as given in the Blt function is in the format of the frame-buffer...
* 'clear' expect it in ARGB format => we need to do some conversion :-)
*/
...
...
@@ -3288,44 +3297,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
return
WINED3DERR_INVALIDCALL
;
}
ActivateContext
(
myDevice
,
(
IWineD3DSurface
*
)
This
,
CTXUSAGE_RESOURCELOAD
);
ENTER_GL
();
TRACE
(
"Calling GetSwapChain with mydevice = %p
\n
"
,
myDevice
);
if
(
dstSwapchain
&&
dstSwapchain
->
backBuffer
&&
This
==
(
IWineD3DSurfaceImpl
*
)
dstSwapchain
->
backBuffer
[
0
])
{
glDrawBuffer
(
GL_BACK
);
checkGLcall
(
"glDrawBuffer(GL_BACK)"
);
}
else
if
(
dstSwapchain
&&
This
==
(
IWineD3DSurfaceImpl
*
)
dstSwapchain
->
frontBuffer
)
{
glDrawBuffer
(
GL_FRONT
);
checkGLcall
(
"glDrawBuffer(GL_FRONT)"
);
}
else
if
(
This
==
(
IWineD3DSurfaceImpl
*
)
myDevice
->
render_targets
[
0
])
{
glDrawBuffer
(
myDevice
->
offscreenBuffer
);
checkGLcall
(
"glDrawBuffer(myDevice->offscreenBuffer3)"
);
}
else
{
LEAVE_GL
();
TRACE
(
"Surface is higher back buffer, falling back to software
\n
"
);
return
WINED3DERR_INVALIDCALL
;
}
TRACE
(
"(%p) executing Render Target override, color = %x
\n
"
,
This
,
color
);
IWineD3DDevice_Clear
(
(
IWineD3DDevice
*
)
myDevice
,
1
/* Number of rectangles */
,
&
rect
,
WINED3DCLEAR_TARGET
,
color
,
0
.
0
/* Z */
,
0
/* Stencil */
);
/* Restore the original draw buffer */
if
(
!
dstSwapchain
)
{
glDrawBuffer
(
myDevice
->
offscreenBuffer
);
}
else
if
(
dstSwapchain
->
backBuffer
&&
dstSwapchain
->
backBuffer
[
0
])
{
glDrawBuffer
(
GL_BACK
);
}
vcheckGLcall
(
"glDrawBuffer"
);
LEAVE_GL
();
IWineD3DDeviceImpl_ClearSurface
(
myDevice
,
This
,
1
,
/* Number of rectangles */
&
rect
,
WINED3DCLEAR_TARGET
,
color
,
0
.
0
/* Z */
,
0
/* Stencil */
);
return
WINED3D_OK
;
}
}
...
...
dlls/wined3d/wined3d_private.h
View file @
f5aaabd1
...
...
@@ -769,6 +769,9 @@ struct IWineD3DDeviceImpl
extern
const
IWineD3DDeviceVtbl
IWineD3DDevice_Vtbl
;
HRESULT
IWineD3DDeviceImpl_ClearSurface
(
IWineD3DDeviceImpl
*
This
,
IWineD3DSurfaceImpl
*
target
,
DWORD
Count
,
CONST
WINED3DRECT
*
pRects
,
DWORD
Flags
,
WINED3DCOLOR
Color
,
float
Z
,
DWORD
Stencil
);
void
IWineD3DDeviceImpl_FindTexUnitMap
(
IWineD3DDeviceImpl
*
This
);
void
IWineD3DDeviceImpl_MarkStateDirty
(
IWineD3DDeviceImpl
*
This
,
DWORD
state
);
static
inline
BOOL
isStateDirty
(
WineD3DContext
*
context
,
DWORD
state
)
{
...
...
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