diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 2aca0cf73e0..2f957ae75b0 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4790,7 +4790,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun curRect[0].x2 < target->currentDesc.Width || curRect[0].y2 < target->currentDesc.Height) { TRACE("Partial clear, and surface not in drawable. Blitting texture to drawable\n"); - blt_to_drawable(This, target); + IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); } } diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index ae61dbbb68c..c6cb9da96d4 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -829,127 +829,6 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, WineDirect3DVerte } } -struct coords { - int x, y, z; -}; - -void blt_to_drawable(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *surface) { - struct coords coords[4]; - int low_coord; - - /* TODO: This could be supported for lazy unlocking */ - if(!(surface->Flags & SFLAG_INTEXTURE)) { - /* It is ok at init to be nowhere */ - if(!(surface->Flags & SFLAG_INSYSMEM)) { - ERR("Blitting surfaces from sysmem not supported yet\n"); - } - return; - } - - ActivateContext(This, This->render_targets[0], CTXUSAGE_BLIT); - ENTER_GL(); - - if(surface->glDescription.target == GL_TEXTURE_2D) { - glBindTexture(GL_TEXTURE_2D, surface->glDescription.textureName); - checkGLcall("GL_TEXTURE_2D, This->glDescription.textureName)"); - - coords[0].x = 0; coords[0].y = 0; coords[0].z = 0; - coords[1].x = 0; coords[1].y = 1; coords[1].z = 0; - coords[2].x = 1; coords[2].y = 1; coords[2].z = 0; - coords[3].x = 1; coords[3].y = 0; coords[3].z = 0; - - low_coord = 0; - } else { - /* Must be a cube map */ - glDisable(GL_TEXTURE_2D); - checkGLcall("glDisable(GL_TEXTURE_2D)"); - glEnable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glEnable(surface->glDescription.target)"); - glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, surface->glDescription.textureName); - checkGLcall("GL_TEXTURE_CUBE_MAP_ARB, This->glDescription.textureName)"); - - switch(surface->glDescription.target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - coords[0].x = 1; coords[0].y = -1; coords[0].z = 1; - coords[1].x = 1; coords[1].y = 1; coords[1].z = 1; - coords[2].x = 1; coords[2].y = 1; coords[2].z = -1; - coords[3].x = 1; coords[3].y = -1; coords[3].z = -1; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - coords[0].x = -1; coords[0].y = -1; coords[0].z = 1; - coords[1].x = -1; coords[1].y = 1; coords[1].z = 1; - coords[2].x = -1; coords[2].y = 1; coords[2].z = -1; - coords[3].x = -1; coords[3].y = -1; coords[3].z = -1; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - coords[0].x = -1; coords[0].y = 1; coords[0].z = 1; - coords[1].x = 1; coords[1].y = 1; coords[1].z = 1; - coords[2].x = 1; coords[2].y = 1; coords[2].z = -1; - coords[3].x = -1; coords[3].y = 1; coords[3].z = -1; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - coords[0].x = -1; coords[0].y = -1; coords[0].z = 1; - coords[1].x = 1; coords[1].y = -1; coords[1].z = 1; - coords[2].x = 1; coords[2].y = -1; coords[2].z = -1; - coords[3].x = -1; coords[3].y = -1; coords[3].z = -1; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - coords[0].x = -1; coords[0].y = -1; coords[0].z = 1; - coords[1].x = 1; coords[1].y = -1; coords[1].z = 1; - coords[2].x = 1; coords[2].y = -1; coords[2].z = 1; - coords[3].x = -1; coords[3].y = -1; coords[3].z = 1; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - coords[0].x = -1; coords[0].y = -1; coords[0].z = -1; - coords[1].x = 1; coords[1].y = -1; coords[1].z = -1; - coords[2].x = 1; coords[2].y = -1; coords[2].z = -1; - coords[3].x = -1; coords[3].y = -1; coords[3].z = -1; - - default: - ERR("Unexpected texture target\n"); - LEAVE_GL(); - return; - } - - low_coord = -1; - } - - if(This->render_offscreen) { - coords[0].y = coords[0].y == 1 ? low_coord : 1; - coords[1].y = coords[1].y == 1 ? low_coord : 1; - coords[2].y = coords[2].y == 1 ? low_coord : 1; - coords[3].y = coords[3].y == 1 ? low_coord : 1; - } - - glBegin(GL_QUADS); - glTexCoord3iv((GLint *) &coords[0]); - glVertex2i(0, 0); - - glTexCoord3iv((GLint *) &coords[1]); - glVertex2i(0, surface->pow2Height); - - glTexCoord3iv((GLint *) &coords[2]); - glVertex2i(surface->pow2Width, surface->pow2Height); - - glTexCoord3iv((GLint *) &coords[3]); - glVertex2i(surface->pow2Width, 0); - glEnd(); - checkGLcall("glEnd"); - - if(surface->glDescription.target != GL_TEXTURE_2D) { - glEnable(GL_TEXTURE_2D); - checkGLcall("glEnable(GL_TEXTURE_2D)"); - glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); - } - LEAVE_GL(); -} - static inline void remove_vbos(IWineD3DDeviceImpl *This, WineDirect3DVertexStridedData *s) { unsigned char i; IWineD3DVertexBufferImpl *vb; @@ -1074,9 +953,7 @@ void drawPrimitive(IWineD3DDevice *iface, IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DSwapChain, (void **)&swapchain); /* Need the surface in the drawable! */ - if(!(target->Flags & SFLAG_INDRAWABLE) && (swapchain || wined3d_settings.offscreen_rendering_mode != ORM_FBO)) { - blt_to_drawable(This, target); - } + IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); /* TODO: Move fbo logic to ModifyLocation */ IWineD3DSurface_ModifyLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, TRUE); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 43cf3a5000a..50b52586ab0 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -7,7 +7,7 @@ * Copyright 2002-2003 Raphael Junqueira * Copyright 2004 Christian Costa * Copyright 2005 Oliver Stieber - * Copyright 2006 Stefan Dösinger for CodeWeavers + * Copyright 2006-2007 Stefan Dösinger for CodeWeavers * Copyright 2007 Henri Verbeet * Copyright 2006-2007 Roderick Colenbrander * @@ -1137,11 +1137,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { switch(wined3d_settings.rendertargetlock_mode) { case RTL_READTEX: case RTL_TEXTEX: - /* drop through */ - FIXME("Render target unlocking using textures temporarily disabled\n"); #if 0 IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL /* partial texture loading not supported yet */); + /* drop through */ #endif + case RTL_AUTO: case RTL_READDRAW: case RTL_TEXDRAW: @@ -3348,6 +3348,119 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW } } +struct coords { + int x, y, z; +}; + +static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This) { + struct coords coords[4]; + int low_coord; + IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + + ActivateContext(device, device->render_targets[0], CTXUSAGE_BLIT); + ENTER_GL(); + + if(This->glDescription.target == GL_TEXTURE_2D) { + glBindTexture(GL_TEXTURE_2D, This->glDescription.textureName); + checkGLcall("GL_TEXTURE_2D, This->glDescription.textureName)"); + + coords[0].x = 0; coords[0].y = 0; coords[0].z = 0; + coords[1].x = 0; coords[1].y = 1; coords[1].z = 0; + coords[2].x = 1; coords[2].y = 1; coords[2].z = 0; + coords[3].x = 1; coords[3].y = 0; coords[3].z = 0; + + low_coord = 0; + } else { + /* Must be a cube map */ + glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable(GL_TEXTURE_2D)"); + glEnable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)"); + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, This->glDescription.textureName); + checkGLcall("GL_TEXTURE_CUBE_MAP_ARB, This->glDescription.textureName)"); + + switch(This->glDescription.target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + coords[0].x = 1; coords[0].y = -1; coords[0].z = 1; + coords[1].x = 1; coords[1].y = 1; coords[1].z = 1; + coords[2].x = 1; coords[2].y = 1; coords[2].z = -1; + coords[3].x = 1; coords[3].y = -1; coords[3].z = -1; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + coords[0].x = -1; coords[0].y = -1; coords[0].z = 1; + coords[1].x = -1; coords[1].y = 1; coords[1].z = 1; + coords[2].x = -1; coords[2].y = 1; coords[2].z = -1; + coords[3].x = -1; coords[3].y = -1; coords[3].z = -1; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + coords[0].x = -1; coords[0].y = 1; coords[0].z = 1; + coords[1].x = 1; coords[1].y = 1; coords[1].z = 1; + coords[2].x = 1; coords[2].y = 1; coords[2].z = -1; + coords[3].x = -1; coords[3].y = 1; coords[3].z = -1; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + coords[0].x = -1; coords[0].y = -1; coords[0].z = 1; + coords[1].x = 1; coords[1].y = -1; coords[1].z = 1; + coords[2].x = 1; coords[2].y = -1; coords[2].z = -1; + coords[3].x = -1; coords[3].y = -1; coords[3].z = -1; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + coords[0].x = -1; coords[0].y = -1; coords[0].z = 1; + coords[1].x = 1; coords[1].y = -1; coords[1].z = 1; + coords[2].x = 1; coords[2].y = -1; coords[2].z = 1; + coords[3].x = -1; coords[3].y = -1; coords[3].z = 1; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + coords[0].x = -1; coords[0].y = -1; coords[0].z = -1; + coords[1].x = 1; coords[1].y = -1; coords[1].z = -1; + coords[2].x = 1; coords[2].y = -1; coords[2].z = -1; + coords[3].x = -1; coords[3].y = -1; coords[3].z = -1; + + default: + ERR("Unexpected texture target\n"); + LEAVE_GL(); + return; + } + + low_coord = -1; + } + + if(device->render_offscreen) { + coords[0].y = coords[0].y == 1 ? low_coord : 1; + coords[1].y = coords[1].y == 1 ? low_coord : 1; + coords[2].y = coords[2].y == 1 ? low_coord : 1; + coords[3].y = coords[3].y == 1 ? low_coord : 1; + } + + glBegin(GL_QUADS); + glTexCoord3iv((GLint *) &coords[0]); + glVertex2i(0, 0); + + glTexCoord3iv((GLint *) &coords[1]); + glVertex2i(0, This->pow2Height); + + glTexCoord3iv((GLint *) &coords[2]); + glVertex2i(This->pow2Width, This->pow2Height); + + glTexCoord3iv((GLint *) &coords[3]); + glVertex2i(This->pow2Width, 0); + glEnd(); + checkGLcall("glEnd"); + + if(This->glDescription.target != GL_TEXTURE_2D) { + glEnable(GL_TEXTURE_2D); + checkGLcall("glEnable(GL_TEXTURE_2D)"); + glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + LEAVE_GL(); +} + /***************************************************************************** * IWineD3DSurface::LoadLocation * @@ -3482,7 +3595,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D } } else if(flag == SFLAG_INDRAWABLE) { if(This->Flags & SFLAG_INTEXTURE) { - /* Blit texture to drawable */ + surface_blt_to_drawable(This); } else { /* Activate the correct context for the render target */ ActivateContext(myDevice, iface, CTXUSAGE_BLIT); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b86d0d0ec6f..a79289073b2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -409,8 +409,6 @@ void primitiveDeclarationConvertToStridedData( DWORD get_flexible_vertex_size(DWORD d3dvtVertexType); -void blt_to_drawable(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *surface); - #define eps 1e-8 #define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \