mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Restrict lock surfaces to off-screen plain and render target surfaces
This commit is contained in:
parent
590b6f1ad0
commit
a45e5768ae
@ -20,6 +20,8 @@ namespace D3dDdi
|
|||||||
: m_origVtable(DeviceFuncs::s_origVtables.at(device))
|
: m_origVtable(DeviceFuncs::s_origVtables.at(device))
|
||||||
, m_adapter(Adapter::get(adapter))
|
, m_adapter(Adapter::get(adapter))
|
||||||
, m_device(device)
|
, m_device(device)
|
||||||
|
, m_renderTarget(nullptr)
|
||||||
|
, m_renderTargetSubResourceIndex(0)
|
||||||
, m_sharedPrimary(nullptr)
|
, m_sharedPrimary(nullptr)
|
||||||
, m_streamSourceData{}
|
, m_streamSourceData{}
|
||||||
, m_streamSource(nullptr)
|
, m_streamSource(nullptr)
|
||||||
@ -39,7 +41,10 @@ namespace D3dDdi
|
|||||||
|
|
||||||
HRESULT Device::clear(const D3DDDIARG_CLEAR& data, UINT numRect, const RECT* rect)
|
HRESULT Device::clear(const D3DDDIARG_CLEAR& data, UINT numRect, const RECT* rect)
|
||||||
{
|
{
|
||||||
prepareForRendering();
|
if (data.Flags & D3DCLEAR_TARGET)
|
||||||
|
{
|
||||||
|
prepareForRendering();
|
||||||
|
}
|
||||||
return m_origVtable.pfnClear(m_device, &data, numRect, rect);
|
return m_origVtable.pfnClear(m_device, &data, numRect, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +64,7 @@ namespace D3dDdi
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Resource resource(Resource::create(*this, data));
|
Resource resource(Resource::create(*this, data));
|
||||||
m_resources.emplace(resource, std::move(resource)).first->second.initialize();
|
m_resources.emplace(resource, std::move(resource));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
catch (const HResultException& e)
|
catch (const HResultException& e)
|
||||||
@ -99,13 +104,7 @@ namespace D3dDdi
|
|||||||
HRESULT result = m_origVtable.pfnDestroyResource(m_device, resource);
|
HRESULT result = m_origVtable.pfnDestroyResource(m_device, resource);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
auto it = m_resources.find(resource);
|
m_resources.erase(resource);
|
||||||
if (it != m_resources.end())
|
|
||||||
{
|
|
||||||
it->second.destroyLockResource();
|
|
||||||
m_resources.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resource == m_sharedPrimary)
|
if (resource == m_sharedPrimary)
|
||||||
{
|
{
|
||||||
m_sharedPrimary = nullptr;
|
m_sharedPrimary = nullptr;
|
||||||
@ -203,6 +202,17 @@ namespace D3dDdi
|
|||||||
return m_origVtable.pfnPresent1(m_device, &data);
|
return m_origVtable.pfnPresent1(m_device, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT Device::setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data)
|
||||||
|
{
|
||||||
|
HRESULT result = m_origVtable.pfnSetRenderTarget(m_device, &data);
|
||||||
|
if (SUCCEEDED(result) && 0 == data.RenderTargetIndex)
|
||||||
|
{
|
||||||
|
m_renderTarget = getResource(data.hRenderTarget);
|
||||||
|
m_renderTargetSubResourceIndex = data.SubResourceIndex;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT Device::setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data)
|
HRESULT Device::setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data)
|
||||||
{
|
{
|
||||||
HRESULT result = m_origVtable.pfnSetStreamSource(m_device, &data);
|
HRESULT result = m_origVtable.pfnSetStreamSource(m_device, &data);
|
||||||
@ -225,20 +235,6 @@ namespace D3dDdi
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Device::texBlt(const D3DDDIARG_TEXBLT& data)
|
|
||||||
{
|
|
||||||
prepareForRendering(data.hDstResource, UINT_MAX, false);
|
|
||||||
prepareForRendering(data.hSrcResource, UINT_MAX, true);
|
|
||||||
return m_origVtable.pfnTexBlt(m_device, &data);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT Device::texBlt1(const D3DDDIARG_TEXBLT1& data)
|
|
||||||
{
|
|
||||||
prepareForRendering(data.hDstResource, UINT_MAX, false);
|
|
||||||
prepareForRendering(data.hSrcResource, UINT_MAX, true);
|
|
||||||
return m_origVtable.pfnTexBlt1(m_device, &data);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT Device::unlock(const D3DDDIARG_UNLOCK& data)
|
HRESULT Device::unlock(const D3DDDIARG_UNLOCK& data)
|
||||||
{
|
{
|
||||||
auto it = m_resources.find(data.hResource);
|
auto it = m_resources.find(data.hResource);
|
||||||
@ -261,16 +257,6 @@ namespace D3dDdi
|
|||||||
return m_origVtable.pfnUpdateWInfo(m_device, &data);
|
return m_origVtable.pfnUpdateWInfo(m_device, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::addDirtyRenderTarget(Resource& resource, UINT subResourceIndex)
|
|
||||||
{
|
|
||||||
m_dirtyRenderTargets.emplace(std::make_pair(static_cast<HANDLE>(resource), subResourceIndex), resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::addDirtyTexture(Resource& resource, UINT subResourceIndex)
|
|
||||||
{
|
|
||||||
m_dirtyTextures.emplace(std::make_pair(static_cast<HANDLE>(resource), subResourceIndex), resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
Resource* Device::getGdiResource()
|
Resource* Device::getGdiResource()
|
||||||
{
|
{
|
||||||
return g_gdiResource;
|
return g_gdiResource;
|
||||||
@ -285,33 +271,12 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::prepareForRendering(std::map<std::pair<HANDLE, UINT>, Resource&>& resources, bool isReadOnly)
|
|
||||||
{
|
|
||||||
auto it = resources.begin();
|
|
||||||
while (it != resources.end())
|
|
||||||
{
|
|
||||||
auto& resource = it->second;
|
|
||||||
auto subResourceIndex = it->first.second;
|
|
||||||
++it;
|
|
||||||
resource.prepareForRendering(subResourceIndex, isReadOnly);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::prepareForRendering()
|
void Device::prepareForRendering()
|
||||||
{
|
{
|
||||||
const bool isReadOnly = true;
|
if (m_renderTarget)
|
||||||
prepareForRendering(m_dirtyRenderTargets, !isReadOnly);
|
{
|
||||||
prepareForRendering(m_dirtyTextures, isReadOnly);
|
m_renderTarget->prepareForRendering(m_renderTargetSubResourceIndex, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::removeDirtyRenderTarget(Resource& resource, UINT subResourceIndex)
|
|
||||||
{
|
|
||||||
m_dirtyRenderTargets.erase(std::make_pair(static_cast<HANDLE>(resource), subResourceIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::removeDirtyTexture(Resource& resource, UINT subResourceIndex)
|
|
||||||
{
|
|
||||||
m_dirtyTextures.erase(std::make_pair(static_cast<HANDLE>(resource), subResourceIndex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::add(HANDLE adapter, HANDLE device)
|
void Device::add(HANDLE adapter, HANDLE device)
|
||||||
|
@ -36,10 +36,9 @@ namespace D3dDdi
|
|||||||
HRESULT openResource(D3DDDIARG_OPENRESOURCE& data);
|
HRESULT openResource(D3DDDIARG_OPENRESOURCE& data);
|
||||||
HRESULT present(const D3DDDIARG_PRESENT& data);
|
HRESULT present(const D3DDDIARG_PRESENT& data);
|
||||||
HRESULT present1(D3DDDIARG_PRESENT1& data);
|
HRESULT present1(D3DDDIARG_PRESENT1& data);
|
||||||
|
HRESULT setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data);
|
||||||
HRESULT setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data);
|
HRESULT setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data);
|
||||||
HRESULT setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& data, const void* umBuffer);
|
HRESULT setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& data, const void* umBuffer);
|
||||||
HRESULT texBlt(const D3DDDIARG_TEXBLT& data);
|
|
||||||
HRESULT texBlt1(const D3DDDIARG_TEXBLT1& data);
|
|
||||||
HRESULT unlock(const D3DDDIARG_UNLOCK& data);
|
HRESULT unlock(const D3DDDIARG_UNLOCK& data);
|
||||||
HRESULT updateWInfo(const D3DDDIARG_WINFO& data);
|
HRESULT updateWInfo(const D3DDDIARG_WINFO& data);
|
||||||
|
|
||||||
@ -47,12 +46,8 @@ namespace D3dDdi
|
|||||||
const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; }
|
const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||||
Resource* getResource(HANDLE resource);
|
Resource* getResource(HANDLE resource);
|
||||||
|
|
||||||
void addDirtyRenderTarget(Resource& resource, UINT subResourceIndex);
|
|
||||||
void addDirtyTexture(Resource& resource, UINT subResourceIndex);
|
|
||||||
void prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly);
|
void prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly);
|
||||||
void prepareForRendering();
|
void prepareForRendering();
|
||||||
void removeDirtyRenderTarget(Resource& resource, UINT subResourceIndex);
|
|
||||||
void removeDirtyTexture(Resource& resource, UINT subResourceIndex);
|
|
||||||
|
|
||||||
static void add(HANDLE adapter, HANDLE device);
|
static void add(HANDLE adapter, HANDLE device);
|
||||||
static Device& get(HANDLE device);
|
static Device& get(HANDLE device);
|
||||||
@ -69,14 +64,12 @@ namespace D3dDdi
|
|||||||
template <typename Arg>
|
template <typename Arg>
|
||||||
HRESULT createResourceImpl(Arg& data);
|
HRESULT createResourceImpl(Arg& data);
|
||||||
|
|
||||||
void prepareForRendering(std::map<std::pair<HANDLE, UINT>, Resource&>& resources, bool isReadOnly);
|
|
||||||
|
|
||||||
const D3DDDI_DEVICEFUNCS& m_origVtable;
|
const D3DDDI_DEVICEFUNCS& m_origVtable;
|
||||||
Adapter& m_adapter;
|
Adapter& m_adapter;
|
||||||
HANDLE m_device;
|
HANDLE m_device;
|
||||||
std::unordered_map<HANDLE, Resource> m_resources;
|
std::unordered_map<HANDLE, Resource> m_resources;
|
||||||
std::map<std::pair<HANDLE, UINT>, Resource&> m_dirtyRenderTargets;
|
Resource* m_renderTarget;
|
||||||
std::map<std::pair<HANDLE, UINT>, Resource&> m_dirtyTextures;
|
UINT m_renderTargetSubResourceIndex;
|
||||||
HANDLE m_sharedPrimary;
|
HANDLE m_sharedPrimary;
|
||||||
D3DDDIARG_SETSTREAMSOURCE m_streamSourceData;
|
D3DDDIARG_SETSTREAMSOURCE m_streamSourceData;
|
||||||
Resource* m_streamSource;
|
Resource* m_streamSource;
|
||||||
|
@ -54,10 +54,9 @@ namespace D3dDdi
|
|||||||
vtable.pfnOpenResource = &DEVICE_FUNC(openResource);
|
vtable.pfnOpenResource = &DEVICE_FUNC(openResource);
|
||||||
vtable.pfnPresent = &DEVICE_FUNC(present);
|
vtable.pfnPresent = &DEVICE_FUNC(present);
|
||||||
vtable.pfnPresent1 = &DEVICE_FUNC(present1);
|
vtable.pfnPresent1 = &DEVICE_FUNC(present1);
|
||||||
|
vtable.pfnSetRenderTarget = &DEVICE_FUNC(setRenderTarget);
|
||||||
vtable.pfnSetStreamSource = &DEVICE_FUNC(setStreamSource);
|
vtable.pfnSetStreamSource = &DEVICE_FUNC(setStreamSource);
|
||||||
vtable.pfnSetStreamSourceUm = &DEVICE_FUNC(setStreamSourceUm);
|
vtable.pfnSetStreamSourceUm = &DEVICE_FUNC(setStreamSourceUm);
|
||||||
vtable.pfnTexBlt = &DEVICE_FUNC(texBlt);
|
|
||||||
vtable.pfnTexBlt1 = &DEVICE_FUNC(texBlt1);
|
|
||||||
vtable.pfnUnlock = &DEVICE_FUNC(unlock);
|
vtable.pfnUnlock = &DEVICE_FUNC(unlock);
|
||||||
vtable.pfnUpdateWInfo = &DEVICE_FUNC(updateWInfo);
|
vtable.pfnUpdateWInfo = &DEVICE_FUNC(updateWInfo);
|
||||||
}
|
}
|
||||||
|
@ -160,19 +160,9 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
if (!resource.m_lockData[subResourceIndex].isSysMemUpToDate)
|
if (!resource.m_lockData[subResourceIndex].isSysMemUpToDate)
|
||||||
{
|
{
|
||||||
if (isReadOnly)
|
resource.copyToSysMem(subResourceIndex);
|
||||||
{
|
|
||||||
resource.copyToSysMem(subResourceIndex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resource.moveToSysMem(subResourceIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!isReadOnly && resource.m_lockData[subResourceIndex].isVidMemUpToDate)
|
|
||||||
{
|
|
||||||
resource.setVidMemUpToDate(subResourceIndex, false);
|
|
||||||
}
|
}
|
||||||
|
resource.m_lockData[subResourceIndex].isVidMemUpToDate &= isReadOnly;
|
||||||
data = resource.m_lockData[subResourceIndex].data;
|
data = resource.m_lockData[subResourceIndex].data;
|
||||||
pitch = resource.m_lockData[subResourceIndex].pitch;
|
pitch = resource.m_lockData[subResourceIndex].pitch;
|
||||||
}
|
}
|
||||||
@ -187,9 +177,8 @@ namespace D3dDdi
|
|||||||
: m_device(device)
|
: m_device(device)
|
||||||
, m_handle(nullptr)
|
, m_handle(nullptr)
|
||||||
, m_origData(data)
|
, m_origData(data)
|
||||||
, m_lockResource(nullptr)
|
|
||||||
, m_lockBuffer(nullptr, &heapFree)
|
, m_lockBuffer(nullptr, &heapFree)
|
||||||
, m_canCreateLockResource(false)
|
, m_lockResource(nullptr, ResourceDeleter(device))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,19 +224,9 @@ namespace D3dDdi
|
|||||||
auto& lockData = m_lockData[data.SubResourceIndex];
|
auto& lockData = m_lockData[data.SubResourceIndex];
|
||||||
if (!lockData.isSysMemUpToDate)
|
if (!lockData.isSysMemUpToDate)
|
||||||
{
|
{
|
||||||
if (data.Flags.ReadOnly)
|
copyToSysMem(data.SubResourceIndex);
|
||||||
{
|
|
||||||
copyToSysMem(data.SubResourceIndex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
moveToSysMem(data.SubResourceIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!data.Flags.ReadOnly && lockData.isVidMemUpToDate)
|
|
||||||
{
|
|
||||||
setVidMemUpToDate(data.SubResourceIndex, false);
|
|
||||||
}
|
}
|
||||||
|
lockData.isVidMemUpToDate &= data.Flags.ReadOnly;
|
||||||
|
|
||||||
unsigned char* ptr = static_cast<unsigned char*>(lockData.data);
|
unsigned char* ptr = static_cast<unsigned char*>(lockData.data);
|
||||||
if (data.Flags.AreaValid)
|
if (data.Flags.AreaValid)
|
||||||
@ -274,7 +253,7 @@ namespace D3dDdi
|
|||||||
HRESULT Resource::colorFill(const D3DDDIARG_COLORFILL& data)
|
HRESULT Resource::colorFill(const D3DDDIARG_COLORFILL& data)
|
||||||
{
|
{
|
||||||
LOG_FUNC("Resource::colorFill", data);
|
LOG_FUNC("Resource::colorFill", data);
|
||||||
if (m_lockResource && 0 != m_formatInfo.bytesPerPixel)
|
if (m_lockResource)
|
||||||
{
|
{
|
||||||
auto& lockData = m_lockData[data.SubResourceIndex];
|
auto& lockData = m_lockData[data.SubResourceIndex];
|
||||||
if (lockData.isSysMemUpToDate)
|
if (lockData.isSysMemUpToDate)
|
||||||
@ -286,10 +265,7 @@ namespace D3dDdi
|
|||||||
data.DstRect.right - data.DstRect.left, data.DstRect.bottom - data.DstRect.top,
|
data.DstRect.right - data.DstRect.left, data.DstRect.bottom - data.DstRect.top,
|
||||||
m_formatInfo.bytesPerPixel, colorConvert(m_formatInfo, data.Color));
|
m_formatInfo.bytesPerPixel, colorConvert(m_formatInfo, data.Color));
|
||||||
|
|
||||||
if (lockData.isVidMemUpToDate)
|
m_lockData[data.SubResourceIndex].isVidMemUpToDate = false;
|
||||||
{
|
|
||||||
setVidMemUpToDate(data.SubResourceIndex, false);
|
|
||||||
}
|
|
||||||
return LOG_RESULT(S_OK);
|
return LOG_RESULT(S_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,8 +298,14 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void Resource::copyToSysMem(UINT subResourceIndex)
|
void Resource::copyToSysMem(UINT subResourceIndex)
|
||||||
{
|
{
|
||||||
copySubResource(m_lockResource, m_handle, subResourceIndex);
|
copySubResource(m_lockResource.get(), m_handle, subResourceIndex);
|
||||||
setSysMemUpToDate(subResourceIndex, true);
|
m_lockData[subResourceIndex].isSysMemUpToDate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resource::copyToVidMem(UINT subResourceIndex)
|
||||||
|
{
|
||||||
|
copySubResource(m_handle, m_lockResource.get(), subResourceIndex);
|
||||||
|
m_lockData[subResourceIndex].isVidMemUpToDate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::createGdiLockResource()
|
void Resource::createGdiLockResource()
|
||||||
@ -344,8 +326,7 @@ namespace D3dDdi
|
|||||||
createSysMemResource({ surfaceInfo });
|
createSysMemResource({ surfaceInfo });
|
||||||
if (m_lockResource)
|
if (m_lockResource)
|
||||||
{
|
{
|
||||||
setSysMemUpToDate(0, true);
|
m_lockData[0].isVidMemUpToDate = false;
|
||||||
setVidMemUpToDate(0, false);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -355,6 +336,16 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void Resource::createLockResource()
|
void Resource::createLockResource()
|
||||||
{
|
{
|
||||||
|
D3DDDI_RESOURCEFLAGS flags = {};
|
||||||
|
flags.Value = g_resourceTypeFlags;
|
||||||
|
flags.RenderTarget = 0;
|
||||||
|
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool ||
|
||||||
|
0 == m_formatInfo.bytesPerPixel ||
|
||||||
|
0 != (m_fixedData.Flags.Value & flags.Value))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<D3DDDI_SURFACEINFO> surfaceInfo(m_fixedData.SurfCount);
|
std::vector<D3DDDI_SURFACEINFO> surfaceInfo(m_fixedData.SurfCount);
|
||||||
for (UINT i = 0; i < m_fixedData.SurfCount; ++i)
|
for (UINT i = 0; i < m_fixedData.SurfCount; ++i)
|
||||||
{
|
{
|
||||||
@ -401,7 +392,6 @@ namespace D3dDdi
|
|||||||
data.pSurfList = surfaceInfo.data();
|
data.pSurfList = surfaceInfo.data();
|
||||||
data.SurfCount = surfaceInfo.size();
|
data.SurfCount = surfaceInfo.size();
|
||||||
data.Rotation = D3DDDI_ROTATION_IDENTITY;
|
data.Rotation = D3DDDI_ROTATION_IDENTITY;
|
||||||
data.Flags.Texture = m_fixedData.Flags.Texture;
|
|
||||||
|
|
||||||
HRESULT result = S_OK;
|
HRESULT result = S_OK;
|
||||||
if (m_device.getOrigVtable().pfnCreateResource2)
|
if (m_device.getOrigVtable().pfnCreateResource2)
|
||||||
@ -416,22 +406,18 @@ namespace D3dDdi
|
|||||||
|
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
m_lockResource = data.hResource;
|
m_lockResource.reset(data.hResource);
|
||||||
|
m_lockData.resize(surfaceInfo.size());
|
||||||
for (std::size_t i = 0; i < surfaceInfo.size(); ++i)
|
for (std::size_t i = 0; i < surfaceInfo.size(); ++i)
|
||||||
{
|
{
|
||||||
m_lockData[i].data = const_cast<void*>(surfaceInfo[i].pSysMem);
|
m_lockData[i].data = const_cast<void*>(surfaceInfo[i].pSysMem);
|
||||||
m_lockData[i].pitch = surfaceInfo[i].SysMemPitch;
|
m_lockData[i].pitch = surfaceInfo[i].SysMemPitch;
|
||||||
|
m_lockData[i].isSysMemUpToDate = true;
|
||||||
|
m_lockData[i].isVidMemUpToDate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_canCreateLockResource = false;
|
LOG_RESULT(m_lockResource.get());
|
||||||
LOG_RESULT(m_lockResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resource::copyToVidMem(UINT subResourceIndex)
|
|
||||||
{
|
|
||||||
copySubResource(m_handle, m_lockResource, subResourceIndex);
|
|
||||||
setVidMemUpToDate(subResourceIndex, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Arg>
|
template <typename Arg>
|
||||||
@ -460,6 +446,7 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
|
|
||||||
resource.m_handle = data.hResource;
|
resource.m_handle = data.hResource;
|
||||||
|
resource.createLockResource();
|
||||||
data = origData;
|
data = origData;
|
||||||
data.hResource = resource.m_handle;
|
data.hResource = resource.m_handle;
|
||||||
return resource;
|
return resource;
|
||||||
@ -475,23 +462,6 @@ namespace D3dDdi
|
|||||||
return create(device, data, device.getOrigVtable().pfnCreateResource2);
|
return create(device, data, device.getOrigVtable().pfnCreateResource2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::destroyLockResource()
|
|
||||||
{
|
|
||||||
for (UINT i = 0; i < m_lockData.size(); ++i)
|
|
||||||
{
|
|
||||||
setSysMemUpToDate(i, false);
|
|
||||||
setVidMemUpToDate(i, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_lockResource)
|
|
||||||
{
|
|
||||||
m_device.getOrigVtable().pfnDestroyResource(m_device, m_lockResource);
|
|
||||||
m_lockResource = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lockBuffer.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resource::fixVertexData(UINT offset, UINT count, UINT stride)
|
void Resource::fixVertexData(UINT offset, UINT count, UINT stride)
|
||||||
{
|
{
|
||||||
if (!m_fixedData.Flags.MightDrawFromLocked ||
|
if (!m_fixedData.Flags.MightDrawFromLocked ||
|
||||||
@ -523,21 +493,10 @@ namespace D3dDdi
|
|||||||
: const_cast<void*>(m_fixedData.pSurfList[subResourceIndex].pSysMem);
|
: const_cast<void*>(m_fixedData.pSurfList[subResourceIndex].pSysMem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::initialize()
|
bool Resource::isInSysMem(UINT subResourceIndex) const
|
||||||
{
|
{
|
||||||
m_canCreateLockResource = D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
return D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool ||
|
||||||
0 != m_formatInfo.bytesPerPixel &&
|
(m_lockResource && m_lockData[subResourceIndex].isSysMemUpToDate);
|
||||||
!m_fixedData.Flags.Primary;
|
|
||||||
|
|
||||||
if (m_canCreateLockResource)
|
|
||||||
{
|
|
||||||
m_lockData.resize(m_fixedData.SurfCount);
|
|
||||||
for (std::size_t i = 0; i < m_fixedData.SurfCount; ++i)
|
|
||||||
{
|
|
||||||
setSysMemUpToDate(i, true);
|
|
||||||
setVidMemUpToDate(i, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resource::isOversized() const
|
bool Resource::isOversized() const
|
||||||
@ -558,11 +517,6 @@ namespace D3dDdi
|
|||||||
return splitLock(data, m_device.getOrigVtable().pfnLock);
|
return splitLock(data, m_device.getOrigVtable().pfnLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_canCreateLockResource)
|
|
||||||
{
|
|
||||||
createLockResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_lockResource)
|
if (m_lockResource)
|
||||||
{
|
{
|
||||||
return bltLock(data);
|
return bltLock(data);
|
||||||
@ -571,55 +525,15 @@ namespace D3dDdi
|
|||||||
return m_device.getOrigVtable().pfnLock(m_device, &data);
|
return m_device.getOrigVtable().pfnLock(m_device, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::moveToSysMem(UINT subResourceIndex)
|
|
||||||
{
|
|
||||||
copySubResource(m_lockResource, m_handle, subResourceIndex);
|
|
||||||
setSysMemUpToDate(subResourceIndex, true);
|
|
||||||
setVidMemUpToDate(subResourceIndex, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resource::moveToVidMem(UINT subResourceIndex)
|
|
||||||
{
|
|
||||||
copySubResource(m_handle, m_lockResource, subResourceIndex);
|
|
||||||
setVidMemUpToDate(subResourceIndex, true);
|
|
||||||
setSysMemUpToDate(subResourceIndex, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resource::prepareForRendering(UINT subResourceIndex, bool isReadOnly)
|
void Resource::prepareForRendering(UINT subResourceIndex, bool isReadOnly)
|
||||||
{
|
{
|
||||||
if (subResourceIndex < m_lockData.size())
|
if (m_lockResource && 0 == m_lockData[subResourceIndex].lockCount)
|
||||||
{
|
{
|
||||||
prepareSubResourceForRendering(subResourceIndex, isReadOnly);
|
if (!m_lockData[subResourceIndex].isVidMemUpToDate)
|
||||||
}
|
|
||||||
else if (UINT_MAX == subResourceIndex)
|
|
||||||
{
|
|
||||||
for (UINT i = 0; i < m_lockData.size(); ++i)
|
|
||||||
{
|
{
|
||||||
prepareSubResourceForRendering(i, isReadOnly);
|
copyToVidMem(subResourceIndex);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resource::prepareSubResourceForRendering(UINT subResourceIndex, bool isReadOnly)
|
|
||||||
{
|
|
||||||
auto& lockData = m_lockData[subResourceIndex];
|
|
||||||
if (0 == lockData.lockCount)
|
|
||||||
{
|
|
||||||
if (isReadOnly)
|
|
||||||
{
|
|
||||||
if (!lockData.isVidMemUpToDate)
|
|
||||||
{
|
|
||||||
copyToVidMem(subResourceIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (lockData.isVidMemUpToDate)
|
|
||||||
{
|
|
||||||
setSysMemUpToDate(subResourceIndex, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
moveToVidMem(subResourceIndex);
|
|
||||||
}
|
}
|
||||||
|
m_lockData[subResourceIndex].isSysMemUpToDate &= isReadOnly;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,56 +542,22 @@ namespace D3dDdi
|
|||||||
if (srcResource.m_lockResource &&
|
if (srcResource.m_lockResource &&
|
||||||
srcResource.m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate)
|
srcResource.m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate)
|
||||||
{
|
{
|
||||||
copySubResource(srcResource.m_handle, srcResource.m_lockResource, data.SrcSubResourceIndex);
|
srcResource.copyToVidMem(data.SrcSubResourceIndex);
|
||||||
if (!srcResource.m_lockData[data.SrcSubResourceIndex].isVidMemUpToDate)
|
|
||||||
{
|
|
||||||
srcResource.setVidMemUpToDate(data.SrcSubResourceIndex, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return m_device.getOrigVtable().pfnBlt(m_device, &data);
|
return m_device.getOrigVtable().pfnBlt(m_device, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::setAsGdiResource(bool isGdiResource)
|
void Resource::setAsGdiResource(bool isGdiResource)
|
||||||
{
|
{
|
||||||
destroyLockResource();
|
m_lockResource.reset();
|
||||||
|
m_lockData.clear();
|
||||||
|
m_lockBuffer.reset();
|
||||||
if (isGdiResource)
|
if (isGdiResource)
|
||||||
{
|
{
|
||||||
createGdiLockResource();
|
createGdiLockResource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::setSysMemUpToDate(UINT subResourceIndex, bool upToDate)
|
|
||||||
{
|
|
||||||
m_lockData[subResourceIndex].isSysMemUpToDate = upToDate;
|
|
||||||
if (m_fixedData.Flags.RenderTarget)
|
|
||||||
{
|
|
||||||
if (upToDate)
|
|
||||||
{
|
|
||||||
m_device.addDirtyRenderTarget(*this, subResourceIndex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_device.removeDirtyRenderTarget(*this, subResourceIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resource::setVidMemUpToDate(UINT subResourceIndex, bool upToDate)
|
|
||||||
{
|
|
||||||
m_lockData[subResourceIndex].isVidMemUpToDate = upToDate;
|
|
||||||
if (m_fixedData.Flags.Texture)
|
|
||||||
{
|
|
||||||
if (upToDate)
|
|
||||||
{
|
|
||||||
m_device.removeDirtyTexture(*this, subResourceIndex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_device.addDirtyTexture(*this, subResourceIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT Resource::splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect)
|
HRESULT Resource::splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect)
|
||||||
{
|
{
|
||||||
LOG_FUNC("Resource::splitBlt", data, subResourceIndex, rect, otherRect);
|
LOG_FUNC("Resource::splitBlt", data, subResourceIndex, rect, otherRect);
|
||||||
@ -742,49 +622,36 @@ namespace D3dDdi
|
|||||||
HRESULT Resource::sysMemPreferredBlt(const D3DDDIARG_BLT& data, Resource& srcResource)
|
HRESULT Resource::sysMemPreferredBlt(const D3DDDIARG_BLT& data, Resource& srcResource)
|
||||||
{
|
{
|
||||||
if (m_fixedData.Format == srcResource.m_fixedData.Format &&
|
if (m_fixedData.Format == srcResource.m_fixedData.Format &&
|
||||||
0 != m_formatInfo.bytesPerPixel)
|
0 != m_formatInfo.bytesPerPixel &&
|
||||||
|
(data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown ||
|
||||||
|
(isInSysMem(data.DstSubResourceIndex) &&
|
||||||
|
(!srcResource.m_fixedData.Flags.RenderTarget || srcResource.isInSysMem(data.SrcSubResourceIndex)))))
|
||||||
{
|
{
|
||||||
if (data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown)
|
SysMemBltGuard srcGuard(srcResource, data.SrcSubResourceIndex, true);
|
||||||
|
if (srcGuard.data)
|
||||||
{
|
{
|
||||||
if (m_canCreateLockResource)
|
SysMemBltGuard dstGuard(*this, data.DstSubResourceIndex, false);
|
||||||
|
if (dstGuard.data)
|
||||||
{
|
{
|
||||||
createLockResource();
|
auto dstBuf = static_cast<BYTE*>(dstGuard.data) +
|
||||||
}
|
data.DstRect.top * dstGuard.pitch + data.DstRect.left * m_formatInfo.bytesPerPixel;
|
||||||
if (srcResource.m_canCreateLockResource)
|
auto srcBuf = static_cast<const BYTE*>(srcGuard.data) +
|
||||||
{
|
data.SrcRect.top * srcGuard.pitch + data.SrcRect.left * m_formatInfo.bytesPerPixel;
|
||||||
srcResource.createLockResource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool ||
|
DDraw::Blitter::blt(
|
||||||
(m_lockResource && m_lockData[data.DstSubResourceIndex].isSysMemUpToDate))
|
dstBuf,
|
||||||
{
|
dstGuard.pitch,
|
||||||
SysMemBltGuard srcGuard(srcResource, data.SrcSubResourceIndex, true);
|
data.DstRect.right - data.DstRect.left,
|
||||||
if (srcGuard.data)
|
data.DstRect.bottom - data.DstRect.top,
|
||||||
{
|
srcBuf,
|
||||||
SysMemBltGuard dstGuard(*this, data.DstSubResourceIndex, false);
|
srcGuard.pitch,
|
||||||
if (dstGuard.data)
|
(1 - 2 * data.Flags.MirrorLeftRight) * (data.SrcRect.right - data.SrcRect.left),
|
||||||
{
|
(1 - 2 * data.Flags.MirrorUpDown) * (data.SrcRect.bottom - data.SrcRect.top),
|
||||||
auto dstBuf = static_cast<BYTE*>(dstGuard.data) +
|
m_formatInfo.bytesPerPixel,
|
||||||
data.DstRect.top * dstGuard.pitch + data.DstRect.left * m_formatInfo.bytesPerPixel;
|
data.Flags.DstColorKey ? reinterpret_cast<const DWORD*>(&data.ColorKey) : nullptr,
|
||||||
auto srcBuf = static_cast<const BYTE*>(srcGuard.data) +
|
data.Flags.SrcColorKey ? reinterpret_cast<const DWORD*>(&data.ColorKey) : nullptr);
|
||||||
data.SrcRect.top * srcGuard.pitch + data.SrcRect.left * m_formatInfo.bytesPerPixel;
|
|
||||||
|
|
||||||
DDraw::Blitter::blt(
|
return S_OK;
|
||||||
dstBuf,
|
|
||||||
dstGuard.pitch,
|
|
||||||
data.DstRect.right - data.DstRect.left,
|
|
||||||
data.DstRect.bottom - data.DstRect.top,
|
|
||||||
srcBuf,
|
|
||||||
srcGuard.pitch,
|
|
||||||
(1 - 2 * data.Flags.MirrorLeftRight) * (data.SrcRect.right - data.SrcRect.left),
|
|
||||||
(1 - 2 * data.Flags.MirrorUpDown) * (data.SrcRect.bottom - data.SrcRect.top),
|
|
||||||
m_formatInfo.bytesPerPixel,
|
|
||||||
data.Flags.DstColorKey ? reinterpret_cast<const DWORD*>(&data.ColorKey) : nullptr,
|
|
||||||
data.Flags.SrcColorKey ? reinterpret_cast<const DWORD*>(&data.ColorKey) : nullptr);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,18 @@ namespace D3dDdi
|
|||||||
static Resource create(Device& device, D3DDDIARG_CREATERESOURCE& data);
|
static Resource create(Device& device, D3DDDIARG_CREATERESOURCE& data);
|
||||||
static Resource create(Device& device, D3DDDIARG_CREATERESOURCE2& data);
|
static Resource create(Device& device, D3DDDIARG_CREATERESOURCE2& data);
|
||||||
|
|
||||||
|
Resource(const Resource&) = delete;
|
||||||
|
Resource& operator=(const Resource&) = delete;
|
||||||
|
|
||||||
|
Resource(Resource&&) = default;
|
||||||
|
Resource& operator=(Resource&&) = default;
|
||||||
|
|
||||||
operator HANDLE() const { return m_handle; }
|
operator HANDLE() const { return m_handle; }
|
||||||
|
|
||||||
HRESULT blt(D3DDDIARG_BLT data);
|
HRESULT blt(D3DDDIARG_BLT data);
|
||||||
HRESULT colorFill(const D3DDDIARG_COLORFILL& data);
|
HRESULT colorFill(const D3DDDIARG_COLORFILL& data);
|
||||||
void destroyLockResource();
|
|
||||||
void fixVertexData(UINT offset, UINT count, UINT stride);
|
void fixVertexData(UINT offset, UINT count, UINT stride);
|
||||||
void* getLockPtr(UINT subResourceIndex);
|
void* getLockPtr(UINT subResourceIndex);
|
||||||
void initialize();
|
|
||||||
HRESULT lock(D3DDDIARG_LOCK& data);
|
HRESULT lock(D3DDDIARG_LOCK& data);
|
||||||
void prepareForRendering(UINT subResourceIndex, bool isReadOnly);
|
void prepareForRendering(UINT subResourceIndex, bool isReadOnly);
|
||||||
void setAsGdiResource(bool isGdiResource);
|
void setAsGdiResource(bool isGdiResource);
|
||||||
@ -55,6 +59,16 @@ namespace D3dDdi
|
|||||||
bool isVidMemUpToDate;
|
bool isVidMemUpToDate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ResourceDeleter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ResourceDeleter(Device& device) : m_device(device) {}
|
||||||
|
void operator()(HANDLE resource) { m_device.getOrigVtable().pfnDestroyResource(m_device, resource); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Device& m_device;
|
||||||
|
};
|
||||||
|
|
||||||
struct SysMemBltGuard
|
struct SysMemBltGuard
|
||||||
{
|
{
|
||||||
void* data;
|
void* data;
|
||||||
@ -78,12 +92,8 @@ namespace D3dDdi
|
|||||||
void createLockResource();
|
void createLockResource();
|
||||||
void createSysMemResource(const std::vector<D3DDDI_SURFACEINFO>& surfaceInfo);
|
void createSysMemResource(const std::vector<D3DDDI_SURFACEINFO>& surfaceInfo);
|
||||||
bool isOversized() const;
|
bool isOversized() const;
|
||||||
void moveToSysMem(UINT subResourceIndex);
|
bool isInSysMem(UINT subResourceIndex) const;
|
||||||
void moveToVidMem(UINT subResourceIndex);
|
|
||||||
void prepareSubResourceForRendering(UINT subResourceIndex, bool isReadOnly);
|
|
||||||
HRESULT presentationBlt(const D3DDDIARG_BLT& data, Resource& srcResource);
|
HRESULT presentationBlt(const D3DDDIARG_BLT& data, Resource& srcResource);
|
||||||
void setSysMemUpToDate(UINT subResourceIndex, bool upToDate);
|
|
||||||
void setVidMemUpToDate(UINT subResourceIndex, bool upToDate);
|
|
||||||
HRESULT splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect);
|
HRESULT splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect);
|
||||||
|
|
||||||
template <typename Arg>
|
template <typename Arg>
|
||||||
@ -96,9 +106,8 @@ namespace D3dDdi
|
|||||||
Data m_origData;
|
Data m_origData;
|
||||||
Data m_fixedData;
|
Data m_fixedData;
|
||||||
FormatInfo m_formatInfo;
|
FormatInfo m_formatInfo;
|
||||||
HANDLE m_lockResource;
|
|
||||||
std::vector<LockData> m_lockData;
|
|
||||||
std::unique_ptr<void, void(*)(void*)> m_lockBuffer;
|
std::unique_ptr<void, void(*)(void*)> m_lockBuffer;
|
||||||
bool m_canCreateLockResource;
|
std::vector<LockData> m_lockData;
|
||||||
|
std::unique_ptr<void, ResourceDeleter> m_lockResource;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -182,13 +182,15 @@ namespace Gdi
|
|||||||
|
|
||||||
if (!preservedRegion.isEmpty())
|
if (!preservedRegion.isEmpty())
|
||||||
{
|
{
|
||||||
HDC screenDc = Gdi::getScreenDc();
|
if (m_windowRect.left != oldWindowRect.left || m_windowRect.top != oldWindowRect.top)
|
||||||
SelectClipRgn(screenDc, preservedRegion);
|
{
|
||||||
BitBlt(screenDc, m_windowRect.left, m_windowRect.top,
|
HDC screenDc = Gdi::getScreenDc();
|
||||||
oldWindowRect.right - oldWindowRect.left, oldWindowRect.bottom - oldWindowRect.top,
|
SelectClipRgn(screenDc, preservedRegion);
|
||||||
screenDc, oldWindowRect.left, oldWindowRect.top, SRCCOPY);
|
BitBlt(screenDc, m_windowRect.left, m_windowRect.top,
|
||||||
SelectClipRgn(screenDc, nullptr);
|
oldWindowRect.right - oldWindowRect.left, oldWindowRect.bottom - oldWindowRect.top,
|
||||||
|
screenDc, oldWindowRect.left, oldWindowRect.top, SRCCOPY);
|
||||||
|
SelectClipRgn(screenDc, nullptr);
|
||||||
|
}
|
||||||
m_invalidatedRegion -= preservedRegion;
|
m_invalidatedRegion -= preservedRegion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user