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

Fixed texture stage count determination

This commit is contained in:
narzoul 2023-01-29 23:48:50 +01:00
parent bfc5a0be24
commit bf9833946a
5 changed files with 42 additions and 12 deletions

View File

@ -47,11 +47,13 @@ namespace D3dDdi
, m_vertexShaderConst{}
, m_vertexShaderConstB{}
, m_vertexShaderConstI{}
, m_vertexDecl(nullptr)
, m_changedStates(0)
, m_maxChangedTextureStage(0)
, m_changedTextureStageStates{}
, m_vsVertexFixup(createVertexShader(g_vsVertexFixup))
, m_textureResource{}
, m_pixelShader(nullptr)
, m_isLocked(false)
, m_spriteMode(false)
{
@ -275,11 +277,15 @@ namespace D3dDdi
return m_textureResource[stage];
}
UINT DeviceState::getTextureStageCount() const
{
return m_pixelShader ? m_pixelShader->textureStageCount : 0;
}
const DeviceState::VertexDecl& DeviceState::getVertexDecl() const
{
static const VertexDecl emptyDecl = {};
auto it = m_vertexShaderDecls.find(m_app.vertexShaderDecl);
return it != m_vertexShaderDecls.end() ? it->second : emptyDecl;
return m_vertexDecl ? *m_vertexDecl : emptyDecl;
}
bool DeviceState::isColorKeyUsed()
@ -290,7 +296,8 @@ namespace D3dDdi
}
bool used = false;
for (UINT i = 0; i < getVertexDecl().textureStageCount && !used; ++i)
UINT textureStageCount = getTextureStageCount();
for (UINT i = 0; i < textureStageCount && !used; ++i)
{
used = !m_app.textureStageState[i][D3DDDITSS_DISABLETEXTURECOLORKEY];
}
@ -426,15 +433,17 @@ namespace D3dDdi
HRESULT DeviceState::pfnCreatePixelShader(D3DDDIARG_CREATEPIXELSHADER* data, const UINT* code)
{
ShaderAssembler shaderAssembler(code, data->CodeSize);
LOG_DEBUG << "Pixel shader bytecode: " << Compat::hexDump(code, data->CodeSize);
LOG_DEBUG << ShaderAssembler(code, data->CodeSize).disassemble();
LOG_DEBUG << shaderAssembler.disassemble();
HRESULT result = m_device.getOrigVtable().pfnCreatePixelShader(m_device, data, code);
if (SUCCEEDED(result))
{
m_pixelShaders.emplace(data->ShaderHandle,
PixelShader{ std::vector<UINT>(code, code + data->CodeSize / 4),
std::unique_ptr<void, ResourceDeleter>(
nullptr, ResourceDeleter(m_device, m_device.getOrigVtable().pfnDeleteVertexShaderFunc)) });
nullptr, ResourceDeleter(m_device, m_device.getOrigVtable().pfnDeleteVertexShaderFunc)),
shaderAssembler.getTextureStageCount(), false });
}
return result;
}
@ -459,10 +468,6 @@ namespace D3dDdi
{
decl.texCoordOffset[vertexElements[i].UsageIndex] = vertexElements[i].Offset;
decl.texCoordType[vertexElements[i].UsageIndex] = vertexElements[i].Type;
if (vertexElements[i].UsageIndex >= decl.textureStageCount)
{
decl.textureStageCount = vertexElements[i].UsageIndex + 1;
}
}
else if (D3DDECLUSAGE_POSITIONT == vertexElements[i].Usage)
{
@ -487,6 +492,10 @@ namespace D3dDdi
auto it = m_pixelShaders.find(shader);
if (it != m_pixelShaders.end())
{
if (m_pixelShader == &it->second)
{
m_pixelShader = nullptr;
}
if (it->second.modifiedPixelShader)
{
deleteShader(it->second.modifiedPixelShader.release(), &State::pixelShader,
@ -500,9 +509,14 @@ namespace D3dDdi
HRESULT DeviceState::pfnDeleteVertexShaderDecl(HANDLE shader)
{
const bool isCurrent = m_app.vertexShaderDecl == shader;
HRESULT result = deleteShader(shader, &State::vertexShaderDecl, m_device.getOrigVtable().pfnDeleteVertexShaderDecl);
if (SUCCEEDED(result))
{
if (isCurrent)
{
m_vertexDecl = nullptr;
}
m_vertexShaderDecls.erase(shader);
}
return result;
@ -525,6 +539,8 @@ namespace D3dDdi
{
m_app.pixelShader = shader;
m_changedStates |= CS_SHADER;
auto it = m_pixelShaders.find(shader);
m_pixelShader = it != m_pixelShaders.end() ? &it->second : nullptr;
return S_OK;
}
@ -636,6 +652,8 @@ namespace D3dDdi
{
m_app.vertexShaderDecl = shader;
m_changedStates |= CS_SHADER;
auto it = m_vertexShaderDecls.find(shader);
m_vertexDecl = it != m_vertexShaderDecls.end() ? &it->second : nullptr;
return S_OK;
}
@ -669,7 +687,8 @@ namespace D3dDdi
void DeviceState::prepareTextures()
{
for (UINT stage = 0; stage < getVertexDecl().textureStageCount; ++stage)
UINT textureStageCount = getTextureStageCount();
for (UINT stage = 0; stage < textureStageCount; ++stage)
{
auto resource = getTextureResource(stage);
if (resource)

View File

@ -80,7 +80,6 @@ namespace D3dDdi
std::vector<D3DDDIVERTEXELEMENT> elements;
std::array<UINT, 8> texCoordOffset;
std::array<UINT, 8> texCoordType;
UINT textureStageCount;
bool isTransformed;
};
@ -130,6 +129,7 @@ namespace D3dDdi
const State& getAppState() const { return m_app; }
const State& getCurrentState() const { return m_current; }
Resource* getTextureResource(UINT stage);
UINT getTextureStageCount() const;
const VertexDecl& getVertexDecl() const;
HANDLE getVertexFixupDecl() const { return m_vsVertexFixup.get(); }
bool isLocked() const { return m_isLocked; }
@ -153,6 +153,7 @@ namespace D3dDdi
{
std::vector<UINT> tokens;
std::unique_ptr<void, ResourceDeleter> modifiedPixelShader;
UINT textureStageCount;
bool isModified;
};
@ -217,6 +218,7 @@ namespace D3dDdi
std::array<ShaderConstB, 16> m_vertexShaderConstB;
std::array<ShaderConstI, 16> m_vertexShaderConstI;
std::map<HANDLE, VertexDecl> m_vertexShaderDecls;
VertexDecl* m_vertexDecl;
UINT m_changedStates;
UINT m_maxChangedTextureStage;
UINT m_usedTextureStages;
@ -225,6 +227,7 @@ namespace D3dDdi
std::unique_ptr<void, ResourceDeleter> m_vsVertexFixup;
std::array<Resource*, 8> m_textureResource;
std::map<HANDLE, PixelShader> m_pixelShaders;
PixelShader* m_pixelShader;
bool m_isLocked;
bool m_spriteMode;
};

View File

@ -829,9 +829,10 @@ namespace D3dDdi
auto& state = m_device.getState();
auto& appState = state.getAppState();
auto& decl = state.getVertexDecl();
auto textureStageCount = state.getTextureStageCount();
auto vertices = m_streamSource.vertices + baseVertexIndex * m_streamSource.stride;
for (UINT stage = 0; stage < decl.textureStageCount; ++stage)
for (UINT stage = 0; stage < textureStageCount; ++stage)
{
const UINT D3DDECLTYPE_FLOAT2 = 1;
if (!appState.textures[stage] ||

View File

@ -696,6 +696,12 @@ namespace D3dDdi
return static_cast<ShaderType>(m_tokens.front() >> 16);
}
UINT ShaderAssembler::getTextureStageCount()
{
auto usedSamplers = getUsedRegisterNumbers(D3DSPR_SAMPLER);
return usedSamplers.empty() ? 0 : (*usedSamplers.rbegin() + 1);
}
template <typename Token>
Token ShaderAssembler::getToken(UINT offset) const
{

View File

@ -16,6 +16,7 @@ namespace D3dDdi
bool addAlphaTest(UINT alphaRef);
std::string disassemble();
UINT getTextureStageCount();
const std::vector<UINT>& getTokens() const { return m_tokens; }
private: