mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-26 20:31:41 +00:00
Merge branch 'hedge-dev:main' into slider-fix
This commit is contained in:
commit
371b4041d5
8 changed files with 74 additions and 20 deletions
|
|
@ -43,7 +43,7 @@ void main(
|
||||||
out float4 oColor0 : COLOR0,
|
out float4 oColor0 : COLOR0,
|
||||||
out float4 oColor1 : COLOR1)
|
out float4 oColor1 : COLOR1)
|
||||||
{
|
{
|
||||||
oPos.xy = (iPosition0.xy - 0.5) * g_ViewportSize.zw * float2(2.0, -2.0) + float2(-1.0, 1.0);
|
oPos.xy = iPosition0.xy * g_ViewportSize.zw * float2(2.0, -2.0) + float2(-1.0, 1.0);
|
||||||
oPos.z = g_Z.x;
|
oPos.z = g_Z.x;
|
||||||
oPos.w = 1.0;
|
oPos.w = 1.0;
|
||||||
oTexCoord0 = iColor0.wxyz;
|
oTexCoord0 = iColor0.wxyz;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ void main(
|
||||||
out float4 oColor0 : COLOR0,
|
out float4 oColor0 : COLOR0,
|
||||||
out float4 oColor1 : COLOR1)
|
out float4 oColor1 : COLOR1)
|
||||||
{
|
{
|
||||||
oPos.xy = (iPosition0.xy - 0.5) * g_ViewportSize.zw * float2(2.0, -2.0) + float2(-1.0, 1.0);
|
oPos.xy = iPosition0.xy * g_ViewportSize.zw * float2(2.0, -2.0) + float2(-1.0, 1.0);
|
||||||
oPos.z = g_Z.x;
|
oPos.z = g_Z.x;
|
||||||
oPos.w = 1.0;
|
oPos.w = 1.0;
|
||||||
oTexCoord0 = iColor0.wxyz;
|
oTexCoord0 = iColor0.wxyz;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ Interpolators main(in VertexShaderInput In)
|
||||||
{
|
{
|
||||||
Interpolators Out;
|
Interpolators Out;
|
||||||
Out.ProjPos = In.ObjPos;
|
Out.ProjPos = In.ObjPos;
|
||||||
|
Out.ProjPos.xy += g_HalfPixelOffset * Out.ProjPos.w;
|
||||||
Out.UV = In.UV;
|
Out.UV = In.UV;
|
||||||
return Out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,8 @@ struct SharedConstants
|
||||||
uint32_t samplerIndices[16]{};
|
uint32_t samplerIndices[16]{};
|
||||||
uint32_t booleans{};
|
uint32_t booleans{};
|
||||||
uint32_t swappedTexcoords{};
|
uint32_t swappedTexcoords{};
|
||||||
|
float halfPixelOffsetX{};
|
||||||
|
float halfPixelOffsetY{};
|
||||||
float alphaThreshold{};
|
float alphaThreshold{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -681,6 +683,9 @@ static void DestructTempResources()
|
||||||
if (texture->patchedTexture != nullptr)
|
if (texture->patchedTexture != nullptr)
|
||||||
g_textureDescriptorAllocator.free(texture->patchedTexture->descriptorIndex);
|
g_textureDescriptorAllocator.free(texture->patchedTexture->descriptorIndex);
|
||||||
|
|
||||||
|
if (texture->recreatedCubeMapTexture != nullptr)
|
||||||
|
g_textureDescriptorAllocator.free(texture->recreatedCubeMapTexture->descriptorIndex);
|
||||||
|
|
||||||
texture->~GuestTexture();
|
texture->~GuestTexture();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -3089,8 +3094,6 @@ static void FlushViewport()
|
||||||
if (g_dirtyStates.viewport)
|
if (g_dirtyStates.viewport)
|
||||||
{
|
{
|
||||||
auto viewport = g_viewport;
|
auto viewport = g_viewport;
|
||||||
viewport.x += 0.5f;
|
|
||||||
viewport.y += 0.5f;
|
|
||||||
|
|
||||||
if (viewport.minDepth > viewport.maxDepth)
|
if (viewport.minDepth > viewport.maxDepth)
|
||||||
std::swap(viewport.minDepth, viewport.maxDepth);
|
std::swap(viewport.minDepth, viewport.maxDepth);
|
||||||
|
|
@ -3514,6 +3517,12 @@ static void SetFramebuffer(GuestSurface* renderTarget, GuestSurface* depthStenci
|
||||||
g_framebuffer = nullptr;
|
g_framebuffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_framebuffer != nullptr)
|
||||||
|
{
|
||||||
|
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.halfPixelOffsetX, 1.0f / float(g_framebuffer->getWidth()));
|
||||||
|
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.halfPixelOffsetY, -1.0f / float(g_framebuffer->getHeight()));
|
||||||
|
}
|
||||||
|
|
||||||
g_dirtyStates.renderTargetAndDepthStencil = settingForClear;
|
g_dirtyStates.renderTargetAndDepthStencil = settingForClear;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3641,6 +3650,14 @@ static void SetTextureInRenderThread(uint32_t index, GuestTexture* texture)
|
||||||
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.texture3DIndices[index], texture != nullptr &&
|
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.texture3DIndices[index], texture != nullptr &&
|
||||||
viewDimension == RenderTextureViewDimension::TEXTURE_3D ? texture->descriptorIndex : TEXTURE_DESCRIPTOR_NULL_TEXTURE_3D);
|
viewDimension == RenderTextureViewDimension::TEXTURE_3D ? texture->descriptorIndex : TEXTURE_DESCRIPTOR_NULL_TEXTURE_3D);
|
||||||
|
|
||||||
|
// Check if there's a cubemap texture we recreated and assign it if it's valid. The shader will pick whichever is correct.
|
||||||
|
if (viewDimension == RenderTextureViewDimension::TEXTURE_2D && texture->recreatedCubeMapTexture != nullptr)
|
||||||
|
{
|
||||||
|
texture = texture->recreatedCubeMapTexture.get();
|
||||||
|
AddBarrier(texture, RenderTextureLayout::SHADER_READ);
|
||||||
|
viewDimension = texture->viewDimension;
|
||||||
|
}
|
||||||
|
|
||||||
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.textureCubeIndices[index], texture != nullptr &&
|
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.textureCubeIndices[index], texture != nullptr &&
|
||||||
viewDimension == RenderTextureViewDimension::TEXTURE_CUBE ? texture->descriptorIndex : TEXTURE_DESCRIPTOR_NULL_TEXTURE_CUBE);
|
viewDimension == RenderTextureViewDimension::TEXTURE_CUBE ? texture->descriptorIndex : TEXTURE_DESCRIPTOR_NULL_TEXTURE_CUBE);
|
||||||
}
|
}
|
||||||
|
|
@ -5471,21 +5488,30 @@ static RenderFormat ConvertDXGIFormat(ddspp::DXGIFormat format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataSize, RenderComponentMapping componentMapping)
|
static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataSize, RenderComponentMapping componentMapping, bool forceCubeMap = false)
|
||||||
{
|
{
|
||||||
ddspp::Descriptor ddsDesc;
|
ddspp::Descriptor ddsDesc;
|
||||||
if (ddspp::decode_header((unsigned char *)(data), ddsDesc) != ddspp::Error)
|
if (ddspp::decode_header((unsigned char *)(data), ddsDesc) != ddspp::Error)
|
||||||
{
|
{
|
||||||
|
forceCubeMap &= (ddsDesc.type == ddspp::Texture2D) && (ddsDesc.arraySize == 1);
|
||||||
|
uint32_t arraySize = ddsDesc.type == ddspp::TextureType::Cubemap ? (ddsDesc.arraySize * 6) : ddsDesc.arraySize;
|
||||||
|
|
||||||
RenderTextureDesc desc;
|
RenderTextureDesc desc;
|
||||||
desc.dimension = ConvertTextureDimension(ddsDesc.type);
|
desc.dimension = ConvertTextureDimension(ddsDesc.type);
|
||||||
desc.width = ddsDesc.width;
|
desc.width = ddsDesc.width;
|
||||||
desc.height = ddsDesc.height;
|
desc.height = ddsDesc.height;
|
||||||
desc.depth = ddsDesc.depth;
|
desc.depth = ddsDesc.depth;
|
||||||
desc.mipLevels = ddsDesc.numMips;
|
desc.mipLevels = ddsDesc.numMips;
|
||||||
desc.arraySize = ddsDesc.type == ddspp::TextureType::Cubemap ? ddsDesc.arraySize * 6 : ddsDesc.arraySize;
|
desc.arraySize = arraySize;
|
||||||
desc.format = ConvertDXGIFormat(ddsDesc.format);
|
desc.format = ConvertDXGIFormat(ddsDesc.format);
|
||||||
desc.flags = ddsDesc.type == ddspp::TextureType::Cubemap ? RenderTextureFlag::CUBE : RenderTextureFlag::NONE;
|
desc.flags = ddsDesc.type == ddspp::TextureType::Cubemap ? RenderTextureFlag::CUBE : RenderTextureFlag::NONE;
|
||||||
|
|
||||||
|
if (forceCubeMap)
|
||||||
|
{
|
||||||
|
desc.arraySize = 6;
|
||||||
|
desc.flags = RenderTextureFlag::CUBE;
|
||||||
|
}
|
||||||
|
|
||||||
texture.textureHolder = g_device->createTexture(desc);
|
texture.textureHolder = g_device->createTexture(desc);
|
||||||
texture.texture = texture.textureHolder.get();
|
texture.texture = texture.textureHolder.get();
|
||||||
texture.layout = RenderTextureLayout::COPY_DEST;
|
texture.layout = RenderTextureLayout::COPY_DEST;
|
||||||
|
|
@ -5495,6 +5521,10 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
|
||||||
viewDesc.dimension = ConvertTextureViewDimension(ddsDesc.type);
|
viewDesc.dimension = ConvertTextureViewDimension(ddsDesc.type);
|
||||||
viewDesc.mipLevels = ddsDesc.numMips;
|
viewDesc.mipLevels = ddsDesc.numMips;
|
||||||
viewDesc.componentMapping = componentMapping;
|
viewDesc.componentMapping = componentMapping;
|
||||||
|
|
||||||
|
if (forceCubeMap)
|
||||||
|
viewDesc.dimension = RenderTextureViewDimension::TEXTURE_CUBE;
|
||||||
|
|
||||||
texture.textureView = texture.texture->createTextureView(viewDesc);
|
texture.textureView = texture.texture->createTextureView(viewDesc);
|
||||||
texture.descriptorIndex = g_textureDescriptorAllocator.allocate();
|
texture.descriptorIndex = g_textureDescriptorAllocator.allocate();
|
||||||
g_textureDescriptorSet->setTexture(texture.descriptorIndex, texture.texture, RenderTextureLayout::SHADER_READ, texture.textureView.get());
|
g_textureDescriptorSet->setTexture(texture.descriptorIndex, texture.texture, RenderTextureLayout::SHADER_READ, texture.textureView.get());
|
||||||
|
|
@ -5519,7 +5549,7 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
|
||||||
uint32_t curSrcOffset = 0;
|
uint32_t curSrcOffset = 0;
|
||||||
uint32_t curDstOffset = 0;
|
uint32_t curDstOffset = 0;
|
||||||
|
|
||||||
for (uint32_t arraySlice = 0; arraySlice < desc.arraySize; arraySlice++)
|
for (uint32_t arraySlice = 0; arraySlice < arraySize; arraySlice++)
|
||||||
{
|
{
|
||||||
for (uint32_t mipSlice = 0; mipSlice < ddsDesc.numMips; mipSlice++)
|
for (uint32_t mipSlice = 0; mipSlice < ddsDesc.numMips; mipSlice++)
|
||||||
{
|
{
|
||||||
|
|
@ -5569,13 +5599,24 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
|
||||||
{
|
{
|
||||||
g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(texture.texture, RenderTextureLayout::COPY_DEST));
|
g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(texture.texture, RenderTextureLayout::COPY_DEST));
|
||||||
|
|
||||||
for (size_t i = 0; i < slices.size(); i++)
|
auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
|
||||||
{
|
{
|
||||||
auto& slice = slices[i];
|
|
||||||
|
|
||||||
g_copyCommandList->copyTextureRegion(
|
g_copyCommandList->copyTextureRegion(
|
||||||
RenderTextureCopyLocation::Subresource(texture.texture, i),
|
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex),
|
||||||
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
|
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < slices.size(); i++)
|
||||||
|
copyTextureRegion(slices[i], i);
|
||||||
|
|
||||||
|
// Duplicate the first face across the remaining 6 faces.
|
||||||
|
if (forceCubeMap)
|
||||||
|
{
|
||||||
|
for (size_t i = 1; i < 6; i++)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < slices.size(); j++)
|
||||||
|
copyTextureRegion(slices[j], (slices.size() * i) + j);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -5648,13 +5689,12 @@ std::unique_ptr<GuestTexture> LoadTexture(const uint8_t* data, size_t dataSize,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DiffPatchTexture(GuestTexture& texture, uint8_t* data, uint32_t dataSize)
|
static void DiffPatchTexture(GuestTexture& texture, uint8_t* data, uint32_t dataSize, XXH64_hash_t hash)
|
||||||
{
|
{
|
||||||
auto header = reinterpret_cast<BlockCompressionDiffPatchHeader*>(g_buttonBcDiff.get());
|
auto header = reinterpret_cast<BlockCompressionDiffPatchHeader*>(g_buttonBcDiff.get());
|
||||||
auto entries = reinterpret_cast<BlockCompressionDiffPatchEntry*>(g_buttonBcDiff.get() + header->entriesOffset);
|
auto entries = reinterpret_cast<BlockCompressionDiffPatchEntry*>(g_buttonBcDiff.get() + header->entriesOffset);
|
||||||
auto end = entries + header->entryCount;
|
auto end = entries + header->entryCount;
|
||||||
|
|
||||||
XXH64_hash_t hash = XXH3_64bits(data, dataSize);
|
|
||||||
auto findResult = std::lower_bound(entries, end, hash, [](BlockCompressionDiffPatchEntry& lhs, XXH64_hash_t rhs)
|
auto findResult = std::lower_bound(entries, end, hash, [](BlockCompressionDiffPatchEntry& lhs, XXH64_hash_t rhs)
|
||||||
{
|
{
|
||||||
return lhs.hash < rhs;
|
return lhs.hash < rhs;
|
||||||
|
|
@ -5687,8 +5727,19 @@ static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
texture.texture->setName(reinterpret_cast<char*>(g_memory.Translate(pictureData->name + 2)));
|
texture.texture->setName(reinterpret_cast<char*>(g_memory.Translate(pictureData->name + 2)));
|
||||||
#endif
|
#endif
|
||||||
|
XXH64_hash_t hash = XXH3_64bits(data, dataSize);
|
||||||
|
|
||||||
DiffPatchTexture(texture, data, dataSize);
|
// The whale in Cool Edge has a 2D texture assigned as a cubemap which makes it not display in recomp.
|
||||||
|
// The hardware duplicates the first face to the remaining 6 faces, so to simulate that we'll recreate the asset.
|
||||||
|
bool forceCubeMap = (dataSize == 0xAB38) && (hash == 0x160E9E250FDE88A9);
|
||||||
|
if (forceCubeMap)
|
||||||
|
{
|
||||||
|
GuestTexture recreatedCubeMapTexture(ResourceType::Texture);
|
||||||
|
if (LoadTexture(recreatedCubeMapTexture, data, dataSize, {}, true))
|
||||||
|
texture.recreatedCubeMapTexture = std::make_unique<GuestTexture>(std::move(recreatedCubeMapTexture));
|
||||||
|
}
|
||||||
|
|
||||||
|
DiffPatchTexture(texture, data, dataSize, hash);
|
||||||
|
|
||||||
pictureData->texture = g_memory.MapVirtual(g_userHeap.AllocPhysical<GuestTexture>(std::move(texture)));
|
pictureData->texture = g_memory.MapVirtual(g_userHeap.AllocPhysical<GuestTexture>(std::move(texture)));
|
||||||
pictureData->type = 0;
|
pictureData->type = 0;
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ struct GuestTexture : GuestBaseTexture
|
||||||
void* mappedMemory = nullptr;
|
void* mappedMemory = nullptr;
|
||||||
std::unique_ptr<RenderFramebuffer> framebuffer;
|
std::unique_ptr<RenderFramebuffer> framebuffer;
|
||||||
std::unique_ptr<GuestTexture> patchedTexture;
|
std::unique_ptr<GuestTexture> patchedTexture;
|
||||||
|
std::unique_ptr<GuestTexture> recreatedCubeMapTexture;
|
||||||
struct GuestSurface* sourceSurface = nullptr;
|
struct GuestSurface* sourceSurface = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,8 +191,11 @@ void ModLoader::Init()
|
||||||
{
|
{
|
||||||
std::string includeDirU8 = modIni.getString("Main", fmt::format("IncludeDir{}", j), "");
|
std::string includeDirU8 = modIni.getString("Main", fmt::format("IncludeDir{}", j), "");
|
||||||
if (!includeDirU8.empty())
|
if (!includeDirU8.empty())
|
||||||
|
{
|
||||||
|
std::replace(includeDirU8.begin(), includeDirU8.end(), '\\', '/');
|
||||||
mod.includeDirs.emplace_back(modDirectoryPath / std::u8string_view((const char8_t*)includeDirU8.c_str()));
|
mod.includeDirs.emplace_back(modDirectoryPath / std::u8string_view((const char8_t*)includeDirU8.c_str()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!foundModSaveFilePath)
|
if (!foundModSaveFilePath)
|
||||||
modSaveFilePathU8 = modIni.getString("Main", "SaveFile", std::string());
|
modSaveFilePathU8 = modIni.getString("Main", "SaveFile", std::string());
|
||||||
|
|
|
||||||
|
|
@ -711,8 +711,6 @@ static const xxHashMap<CsdModifier> g_modifiers =
|
||||||
|
|
||||||
// ui_shop
|
// ui_shop
|
||||||
{ HashStr("ui_shop/footer/shop_footer"), { ALIGN_BOTTOM } },
|
{ HashStr("ui_shop/footer/shop_footer"), { ALIGN_BOTTOM } },
|
||||||
{ HashStr("ui_shop/header/ring"), { ALIGN_TOP } },
|
|
||||||
{ HashStr("ui_shop/header/shop_nametag"), { ALIGN_TOP } },
|
|
||||||
|
|
||||||
// ui_start
|
// ui_start
|
||||||
{ HashStr("ui_start/Clear/position/bg/bg_1"), { STRETCH } },
|
{ HashStr("ui_start/Clear/position/bg/bg_1"), { STRETCH } },
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 855a5a8c51ea5f84baecbf4fc87c182795d482c9
|
Subproject commit 4897cf7ef2070120310c28a1a672b427d745dad8
|
||||||
Loading…
Add table
Reference in a new issue