1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Added Antialiasing setting

This commit is contained in:
narzoul 2021-07-10 15:06:20 +02:00
parent bb987d25b1
commit fb6555523f
19 changed files with 544 additions and 136 deletions

View File

@ -3,6 +3,7 @@
namespace Config
{
Settings::AlternatePixelCenter alternatePixelCenter;
Settings::Antialiasing antialiasing;
Settings::CpuAffinity cpuAffinity;
Settings::DesktopColorDepth desktopColorDepth;
Settings::DisplayFilter displayFilter;

View File

@ -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;

View 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 + "'");
}
}
}

View 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;
};
}
}

View File

@ -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;
}

View File

@ -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;
};
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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>

View File

@ -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;
};
}

View File

@ -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;
}

View File

@ -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;
};
}

View File

@ -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" />

View File

@ -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">

View File

@ -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);