wined3d: Move a part of LockRect to the base class.
This commit is contained in:
parent
2a09716c75
commit
a175e7b68e
@ -690,41 +690,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
|
|||||||
|
|
||||||
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
|
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
|
||||||
|
|
||||||
|
/* This is also done in the base class, but we have to verify this before loading any data from
|
||||||
|
* gl into the sysmem copy. The PBO may be mapped, a different rectangle locked, the discard flag
|
||||||
|
* may interfere, and all other bad things may happen
|
||||||
|
*/
|
||||||
if (This->Flags & SFLAG_LOCKED) {
|
if (This->Flags & SFLAG_LOCKED) {
|
||||||
WARN("Surface is already locked, returning D3DERR_INVALIDCALL\n");
|
WARN("Surface is already locked, returning D3DERR_INVALIDCALL\n");
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
if (!(This->Flags & SFLAG_LOCKABLE)) {
|
|
||||||
/* Note: UpdateTextures calls CopyRects which calls this routine to populate the
|
|
||||||
texture regions, and since the destination is an unlockable region we need
|
|
||||||
to tolerate this */
|
|
||||||
TRACE("Warning: trying to lock unlockable surf@%p\n", This);
|
|
||||||
/*return WINED3DERR_INVALIDCALL; */
|
|
||||||
}
|
|
||||||
|
|
||||||
pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
|
|
||||||
|
|
||||||
/* Mark the surface locked */
|
|
||||||
This->Flags |= SFLAG_LOCKED;
|
|
||||||
|
|
||||||
/* Calculate the correct start address to report */
|
|
||||||
if (NULL == pRect) {
|
|
||||||
This->lockedRect.left = 0;
|
|
||||||
This->lockedRect.top = 0;
|
|
||||||
This->lockedRect.right = This->currentDesc.Width;
|
|
||||||
This->lockedRect.bottom = This->currentDesc.Height;
|
|
||||||
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n", &This->lockedRect, This->lockedRect.left, This->lockedRect.top, This->lockedRect.right, This->lockedRect.bottom);
|
|
||||||
} else {
|
|
||||||
This->lockedRect.left = pRect->left;
|
|
||||||
This->lockedRect.top = pRect->top;
|
|
||||||
This->lockedRect.right = pRect->right;
|
|
||||||
This->lockedRect.bottom = pRect->bottom;
|
|
||||||
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n", pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (This->Flags & SFLAG_NONPOW2) {
|
|
||||||
TRACE("Locking non-power 2 texture\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Flags & WINED3DLOCK_DISCARD) {
|
if (Flags & WINED3DLOCK_DISCARD) {
|
||||||
/* Set SFLAG_INSYSMEM, so we'll never try to download the data from the texture. */
|
/* Set SFLAG_INSYSMEM, so we'll never try to download the data from the texture. */
|
||||||
@ -744,15 +717,17 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
|
|||||||
*/
|
*/
|
||||||
IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
|
IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
|
||||||
if(swapchain || iface == myDevice->render_targets[0]) {
|
if(swapchain || iface == myDevice->render_targets[0]) {
|
||||||
RECT *read_rect;
|
const RECT *pass_rect = pRect;
|
||||||
|
|
||||||
if(This->lockedRect.left == 0 &&
|
/* IWineD3DSurface_LoadLocation does not check if the rectangle specifies the full surfaces
|
||||||
This->lockedRect.top == 0 &&
|
* because most caller functions do not need that. So do that here
|
||||||
This->lockedRect.right == This->currentDesc.Width &&
|
*/
|
||||||
This->lockedRect.bottom == This->currentDesc.Height) {
|
if(pRect &&
|
||||||
read_rect = NULL;
|
pRect->top == 0 &&
|
||||||
} else {
|
pRect->left == 0 &&
|
||||||
read_rect = &This->lockedRect;
|
pRect->right == This->currentDesc.Width &&
|
||||||
|
pRect->bottom == This->currentDesc.Height) {
|
||||||
|
pass_rect = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(wined3d_settings.rendertargetlock_mode) {
|
switch(wined3d_settings.rendertargetlock_mode) {
|
||||||
@ -771,7 +746,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
|
|||||||
case RTL_AUTO:
|
case RTL_AUTO:
|
||||||
case RTL_READDRAW:
|
case RTL_READDRAW:
|
||||||
case RTL_READTEX:
|
case RTL_READTEX:
|
||||||
IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, read_rect);
|
IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pRect);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RTL_DISABLE:
|
case RTL_DISABLE:
|
||||||
@ -828,27 +803,6 @@ lock_end:
|
|||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the correct start address to report */
|
|
||||||
if (NULL == pRect) {
|
|
||||||
pLockedRect->pBits = This->resource.allocatedMemory;
|
|
||||||
} else {
|
|
||||||
/* DXTn textures are based on compressed blocks of 4x4 pixels, each
|
|
||||||
* 16 bytes large (8 bytes in case of DXT1). Because of that Pitch has
|
|
||||||
* slightly different meaning compared to regular textures. For DXTn
|
|
||||||
* textures Pitch is the size of a row of blocks, 4 high and "width"
|
|
||||||
* long. The x offset is calculated differently as well, since moving 4
|
|
||||||
* pixels to the right actually moves an entire 4x4 block to right, ie
|
|
||||||
* 16 bytes (8 in case of DXT1). */
|
|
||||||
if (This->resource.format == WINED3DFMT_DXT1) {
|
|
||||||
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 2);
|
|
||||||
} else if (This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3
|
|
||||||
|| This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) {
|
|
||||||
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 4);
|
|
||||||
} else {
|
|
||||||
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * This->bytesPerPixel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Flags & (WINED3DLOCK_NO_DIRTY_UPDATE | WINED3DLOCK_READONLY)) {
|
if (Flags & (WINED3DLOCK_NO_DIRTY_UPDATE | WINED3DLOCK_READONLY)) {
|
||||||
/* Don't dirtify */
|
/* Don't dirtify */
|
||||||
} else {
|
} else {
|
||||||
@ -869,9 +823,7 @@ lock_end:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("returning memory@%p, pitch(%d) dirtyfied(%d)\n", pLockedRect->pBits, pLockedRect->Pitch,
|
return IWineD3DBaseSurfaceImpl_LockRect(iface, pLockedRect, pRect, Flags);
|
||||||
This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1);
|
|
||||||
return WINED3D_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) {
|
static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) {
|
||||||
|
@ -1568,3 +1568,80 @@ error:
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags)
|
||||||
|
{
|
||||||
|
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
||||||
|
|
||||||
|
/* Already locked? */
|
||||||
|
if(This->Flags & SFLAG_LOCKED)
|
||||||
|
{
|
||||||
|
ERR("(%p) Surface already locked\n", This);
|
||||||
|
/* What should I return here? */
|
||||||
|
return WINED3DERR_INVALIDCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(This->Flags & SFLAG_LOCKABLE))
|
||||||
|
{
|
||||||
|
/* This is some GL specific thing, see the OpenGL version of
|
||||||
|
* this method, but check for the flag and write a trace
|
||||||
|
*/
|
||||||
|
TRACE("Warning: trying to lock unlockable surf@%p\n", This);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n",
|
||||||
|
This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
|
||||||
|
|
||||||
|
pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
|
||||||
|
|
||||||
|
if (NULL == pRect)
|
||||||
|
{
|
||||||
|
pLockedRect->pBits = This->resource.allocatedMemory;
|
||||||
|
This->lockedRect.left = 0;
|
||||||
|
This->lockedRect.top = 0;
|
||||||
|
This->lockedRect.right = This->currentDesc.Width;
|
||||||
|
This->lockedRect.bottom = This->currentDesc.Height;
|
||||||
|
|
||||||
|
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n",
|
||||||
|
&This->lockedRect, This->lockedRect.left, This->lockedRect.top,
|
||||||
|
This->lockedRect.right, This->lockedRect.bottom);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n",
|
||||||
|
pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
|
||||||
|
|
||||||
|
/* DXTn textures are based on compressed blocks of 4x4 pixels, each
|
||||||
|
* 16 bytes large (8 bytes in case of DXT1). Because of that Pitch has
|
||||||
|
* slightly different meaning compared to regular textures. For DXTn
|
||||||
|
* textures Pitch is the size of a row of blocks, 4 high and "width"
|
||||||
|
* long. The x offset is calculated differently as well, since moving 4
|
||||||
|
* pixels to the right actually moves an entire 4x4 block to right, ie
|
||||||
|
* 16 bytes (8 in case of DXT1). */
|
||||||
|
if (This->resource.format == WINED3DFMT_DXT1)
|
||||||
|
{
|
||||||
|
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 2);
|
||||||
|
}
|
||||||
|
else if (This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 ||
|
||||||
|
This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5)
|
||||||
|
{
|
||||||
|
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pLockedRect->pBits = This->resource.allocatedMemory +
|
||||||
|
(pLockedRect->Pitch * pRect->top) +
|
||||||
|
(pRect->left * This->bytesPerPixel);
|
||||||
|
}
|
||||||
|
This->lockedRect.left = pRect->left;
|
||||||
|
This->lockedRect.top = pRect->top;
|
||||||
|
This->lockedRect.right = pRect->right;
|
||||||
|
This->lockedRect.bottom = pRect->bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No dirtifying is needed for this surface implementation */
|
||||||
|
TRACE("returning memory@%p, pitch(%d)\n", pLockedRect->pBits, pLockedRect->Pitch);
|
||||||
|
|
||||||
|
This->Flags |= SFLAG_LOCKED;
|
||||||
|
return WINED3D_OK;
|
||||||
|
}
|
||||||
|
@ -205,80 +205,15 @@ IWineGDISurfaceImpl_LockRect(IWineD3DSurface *iface,
|
|||||||
{
|
{
|
||||||
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
||||||
|
|
||||||
/* Already locked? */
|
|
||||||
if(This->Flags & SFLAG_LOCKED)
|
|
||||||
{
|
|
||||||
ERR("(%p) Surface already locked\n", This);
|
|
||||||
/* What should I return here? */
|
|
||||||
return WINED3DERR_INVALIDCALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(This->Flags & SFLAG_LOCKABLE))
|
|
||||||
{
|
|
||||||
/* This is some GL specific thing, see the OpenGL version of
|
|
||||||
* this method, but check for the flag and write a trace
|
|
||||||
*/
|
|
||||||
TRACE("Warning: trying to lock unlockable surf@%p\n", This);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n",
|
|
||||||
This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
|
|
||||||
|
|
||||||
if(!This->resource.allocatedMemory) {
|
if(!This->resource.allocatedMemory) {
|
||||||
HDC hdc;
|
|
||||||
HRESULT hr;
|
|
||||||
/* This happens on gdi surfaces if the application set a user pointer and resets it.
|
/* This happens on gdi surfaces if the application set a user pointer and resets it.
|
||||||
* Recreate the DIB section
|
* Recreate the DIB section
|
||||||
*/
|
*/
|
||||||
hr = IWineD3DSurface_GetDC(iface, &hdc); /* will recursively call lockrect, do not set the LOCKED flag to this line */
|
IWineD3DBaseSurfaceImpl_CreateDIBSection(iface);
|
||||||
if(hr != WINED3D_OK) return hr;
|
This->resource.allocatedMemory = This->dib.bitmap_data;
|
||||||
hr = IWineD3DSurface_ReleaseDC(iface, hdc);
|
|
||||||
if(hr != WINED3D_OK) return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
|
return IWineD3DBaseSurfaceImpl_LockRect(iface, pLockedRect, pRect, Flags);
|
||||||
|
|
||||||
if (NULL == pRect)
|
|
||||||
{
|
|
||||||
pLockedRect->pBits = This->resource.allocatedMemory;
|
|
||||||
This->lockedRect.left = 0;
|
|
||||||
This->lockedRect.top = 0;
|
|
||||||
This->lockedRect.right = This->currentDesc.Width;
|
|
||||||
This->lockedRect.bottom = This->currentDesc.Height;
|
|
||||||
|
|
||||||
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n",
|
|
||||||
&This->lockedRect, This->lockedRect.left, This->lockedRect.top,
|
|
||||||
This->lockedRect.right, This->lockedRect.bottom);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n",
|
|
||||||
pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
|
|
||||||
|
|
||||||
if (This->resource.format == WINED3DFMT_DXT1)
|
|
||||||
{
|
|
||||||
/* DXT1 is half byte per pixel */
|
|
||||||
pLockedRect->pBits = This->resource.allocatedMemory +
|
|
||||||
(pLockedRect->Pitch * pRect->top) +
|
|
||||||
((pRect->left * This->bytesPerPixel / 2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pLockedRect->pBits = This->resource.allocatedMemory +
|
|
||||||
(pLockedRect->Pitch * pRect->top) +
|
|
||||||
(pRect->left * This->bytesPerPixel);
|
|
||||||
}
|
|
||||||
This->lockedRect.left = pRect->left;
|
|
||||||
This->lockedRect.top = pRect->top;
|
|
||||||
This->lockedRect.right = pRect->right;
|
|
||||||
This->lockedRect.bottom = pRect->bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No dirtifying is needed for this surface implementation */
|
|
||||||
TRACE("returning memory@%p, pitch(%d)\n", pLockedRect->pBits, pLockedRect->Pitch);
|
|
||||||
|
|
||||||
This->Flags |= SFLAG_LOCKED;
|
|
||||||
return WINED3D_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -1163,10 +1163,10 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3D
|
|||||||
HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface);
|
HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface);
|
||||||
HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter);
|
HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter);
|
||||||
HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans);
|
HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans);
|
||||||
|
HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags);
|
||||||
|
|
||||||
const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface);
|
const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface);
|
||||||
|
|
||||||
|
|
||||||
/* Surface flags: */
|
/* Surface flags: */
|
||||||
#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
|
#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
|
||||||
#define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */
|
#define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user