mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Eliminate redundant device state changes
This commit is contained in:
parent
bb8ce374e2
commit
ff5bcc031c
@ -24,9 +24,8 @@ namespace D3dDdi
|
||||
, m_renderTarget(nullptr)
|
||||
, m_renderTargetSubResourceIndex(0)
|
||||
, m_sharedPrimary(nullptr)
|
||||
, m_textures{}
|
||||
, m_vertexShaderDecl(nullptr)
|
||||
, m_drawPrimitive(*this)
|
||||
, m_state(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -226,44 +225,6 @@ namespace D3dDdi
|
||||
return m_drawPrimitive.setStreamSourceUm(*data, umBuffer);
|
||||
}
|
||||
|
||||
HRESULT Device::setTexture(UINT stage, HANDLE texture)
|
||||
{
|
||||
if (stage < m_textures.size())
|
||||
{
|
||||
if (texture == m_textures[stage])
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
flushPrimitives();
|
||||
HRESULT result = m_origVtable.pfnSetTexture(m_device, stage, texture);
|
||||
if (SUCCEEDED(result) && stage < m_textures.size())
|
||||
{
|
||||
m_textures[stage] = texture;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
flushPrimitives();
|
||||
return m_origVtable.pfnSetTexture(m_device, stage, texture);
|
||||
}
|
||||
|
||||
HRESULT Device::setVertexShaderDecl(HANDLE shader)
|
||||
{
|
||||
if (shader == m_vertexShaderDecl)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
flushPrimitives();
|
||||
HRESULT result = m_origVtable.pfnSetVertexShaderDecl(m_device, shader);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_vertexShaderDecl = shader;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT Device::unlock(const D3DDDIARG_UNLOCK* data)
|
||||
{
|
||||
flushPrimitives();
|
||||
@ -275,19 +236,6 @@ namespace D3dDdi
|
||||
return m_origVtable.pfnUnlock(m_device, data);
|
||||
}
|
||||
|
||||
HRESULT Device::updateWInfo(const D3DDDIARG_WINFO* data)
|
||||
{
|
||||
flushPrimitives();
|
||||
if (1.0f == data->WNear && 1.0f == data->WFar)
|
||||
{
|
||||
D3DDDIARG_WINFO wInfo = {};
|
||||
wInfo.WNear = 0.0f;
|
||||
wInfo.WFar = 1.0f;
|
||||
return m_origVtable.pfnUpdateWInfo(m_device, &wInfo);
|
||||
}
|
||||
return m_origVtable.pfnUpdateWInfo(m_device, data);
|
||||
}
|
||||
|
||||
Resource* Device::getGdiResource()
|
||||
{
|
||||
return g_gdiResource;
|
||||
@ -312,7 +260,7 @@ namespace D3dDdi
|
||||
|
||||
void Device::add(HANDLE adapter, HANDLE device)
|
||||
{
|
||||
s_devices.emplace(device, Device(adapter, device));
|
||||
s_devices.try_emplace(device, adapter, device);
|
||||
}
|
||||
|
||||
Device& Device::get(HANDLE device)
|
||||
@ -323,7 +271,7 @@ namespace D3dDdi
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return s_devices.emplace(device, Device(nullptr, device)).first->second;
|
||||
return s_devices.try_emplace(device, nullptr, device).first->second;
|
||||
}
|
||||
|
||||
void Device::remove(HANDLE device)
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
@ -8,6 +7,7 @@
|
||||
#include <d3dnthal.h>
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include <D3dDdi/DeviceState.h>
|
||||
#include <D3dDdi/DrawPrimitive.h>
|
||||
|
||||
namespace D3dDdi
|
||||
@ -18,6 +18,13 @@ namespace D3dDdi
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
Device(HANDLE adapter, HANDLE device);
|
||||
|
||||
Device(const Device&) = delete;
|
||||
Device(Device&&) = delete;
|
||||
Device& operator=(const Device&) = delete;
|
||||
Device& operator=(Device&&) = delete;
|
||||
|
||||
operator HANDLE() const { return m_device; }
|
||||
|
||||
HRESULT blt(const D3DDDIARG_BLT* data);
|
||||
@ -38,14 +45,12 @@ namespace D3dDdi
|
||||
HRESULT setRenderTarget(const D3DDDIARG_SETRENDERTARGET* data);
|
||||
HRESULT setStreamSource(const D3DDDIARG_SETSTREAMSOURCE* data);
|
||||
HRESULT setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM* data, const void* umBuffer);
|
||||
HRESULT setTexture(UINT stage, HANDLE texture);
|
||||
HRESULT setVertexShaderDecl(HANDLE shader);
|
||||
HRESULT unlock(const D3DDDIARG_UNLOCK* data);
|
||||
HRESULT updateWInfo(const D3DDDIARG_WINFO* data);
|
||||
|
||||
Adapter& getAdapter() const { return m_adapter; }
|
||||
const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||
Resource* getResource(HANDLE resource);
|
||||
DeviceState& getState() { return m_state; }
|
||||
|
||||
void flushPrimitives() { m_drawPrimitive.flushPrimitives(); }
|
||||
void prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly);
|
||||
@ -62,8 +67,6 @@ namespace D3dDdi
|
||||
static void setReadOnlyGdiLock(bool enable);
|
||||
|
||||
private:
|
||||
Device(HANDLE adapter, HANDLE device);
|
||||
|
||||
template <typename Arg>
|
||||
HRESULT createResourceImpl(Arg& data);
|
||||
|
||||
@ -74,9 +77,8 @@ namespace D3dDdi
|
||||
Resource* m_renderTarget;
|
||||
UINT m_renderTargetSubResourceIndex;
|
||||
HANDLE m_sharedPrimary;
|
||||
std::array<HANDLE, 8> m_textures;
|
||||
HANDLE m_vertexShaderDecl;
|
||||
DrawPrimitive m_drawPrimitive;
|
||||
DeviceState m_state;
|
||||
|
||||
static std::map<HANDLE, Device> s_devices;
|
||||
static bool s_isFlushEnabled;
|
||||
|
@ -3,12 +3,18 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename DeviceMethodPtr, DeviceMethodPtr deviceMethod, typename... Params>
|
||||
template <typename MethodPtr, MethodPtr deviceMethod, typename... Params>
|
||||
HRESULT WINAPI deviceFunc(HANDLE device, Params... params)
|
||||
{
|
||||
return (D3dDdi::Device::get(device).*deviceMethod)(params...);
|
||||
}
|
||||
|
||||
template <typename MethodPtr, MethodPtr deviceStateMethod, typename... Params>
|
||||
HRESULT WINAPI deviceStateFunc(HANDLE device, Params... params)
|
||||
{
|
||||
return (D3dDdi::Device::get(device).getState().*deviceStateMethod)(params...);
|
||||
}
|
||||
|
||||
HRESULT APIENTRY destroyDevice(HANDLE hDevice)
|
||||
{
|
||||
D3dDdi::Device::remove(hDevice);
|
||||
@ -24,6 +30,7 @@ namespace
|
||||
}
|
||||
|
||||
#define DEVICE_FUNC(func) deviceFunc<decltype(&Device::func), &Device::func>
|
||||
#define SET_DEVICE_STATE_FUNC(func) vtable.func = &deviceStateFunc<decltype(&DeviceState::func), &DeviceState::func>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
@ -31,7 +38,7 @@ namespace D3dDdi
|
||||
{
|
||||
Device::add(adapter, device);
|
||||
}
|
||||
|
||||
|
||||
void DeviceFuncs::setCompatVtable(D3DDDI_DEVICEFUNCS& vtable)
|
||||
{
|
||||
vtable.pfnBlt = &DEVICE_FUNC(blt);
|
||||
@ -52,40 +59,41 @@ namespace D3dDdi
|
||||
vtable.pfnSetRenderTarget = &DEVICE_FUNC(setRenderTarget);
|
||||
vtable.pfnSetStreamSource = &DEVICE_FUNC(setStreamSource);
|
||||
vtable.pfnSetStreamSourceUm = &DEVICE_FUNC(setStreamSourceUm);
|
||||
vtable.pfnSetTexture = &DEVICE_FUNC(setTexture);
|
||||
vtable.pfnSetVertexShaderDecl = &DEVICE_FUNC(setVertexShaderDecl);
|
||||
vtable.pfnUnlock = &DEVICE_FUNC(unlock);
|
||||
vtable.pfnUpdateWInfo = &DEVICE_FUNC(updateWInfo);
|
||||
|
||||
SET_DEVICE_STATE_FUNC(pfnDeletePixelShader);
|
||||
SET_DEVICE_STATE_FUNC(pfnDeleteVertexShaderDecl);
|
||||
SET_DEVICE_STATE_FUNC(pfnDeleteVertexShaderFunc);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetPixelShader);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetPixelShaderConst);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetPixelShaderConstB);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetPixelShaderConstI);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetRenderState);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetTexture);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetTextureStageState);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderConst);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderConstB);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderConstI);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderDecl);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderFunc);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetZRange);
|
||||
SET_DEVICE_STATE_FUNC(pfnUpdateWInfo);
|
||||
|
||||
#define FLUSH_PRIMITIVES(func) vtable.func = &flushPrimitives<decltype(&D3DDDI_DEVICEFUNCS::func), &D3DDDI_DEVICEFUNCS::func>
|
||||
FLUSH_PRIMITIVES(pfnBufBlt);
|
||||
FLUSH_PRIMITIVES(pfnBufBlt1);
|
||||
FLUSH_PRIMITIVES(pfnDeletePixelShader);
|
||||
FLUSH_PRIMITIVES(pfnDeleteVertexShaderDecl);
|
||||
FLUSH_PRIMITIVES(pfnDeleteVertexShaderFunc);
|
||||
FLUSH_PRIMITIVES(pfnDepthFill);
|
||||
FLUSH_PRIMITIVES(pfnDiscard);
|
||||
FLUSH_PRIMITIVES(pfnGenerateMipSubLevels);
|
||||
FLUSH_PRIMITIVES(pfnSetClipPlane);
|
||||
FLUSH_PRIMITIVES(pfnSetDepthStencil);
|
||||
FLUSH_PRIMITIVES(pfnSetPalette);
|
||||
FLUSH_PRIMITIVES(pfnSetPixelShader);
|
||||
FLUSH_PRIMITIVES(pfnSetPixelShaderConst);
|
||||
FLUSH_PRIMITIVES(pfnSetPixelShaderConstB);
|
||||
FLUSH_PRIMITIVES(pfnSetPixelShaderConstI);
|
||||
FLUSH_PRIMITIVES(pfnSetRenderState);
|
||||
FLUSH_PRIMITIVES(pfnSetScissorRect);
|
||||
FLUSH_PRIMITIVES(pfnSetTextureStageState);
|
||||
FLUSH_PRIMITIVES(pfnSetVertexShaderConst);
|
||||
FLUSH_PRIMITIVES(pfnSetVertexShaderConstB);
|
||||
FLUSH_PRIMITIVES(pfnSetVertexShaderConstI);
|
||||
FLUSH_PRIMITIVES(pfnSetVertexShaderFunc);
|
||||
FLUSH_PRIMITIVES(pfnSetViewport);
|
||||
FLUSH_PRIMITIVES(pfnStateSet);
|
||||
FLUSH_PRIMITIVES(pfnTexBlt);
|
||||
FLUSH_PRIMITIVES(pfnTexBlt1);
|
||||
FLUSH_PRIMITIVES(pfnUpdatePalette);
|
||||
FLUSH_PRIMITIVES(pfnSetZRange);
|
||||
#undef FLUSH_PRIMITIVES
|
||||
}
|
||||
}
|
||||
|
240
DDrawCompat/D3dDdi/DeviceState.cpp
Normal file
240
DDrawCompat/D3dDdi/DeviceState.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/DeviceState.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool operator==(const D3DDDIARG_ZRANGE& lhs, const D3DDDIARG_ZRANGE& rhs)
|
||||
{
|
||||
return lhs.MinZ == rhs.MinZ && lhs.MaxZ == rhs.MaxZ;
|
||||
}
|
||||
|
||||
bool operator==(const D3DDDIARG_WINFO& lhs, const D3DDDIARG_WINFO& rhs)
|
||||
{
|
||||
return lhs.WNear == rhs.WNear && lhs.WFar == rhs.WFar;
|
||||
}
|
||||
}
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
DeviceState::DeviceState(Device& device)
|
||||
: m_device(device)
|
||||
, m_pixelShader(nullptr)
|
||||
, m_textures{}
|
||||
, m_vertexShaderDecl(nullptr)
|
||||
, m_vertexShaderFunc(nullptr)
|
||||
, m_wInfo{ NAN, NAN }
|
||||
, m_zRange{ NAN, NAN }
|
||||
{
|
||||
m_renderState.fill(0xBAADBAAD);
|
||||
for (UINT i = 0; i < m_textureStageState.size(); ++i)
|
||||
{
|
||||
m_textureStageState[i].fill(0xBAADBAAD);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnDeletePixelShader(HANDLE shader)
|
||||
{
|
||||
return deleteShader(shader, m_pixelShader, m_device.getOrigVtable().pfnDeletePixelShader);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnDeleteVertexShaderDecl(HANDLE shader)
|
||||
{
|
||||
return deleteShader(shader, m_vertexShaderDecl, m_device.getOrigVtable().pfnDeleteVertexShaderDecl);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnDeleteVertexShaderFunc(HANDLE shader)
|
||||
{
|
||||
return deleteShader(shader, m_vertexShaderFunc, m_device.getOrigVtable().pfnDeleteVertexShaderFunc);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetPixelShader(HANDLE shader)
|
||||
{
|
||||
return setShader(shader, m_pixelShader, m_device.getOrigVtable().pfnSetPixelShader);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetPixelShaderConst(const D3DDDIARG_SETPIXELSHADERCONST* data, const FLOAT* registers)
|
||||
{
|
||||
return setShaderConst(data, registers, m_pixelShaderConst, m_device.getOrigVtable().pfnSetPixelShaderConst);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetPixelShaderConstB(const D3DDDIARG_SETPIXELSHADERCONSTB* data, const BOOL* registers)
|
||||
{
|
||||
return setShaderConst(data, registers, m_pixelShaderConstB, m_device.getOrigVtable().pfnSetPixelShaderConstB);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetPixelShaderConstI(const D3DDDIARG_SETPIXELSHADERCONSTI* data, const INT* registers)
|
||||
{
|
||||
return setShaderConst(data, registers, m_pixelShaderConstI, m_device.getOrigVtable().pfnSetPixelShaderConstI);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetRenderState(const D3DDDIARG_RENDERSTATE* data)
|
||||
{
|
||||
return setStateArray(data, m_renderState, m_device.getOrigVtable().pfnSetRenderState);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetTexture(UINT stage, HANDLE texture)
|
||||
{
|
||||
if (stage >= m_textures.size())
|
||||
{
|
||||
m_device.flushPrimitives();
|
||||
return m_device.getOrigVtable().pfnSetTexture(m_device, stage, texture);
|
||||
}
|
||||
|
||||
if (texture == m_textures[stage])
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_device.flushPrimitives();
|
||||
HRESULT result = m_device.getOrigVtable().pfnSetTexture(m_device, stage, texture);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_textures[stage] = texture;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE* data)
|
||||
{
|
||||
return setStateArray(data, m_textureStageState[data->Stage], m_device.getOrigVtable().pfnSetTextureStageState);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetVertexShaderConst(const D3DDDIARG_SETVERTEXSHADERCONST* data, const void* registers)
|
||||
{
|
||||
return setShaderConst(data, registers, m_vertexShaderConst, m_device.getOrigVtable().pfnSetVertexShaderConst);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetVertexShaderConstB(const D3DDDIARG_SETVERTEXSHADERCONSTB* data, const BOOL* registers)
|
||||
{
|
||||
return setShaderConst(data, registers, m_vertexShaderConstB, m_device.getOrigVtable().pfnSetVertexShaderConstB);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetVertexShaderConstI(const D3DDDIARG_SETVERTEXSHADERCONSTI* data, const INT* registers)
|
||||
{
|
||||
return setShaderConst(data, registers, m_vertexShaderConstI, m_device.getOrigVtable().pfnSetVertexShaderConstI);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetVertexShaderDecl(HANDLE shader)
|
||||
{
|
||||
return setShader(shader, m_vertexShaderDecl, m_device.getOrigVtable().pfnSetVertexShaderDecl);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetVertexShaderFunc(HANDLE shader)
|
||||
{
|
||||
return setShader(shader, m_vertexShaderFunc, m_device.getOrigVtable().pfnSetVertexShaderFunc);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetZRange(const D3DDDIARG_ZRANGE* data)
|
||||
{
|
||||
return setState(data, m_zRange, m_device.getOrigVtable().pfnSetZRange);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnUpdateWInfo(const D3DDDIARG_WINFO* data)
|
||||
{
|
||||
D3DDDIARG_WINFO wInfo = *data;
|
||||
if (1.0f == wInfo.WNear && 1.0f == wInfo.WFar)
|
||||
{
|
||||
wInfo.WNear = 0.0f;
|
||||
}
|
||||
return setState(&wInfo, m_wInfo, m_device.getOrigVtable().pfnUpdateWInfo);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::deleteShader(HANDLE shader, HANDLE& currentShader,
|
||||
HRESULT(APIENTRY* origDeleteShaderFunc)(HANDLE, HANDLE))
|
||||
{
|
||||
if (shader == currentShader)
|
||||
{
|
||||
m_device.flushPrimitives();
|
||||
}
|
||||
|
||||
HRESULT result = origDeleteShaderFunc(m_device, shader);
|
||||
if (SUCCEEDED(result) && shader == currentShader)
|
||||
{
|
||||
currentShader = nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::setShader(HANDLE shader, HANDLE& currentShader,
|
||||
HRESULT(APIENTRY* origSetShaderFunc)(HANDLE, HANDLE))
|
||||
{
|
||||
if (shader == currentShader)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_device.flushPrimitives();
|
||||
HRESULT result = origSetShaderFunc(m_device, shader);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
currentShader = shader;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename SetShaderConstData, typename ShaderConst, typename Registers>
|
||||
HRESULT DeviceState::setShaderConst(const SetShaderConstData* data, const Registers* registers,
|
||||
std::vector<ShaderConst>& shaderConst,
|
||||
HRESULT(APIENTRY* origSetShaderConstFunc)(HANDLE, const SetShaderConstData*, const Registers*))
|
||||
{
|
||||
if (data->Register + data->Count > shaderConst.size())
|
||||
{
|
||||
shaderConst.resize(data->Register + data->Count);
|
||||
}
|
||||
|
||||
if (0 == memcmp(&shaderConst[data->Register], registers, data->Count * sizeof(ShaderConst)))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_device.flushPrimitives();
|
||||
HRESULT result = origSetShaderConstFunc(m_device, data, registers);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
memcpy(&shaderConst[data->Register], registers, data->Count * sizeof(ShaderConst));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename StateData>
|
||||
HRESULT DeviceState::setState(const StateData* data, StateData& currentState,
|
||||
HRESULT(APIENTRY* origSetState)(HANDLE, const StateData*))
|
||||
{
|
||||
if (*data == currentState)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_device.flushPrimitives();
|
||||
HRESULT result = origSetState(m_device, data);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
currentState = *data;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename StateData, UINT size>
|
||||
HRESULT DeviceState::setStateArray(const StateData* data, std::array<UINT, size>& currentState,
|
||||
HRESULT(APIENTRY* origSetState)(HANDLE, const StateData*))
|
||||
{
|
||||
if (data->State >= static_cast<INT>(currentState.size()))
|
||||
{
|
||||
m_device.flushPrimitives();
|
||||
return origSetState(m_device, data);
|
||||
}
|
||||
|
||||
if (data->Value == currentState[data->State])
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_device.flushPrimitives();
|
||||
HRESULT result = origSetState(m_device, data);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
currentState[data->State] = data->Value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
71
DDrawCompat/D3dDdi/DeviceState.h
Normal file
71
DDrawCompat/D3dDdi/DeviceState.h
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
class Device;
|
||||
|
||||
class DeviceState
|
||||
{
|
||||
public:
|
||||
DeviceState(Device& device);
|
||||
|
||||
HRESULT pfnDeletePixelShader(HANDLE shader);
|
||||
HRESULT pfnDeleteVertexShaderDecl(HANDLE shader);
|
||||
HRESULT pfnDeleteVertexShaderFunc(HANDLE shader);
|
||||
HRESULT pfnSetPixelShader(HANDLE shader);
|
||||
HRESULT pfnSetPixelShaderConst(const D3DDDIARG_SETPIXELSHADERCONST* data, const FLOAT* registers);
|
||||
HRESULT pfnSetPixelShaderConstB(const D3DDDIARG_SETPIXELSHADERCONSTB* data, const BOOL* registers);
|
||||
HRESULT pfnSetPixelShaderConstI(const D3DDDIARG_SETPIXELSHADERCONSTI* data, const INT* registers);
|
||||
HRESULT pfnSetRenderState(const D3DDDIARG_RENDERSTATE* data);
|
||||
HRESULT pfnSetTexture(UINT stage, HANDLE texture);
|
||||
HRESULT pfnSetTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE* data);
|
||||
HRESULT pfnSetVertexShaderConst(const D3DDDIARG_SETVERTEXSHADERCONST* data, const void* registers);
|
||||
HRESULT pfnSetVertexShaderConstB(const D3DDDIARG_SETVERTEXSHADERCONSTB* data, const BOOL* registers);
|
||||
HRESULT pfnSetVertexShaderConstI(const D3DDDIARG_SETVERTEXSHADERCONSTI* data, const INT* registers);
|
||||
HRESULT pfnSetVertexShaderDecl(HANDLE shader);
|
||||
HRESULT pfnSetVertexShaderFunc(HANDLE shader);
|
||||
HRESULT pfnSetZRange(const D3DDDIARG_ZRANGE* data);
|
||||
HRESULT pfnUpdateWInfo(const D3DDDIARG_WINFO* data);
|
||||
|
||||
private:
|
||||
typedef std::tuple<FLOAT, FLOAT, FLOAT, FLOAT> ShaderConstF;
|
||||
typedef std::tuple<INT, INT, INT, INT> ShaderConstI;
|
||||
|
||||
HRESULT deleteShader(HANDLE shader, HANDLE& currentShader,
|
||||
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 StateData>
|
||||
HRESULT setState(const StateData* data, StateData& currentState,
|
||||
HRESULT(APIENTRY* origSetState)(HANDLE, const StateData*));
|
||||
|
||||
template <typename StateData, UINT size>
|
||||
HRESULT setStateArray(const StateData* data, std::array<UINT, size>& currentState,
|
||||
HRESULT(APIENTRY* origSetState)(HANDLE, const StateData*));
|
||||
|
||||
Device& m_device;
|
||||
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;
|
||||
std::array<HANDLE, 8> m_textures;
|
||||
std::array<std::array<UINT, D3DDDITSS_CONSTANT + 1>, 8> m_textureStageState;
|
||||
std::vector<ShaderConstF> m_vertexShaderConst;
|
||||
std::vector<BOOL> m_vertexShaderConstB;
|
||||
std::vector<ShaderConstI> m_vertexShaderConstI;
|
||||
HANDLE m_vertexShaderDecl;
|
||||
HANDLE m_vertexShaderFunc;
|
||||
D3DDDIARG_WINFO m_wInfo;
|
||||
D3DDDIARG_ZRANGE m_zRange;
|
||||
};
|
||||
}
|
@ -598,6 +598,8 @@ namespace D3dDdi
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LOG_DEBUG << "Flushing " << m_batched.primitiveCount << " primitives of type " << m_batched.primitiveType;
|
||||
return m_batched.indices.empty() ? flush(flagBuffer) : flushIndexed(flagBuffer);
|
||||
}
|
||||
|
||||
|
@ -197,6 +197,13 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_RENDERSTATE& val)
|
||||
<< val.Value;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETPIXELSHADERCONST& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.Register
|
||||
<< val.Count;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETRENDERTARGET& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
@ -221,6 +228,13 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCEUM& va
|
||||
<< val.Stride;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETVERTEXSHADERCONST& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.Register
|
||||
<< val.Count;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_TEXTURESTAGESTATE& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
|
@ -24,9 +24,11 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_PRESENT& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_PRESENT1& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_PRESENTSURFACE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_RENDERSTATE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETPIXELSHADERCONST& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETRENDERTARGET& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCEUM& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETVERTEXSHADERCONST& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_TEXTURESTAGESTATE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_UNLOCK& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_WINFO& val);
|
||||
|
@ -154,6 +154,7 @@
|
||||
<ClInclude Include="D3dDdi\Device.h" />
|
||||
<ClInclude Include="D3dDdi\DeviceCallbacks.h" />
|
||||
<ClInclude Include="D3dDdi\DeviceFuncs.h" />
|
||||
<ClInclude Include="D3dDdi\DeviceState.h" />
|
||||
<ClInclude Include="D3dDdi\DrawPrimitive.h" />
|
||||
<ClInclude Include="D3dDdi\DynamicBuffer.h" />
|
||||
<ClInclude Include="D3dDdi\FormatInfo.h" />
|
||||
@ -244,6 +245,7 @@
|
||||
<ClCompile Include="D3dDdi\Device.cpp" />
|
||||
<ClCompile Include="D3dDdi\DeviceCallbacks.cpp" />
|
||||
<ClCompile Include="D3dDdi\DeviceFuncs.cpp" />
|
||||
<ClCompile Include="D3dDdi\DeviceState.cpp" />
|
||||
<ClCompile Include="D3dDdi\DrawPrimitive.cpp" />
|
||||
<ClCompile Include="D3dDdi\DynamicBuffer.cpp" />
|
||||
<ClCompile Include="D3dDdi\FormatInfo.cpp" />
|
||||
|
@ -390,6 +390,9 @@
|
||||
<ClInclude Include="D3dDdi\DynamicBuffer.h">
|
||||
<Filter>Header Files\D3dDdi</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3dDdi\DeviceState.h">
|
||||
<Filter>Header Files\D3dDdi</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -599,5 +602,8 @@
|
||||
<ClCompile Include="D3dDdi\DynamicBuffer.cpp">
|
||||
<Filter>Source Files\D3dDdi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3dDdi\DeviceState.cpp">
|
||||
<Filter>Source Files\D3dDdi</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user