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

Accumulate device state changes

This commit is contained in:
narzoul 2021-12-04 16:39:07 +01:00
parent 664c573d91
commit 9fb450e233
13 changed files with 915 additions and 703 deletions

View File

@ -0,0 +1,57 @@
#pragma once
#include <array>
#include <intrin.h>
template <int min, int max>
class BitSet
{
public:
BitSet() : m_bits{}
{
}
template <typename Func>
void forEach(Func func)
{
int value = min;
unsigned long index = 0;
for (unsigned bits : m_bits)
{
while (0 != bits)
{
_BitScanForward(&index, bits);
func(value + index);
bits &= ~(1 << index);
}
value += 32;
}
}
void reset()
{
m_bits.fill(0);
}
void reset(int value)
{
const unsigned index = value - min;
m_bits[index / 32] &= ~(1 << (index % 32));
}
void set(int value)
{
const unsigned index = value - min;
m_bits[index / 32] |= 1 << (index % 32);
}
bool test(int value)
{
const unsigned index = value - min;
return m_bits[index / 32] & (1 << (index % 32));
}
private:
std::array<unsigned, (max - min + 32) / 32> m_bits;
};

View File

@ -159,6 +159,7 @@ namespace D3dDdi
HRESULT Device::pfnClear(const D3DDDIARG_CLEAR* data, UINT numRect, const RECT* rect)
{
flushPrimitives();
m_state.flush();
if (data->Flags & D3DCLEAR_TARGET)
{
prepareForRendering();

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,8 @@
#include <map>
#include <vector>
#include <Common/BitSet.h>
const UINT D3DTEXF_NONE = 0;
const UINT D3DTEXF_POINT = 1;
const UINT D3DTEXF_LINEAR = 2;
@ -19,9 +21,41 @@ namespace D3dDdi
class DeviceState
{
public:
typedef std::array<BOOL, 1> ShaderConstB;
typedef std::array<FLOAT, 4> ShaderConstF;
typedef std::array<INT, 4> ShaderConstI;
class TempPixelShaderConst
{
public:
TempPixelShaderConst(DeviceState& state, const D3DDDIARG_SETPIXELSHADERCONST& data, const ShaderConstF* registers);
~TempPixelShaderConst();
private:
DeviceState& m_state;
D3DDDIARG_SETPIXELSHADERCONST m_data;
};
class TempStateLock
{
public:
TempStateLock(DeviceState& state)
: m_state(state)
, m_prevChangedStates(state.m_changedStates)
{
state.m_changedStates = 0;
}
~TempStateLock()
{
m_state.m_changedStates = m_prevChangedStates;
}
private:
DeviceState& m_state;
UINT m_prevChangedStates;
};
DeviceState(Device& device);
HRESULT pfnCreateVertexShaderDecl(D3DDDIARG_CREATEVERTEXSHADERDECL* data, const D3DDDIVERTEXELEMENT* vertexElements);
@ -48,248 +82,106 @@ namespace D3dDdi
HRESULT pfnSetZRange(const D3DDDIARG_ZRANGE* data);
HRESULT pfnUpdateWInfo(const D3DDDIARG_WINFO* data);
void setTempDepthStencil(const D3DDDIARG_SETDEPTHSTENCIL& depthStencil);
void setTempPixelShader(HANDLE shader);
void setTempRenderState(const D3DDDIARG_RENDERSTATE& renderState);
void setTempRenderTarget(const D3DDDIARG_SETRENDERTARGET& renderTarget);
void setTempStreamSource(const D3DDDIARG_SETSTREAMSOURCE& streamSource);
void setTempStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& streamSourceUm, const void* umBuffer);
void setTempTexture(UINT stage, HANDLE texture);
void setTempTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE& tss);
void setTempVertexShaderDecl(HANDLE decl);
void setTempViewport(const D3DDDIARG_VIEWPORTINFO& viewport);
void setTempWInfo(const D3DDDIARG_WINFO& wInfo);
void setTempZRange(const D3DDDIARG_ZRANGE& zRange);
void flush();
void onDestroyResource(HANDLE resource);
void updateConfig();
private:
HRESULT deleteShader(HANDLE shader, HANDLE& currentShader,
friend class ScopedDeviceState;
enum ChangedState
{
CS_MISC = 1 << 0,
CS_RENDER_STATE = 1 << 1,
CS_RENDER_TARGET = 1 << 2,
CS_SHADER = 1 << 3,
CS_STREAM_SOURCE = 1 << 4,
CS_TEXTURE_STAGE = 1 << 5
};
struct State
{
D3DDDIARG_SETDEPTHSTENCIL depthStencil;
HANDLE pixelShader;
std::array<UINT, D3DDDIRS_BLENDOPALPHA + 1> renderState;
D3DDDIARG_SETRENDERTARGET renderTarget;
D3DDDIARG_SETSTREAMSOURCE streamSource;
D3DDDIARG_SETSTREAMSOURCEUM streamSourceUm;
const void* streamSourceUmBuffer;
std::array<HANDLE, 8> textures;
std::array<std::array<UINT, D3DDDITSS_TEXTURECOLORKEYVAL + 1>, 8> textureStageState;
HANDLE vertexShaderDecl;
HANDLE vertexShaderFunc;
D3DDDIARG_VIEWPORTINFO viewport;
D3DDDIARG_WINFO wInfo;
D3DDDIARG_ZRANGE zRange;
};
HRESULT deleteShader(HANDLE shader, HANDLE State::* shaderMember,
HRESULT(APIENTRY* origDeleteShaderFunc)(HANDLE, HANDLE));
HRESULT setShader(HANDLE shader, HANDLE& currentShader,
HRESULT(APIENTRY* origSetShaderFunc)(HANDLE, HANDLE));
template <typename SetShaderConstData, typename ShaderConst, typename Registers>
HRESULT setShaderConst(const SetShaderConstData* data, const Registers* registers,
std::vector<ShaderConst>& shaderConst,
HRESULT(APIENTRY* origSetShaderConstFunc)(HANDLE, const SetShaderConstData*, const Registers*));
template <typename Data>
void removeResource(HANDLE resource, Data State::* data, HANDLE Data::* resourceMember,
HRESULT(DeviceState::* pfnSetResourceFunc)(const Data*));
template <typename StateData>
HRESULT setState(const StateData* data, StateData& currentState,
HRESULT(APIENTRY* origSetState)(HANDLE, const StateData*));
template <typename Data>
bool setData(const Data& data, Data& currentData, HRESULT(APIENTRY* origSetData)(HANDLE, const Data*));
template <typename StateData, UINT size>
HRESULT setStateArray(const StateData* data, std::array<UINT, size>& currentState,
HRESULT(APIENTRY* origSetState)(HANDLE, const StateData*));
bool setShader(HANDLE shader, HANDLE& currentShader, HRESULT(APIENTRY* origSetShaderFunc)(HANDLE, HANDLE));
void updateTextureStageState(UINT stage, D3DDDITEXTURESTAGESTATETYPE state);
template <typename SetShaderConstData, typename ShaderConstArray, typename Register>
HRESULT setShaderConst(const SetShaderConstData* data, const Register* registers,
ShaderConstArray& shaderConstArray,
HRESULT(APIENTRY* origSetShaderConstFunc)(HANDLE, const SetShaderConstData*, const Register*));
void setDepthStencil(const D3DDDIARG_SETDEPTHSTENCIL& depthStencil);
void setPixelShader(HANDLE shader);
void setRenderState(const D3DDDIARG_RENDERSTATE& renderState);
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& renderTarget);
void setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& streamSource);
void setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& streamSourceUm, const void* umBuffer);
bool setTexture(UINT stage, HANDLE texture);
void setTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE& tss);
void setVertexShaderDecl(HANDLE decl);
void setVertexShaderFunc(HANDLE shader);
void setViewport(const D3DDDIARG_VIEWPORTINFO& viewport);
void setWInfo(const D3DDDIARG_WINFO& wInfo);
void setZRange(const D3DDDIARG_ZRANGE& zRange);
void updateMisc();
void updateRenderStates();
void updateRenderTargets();
void updateShaders();
void updateStreamSource();
void updateTextureColorKey(UINT stage);
void updateTextureStages();
Device& m_device;
D3DDDIARG_SETDEPTHSTENCIL m_depthStencil;
HANDLE m_pixelShader;
std::vector<ShaderConstF> m_pixelShaderConst;
std::vector<BOOL> m_pixelShaderConstB;
std::vector<ShaderConstI> m_pixelShaderConstI;
std::array<UINT, D3DDDIRS_BLENDOPALPHA + 1> m_renderState;
D3DDDIARG_SETRENDERTARGET m_renderTarget;
D3DDDIARG_SETSTREAMSOURCE m_streamSource;
D3DDDIARG_SETSTREAMSOURCEUM m_streamSourceUm;
const void* m_streamSourceUmBuffer;
std::array<HANDLE, 8> m_textures;
std::array<std::array<UINT, D3DDDITSS_TEXTURECOLORKEYVAL + 1>, 8> m_textureStageState;
std::vector<ShaderConstF> m_vertexShaderConst;
std::vector<BOOL> m_vertexShaderConstB;
std::vector<ShaderConstI> m_vertexShaderConstI;
State m_app;
State m_current;
std::array<ShaderConstF, 32> m_pixelShaderConst;
std::array<ShaderConstB, 16> m_pixelShaderConstB;
std::array<ShaderConstI, 16> m_pixelShaderConstI;
std::array<ShaderConstF, 256> m_vertexShaderConst;
std::array<ShaderConstB, 16> m_vertexShaderConstB;
std::array<ShaderConstI, 16> m_vertexShaderConstI;
std::map<HANDLE, std::vector<D3DDDIVERTEXELEMENT>> m_vertexShaderDecls;
HANDLE m_vertexShaderDecl;
HANDLE m_vertexShaderFunc;
D3DDDIARG_VIEWPORTINFO m_viewport;
D3DDDIARG_WINFO m_wInfo;
D3DDDIARG_ZRANGE m_zRange;
public:
template <auto setterMethod, auto dataMemberPtr>
class ScopedData
{
public:
typedef std::remove_reference_t<decltype(std::declval<DeviceState>().*dataMemberPtr)> Data;
ScopedData(DeviceState& deviceState, const Data& data)
: m_deviceState(deviceState)
, m_prevData(deviceState.*dataMemberPtr)
{
(m_deviceState.*setterMethod)(&data);
}
~ScopedData()
{
(m_deviceState.*setterMethod)(&m_prevData);
}
protected:
DeviceState& m_deviceState;
Data m_prevData;
};
class ScopedDepthStencil : public ScopedData<&DeviceState::pfnSetDepthStencil, &DeviceState::m_depthStencil>
{
public:
using ScopedData::ScopedData;
};
template <HRESULT(DeviceState::* setHandle)(HANDLE), HANDLE DeviceState::* storedHandle>
class ScopedHandle
{
public:
ScopedHandle(DeviceState& deviceState, HANDLE handle)
: m_deviceState(deviceState)
, m_prevHandle(deviceState.*storedHandle)
{
(m_deviceState.*setHandle)(handle);
}
~ScopedHandle()
{
if (m_prevHandle)
{
(m_deviceState.*setHandle)(m_prevHandle);
}
}
private:
DeviceState& m_deviceState;
HANDLE m_prevHandle;
};
class ScopedPixelShader : public ScopedHandle<&DeviceState::pfnSetPixelShader, &DeviceState::m_pixelShader>
{
public:
using ScopedHandle::ScopedHandle;
};
class ScopedPixelShaderConst
{
public:
ScopedPixelShaderConst(
DeviceState& deviceState, const D3DDDIARG_SETPIXELSHADERCONST& data, const ShaderConstF* registers)
: m_deviceState(deviceState)
, m_register(data.Register)
{
if (data.Register + data.Count > m_deviceState.m_pixelShaderConst.size())
{
m_deviceState.m_pixelShaderConst.resize(data.Register + data.Count);
}
auto it = deviceState.m_pixelShaderConst.begin() + data.Register;
m_prevRegisters.assign(it, it + data.Count);
m_deviceState.pfnSetPixelShaderConst(&data, reinterpret_cast<const FLOAT*>(registers));
}
~ScopedPixelShaderConst()
{
D3DDDIARG_SETPIXELSHADERCONST data = {};
data.Register = m_register;
data.Count = m_prevRegisters.size();
m_deviceState.pfnSetPixelShaderConst(&data, reinterpret_cast<const FLOAT*>(m_prevRegisters.data()));
}
private:
DeviceState& m_deviceState;
UINT m_register;
std::vector<ShaderConstF> m_prevRegisters;
};
class ScopedRenderState
{
public:
ScopedRenderState(DeviceState& deviceState, const D3DDDIARG_RENDERSTATE& data);
~ScopedRenderState();
private:
DeviceState& m_deviceState;
D3DDDIARG_RENDERSTATE m_prevData;
};
class ScopedRenderTarget : public ScopedData<&DeviceState::pfnSetRenderTarget, &DeviceState::m_renderTarget>
{
public:
ScopedRenderTarget(DeviceState& deviceState, const D3DDDIARG_SETRENDERTARGET& data)
: ScopedData(deviceState, data)
{
if (!m_prevData.hRenderTarget)
{
m_prevData = data;
}
}
};
class ScopedStreamSourceUm
{
public:
ScopedStreamSourceUm(DeviceState& deviceState, const D3DDDIARG_SETSTREAMSOURCEUM& data, const void* umBuffer)
: m_deviceState(deviceState)
, m_prevStreamSource(deviceState.m_streamSource)
, m_prevStreamSourceUm(deviceState.m_streamSourceUm)
, m_prevStreamSourceUmBuffer(deviceState.m_streamSourceUmBuffer)
{
m_deviceState.pfnSetStreamSourceUm(&data, umBuffer);
}
~ScopedStreamSourceUm()
{
if (m_prevStreamSourceUmBuffer)
{
m_deviceState.pfnSetStreamSourceUm(&m_prevStreamSourceUm, m_prevStreamSourceUmBuffer);
}
else if (m_prevStreamSource.hVertexBuffer)
{
m_deviceState.pfnSetStreamSource(&m_prevStreamSource);
}
}
private:
DeviceState& m_deviceState;
D3DDDIARG_SETSTREAMSOURCE m_prevStreamSource;
D3DDDIARG_SETSTREAMSOURCEUM m_prevStreamSourceUm;
const void* m_prevStreamSourceUmBuffer;
};
class ScopedTextureStageState
{
public:
ScopedTextureStageState(DeviceState& deviceState, const D3DDDIARG_TEXTURESTAGESTATE& data);
~ScopedTextureStageState();
private:
DeviceState& m_deviceState;
D3DDDIARG_TEXTURESTAGESTATE m_prevData;
};
class ScopedTexture
{
public:
ScopedTexture(DeviceState& deviceState, UINT stage, HANDLE texture, UINT filter);
~ScopedTexture();
private:
DeviceState& m_deviceState;
UINT m_stage;
HANDLE m_prevTexture;
ScopedTextureStageState m_scopedAddressU;
ScopedTextureStageState m_scopedAddressV;
ScopedTextureStageState m_scopedMagFilter;
ScopedTextureStageState m_scopedMinFilter;
ScopedTextureStageState m_scopedMipFilter;
ScopedTextureStageState m_scopedSrgbTexture;
ScopedRenderState m_scopedWrap;
UINT m_prevTextureColorKeyVal;
UINT m_prevDisableTextureColorKey;
};
class ScopedVertexShaderDecl : public ScopedHandle<&DeviceState::pfnSetVertexShaderDecl, &DeviceState::m_vertexShaderDecl>
{
public:
using ScopedHandle::ScopedHandle;
};
class ScopedViewport : public ScopedData<&DeviceState::pfnSetViewport, &DeviceState::m_viewport>
{
public:
using ScopedData::ScopedData;
};
class ScopedZRange : public ScopedData<&DeviceState::pfnSetZRange, &DeviceState::m_zRange>
{
public:
using ScopedData::ScopedData;
};
UINT m_changedStates;
UINT m_maxChangedTextureStage;
BitSet<D3DDDIRS_ZENABLE, D3DDDIRS_BLENDOPALPHA> m_changedRenderStates;
std::array<BitSet<D3DDDITSS_TEXTUREMAP, D3DDDITSS_TEXTURECOLORKEYVAL>, 8> m_changedTextureStageStates;
};
}

View File

@ -454,6 +454,8 @@ namespace D3dDdi
HRESULT DrawPrimitive::draw(D3DDDIARG_DRAWPRIMITIVE data, const UINT* flagBuffer)
{
m_device.getState().flush();
if (0 == m_batched.primitiveCount || flagBuffer ||
!appendPrimitives(data.PrimitiveType, data.VStart, data.PrimitiveCount, nullptr, 0, 0))
{
@ -485,6 +487,8 @@ namespace D3dDdi
HRESULT DrawPrimitive::drawIndexed(
D3DDDIARG_DRAWINDEXEDPRIMITIVE2 data, const UINT16* indices, const UINT* flagBuffer)
{
m_device.getState().flush();
auto indexCount = getVertexCount(data.PrimitiveType, data.PrimitiveCount);
auto [min, max] = std::minmax_element(indices, indices + indexCount);
data.MinIndex = *min;

View File

@ -79,7 +79,7 @@ namespace D3dDdi
HRESULT setSysMemStreamSource(const BYTE* vertices, UINT stride);
HANDLE m_device;
Device& m_device;
const D3DDDI_DEVICEFUNCS& m_origVtable;
DynamicVertexBuffer m_vertexBuffer;
DynamicIndexBuffer m_indexBuffer;

View File

@ -105,7 +105,7 @@ namespace D3dDdi
, m_origData(data)
, m_fixedData(data)
, m_lockBuffer(nullptr, &heapFree)
, m_lockResource(nullptr, ResourceDeleter(device))
, m_lockResource(nullptr, ResourceDeleter(device, device.getOrigVtable().pfnDestroyResource))
, m_customSurface{}
, m_multiSampleConfig{ D3DDDIMULTISAMPLE_NONE, 0 }
, m_isSurfaceRepoResource(SurfaceRepository::inCreateSurface())

View File

@ -7,6 +7,7 @@
#include <d3dumddi.h>
#include <D3dDdi/FormatInfo.h>
#include <D3dDdi/ResourceDeleter.h>
#include <D3dDdi/SurfaceRepository.h>
namespace D3dDdi
@ -65,16 +66,6 @@ namespace D3dDdi
bool isCustomUpToDate;
};
class ResourceDeleter
{
public:
ResourceDeleter(Device& device) : m_device(device) {}
void operator()(HANDLE resource) { m_device.getOrigVtable().pfnDestroyResource(m_device, resource); }
private:
Device& m_device;
};
HRESULT bltLock(D3DDDIARG_LOCK& data);
HRESULT bltUnlock(const D3DDDIARG_UNLOCK& data);
void clipRect(UINT subResourceIndex, RECT& rect);

View File

@ -0,0 +1,27 @@
#pragma once
#include <Windows.h>
namespace D3dDdi
{
class ResourceDeleter
{
public:
typedef HRESULT(APIENTRY* Deleter)(HANDLE, HANDLE);
ResourceDeleter(HANDLE device = nullptr, Deleter deleter = nullptr)
: m_device(device)
, m_deleter(deleter)
{
}
void operator()(HANDLE resource)
{
m_deleter(m_device, resource);
}
private:
HANDLE m_device;
Deleter m_deleter;
};
}

View File

@ -39,29 +39,32 @@ namespace D3dDdi
const auto& dstSurface = dstResource.getFixedDesc().pSurfList[dstSubResourceIndex];
const auto& srcSurface = srcResource.getFixedDesc().pSurfList[0];
SCOPED_STATE(RenderState, { D3DDDIRS_SCENECAPTURE, TRUE });
SCOPED_STATE(VertexShaderDecl, m_vertexShaderDecl);
SCOPED_STATE(PixelShader, pixelShader);
SCOPED_STATE(DepthStencil, { nullptr });
SCOPED_STATE(RenderTarget, { 0, dstResource, dstSubResourceIndex });
SCOPED_STATE(Viewport, { 0, 0, dstSurface.Width, dstSurface.Height });
SCOPED_STATE(ZRange, { 0, 1 });
auto& state = m_device.getState();
state.setTempRenderState({ D3DDDIRS_SCENECAPTURE, TRUE });
state.setTempVertexShaderDecl(m_vertexShaderDecl.get());
state.setTempPixelShader(pixelShader);
state.setTempRenderTarget({ 0, dstResource, dstSubResourceIndex });
state.setTempDepthStencil({ nullptr });
state.setTempViewport({ 0, 0, dstSurface.Width, dstSurface.Height });
state.setTempZRange({ 0, 1 });
SCOPED_STATE(RenderState, { D3DDDIRS_ZENABLE, D3DZB_FALSE });
SCOPED_STATE(RenderState, { D3DDDIRS_FILLMODE, D3DFILL_SOLID });
SCOPED_STATE(RenderState, { D3DDDIRS_ALPHATESTENABLE, FALSE });
SCOPED_STATE(RenderState, { D3DDDIRS_CULLMODE, D3DCULL_NONE });
SCOPED_STATE(RenderState, { D3DDDIRS_DITHERENABLE, FALSE });
SCOPED_STATE(RenderState, { D3DDDIRS_ALPHABLENDENABLE, FALSE });
SCOPED_STATE(RenderState, { D3DDDIRS_FOGENABLE, FALSE });
SCOPED_STATE(RenderState, { D3DDDIRS_STENCILENABLE, FALSE });
SCOPED_STATE(RenderState, { D3DDDIRS_CLIPPING, FALSE });
SCOPED_STATE(RenderState, { D3DDDIRS_CLIPPLANEENABLE, 0 });
SCOPED_STATE(RenderState, { D3DDDIRS_MULTISAMPLEANTIALIAS, FALSE });
SCOPED_STATE(RenderState, { D3DDDIRS_COLORWRITEENABLE, 0xF });
SCOPED_STATE(RenderState, { D3DDDIRS_SRGBWRITEENABLE, D3DTEXF_LINEAR == filter });
state.setTempRenderState({ D3DDDIRS_ZENABLE, D3DZB_FALSE });
state.setTempRenderState({ D3DDDIRS_FILLMODE, D3DFILL_SOLID });
state.setTempRenderState({ D3DDDIRS_ZWRITEENABLE, FALSE });
state.setTempRenderState({ D3DDDIRS_ALPHATESTENABLE, FALSE });
state.setTempRenderState({ D3DDDIRS_CULLMODE, D3DCULL_NONE });
state.setTempRenderState({ D3DDDIRS_DITHERENABLE, FALSE });
state.setTempRenderState({ D3DDDIRS_ALPHABLENDENABLE, FALSE });
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, 0xF });
state.setTempRenderState({ D3DDDIRS_SRGBWRITEENABLE, D3DTEXF_LINEAR == filter });
SCOPED_STATE(Texture, 0, srcResource, filter);
setTempTextureStage(0, srcResource, filter);
struct Vertex
{
@ -83,9 +86,9 @@ namespace D3dDdi
{ dstRect.left - 0.5f, dstRect.bottom - 0.5f, 0, 1, srcRect.left / srcWidth, srcRect.bottom / srcHeight }
};
D3DDDIARG_SETSTREAMSOURCEUM um = {};
um.Stride = sizeof(Vertex);
SCOPED_STATE(StreamSourceUm, um, vertices);
state.setTempStreamSourceUm({ 0, sizeof(Vertex) }, vertices);
DeviceState::TempStateLock lock(state);
D3DDDIARG_DRAWPRIMITIVE dp = {};
dp.PrimitiveType = D3DPT_TRIANGLEFAN;
@ -95,7 +98,7 @@ namespace D3dDdi
m_device.flushPrimitives();
}
HANDLE ShaderBlitter::createPixelShader(const BYTE* code, UINT size)
std::unique_ptr<void, ResourceDeleter> ShaderBlitter::createPixelShader(const BYTE* code, UINT size)
{
D3DDDIARG_CREATEPIXELSHADER data = {};
data.CodeSize = size;
@ -103,10 +106,10 @@ namespace D3dDdi
{
return nullptr;
}
return data.ShaderHandle;
return { data.ShaderHandle, ResourceDeleter(m_device, m_device.getOrigVtable().pfnDeletePixelShader) };
}
HANDLE ShaderBlitter::createVertexShaderDecl()
std::unique_ptr<void, ResourceDeleter> ShaderBlitter::createVertexShaderDecl()
{
const UINT D3DDECLTYPE_FLOAT2 = 1;
const UINT D3DDECLTYPE_FLOAT4 = 3;
@ -126,7 +129,7 @@ namespace D3dDdi
{
return nullptr;
}
return data.ShaderHandle;
return { data.ShaderHandle, ResourceDeleter(m_device, m_device.getOrigVtable().pfnDeleteVertexShaderDecl) };
}
void ShaderBlitter::cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, HCURSOR cursor, POINT pt)
@ -163,10 +166,10 @@ namespace D3dDdi
data.DstRect = clippedSrcRect;
m_device.getOrigVtable().pfnBlt(m_device, &data);
SCOPED_STATE(Texture, 1, *cur.maskTexture, D3DTEXF_POINT);
SCOPED_STATE(Texture, 2, *cur.colorTexture, D3DTEXF_POINT);
SCOPED_STATE(Texture, 3, *xorTexture, D3DTEXF_POINT);
blt(dstResource, dstSubResourceIndex, clippedDstRect, *cur.tempTexture, clippedSrcRect, m_psDrawCursor, D3DTEXF_POINT);
setTempTextureStage(1, *cur.maskTexture, D3DTEXF_POINT);
setTempTextureStage(2, *cur.colorTexture, D3DTEXF_POINT);
setTempTextureStage(3, *xorTexture, D3DTEXF_POINT);
blt(dstResource, dstSubResourceIndex, clippedDstRect, *cur.tempTexture, clippedSrcRect, m_psDrawCursor.get(), D3DTEXF_POINT);
}
void ShaderBlitter::genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
@ -174,7 +177,7 @@ namespace D3dDdi
{
if (100 == blurPercent)
{
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psTextureSampler, D3DTEXF_LINEAR);
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psTextureSampler.get(), D3DTEXF_LINEAR);
return;
}
@ -186,14 +189,13 @@ namespace D3dDdi
scaleX = 1 / ((1 - blur) / scaleX + blur);
scaleY = 1 / ((1 - blur) / scaleY + blur);
const DeviceState::ShaderConstF registers[] = {
const std::array<DeviceState::ShaderConstF, 2> registers{ {
{ static_cast<float>(srcDesc.Width), static_cast<float>(srcDesc.Height), 0.0f, 0.0f },
{ scaleX, scaleY, 0.0f, 0.0f }
};
} };
SCOPED_STATE(PixelShaderConst, { 0, sizeof(registers) / sizeof(registers[0]) }, registers);
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psGenBilinear, D3DTEXF_LINEAR);
DeviceState::TempPixelShaderConst tempPsConst(m_device.getState(), { 0, registers.size() }, registers.data());
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psGenBilinear.get(), D3DTEXF_LINEAR);
}
void ShaderBlitter::palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex,
@ -228,7 +230,20 @@ namespace D3dDdi
const RECT dstRect = { 0, 0, static_cast<LONG>(dstSurface.Width), static_cast<LONG>(dstSurface.Height) };
const RECT srcRect = { 0, 0, static_cast<LONG>(srcSurface.Width), static_cast<LONG>(srcSurface.Height) };
SCOPED_STATE(Texture, 1, *paletteTexture, D3DTEXF_POINT);
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psPaletteLookup, D3DTEXF_POINT);
setTempTextureStage(1, *paletteTexture, D3DTEXF_POINT);
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psPaletteLookup.get(), D3DTEXF_POINT);
}
void ShaderBlitter::setTempTextureStage(UINT stage, HANDLE texture, UINT filter)
{
auto& state = m_device.getState();
state.setTempTexture(stage, texture);
state.setTempTextureStageState({ stage, D3DDDITSS_ADDRESSU, D3DTADDRESS_CLAMP });
state.setTempTextureStageState({ stage, D3DDDITSS_ADDRESSV, D3DTADDRESS_CLAMP });
state.setTempTextureStageState({ stage, D3DDDITSS_MAGFILTER, filter });
state.setTempTextureStageState({ stage, D3DDDITSS_MINFILTER, filter });
state.setTempTextureStageState({ stage, D3DDDITSS_MIPFILTER, D3DTEXF_NONE });
state.setTempTextureStageState({ stage, D3DDDITSS_SRGBTEXTURE, D3DTEXF_LINEAR == filter });
state.setTempRenderState({ static_cast<D3DDDIRENDERSTATETYPE>(D3DDDIRS_WRAP0 + stage), 0 });
}
}

View File

@ -1,7 +1,11 @@
#pragma once
#include <memory>
#include <Windows.h>
#include <D3dDdi/ResourceDeleter.h>
namespace D3dDdi
{
class Device;
@ -27,19 +31,20 @@ namespace D3dDdi
const Resource& srcResource, const RECT& srcRect, HANDLE pixelShader, UINT filter);
template <int N>
HANDLE createPixelShader(const BYTE(&code)[N])
std::unique_ptr<void, ResourceDeleter> createPixelShader(const BYTE(&code)[N])
{
return createPixelShader(code, N);
}
HANDLE createPixelShader(const BYTE* code, UINT size);
HANDLE createVertexShaderDecl();
std::unique_ptr<void, ResourceDeleter> createPixelShader(const BYTE* code, UINT size);
std::unique_ptr<void, ResourceDeleter> createVertexShaderDecl();
void setTempTextureStage(UINT stage, HANDLE texture, UINT filter);
Device& m_device;
HANDLE m_psDrawCursor;
HANDLE m_psGenBilinear;
HANDLE m_psPaletteLookup;
HANDLE m_psTextureSampler;
HANDLE m_vertexShaderDecl;
std::unique_ptr<void, ResourceDeleter> m_psDrawCursor;
std::unique_ptr<void, ResourceDeleter> m_psGenBilinear;
std::unique_ptr<void, ResourceDeleter> m_psPaletteLookup;
std::unique_ptr<void, ResourceDeleter> m_psTextureSampler;
std::unique_ptr<void, ResourceDeleter> m_vertexShaderDecl;
};
}

View File

@ -191,6 +191,7 @@
</FxCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Common\BitSet.h" />
<ClInclude Include="Common\Comparison.h" />
<ClInclude Include="Common\CompatPtr.h" />
<ClInclude Include="Common\CompatQueryInterface.h" />
@ -241,6 +242,7 @@
<ClInclude Include="D3dDdi\Log\DeviceFuncsLog.h" />
<ClInclude Include="D3dDdi\Log\KernelModeThunksLog.h" />
<ClInclude Include="D3dDdi\Resource.h" />
<ClInclude Include="D3dDdi\ResourceDeleter.h" />
<ClInclude Include="D3dDdi\ScopedCriticalSection.h" />
<ClInclude Include="D3dDdi\ShaderBlitter.h" />
<ClInclude Include="D3dDdi\SurfaceRepository.h" />

View File

@ -495,6 +495,12 @@
<ClInclude Include="D3dDdi\Log\AdapterCallbacksLog.h">
<Filter>Header Files\D3dDdi\Log</Filter>
</ClInclude>
<ClInclude Include="Common\BitSet.h">
<Filter>Header Files\Common</Filter>
</ClInclude>
<ClInclude Include="D3dDdi\ResourceDeleter.h">
<Filter>Header Files\D3dDdi</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">