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
81771491
Commit
81771491
authored
Dec 06, 2009
by
Stefan Dösinger
Committed by
Alexandre Julliard
Dec 07, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Infrastructure to render swapchains to a FBO.
parent
2b0271b1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
149 additions
and
5 deletions
+149
-5
context.c
dlls/wined3d/context.c
+1
-1
device.c
dlls/wined3d/device.c
+1
-0
surface.c
dlls/wined3d/surface.c
+14
-1
swapchain.c
dlls/wined3d/swapchain.c
+132
-3
wined3d_private.h
dlls/wined3d/wined3d_private.h
+1
-0
No files found.
dlls/wined3d/context.c
View file @
81771491
...
...
@@ -1893,7 +1893,7 @@ static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWin
context
=
findThreadContextForSwapChain
(
swapchain
,
tid
);
old_render_offscreen
=
context
->
render_offscreen
;
context
->
render_offscreen
=
FALSE
;
context
->
render_offscreen
=
((
IWineD3DSwapChainImpl
*
)
swapchain
)
->
render_to_fbo
;
/* The context != This->activeContext will catch a NOP context change. This can occur
* if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
* rendering. No context change is needed in that case
...
...
dlls/wined3d/device.c
View file @
81771491
...
...
@@ -6683,6 +6683,7 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *
}
swapchain
->
context
[
0
]
=
context_create
(
This
,
target
,
swapchain
->
win_handle
,
FALSE
,
&
swapchain
->
presentParms
);
swapchain
->
num_contexts
=
1
;
swapchain
->
context
[
0
]
->
render_offscreen
=
swapchain
->
render_to_fbo
;
create_dummy_textures
(
This
);
...
...
dlls/wined3d/surface.c
View file @
81771491
...
...
@@ -668,6 +668,10 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchai
TRACE
(
"(%p) : swapchain %p
\n
"
,
This
,
swapchain
);
if
(
swapchain_impl
->
backBuffer
&&
swapchain_impl
->
backBuffer
[
0
]
==
iface
)
{
if
(
swapchain_impl
->
render_to_fbo
)
{
TRACE
(
"Returning GL_COLOR_ATTACHMENT0
\n
"
);
return
GL_COLOR_ATTACHMENT0
;
}
TRACE
(
"Returning GL_BACK
\n
"
);
return
GL_BACK
;
}
else
if
(
swapchain_impl
->
frontBuffer
==
iface
)
{
...
...
@@ -5129,8 +5133,17 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) {
BOOL
surface_is_offscreen
(
IWineD3DSurface
*
iface
)
{
IWineD3DSurfaceImpl
*
This
=
(
IWineD3DSurfaceImpl
*
)
iface
;
IWineD3DSwapChainImpl
*
swapchain
=
(
IWineD3DSwapChainImpl
*
)
This
->
container
;
/* Not on a swapchain - must be offscreen */
if
(
!
(
This
->
Flags
&
SFLAG_SWAPCHAIN
))
return
TRUE
;
/* The front buffer is always onscreen */
if
(
iface
==
swapchain
->
frontBuffer
)
return
FALSE
;
return
!
(
This
->
Flags
&
SFLAG_SWAPCHAIN
);
/* If the swapchain is rendered to an FBO, the backbuffer is
* offscreen, otherwise onscreen */
return
swapchain
->
render_to_fbo
;
}
const
IWineD3DSurfaceVtbl
IWineD3DSurface_Vtbl
=
...
...
dlls/wined3d/swapchain.c
View file @
81771491
...
...
@@ -95,6 +95,116 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
/* A GL context is provided by the caller */
static
inline
void
swapchain_blit
(
IWineD3DSwapChainImpl
*
This
,
struct
wined3d_context
*
context
)
{
RECT
window
;
IWineD3DDeviceImpl
*
device
=
This
->
wineD3DDevice
;
IWineD3DSurfaceImpl
*
backbuffer
=
((
IWineD3DSurfaceImpl
*
)
This
->
backBuffer
[
0
]);
UINT
w
=
backbuffer
->
currentDesc
.
Width
;
UINT
h
=
backbuffer
->
currentDesc
.
Height
;
GLenum
gl_filter
;
const
struct
wined3d_gl_info
*
gl_info
=
context
->
gl_info
;
GetClientRect
(
This
->
win_handle
,
&
window
);
if
(
w
==
window
.
right
&&
h
==
window
.
bottom
)
gl_filter
=
GL_NEAREST
;
else
gl_filter
=
GL_LINEAR
;
if
(
gl_info
->
supported
[
EXT_FRAMEBUFFER_BLIT
])
{
ENTER_GL
();
context_bind_fbo
(
context
,
GL_READ_FRAMEBUFFER
,
&
context
->
src_fbo
);
context_attach_surface_fbo
(
context
,
GL_READ_FRAMEBUFFER
,
0
,
This
->
backBuffer
[
0
]);
context_attach_depth_stencil_fbo
(
context
,
GL_READ_FRAMEBUFFER
,
NULL
,
FALSE
);
context_bind_fbo
(
context
,
GL_DRAW_FRAMEBUFFER
,
NULL
);
glDrawBuffer
(
GL_BACK
);
glDisable
(
GL_SCISSOR_TEST
);
IWineD3DDeviceImpl_MarkStateDirty
(
This
->
wineD3DDevice
,
STATE_RENDER
(
WINED3DRS_SCISSORTESTENABLE
));
/* Note that the texture is upside down */
gl_info
->
fbo_ops
.
glBlitFramebuffer
(
0
,
0
,
w
,
h
,
window
.
left
,
window
.
bottom
,
window
.
right
,
window
.
top
,
GL_COLOR_BUFFER_BIT
,
gl_filter
);
checkGLcall
(
"Swapchain present blit(EXT_framebuffer_blit)
\n
"
);
LEAVE_GL
();
}
else
{
struct
wined3d_context
*
context2
;
float
tex_left
=
0
;
float
tex_top
=
0
;
float
tex_right
=
w
;
float
tex_bottom
=
h
;
context2
=
context_acquire
(
This
->
wineD3DDevice
,
This
->
backBuffer
[
0
],
CTXUSAGE_BLIT
);
if
(
backbuffer
->
Flags
&
SFLAG_NORMCOORD
)
{
tex_left
/=
w
;
tex_right
/=
w
;
tex_top
/=
h
;
tex_bottom
/=
h
;
}
ENTER_GL
();
context_bind_fbo
(
context2
,
GL_DRAW_FRAMEBUFFER
,
NULL
);
/* Set up the texture. The surface is not in a IWineD3D*Texture container,
* so there are no d3d texture settings to dirtify
*/
device
->
blitter
->
set_shader
((
IWineD3DDevice
*
)
device
,
backbuffer
->
resource
.
format_desc
,
backbuffer
->
texture_target
,
backbuffer
->
pow2Width
,
backbuffer
->
pow2Height
);
glTexParameteri
(
backbuffer
->
texture_target
,
GL_TEXTURE_MIN_FILTER
,
GL_LINEAR
);
glTexParameteri
(
backbuffer
->
texture_target
,
GL_TEXTURE_MAG_FILTER
,
GL_LINEAR
);
glDrawBuffer
(
GL_BACK
);
/* Set the viewport to the destination rectandle, disable any projection
* transformation set up by CTXUSAGE_BLIT, and draw a (-1,-1)-(1,1) quad.
*
* Back up viewport and matrix to avoid breaking last_was_blit
*
* Note that CTXUSAGE_BLIT set up viewport and ortho to match the surface
* size - we want the GL drawable(=window) size.
*/
glPushAttrib
(
GL_VIEWPORT_BIT
);
glViewport
(
window
.
left
,
window
.
top
,
window
.
right
,
window
.
bottom
);
glMatrixMode
(
GL_PROJECTION
);
glPushMatrix
();
glLoadIdentity
();
glBegin
(
GL_QUADS
);
/* bottom left */
glTexCoord2f
(
tex_left
,
tex_bottom
);
glVertex2i
(
-
1
,
-
1
);
/* top left */
glTexCoord2f
(
tex_left
,
tex_top
);
glVertex2i
(
-
1
,
1
);
/* top right */
glTexCoord2f
(
tex_right
,
tex_top
);
glVertex2i
(
1
,
1
);
/* bottom right */
glTexCoord2f
(
tex_right
,
tex_bottom
);
glVertex2i
(
1
,
-
1
);
glEnd
();
glPopMatrix
();
glPopAttrib
();
device
->
blitter
->
unset_shader
((
IWineD3DDevice
*
)
device
);
checkGLcall
(
"Swapchain present blit(manual)
\n
"
);
LEAVE_GL
();
context_release
(
context2
);
}
}
static
HRESULT
WINAPI
IWineD3DSwapChainImpl_Present
(
IWineD3DSwapChain
*
iface
,
CONST
RECT
*
pSourceRect
,
CONST
RECT
*
pDestRect
,
HWND
hDestWindowOverride
,
CONST
RGNDATA
*
pDirtyRegion
,
DWORD
dwFlags
)
{
IWineD3DSwapChainImpl
*
This
=
(
IWineD3DSwapChainImpl
*
)
iface
;
struct
wined3d_context
*
context
;
...
...
@@ -160,6 +270,22 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
IWineD3DSwapChain_SetDestWindowOverride
(
iface
,
hDestWindowOverride
);
}
if
(
This
->
render_to_fbo
)
{
/* This codepath should only be hit with the COPY swapeffect. Otherwise a backbuffer-
* window size mismatch is impossible(fullscreen) and src and dst rectangles are
* not allowed(they need the COPY swapeffect)
*
* The DISCARD swap effect is ok as well since any backbuffer content is allowed after
* the swap
*/
if
(
This
->
presentParms
.
SwapEffect
==
WINED3DSWAPEFFECT_FLIP
)
{
FIXME
(
"Render-to-fbo with WINED3DSWAPEFFECT_FLIP
\n
"
);
}
swapchain_blit
(
This
,
context
);
}
SwapBuffers
(
This
->
context
[
0
]
->
hdc
);
/* TODO: cycle through the swapchain buffers */
TRACE
(
"SwapBuffers called, Starting new frame
\n
"
);
...
...
@@ -239,9 +365,12 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
WINED3DCLEAR_TARGET
,
0xff00ffff
,
1
.
0
f
,
0
);
}
if
(((
IWineD3DSurfaceImpl
*
)
This
->
frontBuffer
)
->
Flags
&
SFLAG_INSYSMEM
||
((
IWineD3DSurfaceImpl
*
)
This
->
backBuffer
[
0
])
->
Flags
&
SFLAG_INSYSMEM
)
{
/* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying */
if
(
!
This
->
render_to_fbo
&&
(
((
IWineD3DSurfaceImpl
*
)
This
->
frontBuffer
)
->
Flags
&
SFLAG_INSYSMEM
||
((
IWineD3DSurfaceImpl
*
)
This
->
backBuffer
[
0
])
->
Flags
&
SFLAG_INSYSMEM
)
)
{
/* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying
* Doesn't work with render_to_fbo because we're not flipping
*/
IWineD3DSurfaceImpl
*
front
=
(
IWineD3DSurfaceImpl
*
)
This
->
frontBuffer
;
IWineD3DSurfaceImpl
*
back
=
(
IWineD3DSurfaceImpl
*
)
This
->
backBuffer
[
0
];
...
...
dlls/wined3d/wined3d_private.h
View file @
81771491
...
...
@@ -2413,6 +2413,7 @@ typedef struct IWineD3DSwapChainImpl
DWORD
orig_width
,
orig_height
;
WINED3DFORMAT
orig_fmt
;
WINED3DGAMMARAMP
orig_gamma
;
BOOL
render_to_fbo
;
long
prev_time
,
frames
;
/* Performance tracking */
unsigned
int
vSyncCounter
;
...
...
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