mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added Antialiasing setting
This commit is contained in:
parent
bb987d25b1
commit
fb6555523f
@ -3,6 +3,7 @@
|
||||
namespace Config
|
||||
{
|
||||
Settings::AlternatePixelCenter alternatePixelCenter;
|
||||
Settings::Antialiasing antialiasing;
|
||||
Settings::CpuAffinity cpuAffinity;
|
||||
Settings::DesktopColorDepth desktopColorDepth;
|
||||
Settings::DisplayFilter displayFilter;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/Settings/AlternatePixelCenter.h>
|
||||
#include <Config/Settings/Antialiasing.h>
|
||||
#include <Config/Settings/CpuAffinity.h>
|
||||
#include <Config/Settings/DesktopColorDepth.h>
|
||||
#include <Config/Settings/DisplayFilter.h>
|
||||
@ -16,6 +17,7 @@ namespace Config
|
||||
const unsigned maxPaletteUpdatesPerMs = 5;
|
||||
|
||||
extern Settings::AlternatePixelCenter alternatePixelCenter;
|
||||
extern Settings::Antialiasing antialiasing;
|
||||
extern Settings::CpuAffinity cpuAffinity;
|
||||
extern Settings::DesktopColorDepth desktopColorDepth;
|
||||
extern Settings::DisplayFilter displayFilter;
|
||||
|
47
DDrawCompat/Config/Settings/Antialiasing.cpp
Normal file
47
DDrawCompat/Config/Settings/Antialiasing.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <d3dtypes.h>
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include <Config/Settings/Antialiasing.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
Antialiasing::Antialiasing()
|
||||
: MappedSetting("Antialiasing", "off", {
|
||||
{"off", D3DDDIMULTISAMPLE_NONE},
|
||||
{"msaa", D3DDDIMULTISAMPLE_NONMASKABLE},
|
||||
{"msaa2x", D3DDDIMULTISAMPLE_2_SAMPLES},
|
||||
{"msaa4x", D3DDDIMULTISAMPLE_4_SAMPLES},
|
||||
{"msaa8x", D3DDDIMULTISAMPLE_8_SAMPLES}
|
||||
})
|
||||
, m_param(0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string Antialiasing::getParamStr() const
|
||||
{
|
||||
return D3DDDIMULTISAMPLE_NONE != m_value ? std::to_string(m_param) : std::string();
|
||||
}
|
||||
|
||||
void Antialiasing::setDefaultParam(const UINT& value)
|
||||
{
|
||||
m_param = D3DDDIMULTISAMPLE_NONE != value ? 7 : 0;
|
||||
}
|
||||
|
||||
void Antialiasing::setValue(const UINT& value, const std::string& param)
|
||||
{
|
||||
if (D3DDDIMULTISAMPLE_NONE != value)
|
||||
{
|
||||
const UINT p = Config::Parser::parseUnsigned(param);
|
||||
if (p <= 7)
|
||||
{
|
||||
m_value = value;
|
||||
m_param = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw ParsingError("invalid parameter: '" + param + "'");
|
||||
}
|
||||
}
|
||||
}
|
24
DDrawCompat/Config/Settings/Antialiasing.h
Normal file
24
DDrawCompat/Config/Settings/Antialiasing.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/MappedSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class Antialiasing : public MappedSetting<UINT>
|
||||
{
|
||||
public:
|
||||
Antialiasing();
|
||||
|
||||
UINT getParam() const { return m_param; }
|
||||
|
||||
protected:
|
||||
virtual std::string getParamStr() const override;
|
||||
virtual void setDefaultParam(const UINT& value) override;
|
||||
virtual void setValue(const UINT& value, const std::string& param) override;
|
||||
|
||||
UINT m_param;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
#include <Common/Comparison.h>
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Config/Config.h>
|
||||
#include <D3dDdi/Adapter.h>
|
||||
#include <D3dDdi/AdapterFuncs.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
@ -34,61 +38,124 @@ namespace D3dDdi
|
||||
, m_driverVersion(data.DriverVersion)
|
||||
, m_luid(KernelModeThunks::getLastOpenAdapterInfo().luid)
|
||||
, m_repository{}
|
||||
, m_d3dExtendedCaps{}
|
||||
, m_ddrawCaps{}
|
||||
{
|
||||
if (m_adapter)
|
||||
{
|
||||
D3DDDIARG_GETCAPS getCaps = {};
|
||||
getCaps.Type = D3DDDICAPS_GETD3D7CAPS;
|
||||
getCaps.pData = &m_d3dExtendedCaps;
|
||||
getCaps.DataSize = sizeof(m_d3dExtendedCaps);
|
||||
m_origVtable.pfnGetCaps(m_adapter, &getCaps);
|
||||
|
||||
getCaps.Type = D3DDDICAPS_DDRAW;
|
||||
getCaps.pData = &m_ddrawCaps;
|
||||
getCaps.DataSize = sizeof(m_ddrawCaps);
|
||||
m_origVtable.pfnGetCaps(m_adapter, &getCaps);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD Adapter::getSupportedZBufferBitDepths()
|
||||
const Adapter::AdapterInfo& Adapter::getInfo() const
|
||||
{
|
||||
UINT formatCount = 0;
|
||||
D3DDDIARG_GETCAPS caps = {};
|
||||
caps.Type = D3DDDICAPS_GETFORMATCOUNT;
|
||||
caps.pData = &formatCount;
|
||||
caps.DataSize = sizeof(formatCount);
|
||||
m_origVtable.pfnGetCaps(m_adapter, &caps);
|
||||
|
||||
std::vector<FORMATOP> formatOp(formatCount);
|
||||
caps.Type = D3DDDICAPS_GETFORMATDATA;
|
||||
caps.pData = formatOp.data();
|
||||
caps.DataSize = formatCount * sizeof(FORMATOP);
|
||||
m_origVtable.pfnGetCaps(m_adapter, &caps);
|
||||
|
||||
DWORD supportedZBufferBitDepths = 0;
|
||||
for (UINT i = 0; i < formatCount; ++i)
|
||||
auto it = s_adapterInfos.find(m_luid);
|
||||
if (it != s_adapterInfos.end())
|
||||
{
|
||||
if (formatOp[i].Operations & (FORMATOP_ZSTENCIL | FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH))
|
||||
{
|
||||
switch (formatOp[i].Format)
|
||||
{
|
||||
case D3DDDIFMT_D16:
|
||||
supportedZBufferBitDepths |= DDBD_16;
|
||||
break;
|
||||
|
||||
case D3DDDIFMT_X8D24:
|
||||
supportedZBufferBitDepths |= DDBD_24;
|
||||
break;
|
||||
|
||||
case D3DDDIFMT_D32:
|
||||
supportedZBufferBitDepths |= DDBD_32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
AdapterInfo& info = s_adapterInfos.insert({ m_luid, {} }).first->second;
|
||||
getCaps(D3DDDICAPS_GETD3D7CAPS, info.d3dExtendedCaps);
|
||||
info.formatOps = getFormatOps();
|
||||
info.supportedZBufferBitDepths = getSupportedZBufferBitDepths(info.formatOps);
|
||||
|
||||
Compat::Log() << "Supported z-buffer bit depths: " << bitDepthsToString(info.supportedZBufferBitDepths);
|
||||
Compat::Log() << "Supported MSAA modes: " << getSupportedMsaaModes(info.formatOps);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
template <typename Data>
|
||||
HRESULT Adapter::getCaps(D3DDDICAPS_TYPE type, Data& data, UINT size) const
|
||||
{
|
||||
D3DDDIARG_GETCAPS caps = {};
|
||||
caps.Type = type;
|
||||
caps.pData = &data;
|
||||
caps.DataSize = size;
|
||||
return m_origVtable.pfnGetCaps(m_adapter, &caps);
|
||||
}
|
||||
|
||||
std::map<D3DDDIFORMAT, FORMATOP> Adapter::getFormatOps() const
|
||||
{
|
||||
UINT formatCount = 0;
|
||||
getCaps(D3DDDICAPS_GETFORMATCOUNT, formatCount);
|
||||
|
||||
std::vector<FORMATOP> formatOps(formatCount);
|
||||
getCaps(D3DDDICAPS_GETFORMATDATA, formatOps[0], formatCount * sizeof(FORMATOP));
|
||||
|
||||
std::map<D3DDDIFORMAT, FORMATOP> result;
|
||||
for (UINT i = 0; i < formatCount; ++i)
|
||||
{
|
||||
result[formatOps[i].Format] = formatOps[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> Adapter::getMultisampleConfig(D3DDDIFORMAT format) const
|
||||
{
|
||||
UINT samples = Config::antialiasing.get();
|
||||
if (D3DDDIMULTISAMPLE_NONE == samples)
|
||||
{
|
||||
return { D3DDDIMULTISAMPLE_NONE, 0 };
|
||||
}
|
||||
|
||||
const auto& info(getInfo());
|
||||
auto it = info.formatOps.find(format);
|
||||
if (it == info.formatOps.end() || 0 == it->second.BltMsTypes)
|
||||
{
|
||||
return { D3DDDIMULTISAMPLE_NONE, 0 };
|
||||
}
|
||||
|
||||
while (samples > D3DDDIMULTISAMPLE_NONMASKABLE && !(it->second.BltMsTypes & (1 << (samples - 1))))
|
||||
{
|
||||
--samples;
|
||||
}
|
||||
|
||||
DDIMULTISAMPLEQUALITYLEVELSDATA levels = {};
|
||||
levels.Format = D3DDDIFMT_X8R8G8B8;
|
||||
levels.MsType = static_cast<D3DDDIMULTISAMPLE_TYPE>(samples);
|
||||
getCaps(D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS, levels);
|
||||
return { levels.MsType, min(Config::antialiasing.getParam(), levels.QualityLevels - 1) };
|
||||
}
|
||||
|
||||
std::string Adapter::getSupportedMsaaModes(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const
|
||||
{
|
||||
auto it = formatOps.find(D3DDDIFMT_X8R8G8B8);
|
||||
if (it != formatOps.end() && 0 != it->second.BltMsTypes)
|
||||
{
|
||||
DDIMULTISAMPLEQUALITYLEVELSDATA levels = {};
|
||||
levels.Format = D3DDDIFMT_X8R8G8B8;
|
||||
levels.MsType = D3DDDIMULTISAMPLE_NONMASKABLE;
|
||||
getCaps(D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS, levels);
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "msaa(" << levels.QualityLevels - 1 << ')';
|
||||
|
||||
for (UINT i = D3DDDIMULTISAMPLE_2_SAMPLES; i <= D3DDDIMULTISAMPLE_16_SAMPLES; ++i)
|
||||
{
|
||||
if (it->second.BltMsTypes & (1 << (i - 1)))
|
||||
{
|
||||
levels.MsType = static_cast<D3DDDIMULTISAMPLE_TYPE>(i);
|
||||
levels.QualityLevels = 0;
|
||||
getCaps(D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS, levels);
|
||||
oss << ", msaa" << i << "x(" << levels.QualityLevels - 1 << ')';
|
||||
}
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
return "none";
|
||||
}
|
||||
|
||||
DWORD Adapter::getSupportedZBufferBitDepths(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const
|
||||
{
|
||||
DWORD supportedZBufferBitDepths = 0;
|
||||
if (formatOps.find(D3DDDIFMT_D16) != formatOps.end())
|
||||
{
|
||||
supportedZBufferBitDepths |= DDBD_16;
|
||||
}
|
||||
if (formatOps.find(D3DDDIFMT_X8D24) != formatOps.end())
|
||||
{
|
||||
supportedZBufferBitDepths |= DDBD_24;
|
||||
}
|
||||
if (formatOps.find(D3DDDIFMT_D32) != formatOps.end())
|
||||
{
|
||||
supportedZBufferBitDepths |= DDBD_32;
|
||||
}
|
||||
return supportedZBufferBitDepths;
|
||||
}
|
||||
|
||||
@ -132,14 +199,7 @@ namespace D3dDdi
|
||||
auto& caps = static_cast<D3DNTHAL_GLOBALDRIVERDATA*>(pData->pData)->hwCaps;
|
||||
if (caps.dwFlags & D3DDD_DEVICEZBUFFERBITDEPTH)
|
||||
{
|
||||
const DWORD supportedZBufferBitDepths = getSupportedZBufferBitDepths();
|
||||
if (supportedZBufferBitDepths != caps.dwDeviceZBufferBitDepth)
|
||||
{
|
||||
LOG_ONCE("Incorrect z-buffer bit depth capabilities detected; changed from "
|
||||
<< bitDepthsToString(caps.dwDeviceZBufferBitDepth) << " to "
|
||||
<< bitDepthsToString(supportedZBufferBitDepths));
|
||||
caps.dwDeviceZBufferBitDepth = supportedZBufferBitDepths;
|
||||
}
|
||||
caps.dwDeviceZBufferBitDepth = getInfo().supportedZBufferBitDepths;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -160,4 +220,5 @@ namespace D3dDdi
|
||||
}
|
||||
|
||||
std::map<HANDLE, Adapter> Adapter::s_adapters;
|
||||
std::map<LUID, Adapter::AdapterInfo> Adapter::s_adapterInfos;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dnthal.h>
|
||||
@ -14,6 +15,13 @@ namespace D3dDdi
|
||||
class Adapter
|
||||
{
|
||||
public:
|
||||
struct AdapterInfo
|
||||
{
|
||||
D3DNTHAL_D3DEXTENDEDCAPS d3dExtendedCaps;
|
||||
std::map<D3DDDIFORMAT, FORMATOP> formatOps;
|
||||
DWORD supportedZBufferBitDepths;
|
||||
};
|
||||
|
||||
Adapter(const D3DDDIARG_OPENADAPTER& data);
|
||||
Adapter(const Adapter&) = delete;
|
||||
Adapter(Adapter&&) = delete;
|
||||
@ -22,9 +30,9 @@ namespace D3dDdi
|
||||
|
||||
operator HANDLE() const { return m_adapter; }
|
||||
|
||||
const D3DNTHAL_D3DEXTENDEDCAPS& getD3dExtendedCaps() const { return m_d3dExtendedCaps; }
|
||||
const DDRAW_CAPS& getDDrawCaps() const { return m_ddrawCaps; }
|
||||
const AdapterInfo& getInfo() const;
|
||||
LUID getLuid() const { return m_luid; }
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig(D3DDDIFORMAT format) const;
|
||||
const D3DDDI_ADAPTERFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||
CompatWeakPtr<IDirectDraw7> getRepository() const { return m_repository.repo; }
|
||||
bool isSrcColorKeySupported() const { return m_repository.isSrcColorKeySupported; }
|
||||
@ -38,7 +46,12 @@ namespace D3dDdi
|
||||
static void setRepository(LUID luid, const DDraw::DirectDraw::Repository& repository);
|
||||
|
||||
private:
|
||||
DWORD getSupportedZBufferBitDepths();
|
||||
template <typename Data>
|
||||
HRESULT getCaps(D3DDDICAPS_TYPE type, Data& data, UINT size = sizeof(Data)) const;
|
||||
|
||||
std::map<D3DDDIFORMAT, FORMATOP> getFormatOps() const;
|
||||
std::string getSupportedMsaaModes(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const;
|
||||
DWORD getSupportedZBufferBitDepths(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const;
|
||||
|
||||
HANDLE m_adapter;
|
||||
D3DDDI_ADAPTERFUNCS m_origVtable;
|
||||
@ -47,9 +60,7 @@ namespace D3dDdi
|
||||
LUID m_luid;
|
||||
DDraw::DirectDraw::Repository m_repository;
|
||||
|
||||
D3DNTHAL_D3DEXTENDEDCAPS m_d3dExtendedCaps;
|
||||
DDRAW_CAPS m_ddrawCaps;
|
||||
|
||||
static std::map<HANDLE, Adapter> s_adapters;
|
||||
static std::map<LUID, AdapterInfo> s_adapterInfos;
|
||||
};
|
||||
}
|
||||
|
@ -85,12 +85,21 @@ namespace D3dDdi
|
||||
return it != m_resources.end() ? it->second.get() : nullptr;
|
||||
}
|
||||
|
||||
void Device::prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly)
|
||||
void Device::prepareForBlt(HANDLE resource, UINT subResourceIndex, bool isReadOnly)
|
||||
{
|
||||
auto it = m_resources.find(resource);
|
||||
if (it != m_resources.end())
|
||||
{
|
||||
it->second->prepareForRendering(subResourceIndex, isReadOnly);
|
||||
it->second->prepareForBlt(subResourceIndex, isReadOnly);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::prepareForRendering(HANDLE resource, UINT subResourceIndex)
|
||||
{
|
||||
auto it = m_resources.find(resource);
|
||||
if (it != m_resources.end())
|
||||
{
|
||||
it->second->prepareForRendering(subResourceIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +107,7 @@ namespace D3dDdi
|
||||
{
|
||||
if (m_renderTarget)
|
||||
{
|
||||
m_renderTarget->prepareForRendering(m_renderTargetSubResourceIndex, false);
|
||||
m_renderTarget->prepareForRendering(m_renderTargetSubResourceIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +151,7 @@ namespace D3dDdi
|
||||
{
|
||||
return it->second->blt(*data);
|
||||
}
|
||||
prepareForRendering(data->hSrcResource, data->SrcSubResourceIndex, true);
|
||||
prepareForBlt(data->hSrcResource, data->SrcSubResourceIndex, true);
|
||||
return m_origVtable.pfnBlt(m_device, data);
|
||||
}
|
||||
|
||||
@ -301,7 +310,7 @@ namespace D3dDdi
|
||||
HRESULT Device::pfnPresent(const D3DDDIARG_PRESENT* data)
|
||||
{
|
||||
flushPrimitives();
|
||||
prepareForRendering(data->hSrcResource, data->SrcSubResourceIndex, true);
|
||||
prepareForBlt(data->hSrcResource, data->SrcSubResourceIndex, true);
|
||||
return m_origVtable.pfnPresent(m_device, data);
|
||||
}
|
||||
|
||||
@ -310,7 +319,7 @@ namespace D3dDdi
|
||||
flushPrimitives();
|
||||
for (UINT i = 0; i < data->SrcResources; ++i)
|
||||
{
|
||||
prepareForRendering(data->phSrcResources[i].hResource, data->phSrcResources[i].SubResourceIndex, true);
|
||||
prepareForBlt(data->phSrcResources[i].hResource, data->phSrcResources[i].SubResourceIndex, true);
|
||||
}
|
||||
return m_origVtable.pfnPresent1(m_device, data);
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ namespace D3dDdi
|
||||
|
||||
HRESULT createPrivateResource(D3DDDIARG_CREATERESOURCE2& data);
|
||||
void flushPrimitives() { m_drawPrimitive.flushPrimitives(); }
|
||||
void prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly);
|
||||
void prepareForBlt(HANDLE resource, UINT subResourceIndex, bool isReadOnly);
|
||||
void prepareForRendering(HANDLE resource, UINT subResourceIndex);
|
||||
void prepareForRendering();
|
||||
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <D3dDdi/DeviceState.h>
|
||||
#include <D3dDdi/DrawPrimitive.h>
|
||||
#include <D3dDdi/Log/DeviceFuncsLog.h>
|
||||
#include <D3dDdi/Resource.h>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
@ -191,7 +192,25 @@ namespace D3dDdi
|
||||
|
||||
HRESULT DeviceState::pfnSetDepthStencil(const D3DDDIARG_SETDEPTHSTENCIL* data)
|
||||
{
|
||||
return setState(data, m_depthStencil, m_device.getOrigVtable().pfnSetDepthStencil);
|
||||
if (0 == memcmp(data, &m_depthStencil, sizeof(m_depthStencil)))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
D3DDDIARG_SETDEPTHSTENCIL d = *data;
|
||||
Resource* resource = m_device.getResource(d.hZBuffer);
|
||||
if (resource && resource->getCustomResource())
|
||||
{
|
||||
d.hZBuffer = *resource->getCustomResource();
|
||||
}
|
||||
|
||||
m_device.flushPrimitives();
|
||||
HRESULT result = m_device.getOrigVtable().pfnSetDepthStencil(m_device, &d);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_depthStencil = *data;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetPixelShader(HANDLE shader)
|
||||
@ -216,6 +235,10 @@ namespace D3dDdi
|
||||
|
||||
HRESULT DeviceState::pfnSetRenderState(const D3DDDIARG_RENDERSTATE* data)
|
||||
{
|
||||
if (D3DDDIRS_MULTISAMPLEANTIALIAS == data->State)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
if (data->State >= D3DDDIRS_WRAP0 && data->State <= D3DDDIRS_WRAP7)
|
||||
{
|
||||
auto d = *data;
|
||||
@ -227,9 +250,23 @@ namespace D3dDdi
|
||||
|
||||
HRESULT DeviceState::pfnSetRenderTarget(const D3DDDIARG_SETRENDERTARGET* data)
|
||||
{
|
||||
HRESULT result = setState(data, m_renderTarget, m_device.getOrigVtable().pfnSetRenderTarget);
|
||||
if (0 == memcmp(data, &m_renderTarget, sizeof(m_renderTarget)))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
D3DDDIARG_SETRENDERTARGET d = *data;
|
||||
Resource* resource = m_device.getResource(d.hRenderTarget);
|
||||
if (resource && resource->getCustomResource())
|
||||
{
|
||||
d.hRenderTarget = *resource->getCustomResource();
|
||||
}
|
||||
|
||||
m_device.flushPrimitives();
|
||||
HRESULT result = m_device.getOrigVtable().pfnSetRenderTarget(m_device, &d);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_renderTarget = *data;
|
||||
m_device.setRenderTarget(*data);
|
||||
}
|
||||
return result;
|
||||
@ -482,6 +519,18 @@ namespace D3dDdi
|
||||
return result;
|
||||
}
|
||||
|
||||
DeviceState::ScopedRenderState::ScopedRenderState(DeviceState& deviceState, const D3DDDIARG_RENDERSTATE& data)
|
||||
: m_deviceState(deviceState)
|
||||
, m_prevData{ data.State, deviceState.m_renderState[data.State] }
|
||||
{
|
||||
m_deviceState.m_device.getOrigVtable().pfnSetRenderState(m_deviceState.m_device, &data);
|
||||
}
|
||||
|
||||
DeviceState::ScopedRenderState::~ScopedRenderState()
|
||||
{
|
||||
m_deviceState.m_device.getOrigVtable().pfnSetRenderState(m_deviceState.m_device, &m_prevData);
|
||||
}
|
||||
|
||||
DeviceState::ScopedTexture::ScopedTexture(DeviceState& deviceState, UINT stage, HANDLE texture, UINT filter)
|
||||
: m_deviceState(deviceState)
|
||||
, m_stage(stage)
|
||||
|
@ -187,18 +187,9 @@ namespace D3dDdi
|
||||
class ScopedRenderState
|
||||
{
|
||||
public:
|
||||
ScopedRenderState(DeviceState& deviceState, const D3DDDIARG_RENDERSTATE& data)
|
||||
: m_deviceState(deviceState)
|
||||
, m_prevData{ data.State, deviceState.m_renderState[data.State] }
|
||||
{
|
||||
m_deviceState.pfnSetRenderState(&data);
|
||||
}
|
||||
|
||||
~ScopedRenderState()
|
||||
{
|
||||
m_deviceState.pfnSetRenderState(&m_prevData);
|
||||
}
|
||||
|
||||
ScopedRenderState(DeviceState& deviceState, const D3DDDIARG_RENDERSTATE& data);
|
||||
~ScopedRenderState();
|
||||
|
||||
private:
|
||||
DeviceState& m_deviceState;
|
||||
D3DDDIARG_RENDERSTATE m_prevData;
|
||||
|
@ -36,3 +36,72 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEDEVICE& data)
|
||||
<< Compat::hex(data.Flags.Value)
|
||||
<< Compat::hex(data.CommandBuffer);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, D3DDDICAPS_TYPE data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
LOG_CONST_CASE(D3DDDICAPS_DDRAW);
|
||||
LOG_CONST_CASE(D3DDDICAPS_DDRAW_MODE_SPECIFIC);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETFORMATCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETFORMATDATA);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETD3DQUERYCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETD3DQUERYDATA);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETD3D3CAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETD3D5CAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETD3D6CAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETD3D7CAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETD3D8CAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETD3D9CAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETDECODEGUIDCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETDECODEGUIDS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETDECODERTFORMATCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETDECODERTFORMATS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFOCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFO);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETDECODECONFIGURATIONCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETDECODECONFIGURATIONS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETVIDEOPROCESSORRTFORMATCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETVIDEOPROCESSORRTFORMATS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETVIDEOPROCESSORCAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETPROCAMPRANGE);
|
||||
LOG_CONST_CASE(D3DDDICAPS_FILTERPROPERTYRANGE);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETEXTENSIONGUIDCOUNT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETEXTENSIONGUIDS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETEXTENSIONCAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETGAMMARAMPCAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_CHECKOVERLAYSUPPORT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_DXVAHD_GETVPDEVCAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_DXVAHD_GETVPOUTPUTFORMATS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_DXVAHD_GETVPINPUTFORMATS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_DXVAHD_GETVPCAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_DXVAHD_GETVPCUSTOMRATES);
|
||||
LOG_CONST_CASE(D3DDDICAPS_DXVAHD_GETVPFILTERRANGE);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETCONTENTPROTECTIONCAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETCERTIFICATESIZE);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GETCERTIFICATE);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GET_ARCHITECTURE_INFO);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GET_SHADER_MIN_PRECISION_SUPPORT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GET_MULTIPLANE_OVERLAY_CAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GET_MULTIPLANE_OVERLAY_FILTER_RANGE);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GET_MULTIPLANE_OVERLAY_GROUP_CAPS);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GET_SIMPLE_INSTANCING_SUPPORT);
|
||||
LOG_CONST_CASE(D3DDDICAPS_GET_MARKER_CAPS);
|
||||
}
|
||||
|
||||
return os << "D3DDDICAPS_" << static_cast<DWORD>(data);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_GETCAPS& data)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< data.Type
|
||||
<< data.pInfo
|
||||
<< data.pData
|
||||
<< data.DataSize;
|
||||
}
|
||||
|
@ -10,3 +10,5 @@
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEDEVICE& data);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_GETCAPS& data);
|
||||
std::ostream& operator<<(std::ostream& os, D3DDDICAPS_TYPE data);
|
||||
|
@ -26,6 +26,7 @@ namespace
|
||||
RECT g_presentationRect = {};
|
||||
UINT g_presentationFilter = Config::Settings::DisplayFilter::POINT;
|
||||
UINT g_presentationFilterParam = 0;
|
||||
D3DDDIFORMAT g_formatOverride = D3DDDIFMT_UNKNOWN;
|
||||
|
||||
RECT calculatePresentationRect()
|
||||
{
|
||||
@ -106,6 +107,7 @@ namespace D3dDdi
|
||||
, m_fixedData(data)
|
||||
, m_lockBuffer(nullptr, &heapFree)
|
||||
, m_lockResource(nullptr, ResourceDeleter(device))
|
||||
, m_customSurface{}
|
||||
{
|
||||
if (m_origData.Flags.VertexBuffer &&
|
||||
m_origData.Flags.MightDrawFromLocked &&
|
||||
@ -157,6 +159,35 @@ namespace D3dDdi
|
||||
}
|
||||
m_handle = m_fixedData.hResource;
|
||||
|
||||
if (!SurfaceRepository::inCreateSurface())
|
||||
{
|
||||
const auto msaa = getMultisampleConfig();
|
||||
if (D3DDDIMULTISAMPLE_NONE != msaa.first)
|
||||
{
|
||||
g_formatOverride = m_fixedData.Format;
|
||||
if (m_fixedData.Flags.ZBuffer)
|
||||
{
|
||||
DDPIXELFORMAT pf = {};
|
||||
pf.dwSize = sizeof(pf);
|
||||
pf.dwFlags = DDPF_ZBUFFER;
|
||||
pf.dwZBufferBitDepth = 16;
|
||||
pf.dwZBitMask = 0xFFFF;
|
||||
|
||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_customSurface,
|
||||
m_fixedData.surfaceData[0].Width, m_fixedData.surfaceData[0].Height, pf,
|
||||
DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_customSurface,
|
||||
m_fixedData.surfaceData[0].Width, m_fixedData.surfaceData[0].Height,
|
||||
DDraw::DirectDraw::getRgbPixelFormat(32),
|
||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY);
|
||||
}
|
||||
g_formatOverride = D3DDDIFMT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool &&
|
||||
0 != m_formatInfo.bytesPerPixel)
|
||||
{
|
||||
@ -207,15 +238,22 @@ namespace D3dDdi
|
||||
|
||||
if (isOversized())
|
||||
{
|
||||
m_device.prepareForRendering(data.hSrcResource, data.SrcSubResourceIndex, true);
|
||||
return splitBlt(data, data.DstSubResourceIndex, data.DstRect, data.SrcRect);
|
||||
if (srcResource)
|
||||
{
|
||||
srcResource->prepareForBlt(data.SrcSubResourceIndex, true);
|
||||
}
|
||||
HRESULT result = splitBlt(data, data.DstSubResourceIndex, data.DstRect, data.SrcRect);
|
||||
notifyLock(data.DstSubResourceIndex);
|
||||
return result;
|
||||
}
|
||||
else if (srcResource)
|
||||
{
|
||||
if (srcResource->isOversized())
|
||||
{
|
||||
prepareForRendering(data.DstSubResourceIndex, false);
|
||||
return srcResource->splitBlt(data, data.SrcSubResourceIndex, data.SrcRect, data.DstRect);
|
||||
prepareForBlt(data.DstSubResourceIndex, false);
|
||||
HRESULT result = srcResource->splitBlt(data, data.SrcSubResourceIndex, data.SrcRect, data.DstRect);
|
||||
srcResource->notifyLock(data.SrcSubResourceIndex);
|
||||
return result;
|
||||
}
|
||||
else if (m_fixedData.Flags.Primary)
|
||||
{
|
||||
@ -226,7 +264,7 @@ namespace D3dDdi
|
||||
return sysMemPreferredBlt(data, *srcResource);
|
||||
}
|
||||
}
|
||||
prepareForRendering(data.DstSubResourceIndex, false);
|
||||
prepareForBlt(data.DstSubResourceIndex, false);
|
||||
return m_device.getOrigVtable().pfnBlt(m_device, &data);
|
||||
}
|
||||
|
||||
@ -240,6 +278,7 @@ namespace D3dDdi
|
||||
copyToSysMem(data.SubResourceIndex);
|
||||
}
|
||||
lockData.isVidMemUpToDate &= data.Flags.ReadOnly;
|
||||
lockData.isCustomUpToDate &= data.Flags.ReadOnly;
|
||||
lockData.qpcLastForcedLock = Time::queryPerformanceCounter();
|
||||
|
||||
unsigned char* ptr = static_cast<unsigned char*>(lockData.data);
|
||||
@ -294,10 +333,11 @@ namespace D3dDdi
|
||||
m_formatInfo.bytesPerPixel, colorConvert(m_formatInfo, data.Color));
|
||||
|
||||
m_lockData[data.SubResourceIndex].isVidMemUpToDate = false;
|
||||
m_lockData[data.SubResourceIndex].isCustomUpToDate = false;
|
||||
return LOG_RESULT(S_OK);
|
||||
}
|
||||
}
|
||||
prepareForRendering(data.SubResourceIndex, false);
|
||||
prepareForBlt(data.SubResourceIndex, false);
|
||||
return LOG_RESULT(m_device.getOrigVtable().pfnColorFill(m_device, &data));
|
||||
}
|
||||
|
||||
@ -321,31 +361,32 @@ namespace D3dDdi
|
||||
{
|
||||
LOG_ONCE("ERROR: Resource::copySubResource failed: " << Compat::hex(result));
|
||||
}
|
||||
|
||||
D3DDDIARG_LOCK lock = {};
|
||||
lock.hResource = m_lockResource.get();
|
||||
lock.SubResourceIndex = subResourceIndex;
|
||||
lock.Flags.NotifyOnly = 1;
|
||||
m_device.getOrigVtable().pfnLock(m_device, &lock);
|
||||
|
||||
D3DDDIARG_UNLOCK unlock = {};
|
||||
unlock.hResource = m_lockResource.get();
|
||||
unlock.SubResourceIndex = subResourceIndex;
|
||||
unlock.Flags.NotifyOnly = 1;
|
||||
m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||
|
||||
return LOG_RESULT(result);
|
||||
}
|
||||
|
||||
void Resource::copyToSysMem(UINT subResourceIndex)
|
||||
{
|
||||
if (!m_lockData[subResourceIndex].isVidMemUpToDate)
|
||||
{
|
||||
copySubResource(m_handle, m_customSurface.resource->m_handle, subResourceIndex);
|
||||
m_lockData[subResourceIndex].isVidMemUpToDate = true;
|
||||
}
|
||||
copySubResource(m_lockResource.get(), m_handle, subResourceIndex);
|
||||
notifyLock(subResourceIndex);
|
||||
m_lockData[subResourceIndex].isSysMemUpToDate = true;
|
||||
}
|
||||
|
||||
void Resource::copyToVidMem(UINT subResourceIndex)
|
||||
{
|
||||
copySubResource(m_handle, m_lockResource.get(), subResourceIndex);
|
||||
if (m_lockData[subResourceIndex].isCustomUpToDate)
|
||||
{
|
||||
copySubResource(m_handle, m_customSurface.resource->m_handle, subResourceIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
copySubResource(m_handle, m_lockResource.get(), subResourceIndex);
|
||||
notifyLock(subResourceIndex);
|
||||
}
|
||||
m_lockData[subResourceIndex].isVidMemUpToDate = true;
|
||||
}
|
||||
|
||||
@ -368,6 +409,7 @@ namespace D3dDdi
|
||||
if (m_lockResource)
|
||||
{
|
||||
m_lockData[0].isVidMemUpToDate = false;
|
||||
m_lockData[0].isCustomUpToDate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -447,6 +489,7 @@ namespace D3dDdi
|
||||
m_lockData[i].qpcLastForcedLock = qpcLastForcedLock;
|
||||
m_lockData[i].isSysMemUpToDate = true;
|
||||
m_lockData[i].isVidMemUpToDate = true;
|
||||
m_lockData[i].isCustomUpToDate = m_customSurface.resource;
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,6 +514,14 @@ namespace D3dDdi
|
||||
m_fixedData.Format = D3DDDIFMT_X8R8G8B8;
|
||||
}
|
||||
|
||||
if (D3DDDIFMT_UNKNOWN != g_formatOverride)
|
||||
{
|
||||
m_fixedData.Format = g_formatOverride;
|
||||
auto msaa = getMultisampleConfig();
|
||||
m_fixedData.MultisampleType = msaa.first;
|
||||
m_fixedData.MultisampleQuality = msaa.second;
|
||||
}
|
||||
|
||||
const bool isOffScreenPlain = 0 == (m_fixedData.Flags.Value & g_resourceTypeFlags);
|
||||
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool &&
|
||||
(isOffScreenPlain || m_fixedData.Flags.Texture) &&
|
||||
@ -478,7 +529,7 @@ namespace D3dDdi
|
||||
0 == m_fixedData.pSurfList[0].Depth &&
|
||||
0 != D3dDdi::getFormatInfo(m_fixedData.Format).bytesPerPixel)
|
||||
{
|
||||
const auto& caps = m_device.getAdapter().getD3dExtendedCaps();
|
||||
const auto& caps = m_device.getAdapter().getInfo().d3dExtendedCaps;
|
||||
const auto& surfaceInfo = m_fixedData.pSurfList[0];
|
||||
if (0 != caps.dwMaxTextureWidth && surfaceInfo.Width > caps.dwMaxTextureWidth ||
|
||||
0 != caps.dwMaxTextureHeight && surfaceInfo.Height > caps.dwMaxTextureHeight)
|
||||
@ -493,6 +544,17 @@ namespace D3dDdi
|
||||
return m_lockData.empty() ? nullptr : m_lockData[subResourceIndex].data;
|
||||
}
|
||||
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> Resource::getMultisampleConfig()
|
||||
{
|
||||
if ((m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.Primary ||
|
||||
m_fixedData.Flags.ZBuffer) &&
|
||||
D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool)
|
||||
{
|
||||
return m_device.getAdapter().getMultisampleConfig(m_fixedData.Format);
|
||||
}
|
||||
return { D3DDDIMULTISAMPLE_NONE, 0 };
|
||||
}
|
||||
|
||||
bool Resource::isOversized() const
|
||||
{
|
||||
return m_fixedData.SurfCount != m_origData.SurfCount;
|
||||
@ -526,6 +588,34 @@ namespace D3dDdi
|
||||
return m_device.getOrigVtable().pfnLock(m_device, &data);
|
||||
}
|
||||
|
||||
void Resource::notifyLock(UINT subResourceIndex)
|
||||
{
|
||||
D3DDDIARG_LOCK lock = {};
|
||||
lock.hResource = D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool ? m_handle : m_lockResource.get();
|
||||
lock.SubResourceIndex = subResourceIndex;
|
||||
lock.Flags.NotifyOnly = 1;
|
||||
m_device.getOrigVtable().pfnLock(m_device, &lock);
|
||||
|
||||
D3DDDIARG_UNLOCK unlock = {};
|
||||
unlock.hResource = lock.hResource;
|
||||
unlock.SubResourceIndex = lock.SubResourceIndex;
|
||||
unlock.Flags.NotifyOnly = 1;
|
||||
m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||
}
|
||||
|
||||
void Resource::prepareForBlt(UINT subResourceIndex, bool isReadOnly)
|
||||
{
|
||||
if (m_lockResource && 0 == m_lockData[subResourceIndex].lockCount)
|
||||
{
|
||||
if (!m_lockData[subResourceIndex].isVidMemUpToDate)
|
||||
{
|
||||
copyToVidMem(subResourceIndex);
|
||||
}
|
||||
m_lockData[subResourceIndex].isCustomUpToDate &= isReadOnly;
|
||||
m_lockData[subResourceIndex].isSysMemUpToDate &= isReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::prepareForGdiRendering(bool isReadOnly)
|
||||
{
|
||||
if (!m_lockResource)
|
||||
@ -538,28 +628,44 @@ namespace D3dDdi
|
||||
copyToSysMem(0);
|
||||
}
|
||||
m_lockData[0].isVidMemUpToDate &= isReadOnly;
|
||||
m_lockData[0].isCustomUpToDate &= isReadOnly;
|
||||
m_lockData[0].qpcLastForcedLock = Time::queryPerformanceCounter();
|
||||
}
|
||||
|
||||
void Resource::prepareForRendering(UINT subResourceIndex, bool isReadOnly)
|
||||
void Resource::prepareForRendering(UINT subResourceIndex)
|
||||
{
|
||||
if (m_lockResource && 0 == m_lockData[subResourceIndex].lockCount)
|
||||
{
|
||||
if (!m_lockData[subResourceIndex].isVidMemUpToDate)
|
||||
if (m_customSurface.resource)
|
||||
{
|
||||
if (!m_lockData[subResourceIndex].isCustomUpToDate)
|
||||
{
|
||||
if (!m_lockData[subResourceIndex].isVidMemUpToDate)
|
||||
{
|
||||
copyToVidMem(subResourceIndex);
|
||||
}
|
||||
copySubResource(m_customSurface.resource->m_handle, m_handle, subResourceIndex);
|
||||
m_lockData[subResourceIndex].isCustomUpToDate = true;
|
||||
}
|
||||
m_lockData[subResourceIndex].isVidMemUpToDate = false;
|
||||
}
|
||||
else if (!m_lockData[subResourceIndex].isVidMemUpToDate)
|
||||
{
|
||||
copyToVidMem(subResourceIndex);
|
||||
}
|
||||
m_lockData[subResourceIndex].isSysMemUpToDate &= isReadOnly;
|
||||
m_lockData[subResourceIndex].isSysMemUpToDate = false;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT Resource::presentationBlt(D3DDDIARG_BLT data, Resource* srcResource)
|
||||
{
|
||||
if (srcResource->m_lockResource &&
|
||||
srcResource->m_lockData[0].isSysMemUpToDate)
|
||||
srcResource->m_lockData[0].isSysMemUpToDate &&
|
||||
!srcResource->m_fixedData.Flags.RenderTarget)
|
||||
{
|
||||
srcResource->copyToVidMem(0);
|
||||
srcResource->m_lockData[0].isVidMemUpToDate = false;
|
||||
}
|
||||
srcResource->prepareForBlt(0, true);
|
||||
|
||||
const bool isPalettized = D3DDDIFMT_P8 == srcResource->m_origData.Format;
|
||||
|
||||
@ -659,7 +765,7 @@ namespace D3dDdi
|
||||
return LOG_RESULT(m_device.getOrigVtable().pfnBlt(m_device, &data));
|
||||
}
|
||||
|
||||
const auto& caps = m_device.getAdapter().getD3dExtendedCaps();
|
||||
const auto& caps = m_device.getAdapter().getInfo().d3dExtendedCaps;
|
||||
const auto tilesPerRow = divCeil(m_origData.pSurfList[0].Width, caps.dwMaxTextureWidth);
|
||||
|
||||
const RECT origRect = rect;
|
||||
@ -763,6 +869,7 @@ namespace D3dDdi
|
||||
copyToSysMem(data.DstSubResourceIndex);
|
||||
}
|
||||
dstLockData.isVidMemUpToDate = false;
|
||||
dstLockData.isCustomUpToDate = false;
|
||||
|
||||
if (!srcLockData.isSysMemUpToDate)
|
||||
{
|
||||
@ -787,13 +894,23 @@ namespace D3dDdi
|
||||
data.Flags.DstColorKey ? reinterpret_cast<const DWORD*>(&data.ColorKey) : nullptr,
|
||||
data.Flags.SrcColorKey ? reinterpret_cast<const DWORD*>(&data.ColorKey) : nullptr);
|
||||
|
||||
notifyLock(data.DstSubResourceIndex);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
prepareForRendering(data.DstSubResourceIndex, false);
|
||||
srcResource.prepareForRendering(data.SrcSubResourceIndex, true);
|
||||
return m_device.getOrigVtable().pfnBlt(m_device, &data);
|
||||
prepareForBlt(data.DstSubResourceIndex, false);
|
||||
srcResource.prepareForBlt(data.SrcSubResourceIndex, true);
|
||||
HRESULT result = m_device.getOrigVtable().pfnBlt(m_device, &data);
|
||||
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool)
|
||||
{
|
||||
notifyLock(data.DstSubResourceIndex);
|
||||
}
|
||||
else if (D3DDDIPOOL_SYSTEMMEM == srcResource.m_fixedData.Pool)
|
||||
{
|
||||
srcResource.notifyLock(data.SrcSubResourceIndex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Arg>
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include <D3dDdi/FormatInfo.h>
|
||||
#include <D3dDdi/SurfaceRepository.h>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
@ -24,15 +25,17 @@ namespace D3dDdi
|
||||
~Resource();
|
||||
|
||||
operator HANDLE() const { return m_handle; }
|
||||
const D3DDDIARG_CREATERESOURCE2& getOrigDesc() const { return m_origData; }
|
||||
const Resource* getCustomResource() { return m_customSurface.resource; }
|
||||
const D3DDDIARG_CREATERESOURCE2& getFixedDesc() const { return m_fixedData; }
|
||||
const D3DDDIARG_CREATERESOURCE2& getOrigDesc() const { return m_origData; }
|
||||
|
||||
HRESULT blt(D3DDDIARG_BLT data);
|
||||
HRESULT colorFill(D3DDDIARG_COLORFILL data);
|
||||
void* getLockPtr(UINT subResourceIndex);
|
||||
HRESULT lock(D3DDDIARG_LOCK& data);
|
||||
void prepareForBlt(UINT subResourceIndex, bool isReadOnly);
|
||||
void prepareForGdiRendering(bool isReadOnly);
|
||||
void prepareForRendering(UINT subResourceIndex, bool isReadOnly);
|
||||
void prepareForRendering(UINT subResourceIndex);
|
||||
void setAsGdiResource(bool isGdiResource);
|
||||
HRESULT unlock(const D3DDDIARG_UNLOCK& data);
|
||||
|
||||
@ -58,6 +61,7 @@ namespace D3dDdi
|
||||
long long qpcLastForcedLock;
|
||||
bool isSysMemUpToDate;
|
||||
bool isVidMemUpToDate;
|
||||
bool isCustomUpToDate;
|
||||
};
|
||||
|
||||
class ResourceDeleter
|
||||
@ -80,8 +84,10 @@ namespace D3dDdi
|
||||
void createLockResource();
|
||||
void createSysMemResource(const std::vector<D3DDDI_SURFACEINFO>& surfaceInfo);
|
||||
void fixResourceData();
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig();
|
||||
bool isOversized() const;
|
||||
bool isValidRect(UINT subResourceIndex, const RECT& rect);
|
||||
void notifyLock(UINT subResourceIndex);
|
||||
HRESULT presentationBlt(D3DDDIARG_BLT data, Resource* srcResource);
|
||||
HRESULT splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect);
|
||||
|
||||
@ -99,5 +105,6 @@ namespace D3dDdi
|
||||
std::unique_ptr<void, void(*)(void*)> m_lockBuffer;
|
||||
std::vector<LockData> m_lockData;
|
||||
std::unique_ptr<void, ResourceDeleter> m_lockResource;
|
||||
SurfaceRepository::Surface m_customSurface;
|
||||
};
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace D3dDdi
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> SurfaceRepository::createSurface(
|
||||
DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps)
|
||||
DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps, UINT surfaceCount)
|
||||
{
|
||||
auto dd(m_adapter.getRepository());
|
||||
if (!dd)
|
||||
@ -47,8 +47,16 @@ namespace D3dDdi
|
||||
desc.dwHeight = height;
|
||||
desc.ddpfPixelFormat = pf;
|
||||
desc.ddsCaps.dwCaps = caps;
|
||||
if (surfaceCount > 1)
|
||||
{
|
||||
desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
desc.dwBackBufferCount = surfaceCount - 1;
|
||||
}
|
||||
|
||||
s_inCreateSurface = true;
|
||||
HRESULT result = dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
s_inCreateSurface = false;
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("ERROR: Failed to create repository surface: " << Compat::hex(result) << " " << desc);
|
||||
@ -72,7 +80,7 @@ namespace D3dDdi
|
||||
{
|
||||
DWORD width = rect.right - rect.left;
|
||||
DWORD height = rect.bottom - rect.top;
|
||||
auto resource = getResource(surface, width, height, pf, caps);
|
||||
auto resource = getSurface(surface, width, height, pf, caps).resource;
|
||||
if (!resource)
|
||||
{
|
||||
return nullptr;
|
||||
@ -140,8 +148,8 @@ namespace D3dDdi
|
||||
}
|
||||
DeleteObject(iconInfo.hbmMask);
|
||||
|
||||
m_cursorMaskTexture.resource->prepareForRendering(0, true);
|
||||
m_cursorColorTexture.resource->prepareForRendering(0, true);
|
||||
m_cursorMaskTexture.resource->prepareForBlt(0, true);
|
||||
m_cursorColorTexture.resource->prepareForBlt(0, true);
|
||||
|
||||
m_cursorSize.cx = rect.right - rect.left;
|
||||
m_cursorSize.cy = rect.bottom - rect.top;
|
||||
@ -155,8 +163,8 @@ namespace D3dDdi
|
||||
result.hotspot = m_cursorHotspot;
|
||||
result.maskTexture = m_cursorMaskTexture.resource;
|
||||
result.colorTexture = m_cursorColorTexture.resource;
|
||||
result.tempTexture = getResource(m_cursorTempTexture, m_cursorSize.cx, m_cursorSize.cy,
|
||||
DDraw::DirectDraw::getRgbPixelFormat(32), DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY);
|
||||
result.tempTexture = getSurface(m_cursorTempTexture, m_cursorSize.cx, m_cursorSize.cy,
|
||||
DDraw::DirectDraw::getRgbPixelFormat(32), DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY).resource;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -180,7 +188,7 @@ namespace D3dDdi
|
||||
Resource* SurfaceRepository::getInitializedResource(Surface& surface, DWORD width, DWORD height,
|
||||
const DDPIXELFORMAT& pf, DWORD caps, std::function<void(const DDSURFACEDESC2&)> initFunc)
|
||||
{
|
||||
if (!isLost(surface) || !getResource(surface, width, height, pf, caps))
|
||||
if (!isLost(surface) || !getSurface(surface, width, height, pf, caps).resource)
|
||||
{
|
||||
return surface.resource;
|
||||
}
|
||||
@ -195,14 +203,14 @@ namespace D3dDdi
|
||||
|
||||
initFunc(desc);
|
||||
surface.surface->Unlock(surface.surface, nullptr);
|
||||
surface.resource->prepareForRendering(0, true);
|
||||
surface.resource->prepareForBlt(0, true);
|
||||
return surface.resource;
|
||||
}
|
||||
|
||||
Resource* SurfaceRepository::getPaletteTexture()
|
||||
{
|
||||
return getResource(m_paletteTexture, 256, 1, DDraw::DirectDraw::getRgbPixelFormat(32),
|
||||
DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY);
|
||||
return getSurface(m_paletteTexture, 256, 1, DDraw::DirectDraw::getRgbPixelFormat(32),
|
||||
DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY).resource;
|
||||
}
|
||||
|
||||
const SurfaceRepository::Surface& SurfaceRepository::getRenderTarget(DWORD width, DWORD height)
|
||||
@ -211,13 +219,8 @@ namespace D3dDdi
|
||||
DDSCAPS_3DDEVICE | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY);
|
||||
}
|
||||
|
||||
Resource* SurfaceRepository::getResource(Surface& surface, DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps)
|
||||
{
|
||||
return getSurface(surface, width, height, pf, caps).resource;
|
||||
}
|
||||
|
||||
SurfaceRepository::Surface& SurfaceRepository::getSurface(Surface& surface, DWORD width, DWORD height,
|
||||
const DDPIXELFORMAT& pf, DWORD caps)
|
||||
const DDPIXELFORMAT& pf, DWORD caps, UINT surfaceCount)
|
||||
{
|
||||
if (surface.surface && (surface.width != width || surface.height != height ||
|
||||
0 != memcmp(&surface.pixelFormat, &pf, sizeof(pf)) || isLost(surface)))
|
||||
@ -227,7 +230,7 @@ namespace D3dDdi
|
||||
|
||||
if (!surface.surface)
|
||||
{
|
||||
surface.surface = createSurface(width, height, pf, caps);
|
||||
surface.surface = createSurface(width, height, pf, caps, surfaceCount);
|
||||
if (surface.surface)
|
||||
{
|
||||
surface.resource = D3dDdi::Device::findResource(
|
||||
@ -254,4 +257,6 @@ namespace D3dDdi
|
||||
surface = {};
|
||||
}
|
||||
}
|
||||
|
||||
bool SurfaceRepository::s_inCreateSurface = false;
|
||||
}
|
||||
|
@ -37,18 +37,20 @@ namespace D3dDdi
|
||||
Resource* getLogicalXorTexture();
|
||||
Resource* getPaletteTexture();
|
||||
const Surface& getRenderTarget(DWORD width, DWORD height);
|
||||
Surface& getSurface(Surface& surface, DWORD width, DWORD height,
|
||||
const DDPIXELFORMAT& pf, DWORD caps, UINT surfaceCount = 1);
|
||||
|
||||
static SurfaceRepository& get(const Adapter& adapter);
|
||||
static bool inCreateSurface() { return s_inCreateSurface; }
|
||||
|
||||
private:
|
||||
SurfaceRepository(const Adapter& adapter);
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> createSurface(DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps);
|
||||
CompatWeakPtr<IDirectDrawSurface7> createSurface(DWORD width, DWORD height,
|
||||
const DDPIXELFORMAT& pf, DWORD caps, UINT surfaceCount);
|
||||
Resource* getBitmapResource(Surface& surface, HBITMAP bitmap, const RECT& rect, const DDPIXELFORMAT& pf, DWORD caps);
|
||||
Resource* getInitializedResource(Surface& surface, DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps,
|
||||
std::function<void(const DDSURFACEDESC2&)> initFunc);
|
||||
Resource* getResource(Surface& surface, DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps);
|
||||
Surface& getSurface(Surface& surface, DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps);
|
||||
bool isLost(Surface& surface);
|
||||
void release(Surface& surface);
|
||||
|
||||
@ -62,5 +64,7 @@ namespace D3dDdi
|
||||
Surface m_logicalXorTexture;
|
||||
Surface m_paletteTexture;
|
||||
Surface m_renderTarget;
|
||||
|
||||
static bool s_inCreateSurface;
|
||||
};
|
||||
}
|
||||
|
@ -214,6 +214,7 @@
|
||||
<ClInclude Include="Config\Parser.h" />
|
||||
<ClInclude Include="Config\Setting.h" />
|
||||
<ClInclude Include="Config\Settings\AlternatePixelCenter.h" />
|
||||
<ClInclude Include="Config\Settings\Antialiasing.h" />
|
||||
<ClInclude Include="Config\Settings\CpuAffinity.h" />
|
||||
<ClInclude Include="Config\Settings\DesktopColorDepth.h" />
|
||||
<ClInclude Include="Config\Settings\DisplayFilter.h" />
|
||||
@ -322,6 +323,7 @@
|
||||
<ClCompile Include="Config\ListSetting.cpp" />
|
||||
<ClCompile Include="Config\Parser.cpp" />
|
||||
<ClCompile Include="Config\Setting.cpp" />
|
||||
<ClCompile Include="Config\Settings\Antialiasing.cpp" />
|
||||
<ClCompile Include="Config\Settings\CpuAffinity.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayFilter.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayResolution.cpp" />
|
||||
|
@ -453,6 +453,9 @@
|
||||
<ClInclude Include="Config\Settings\TextureFilter.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\Antialiasing.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -713,6 +716,9 @@
|
||||
<ClCompile Include="Config\Settings\TextureFilter.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\Settings\Antialiasing.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DDrawCompat.rc">
|
||||
|
@ -52,7 +52,7 @@ namespace
|
||||
desc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
|
||||
desc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
|
||||
desc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_3DDEVICE;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> renderTarget;
|
||||
HRESULT result = dd->CreateSurface(&dd, &desc, &renderTarget.getRef(), nullptr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user