[PATCH 1/4] Move upsideDown calculation to blit implementation.
Roderick Colenbrander
thunderbird2k at gmail.com
Thu Apr 1 05:50:29 CDT 2010
---
dlls/wined3d/device.c | 18 +++------
dlls/wined3d/surface.c | 79 +++++++++++++++++++++++-----------------
dlls/wined3d/wined3d_private.h | 2 +-
3 files changed, 53 insertions(+), 46 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index c6f8d9b..a1b1db6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5683,7 +5683,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice
}
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const RECT *src_rect_in,
- IWineD3DSurface *dst_surface, const RECT *dst_rect_in, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip)
+ IWineD3DSurface *dst_surface, const RECT *dst_rect_in, const WINED3DTEXTUREFILTERTYPE filter)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
@@ -5693,8 +5693,8 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
POINT offset = {0, 0};
RECT src_rect, dst_rect;
- TRACE("(%p) : src_surface %p, src_rect_in %p, dst_surface %p, dst_rect_in %p, filter %s (0x%08x), flip %u\n",
- This, src_surface, src_rect_in, dst_surface, dst_rect_in, debug_d3dtexturefiltertype(filter), filter, flip);
+ TRACE("(%p) : src_surface %p, src_rect_in %p, dst_surface %p, dst_rect_in %p, filter %s (0x%08x)\n",
+ This, src_surface, src_rect_in, dst_surface, dst_rect_in, debug_d3dtexturefiltertype(filter), filter);
TRACE("src_rect_in %s\n", wine_dbgstr_rect(src_rect_in));
TRACE("dst_rect_in %s\n", wine_dbgstr_rect(dst_rect_in));
@@ -5807,15 +5807,9 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
glDisable(GL_SCISSOR_TEST);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
- if (flip) {
- gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
- dst_rect.left, dst_rect.bottom, dst_rect.right, dst_rect.top, mask, gl_filter);
- checkGLcall("glBlitFramebuffer()");
- } else {
- gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
- dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, mask, gl_filter);
- checkGLcall("glBlitFramebuffer()");
- }
+ gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
+ dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, mask, gl_filter);
+ checkGLcall("glBlitFramebuffer()");
LEAVE_GL();
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 94880a0..2dea6a0 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3409,14 +3409,25 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS
* with single pixel copy calls
*/
static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
- const RECT *src_rect, const RECT *dst_rect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
+ const RECT *src_rect, const RECT *dst_rect_in, WINED3DTEXTUREFILTERTYPE Filter)
{
IWineD3DDeviceImpl *myDevice = This->resource.device;
float xrel, yrel;
UINT row;
IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
struct wined3d_context *context;
+ BOOL upsidedown = FALSE;
+ RECT dst_rect = *dst_rect_in;
+ /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
+ * glCopyTexSubImage is a bit picky about the parameters we pass to it
+ */
+ if(dst_rect.top > dst_rect.bottom) {
+ UINT tmp = dst_rect.bottom;
+ dst_rect.bottom = dst_rect.top;
+ dst_rect.top = tmp;
+ upsidedown = TRUE;
+ }
context = context_acquire(myDevice, SrcSurface, CTXUSAGE_BLIT);
surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
@@ -3436,8 +3447,8 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
}
checkGLcall("glReadBuffer");
- xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect->right - dst_rect->left);
- yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect->bottom - dst_rect->top);
+ xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect.right - dst_rect.left);
+ yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect.bottom - dst_rect.top);
if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
{
@@ -3460,18 +3471,18 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
/* Upside down copy without stretching is nice, one glCopyTexSubImage call will do */
glCopyTexSubImage2D(This->texture_target, This->texture_level,
- dst_rect->left /*xoffset */, dst_rect->top /* y offset */,
+ dst_rect.left /*xoffset */, dst_rect.top /* y offset */,
src_rect->left, Src->currentDesc.Height - src_rect->bottom,
- dst_rect->right - dst_rect->left, dst_rect->bottom - dst_rect->top);
+ dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
} else {
- UINT yoffset = Src->currentDesc.Height - src_rect->top + dst_rect->top - 1;
+ UINT yoffset = Src->currentDesc.Height - src_rect->top + dst_rect.top - 1;
/* I have to process this row by row to swap the image,
* otherwise it would be upside down, so stretching in y direction
* doesn't cost extra time
*
* However, stretching in x direction can be avoided if not necessary
*/
- for(row = dst_rect->top; row < dst_rect->bottom; row++) {
+ for(row = dst_rect.top; row < dst_rect.bottom; row++) {
if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
{
/* Well, that stuff works, but it's very slow.
@@ -3479,15 +3490,15 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
*/
UINT col;
- for(col = dst_rect->left; col < dst_rect->right; col++) {
+ for(col = dst_rect.left; col < dst_rect.right; col++) {
glCopyTexSubImage2D(This->texture_target, This->texture_level,
- dst_rect->left + col /* x offset */, row /* y offset */,
+ dst_rect.left + col /* x offset */, row /* y offset */,
src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1);
}
} else {
glCopyTexSubImage2D(This->texture_target, This->texture_level,
- dst_rect->left /* x offset */, row /* y offset */,
- src_rect->left, yoffset - (int) (row * yrel), dst_rect->right-dst_rect->left, 1);
+ dst_rect.left /* x offset */, row /* y offset */,
+ src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1);
}
}
}
@@ -3504,8 +3515,8 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
/* Uses the hardware to stretch and flip the image */
static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
- IWineD3DSwapChainImpl *swapchain, const RECT *src_rect, const RECT *dst_rect,
- BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
+ IWineD3DSwapChainImpl *swapchain, const RECT *src_rect, const RECT *dst_rect_in,
+ WINED3DTEXTUREFILTERTYPE Filter)
{
IWineD3DDeviceImpl *myDevice = This->resource.device;
GLuint src, backup = 0;
@@ -3518,6 +3529,8 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
GLenum texture_target;
BOOL noBackBufferBackup;
BOOL src_offscreen;
+ BOOL upsidedown = FALSE;
+ RECT dst_rect = *dst_rect_in;
TRACE("Using hwstretch blit\n");
/* Activate the Proper context for reading from the source surface, set it up for blitting */
@@ -3567,6 +3580,16 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
Src->Flags &= ~SFLAG_INTEXTURE;
}
+ /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
+ * glCopyTexSubImage is a bit picky about the parameters we pass to it
+ */
+ if(dst_rect.top > dst_rect.bottom) {
+ UINT tmp = dst_rect.bottom;
+ dst_rect.bottom = dst_rect.top;
+ dst_rect.top = tmp;
+ upsidedown = TRUE;
+ }
+
if (src_offscreen)
{
TRACE("Reading from an offscreen target\n");
@@ -3666,15 +3689,15 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
/* top left */
glTexCoord2f(left, top);
- glVertex2i(0, fbheight - dst_rect->bottom - dst_rect->top);
+ glVertex2i(0, fbheight - dst_rect.bottom - dst_rect.top);
/* top right */
glTexCoord2f(right, top);
- glVertex2i(dst_rect->right - dst_rect->left, fbheight - dst_rect->bottom - dst_rect->top);
+ glVertex2i(dst_rect.right - dst_rect.left, fbheight - dst_rect.bottom - dst_rect.top);
/* bottom right */
glTexCoord2f(right, bottom);
- glVertex2i(dst_rect->right - dst_rect->left, fbheight);
+ glVertex2i(dst_rect.right - dst_rect.left, fbheight);
glEnd();
checkGLcall("glEnd and previous");
@@ -3690,9 +3713,9 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
checkGLcall("glBindTexture");
glCopyTexSubImage2D(texture_target,
0,
- dst_rect->left, dst_rect->top, /* xoffset, yoffset */
+ dst_rect.left, dst_rect.top, /* xoffset, yoffset */
0, 0, /* We blitted the image to the origin */
- dst_rect->right - dst_rect->left, dst_rect->bottom - dst_rect->top);
+ dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
checkGLcall("glCopyTexSubImage2D");
if(drawBuffer == GL_BACK) {
@@ -3917,7 +3940,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
if((srcSwapchain || SrcSurface == myDevice->render_targets[0]) && !dstSwapchain) {
/* Blit from render target to texture */
- BOOL upsideDown = FALSE, stretchx;
+ BOOL stretchx;
BOOL paletteOverride = FALSE;
if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
@@ -3926,16 +3949,6 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
/* Destination color key is checked above */
}
- /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
- * glCopyTexSubImage is a bit picky about the parameters we pass to it
- */
- if(dst_rect.top > dst_rect.bottom) {
- UINT tmp = dst_rect.bottom;
- dst_rect.bottom = dst_rect.top;
- dst_rect.top = tmp;
- upsideDown = TRUE;
- }
-
if(dst_rect.right - dst_rect.left != src_rect.right - src_rect.left) {
stretchx = TRUE;
} else {
@@ -3971,14 +3984,14 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
&& surface_can_stretch_rect(Src, This))
{
stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &src_rect,
- (IWineD3DSurface *)This, &dst_rect, Filter, upsideDown);
+ (IWineD3DSurface *)This, &dst_rect, Filter);
} else if((!stretchx) || dst_rect.right - dst_rect.left > Src->currentDesc.Width ||
dst_rect.bottom - dst_rect.top > Src->currentDesc.Height) {
TRACE("No stretching in x direction, using direct framebuffer -> texture copy\n");
- fb_copy_to_texture_direct(This, SrcSurface, &src_rect, &dst_rect, upsideDown, Filter);
+ fb_copy_to_texture_direct(This, SrcSurface, &src_rect, &dst_rect, Filter);
} else {
TRACE("Using hardware stretching to flip / stretch the texture\n");
- fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &src_rect, &dst_rect, upsideDown, Filter);
+ fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &src_rect, &dst_rect, Filter);
}
/* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
@@ -4024,7 +4037,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
* contents are never upside down
*/
stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &src_rect,
- (IWineD3DSurface *)This, &dst_rect, Filter, FALSE);
+ (IWineD3DSurface *)This, &dst_rect, Filter);
/* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
if(paletteOverride)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a812114..e168162 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3025,7 +3025,7 @@ static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock)
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface,
const RECT *src_rect, IWineD3DSurface *dst_surface, const RECT *dst_rect,
- const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) DECLSPEC_HIDDEN;
+ const WINED3DTEXTUREFILTERTYPE filter) DECLSPEC_HIDDEN;
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
--
1.6.3.3
More information about the wine-patches
mailing list