mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Replace RHW=INFINITY with RHW=1
Fixes invisible gauge needles in NASCAR Racing 3 (issue #83).
This commit is contained in:
parent
e9a2bdc83f
commit
324b4a77f0
@ -205,7 +205,7 @@ namespace D3dDdi
|
||||
data.pSurfList[0].pSysMem)
|
||||
{
|
||||
m_drawPrimitive.addSysMemVertexBuffer(data.hResource,
|
||||
static_cast<BYTE*>(const_cast<void*>(data.pSurfList[0].pSysMem)), data.Fvf);
|
||||
static_cast<BYTE*>(const_cast<void*>(data.pSurfList[0].pSysMem)));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ namespace D3dDdi
|
||||
HRESULT unlock(const D3DDDIARG_UNLOCK* data);
|
||||
|
||||
Adapter& getAdapter() const { return m_adapter; }
|
||||
DrawPrimitive& getDrawPrimitive() { return m_drawPrimitive; }
|
||||
const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||
Resource* getResource(HANDLE resource);
|
||||
DeviceState& getState() { return m_state; }
|
||||
|
@ -61,6 +61,7 @@ namespace D3dDdi
|
||||
vtable.pfnSetStreamSourceUm = &DEVICE_FUNC(setStreamSourceUm);
|
||||
vtable.pfnUnlock = &DEVICE_FUNC(unlock);
|
||||
|
||||
SET_DEVICE_STATE_FUNC(pfnCreateVertexShaderDecl);
|
||||
SET_DEVICE_STATE_FUNC(pfnDeletePixelShader);
|
||||
SET_DEVICE_STATE_FUNC(pfnDeleteVertexShaderDecl);
|
||||
SET_DEVICE_STATE_FUNC(pfnDeleteVertexShaderFunc);
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <Common/Log.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/DeviceState.h>
|
||||
#include <D3dDdi/DrawPrimitive.h>
|
||||
#include <D3dDdi/Log/DeviceFuncsLog.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -35,6 +38,19 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnCreateVertexShaderDecl(
|
||||
D3DDDIARG_CREATEVERTEXSHADERDECL* data,
|
||||
const D3DDDIVERTEXELEMENT* vertexElements)
|
||||
{
|
||||
LOG_DEBUG << Compat::array(vertexElements, data->NumVertexElements);
|
||||
HRESULT result = m_device.getOrigVtable().pfnCreateVertexShaderDecl(m_device, data, vertexElements);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_vertexShaderDecls[data->ShaderHandle].assign(vertexElements, vertexElements + data->NumVertexElements);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnDeletePixelShader(HANDLE shader)
|
||||
{
|
||||
return deleteShader(shader, m_pixelShader, m_device.getOrigVtable().pfnDeletePixelShader);
|
||||
@ -42,7 +58,17 @@ namespace D3dDdi
|
||||
|
||||
HRESULT DeviceState::pfnDeleteVertexShaderDecl(HANDLE shader)
|
||||
{
|
||||
return deleteShader(shader, m_vertexShaderDecl, m_device.getOrigVtable().pfnDeleteVertexShaderDecl);
|
||||
const bool isCurrentShader = shader == m_vertexShaderDecl;
|
||||
HRESULT result = deleteShader(shader, m_vertexShaderDecl, m_device.getOrigVtable().pfnDeleteVertexShaderDecl);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_vertexShaderDecls.erase(shader);
|
||||
if (isCurrentShader)
|
||||
{
|
||||
m_device.getDrawPrimitive().setVertexShaderDecl({});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnDeleteVertexShaderFunc(HANDLE shader)
|
||||
@ -132,7 +158,20 @@ namespace D3dDdi
|
||||
|
||||
HRESULT DeviceState::pfnSetVertexShaderDecl(HANDLE shader)
|
||||
{
|
||||
return setShader(shader, m_vertexShaderDecl, m_device.getOrigVtable().pfnSetVertexShaderDecl);
|
||||
HRESULT result = setShader(shader, m_vertexShaderDecl, m_device.getOrigVtable().pfnSetVertexShaderDecl);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
auto it = m_vertexShaderDecls.find(shader);
|
||||
if (it != m_vertexShaderDecls.end())
|
||||
{
|
||||
m_device.getDrawPrimitive().setVertexShaderDecl(it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_device.getDrawPrimitive().setVertexShaderDecl({});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetVertexShaderFunc(HANDLE shader)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace D3dDdi
|
||||
@ -12,6 +13,7 @@ namespace D3dDdi
|
||||
public:
|
||||
DeviceState(Device& device);
|
||||
|
||||
HRESULT pfnCreateVertexShaderDecl(D3DDDIARG_CREATEVERTEXSHADERDECL* data, const D3DDDIVERTEXELEMENT* vertexElements);
|
||||
HRESULT pfnDeletePixelShader(HANDLE shader);
|
||||
HRESULT pfnDeleteVertexShaderDecl(HANDLE shader);
|
||||
HRESULT pfnDeleteVertexShaderFunc(HANDLE shader);
|
||||
@ -65,6 +67,7 @@ namespace D3dDdi
|
||||
std::vector<ShaderConstF> m_vertexShaderConst;
|
||||
std::vector<BOOL> m_vertexShaderConstB;
|
||||
std::vector<ShaderConstI> m_vertexShaderConstI;
|
||||
std::map<HANDLE, std::vector<D3DDDIVERTEXELEMENT>> m_vertexShaderDecls;
|
||||
HANDLE m_vertexShaderDecl;
|
||||
HANDLE m_vertexShaderFunc;
|
||||
D3DDDIARG_WINFO m_wInfo;
|
||||
|
@ -55,6 +55,7 @@ namespace D3dDdi
|
||||
, m_indexBuffer(device, m_vertexBuffer ? INDEX_BUFFER_SIZE : 0)
|
||||
, m_streamSource{}
|
||||
, m_batched{}
|
||||
, m_isHwVertexProcessingUsed(false)
|
||||
{
|
||||
LOG_ONCE("Dynamic vertex buffers are " << (m_vertexBuffer ? "" : "not ") << "available");
|
||||
LOG_ONCE("Dynamic index buffers are " << (m_indexBuffer ? "" : "not ") << "available");
|
||||
@ -68,9 +69,9 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPrimitive::addSysMemVertexBuffer(HANDLE resource, BYTE* vertices, UINT fvf)
|
||||
void DrawPrimitive::addSysMemVertexBuffer(HANDLE resource, BYTE* vertices)
|
||||
{
|
||||
m_sysMemVertexBuffers[resource] = { vertices, fvf };
|
||||
m_sysMemVertexBuffers[resource] = vertices;
|
||||
}
|
||||
|
||||
void DrawPrimitive::appendIndexedVertices(const UINT16* indices, UINT count,
|
||||
@ -517,15 +518,6 @@ namespace D3dDdi
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void DrawPrimitive::fixFirstVertexRhw()
|
||||
{
|
||||
auto firstVertex = reinterpret_cast<D3DTLVERTEX*>(m_batched.vertices.data());
|
||||
if ((m_streamSource.fvf & D3DFVF_XYZRHW) && 0.0f == firstVertex->rhw)
|
||||
{
|
||||
firstVertex->rhw = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DrawPrimitive::flush(const UINT* flagBuffer)
|
||||
{
|
||||
D3DDDIARG_DRAWPRIMITIVE data = {};
|
||||
@ -535,8 +527,7 @@ namespace D3dDdi
|
||||
|
||||
if (m_streamSource.vertices)
|
||||
{
|
||||
fixFirstVertexRhw();
|
||||
data.VStart = loadVertices(m_batched.vertices.data(), getBatchedVertexCount());
|
||||
data.VStart = loadVertices(getBatchedVertexCount());
|
||||
}
|
||||
|
||||
clearBatchedPrimitives();
|
||||
@ -562,8 +553,7 @@ namespace D3dDdi
|
||||
|
||||
if (m_streamSource.vertices)
|
||||
{
|
||||
fixFirstVertexRhw();
|
||||
INT baseVertexIndex = loadVertices(m_batched.vertices.data(), data.NumVertices) - data.MinIndex;
|
||||
INT baseVertexIndex = loadVertices(data.NumVertices) - data.MinIndex;
|
||||
data.BaseVertexOffset = baseVertexIndex * static_cast<INT>(m_streamSource.stride);
|
||||
}
|
||||
|
||||
@ -623,8 +613,23 @@ namespace D3dDdi
|
||||
return -1;
|
||||
}
|
||||
|
||||
INT DrawPrimitive::loadVertices(const void* vertices, UINT count)
|
||||
INT DrawPrimitive::loadVertices(UINT count)
|
||||
{
|
||||
auto vertices = m_batched.vertices.data();
|
||||
if (!m_isHwVertexProcessingUsed)
|
||||
{
|
||||
UINT offset = 0;
|
||||
for (UINT i = 0; i < count; ++i)
|
||||
{
|
||||
auto v = reinterpret_cast<D3DTLVERTEX*>(vertices + offset);
|
||||
if (0 == v->rhw || INFINITY == v->rhw)
|
||||
{
|
||||
v->rhw = 1;
|
||||
}
|
||||
offset += m_streamSource.stride;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_vertexBuffer)
|
||||
{
|
||||
UINT size = count * m_streamSource.stride;
|
||||
@ -710,24 +715,24 @@ namespace D3dDdi
|
||||
auto it = m_sysMemVertexBuffers.find(data.hVertexBuffer);
|
||||
if (it != m_sysMemVertexBuffers.end())
|
||||
{
|
||||
return setSysMemStreamSource(it->second.vertices, data.Stride, it->second.fvf);
|
||||
return setSysMemStreamSource(it->second, data.Stride);
|
||||
}
|
||||
|
||||
flushPrimitives();
|
||||
HRESULT result = m_origVtable.pfnSetStreamSource(m_device, &data);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_streamSource = { nullptr, data.Stride, 0 };
|
||||
m_streamSource = { nullptr, data.Stride };
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DrawPrimitive::setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& data, const void* umBuffer)
|
||||
{
|
||||
return setSysMemStreamSource(static_cast<const BYTE*>(umBuffer), data.Stride, 0);
|
||||
return setSysMemStreamSource(static_cast<const BYTE*>(umBuffer), data.Stride);
|
||||
}
|
||||
|
||||
HRESULT DrawPrimitive::setSysMemStreamSource(const BYTE* vertices, UINT stride, UINT fvf)
|
||||
HRESULT DrawPrimitive::setSysMemStreamSource(const BYTE* vertices, UINT stride)
|
||||
{
|
||||
HRESULT result = S_OK;
|
||||
if (!m_streamSource.vertices || stride != m_streamSource.stride)
|
||||
@ -748,8 +753,22 @@ namespace D3dDdi
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_streamSource = { vertices, stride, fvf };
|
||||
m_streamSource = { vertices, stride };
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DrawPrimitive::setVertexShaderDecl(const std::vector<D3DDDIVERTEXELEMENT>& decl)
|
||||
{
|
||||
m_isHwVertexProcessingUsed = true;
|
||||
const UINT D3DDECLUSAGE_POSITIONT = 9;
|
||||
for (auto& vertexElement : decl)
|
||||
{
|
||||
if (D3DDECLUSAGE_POSITIONT == vertexElement.Usage)
|
||||
{
|
||||
m_isHwVertexProcessingUsed = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace D3dDdi
|
||||
public:
|
||||
DrawPrimitive(Device& device);
|
||||
|
||||
void addSysMemVertexBuffer(HANDLE resource, BYTE* vertices, UINT fvf);
|
||||
void addSysMemVertexBuffer(HANDLE resource, BYTE* vertices);
|
||||
void removeSysMemVertexBuffer(HANDLE resource);
|
||||
|
||||
HRESULT flushPrimitives(const UINT* flagBuffer = nullptr);
|
||||
@ -26,6 +26,7 @@ namespace D3dDdi
|
||||
HRESULT drawIndexed(D3DDDIARG_DRAWINDEXEDPRIMITIVE2 data, const UINT16* indices, const UINT* flagBuffer);
|
||||
HRESULT setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data);
|
||||
HRESULT setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& data, const void* umBuffer);
|
||||
void setVertexShaderDecl(const std::vector<D3DDDIVERTEXELEMENT>& decl);
|
||||
|
||||
private:
|
||||
struct BatchedPrimitives
|
||||
@ -43,13 +44,6 @@ namespace D3dDdi
|
||||
{
|
||||
const BYTE* vertices;
|
||||
UINT stride;
|
||||
UINT fvf;
|
||||
};
|
||||
|
||||
struct SysMemVertexBuffer
|
||||
{
|
||||
BYTE* vertices;
|
||||
UINT fvf;
|
||||
};
|
||||
|
||||
void appendIndexedVertices(const UINT16* indices, UINT count,
|
||||
@ -75,23 +69,23 @@ namespace D3dDdi
|
||||
void convertIndexedTriangleFanToList(UINT startPrimitive, UINT primitiveCount);
|
||||
void convertIndexedTriangleStripToList(UINT startPrimitive, UINT primitiveCount);
|
||||
void convertToTriangleList();
|
||||
void fixFirstVertexRhw();
|
||||
HRESULT flush(const UINT* flagBuffer);
|
||||
HRESULT flushIndexed(const UINT* flagBuffer);
|
||||
INT loadIndices(const void* indices, UINT count);
|
||||
INT loadVertices(const void* vertices, UINT count);
|
||||
INT loadVertices(UINT count);
|
||||
UINT getBatchedVertexCount() const;
|
||||
void rebaseIndices();
|
||||
void repeatLastBatchedVertex();
|
||||
|
||||
HRESULT setSysMemStreamSource(const BYTE* vertices, UINT stride, UINT fvf);
|
||||
HRESULT setSysMemStreamSource(const BYTE* vertices, UINT stride);
|
||||
|
||||
HANDLE m_device;
|
||||
const D3DDDI_DEVICEFUNCS& m_origVtable;
|
||||
DynamicVertexBuffer m_vertexBuffer;
|
||||
DynamicIndexBuffer m_indexBuffer;
|
||||
StreamSource m_streamSource;
|
||||
std::map<HANDLE, SysMemVertexBuffer> m_sysMemVertexBuffers;
|
||||
std::map<HANDLE, BYTE*> m_sysMemVertexBuffers;
|
||||
BatchedPrimitives m_batched;
|
||||
bool m_isHwVertexProcessingUsed;
|
||||
};
|
||||
}
|
||||
|
@ -95,6 +95,13 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE2& val)
|
||||
<< Compat::hex(val.Flags2.Value);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEVERTEXSHADERDECL& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.NumVertexElements
|
||||
<< val.ShaderHandle;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
@ -474,3 +481,14 @@ std::ostream& operator<<(std::ostream& os, D3DDDITEXTURESTAGESTATETYPE val)
|
||||
|
||||
return os << "D3DDDITSS_" << static_cast<DWORD>(val);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIVERTEXELEMENT& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.Stream
|
||||
<< val.Offset
|
||||
<< static_cast<UINT>(val.Type)
|
||||
<< static_cast<UINT>(val.Method)
|
||||
<< static_cast<UINT>(val.Usage)
|
||||
<< static_cast<UINT>(val.UsageIndex);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CLEAR& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_COLORFILL& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE2& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEVERTEXSHADERDECL& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE2& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWPRIMITIVE& val);
|
||||
@ -36,3 +37,4 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_ZRANGE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIBOX& val);
|
||||
std::ostream& operator<<(std::ostream& os, D3DDDIRENDERSTATETYPE val);
|
||||
std::ostream& operator<<(std::ostream& os, D3DDDITEXTURESTAGESTATETYPE val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIVERTEXELEMENT& val);
|
||||
|
Loading…
x
Reference in New Issue
Block a user