1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00
DDrawCompat/DDrawCompat/D3dDdi/RenderTargetResource.cpp
2019-08-01 16:00:18 +02:00

105 lines
2.6 KiB
C++

#include "D3dDdi/Device.h"
#include "D3dDdi/RenderTargetResource.h"
namespace D3dDdi
{
RenderTargetResource::RenderTargetResource(Device& device, HANDLE resource, D3DDDIFORMAT format, UINT surfaceCount)
: m_device(device)
, m_resource(resource)
, m_bytesPerPixel(getBytesPerPixel(format))
, m_subResources(surfaceCount, SubResource(*this))
{
}
HRESULT RenderTargetResource::lock(D3DDDIARG_LOCK& data)
{
if (data.SubResourceIndex >= m_subResources.size())
{
return m_device.getOrigVtable().pfnLock(m_device, &data);
}
auto& subResource = m_subResources[data.SubResourceIndex];
if (subResource.surfacePtr)
{
auto surfacePtr = static_cast<unsigned char*>(subResource.surfacePtr);
if (data.Flags.AreaValid)
{
surfacePtr += data.Area.top * subResource.pitch + data.Area.left * m_bytesPerPixel;
}
data.pSurfData = surfacePtr;
data.Pitch = subResource.pitch;
subResource.isLocked = true;
return S_OK;
}
const UINT origFlags = data.Flags.Value;
data.Flags.Value = 0;
const HRESULT result = m_device.getOrigVtable().pfnLock(m_device, &data);
data.Flags.Value = origFlags;
if (SUCCEEDED(result))
{
subResource.surfacePtr = data.pSurfData;
subResource.pitch = data.Pitch;
subResource.isLocked = true;
m_lockedSubResources.insert(data.SubResourceIndex);
}
return result;
}
HRESULT RenderTargetResource::unlock(const D3DDDIARG_UNLOCK& data)
{
if (data.SubResourceIndex >= m_subResources.size())
{
return m_device.getOrigVtable().pfnUnlock(m_device, &data);
}
m_subResources[data.SubResourceIndex].isLocked = false;
return S_OK;
}
void RenderTargetResource::prepareForRendering(UINT subResourceIndex)
{
if (UINT_MAX == subResourceIndex)
{
auto it = m_lockedSubResources.begin();
while (it != m_lockedSubResources.end())
{
prepareSubResourceForRendering(*(it++));
}
}
if (subResourceIndex >= m_subResources.size())
{
return;
}
prepareSubResourceForRendering(subResourceIndex);
}
void RenderTargetResource::prepareSubResourceForRendering(UINT subResourceIndex)
{
auto& subResource = m_subResources[subResourceIndex];
if (subResource.surfacePtr && !subResource.isLocked)
{
D3DDDIARG_UNLOCK data = {};
data.hResource = m_resource;
data.SubResourceIndex = subResourceIndex;
m_device.getOrigVtable().pfnUnlock(m_device, &data);
subResource.surfacePtr = nullptr;
subResource.pitch = 0;
m_lockedSubResources.erase(subResourceIndex);
}
}
RenderTargetResource::SubResource::SubResource(RenderTargetResource& parent)
: parent(parent)
, surfacePtr(nullptr)
, pitch(0)
, isLocked(false)
{
}
}