wined3d: Move upsideDown calculation to blit implementation.
This commit is contained in:
parent
29937272cb
commit
ff82e66a69
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -3033,7 +3033,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"
|
||||
|
|
Loading…
Reference in New Issue