mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Perform P8 to R8G8B8 conversion in pixel shader
This commit is contained in:
parent
74460b2d24
commit
51a451f424
@ -44,6 +44,7 @@ namespace D3dDdi
|
||||
, m_sharedPrimary(nullptr)
|
||||
, m_drawPrimitive(*this)
|
||||
, m_state(*this)
|
||||
, m_shaderBlitter(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -51,6 +52,7 @@ namespace D3dDdi
|
||||
{
|
||||
s_devices.try_emplace(device, adapter, device);
|
||||
}
|
||||
|
||||
bool Device::checkSrcColorKeySupport()
|
||||
{
|
||||
if (!(m_adapter.getDDrawCaps().CKeyCaps & DDRAW_CKEYCAPS_SRCBLT))
|
||||
@ -211,6 +213,23 @@ namespace D3dDdi
|
||||
return it != m_resources.end() ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
void Device::prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly)
|
||||
{
|
||||
auto it = m_resources.find(resource);
|
||||
if (it != m_resources.end())
|
||||
{
|
||||
it->second.prepareForRendering(subResourceIndex, isReadOnly);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::prepareForRendering()
|
||||
{
|
||||
if (m_renderTarget)
|
||||
{
|
||||
m_renderTarget->prepareForRendering(m_renderTargetSubResourceIndex, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::setGdiResourceHandle(HANDLE resource)
|
||||
{
|
||||
ScopedCriticalSection lock;
|
||||
@ -234,20 +253,12 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
void Device::prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly)
|
||||
void Device::setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data)
|
||||
{
|
||||
auto it = m_resources.find(resource);
|
||||
if (it != m_resources.end())
|
||||
if (0 == data.RenderTargetIndex)
|
||||
{
|
||||
it->second.prepareForRendering(subResourceIndex, isReadOnly);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::prepareForRendering()
|
||||
{
|
||||
if (m_renderTarget)
|
||||
{
|
||||
m_renderTarget->prepareForRendering(m_renderTargetSubResourceIndex, false);
|
||||
m_renderTarget = getResource(data.hRenderTarget);
|
||||
m_renderTargetSubResourceIndex = data.SubResourceIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,7 +346,7 @@ namespace D3dDdi
|
||||
g_gdiResource = nullptr;
|
||||
}
|
||||
m_drawPrimitive.removeSysMemVertexBuffer(resource);
|
||||
m_state.removeTexture(resource);
|
||||
m_state.onDestroyResource(resource);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -412,28 +423,6 @@ namespace D3dDdi
|
||||
return m_origVtable.pfnPresent1(m_device, data);
|
||||
}
|
||||
|
||||
HRESULT Device::pfnSetRenderTarget(const D3DDDIARG_SETRENDERTARGET* data)
|
||||
{
|
||||
flushPrimitives();
|
||||
HRESULT result = m_origVtable.pfnSetRenderTarget(m_device, data);
|
||||
if (SUCCEEDED(result) && 0 == data->RenderTargetIndex)
|
||||
{
|
||||
m_renderTarget = getResource(data->hRenderTarget);
|
||||
m_renderTargetSubResourceIndex = data->SubResourceIndex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT Device::pfnSetStreamSource(const D3DDDIARG_SETSTREAMSOURCE* data)
|
||||
{
|
||||
return m_drawPrimitive.setStreamSource(*data);
|
||||
}
|
||||
|
||||
HRESULT Device::pfnSetStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM* data, const void* umBuffer)
|
||||
{
|
||||
return m_drawPrimitive.setStreamSourceUm(*data, umBuffer);
|
||||
}
|
||||
|
||||
HRESULT Device::pfnUnlock(const D3DDDIARG_UNLOCK* data)
|
||||
{
|
||||
flushPrimitives();
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <D3dDdi/DeviceState.h>
|
||||
#include <D3dDdi/DrawPrimitive.h>
|
||||
#include <D3dDdi/ShaderBlitter.h>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
@ -43,9 +44,6 @@ namespace D3dDdi
|
||||
HRESULT pfnOpenResource(D3DDDIARG_OPENRESOURCE* data);
|
||||
HRESULT pfnPresent(const D3DDDIARG_PRESENT* data);
|
||||
HRESULT pfnPresent1(D3DDDIARG_PRESENT1* data);
|
||||
HRESULT pfnSetRenderTarget(const D3DDDIARG_SETRENDERTARGET* data);
|
||||
HRESULT pfnSetStreamSource(const D3DDDIARG_SETSTREAMSOURCE* data);
|
||||
HRESULT pfnSetStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM* data, const void* umBuffer);
|
||||
HRESULT pfnUnlock(const D3DDDIARG_UNLOCK* data);
|
||||
|
||||
Adapter& getAdapter() const { return m_adapter; }
|
||||
@ -53,11 +51,13 @@ namespace D3dDdi
|
||||
const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||
Resource* getResource(HANDLE resource);
|
||||
DeviceState& getState() { return m_state; }
|
||||
ShaderBlitter& getShaderBlitter() { return m_shaderBlitter; }
|
||||
|
||||
HRESULT createPrivateResource(D3DDDIARG_CREATERESOURCE2& data);
|
||||
void flushPrimitives() { m_drawPrimitive.flushPrimitives(); }
|
||||
void prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly);
|
||||
void prepareForRendering();
|
||||
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data);
|
||||
|
||||
bool isSrcColorKeySupported() const { return m_isSrcColorKeySupported; }
|
||||
|
||||
@ -84,6 +84,7 @@ namespace D3dDdi
|
||||
HANDLE m_sharedPrimary;
|
||||
DrawPrimitive m_drawPrimitive;
|
||||
DeviceState m_state;
|
||||
ShaderBlitter m_shaderBlitter;
|
||||
bool m_isSrcColorKeySupported;
|
||||
|
||||
static std::map<HANDLE, Device> s_devices;
|
||||
|
@ -64,20 +64,21 @@ namespace
|
||||
SET_DEVICE_FUNC(pfnOpenResource);
|
||||
SET_DEVICE_FUNC(pfnPresent);
|
||||
SET_DEVICE_FUNC(pfnPresent1);
|
||||
SET_DEVICE_FUNC(pfnSetRenderTarget);
|
||||
SET_DEVICE_FUNC(pfnSetStreamSource);
|
||||
SET_DEVICE_FUNC(pfnSetStreamSourceUm);
|
||||
SET_DEVICE_FUNC(pfnUnlock);
|
||||
|
||||
SET_DEVICE_STATE_FUNC(pfnCreateVertexShaderDecl);
|
||||
SET_DEVICE_STATE_FUNC(pfnDeletePixelShader);
|
||||
SET_DEVICE_STATE_FUNC(pfnDeleteVertexShaderDecl);
|
||||
SET_DEVICE_STATE_FUNC(pfnDeleteVertexShaderFunc);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetDepthStencil);
|
||||
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(pfnSetRenderTarget);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetStreamSource);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetStreamSourceUm);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetTexture);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetTextureStageState);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderConst);
|
||||
@ -85,6 +86,7 @@ namespace
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderConstI);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderDecl);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetVertexShaderFunc);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetViewport);
|
||||
SET_DEVICE_STATE_FUNC(pfnSetZRange);
|
||||
SET_DEVICE_STATE_FUNC(pfnUpdateWInfo);
|
||||
|
||||
@ -94,10 +96,8 @@ namespace
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnDiscard);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnGenerateMipSubLevels);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnSetClipPlane);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnSetDepthStencil);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnSetPalette);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnSetScissorRect);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnSetViewport);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnStateSet);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnTexBlt);
|
||||
SET_FLUSH_PRIMITIVES_FUNC(pfnTexBlt1);
|
||||
|
@ -4,37 +4,138 @@
|
||||
#include <D3dDdi/DrawPrimitive.h>
|
||||
#include <D3dDdi/Log/DeviceFuncsLog.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
const UINT UNINITIALIZED_STATE = 0xBAADBAAD;
|
||||
const HANDLE UNINITIALIZED_HANDLE = reinterpret_cast<HANDLE>(0xBAADBAAD);
|
||||
|
||||
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(UNINITIALIZED_HANDLE)
|
||||
, m_vertexShaderDecl(UNINITIALIZED_HANDLE)
|
||||
, m_vertexShaderFunc(UNINITIALIZED_HANDLE)
|
||||
, m_wInfo{ NAN, NAN }
|
||||
, m_zRange{ NAN, NAN }
|
||||
, m_depthStencil{}
|
||||
, m_pixelShader(nullptr)
|
||||
, m_renderTarget{}
|
||||
, m_streamSource{}
|
||||
, m_streamSourceUm{}
|
||||
, m_streamSourceUmBuffer(nullptr)
|
||||
, m_textures{}
|
||||
, m_vertexShaderDecl(nullptr)
|
||||
, m_vertexShaderFunc(nullptr)
|
||||
, m_viewport{}
|
||||
, m_wInfo{}
|
||||
, m_zRange{}
|
||||
{
|
||||
const UINT D3DBLENDOP_ADD = 1;
|
||||
const UINT UNINITIALIZED_STATE = 0xBAADBAAD;
|
||||
|
||||
m_device.getOrigVtable().pfnSetDepthStencil(m_device, &m_depthStencil);
|
||||
m_device.getOrigVtable().pfnSetPixelShader(m_device, nullptr);
|
||||
m_device.getOrigVtable().pfnSetRenderTarget(m_device, &m_renderTarget);
|
||||
m_device.getOrigVtable().pfnSetVertexShaderDecl(m_device, nullptr);
|
||||
m_device.getOrigVtable().pfnSetVertexShaderFunc(m_device, nullptr);
|
||||
m_device.getOrigVtable().pfnSetViewport(m_device, &m_viewport);
|
||||
m_device.getOrigVtable().pfnUpdateWInfo(m_device, &m_wInfo);
|
||||
m_device.getOrigVtable().pfnSetZRange(m_device, &m_zRange);
|
||||
|
||||
m_renderState.fill(UNINITIALIZED_STATE);
|
||||
m_textures.fill(UNINITIALIZED_HANDLE);
|
||||
m_renderState[D3DDDIRS_ZENABLE] = D3DZB_TRUE;
|
||||
m_renderState[D3DDDIRS_FILLMODE] = D3DFILL_SOLID;
|
||||
m_renderState[D3DDDIRS_SHADEMODE] = D3DSHADE_GOURAUD;
|
||||
m_renderState[D3DDDIRS_LINEPATTERN] = 0;
|
||||
m_renderState[D3DDDIRS_ZWRITEENABLE] = TRUE;
|
||||
m_renderState[D3DDDIRS_ALPHATESTENABLE] = FALSE;
|
||||
m_renderState[D3DDDIRS_LASTPIXEL] = TRUE;
|
||||
m_renderState[D3DDDIRS_SRCBLEND] = D3DBLEND_ONE;
|
||||
m_renderState[D3DDDIRS_DESTBLEND] = D3DBLEND_ZERO;
|
||||
m_renderState[D3DDDIRS_CULLMODE] = D3DCULL_CCW;
|
||||
m_renderState[D3DDDIRS_ZFUNC] = D3DCMP_LESSEQUAL;
|
||||
m_renderState[D3DDDIRS_ALPHAREF] = 0;
|
||||
m_renderState[D3DDDIRS_ALPHAFUNC] = D3DCMP_ALWAYS;
|
||||
m_renderState[D3DDDIRS_DITHERENABLE] = FALSE;
|
||||
m_renderState[D3DDDIRS_ALPHABLENDENABLE] = FALSE;
|
||||
m_renderState[D3DDDIRS_FOGENABLE] = FALSE;
|
||||
m_renderState[D3DDDIRS_SPECULARENABLE] = FALSE;
|
||||
m_renderState[D3DDDIRS_ZVISIBLE] = 0;
|
||||
m_renderState[D3DDDIRS_FOGCOLOR] = 0;
|
||||
m_renderState[D3DDDIRS_FOGTABLEMODE] = D3DFOG_NONE;
|
||||
m_renderState[D3DDDIRS_FOGSTART] = 0;
|
||||
m_renderState[D3DDDIRS_FOGEND] = 0x3F800000;
|
||||
m_renderState[D3DDDIRS_FOGDENSITY] = 0x3F800000;
|
||||
m_renderState[D3DDDIRS_COLORKEYENABLE] = FALSE;
|
||||
m_renderState[D3DDDIRS_EDGEANTIALIAS] = 0;
|
||||
m_renderState[D3DDDIRS_ZBIAS] = 0;
|
||||
m_renderState[D3DDDIRS_RANGEFOGENABLE] = FALSE;
|
||||
for (UINT i = D3DDDIRS_STIPPLEPATTERN00; i <= D3DDDIRS_STIPPLEPATTERN31; ++i)
|
||||
{
|
||||
m_renderState[i] = 0;
|
||||
}
|
||||
m_renderState[D3DDDIRS_STENCILENABLE] = FALSE;
|
||||
m_renderState[D3DDDIRS_STENCILFAIL] = D3DSTENCILOP_KEEP;
|
||||
m_renderState[D3DDDIRS_STENCILZFAIL] = D3DSTENCILOP_KEEP;
|
||||
m_renderState[D3DDDIRS_STENCILPASS] = D3DSTENCILOP_KEEP;
|
||||
m_renderState[D3DDDIRS_STENCILFUNC] = D3DCMP_ALWAYS;
|
||||
m_renderState[D3DDDIRS_STENCILREF] = 0;
|
||||
m_renderState[D3DDDIRS_STENCILMASK] = 0xFFFFFFFF;
|
||||
m_renderState[D3DDDIRS_STENCILWRITEMASK] = 0xFFFFFFFF;
|
||||
m_renderState[D3DDDIRS_TEXTUREFACTOR] = 0xFFFFFFFF;
|
||||
for (UINT i = D3DDDIRS_WRAP0; i <= D3DDDIRS_WRAP7; ++i)
|
||||
{
|
||||
m_renderState[i] = 0;
|
||||
}
|
||||
m_renderState[D3DDDIRS_CLIPPING] = TRUE;
|
||||
m_renderState[D3DDDIRS_CLIPPLANEENABLE] = 0;
|
||||
m_renderState[D3DDDIRS_SOFTWAREVERTEXPROCESSING] = FALSE;
|
||||
m_renderState[D3DDDIRS_POINTSIZE_MAX] = 0x3F800000;
|
||||
m_renderState[D3DDDIRS_POINTSIZE] = 0x3F800000;
|
||||
m_renderState[D3DDDIRS_POINTSIZE_MIN] = 0;
|
||||
m_renderState[D3DDDIRS_POINTSPRITEENABLE] = 0;
|
||||
m_renderState[D3DDDIRS_MULTISAMPLEMASK] = 0xFFFFFFFF;
|
||||
m_renderState[D3DDDIRS_MULTISAMPLEANTIALIAS] = TRUE;
|
||||
m_renderState[D3DDDIRS_PATCHEDGESTYLE] = FALSE;
|
||||
m_renderState[D3DDDIRS_PATCHSEGMENTS] = 0x3F800000;
|
||||
m_renderState[D3DDDIRS_COLORWRITEENABLE] = 0xF;
|
||||
m_renderState[D3DDDIRS_BLENDOP] = D3DBLENDOP_ADD;
|
||||
|
||||
for (UINT i = 0; i < m_renderState.size(); i++)
|
||||
{
|
||||
if (UNINITIALIZED_STATE != m_renderState[i])
|
||||
{
|
||||
D3DDDIARG_RENDERSTATE data = {};
|
||||
data.State = static_cast<D3DDDIRENDERSTATETYPE>(i);
|
||||
data.Value = m_renderState[i];
|
||||
m_device.getOrigVtable().pfnSetRenderState(m_device, &data);
|
||||
}
|
||||
}
|
||||
|
||||
for (UINT i = 0; i < m_textures.size(); ++i)
|
||||
{
|
||||
m_device.getOrigVtable().pfnSetTexture(m_device, i, nullptr);
|
||||
}
|
||||
|
||||
for (UINT i = 0; i < m_textureStageState.size(); ++i)
|
||||
{
|
||||
m_textureStageState[i].fill(UNINITIALIZED_STATE);
|
||||
m_textureStageState[i][D3DDDITSS_TEXCOORDINDEX] = i;
|
||||
m_textureStageState[i][D3DDDITSS_ADDRESSU] = D3DTADDRESS_WRAP;
|
||||
m_textureStageState[i][D3DDDITSS_ADDRESSV] = D3DTADDRESS_WRAP;
|
||||
m_textureStageState[i][D3DDDITSS_BORDERCOLOR] = 0;
|
||||
m_textureStageState[i][D3DDDITSS_MAGFILTER] = D3DTEXF_POINT;
|
||||
m_textureStageState[i][D3DDDITSS_MINFILTER] = D3DTEXF_POINT;
|
||||
m_textureStageState[i][D3DDDITSS_MIPFILTER] = D3DTEXF_NONE;
|
||||
m_textureStageState[i][D3DDDITSS_MIPMAPLODBIAS] = 0;
|
||||
m_textureStageState[i][D3DDDITSS_MAXMIPLEVEL] = 0;
|
||||
m_textureStageState[i][D3DDDITSS_MAXANISOTROPY] = 1;
|
||||
m_textureStageState[i][D3DDDITSS_TEXTURETRANSFORMFLAGS] = D3DTTFF_DISABLE;
|
||||
m_textureStageState[i][D3DDDITSS_ADDRESSW] = D3DTADDRESS_WRAP;
|
||||
m_textureStageState[i][D3DDDITSS_DISABLETEXTURECOLORKEY] = TRUE;
|
||||
|
||||
for (UINT j = 0; j < m_textureStageState[i].size(); ++j)
|
||||
{
|
||||
if (UNINITIALIZED_STATE != m_textureStageState[i][j])
|
||||
{
|
||||
D3DDDIARG_TEXTURESTAGESTATE data = {};
|
||||
data.Stage = i;
|
||||
data.State = static_cast<D3DDDITEXTURESTAGESTATETYPE>(j);
|
||||
data.Value = m_textureStageState[i][j];
|
||||
m_device.getOrigVtable().pfnSetTextureStageState(m_device, &data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,6 +177,11 @@ namespace D3dDdi
|
||||
return deleteShader(shader, m_vertexShaderFunc, m_device.getOrigVtable().pfnDeleteVertexShaderFunc);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetDepthStencil(const D3DDDIARG_SETDEPTHSTENCIL* data)
|
||||
{
|
||||
return setState(data, m_depthStencil, m_device.getOrigVtable().pfnSetDepthStencil);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetPixelShader(HANDLE shader)
|
||||
{
|
||||
return setShader(shader, m_pixelShader, m_device.getOrigVtable().pfnSetPixelShader);
|
||||
@ -107,6 +213,40 @@ namespace D3dDdi
|
||||
return setStateArray(data, m_renderState, m_device.getOrigVtable().pfnSetRenderState);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetRenderTarget(const D3DDDIARG_SETRENDERTARGET* data)
|
||||
{
|
||||
HRESULT result = setState(data, m_renderTarget, m_device.getOrigVtable().pfnSetRenderTarget);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_device.setRenderTarget(*data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetStreamSource(const D3DDDIARG_SETSTREAMSOURCE* data)
|
||||
{
|
||||
HRESULT result = m_device.getDrawPrimitive().setStreamSource(*data);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_streamSource = *data;
|
||||
m_streamSourceUm = {};
|
||||
m_streamSourceUmBuffer = nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM* data, const void* umBuffer)
|
||||
{
|
||||
HRESULT result = m_device.getDrawPrimitive().setStreamSourceUm(*data, umBuffer);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_streamSourceUm = *data;
|
||||
m_streamSourceUmBuffer = umBuffer;
|
||||
m_streamSource = {};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetTexture(UINT stage, HANDLE texture)
|
||||
{
|
||||
if (stage >= m_textures.size())
|
||||
@ -115,8 +255,7 @@ namespace D3dDdi
|
||||
return m_device.getOrigVtable().pfnSetTexture(m_device, stage, texture);
|
||||
}
|
||||
|
||||
if (texture == m_textures[stage] &&
|
||||
texture != UNINITIALIZED_HANDLE)
|
||||
if (texture == m_textures[stage])
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
@ -126,23 +265,22 @@ namespace D3dDdi
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_textures[stage] = texture;
|
||||
m_textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY] = UNINITIALIZED_STATE;
|
||||
m_textureStageState[stage][D3DDDITSS_TEXTURECOLORKEYVAL] = UNINITIALIZED_STATE;
|
||||
m_textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY] = TRUE;
|
||||
|
||||
D3DDDIARG_TEXTURESTAGESTATE data = {};
|
||||
data.Stage = stage;
|
||||
data.State = D3DDDITSS_DISABLETEXTURECOLORKEY;
|
||||
data.Value = TRUE;
|
||||
m_device.getOrigVtable().pfnSetTextureStageState(m_device, &data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE* data)
|
||||
{
|
||||
switch (data->State)
|
||||
if (D3DDDITSS_TEXTURECOLORKEYVAL == data->State)
|
||||
{
|
||||
case D3DDDITSS_DISABLETEXTURECOLORKEY:
|
||||
m_textureStageState[data->Stage][D3DDDITSS_TEXTURECOLORKEYVAL] = UNINITIALIZED_STATE;
|
||||
break;
|
||||
|
||||
case D3DDDITSS_TEXTURECOLORKEYVAL:
|
||||
m_textureStageState[data->Stage][D3DDDITSS_DISABLETEXTURECOLORKEY] = UNINITIALIZED_STATE;
|
||||
break;
|
||||
m_textureStageState[data->Stage][D3DDDITSS_DISABLETEXTURECOLORKEY] = FALSE;
|
||||
}
|
||||
return setStateArray(data, m_textureStageState[data->Stage], m_device.getOrigVtable().pfnSetTextureStageState);
|
||||
}
|
||||
@ -185,6 +323,11 @@ namespace D3dDdi
|
||||
return setShader(shader, m_vertexShaderFunc, m_device.getOrigVtable().pfnSetVertexShaderFunc);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetViewport(const D3DDDIARG_VIEWPORTINFO* data)
|
||||
{
|
||||
return setState(data, m_viewport, m_device.getOrigVtable().pfnSetViewport);
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetZRange(const D3DDDIARG_ZRANGE* data)
|
||||
{
|
||||
return setState(data, m_zRange, m_device.getOrigVtable().pfnSetZRange);
|
||||
@ -211,27 +354,32 @@ namespace D3dDdi
|
||||
HRESULT result = origDeleteShaderFunc(m_device, shader);
|
||||
if (SUCCEEDED(result) && shader == currentShader)
|
||||
{
|
||||
currentShader = UNINITIALIZED_HANDLE;
|
||||
currentShader = nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DeviceState::removeTexture(HANDLE texture)
|
||||
void DeviceState::onDestroyResource(HANDLE resource)
|
||||
{
|
||||
for (UINT i = 0; i < m_textures.size(); ++i)
|
||||
{
|
||||
if (m_textures[i] == texture)
|
||||
if (m_textures[i] == resource)
|
||||
{
|
||||
m_textures[i] = UNINITIALIZED_HANDLE;
|
||||
m_textures[i] = nullptr;
|
||||
m_device.getOrigVtable().pfnSetTexture(m_device, i, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_renderTarget.hRenderTarget == resource)
|
||||
{
|
||||
m_renderTarget = {};
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DeviceState::setShader(HANDLE shader, HANDLE& currentShader,
|
||||
HRESULT(APIENTRY* origSetShaderFunc)(HANDLE, HANDLE))
|
||||
{
|
||||
if (shader == currentShader &&
|
||||
shader != UNINITIALIZED_HANDLE)
|
||||
if (shader == currentShader)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
@ -273,7 +421,7 @@ namespace D3dDdi
|
||||
HRESULT DeviceState::setState(const StateData* data, StateData& currentState,
|
||||
HRESULT(APIENTRY* origSetState)(HANDLE, const StateData*))
|
||||
{
|
||||
if (*data == currentState)
|
||||
if (0 == memcmp(data, ¤tState, sizeof(currentState)))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
@ -297,8 +445,7 @@ namespace D3dDdi
|
||||
return origSetState(m_device, data);
|
||||
}
|
||||
|
||||
if (data->Value == currentState[data->State] &&
|
||||
data->Value != UNINITIALIZED_STATE)
|
||||
if (data->Value == currentState[data->State])
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -4,6 +4,10 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
const UINT D3DTEXF_NONE = 0;
|
||||
const UINT D3DTEXF_POINT = 1;
|
||||
const UINT D3DTEXF_LINEAR = 2;
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
class Device;
|
||||
@ -17,11 +21,15 @@ namespace D3dDdi
|
||||
HRESULT pfnDeletePixelShader(HANDLE shader);
|
||||
HRESULT pfnDeleteVertexShaderDecl(HANDLE shader);
|
||||
HRESULT pfnDeleteVertexShaderFunc(HANDLE shader);
|
||||
HRESULT pfnSetDepthStencil(const D3DDDIARG_SETDEPTHSTENCIL* data);
|
||||
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 pfnSetRenderTarget(const D3DDDIARG_SETRENDERTARGET* data);
|
||||
HRESULT pfnSetStreamSource(const D3DDDIARG_SETSTREAMSOURCE* data);
|
||||
HRESULT pfnSetStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM* data, const void* umBuffer);
|
||||
HRESULT pfnSetTexture(UINT stage, HANDLE texture);
|
||||
HRESULT pfnSetTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE* data);
|
||||
HRESULT pfnSetVertexShaderConst(const D3DDDIARG_SETVERTEXSHADERCONST* data, const void* registers);
|
||||
@ -29,10 +37,11 @@ namespace D3dDdi
|
||||
HRESULT pfnSetVertexShaderConstI(const D3DDDIARG_SETVERTEXSHADERCONSTI* data, const INT* registers);
|
||||
HRESULT pfnSetVertexShaderDecl(HANDLE shader);
|
||||
HRESULT pfnSetVertexShaderFunc(HANDLE shader);
|
||||
HRESULT pfnSetViewport(const D3DDDIARG_VIEWPORTINFO* data);
|
||||
HRESULT pfnSetZRange(const D3DDDIARG_ZRANGE* data);
|
||||
HRESULT pfnUpdateWInfo(const D3DDDIARG_WINFO* data);
|
||||
|
||||
void removeTexture(HANDLE texture);
|
||||
void onDestroyResource(HANDLE resource);
|
||||
|
||||
private:
|
||||
typedef std::tuple<FLOAT, FLOAT, FLOAT, FLOAT> ShaderConstF;
|
||||
@ -57,11 +66,16 @@ namespace D3dDdi
|
||||
HRESULT(APIENTRY* origSetState)(HANDLE, const StateData*));
|
||||
|
||||
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;
|
||||
@ -70,7 +84,228 @@ namespace D3dDdi
|
||||
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 ScopedRenderState
|
||||
{
|
||||
public:
|
||||
ScopedRenderState(DeviceState& deviceState, const D3DDDIARG_RENDERSTATE& data)
|
||||
: m_deviceState(deviceState)
|
||||
, m_prevData{ data.State, deviceState.m_renderState[data.State] }
|
||||
{
|
||||
m_deviceState.pfnSetRenderState(&data);
|
||||
}
|
||||
|
||||
~ScopedRenderState()
|
||||
{
|
||||
m_deviceState.pfnSetRenderState(&m_prevData);
|
||||
}
|
||||
|
||||
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)
|
||||
: m_deviceState(deviceState)
|
||||
, m_prevData{ data.Stage, data.State, deviceState.m_textureStageState[data.Stage][data.State] }
|
||||
{
|
||||
m_deviceState.pfnSetTextureStageState(&data);
|
||||
}
|
||||
|
||||
~ScopedTextureStageState()
|
||||
{
|
||||
m_deviceState.pfnSetTextureStageState(&m_prevData);
|
||||
}
|
||||
|
||||
private:
|
||||
DeviceState& m_deviceState;
|
||||
D3DDDIARG_TEXTURESTAGESTATE m_prevData;
|
||||
};
|
||||
|
||||
class ScopedTexture
|
||||
{
|
||||
public:
|
||||
ScopedTexture(DeviceState& deviceState, UINT stage, HANDLE texture, UINT filter)
|
||||
: m_deviceState(deviceState)
|
||||
, m_stage(stage)
|
||||
, m_prevTexture(deviceState.m_textures[stage])
|
||||
, m_scopedAddressU(deviceState, { stage, D3DDDITSS_ADDRESSU, D3DTADDRESS_CLAMP })
|
||||
, m_scopedAddressV(deviceState, { stage, D3DDDITSS_ADDRESSV, D3DTADDRESS_CLAMP })
|
||||
, m_scopedMagFilter(deviceState, { stage, D3DDDITSS_MAGFILTER, filter })
|
||||
, m_scopedMinFilter(deviceState, { stage, D3DDDITSS_MINFILTER, filter })
|
||||
, m_scopedMipFilter(deviceState, { stage, D3DDDITSS_MIPFILTER, D3DTEXF_NONE })
|
||||
, m_scopedWrap(deviceState, { static_cast<D3DDDIRENDERSTATETYPE>(D3DDDIRS_WRAP0 + stage), 0 })
|
||||
, m_prevTextureColorKeyVal(deviceState.m_textureStageState[stage][D3DDDITSS_TEXTURECOLORKEYVAL])
|
||||
, m_prevDisableTextureColorKey(deviceState.m_textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY])
|
||||
{
|
||||
m_deviceState.pfnSetTexture(stage, texture);
|
||||
|
||||
D3DDDIARG_TEXTURESTAGESTATE data = {};
|
||||
data.Stage = stage;
|
||||
data.State = D3DDDITSS_DISABLETEXTURECOLORKEY;
|
||||
data.Value = TRUE;
|
||||
m_deviceState.pfnSetTextureStageState(&data);
|
||||
}
|
||||
|
||||
~ScopedTexture()
|
||||
{
|
||||
m_deviceState.pfnSetTexture(m_stage, m_prevTexture);
|
||||
|
||||
D3DDDIARG_TEXTURESTAGESTATE data = {};
|
||||
data.Stage = m_stage;
|
||||
if (m_prevDisableTextureColorKey)
|
||||
{
|
||||
data.State = D3DDDITSS_DISABLETEXTURECOLORKEY;
|
||||
data.Value = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.State = D3DDDITSS_TEXTURECOLORKEYVAL;
|
||||
data.Value = m_prevTextureColorKeyVal;
|
||||
}
|
||||
m_deviceState.pfnSetTextureStageState(&data);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -204,6 +204,12 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_RENDERSTATE& val)
|
||||
<< val.Value;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETDEPTHSTENCIL& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.hZBuffer;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETPIXELSHADERCONST& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
|
@ -25,6 +25,7 @@ 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_SETDEPTHSTENCIL& 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);
|
||||
|
@ -154,6 +154,13 @@ namespace D3dDdi
|
||||
fixResourceData(device, reinterpret_cast<D3DDDIARG_CREATERESOURCE&>(m_fixedData));
|
||||
m_formatInfo = getFormatInfo(m_fixedData.Format);
|
||||
|
||||
const bool isPalettized = D3DDDIFMT_P8 == m_fixedData.Format;
|
||||
if (isPalettized)
|
||||
{
|
||||
m_fixedData.Format = D3DDDIFMT_L8;
|
||||
m_fixedData.Flags.Texture = 1;
|
||||
}
|
||||
|
||||
HRESULT result = createResourceFunc(device, reinterpret_cast<Arg*>(&m_fixedData));
|
||||
if (FAILED(result))
|
||||
{
|
||||
@ -161,6 +168,12 @@ namespace D3dDdi
|
||||
}
|
||||
m_handle = m_fixedData.hResource;
|
||||
|
||||
if (isPalettized)
|
||||
{
|
||||
m_fixedData.Format = D3DDDIFMT_P8;
|
||||
m_fixedData.Flags.Texture = 0;
|
||||
}
|
||||
|
||||
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool &&
|
||||
0 != m_formatInfo.bytesPerPixel)
|
||||
{
|
||||
@ -432,7 +445,7 @@ namespace D3dDdi
|
||||
{
|
||||
LOG_FUNC("Resource::createSysMemResource", Compat::array(surfaceInfo.data(), surfaceInfo.size()));
|
||||
D3DDDIARG_CREATERESOURCE2 data = {};
|
||||
data.Format = m_fixedData.Format;
|
||||
data.Format = (D3DDDIFMT_P8 == m_fixedData.Format) ? D3DDDIFMT_L8 : m_fixedData.Format;
|
||||
data.Pool = D3DDDIPOOL_SYSTEMMEM;
|
||||
data.pSurfList = surfaceInfo.data();
|
||||
data.SurfCount = surfaceInfo.size();
|
||||
@ -526,47 +539,27 @@ namespace D3dDdi
|
||||
|
||||
HRESULT Resource::presentationBlt(const D3DDDIARG_BLT& data, Resource& srcResource)
|
||||
{
|
||||
if (D3DDDIFMT_P8 == srcResource.m_origData.Format)
|
||||
{
|
||||
D3DDDIARG_LOCK lock = {};
|
||||
lock.hResource = m_handle;
|
||||
lock.SubResourceIndex = data.DstSubResourceIndex;
|
||||
HRESULT result = m_device.getOrigVtable().pfnLock(m_device, &lock);
|
||||
if (FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
auto entries(Gdi::Palette::getHardwarePalette());
|
||||
DWORD pal[256] = {};
|
||||
for (UINT i = 0; i < 256; ++i)
|
||||
{
|
||||
pal[i] = (entries[i].peRed << 16) | (entries[i].peGreen << 8) | entries[i].peBlue;
|
||||
}
|
||||
|
||||
auto& srcLockData = srcResource.m_lockData[data.SrcSubResourceIndex];
|
||||
for (UINT y = 0; y < srcResource.m_fixedData.surfaceData[data.SrcSubResourceIndex].Height; ++y)
|
||||
{
|
||||
auto src = static_cast<const BYTE*>(srcLockData.data) + y * srcLockData.pitch;
|
||||
auto dst = reinterpret_cast<DWORD*>(static_cast<BYTE*>(lock.pSurfData) + y * lock.Pitch);
|
||||
for (UINT x = 0; x < srcResource.m_fixedData.surfaceData[data.SrcSubResourceIndex].Width; ++x)
|
||||
{
|
||||
dst[x] = pal[*src];
|
||||
++src;
|
||||
}
|
||||
}
|
||||
|
||||
D3DDDIARG_UNLOCK unlock = {};
|
||||
unlock.hResource = m_handle;
|
||||
unlock.SubResourceIndex = data.DstSubResourceIndex;
|
||||
return m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||
}
|
||||
|
||||
if (srcResource.m_lockResource &&
|
||||
srcResource.m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate)
|
||||
{
|
||||
srcResource.copyToVidMem(data.SrcSubResourceIndex);
|
||||
}
|
||||
|
||||
if (D3DDDIFMT_P8 == srcResource.m_origData.Format)
|
||||
{
|
||||
auto entries(Gdi::Palette::getHardwarePalette());
|
||||
RGBQUAD pal[256] = {};
|
||||
for (UINT i = 0; i < 256; ++i)
|
||||
{
|
||||
pal[i].rgbRed = entries[i].peRed;
|
||||
pal[i].rgbGreen = entries[i].peGreen;
|
||||
pal[i].rgbBlue = entries[i].peBlue;
|
||||
}
|
||||
|
||||
m_device.getShaderBlitter().palettizedBlt(*this, data.DstSubResourceIndex, srcResource, pal);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return m_device.getOrigVtable().pfnBlt(m_device, &data);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@ namespace D3dDdi
|
||||
Resource& operator=(Resource&&) = default;
|
||||
|
||||
operator HANDLE() const { return m_handle; }
|
||||
const D3DDDIARG_CREATERESOURCE2& getOrigDesc() const { return m_origData; }
|
||||
const D3DDDIARG_CREATERESOURCE2& getFixedDesc() const { return m_fixedData; }
|
||||
|
||||
HRESULT blt(D3DDDIARG_BLT data);
|
||||
HRESULT colorFill(D3DDDIARG_COLORFILL data);
|
||||
|
177
DDrawCompat/D3dDdi/ShaderBlitter.cpp
Normal file
177
DDrawCompat/D3dDdi/ShaderBlitter.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
#include <Common/Log.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/Resource.h>
|
||||
#include <D3dDdi/ShaderBlitter.h>
|
||||
#include <Shaders/PaletteLookup.h>
|
||||
|
||||
#define CONCAT_(a, b) a##b
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
#define SCOPED_STATE(state, ...) DeviceState::Scoped##state CONCAT(scopedState, __LINE__)(m_device.getState(), __VA_ARGS__)
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
ShaderBlitter::ShaderBlitter(Device& device)
|
||||
: m_device(device)
|
||||
, m_paletteTexture(nullptr)
|
||||
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup, sizeof(g_psPaletteLookup)))
|
||||
, m_vertexShaderDecl(createVertexShaderDecl())
|
||||
{
|
||||
D3DDDI_SURFACEINFO si = {};
|
||||
si.Width = 256;
|
||||
si.Height = 1;
|
||||
|
||||
D3DDDIARG_CREATERESOURCE2 cr = {};
|
||||
cr.Format = D3DDDIFMT_X8R8G8B8;
|
||||
cr.Pool = D3DDDIPOOL_VIDEOMEMORY;
|
||||
cr.pSurfList = &si;
|
||||
cr.SurfCount = 1;
|
||||
cr.Rotation = D3DDDI_ROTATION_IDENTITY;
|
||||
cr.Flags.Texture = 1;
|
||||
|
||||
m_device.createPrivateResource(cr);
|
||||
m_paletteTexture = cr.hResource;
|
||||
}
|
||||
|
||||
ShaderBlitter::~ShaderBlitter()
|
||||
{
|
||||
if (m_paletteTexture)
|
||||
{
|
||||
m_device.getOrigVtable().pfnDestroyResource(m_device, m_paletteTexture);
|
||||
m_paletteTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderBlitter::blt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, const RECT& srcRect, HANDLE pixelShader, UINT filter)
|
||||
{
|
||||
LOG_FUNC("ShaderBlitter::blt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||
static_cast<HANDLE>(srcResource), srcRect, pixelShader, filter);
|
||||
|
||||
if (!m_vertexShaderDecl || !pixelShader)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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 });
|
||||
|
||||
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(Texture, 0, srcResource, filter);
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float rhw;
|
||||
float tu;
|
||||
float tv;
|
||||
};
|
||||
|
||||
const float srcWidth = static_cast<float>(srcSurface.Width);
|
||||
const float srcHeight = static_cast<float>(srcSurface.Height);
|
||||
|
||||
Vertex vertices[4] = {
|
||||
{ dstRect.left - 0.5f, dstRect.top - 0.5f, 0, 1, srcRect.left / srcWidth, srcRect.top / srcHeight },
|
||||
{ dstRect.right - 0.5f, dstRect.top - 0.5f, 0, 1, srcRect.right / srcWidth, srcRect.top / srcHeight },
|
||||
{ dstRect.right - 0.5f, dstRect.bottom - 0.5f, 0, 1, srcRect.right / srcWidth, srcRect.bottom / srcHeight },
|
||||
{ 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);
|
||||
|
||||
D3DDDIARG_DRAWPRIMITIVE dp = {};
|
||||
dp.PrimitiveType = D3DPT_TRIANGLEFAN;
|
||||
dp.VStart = 0;
|
||||
dp.PrimitiveCount = 2;
|
||||
m_device.getDrawPrimitive().draw(dp, nullptr);
|
||||
}
|
||||
|
||||
HANDLE ShaderBlitter::createPixelShader(const BYTE* code, UINT size)
|
||||
{
|
||||
D3DDDIARG_CREATEPIXELSHADER data = {};
|
||||
data.CodeSize = size;
|
||||
if (FAILED(m_device.getOrigVtable().pfnCreatePixelShader(m_device, &data, reinterpret_cast<const UINT*>(code))))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return data.ShaderHandle;
|
||||
}
|
||||
|
||||
HANDLE ShaderBlitter::createVertexShaderDecl()
|
||||
{
|
||||
const UINT D3DDECLTYPE_FLOAT2 = 1;
|
||||
const UINT D3DDECLTYPE_FLOAT4 = 3;
|
||||
const UINT D3DDECLMETHOD_DEFAULT = 0;
|
||||
const UINT D3DDECLUSAGE_TEXCOORD = 5;
|
||||
const UINT D3DDECLUSAGE_POSITIONT = 9;
|
||||
|
||||
const D3DDDIVERTEXELEMENT vertexElements[] = {
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
|
||||
{ 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }
|
||||
};
|
||||
|
||||
D3DDDIARG_CREATEVERTEXSHADERDECL data = {};
|
||||
data.NumVertexElements = sizeof(vertexElements) / sizeof(vertexElements[0]);
|
||||
|
||||
if (FAILED(m_device.getOrigVtable().pfnCreateVertexShaderDecl(m_device, &data, vertexElements)))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return data.ShaderHandle;
|
||||
}
|
||||
|
||||
void ShaderBlitter::palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex,
|
||||
const Resource& srcResource, RGBQUAD palette[256])
|
||||
{
|
||||
if (!m_paletteTexture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
D3DDDIARG_LOCK lock = {};
|
||||
lock.hResource = m_paletteTexture;
|
||||
lock.Flags.Discard = 1;
|
||||
m_device.getOrigVtable().pfnLock(m_device, &lock);
|
||||
if (!lock.pSurfData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(lock.pSurfData, palette, 256 * sizeof(RGBQUAD));
|
||||
|
||||
D3DDDIARG_UNLOCK unlock = {};
|
||||
unlock.hResource = m_paletteTexture;
|
||||
m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||
|
||||
const auto& dstSurface = dstResource.getFixedDesc().pSurfList[dstSubResourceIndex];
|
||||
const auto& srcSurface = srcResource.getFixedDesc().pSurfList[0];
|
||||
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, m_paletteTexture, D3DTEXF_POINT);
|
||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psPaletteLookup, D3DTEXF_POINT);
|
||||
}
|
||||
}
|
35
DDrawCompat/D3dDdi/ShaderBlitter.h
Normal file
35
DDrawCompat/D3dDdi/ShaderBlitter.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
class Device;
|
||||
class Resource;
|
||||
|
||||
class ShaderBlitter
|
||||
{
|
||||
public:
|
||||
ShaderBlitter(Device& device);
|
||||
ShaderBlitter(const ShaderBlitter&) = delete;
|
||||
ShaderBlitter(ShaderBlitter&&) = delete;
|
||||
ShaderBlitter& operator=(const ShaderBlitter&) = delete;
|
||||
ShaderBlitter& operator=(ShaderBlitter&&) = delete;
|
||||
~ShaderBlitter();
|
||||
|
||||
void palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex,
|
||||
const Resource& srcResource, RGBQUAD palette[256]);
|
||||
|
||||
private:
|
||||
void blt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, const RECT& srcRect, HANDLE pixelShader, UINT filter);
|
||||
|
||||
HANDLE createPixelShader(const BYTE* code, UINT size);
|
||||
HANDLE createVertexShaderDecl();
|
||||
|
||||
Device& m_device;
|
||||
HANDLE m_paletteTexture;
|
||||
HANDLE m_psPaletteLookup;
|
||||
HANDLE m_vertexShaderDecl;
|
||||
};
|
||||
}
|
@ -255,7 +255,7 @@ namespace DDraw
|
||||
typename Types<DirectDraw>::TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
desc.dwBackBufferCount = 2;
|
||||
|
||||
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface;
|
||||
|
@ -61,26 +61,23 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetName>ddraw</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<IntDir>$(SolutionDir)Build\$(Configuration)\</IntDir>
|
||||
<MultiProcFXC>true</MultiProcFXC>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetName>ddraw</TargetName>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<IntDir>$(SolutionDir)Build\$(Configuration)\</IntDir>
|
||||
<MultiProcFXC>true</MultiProcFXC>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebugLogs|Win32'">
|
||||
<TargetName>ddraw</TargetName>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<IntDir>$(SolutionDir)Build\$(Configuration)\</IntDir>
|
||||
<MultiProcFXC>true</MultiProcFXC>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@ -94,6 +91,7 @@
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dbgeng.lib;dxguid.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
@ -109,6 +107,15 @@
|
||||
<AdditionalIncludeDirectories>$(IntDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>SPECIALBUILD=\"$(Configuration)\"</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<FxCompile>
|
||||
<VariableName>g_ps%(Filename)</VariableName>
|
||||
</FxCompile>
|
||||
<FxCompile>
|
||||
<ObjectFileOutput />
|
||||
<ShaderModel>2.0</ShaderModel>
|
||||
<HeaderFileOutput>$(IntDir)%(RelativeDir)%(Filename).h</HeaderFileOutput>
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@ -120,6 +127,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dbgeng.lib;dxguid.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
@ -134,6 +142,17 @@
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>$(IntDir)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<FxCompile>
|
||||
<VariableName>g_ps%(Filename)</VariableName>
|
||||
</FxCompile>
|
||||
<FxCompile>
|
||||
<HeaderFileOutput>$(IntDir)%(RelativeDir)%(Filename).h</HeaderFileOutput>
|
||||
</FxCompile>
|
||||
<FxCompile>
|
||||
<ObjectFileOutput />
|
||||
<ShaderModel>2.0</ShaderModel>
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebugLogs|Win32'">
|
||||
<ClCompile>
|
||||
@ -145,6 +164,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dbgeng.lib;dxguid.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
@ -160,6 +180,15 @@
|
||||
<AdditionalIncludeDirectories>$(IntDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>SPECIALBUILD=\"$(Configuration)\"</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<FxCompile>
|
||||
<VariableName>g_ps%(Filename)</VariableName>
|
||||
</FxCompile>
|
||||
<FxCompile>
|
||||
<ObjectFileOutput />
|
||||
<ShaderModel>2.0</ShaderModel>
|
||||
<HeaderFileOutput>$(IntDir)%(RelativeDir)%(Filename).h</HeaderFileOutput>
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Common\CompatPtr.h" />
|
||||
@ -203,6 +232,7 @@
|
||||
<ClInclude Include="D3dDdi\Log\KernelModeThunksLog.h" />
|
||||
<ClInclude Include="D3dDdi\Resource.h" />
|
||||
<ClInclude Include="D3dDdi\ScopedCriticalSection.h" />
|
||||
<ClInclude Include="D3dDdi\ShaderBlitter.h" />
|
||||
<ClInclude Include="D3dDdi\Visitors\AdapterCallbacksVisitor.h" />
|
||||
<ClInclude Include="D3dDdi\Visitors\AdapterFuncsVisitor.h" />
|
||||
<ClInclude Include="D3dDdi\Visitors\DeviceCallbacksVisitor.h" />
|
||||
@ -302,6 +332,7 @@
|
||||
<ClCompile Include="D3dDdi\Log\KernelModeThunksLog.cpp" />
|
||||
<ClCompile Include="D3dDdi\Resource.cpp" />
|
||||
<ClCompile Include="D3dDdi\ScopedCriticalSection.cpp" />
|
||||
<ClCompile Include="D3dDdi\ShaderBlitter.cpp" />
|
||||
<ClCompile Include="DDraw\Blitter.cpp" />
|
||||
<ClCompile Include="DDraw\DirectDraw.cpp" />
|
||||
<ClCompile Include="DDraw\DirectDrawClipper.cpp" />
|
||||
@ -359,6 +390,9 @@
|
||||
<ItemGroup>
|
||||
<None Include="genversion.ps1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="Shaders\PaletteLookup.hlsl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -88,6 +88,9 @@
|
||||
<Filter Include="Source Files\Config\Settings">
|
||||
<UniqueIdentifier>{0b4eec6c-ece5-4417-913c-8829b34ec08c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Shaders">
|
||||
<UniqueIdentifier>{00e06bd4-3f10-46dc-af0f-99834dfac835}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Gdi\Gdi.h">
|
||||
@ -417,6 +420,9 @@
|
||||
<ClInclude Include="Config\Settings\CpuAffinity.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3dDdi\ShaderBlitter.h">
|
||||
<Filter>Header Files\D3dDdi</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -656,6 +662,9 @@
|
||||
<ClCompile Include="Config\Settings\CpuAffinity.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3dDdi\ShaderBlitter.cpp">
|
||||
<Filter>Source Files\D3dDdi</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DDrawCompat.rc">
|
||||
@ -667,4 +676,9 @@
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="Shaders\PaletteLookup.hlsl">
|
||||
<Filter>Shaders</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
7
DDrawCompat/Shaders/PaletteLookup.hlsl
Normal file
7
DDrawCompat/Shaders/PaletteLookup.hlsl
Normal file
@ -0,0 +1,7 @@
|
||||
sampler2D s_texture : register(s0);
|
||||
sampler2D s_palette : register(s1);
|
||||
|
||||
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
|
||||
{
|
||||
return tex2D(s_palette, float2(tex2D(s_texture, texCoord).r, 0));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user