mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added SoftwareDevice setting
This commit is contained in:
parent
bb0eadc310
commit
13e4d90116
@ -23,6 +23,12 @@ std::enable_if_t<std::is_class_v<T> && std::is_trivial_v<T>, bool> operator<(con
|
|||||||
return toTuple(left) < toTuple(right);
|
return toTuple(left) < toTuple(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline auto toTuple(const GUID& guid)
|
||||||
|
{
|
||||||
|
const auto data4 = *reinterpret_cast<const unsigned long long*>(&guid.Data4);
|
||||||
|
return std::make_tuple(guid.Data1, guid.Data2, guid.Data3, data4);
|
||||||
|
}
|
||||||
|
|
||||||
inline auto toTuple(const LUID& luid)
|
inline auto toTuple(const LUID& luid)
|
||||||
{
|
{
|
||||||
return std::make_tuple(luid.LowPart, luid.HighPart);
|
return std::make_tuple(luid.LowPart, luid.HighPart);
|
||||||
@ -38,6 +44,11 @@ inline auto toTuple(const RGBQUAD& q)
|
|||||||
return std::make_tuple(q.rgbBlue, q.rgbGreen, q.rgbRed, q.rgbReserved);
|
return std::make_tuple(q.rgbBlue, q.rgbGreen, q.rgbRed, q.rgbReserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline auto toTuple(const RECT& rect)
|
||||||
|
{
|
||||||
|
return std::make_tuple(rect.left, rect.top, rect.right, rect.bottom);
|
||||||
|
}
|
||||||
|
|
||||||
inline auto toTuple(const SIZE& size)
|
inline auto toTuple(const SIZE& size)
|
||||||
{
|
{
|
||||||
return std::make_tuple(size.cx, size.cy);
|
return std::make_tuple(size.cx, size.cy);
|
||||||
|
@ -23,6 +23,7 @@ namespace Config
|
|||||||
Settings::RemoveBorders removeBorders;
|
Settings::RemoveBorders removeBorders;
|
||||||
Settings::RenderColorDepth renderColorDepth;
|
Settings::RenderColorDepth renderColorDepth;
|
||||||
Settings::ResolutionScale resolutionScale;
|
Settings::ResolutionScale resolutionScale;
|
||||||
|
Settings::SoftwareDevice softwareDevice;
|
||||||
Settings::SpriteDetection spriteDetection;
|
Settings::SpriteDetection spriteDetection;
|
||||||
Settings::SpriteFilter spriteFilter;
|
Settings::SpriteFilter spriteFilter;
|
||||||
Settings::SpriteTexCoord spriteTexCoord;
|
Settings::SpriteTexCoord spriteTexCoord;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <Config/Settings/RemoveBorders.h>
|
#include <Config/Settings/RemoveBorders.h>
|
||||||
#include <Config/Settings/RenderColorDepth.h>
|
#include <Config/Settings/RenderColorDepth.h>
|
||||||
#include <Config/Settings/ResolutionScale.h>
|
#include <Config/Settings/ResolutionScale.h>
|
||||||
|
#include <Config/Settings/SoftwareDevice.h>
|
||||||
#include <Config/Settings/SpriteDetection.h>
|
#include <Config/Settings/SpriteDetection.h>
|
||||||
#include <Config/Settings/SpriteFilter.h>
|
#include <Config/Settings/SpriteFilter.h>
|
||||||
#include <Config/Settings/SpriteTexCoord.h>
|
#include <Config/Settings/SpriteTexCoord.h>
|
||||||
@ -53,6 +54,7 @@ namespace Config
|
|||||||
extern Settings::RemoveBorders removeBorders;
|
extern Settings::RemoveBorders removeBorders;
|
||||||
extern Settings::RenderColorDepth renderColorDepth;
|
extern Settings::RenderColorDepth renderColorDepth;
|
||||||
extern Settings::ResolutionScale resolutionScale;
|
extern Settings::ResolutionScale resolutionScale;
|
||||||
|
extern Settings::SoftwareDevice softwareDevice;
|
||||||
extern Settings::SpriteDetection spriteDetection;
|
extern Settings::SpriteDetection spriteDetection;
|
||||||
extern Settings::SpriteFilter spriteFilter;
|
extern Settings::SpriteFilter spriteFilter;
|
||||||
extern Settings::SpriteTexCoord spriteTexCoord;
|
extern Settings::SpriteTexCoord spriteTexCoord;
|
||||||
|
25
DDrawCompat/Config/Settings/SoftwareDevice.h
Normal file
25
DDrawCompat/Config/Settings/SoftwareDevice.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <d3d.h>
|
||||||
|
|
||||||
|
#include <Config/MappedSetting.h>
|
||||||
|
|
||||||
|
namespace Config
|
||||||
|
{
|
||||||
|
namespace Settings
|
||||||
|
{
|
||||||
|
class SoftwareDevice : public MappedSetting<const IID*>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoftwareDevice()
|
||||||
|
: MappedSetting("SoftwareDevice", "rgb", {
|
||||||
|
{"app", nullptr},
|
||||||
|
{"hal", &IID_IDirect3DHALDevice},
|
||||||
|
{"ref", &IID_IDirect3DRefDevice},
|
||||||
|
{"rgb", &IID_IDirect3DRGBDevice}
|
||||||
|
})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@
|
|||||||
#include <D3dDdi/Device.h>
|
#include <D3dDdi/Device.h>
|
||||||
#include <D3dDdi/DeviceCallbacks.h>
|
#include <D3dDdi/DeviceCallbacks.h>
|
||||||
#include <D3dDdi/DeviceFuncs.h>
|
#include <D3dDdi/DeviceFuncs.h>
|
||||||
|
#include <D3dDdi/FormatInfo.h>
|
||||||
#include <D3dDdi/KernelModeThunks.h>
|
#include <D3dDdi/KernelModeThunks.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -55,12 +56,17 @@ namespace D3dDdi
|
|||||||
info.formatOps = getFormatOps();
|
info.formatOps = getFormatOps();
|
||||||
info.supportedZBufferBitDepths = getSupportedZBufferBitDepths(info.formatOps);
|
info.supportedZBufferBitDepths = getSupportedZBufferBitDepths(info.formatOps);
|
||||||
|
|
||||||
|
info.isMsaaDepthResolveSupported =
|
||||||
|
info.formatOps.find(FOURCC_RESZ) != info.formatOps.end() &&
|
||||||
|
info.formatOps.find(FOURCC_INTZ) != info.formatOps.end() &&
|
||||||
|
info.formatOps.find(FOURCC_NULL) != info.formatOps.end();
|
||||||
|
|
||||||
LOG_INFO << "Supported z-buffer bit depths: " << bitDepthsToString(info.supportedZBufferBitDepths);
|
LOG_INFO << "Supported z-buffer bit depths: " << bitDepthsToString(info.supportedZBufferBitDepths);
|
||||||
LOG_INFO << "Supported MSAA modes: " << getSupportedMsaaModes(info.formatOps);
|
LOG_INFO << "Supported MSAA modes: " << getSupportedMsaaModes(info.formatOps);
|
||||||
LOG_DEBUG << "Supported resource formats:";
|
LOG_INFO << "Supported resource formats:";
|
||||||
for (const auto& formatOp : info.formatOps)
|
for (const auto& formatOp : info.formatOps)
|
||||||
{
|
{
|
||||||
LOG_DEBUG << " " << formatOp.second;
|
LOG_INFO << " " << formatOp.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
@ -20,6 +20,7 @@ namespace D3dDdi
|
|||||||
D3DNTHAL_D3DEXTENDEDCAPS d3dExtendedCaps;
|
D3DNTHAL_D3DEXTENDEDCAPS d3dExtendedCaps;
|
||||||
std::map<D3DDDIFORMAT, FORMATOP> formatOps;
|
std::map<D3DDDIFORMAT, FORMATOP> formatOps;
|
||||||
DWORD supportedZBufferBitDepths;
|
DWORD supportedZBufferBitDepths;
|
||||||
|
bool isMsaaDepthResolveSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
Adapter(const D3DDDIARG_OPENADAPTER& data);
|
Adapter(const D3DDDIARG_OPENADAPTER& data);
|
||||||
|
@ -28,6 +28,7 @@ namespace D3dDdi
|
|||||||
, m_adapter(adapter)
|
, m_adapter(adapter)
|
||||||
, m_device(device)
|
, m_device(device)
|
||||||
, m_eventQuery(nullptr)
|
, m_eventQuery(nullptr)
|
||||||
|
, m_depthStencil(nullptr)
|
||||||
, m_renderTarget(nullptr)
|
, m_renderTarget(nullptr)
|
||||||
, m_renderTargetSubResourceIndex(0)
|
, m_renderTargetSubResourceIndex(0)
|
||||||
, m_sharedPrimary(nullptr)
|
, m_sharedPrimary(nullptr)
|
||||||
@ -107,12 +108,21 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void Device::prepareForGpuWrite()
|
void Device::prepareForGpuWrite()
|
||||||
{
|
{
|
||||||
|
if (m_depthStencil)
|
||||||
|
{
|
||||||
|
m_depthStencil->prepareForGpuWrite(0);
|
||||||
|
}
|
||||||
if (m_renderTarget)
|
if (m_renderTarget)
|
||||||
{
|
{
|
||||||
m_renderTarget->prepareForGpuWrite(m_renderTargetSubResourceIndex);
|
m_renderTarget->prepareForGpuWrite(m_renderTargetSubResourceIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::setDepthStencil(HANDLE resource)
|
||||||
|
{
|
||||||
|
m_depthStencil = getResource(resource);
|
||||||
|
}
|
||||||
|
|
||||||
void Device::setGdiResourceHandle(HANDLE resource)
|
void Device::setGdiResourceHandle(HANDLE resource)
|
||||||
{
|
{
|
||||||
LOG_FUNC("Device::setGdiResourceHandle", resource);
|
LOG_FUNC("Device::setGdiResourceHandle", resource);
|
||||||
@ -166,19 +176,16 @@ namespace D3dDdi
|
|||||||
HRESULT Device::pfnClear(const D3DDDIARG_CLEAR* data, UINT numRect, const RECT* rect)
|
HRESULT Device::pfnClear(const D3DDDIARG_CLEAR* data, UINT numRect, const RECT* rect)
|
||||||
{
|
{
|
||||||
flushPrimitives();
|
flushPrimitives();
|
||||||
if (data->Flags & D3DCLEAR_TARGET)
|
prepareForGpuWrite();
|
||||||
{
|
|
||||||
setRenderTarget(m_state.getAppState().renderTarget);
|
|
||||||
prepareForGpuWrite();
|
|
||||||
}
|
|
||||||
m_state.flush();
|
m_state.flush();
|
||||||
|
|
||||||
if (m_renderTarget && rect)
|
if ((m_renderTarget || m_depthStencil) && rect)
|
||||||
{
|
{
|
||||||
std::vector<RECT> scaledRect(rect, rect + numRect);
|
std::vector<RECT> scaledRect(rect, rect + numRect);
|
||||||
|
auto resource = m_renderTarget ? m_renderTarget : m_depthStencil;
|
||||||
for (UINT i = 0; i < numRect; ++i)
|
for (UINT i = 0; i < numRect; ++i)
|
||||||
{
|
{
|
||||||
m_renderTarget->scaleRect(scaledRect[i]);
|
resource->scaleRect(scaledRect[i]);
|
||||||
}
|
}
|
||||||
return m_origVtable.pfnClear(m_device, data, numRect, scaledRect.data());
|
return m_origVtable.pfnClear(m_device, data, numRect, scaledRect.data());
|
||||||
}
|
}
|
||||||
@ -188,6 +195,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
HRESULT Device::pfnColorFill(const D3DDDIARG_COLORFILL* data)
|
HRESULT Device::pfnColorFill(const D3DDDIARG_COLORFILL* data)
|
||||||
{
|
{
|
||||||
|
flushPrimitives();
|
||||||
auto it = m_resources.find(data->hResource);
|
auto it = m_resources.find(data->hResource);
|
||||||
if (it != m_resources.end())
|
if (it != m_resources.end())
|
||||||
{
|
{
|
||||||
@ -226,6 +234,30 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT Device::pfnDepthFill(const D3DDDIARG_DEPTHFILL* data)
|
||||||
|
{
|
||||||
|
flushPrimitives();
|
||||||
|
auto resource = getResource(data->hResource);
|
||||||
|
auto customResource = resource->getCustomResource();
|
||||||
|
auto fi = getFormatInfo(resource->getFixedDesc().Format);
|
||||||
|
resource->prepareForGpuWrite(0);
|
||||||
|
|
||||||
|
m_state.setTempDepthStencil({ customResource ? *customResource : *resource });
|
||||||
|
|
||||||
|
RECT rect = data->DstRect;
|
||||||
|
resource->scaleRect(rect);
|
||||||
|
|
||||||
|
D3DDDIARG_CLEAR clear = {};
|
||||||
|
clear.Flags = D3DCLEAR_ZBUFFER;
|
||||||
|
clear.FillDepth = getComponentAsFloat(data->Depth, fi.depth);
|
||||||
|
if (0 != fi.stencil.bitCount)
|
||||||
|
{
|
||||||
|
clear.Flags |= D3DCLEAR_STENCIL;
|
||||||
|
clear.FillStencil = getComponent(data->Depth, fi.stencil);
|
||||||
|
}
|
||||||
|
return m_origVtable.pfnClear(m_device, &clear, 1, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT Device::pfnDestroyDevice()
|
HRESULT Device::pfnDestroyDevice()
|
||||||
{
|
{
|
||||||
auto device = m_device;
|
auto device = m_device;
|
||||||
@ -247,6 +279,15 @@ namespace D3dDdi
|
|||||||
D3DKMTReleaseProcessVidPnSourceOwners(GetCurrentProcess());
|
D3DKMTReleaseProcessVidPnSourceOwners(GetCurrentProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_renderTarget && resource == *m_renderTarget)
|
||||||
|
{
|
||||||
|
m_renderTarget = nullptr;
|
||||||
|
}
|
||||||
|
else if (m_depthStencil && resource == *m_depthStencil)
|
||||||
|
{
|
||||||
|
m_depthStencil = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT result = m_origVtable.pfnDestroyResource(m_device, resource);
|
HRESULT result = m_origVtable.pfnDestroyResource(m_device, resource);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
@ -373,7 +414,7 @@ namespace D3dDdi
|
|||||||
auto it = m_resources.find(data->hResource);
|
auto it = m_resources.find(data->hResource);
|
||||||
if (it != m_resources.end())
|
if (it != m_resources.end())
|
||||||
{
|
{
|
||||||
it->second->setPaletteHandle(data->PaletteHandle);
|
it->second->setPaletteHandle(data->PaletteHandle);
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ namespace D3dDdi
|
|||||||
HRESULT pfnColorFill(const D3DDDIARG_COLORFILL* data);
|
HRESULT pfnColorFill(const D3DDDIARG_COLORFILL* data);
|
||||||
HRESULT pfnCreateResource(D3DDDIARG_CREATERESOURCE* data);
|
HRESULT pfnCreateResource(D3DDDIARG_CREATERESOURCE* data);
|
||||||
HRESULT pfnCreateResource2(D3DDDIARG_CREATERESOURCE2* data);
|
HRESULT pfnCreateResource2(D3DDDIARG_CREATERESOURCE2* data);
|
||||||
|
HRESULT pfnDepthFill(const D3DDDIARG_DEPTHFILL* data);
|
||||||
HRESULT pfnDestroyDevice();
|
HRESULT pfnDestroyDevice();
|
||||||
HRESULT pfnDestroyResource(HANDLE resource);
|
HRESULT pfnDestroyResource(HANDLE resource);
|
||||||
HRESULT pfnDrawIndexedPrimitive2(const D3DDDIARG_DRAWINDEXEDPRIMITIVE2* data,
|
HRESULT pfnDrawIndexedPrimitive2(const D3DDDIARG_DRAWINDEXEDPRIMITIVE2* data,
|
||||||
@ -61,6 +62,7 @@ namespace D3dDdi
|
|||||||
HRESULT createPrivateResource(D3DDDIARG_CREATERESOURCE2& data);
|
HRESULT createPrivateResource(D3DDDIARG_CREATERESOURCE2& data);
|
||||||
void flushPrimitives() { m_drawPrimitive.flushPrimitives(); }
|
void flushPrimitives() { m_drawPrimitive.flushPrimitives(); }
|
||||||
void prepareForGpuWrite();
|
void prepareForGpuWrite();
|
||||||
|
void setDepthStencil(HANDLE resource);
|
||||||
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data);
|
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data);
|
||||||
void updateConfig();
|
void updateConfig();
|
||||||
void waitForIdle();
|
void waitForIdle();
|
||||||
@ -83,6 +85,7 @@ namespace D3dDdi
|
|||||||
HANDLE m_device;
|
HANDLE m_device;
|
||||||
HANDLE m_eventQuery;
|
HANDLE m_eventQuery;
|
||||||
std::map<HANDLE, std::unique_ptr<Resource>> m_resources;
|
std::map<HANDLE, std::unique_ptr<Resource>> m_resources;
|
||||||
|
Resource* m_depthStencil;
|
||||||
Resource* m_renderTarget;
|
Resource* m_renderTarget;
|
||||||
UINT m_renderTargetSubResourceIndex;
|
UINT m_renderTargetSubResourceIndex;
|
||||||
HANDLE m_sharedPrimary;
|
HANDLE m_sharedPrimary;
|
||||||
|
@ -54,6 +54,7 @@ namespace
|
|||||||
SET_DEVICE_FUNC(pfnColorFill);
|
SET_DEVICE_FUNC(pfnColorFill);
|
||||||
SET_DEVICE_FUNC(pfnCreateResource);
|
SET_DEVICE_FUNC(pfnCreateResource);
|
||||||
SET_DEVICE_FUNC(pfnCreateResource2);
|
SET_DEVICE_FUNC(pfnCreateResource2);
|
||||||
|
SET_DEVICE_FUNC(pfnDepthFill);
|
||||||
SET_DEVICE_FUNC(pfnDestroyDevice);
|
SET_DEVICE_FUNC(pfnDestroyDevice);
|
||||||
SET_DEVICE_FUNC(pfnDestroyResource);
|
SET_DEVICE_FUNC(pfnDestroyResource);
|
||||||
SET_DEVICE_FUNC(pfnDrawIndexedPrimitive2);
|
SET_DEVICE_FUNC(pfnDrawIndexedPrimitive2);
|
||||||
@ -94,7 +95,6 @@ namespace
|
|||||||
|
|
||||||
SET_FLUSH_PRIMITIVES_FUNC(pfnBufBlt);
|
SET_FLUSH_PRIMITIVES_FUNC(pfnBufBlt);
|
||||||
SET_FLUSH_PRIMITIVES_FUNC(pfnBufBlt1);
|
SET_FLUSH_PRIMITIVES_FUNC(pfnBufBlt1);
|
||||||
SET_FLUSH_PRIMITIVES_FUNC(pfnDepthFill);
|
|
||||||
SET_FLUSH_PRIMITIVES_FUNC(pfnDiscard);
|
SET_FLUSH_PRIMITIVES_FUNC(pfnDiscard);
|
||||||
SET_FLUSH_PRIMITIVES_FUNC(pfnGenerateMipSubLevels);
|
SET_FLUSH_PRIMITIVES_FUNC(pfnGenerateMipSubLevels);
|
||||||
SET_FLUSH_PRIMITIVES_FUNC(pfnSetClipPlane);
|
SET_FLUSH_PRIMITIVES_FUNC(pfnSetClipPlane);
|
||||||
|
@ -432,6 +432,7 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
m_app.depthStencil = *data;
|
m_app.depthStencil = *data;
|
||||||
m_changedStates |= CS_RENDER_TARGET;
|
m_changedStates |= CS_RENDER_TARGET;
|
||||||
|
m_device.setDepthStencil(data->hZBuffer);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,6 +470,7 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
m_app.renderTarget = *data;
|
m_app.renderTarget = *data;
|
||||||
m_changedStates |= CS_RENDER_TARGET;
|
m_changedStates |= CS_RENDER_TARGET;
|
||||||
|
m_device.setRenderTarget(*data);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,7 +753,6 @@ namespace D3dDdi
|
|||||||
void DeviceState::setTempRenderTarget(const D3DDDIARG_SETRENDERTARGET& renderTarget)
|
void DeviceState::setTempRenderTarget(const D3DDDIARG_SETRENDERTARGET& renderTarget)
|
||||||
{
|
{
|
||||||
setRenderTarget(renderTarget);
|
setRenderTarget(renderTarget);
|
||||||
m_device.setRenderTarget({});
|
|
||||||
m_changedStates |= CS_RENDER_TARGET;
|
m_changedStates |= CS_RENDER_TARGET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,7 +959,6 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
|
|
||||||
setRenderTarget(renderTarget);
|
setRenderTarget(renderTarget);
|
||||||
m_device.setRenderTarget(m_app.renderTarget);
|
|
||||||
setDepthStencil(depthStencil);
|
setDepthStencil(depthStencil);
|
||||||
setViewport(vp);
|
setViewport(vp);
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ namespace D3dDdi
|
|||||||
void disableTextureClamp(UINT stage);
|
void disableTextureClamp(UINT stage);
|
||||||
void flush();
|
void flush();
|
||||||
const State& getAppState() const { return m_app; }
|
const State& getAppState() const { return m_app; }
|
||||||
|
const State& getCurrentState() const { return m_current; }
|
||||||
Resource* getTextureResource(UINT stage);
|
Resource* getTextureResource(UINT stage);
|
||||||
const VertexDecl& getVertexDecl() const;
|
const VertexDecl& getVertexDecl() const;
|
||||||
HANDLE getVertexFixupDecl() const { return m_vsVertexFixup.get(); }
|
HANDLE getVertexFixupDecl() const { return m_vsVertexFixup.get(); }
|
||||||
|
@ -454,14 +454,10 @@ namespace D3dDdi
|
|||||||
HRESULT DrawPrimitive::draw(D3DDDIARG_DRAWPRIMITIVE data, const UINT* flagBuffer)
|
HRESULT DrawPrimitive::draw(D3DDDIARG_DRAWPRIMITIVE data, const UINT* flagBuffer)
|
||||||
{
|
{
|
||||||
auto& state = m_device.getState();
|
auto& state = m_device.getState();
|
||||||
if (!state.isLocked())
|
|
||||||
{
|
|
||||||
state.updateStreamSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto vertexCount = getVertexCount(data.PrimitiveType, data.PrimitiveCount);
|
auto vertexCount = getVertexCount(data.PrimitiveType, data.PrimitiveCount);
|
||||||
if (!state.isLocked())
|
if (!state.isLocked())
|
||||||
{
|
{
|
||||||
|
state.updateStreamSource();
|
||||||
if (m_streamSource.vertices && data.PrimitiveType >= D3DPT_TRIANGLELIST)
|
if (m_streamSource.vertices && data.PrimitiveType >= D3DPT_TRIANGLELIST)
|
||||||
{
|
{
|
||||||
bool spriteMode = isSprite(data.VStart, 0, 1, 2);
|
bool spriteMode = isSprite(data.VStart, 0, 1, 2);
|
||||||
@ -475,7 +471,6 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
state.setSpriteMode(false);
|
state.setSpriteMode(false);
|
||||||
}
|
}
|
||||||
m_device.setRenderTarget(state.getAppState().renderTarget);
|
|
||||||
m_device.prepareForGpuWrite();
|
m_device.prepareForGpuWrite();
|
||||||
state.flush();
|
state.flush();
|
||||||
}
|
}
|
||||||
@ -533,7 +528,6 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
state.setSpriteMode(false);
|
state.setSpriteMode(false);
|
||||||
}
|
}
|
||||||
m_device.setRenderTarget(state.getAppState().renderTarget);
|
|
||||||
m_device.prepareForGpuWrite();
|
m_device.prepareForGpuWrite();
|
||||||
state.flush();
|
state.flush();
|
||||||
}
|
}
|
||||||
@ -644,7 +638,10 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG << "Flushing " << m_batched.primitiveCount << " primitives of type " << m_batched.primitiveType;
|
LOG_DEBUG << "Flushing " << m_batched.primitiveCount << " primitives of type " << m_batched.primitiveType;
|
||||||
m_device.prepareForGpuWrite();
|
if (!m_device.getState().isLocked())
|
||||||
|
{
|
||||||
|
m_device.prepareForGpuWrite();
|
||||||
|
}
|
||||||
return m_batched.indices.empty() ? flush(flagBuffer) : flushIndexed(flagBuffer);
|
return m_batched.indices.empty() ? flush(flagBuffer) : flushIndexed(flagBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ namespace
|
|||||||
RgbFormatInfo(BYTE unusedBitCount, BYTE alphaBitCount, BYTE redBitCount, BYTE greenBitCount, BYTE blueBitCount)
|
RgbFormatInfo(BYTE unusedBitCount, BYTE alphaBitCount, BYTE redBitCount, BYTE greenBitCount, BYTE blueBitCount)
|
||||||
: FormatInfo(unusedBitCount, alphaBitCount, redBitCount, greenBitCount, blueBitCount)
|
: FormatInfo(unusedBitCount, alphaBitCount, redBitCount, greenBitCount, blueBitCount)
|
||||||
{
|
{
|
||||||
redPos = greenBitCount + blueBitCount;
|
red.pos = greenBitCount + blueBitCount;
|
||||||
greenPos = blueBitCount;
|
green.pos = blueBitCount;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,37 +25,67 @@ namespace
|
|||||||
BgrFormatInfo(BYTE unusedBitCount, BYTE alphaBitCount, BYTE blueBitCount, BYTE greenBitCount, BYTE redBitCount)
|
BgrFormatInfo(BYTE unusedBitCount, BYTE alphaBitCount, BYTE blueBitCount, BYTE greenBitCount, BYTE redBitCount)
|
||||||
: FormatInfo(unusedBitCount, alphaBitCount, redBitCount, greenBitCount, blueBitCount)
|
: FormatInfo(unusedBitCount, alphaBitCount, redBitCount, greenBitCount, blueBitCount)
|
||||||
{
|
{
|
||||||
greenPos = redBitCount;
|
green.pos = redBitCount;
|
||||||
bluePos = redBitCount + greenBitCount;
|
blue.pos = redBitCount + greenBitCount;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
float getComponent(D3DCOLOR color, BYTE bitCount, BYTE pos)
|
struct DxsFormatInfo : D3dDdi::FormatInfo
|
||||||
{
|
{
|
||||||
if (0 == bitCount)
|
DxsFormatInfo(BYTE depthBitCount, BYTE unusedBitCount, BYTE stencilBitCount)
|
||||||
|
: FormatInfo(unusedBitCount, depthBitCount, stencilBitCount)
|
||||||
{
|
{
|
||||||
return 0;
|
depth.pos = unusedBitCount + stencilBitCount;
|
||||||
|
unused.pos = stencilBitCount;
|
||||||
}
|
}
|
||||||
const UINT max = (1 << bitCount) - 1;
|
};
|
||||||
const UINT mask = max << pos;
|
|
||||||
return static_cast<float>((color & mask) >> pos) / max;
|
struct XsdFormatInfo : D3dDdi::FormatInfo
|
||||||
|
{
|
||||||
|
XsdFormatInfo(BYTE unusedBitCount, BYTE stencilBitCount, BYTE depthBitCount)
|
||||||
|
: FormatInfo(unusedBitCount, depthBitCount, stencilBitCount)
|
||||||
|
{
|
||||||
|
unused.pos = stencilBitCount + depthBitCount;
|
||||||
|
stencil.pos = depthBitCount;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DWORD getMask(const D3dDdi::FormatInfo::Component& component)
|
||||||
|
{
|
||||||
|
return ((1 << component.bitCount) - 1) << component.pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace D3dDdi
|
namespace D3dDdi
|
||||||
{
|
{
|
||||||
|
FormatInfo::FormatInfo()
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
}
|
||||||
|
|
||||||
FormatInfo::FormatInfo(BYTE unusedBitCount, BYTE alphaBitCount, BYTE redBitCount, BYTE greenBitCount, BYTE blueBitCount)
|
FormatInfo::FormatInfo(BYTE unusedBitCount, BYTE alphaBitCount, BYTE redBitCount, BYTE greenBitCount, BYTE blueBitCount)
|
||||||
: bitsPerPixel(unusedBitCount + alphaBitCount + redBitCount + greenBitCount + blueBitCount)
|
: bitsPerPixel(unusedBitCount + alphaBitCount + redBitCount + greenBitCount + blueBitCount)
|
||||||
, bytesPerPixel((bitsPerPixel + 7) / 8)
|
, bytesPerPixel((bitsPerPixel + 7) / 8)
|
||||||
, unusedBitCount(unusedBitCount)
|
, unused{ unusedBitCount, static_cast<BYTE>(alphaBitCount + redBitCount + greenBitCount + blueBitCount) }
|
||||||
, alphaBitCount(alphaBitCount)
|
, alpha{ alphaBitCount, static_cast<BYTE>(redBitCount + greenBitCount + blueBitCount) }
|
||||||
, alphaPos(redBitCount + greenBitCount + blueBitCount)
|
, red{ redBitCount, 0 }
|
||||||
, redBitCount(redBitCount)
|
, green{ greenBitCount, 0 }
|
||||||
, redPos(0)
|
, blue{ blueBitCount, 0 }
|
||||||
, greenBitCount(greenBitCount)
|
, depth{}
|
||||||
, greenPos(0)
|
, stencil{}
|
||||||
, blueBitCount(blueBitCount)
|
{
|
||||||
, bluePos(0)
|
}
|
||||||
|
|
||||||
|
FormatInfo::FormatInfo(BYTE unusedBitCount, BYTE depthBitCount, BYTE stencilBitCount)
|
||||||
|
: bitsPerPixel(unusedBitCount + depthBitCount + stencilBitCount)
|
||||||
|
, bytesPerPixel((bitsPerPixel + 7) / 8)
|
||||||
|
, unused{ unusedBitCount, 0 }
|
||||||
|
, alpha{}
|
||||||
|
, red{}
|
||||||
|
, green{}
|
||||||
|
, blue{}
|
||||||
|
, depth{ depthBitCount, 0 }
|
||||||
|
, stencil{ stencilBitCount, 0 }
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,27 +93,43 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
auto& src = *reinterpret_cast<ArgbColor*>(&srcColor);
|
auto& src = *reinterpret_cast<ArgbColor*>(&srcColor);
|
||||||
|
|
||||||
BYTE alpha = src.alpha >> (8 - dstFormatInfo.alphaBitCount);
|
BYTE alpha = src.alpha >> (8 - dstFormatInfo.alpha.bitCount);
|
||||||
BYTE red = src.red >> (8 - dstFormatInfo.redBitCount);
|
BYTE red = src.red >> (8 - dstFormatInfo.red.bitCount);
|
||||||
BYTE green = src.green >> (8 - dstFormatInfo.greenBitCount);
|
BYTE green = src.green >> (8 - dstFormatInfo.green.bitCount);
|
||||||
BYTE blue = src.blue >> (8 - dstFormatInfo.blueBitCount);
|
BYTE blue = src.blue >> (8 - dstFormatInfo.blue.bitCount);
|
||||||
|
|
||||||
return (alpha << dstFormatInfo.alphaPos) |
|
return (alpha << dstFormatInfo.alpha.pos) |
|
||||||
(red << dstFormatInfo.redPos) |
|
(red << dstFormatInfo.red.pos) |
|
||||||
(green << dstFormatInfo.greenPos) |
|
(green << dstFormatInfo.green.pos) |
|
||||||
(blue << dstFormatInfo.bluePos);
|
(blue << dstFormatInfo.blue.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceState::ShaderConstF convertToShaderConst(const FormatInfo& srcFormatInfo, D3DCOLOR srcColor)
|
DeviceState::ShaderConstF convertToShaderConst(const FormatInfo& srcFormatInfo, D3DCOLOR srcColor)
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
getComponent(srcColor, srcFormatInfo.redBitCount, srcFormatInfo.redPos),
|
getComponentAsFloat(srcColor, srcFormatInfo.red),
|
||||||
getComponent(srcColor, srcFormatInfo.greenBitCount, srcFormatInfo.greenPos),
|
getComponentAsFloat(srcColor, srcFormatInfo.green),
|
||||||
getComponent(srcColor, srcFormatInfo.blueBitCount, srcFormatInfo.bluePos),
|
getComponentAsFloat(srcColor, srcFormatInfo.blue),
|
||||||
getComponent(srcColor, srcFormatInfo.alphaBitCount, srcFormatInfo.alphaPos)
|
getComponentAsFloat(srcColor, srcFormatInfo.alpha)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD getComponent(D3DCOLOR color, const D3dDdi::FormatInfo::Component& component)
|
||||||
|
{
|
||||||
|
return (color & getMask(component)) >> component.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getComponentAsFloat(D3DCOLOR color, const D3dDdi::FormatInfo::Component& component)
|
||||||
|
{
|
||||||
|
if (0 == component.bitCount)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const UINT max = (1 << component.bitCount) - 1;
|
||||||
|
const UINT mask = max << component.pos;
|
||||||
|
return static_cast<float>((color & mask) >> component.pos) / max;
|
||||||
|
}
|
||||||
|
|
||||||
FormatInfo getFormatInfo(D3DDDIFORMAT format)
|
FormatInfo getFormatInfo(D3DDDIFORMAT format)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
@ -109,6 +155,17 @@ namespace D3dDdi
|
|||||||
case D3DDDIFMT_A8B8G8R8: return BgrFormatInfo(0, 8, 8, 8, 8);
|
case D3DDDIFMT_A8B8G8R8: return BgrFormatInfo(0, 8, 8, 8, 8);
|
||||||
case D3DDDIFMT_X8B8G8R8: return BgrFormatInfo(8, 0, 8, 8, 8);
|
case D3DDDIFMT_X8B8G8R8: return BgrFormatInfo(8, 0, 8, 8, 8);
|
||||||
|
|
||||||
|
case D3DDDIFMT_D32: return DxsFormatInfo(32, 0, 0);
|
||||||
|
case D3DDDIFMT_D15S1: return DxsFormatInfo(15, 0, 1);
|
||||||
|
case D3DDDIFMT_D24S8: return DxsFormatInfo(24, 0, 8);
|
||||||
|
case D3DDDIFMT_D24X8: return DxsFormatInfo(24, 8, 0);
|
||||||
|
case D3DDDIFMT_D24X4S4: return DxsFormatInfo(24, 4, 4);
|
||||||
|
case D3DDDIFMT_D16: return DxsFormatInfo(16, 0, 0);
|
||||||
|
case D3DDDIFMT_S1D15: return XsdFormatInfo(0, 1, 15);
|
||||||
|
case D3DDDIFMT_S8D24: return XsdFormatInfo(0, 8, 24);
|
||||||
|
case D3DDDIFMT_X8D24: return XsdFormatInfo(8, 0, 24);
|
||||||
|
case D3DDDIFMT_X4S4D24: return XsdFormatInfo(4, 4, 24);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return FormatInfo();
|
return FormatInfo();
|
||||||
}
|
}
|
||||||
@ -124,18 +181,34 @@ namespace D3dDdi
|
|||||||
|
|
||||||
DDPIXELFORMAT pf = {};
|
DDPIXELFORMAT pf = {};
|
||||||
pf.dwSize = sizeof(pf);
|
pf.dwSize = sizeof(pf);
|
||||||
pf.dwRGBBitCount = info.bitsPerPixel;
|
if (0 != info.depth.bitCount)
|
||||||
if (0 != pf.dwRGBBitCount)
|
|
||||||
{
|
{
|
||||||
pf.dwFlags = DDPF_RGB;
|
pf.dwFlags = DDPF_ZBUFFER;
|
||||||
pf.dwRBitMask = (0xFF >> (8 - info.redBitCount)) << info.redPos;
|
pf.dwZBufferBitDepth = info.depth.bitCount;
|
||||||
pf.dwGBitMask = (0xFF >> (8 - info.greenBitCount)) << info.greenPos;
|
pf.dwZBitMask = getMask(info.depth);
|
||||||
pf.dwBBitMask = (0xFF >> (8 - info.blueBitCount)) << info.bluePos;
|
if (0 != info.stencil.bitCount)
|
||||||
|
{
|
||||||
|
pf.dwFlags |= DDPF_STENCILBUFFER;
|
||||||
|
pf.dwZBufferBitDepth += info.stencil.bitCount;
|
||||||
|
pf.dwStencilBitDepth = info.stencil.bitCount;
|
||||||
|
pf.dwStencilBitMask = getMask(info.stencil);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (0 != info.alphaBitCount)
|
else
|
||||||
{
|
{
|
||||||
pf.dwFlags |= (0 == pf.dwFlags) ? DDPF_ALPHA : DDPF_ALPHAPIXELS;
|
pf.dwRGBBitCount = info.bitsPerPixel;
|
||||||
pf.dwRGBAlphaBitMask = (0xFF >> (8 - info.alphaBitCount)) << info.alphaPos;
|
if (info.bitsPerPixel > info.alpha.bitCount)
|
||||||
|
{
|
||||||
|
pf.dwFlags = DDPF_RGB;
|
||||||
|
pf.dwRBitMask = getMask(info.red);;
|
||||||
|
pf.dwGBitMask = getMask(info.green);
|
||||||
|
pf.dwBBitMask = getMask(info.blue);
|
||||||
|
}
|
||||||
|
if (0 != info.alpha.bitCount)
|
||||||
|
{
|
||||||
|
pf.dwFlags |= (0 == pf.dwFlags) ? DDPF_ALPHA : DDPF_ALPHAPIXELS;
|
||||||
|
pf.dwRGBAlphaBitMask = getMask(info.alpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return pf;
|
return pf;
|
||||||
}
|
}
|
||||||
|
@ -7,26 +7,37 @@
|
|||||||
|
|
||||||
namespace D3dDdi
|
namespace D3dDdi
|
||||||
{
|
{
|
||||||
|
static const auto FOURCC_RESZ = static_cast<D3DDDIFORMAT>(MAKEFOURCC('R', 'E', 'S', 'Z'));
|
||||||
|
static const auto FOURCC_INTZ = static_cast<D3DDDIFORMAT>(MAKEFOURCC('I', 'N', 'T', 'Z'));
|
||||||
|
static const auto FOURCC_NULL = static_cast<D3DDDIFORMAT>(MAKEFOURCC('N', 'U', 'L', 'L'));
|
||||||
|
|
||||||
struct FormatInfo
|
struct FormatInfo
|
||||||
{
|
{
|
||||||
|
struct Component
|
||||||
|
{
|
||||||
|
BYTE bitCount;
|
||||||
|
BYTE pos;
|
||||||
|
};
|
||||||
|
|
||||||
BYTE bitsPerPixel;
|
BYTE bitsPerPixel;
|
||||||
BYTE bytesPerPixel;
|
BYTE bytesPerPixel;
|
||||||
BYTE unusedBitCount;
|
Component unused;
|
||||||
BYTE alphaBitCount;
|
Component alpha;
|
||||||
BYTE alphaPos;
|
Component red;
|
||||||
BYTE redBitCount;
|
Component green;
|
||||||
BYTE redPos;
|
Component blue;
|
||||||
BYTE greenBitCount;
|
Component depth;
|
||||||
BYTE greenPos;
|
Component stencil;
|
||||||
BYTE blueBitCount;
|
|
||||||
BYTE bluePos;
|
|
||||||
|
|
||||||
FormatInfo(BYTE unusedBitCount = 0, BYTE alphaBitCount = 0,
|
FormatInfo();
|
||||||
BYTE redBitCount = 0, BYTE greenBitCount = 0, BYTE blueBitCount = 0);
|
FormatInfo(BYTE unusedBitCount, BYTE alphaBitCount, BYTE redBitCount, BYTE greenBitCount, BYTE blueBitCount);
|
||||||
|
FormatInfo(BYTE unusedBitCount, BYTE depthBitCount, BYTE stencilBitCount);
|
||||||
};
|
};
|
||||||
|
|
||||||
D3DCOLOR convertFrom32Bit(const FormatInfo& dstFormatInfo, D3DCOLOR srcColor);
|
D3DCOLOR convertFrom32Bit(const FormatInfo& dstFormatInfo, D3DCOLOR srcColor);
|
||||||
DeviceState::ShaderConstF convertToShaderConst(const FormatInfo& srcFormatInfo, D3DCOLOR srcColor);
|
DeviceState::ShaderConstF convertToShaderConst(const FormatInfo& srcFormatInfo, D3DCOLOR srcColor);
|
||||||
|
DWORD getComponent(D3DCOLOR color, const D3dDdi::FormatInfo::Component& component);
|
||||||
|
float getComponentAsFloat(D3DCOLOR color, const D3dDdi::FormatInfo::Component& component);
|
||||||
FormatInfo getFormatInfo(D3DDDIFORMAT format);
|
FormatInfo getFormatInfo(D3DDDIFORMAT format);
|
||||||
DDPIXELFORMAT getPixelFormat(D3DDDIFORMAT format);
|
DDPIXELFORMAT getPixelFormat(D3DDDIFORMAT format);
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,15 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEVERTEXSHADERDEC
|
|||||||
<< val.ShaderHandle;
|
<< val.ShaderHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DEPTHFILL& val)
|
||||||
|
{
|
||||||
|
return Compat::LogStruct(os)
|
||||||
|
<< val.hResource
|
||||||
|
<< val.SubResourceIndex
|
||||||
|
<< val.DstRect
|
||||||
|
<< Compat::hex(val.Depth);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE& val)
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE& val)
|
||||||
{
|
{
|
||||||
return Compat::LogStruct(os)
|
return Compat::LogStruct(os)
|
||||||
|
@ -16,6 +16,7 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_COLORFILL& val);
|
|||||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE& val);
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE& val);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE2& val);
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE2& val);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEVERTEXSHADERDECL& val);
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEVERTEXSHADERDECL& val);
|
||||||
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DEPTHFILL& val);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE& val);
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE& val);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE2& val);
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE2& val);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWPRIMITIVE& val);
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWPRIMITIVE& val);
|
||||||
|
@ -94,6 +94,12 @@ namespace
|
|||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, p);
|
HeapFree(GetProcessHeap(), 0, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logUnsupportedMsaaDepthBufferResolve()
|
||||||
|
{
|
||||||
|
LOG_ONCE("Warning: Resolving multisampled depth buffers is not supported by the GPU. "
|
||||||
|
"Disable antialiasing if experiencing visual glitches.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace D3dDdi
|
namespace D3dDdi
|
||||||
@ -115,6 +121,7 @@ namespace D3dDdi
|
|||||||
, m_lockRefSurface{}
|
, m_lockRefSurface{}
|
||||||
, m_msaaSurface{}
|
, m_msaaSurface{}
|
||||||
, m_msaaResolvedSurface{}
|
, m_msaaResolvedSurface{}
|
||||||
|
, m_nullSurface{}
|
||||||
, m_formatConfig(D3DDDIFMT_UNKNOWN)
|
, m_formatConfig(D3DDDIFMT_UNKNOWN)
|
||||||
, m_multiSampleConfig{ D3DDDIMULTISAMPLE_NONE, 0 }
|
, m_multiSampleConfig{ D3DDDIMULTISAMPLE_NONE, 0 }
|
||||||
, m_scaledSize{}
|
, m_scaledSize{}
|
||||||
@ -153,8 +160,18 @@ namespace D3dDdi
|
|||||||
|
|
||||||
updateConfig();
|
updateConfig();
|
||||||
|
|
||||||
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool &&
|
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && m_origData.Flags.ZBuffer)
|
||||||
0 != m_formatInfo.bytesPerPixel)
|
{
|
||||||
|
m_lockData.resize(m_origData.SurfCount);
|
||||||
|
for (UINT i = 0; i < m_origData.SurfCount; ++i)
|
||||||
|
{
|
||||||
|
m_lockData[i].isSysMemUpToDate = true;
|
||||||
|
m_lockData[i].isVidMemUpToDate = true;
|
||||||
|
m_lockData[i].isMsaaUpToDate = m_msaaSurface.resource;
|
||||||
|
m_lockData[i].isMsaaResolvedUpToDate = m_msaaResolvedSurface.resource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool && 0 != m_formatInfo.bytesPerPixel)
|
||||||
{
|
{
|
||||||
m_lockData.resize(m_origData.SurfCount);
|
m_lockData.resize(m_origData.SurfCount);
|
||||||
for (UINT i = 0; i < m_origData.SurfCount; ++i)
|
for (UINT i = 0; i < m_origData.SurfCount; ++i)
|
||||||
@ -190,6 +207,13 @@ namespace D3dDdi
|
|||||||
|
|
||||||
HRESULT Resource::blt(D3DDDIARG_BLT data)
|
HRESULT Resource::blt(D3DDDIARG_BLT data)
|
||||||
{
|
{
|
||||||
|
if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource &&
|
||||||
|
!m_device.getAdapter().getInfo().isMsaaDepthResolveSupported)
|
||||||
|
{
|
||||||
|
logUnsupportedMsaaDepthBufferResolve();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isValidRect(data.DstSubResourceIndex, data.DstRect))
|
if (!isValidRect(data.DstSubResourceIndex, data.DstRect))
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@ -350,6 +374,11 @@ namespace D3dDdi
|
|||||||
|
|
||||||
HRESULT Resource::bltViaGpu(D3DDDIARG_BLT data, Resource& srcResource)
|
HRESULT Resource::bltViaGpu(D3DDDIARG_BLT data, Resource& srcResource)
|
||||||
{
|
{
|
||||||
|
if (srcResource.m_lockResource)
|
||||||
|
{
|
||||||
|
srcResource.loadFromLockRefResource(data.SrcSubResourceIndex);
|
||||||
|
}
|
||||||
|
|
||||||
Resource* srcRes = &srcResource;
|
Resource* srcRes = &srcResource;
|
||||||
if (m_msaaResolvedSurface.resource && srcResource.m_msaaResolvedSurface.resource &&
|
if (m_msaaResolvedSurface.resource && srcResource.m_msaaResolvedSurface.resource &&
|
||||||
(srcResource.m_lockData[data.SrcSubResourceIndex].isMsaaResolvedUpToDate ||
|
(srcResource.m_lockData[data.SrcSubResourceIndex].isMsaaResolvedUpToDate ||
|
||||||
@ -359,7 +388,10 @@ namespace D3dDdi
|
|||||||
srcRes = srcResource.m_msaaResolvedSurface.resource;
|
srcRes = srcResource.m_msaaResolvedSurface.resource;
|
||||||
data.hSrcResource = *srcRes;
|
data.hSrcResource = *srcRes;
|
||||||
srcResource.scaleRect(data.SrcRect);
|
srcResource.scaleRect(data.SrcRect);
|
||||||
loadMsaaResolvedResource(data.DstSubResourceIndex);
|
if (!m_lockData[data.DstSubResourceIndex].isMsaaUpToDate)
|
||||||
|
{
|
||||||
|
loadMsaaResolvedResource(data.DstSubResourceIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -369,7 +401,9 @@ namespace D3dDdi
|
|||||||
Resource& dstRes = prepareForBltDst(data);
|
Resource& dstRes = prepareForBltDst(data);
|
||||||
|
|
||||||
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
||||||
(m_fixedData.Flags.RenderTarget || data.Flags.SrcColorKey || data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown) &&
|
(m_fixedData.Flags.ZBuffer && &dstRes == m_msaaSurface.resource && m_nullSurface.resource ||
|
||||||
|
m_fixedData.Flags.RenderTarget || data.Flags.SrcColorKey ||
|
||||||
|
data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown) &&
|
||||||
SUCCEEDED(shaderBlt(data, dstRes, *srcRes)))
|
SUCCEEDED(shaderBlt(data, dstRes, *srcRes)))
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@ -634,37 +668,27 @@ namespace D3dDdi
|
|||||||
m_isClampable = false;
|
m_isClampable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resource::downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight)
|
void Resource::downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight, bool dryRun)
|
||||||
{
|
{
|
||||||
LONG newSrcWidth = (srcWidth + 1) / 2;
|
while (srcWidth > 2 * dstWidth || srcHeight > 2 * dstHeight)
|
||||||
if (newSrcWidth <= dstWidth)
|
|
||||||
{
|
{
|
||||||
newSrcWidth = srcWidth;
|
const LONG newSrcWidth = max(dstWidth, (srcWidth + 1) / 2);
|
||||||
}
|
const LONG newSrcHeight = max(dstHeight, (srcHeight + 1) / 2);
|
||||||
|
auto& nextRt = getNextRenderTarget(rt, newSrcWidth, newSrcHeight);
|
||||||
|
if (!nextRt.resource)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LONG newSrcHeight = (srcHeight + 1) / 2;
|
if (!dryRun)
|
||||||
if (newSrcHeight <= dstHeight)
|
{
|
||||||
{
|
m_device.getShaderBlitter().textureBlt(*nextRt.resource, 0, { 0, 0, newSrcWidth, newSrcHeight },
|
||||||
newSrcHeight = srcHeight;
|
*rt, 0, { 0, 0, srcWidth, srcHeight }, D3DTEXF_LINEAR);
|
||||||
|
}
|
||||||
|
rt = nextRt.resource;
|
||||||
|
srcWidth = newSrcWidth;
|
||||||
|
srcHeight = newSrcHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newSrcWidth == srcWidth && newSrcHeight == srcHeight)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& nextRt = getNextRenderTarget(rt, newSrcWidth, newSrcHeight);
|
|
||||||
if (!nextRt.resource)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_device.getShaderBlitter().textureBlt(*nextRt.resource, 0, { 0, 0, newSrcWidth, newSrcHeight },
|
|
||||||
*rt, 0, { 0, 0, srcWidth, srcHeight }, D3DTEXF_LINEAR);
|
|
||||||
rt = nextRt.resource;
|
|
||||||
srcWidth = newSrcWidth;
|
|
||||||
srcHeight = newSrcHeight;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::fixResourceData()
|
void Resource::fixResourceData()
|
||||||
@ -686,6 +710,10 @@ namespace D3dDdi
|
|||||||
if (D3DDDIFMT_UNKNOWN != g_formatOverride)
|
if (D3DDDIFMT_UNKNOWN != g_formatOverride)
|
||||||
{
|
{
|
||||||
m_fixedData.Format = g_formatOverride;
|
m_fixedData.Format = g_formatOverride;
|
||||||
|
if (m_fixedData.Flags.ZBuffer)
|
||||||
|
{
|
||||||
|
m_fixedData.Flags.Texture = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (D3DDDIMULTISAMPLE_NONE != g_msaaOverride.first)
|
if (D3DDDIMULTISAMPLE_NONE != g_msaaOverride.first)
|
||||||
@ -744,10 +772,10 @@ namespace D3dDdi
|
|||||||
const SurfaceRepository::Surface& Resource::getNextRenderTarget(Resource* currentRt, DWORD width, DWORD height)
|
const SurfaceRepository::Surface& Resource::getNextRenderTarget(Resource* currentRt, DWORD width, DWORD height)
|
||||||
{
|
{
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
||||||
auto nextRt = &repo.getTempRenderTarget(width, height, 1);
|
auto nextRt = &repo.getTempRenderTarget(width, height, 0);
|
||||||
if (nextRt->resource == currentRt)
|
if (nextRt->resource == currentRt)
|
||||||
{
|
{
|
||||||
nextRt = &repo.getTempRenderTarget(width, height, 0);
|
nextRt = &repo.getTempRenderTarget(width, height, 1);
|
||||||
}
|
}
|
||||||
return *nextRt;
|
return *nextRt;
|
||||||
}
|
}
|
||||||
@ -814,7 +842,19 @@ namespace D3dDdi
|
|||||||
if (m_msaaResolvedSurface.resource)
|
if (m_msaaResolvedSurface.resource)
|
||||||
{
|
{
|
||||||
loadMsaaResolvedResource(subResourceIndex);
|
loadMsaaResolvedResource(subResourceIndex);
|
||||||
copySubResource(*m_msaaSurface.resource, *m_msaaResolvedSurface.resource, subResourceIndex);
|
if (m_fixedData.Flags.ZBuffer)
|
||||||
|
{
|
||||||
|
if (m_nullSurface.resource)
|
||||||
|
{
|
||||||
|
RECT r = m_msaaResolvedSurface.resource->getRect(0);
|
||||||
|
m_device.getShaderBlitter().depthBlt(
|
||||||
|
*m_msaaSurface.resource, r, *m_msaaResolvedSurface.resource, r, *m_nullSurface.resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copySubResource(*m_msaaSurface.resource, *m_msaaResolvedSurface.resource, subResourceIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -828,19 +868,35 @@ namespace D3dDdi
|
|||||||
void Resource::loadMsaaResolvedResource(UINT subResourceIndex)
|
void Resource::loadMsaaResolvedResource(UINT subResourceIndex)
|
||||||
{
|
{
|
||||||
loadFromLockRefResource(subResourceIndex);
|
loadFromLockRefResource(subResourceIndex);
|
||||||
if (!m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
|
if (m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
|
||||||
{
|
{
|
||||||
if (m_lockData[subResourceIndex].isMsaaUpToDate)
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_lockData[subResourceIndex].isMsaaUpToDate)
|
||||||
|
{
|
||||||
|
if (m_fixedData.Flags.ZBuffer)
|
||||||
{
|
{
|
||||||
copySubResource(*m_msaaResolvedSurface.resource, *m_msaaSurface.resource, subResourceIndex);
|
if (m_device.getAdapter().getInfo().isMsaaDepthResolveSupported)
|
||||||
|
{
|
||||||
|
resolveMsaaDepthBuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logUnsupportedMsaaDepthBufferResolve();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loadVidMemResource(subResourceIndex);
|
copySubResource(*m_msaaResolvedSurface.resource, *m_msaaSurface.resource, subResourceIndex);
|
||||||
copySubResource(*m_msaaResolvedSurface.resource, *this, subResourceIndex);
|
|
||||||
}
|
}
|
||||||
m_lockData[subResourceIndex].isMsaaResolvedUpToDate = true;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loadVidMemResource(subResourceIndex);
|
||||||
|
copySubResource(*m_msaaResolvedSurface.resource, *this, subResourceIndex);
|
||||||
|
}
|
||||||
|
m_lockData[subResourceIndex].isMsaaResolvedUpToDate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::loadSysMemResource(UINT subResourceIndex)
|
void Resource::loadSysMemResource(UINT subResourceIndex)
|
||||||
@ -856,20 +912,59 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void Resource::loadVidMemResource(UINT subResourceIndex)
|
void Resource::loadVidMemResource(UINT subResourceIndex)
|
||||||
{
|
{
|
||||||
if (!m_lockData[subResourceIndex].isVidMemUpToDate)
|
if (m_lockData[subResourceIndex].isVidMemUpToDate)
|
||||||
{
|
{
|
||||||
if (m_lockData[subResourceIndex].isMsaaUpToDate || m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
|
return;
|
||||||
|
}
|
||||||
|
m_lockData[subResourceIndex].isVidMemUpToDate = true;
|
||||||
|
|
||||||
|
if (m_lockData[subResourceIndex].isMsaaUpToDate || m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
|
||||||
|
{
|
||||||
|
loadMsaaResolvedResource(subResourceIndex);
|
||||||
|
if (!m_fixedData.Flags.RenderTarget)
|
||||||
{
|
{
|
||||||
loadMsaaResolvedResource(subResourceIndex);
|
|
||||||
copySubResource(*this, *m_msaaResolvedSurface.resource, subResourceIndex);
|
copySubResource(*this, *m_msaaResolvedSurface.resource, subResourceIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto src = m_msaaResolvedSurface.resource;
|
||||||
|
auto srcRect = src->getRect(subResourceIndex);
|
||||||
|
auto dstRect = getRect(subResourceIndex);
|
||||||
|
|
||||||
|
SurfaceRepository::enableSurfaceCheck(false);
|
||||||
|
downscale(src, srcRect.right, srcRect.bottom, dstRect.right, dstRect.bottom);
|
||||||
|
auto srcIndex = src == m_msaaResolvedSurface.resource ? subResourceIndex : 0;
|
||||||
|
|
||||||
|
if (dstRect != srcRect &&
|
||||||
|
!(m_device.getAdapter().getInfo().formatOps.at(m_fixedData.Format).Operations & FORMATOP_SRGBWRITE))
|
||||||
|
{
|
||||||
|
auto nextRt = getNextRenderTarget(src, dstRect.right, dstRect.bottom).resource;
|
||||||
|
if (nextRt)
|
||||||
|
{
|
||||||
|
m_device.getShaderBlitter().textureBlt(*nextRt, 0, dstRect,
|
||||||
|
*src, srcIndex, srcRect, D3DTEXF_LINEAR);
|
||||||
|
src = nextRt;
|
||||||
|
srcRect = dstRect;
|
||||||
|
srcIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SurfaceRepository::enableSurfaceCheck(true);
|
||||||
|
|
||||||
|
if (dstRect == srcRect)
|
||||||
|
{
|
||||||
|
copySubResourceRegion(m_handle, subResourceIndex, dstRect, *src, srcIndex, srcRect);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
copySubResource(*this, m_lockResource.get(), subResourceIndex);
|
m_device.getShaderBlitter().textureBlt(*this, subResourceIndex, dstRect,
|
||||||
notifyLock(subResourceIndex);
|
*src, srcIndex, srcRect, D3DTEXF_LINEAR);
|
||||||
m_lockData[subResourceIndex].isRefLocked = false;
|
|
||||||
}
|
}
|
||||||
m_lockData[subResourceIndex].isVidMemUpToDate = true;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copySubResource(*this, m_lockResource.get(), subResourceIndex);
|
||||||
|
notifyLock(subResourceIndex);
|
||||||
|
m_lockData[subResourceIndex].isRefLocked = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,6 +991,16 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
m_isPalettizedTextureUpToDate = false;
|
m_isPalettizedTextureUpToDate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_fixedData.Flags.ZBuffer && m_msaaResolvedSurface.resource)
|
||||||
|
{
|
||||||
|
loadVidMemResource(0);
|
||||||
|
if (!data.Flags.ReadOnly)
|
||||||
|
{
|
||||||
|
m_lockData[0].isMsaaUpToDate = false;
|
||||||
|
m_lockData[0].isMsaaResolvedUpToDate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return m_device.getOrigVtable().pfnLock(m_device, &data);
|
return m_device.getOrigVtable().pfnLock(m_device, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,7 +1031,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
Resource& Resource::prepareForBltSrc(const D3DDDIARG_BLT& data)
|
Resource& Resource::prepareForBltSrc(const D3DDDIARG_BLT& data)
|
||||||
{
|
{
|
||||||
if (m_lockResource)
|
if (m_lockResource || m_msaaResolvedSurface.resource)
|
||||||
{
|
{
|
||||||
loadVidMemResource(data.SrcSubResourceIndex);
|
loadVidMemResource(data.SrcSubResourceIndex);
|
||||||
}
|
}
|
||||||
@ -941,7 +1046,7 @@ namespace D3dDdi
|
|||||||
Resource& Resource::prepareForBltDst(HANDLE& resource, UINT subResourceIndex, RECT& rect)
|
Resource& Resource::prepareForBltDst(HANDLE& resource, UINT subResourceIndex, RECT& rect)
|
||||||
{
|
{
|
||||||
m_isPalettizedTextureUpToDate = false;
|
m_isPalettizedTextureUpToDate = false;
|
||||||
if (m_lockResource)
|
if (m_lockResource || m_msaaResolvedSurface.resource)
|
||||||
{
|
{
|
||||||
loadFromLockRefResource(subResourceIndex);
|
loadFromLockRefResource(subResourceIndex);
|
||||||
if (m_lockData[subResourceIndex].isMsaaUpToDate)
|
if (m_lockData[subResourceIndex].isMsaaUpToDate)
|
||||||
@ -1000,6 +1105,7 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
if (m_lockResource)
|
if (m_lockResource)
|
||||||
{
|
{
|
||||||
|
loadFromLockRefResource(subResourceIndex);
|
||||||
if (m_msaaResolvedSurface.resource)
|
if (m_msaaResolvedSurface.resource)
|
||||||
{
|
{
|
||||||
loadMsaaResolvedResource(subResourceIndex);
|
loadMsaaResolvedResource(subResourceIndex);
|
||||||
@ -1015,7 +1121,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void Resource::prepareForGpuWrite(UINT subResourceIndex)
|
void Resource::prepareForGpuWrite(UINT subResourceIndex)
|
||||||
{
|
{
|
||||||
if (m_lockResource)
|
if (m_lockResource || m_msaaResolvedSurface.resource)
|
||||||
{
|
{
|
||||||
if (m_msaaSurface.resource)
|
if (m_msaaSurface.resource)
|
||||||
{
|
{
|
||||||
@ -1113,9 +1219,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
const LONG dstWidth = data.DstRect.right - data.DstRect.left;
|
const LONG dstWidth = data.DstRect.right - data.DstRect.left;
|
||||||
const LONG dstHeight = data.DstRect.bottom - data.DstRect.top;
|
const LONG dstHeight = data.DstRect.bottom - data.DstRect.top;
|
||||||
while (downscale(rt, data.SrcRect.right, data.SrcRect.bottom, dstWidth, dstHeight))
|
downscale(rt, data.SrcRect.right, data.SrcRect.bottom, dstWidth, dstHeight);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const SurfaceRepository::Surface* rtGamma = nullptr;
|
const SurfaceRepository::Surface* rtGamma = nullptr;
|
||||||
if (!ShaderBlitter::isGammaRampDefault() &&
|
if (!ShaderBlitter::isGammaRampDefault() &&
|
||||||
@ -1214,6 +1318,17 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Resource::resolveMsaaDepthBuffer()
|
||||||
|
{
|
||||||
|
LOG_FUNC("Resource::resolveMsaaDepthBuffer");
|
||||||
|
auto& state = m_device.getState();
|
||||||
|
state.setTempDepthStencil({ *m_msaaSurface.resource });
|
||||||
|
state.setTempTexture(0, *m_msaaResolvedSurface.resource);
|
||||||
|
|
||||||
|
const UINT RESZ_CODE = 0x7fa05000;
|
||||||
|
state.setTempRenderState({ D3DDDIRS_POINTSIZE, RESZ_CODE });
|
||||||
|
}
|
||||||
|
|
||||||
void Resource::scaleRect(RECT& rect)
|
void Resource::scaleRect(RECT& rect)
|
||||||
{
|
{
|
||||||
const LONG origWidth = m_fixedData.pSurfList[0].Width;
|
const LONG origWidth = m_fixedData.pSurfList[0].Width;
|
||||||
@ -1310,13 +1425,15 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
DWORD width = data.SrcRect.right - data.SrcRect.left;
|
DWORD width = data.SrcRect.right - data.SrcRect.left;
|
||||||
DWORD height = data.SrcRect.bottom - data.SrcRect.top;
|
DWORD height = data.SrcRect.bottom - data.SrcRect.top;
|
||||||
auto& texture = repo.getTempTexture(width, height, getPixelFormat(srcResource.m_fixedData.Format));
|
auto texture = m_fixedData.Flags.ZBuffer
|
||||||
if (!texture.resource)
|
? m_msaaResolvedSurface.resource
|
||||||
|
: repo.getTempTexture(width, height, getPixelFormat(srcResource.m_fixedData.Format)).resource;
|
||||||
|
if (!texture)
|
||||||
{
|
{
|
||||||
return LOG_RESULT(E_OUTOFMEMORY);
|
return LOG_RESULT(E_OUTOFMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
srcRes = texture.resource;
|
srcRes = texture;
|
||||||
srcIndex = 0;
|
srcIndex = 0;
|
||||||
srcRect = { 0, 0, static_cast<LONG>(width), static_cast<LONG>(height) };
|
srcRect = { 0, 0, static_cast<LONG>(width), static_cast<LONG>(height) };
|
||||||
|
|
||||||
@ -1371,8 +1488,15 @@ namespace D3dDdi
|
|||||||
auto ck = data.Flags.SrcColorKey
|
auto ck = data.Flags.SrcColorKey
|
||||||
? convertToShaderConst(srcResource.m_formatInfo, data.ColorKey)
|
? convertToShaderConst(srcResource.m_formatInfo, data.ColorKey)
|
||||||
: DeviceState::ShaderConstF{};
|
: DeviceState::ShaderConstF{};
|
||||||
m_device.getShaderBlitter().textureBlt(*dstRes, dstIndex, dstRect, *srcRes, srcIndex, srcRect,
|
if (m_fixedData.Flags.ZBuffer)
|
||||||
D3DTEXF_POINT, data.Flags.SrcColorKey ? &ck : nullptr);
|
{
|
||||||
|
m_device.getShaderBlitter().depthBlt(*dstRes, dstRect, *srcRes, srcRect, *m_nullSurface.resource);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_device.getShaderBlitter().textureBlt(*dstRes, dstIndex, dstRect, *srcRes, srcIndex, srcRect,
|
||||||
|
D3DTEXF_POINT, data.Flags.SrcColorKey ? &ck : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_fixedData.Flags.RenderTarget)
|
if (!m_fixedData.Flags.RenderTarget)
|
||||||
{
|
{
|
||||||
@ -1413,8 +1537,7 @@ namespace D3dDdi
|
|||||||
m_formatConfig = formatConfig;
|
m_formatConfig = formatConfig;
|
||||||
m_scaledSize = scaledSize;
|
m_scaledSize = scaledSize;
|
||||||
|
|
||||||
if ((m_fixedData.Flags.RenderTarget || m_isPrimary) &&
|
if (m_msaaSurface.resource || m_msaaResolvedSurface.resource)
|
||||||
(m_msaaSurface.resource || m_msaaResolvedSurface.resource))
|
|
||||||
{
|
{
|
||||||
for (UINT i = 0; i < m_lockData.size(); ++i)
|
for (UINT i = 0; i < m_lockData.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -1430,55 +1553,65 @@ namespace D3dDdi
|
|||||||
|
|
||||||
m_msaaSurface = {};
|
m_msaaSurface = {};
|
||||||
m_msaaResolvedSurface = {};
|
m_msaaResolvedSurface = {};
|
||||||
|
m_nullSurface = {};
|
||||||
m_lockRefSurface = {};
|
m_lockRefSurface = {};
|
||||||
|
|
||||||
if (D3DDDIMULTISAMPLE_NONE != msaa.first || m_fixedData.Format != formatConfig ||
|
const bool isScaled = static_cast<LONG>(m_fixedData.pSurfList[0].Width) != m_scaledSize.cx ||
|
||||||
static_cast<LONG>(m_fixedData.pSurfList[0].Width) != m_scaledSize.cx ||
|
static_cast<LONG>(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy;
|
||||||
static_cast<LONG>(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy)
|
if (D3DDDIMULTISAMPLE_NONE != msaa.first || m_fixedData.Format != formatConfig || isScaled)
|
||||||
{
|
{
|
||||||
if (m_fixedData.Flags.ZBuffer)
|
const DWORD caps = (m_fixedData.Flags.ZBuffer ? DDSCAPS_ZBUFFER : DDSCAPS_3DDEVICE) | DDSCAPS_VIDEOMEMORY;
|
||||||
|
if (D3DDDIMULTISAMPLE_NONE != msaa.first)
|
||||||
{
|
{
|
||||||
DDPIXELFORMAT pf = {};
|
|
||||||
pf.dwSize = sizeof(pf);
|
|
||||||
pf.dwFlags = DDPF_ZBUFFER;
|
|
||||||
pf.dwZBufferBitDepth = 16;
|
|
||||||
pf.dwZBitMask = 0xFFFF;
|
|
||||||
|
|
||||||
g_formatOverride = formatConfig;
|
|
||||||
g_msaaOverride = msaa;
|
g_msaaOverride = msaa;
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaSurface,
|
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaSurface,
|
||||||
scaledSize.cx, scaledSize.cy, pf,
|
scaledSize.cx, scaledSize.cy, getPixelFormat(formatConfig), caps, m_fixedData.SurfCount);
|
||||||
DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
|
||||||
g_formatOverride = D3DDDIFMT_UNKNOWN;
|
|
||||||
g_msaaOverride = {};
|
g_msaaOverride = {};
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource &&
|
||||||
|
m_device.getAdapter().getInfo().isMsaaDepthResolveSupported)
|
||||||
{
|
{
|
||||||
if (D3DDDIMULTISAMPLE_NONE != msaa.first)
|
g_formatOverride = FOURCC_NULL;
|
||||||
{
|
g_msaaOverride = msaa;
|
||||||
g_msaaOverride = msaa;
|
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_nullSurface,
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaSurface,
|
scaledSize.cx, scaledSize.cy, getPixelFormat(D3DDDIFMT_X8R8G8B8),
|
||||||
scaledSize.cx, scaledSize.cy, getPixelFormat(formatConfig),
|
|
||||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
|
||||||
g_msaaOverride = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface,
|
|
||||||
scaledSize.cx, scaledSize.cy, getPixelFormat(formatConfig),
|
|
||||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
||||||
if (!m_msaaResolvedSurface.resource && m_msaaSurface.resource)
|
g_msaaOverride = {};
|
||||||
{
|
g_formatOverride = m_nullSurface.resource ? FOURCC_INTZ : D3DDDIFMT_UNKNOWN;
|
||||||
m_msaaSurface = {};
|
}
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface,
|
auto msaaResolvedSurfaceCaps = caps | ((m_fixedData.Flags.ZBuffer || !isScaled) ? 0 : DDSCAPS_TEXTURE);
|
||||||
scaledSize.cx, scaledSize.cy, getPixelFormat(formatConfig),
|
auto msaaResolvedSurfaceFormat =
|
||||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
(m_fixedData.Flags.ZBuffer || !isScaled) ? getPixelFormat(formatConfig) : getPixelFormat(D3DDDIFMT_A8R8G8B8);
|
||||||
}
|
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface,
|
||||||
|
scaledSize.cx, scaledSize.cy, msaaResolvedSurfaceFormat, msaaResolvedSurfaceCaps, m_fixedData.SurfCount);
|
||||||
|
g_formatOverride = D3DDDIFMT_UNKNOWN;
|
||||||
|
|
||||||
if (m_msaaResolvedSurface.resource)
|
if (!m_msaaResolvedSurface.resource && m_msaaSurface.resource)
|
||||||
|
{
|
||||||
|
m_msaaSurface = {};
|
||||||
|
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface,
|
||||||
|
scaledSize.cx, scaledSize.cy, msaaResolvedSurfaceFormat, msaaResolvedSurfaceCaps, m_fixedData.SurfCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_fixedData.Flags.ZBuffer && m_msaaResolvedSurface.resource)
|
||||||
|
{
|
||||||
|
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_lockRefSurface,
|
||||||
|
m_fixedData.pSurfList[0].Width, m_fixedData.pSurfList[0].Height, getPixelFormat(m_fixedData.Format),
|
||||||
|
DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
||||||
|
|
||||||
|
if (isScaled)
|
||||||
{
|
{
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_lockRefSurface,
|
Resource* rt = m_msaaResolvedSurface.resource;
|
||||||
m_fixedData.pSurfList[0].Width, m_fixedData.pSurfList[0].Height, getPixelFormat(m_fixedData.Format),
|
auto srcRect = rt->getRect(0);
|
||||||
DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
auto dstRect = getRect(0);
|
||||||
|
const bool dryRun = true;
|
||||||
|
downscale(rt, srcRect.right, srcRect.bottom, dstRect.right, dstRect.bottom, dryRun);
|
||||||
|
if (dstRect != srcRect &&
|
||||||
|
!(m_device.getAdapter().getInfo().formatOps.at(m_fixedData.Format).Operations & FORMATOP_SRGBWRITE))
|
||||||
|
{
|
||||||
|
getNextRenderTarget(rt, dstRect.right, dstRect.bottom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,8 @@ namespace D3dDdi
|
|||||||
bool isMsaaUpToDate;
|
bool isMsaaUpToDate;
|
||||||
bool isMsaaResolvedUpToDate;
|
bool isMsaaResolvedUpToDate;
|
||||||
bool isRefLocked;
|
bool isRefLocked;
|
||||||
|
|
||||||
|
LockData() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT bltLock(D3DDDIARG_LOCK& data);
|
HRESULT bltLock(D3DDDIARG_LOCK& data);
|
||||||
@ -100,7 +102,7 @@ namespace D3dDdi
|
|||||||
void createGdiLockResource();
|
void createGdiLockResource();
|
||||||
void createLockResource();
|
void createLockResource();
|
||||||
void createSysMemResource(const std::vector<D3DDDI_SURFACEINFO>& surfaceInfo);
|
void createSysMemResource(const std::vector<D3DDDI_SURFACEINFO>& surfaceInfo);
|
||||||
bool downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight);
|
void downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight, bool dryRun = false);
|
||||||
void fixResourceData();
|
void fixResourceData();
|
||||||
D3DDDIFORMAT getFormatConfig();
|
D3DDDIFORMAT getFormatConfig();
|
||||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig();
|
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig();
|
||||||
@ -115,6 +117,7 @@ namespace D3dDdi
|
|||||||
void loadVidMemResource(UINT subResourceIndex);
|
void loadVidMemResource(UINT subResourceIndex);
|
||||||
void notifyLock(UINT subResourceIndex);
|
void notifyLock(UINT subResourceIndex);
|
||||||
void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect);
|
void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect);
|
||||||
|
void resolveMsaaDepthBuffer();
|
||||||
HRESULT shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource);
|
HRESULT shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource);
|
||||||
|
|
||||||
Device& m_device;
|
Device& m_device;
|
||||||
@ -128,6 +131,7 @@ namespace D3dDdi
|
|||||||
SurfaceRepository::Surface m_lockRefSurface;
|
SurfaceRepository::Surface m_lockRefSurface;
|
||||||
SurfaceRepository::Surface m_msaaSurface;
|
SurfaceRepository::Surface m_msaaSurface;
|
||||||
SurfaceRepository::Surface m_msaaResolvedSurface;
|
SurfaceRepository::Surface m_msaaResolvedSurface;
|
||||||
|
SurfaceRepository::Surface m_nullSurface;
|
||||||
D3DDDIFORMAT m_formatConfig;
|
D3DDDIFORMAT m_formatConfig;
|
||||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> m_multiSampleConfig;
|
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> m_multiSampleConfig;
|
||||||
SIZE m_scaledSize;
|
SIZE m_scaledSize;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <D3dDdi/SurfaceRepository.h>
|
#include <D3dDdi/SurfaceRepository.h>
|
||||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||||
#include <Shaders/ColorKey.h>
|
#include <Shaders/ColorKey.h>
|
||||||
|
#include <Shaders/DepthBlt.h>
|
||||||
#include <Shaders/DrawCursor.h>
|
#include <Shaders/DrawCursor.h>
|
||||||
#include <Shaders/Gamma.h>
|
#include <Shaders/Gamma.h>
|
||||||
#include <Shaders/GenBilinear.h>
|
#include <Shaders/GenBilinear.h>
|
||||||
@ -54,6 +55,7 @@ namespace D3dDdi
|
|||||||
ShaderBlitter::ShaderBlitter(Device& device)
|
ShaderBlitter::ShaderBlitter(Device& device)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
, m_psColorKey(createPixelShader(g_psColorKey))
|
, m_psColorKey(createPixelShader(g_psColorKey))
|
||||||
|
, m_psDepthBlt(createPixelShader(g_psDepthBlt))
|
||||||
, m_psDrawCursor(createPixelShader(g_psDrawCursor))
|
, m_psDrawCursor(createPixelShader(g_psDrawCursor))
|
||||||
, m_psGamma(createPixelShader(g_psGamma))
|
, m_psGamma(createPixelShader(g_psGamma))
|
||||||
, m_psGenBilinear(createPixelShader(g_psGenBilinear))
|
, m_psGenBilinear(createPixelShader(g_psGenBilinear))
|
||||||
@ -74,7 +76,7 @@ namespace D3dDdi
|
|||||||
HANDLE pixelShader, UINT filter, UINT flags, const BYTE* alpha, const Gdi::Region& srcRgn)
|
HANDLE pixelShader, UINT filter, UINT flags, const BYTE* alpha, const Gdi::Region& srcRgn)
|
||||||
{
|
{
|
||||||
LOG_FUNC("ShaderBlitter::blt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
LOG_FUNC("ShaderBlitter::blt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
static_cast<HANDLE>(srcResource), srcRect, srcSubResourceIndex, pixelShader, filter,
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect, pixelShader, filter,
|
||||||
Compat::hex(flags), alpha, static_cast<HRGN>(srcRgn));
|
Compat::hex(flags), alpha, static_cast<HRGN>(srcRgn));
|
||||||
|
|
||||||
if (!m_vertexShaderDecl || !pixelShader)
|
if (!m_vertexShaderDecl || !pixelShader)
|
||||||
@ -95,14 +97,14 @@ namespace D3dDdi
|
|||||||
|
|
||||||
auto& state = m_device.getState();
|
auto& state = m_device.getState();
|
||||||
state.setSpriteMode(false);
|
state.setSpriteMode(false);
|
||||||
state.setTempRenderState({ D3DDDIRS_SCENECAPTURE, TRUE });
|
|
||||||
state.setTempVertexShaderDecl(m_vertexShaderDecl.get());
|
|
||||||
state.setTempPixelShader(pixelShader);
|
|
||||||
state.setTempRenderTarget({ 0, dstResource, dstSubResourceIndex });
|
state.setTempRenderTarget({ 0, dstResource, dstSubResourceIndex });
|
||||||
state.setTempDepthStencil({ nullptr });
|
state.setTempDepthStencil({ nullptr });
|
||||||
state.setTempViewport({ 0, 0, dstSurface.Width, dstSurface.Height });
|
state.setTempViewport({ 0, 0, dstSurface.Width, dstSurface.Height });
|
||||||
state.setTempZRange({ 0, 1 });
|
state.setTempZRange({ 0, 1 });
|
||||||
|
state.setTempPixelShader(pixelShader);
|
||||||
|
state.setTempVertexShaderDecl(m_vertexShaderDecl.get());
|
||||||
|
|
||||||
|
state.setTempRenderState({ D3DDDIRS_SCENECAPTURE, TRUE });
|
||||||
state.setTempRenderState({ D3DDDIRS_ZENABLE, D3DZB_FALSE });
|
state.setTempRenderState({ D3DDDIRS_ZENABLE, D3DZB_FALSE });
|
||||||
state.setTempRenderState({ D3DDDIRS_FILLMODE, D3DFILL_SOLID });
|
state.setTempRenderState({ D3DDDIRS_FILLMODE, D3DFILL_SOLID });
|
||||||
state.setTempRenderState({ D3DDDIRS_ZWRITEENABLE, FALSE });
|
state.setTempRenderState({ D3DDDIRS_ZWRITEENABLE, FALSE });
|
||||||
@ -261,6 +263,56 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderBlitter::depthBlt(const Resource& dstResource, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, const RECT& srcRect, const Resource& nullResource)
|
||||||
|
{
|
||||||
|
LOG_FUNC("ShaderBlitter::depthBlt", static_cast<HANDLE>(dstResource), dstRect,
|
||||||
|
static_cast<HANDLE>(srcResource), srcRect, static_cast<HANDLE>(nullResource));
|
||||||
|
|
||||||
|
const auto& srcSurface = srcResource.getFixedDesc().pSurfList[0];
|
||||||
|
const auto& dstSurface = dstResource.getFixedDesc().pSurfList[0];
|
||||||
|
|
||||||
|
auto& state = m_device.getState();
|
||||||
|
state.setSpriteMode(false);
|
||||||
|
state.setTempRenderTarget({ 0, nullResource, 0 });
|
||||||
|
state.setTempDepthStencil({ dstResource });
|
||||||
|
state.setTempViewport({ 0, 0, dstSurface.Width, dstSurface.Height });
|
||||||
|
state.setTempZRange({ 0, 1 });
|
||||||
|
state.setTempPixelShader(m_psDepthBlt.get());
|
||||||
|
state.setTempVertexShaderDecl(m_vertexShaderDecl.get());
|
||||||
|
|
||||||
|
state.setTempRenderState({ D3DDDIRS_SCENECAPTURE, TRUE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_ZENABLE, D3DZB_TRUE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_ZFUNC, D3DCMP_ALWAYS });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_FILLMODE, D3DFILL_SOLID });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_ZWRITEENABLE, TRUE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_ALPHATESTENABLE, FALSE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_CULLMODE, D3DCULL_NONE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_DITHERENABLE, FALSE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_ALPHABLENDENABLE, TRUE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_FOGENABLE, FALSE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_COLORKEYENABLE, FALSE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_STENCILENABLE, FALSE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_CLIPPING, FALSE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_CLIPPLANEENABLE, 0 });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_MULTISAMPLEANTIALIAS, FALSE });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_COLORWRITEENABLE, 0 });
|
||||||
|
|
||||||
|
const UINT D3DBLEND_ZERO = 1;
|
||||||
|
const UINT D3DBLEND_ONE = 2;
|
||||||
|
state.setTempRenderState({ D3DDDIRS_SRCBLEND, D3DBLEND_ZERO });
|
||||||
|
state.setTempRenderState({ D3DDDIRS_DESTBLEND, D3DBLEND_ONE });
|
||||||
|
|
||||||
|
setTempTextureStage(0, srcResource, srcRect, D3DTEXF_POINT);
|
||||||
|
state.setTempTextureStageState({ 0, D3DDDITSS_SRGBTEXTURE, FALSE });
|
||||||
|
|
||||||
|
state.setTempStreamSourceUm({ 0, sizeof(Vertex) }, m_vertices.data());
|
||||||
|
|
||||||
|
DeviceState::TempStateLock lock(state);
|
||||||
|
drawRect(srcRect, Rect::toRectF(dstRect), srcSurface.Width, srcSurface.Height);
|
||||||
|
m_device.flushPrimitives();
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderBlitter::drawRect(const RECT& srcRect, const RectF& dstRect, UINT srcWidth, UINT srcHeight)
|
void ShaderBlitter::drawRect(const RECT& srcRect, const RectF& dstRect, UINT srcWidth, UINT srcHeight)
|
||||||
{
|
{
|
||||||
m_vertices[0].xy = { dstRect.left - 0.5f, dstRect.top - 0.5f };
|
m_vertices[0].xy = { dstRect.left - 0.5f, dstRect.top - 0.5f };
|
||||||
|
@ -26,6 +26,8 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
HCURSOR cursor, POINT pt);
|
HCURSOR cursor, POINT pt);
|
||||||
|
void depthBlt(const Resource& dstResource, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, const RECT& srcRect, const Resource& nullResource);
|
||||||
void gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, const RECT& srcRect);
|
const Resource& srcResource, const RECT& srcRect);
|
||||||
void genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
@ -73,6 +75,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
Device& m_device;
|
Device& m_device;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psColorKey;
|
std::unique_ptr<void, ResourceDeleter> m_psColorKey;
|
||||||
|
std::unique_ptr<void, ResourceDeleter> m_psDepthBlt;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psDrawCursor;
|
std::unique_ptr<void, ResourceDeleter> m_psDrawCursor;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psGamma;
|
std::unique_ptr<void, ResourceDeleter> m_psGamma;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psGenBilinear;
|
std::unique_ptr<void, ResourceDeleter> m_psGenBilinear;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::map<LUID, D3dDdi::SurfaceRepository> g_repositories;
|
std::map<LUID, D3dDdi::SurfaceRepository> g_repositories;
|
||||||
|
bool g_enableSurfaceCheck = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace D3dDdi
|
namespace D3dDdi
|
||||||
@ -66,6 +67,11 @@ namespace D3dDdi
|
|||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SurfaceRepository::enableSurfaceCheck(bool enable)
|
||||||
|
{
|
||||||
|
g_enableSurfaceCheck = enable;
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceRepository& SurfaceRepository::get(const Adapter& adapter)
|
SurfaceRepository& SurfaceRepository::get(const Adapter& adapter)
|
||||||
{
|
{
|
||||||
auto it = g_repositories.find(adapter.getLuid());
|
auto it = g_repositories.find(adapter.getLuid());
|
||||||
@ -215,6 +221,11 @@ namespace D3dDdi
|
|||||||
SurfaceRepository::Surface& SurfaceRepository::getSurface(Surface& surface, DWORD width, DWORD height,
|
SurfaceRepository::Surface& SurfaceRepository::getSurface(Surface& surface, DWORD width, DWORD height,
|
||||||
const DDPIXELFORMAT& pf, DWORD caps, UINT surfaceCount)
|
const DDPIXELFORMAT& pf, DWORD caps, UINT surfaceCount)
|
||||||
{
|
{
|
||||||
|
if (!g_enableSurfaceCheck)
|
||||||
|
{
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
if (surface.surface && (surface.width != width || surface.height != height ||
|
if (surface.surface && (surface.width != width || surface.height != height ||
|
||||||
0 != memcmp(&surface.pixelFormat, &pf, sizeof(pf)) || isLost(surface)))
|
0 != memcmp(&surface.pixelFormat, &pf, sizeof(pf)) || isLost(surface)))
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
static SurfaceRepository& get(const Adapter& adapter);
|
static SurfaceRepository& get(const Adapter& adapter);
|
||||||
static bool inCreateSurface() { return s_inCreateSurface; }
|
static bool inCreateSurface() { return s_inCreateSurface; }
|
||||||
|
static void enableSurfaceCheck(bool enable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SurfaceRepository(const Adapter& adapter);
|
SurfaceRepository(const Adapter& adapter);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <D3dDdi/Device.h>
|
#include <D3dDdi/Device.h>
|
||||||
#include <D3dDdi/KernelModeThunks.h>
|
#include <D3dDdi/KernelModeThunks.h>
|
||||||
#include <D3dDdi/Resource.h>
|
#include <D3dDdi/Resource.h>
|
||||||
|
#include <D3dDdi/SurfaceRepository.h>
|
||||||
#include <DDraw/DirectDraw.h>
|
#include <DDraw/DirectDraw.h>
|
||||||
#include <DDraw/DirectDrawSurface.h>
|
#include <DDraw/DirectDrawSurface.h>
|
||||||
#include <DDraw/RealPrimarySurface.h>
|
#include <DDraw/RealPrimarySurface.h>
|
||||||
@ -34,19 +35,41 @@ namespace
|
|||||||
{
|
{
|
||||||
return DDraw::PrimarySurface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
return DDraw::PrimarySurface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
||||||
}
|
}
|
||||||
else if (Config::palettizedTextures.get() &&
|
|
||||||
(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) &&
|
TSurfaceDesc desc = *lpDDSurfaceDesc;
|
||||||
!(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
|
if (!D3dDdi::SurfaceRepository::inCreateSurface())
|
||||||
(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
|
|
||||||
(DDPF_RGB | DDPF_PALETTEINDEXED8) == lpDDSurfaceDesc->ddpfPixelFormat.dwFlags)
|
|
||||||
{
|
{
|
||||||
return DDraw::PalettizedTexture::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
if (&IID_IDirect3DHALDevice == Config::softwareDevice.get())
|
||||||
}
|
{
|
||||||
else
|
if ((desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
|
||||||
{
|
!(desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) &&
|
||||||
return DDraw::Surface::create<TDirectDraw>(
|
(desc.dwFlags & DDSD_PIXELFORMAT) &&
|
||||||
*This, *lpDDSurfaceDesc, *lplpDDSurface, std::make_unique<DDraw::Surface>(lpDDSurfaceDesc->ddsCaps.dwCaps));
|
(DDPF_RGB | DDPF_PALETTEINDEXED8) == desc.ddpfPixelFormat.dwFlags)
|
||||||
|
{
|
||||||
|
desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
|
||||||
|
desc.ddsCaps.dwCaps &= ~DDSCAPS_OFFSCREENPLAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY &&
|
||||||
|
(desc.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER)))
|
||||||
|
{
|
||||||
|
desc.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
|
||||||
|
desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config::palettizedTextures.get() &&
|
||||||
|
(desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) &&
|
||||||
|
!(desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
|
||||||
|
(desc.dwFlags & DDSD_PIXELFORMAT) &&
|
||||||
|
(DDPF_RGB | DDPF_PALETTEINDEXED8) == desc.ddpfPixelFormat.dwFlags)
|
||||||
|
{
|
||||||
|
return DDraw::PalettizedTexture::create<TDirectDraw>(*This, desc, *lplpDDSurface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return DDraw::Surface::create<TDirectDraw>(
|
||||||
|
*This, desc, *lplpDDSurface, std::make_unique<DDraw::Surface>(desc.ddsCaps.dwCaps));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TDirectDraw>
|
template <typename TDirectDraw>
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||||
#include <DDraw/Surfaces/Surface.h>
|
#include <DDraw/Surfaces/Surface.h>
|
||||||
#include <DDraw/Surfaces/SurfaceImpl.h>
|
#include <DDraw/Surfaces/SurfaceImpl.h>
|
||||||
|
#include <Direct3d/Direct3d.h>
|
||||||
#include <Dll/Dll.h>
|
#include <Dll/Dll.h>
|
||||||
#include <Gdi/WinProc.h>
|
#include <Gdi/WinProc.h>
|
||||||
|
|
||||||
@ -217,14 +218,18 @@ namespace DDraw
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
HRESULT SurfaceImpl<TSurface>::QueryInterface(TSurface* This, REFIID riid, LPVOID* obp)
|
HRESULT SurfaceImpl<TSurface>::QueryInterface(TSurface* This, REFIID riid, LPVOID* obp)
|
||||||
{
|
{
|
||||||
auto iid = (IID_IDirect3DRampDevice == riid) ? &IID_IDirect3DRGBDevice : &riid;
|
auto& iid = Direct3d::replaceDevice(riid);;
|
||||||
HRESULT result = getOrigVtable(This).QueryInterface(This, *iid, obp);
|
HRESULT result = getOrigVtable(This).QueryInterface(This, iid, obp);
|
||||||
if (DDERR_INVALIDOBJECT == result)
|
if (DDERR_INVALIDOBJECT == result)
|
||||||
{
|
{
|
||||||
m_data->setSizeOverride(1, 1);
|
m_data->setSizeOverride(1, 1);
|
||||||
result = getOrigVtable(This).QueryInterface(This, *iid, obp);
|
result = getOrigVtable(This).QueryInterface(This, iid, obp);
|
||||||
m_data->setSizeOverride(0, 0);
|
m_data->setSizeOverride(0, 0);
|
||||||
}
|
}
|
||||||
|
if (SUCCEEDED(result))
|
||||||
|
{
|
||||||
|
Direct3d::onCreateDevice(iid, *m_data->m_surface);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +180,7 @@
|
|||||||
<ClInclude Include="Config\Settings\RemoveBorders.h" />
|
<ClInclude Include="Config\Settings\RemoveBorders.h" />
|
||||||
<ClInclude Include="Config\Settings\RenderColorDepth.h" />
|
<ClInclude Include="Config\Settings\RenderColorDepth.h" />
|
||||||
<ClInclude Include="Config\Settings\ResolutionScale.h" />
|
<ClInclude Include="Config\Settings\ResolutionScale.h" />
|
||||||
|
<ClInclude Include="Config\Settings\SoftwareDevice.h" />
|
||||||
<ClInclude Include="Config\Settings\SpriteDetection.h" />
|
<ClInclude Include="Config\Settings\SpriteDetection.h" />
|
||||||
<ClInclude Include="Config\Settings\SpriteFilter.h" />
|
<ClInclude Include="Config\Settings\SpriteFilter.h" />
|
||||||
<ClInclude Include="Config\Settings\SpriteTexCoord.h" />
|
<ClInclude Include="Config\Settings\SpriteTexCoord.h" />
|
||||||
@ -423,6 +424,9 @@
|
|||||||
<FxCompile Include="Shaders\ColorKey.hlsl">
|
<FxCompile Include="Shaders\ColorKey.hlsl">
|
||||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\DepthBlt.hlsl">
|
||||||
|
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
|
||||||
|
</FxCompile>
|
||||||
<FxCompile Include="Shaders\DrawCursor.hlsl" />
|
<FxCompile Include="Shaders\DrawCursor.hlsl" />
|
||||||
<FxCompile Include="Shaders\Gamma.hlsl" />
|
<FxCompile Include="Shaders\Gamma.hlsl" />
|
||||||
<FxCompile Include="Shaders\GenBilinear.hlsl" />
|
<FxCompile Include="Shaders\GenBilinear.hlsl" />
|
||||||
|
@ -597,6 +597,9 @@
|
|||||||
<ClInclude Include="Config\Settings\PalettizedTextures.h">
|
<ClInclude Include="Config\Settings\PalettizedTextures.h">
|
||||||
<Filter>Header Files\Config\Settings</Filter>
|
<Filter>Header Files\Config\Settings</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Config\Settings\SoftwareDevice.h">
|
||||||
|
<Filter>Header Files\Config\Settings</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Gdi\Gdi.cpp">
|
<ClCompile Include="Gdi\Gdi.cpp">
|
||||||
@ -974,6 +977,9 @@
|
|||||||
<FxCompile Include="Shaders\ColorKey.hlsl">
|
<FxCompile Include="Shaders\ColorKey.hlsl">
|
||||||
<Filter>Shaders</Filter>
|
<Filter>Shaders</Filter>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\DepthBlt.hlsl">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</FxCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="arrow.bmp">
|
<Image Include="arrow.bmp">
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <Common/CompatPtr.h>
|
#include <Common/CompatPtr.h>
|
||||||
#include <Common/CompatVtable.h>
|
#include <Common/CompatVtable.h>
|
||||||
|
#include <Config/Config.h>
|
||||||
|
#include <D3dDdi/Device.h>
|
||||||
|
#include <DDraw/DirectDrawSurface.h>
|
||||||
#include <DDraw/ScopedThreadLock.h>
|
#include <DDraw/ScopedThreadLock.h>
|
||||||
#include <DDraw/Surfaces/Surface.h>
|
#include <DDraw/Surfaces/Surface.h>
|
||||||
#include <Direct3d/Direct3d.h>
|
#include <Direct3d/Direct3d.h>
|
||||||
@ -20,25 +22,26 @@ namespace
|
|||||||
TDirect3dDevice** lplpD3DDevice,
|
TDirect3dDevice** lplpD3DDevice,
|
||||||
Params... params)
|
Params... params)
|
||||||
{
|
{
|
||||||
auto iid = (IID_IDirect3DRampDevice == rclsid) ? &IID_IDirect3DRGBDevice : &rclsid;
|
auto& iid = Direct3d::replaceDevice(rclsid);
|
||||||
HRESULT result = getOrigVtable(This).CreateDevice(This, *iid, lpDDS, lplpD3DDevice, params...);
|
HRESULT result = getOrigVtable(This).CreateDevice(This, iid, lpDDS, lplpD3DDevice, params...);
|
||||||
if (DDERR_INVALIDOBJECT == result && lpDDS)
|
if (DDERR_INVALIDOBJECT == result && lpDDS)
|
||||||
{
|
{
|
||||||
auto surface = DDraw::Surface::getSurface(*lpDDS);
|
auto surface = DDraw::Surface::getSurface(*lpDDS);
|
||||||
if (surface)
|
if (surface)
|
||||||
{
|
{
|
||||||
surface->setSizeOverride(1, 1);
|
surface->setSizeOverride(1, 1);
|
||||||
result = getOrigVtable(This).CreateDevice(This, *iid, lpDDS, lplpD3DDevice, params...);
|
result = getOrigVtable(This).CreateDevice(This, iid, lpDDS, lplpD3DDevice, params...);
|
||||||
surface->setSizeOverride(0, 0);
|
surface->setSizeOverride(0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (std::is_same_v<TDirect3d, IDirect3D7>)
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
if (SUCCEEDED(result))
|
if constexpr (std::is_same_v<TDirect3d, IDirect3D7>)
|
||||||
{
|
{
|
||||||
Direct3d::Direct3dDevice::hookVtable(*(*lplpD3DDevice)->lpVtbl);
|
Direct3d::Direct3dDevice::hookVtable(*(*lplpD3DDevice)->lpVtbl);
|
||||||
}
|
}
|
||||||
|
Direct3d::onCreateDevice(iid, *CompatPtr<IDirectDrawSurface7>::from(lpDDS));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -74,6 +77,52 @@ namespace
|
|||||||
|
|
||||||
namespace Direct3d
|
namespace Direct3d
|
||||||
{
|
{
|
||||||
|
void onCreateDevice(const IID& iid, IDirectDrawSurface7& surface)
|
||||||
|
{
|
||||||
|
if (IID_IDirect3DHALDevice == iid || IID_IDirect3DTnLHalDevice == iid)
|
||||||
|
{
|
||||||
|
auto device = D3dDdi::Device::findDeviceByResource(
|
||||||
|
DDraw::DirectDrawSurface::getDriverResourceHandle(surface));
|
||||||
|
if (device)
|
||||||
|
{
|
||||||
|
device->getState().flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const IID& replaceDevice(const IID& iid)
|
||||||
|
{
|
||||||
|
if (IID_IDirect3DRampDevice != iid &&
|
||||||
|
IID_IDirect3DRGBDevice != iid &&
|
||||||
|
IID_IDirect3DHALDevice != iid &&
|
||||||
|
IID_IDirect3DMMXDevice != iid &&
|
||||||
|
IID_IDirect3DRefDevice != iid &&
|
||||||
|
IID_IDirect3DNullDevice != iid &&
|
||||||
|
IID_IDirect3DTnLHalDevice != iid)
|
||||||
|
{
|
||||||
|
return iid;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mappedDeviceType = &iid;
|
||||||
|
if (Config::softwareDevice.get() &&
|
||||||
|
(IID_IDirect3DRampDevice == iid || IID_IDirect3DMMXDevice == iid || IID_IDirect3DRGBDevice == iid))
|
||||||
|
{
|
||||||
|
mappedDeviceType = Config::softwareDevice.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::set<IID> usedDeviceTypes;
|
||||||
|
if (usedDeviceTypes.insert(iid).second)
|
||||||
|
{
|
||||||
|
Compat::Log log(Config::Settings::LogLevel::INFO);
|
||||||
|
log << "Using Direct3D device type: " << iid;
|
||||||
|
if (iid != *mappedDeviceType)
|
||||||
|
{
|
||||||
|
log << " (mapped to " << *mappedDeviceType << ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *mappedDeviceType;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Direct3d
|
namespace Direct3d
|
||||||
{
|
{
|
||||||
template <typename Vtable>
|
template <typename Vtable>
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ddraw.h>
|
||||||
|
|
||||||
#include <Direct3d/Log.h>
|
#include <Direct3d/Log.h>
|
||||||
|
|
||||||
namespace Direct3d
|
namespace Direct3d
|
||||||
{
|
{
|
||||||
|
void onCreateDevice(const IID& iid, IDirectDrawSurface7& surface);
|
||||||
|
const IID& replaceDevice(const IID& iid);
|
||||||
|
|
||||||
namespace Direct3d
|
namespace Direct3d
|
||||||
{
|
{
|
||||||
template <typename Vtable>
|
template <typename Vtable>
|
||||||
|
15
DDrawCompat/Shaders/DepthBlt.hlsl
Normal file
15
DDrawCompat/Shaders/DepthBlt.hlsl
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
sampler2D s_texture : register(s0);
|
||||||
|
|
||||||
|
struct PS_OUT
|
||||||
|
{
|
||||||
|
float4 color : COLOR0;
|
||||||
|
float depth : DEPTH0;
|
||||||
|
};
|
||||||
|
|
||||||
|
PS_OUT main(float2 texCoord : TEXCOORD0)
|
||||||
|
{
|
||||||
|
PS_OUT result;
|
||||||
|
result.color = 0;
|
||||||
|
result.depth = tex2D(s_texture, texCoord).r;
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user