mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 21:01:37 +00:00
Compile morph pipelines asynchronously.
This commit is contained in:
parent
028767b33a
commit
babad3402c
5 changed files with 192 additions and 34 deletions
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/smart_ptr/shared_ptr.h>
|
||||||
|
#include <Hedgehog/Database/System/hhDatabaseData.h>
|
||||||
|
|
||||||
|
namespace Hedgehog::Mirage
|
||||||
|
{
|
||||||
|
class CMaterialData;
|
||||||
|
|
||||||
|
class CMeshIndexData : public Hedgehog::Database::CDatabaseData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
be<uint32_t> m_IndexNum;
|
||||||
|
be<uint32_t> m_NodeNum;
|
||||||
|
xpointer<uint8_t> m_pNodeIndices;
|
||||||
|
xpointer<void> m_pD3DIndexBuffer;
|
||||||
|
boost::shared_ptr<CMaterialData> m_spMaterial;
|
||||||
|
};
|
||||||
|
|
||||||
|
SWA_ASSERT_OFFSETOF(CMeshIndexData, m_IndexNum, 0xC);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMeshIndexData, m_NodeNum, 0x10);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMeshIndexData, m_pNodeIndices, 0x14);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMeshIndexData, m_pD3DIndexBuffer, 0x18);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMeshIndexData, m_spMaterial, 0x1C);
|
||||||
|
SWA_ASSERT_SIZEOF(CMeshIndexData, 0x24);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/smart_ptr/shared_ptr.h>
|
||||||
|
|
||||||
|
#include <Hedgehog/Base/Container/hhVector.h>
|
||||||
|
#include <Hedgehog/Database/System/hhDatabaseData.h>
|
||||||
|
#include <Hedgehog/MirageCore/Misc/hhVertexDeclarationPtr.h>
|
||||||
|
|
||||||
|
namespace Hedgehog::Mirage
|
||||||
|
{
|
||||||
|
class CMorphTargetData;
|
||||||
|
class CMeshIndexData;
|
||||||
|
|
||||||
|
class CMorphModelData : public Hedgehog::Database::CDatabaseData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
be<uint32_t> m_VertexNum;
|
||||||
|
be<uint32_t> m_VertexSize;
|
||||||
|
be<uint32_t> m_MorphTargetVertexSize;
|
||||||
|
xpointer<void> m_pD3DVertexBuffer;
|
||||||
|
CVertexDeclarationPtr m_VertexDeclarationPtr;
|
||||||
|
hh::vector<boost::shared_ptr<CMorphTargetData>> m_MorphTargetList;
|
||||||
|
hh::vector<boost::shared_ptr<CMeshIndexData>> m_OpaqueMeshList;
|
||||||
|
hh::vector<boost::shared_ptr<CMeshIndexData>> m_TransparentMeshList;
|
||||||
|
hh::vector<boost::shared_ptr<CMeshIndexData>> m_PunchThroughMeshList;
|
||||||
|
};
|
||||||
|
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_VertexNum, 0xC);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_VertexSize, 0x10);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_MorphTargetVertexSize, 0x14);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_pD3DVertexBuffer, 0x18);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_VertexDeclarationPtr, 0x1C);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_MorphTargetList, 0x24);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_OpaqueMeshList, 0x34);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_TransparentMeshList, 0x44);
|
||||||
|
SWA_ASSERT_OFFSETOF(CMorphModelData, m_PunchThroughMeshList, 0x54);
|
||||||
|
SWA_ASSERT_SIZEOF(CMorphModelData, 0x64);
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,9 @@
|
||||||
#include "Hedgehog/MirageCore/Misc/hhVertexDeclarationPtr.h"
|
#include "Hedgehog/MirageCore/Misc/hhVertexDeclarationPtr.h"
|
||||||
#include "Hedgehog/MirageCore/RenderData/hhMaterialData.h"
|
#include "Hedgehog/MirageCore/RenderData/hhMaterialData.h"
|
||||||
#include "Hedgehog/MirageCore/RenderData/hhMeshData.h"
|
#include "Hedgehog/MirageCore/RenderData/hhMeshData.h"
|
||||||
|
#include "Hedgehog/MirageCore/RenderData/hhMeshIndexData.h"
|
||||||
#include "Hedgehog/MirageCore/RenderData/hhModelData.h"
|
#include "Hedgehog/MirageCore/RenderData/hhModelData.h"
|
||||||
|
#include "Hedgehog/MirageCore/RenderData/hhMorphModelData.h"
|
||||||
#include "Hedgehog/MirageCore/RenderData/hhNodeGroupModelData.h"
|
#include "Hedgehog/MirageCore/RenderData/hhNodeGroupModelData.h"
|
||||||
#include "Hedgehog/MirageCore/RenderData/hhPixelShaderCodeData.h"
|
#include "Hedgehog/MirageCore/RenderData/hhPixelShaderCodeData.h"
|
||||||
#include "Hedgehog/MirageCore/RenderData/hhPixelShaderData.h"
|
#include "Hedgehog/MirageCore/RenderData/hhPixelShaderData.h"
|
||||||
|
|
|
||||||
|
|
@ -3183,6 +3183,12 @@ static void SanitizePipelineState(PipelineState& pipelineState)
|
||||||
pipelineState.blendOpAlpha = RenderBlendOperation::ADD;
|
pipelineState.blendOpAlpha = RenderBlendOperation::ADD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
if (!pipelineState.vertexDeclaration->vertexStreams[i])
|
||||||
|
pipelineState.vertexStrides[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t specConstantsMask = 0;
|
uint32_t specConstantsMask = 0;
|
||||||
if (pipelineState.vertexShader->shaderCacheEntry != nullptr)
|
if (pipelineState.vertexShader->shaderCacheEntry != nullptr)
|
||||||
specConstantsMask |= pipelineState.vertexShader->shaderCacheEntry->specConstantsMask;
|
specConstantsMask |= pipelineState.vertexShader->shaderCacheEntry->specConstantsMask;
|
||||||
|
|
@ -3964,6 +3970,8 @@ static GuestVertexDeclaration* CreateVertexDeclarationWithoutAddRef(GuestVertexE
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vertexDeclaration->vertexStreams[vertexElement->stream] = true;
|
||||||
|
|
||||||
++vertexElement;
|
++vertexElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5220,28 +5228,42 @@ enum class MeshLayer
|
||||||
Special
|
Special
|
||||||
};
|
};
|
||||||
|
|
||||||
static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer layer, CompilationArgs& args)
|
struct Mesh
|
||||||
{
|
{
|
||||||
if (mesh->m_spMaterial.get() == nullptr || mesh->m_spMaterial->m_spShaderListData.get() == nullptr)
|
uint32_t vertexSize{};
|
||||||
|
uint32_t morphTargetVertexSize{};
|
||||||
|
GuestVertexDeclaration* vertexDeclaration{};
|
||||||
|
Hedgehog::Mirage::CMaterialData* material{};
|
||||||
|
MeshLayer layer{};
|
||||||
|
bool morphModel{};
|
||||||
|
};
|
||||||
|
|
||||||
|
static void CompileMeshPipeline(const Mesh& mesh, CompilationArgs& args)
|
||||||
|
{
|
||||||
|
if (mesh.material == nullptr || mesh.material->m_spShaderListData.get() == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto& material = mesh->m_spMaterial;
|
auto& shaderList = mesh.material->m_spShaderListData;
|
||||||
auto& shaderList = material->m_spShaderListData;
|
|
||||||
|
|
||||||
bool isFur = strstr(shaderList->m_TypeAndName.c_str(), "Fur") != nullptr;
|
bool isFur = !mesh.morphModel &&
|
||||||
bool isSky = strstr(shaderList->m_TypeAndName.c_str(), "Sky") != nullptr;
|
strstr(shaderList->m_TypeAndName.c_str(), "Fur") != nullptr;
|
||||||
bool isSonicMouth = strcmp(material->m_TypeAndName.c_str() + 2, "sonic_gm_mouth_duble") == 0 &&
|
|
||||||
|
bool isSky = !mesh.morphModel &&
|
||||||
|
strstr(shaderList->m_TypeAndName.c_str(), "Sky") != nullptr;
|
||||||
|
|
||||||
|
bool isSonicMouth = !mesh.morphModel &&
|
||||||
|
strcmp(mesh.material->m_TypeAndName.c_str() + 2, "sonic_gm_mouth_duble") == 0 &&
|
||||||
strcmp(shaderList->m_TypeAndName.c_str() + 3, "SonicSkin_dspf[b]") == 0;
|
strcmp(shaderList->m_TypeAndName.c_str() + 3, "SonicSkin_dspf[b]") == 0;
|
||||||
|
|
||||||
bool compiledOutsideMainFramebuffer = !isFur && !isSky;
|
bool compiledOutsideMainFramebuffer = !isFur && !isSky;
|
||||||
|
|
||||||
bool constTexCoord = true;
|
bool constTexCoord = true;
|
||||||
if (material->m_spTexsetData.get() != nullptr)
|
if (mesh.material->m_spTexsetData.get() != nullptr)
|
||||||
{
|
{
|
||||||
for (size_t i = 1; i < material->m_spTexsetData->m_TextureList.size(); i++)
|
for (size_t i = 1; i < mesh.material->m_spTexsetData->m_TextureList.size(); i++)
|
||||||
{
|
{
|
||||||
if (material->m_spTexsetData->m_TextureList[i]->m_TexcoordIndex !=
|
if (mesh.material->m_spTexsetData->m_TextureList[i]->m_TexcoordIndex !=
|
||||||
material->m_spTexsetData->m_TextureList[0]->m_TexcoordIndex)
|
mesh.material->m_spTexsetData->m_TextureList[0]->m_TexcoordIndex)
|
||||||
{
|
{
|
||||||
constTexCoord = false;
|
constTexCoord = false;
|
||||||
break;
|
break;
|
||||||
|
|
@ -5249,14 +5271,12 @@ static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer lay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto vertexDeclaration = reinterpret_cast<GuestVertexDeclaration*>(mesh->m_VertexDeclarationPtr.m_pD3DVertexDeclaration.get());
|
|
||||||
|
|
||||||
// Shadow pipeline.
|
// Shadow pipeline.
|
||||||
if (compiledOutsideMainFramebuffer && (layer == MeshLayer::Opaque || layer == MeshLayer::PunchThrough))
|
if (compiledOutsideMainFramebuffer && (mesh.layer == MeshLayer::Opaque || mesh.layer == MeshLayer::PunchThrough))
|
||||||
{
|
{
|
||||||
PipelineState pipelineState{};
|
PipelineState pipelineState{};
|
||||||
|
|
||||||
if (layer == MeshLayer::PunchThrough)
|
if (mesh.layer == MeshLayer::PunchThrough)
|
||||||
{
|
{
|
||||||
pipelineState.vertexShader = FindShaderCacheEntry(0xDD4FA7BB53876300)->guestShader;
|
pipelineState.vertexShader = FindShaderCacheEntry(0xDD4FA7BB53876300)->guestShader;
|
||||||
pipelineState.pixelShader = FindShaderCacheEntry(0xE2ECA594590DDE8B)->guestShader;
|
pipelineState.pixelShader = FindShaderCacheEntry(0xE2ECA594590DDE8B)->guestShader;
|
||||||
|
|
@ -5266,35 +5286,49 @@ static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer lay
|
||||||
pipelineState.vertexShader = FindShaderCacheEntry(0x8E4BB23465BD909E)->guestShader;
|
pipelineState.vertexShader = FindShaderCacheEntry(0x8E4BB23465BD909E)->guestShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipelineState.vertexDeclaration = vertexDeclaration;
|
pipelineState.vertexDeclaration = mesh.vertexDeclaration;
|
||||||
pipelineState.cullMode = material->m_DoubleSided ? RenderCullMode::NONE : RenderCullMode::BACK;
|
pipelineState.cullMode = mesh.material->m_DoubleSided ? RenderCullMode::NONE : RenderCullMode::BACK;
|
||||||
pipelineState.zFunc = RenderComparisonFunction::LESS_EQUAL;
|
pipelineState.zFunc = RenderComparisonFunction::LESS_EQUAL;
|
||||||
pipelineState.depthBias = (1 << 24) * (*reinterpret_cast<be<float>*>(g_memory.Translate(0x83302760)));
|
pipelineState.depthBias = (1 << 24) * (*reinterpret_cast<be<float>*>(g_memory.Translate(0x83302760)));
|
||||||
pipelineState.slopeScaledDepthBias = *reinterpret_cast<be<float>*>(g_memory.Translate(0x83302764));
|
pipelineState.slopeScaledDepthBias = *reinterpret_cast<be<float>*>(g_memory.Translate(0x83302764));
|
||||||
pipelineState.colorWriteEnable = 0;
|
pipelineState.colorWriteEnable = 0;
|
||||||
pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_STRIP;
|
pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_STRIP;
|
||||||
pipelineState.vertexStrides[0] = mesh->m_VertexSize;
|
pipelineState.vertexStrides[0] = mesh.vertexSize;
|
||||||
pipelineState.depthStencilFormat = RenderFormat::D32_FLOAT;
|
pipelineState.depthStencilFormat = RenderFormat::D32_FLOAT;
|
||||||
|
|
||||||
if (layer == MeshLayer::PunchThrough)
|
if (mesh.layer == MeshLayer::PunchThrough)
|
||||||
pipelineState.specConstants |= SPEC_CONSTANT_ALPHA_TEST;
|
pipelineState.specConstants |= SPEC_CONSTANT_ALPHA_TEST;
|
||||||
|
|
||||||
|
const char* name = (mesh.layer == MeshLayer::PunchThrough ? "MakeShadowMapTransparent" : "MakeShadowMap");
|
||||||
SanitizePipelineState(pipelineState);
|
SanitizePipelineState(pipelineState);
|
||||||
EnqueueGraphicsPipelineCompilation(pipelineState, args.holderPair, layer == MeshLayer::PunchThrough ? "MakeShadowMapTransparent" : "MakeShadowMap");
|
EnqueueGraphicsPipelineCompilation(pipelineState, args.holderPair, name);
|
||||||
|
|
||||||
|
// Morph models have 4 targets where unused targets default to the first vertex stream.
|
||||||
|
if (mesh.morphModel)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < 4; j++)
|
||||||
|
pipelineState.vertexStrides[j + 1] = i > j ? mesh.morphTargetVertexSize : mesh.vertexSize;
|
||||||
|
|
||||||
|
SanitizePipelineState(pipelineState);
|
||||||
|
EnqueueGraphicsPipelineCompilation(pipelineState, args.holderPair, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Motion blur pipeline. We could normally do the player here only, but apparently Werehog enemies also have object blur.
|
// Motion blur pipeline. We could normally do the player here only, but apparently Werehog enemies also have object blur.
|
||||||
// TODO: Do punch through meshes get rendered?
|
// TODO: Do punch through meshes get rendered?
|
||||||
if (compiledOutsideMainFramebuffer && args.hasMoreThanOneBone && layer == MeshLayer::Opaque)
|
if (!mesh.morphModel && compiledOutsideMainFramebuffer && args.hasMoreThanOneBone && mesh.layer == MeshLayer::Opaque)
|
||||||
{
|
{
|
||||||
PipelineState pipelineState{};
|
PipelineState pipelineState{};
|
||||||
pipelineState.vertexShader = FindShaderCacheEntry(0x4620B236DC38100C)->guestShader;
|
pipelineState.vertexShader = FindShaderCacheEntry(0x4620B236DC38100C)->guestShader;
|
||||||
pipelineState.pixelShader = FindShaderCacheEntry(0xBBDB735BEACC8F41)->guestShader;
|
pipelineState.pixelShader = FindShaderCacheEntry(0xBBDB735BEACC8F41)->guestShader;
|
||||||
pipelineState.vertexDeclaration = vertexDeclaration;
|
pipelineState.vertexDeclaration = mesh.vertexDeclaration;
|
||||||
pipelineState.cullMode = RenderCullMode::NONE;
|
pipelineState.cullMode = RenderCullMode::NONE;
|
||||||
pipelineState.zFunc = RenderComparisonFunction::GREATER_EQUAL;
|
pipelineState.zFunc = RenderComparisonFunction::GREATER_EQUAL;
|
||||||
pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_STRIP;
|
pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_STRIP;
|
||||||
pipelineState.vertexStrides[0] = mesh->m_VertexSize;
|
pipelineState.vertexStrides[0] = mesh.vertexSize;
|
||||||
pipelineState.renderTargetFormat = RenderFormat::R8G8B8A8_UNORM;
|
pipelineState.renderTargetFormat = RenderFormat::R8G8B8A8_UNORM;
|
||||||
pipelineState.depthStencilFormat = RenderFormat::D32_FLOAT;
|
pipelineState.depthStencilFormat = RenderFormat::D32_FLOAT;
|
||||||
pipelineState.specConstants = SPEC_CONSTANT_REVERSE_Z;
|
pipelineState.specConstants = SPEC_CONSTANT_REVERSE_Z;
|
||||||
|
|
@ -5322,7 +5356,8 @@ static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer lay
|
||||||
if ((defaultFindResult->second.m_SubPermutations.get() & (1 << pixelShaderSubPermutationsToCompile)) == 0) pixelShaderSubPermutationsToCompile &= ~0x1;
|
if ((defaultFindResult->second.m_SubPermutations.get() & (1 << pixelShaderSubPermutationsToCompile)) == 0) pixelShaderSubPermutationsToCompile &= ~0x1;
|
||||||
if ((defaultFindResult->second.m_SubPermutations.get() & (1 << pixelShaderSubPermutationsToCompile)) == 0) pixelShaderSubPermutationsToCompile &= ~0x2;
|
if ((defaultFindResult->second.m_SubPermutations.get() & (1 << pixelShaderSubPermutationsToCompile)) == 0) pixelShaderSubPermutationsToCompile &= ~0x2;
|
||||||
|
|
||||||
guest_stack_var<Hedgehog::Base::CStringSymbol> noneSymbol(reinterpret_cast<const char*>(g_memory.Translate(0x8200D938)));
|
uint32_t noneStr = mesh.morphModel ? 0x820D72F0 : 0x8200D938; // "p" for morph, "none" for regular
|
||||||
|
guest_stack_var<Hedgehog::Base::CStringSymbol> noneSymbol(reinterpret_cast<const char*>(g_memory.Translate(noneStr)));
|
||||||
auto noneFindResult = defaultFindResult->second.m_VertexShaderPermutations.find(*noneSymbol);
|
auto noneFindResult = defaultFindResult->second.m_VertexShaderPermutations.find(*noneSymbol);
|
||||||
if (noneFindResult == defaultFindResult->second.m_VertexShaderPermutations.end())
|
if (noneFindResult == defaultFindResult->second.m_VertexShaderPermutations.end())
|
||||||
return;
|
return;
|
||||||
|
|
@ -5333,15 +5368,17 @@ static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer lay
|
||||||
if ((noneFindResult->second->m_SubPermutations.get() & (1 << vertexShaderSubPermutationsToCompile)) == 0)
|
if ((noneFindResult->second->m_SubPermutations.get() & (1 << vertexShaderSubPermutationsToCompile)) == 0)
|
||||||
vertexShaderSubPermutationsToCompile &= ~0x1;
|
vertexShaderSubPermutationsToCompile &= ~0x1;
|
||||||
|
|
||||||
|
auto vertexDeclaration = mesh.vertexDeclaration;
|
||||||
|
|
||||||
// Fur requires an instanced variant of the vertex declaration.
|
// Fur requires an instanced variant of the vertex declaration.
|
||||||
if (isFur)
|
if (isFur)
|
||||||
{
|
{
|
||||||
GuestVertexElement vertexElements[64];
|
GuestVertexElement vertexElements[64];
|
||||||
memcpy(vertexElements, vertexDeclaration->vertexElements.get(), (vertexDeclaration->vertexElementCount - 1) * sizeof(GuestVertexElement));
|
memcpy(vertexElements, mesh.vertexDeclaration->vertexElements.get(), (mesh.vertexDeclaration->vertexElementCount - 1) * sizeof(GuestVertexElement));
|
||||||
|
|
||||||
vertexElements[vertexDeclaration->vertexElementCount - 1] = { 1, 0, 0x2C82A1, 0, 0, 1 };
|
vertexElements[mesh.vertexDeclaration->vertexElementCount - 1] = { 1, 0, 0x2C82A1, 0, 0, 1 };
|
||||||
vertexElements[vertexDeclaration->vertexElementCount] = { 2, 0, 0x2C83A4, 0, 0, 2 };
|
vertexElements[mesh.vertexDeclaration->vertexElementCount] = { 2, 0, 0x2C83A4, 0, 0, 2 };
|
||||||
vertexElements[vertexDeclaration->vertexElementCount + 1] = D3DDECL_END();
|
vertexElements[mesh.vertexDeclaration->vertexElementCount + 1] = D3DDECL_END();
|
||||||
|
|
||||||
vertexDeclaration = CreateVertexDeclarationWithoutAddRef(vertexElements);
|
vertexDeclaration = CreateVertexDeclarationWithoutAddRef(vertexElements);
|
||||||
}
|
}
|
||||||
|
|
@ -5361,16 +5398,16 @@ static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer lay
|
||||||
pipelineState.pixelShader = reinterpret_cast<GuestShader*>(pixelShader->m_spCode->m_pD3DPixelShader.get());
|
pipelineState.pixelShader = reinterpret_cast<GuestShader*>(pixelShader->m_spCode->m_pD3DPixelShader.get());
|
||||||
pipelineState.vertexDeclaration = vertexDeclaration;
|
pipelineState.vertexDeclaration = vertexDeclaration;
|
||||||
pipelineState.instancing = isFur;
|
pipelineState.instancing = isFur;
|
||||||
pipelineState.zWriteEnable = !isSky && layer != MeshLayer::Transparent;
|
pipelineState.zWriteEnable = !isSky && mesh.layer != MeshLayer::Transparent;
|
||||||
pipelineState.srcBlend = RenderBlend::SRC_ALPHA;
|
pipelineState.srcBlend = RenderBlend::SRC_ALPHA;
|
||||||
pipelineState.destBlend = material->m_Additive ? RenderBlend::ONE : RenderBlend::INV_SRC_ALPHA;
|
pipelineState.destBlend = mesh.material->m_Additive ? RenderBlend::ONE : RenderBlend::INV_SRC_ALPHA;
|
||||||
pipelineState.cullMode = material->m_DoubleSided ? RenderCullMode::NONE : RenderCullMode::BACK;
|
pipelineState.cullMode = mesh.material->m_DoubleSided ? RenderCullMode::NONE : RenderCullMode::BACK;
|
||||||
pipelineState.zFunc = RenderComparisonFunction::GREATER_EQUAL; // Reverse Z
|
pipelineState.zFunc = RenderComparisonFunction::GREATER_EQUAL; // Reverse Z
|
||||||
pipelineState.alphaBlendEnable = layer == MeshLayer::Transparent || layer == MeshLayer::Special;
|
pipelineState.alphaBlendEnable = mesh.layer == MeshLayer::Transparent || mesh.layer == MeshLayer::Special;
|
||||||
pipelineState.srcBlendAlpha = RenderBlend::SRC_ALPHA;
|
pipelineState.srcBlendAlpha = RenderBlend::SRC_ALPHA;
|
||||||
pipelineState.destBlendAlpha = RenderBlend::INV_SRC_ALPHA;
|
pipelineState.destBlendAlpha = RenderBlend::INV_SRC_ALPHA;
|
||||||
pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_STRIP;
|
pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_STRIP;
|
||||||
pipelineState.vertexStrides[0] = mesh->m_VertexSize;
|
pipelineState.vertexStrides[0] = mesh.vertexSize;
|
||||||
pipelineState.vertexStrides[1] = isFur ? 4 : 0;
|
pipelineState.vertexStrides[1] = isFur ? 4 : 0;
|
||||||
pipelineState.vertexStrides[2] = isFur ? 4 : 0;
|
pipelineState.vertexStrides[2] = isFur ? 4 : 0;
|
||||||
pipelineState.renderTargetFormat = RenderFormat::R16G16B16A16_FLOAT;
|
pipelineState.renderTargetFormat = RenderFormat::R16G16B16A16_FLOAT;
|
||||||
|
|
@ -5383,7 +5420,7 @@ static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer lay
|
||||||
if (Config::GITextureFiltering == EGITextureFiltering::Bicubic)
|
if (Config::GITextureFiltering == EGITextureFiltering::Bicubic)
|
||||||
pipelineState.specConstants |= SPEC_CONSTANT_BICUBIC_GI_FILTER;
|
pipelineState.specConstants |= SPEC_CONSTANT_BICUBIC_GI_FILTER;
|
||||||
|
|
||||||
if (layer == MeshLayer::PunchThrough)
|
if (mesh.layer == MeshLayer::PunchThrough)
|
||||||
{
|
{
|
||||||
if (Config::AntiAliasing != EAntiAliasing::None && Config::TransparencyAntiAliasing)
|
if (Config::AntiAliasing != EAntiAliasing::None && Config::TransparencyAntiAliasing)
|
||||||
{
|
{
|
||||||
|
|
@ -5403,6 +5440,19 @@ static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer lay
|
||||||
{
|
{
|
||||||
SanitizePipelineState(pipelineStateToCreate);
|
SanitizePipelineState(pipelineStateToCreate);
|
||||||
EnqueueGraphicsPipelineCompilation(pipelineStateToCreate, args.holderPair, shaderList->m_TypeAndName.c_str() + 3);
|
EnqueueGraphicsPipelineCompilation(pipelineStateToCreate, args.holderPair, shaderList->m_TypeAndName.c_str() + 3);
|
||||||
|
|
||||||
|
// Morph models have 4 targets where unused targets default to the first vertex stream.
|
||||||
|
if (mesh.morphModel)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < 4; j++)
|
||||||
|
pipelineStateToCreate.vertexStrides[j + 1] = i > j ? mesh.morphTargetVertexSize : mesh.vertexSize;
|
||||||
|
|
||||||
|
SanitizePipelineState(pipelineStateToCreate);
|
||||||
|
EnqueueGraphicsPipelineCompilation(pipelineStateToCreate, args.holderPair, shaderList->m_TypeAndName.c_str() + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
createGraphicsPipeline(pipelineState);
|
createGraphicsPipeline(pipelineState);
|
||||||
|
|
@ -5454,6 +5504,32 @@ static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer lay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CompileMeshPipeline(Hedgehog::Mirage::CMeshData* mesh, MeshLayer layer, CompilationArgs& args)
|
||||||
|
{
|
||||||
|
CompileMeshPipeline(Mesh
|
||||||
|
{
|
||||||
|
mesh->m_VertexSize,
|
||||||
|
0,
|
||||||
|
reinterpret_cast<GuestVertexDeclaration*>(mesh->m_VertexDeclarationPtr.m_pD3DVertexDeclaration.get()),
|
||||||
|
mesh->m_spMaterial.get(),
|
||||||
|
layer,
|
||||||
|
false
|
||||||
|
}, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CompileMeshPipeline(Hedgehog::Mirage::CMorphModelData* morphModel, Hedgehog::Mirage::CMeshIndexData* mesh, MeshLayer layer, CompilationArgs& args)
|
||||||
|
{
|
||||||
|
CompileMeshPipeline(Mesh
|
||||||
|
{
|
||||||
|
morphModel->m_VertexSize,
|
||||||
|
morphModel->m_MorphTargetVertexSize,
|
||||||
|
reinterpret_cast<GuestVertexDeclaration*>(morphModel->m_VertexDeclarationPtr.m_pD3DVertexDeclaration.get()),
|
||||||
|
mesh->m_spMaterial.get(),
|
||||||
|
layer,
|
||||||
|
true
|
||||||
|
}, args);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void CompileMeshPipelines(const T& modelData, CompilationArgs& args)
|
static void CompileMeshPipelines(const T& modelData, CompilationArgs& args)
|
||||||
{
|
{
|
||||||
|
|
@ -5493,6 +5569,21 @@ static void CompileMeshPipelines(const T& modelData, CompilationArgs& args)
|
||||||
|
|
||||||
for (auto& mesh : modelData.m_PunchThroughMeshes)
|
for (auto& mesh : modelData.m_PunchThroughMeshes)
|
||||||
CompileMeshPipeline(mesh.get(), MeshLayer::PunchThrough, args);
|
CompileMeshPipeline(mesh.get(), MeshLayer::PunchThrough, args);
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, Hedgehog::Mirage::CModelData>)
|
||||||
|
{
|
||||||
|
for (auto& morphModel : modelData.m_MorphModels)
|
||||||
|
{
|
||||||
|
for (auto& mesh : morphModel->m_OpaqueMeshList)
|
||||||
|
CompileMeshPipeline(morphModel.get(), mesh.get(), MeshLayer::Opaque, args);
|
||||||
|
|
||||||
|
for (auto& mesh : morphModel->m_TransparentMeshList)
|
||||||
|
CompileMeshPipeline(morphModel.get(), mesh.get(), MeshLayer::Transparent, args);
|
||||||
|
|
||||||
|
for (auto& mesh : morphModel->m_PunchThroughMeshList)
|
||||||
|
CompileMeshPipeline(morphModel.get(), mesh.get(), MeshLayer::PunchThrough, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CompileParticleMaterialPipeline(const Hedgehog::Sparkle::CParticleMaterial& material, DatabaseDataHolderPair& holderPair)
|
static void CompileParticleMaterialPipeline(const Hedgehog::Sparkle::CParticleMaterial& material, DatabaseDataHolderPair& holderPair)
|
||||||
|
|
|
||||||
|
|
@ -270,6 +270,7 @@ struct GuestVertexDeclaration : GuestResource
|
||||||
uint32_t vertexElementCount = 0;
|
uint32_t vertexElementCount = 0;
|
||||||
uint32_t swappedTexcoords = 0;
|
uint32_t swappedTexcoords = 0;
|
||||||
bool hasR11G11B10Normal = false;
|
bool hasR11G11B10Normal = false;
|
||||||
|
bool vertexStreams[16]{};
|
||||||
uint32_t indexVertexStream = 0;
|
uint32_t indexVertexStream = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue