mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-04-28 13:27:58 +03:00
Fix Cool Edge whale not having reflections. (#1441)
Some checks failed
validate-internal / build (push) Failing after 9s
Some checks failed
validate-internal / build (push) Failing after 9s
* Fix Cool Edge whale not having reflections. * Fix Vulkan validation error.
This commit is contained in:
parent
41fd1761b1
commit
a02f34b028
2 changed files with 59 additions and 13 deletions
|
@ -683,6 +683,9 @@ static void DestructTempResources()
|
|||
if (texture->patchedTexture != nullptr)
|
||||
g_textureDescriptorAllocator.free(texture->patchedTexture->descriptorIndex);
|
||||
|
||||
if (texture->recreatedCubeMapTexture != nullptr)
|
||||
g_textureDescriptorAllocator.free(texture->recreatedCubeMapTexture->descriptorIndex);
|
||||
|
||||
texture->~GuestTexture();
|
||||
break;
|
||||
}
|
||||
|
@ -3647,6 +3650,14 @@ static void SetTextureInRenderThread(uint32_t index, GuestTexture* texture)
|
|||
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.texture3DIndices[index], texture != nullptr &&
|
||||
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 &&
|
||||
viewDimension == RenderTextureViewDimension::TEXTURE_CUBE ? texture->descriptorIndex : TEXTURE_DESCRIPTOR_NULL_TEXTURE_CUBE);
|
||||
}
|
||||
|
@ -5477,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;
|
||||
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;
|
||||
desc.dimension = ConvertTextureDimension(ddsDesc.type);
|
||||
desc.width = ddsDesc.width;
|
||||
desc.height = ddsDesc.height;
|
||||
desc.depth = ddsDesc.depth;
|
||||
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.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.texture = texture.textureHolder.get();
|
||||
texture.layout = RenderTextureLayout::COPY_DEST;
|
||||
|
@ -5501,6 +5521,10 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
|
|||
viewDesc.dimension = ConvertTextureViewDimension(ddsDesc.type);
|
||||
viewDesc.mipLevels = ddsDesc.numMips;
|
||||
viewDesc.componentMapping = componentMapping;
|
||||
|
||||
if (forceCubeMap)
|
||||
viewDesc.dimension = RenderTextureViewDimension::TEXTURE_CUBE;
|
||||
|
||||
texture.textureView = texture.texture->createTextureView(viewDesc);
|
||||
texture.descriptorIndex = g_textureDescriptorAllocator.allocate();
|
||||
g_textureDescriptorSet->setTexture(texture.descriptorIndex, texture.texture, RenderTextureLayout::SHADER_READ, texture.textureView.get());
|
||||
|
@ -5525,7 +5549,7 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
|
|||
uint32_t curSrcOffset = 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++)
|
||||
{
|
||||
|
@ -5575,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));
|
||||
|
||||
for (size_t i = 0; i < slices.size(); i++)
|
||||
{
|
||||
auto& slice = slices[i];
|
||||
auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
|
||||
{
|
||||
g_copyCommandList->copyTextureRegion(
|
||||
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));
|
||||
};
|
||||
|
||||
g_copyCommandList->copyTextureRegion(
|
||||
RenderTextureCopyLocation::Subresource(texture.texture, i),
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -5654,13 +5689,12 @@ std::unique_ptr<GuestTexture> LoadTexture(const uint8_t* data, size_t dataSize,
|
|||
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 entries = reinterpret_cast<BlockCompressionDiffPatchEntry*>(g_buttonBcDiff.get() + header->entriesOffset);
|
||||
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)
|
||||
{
|
||||
return lhs.hash < rhs;
|
||||
|
@ -5693,8 +5727,19 @@ static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32
|
|||
#ifdef _DEBUG
|
||||
texture.texture->setName(reinterpret_cast<char*>(g_memory.Translate(pictureData->name + 2)));
|
||||
#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->type = 0;
|
||||
|
|
|
@ -158,6 +158,7 @@ struct GuestTexture : GuestBaseTexture
|
|||
void* mappedMemory = nullptr;
|
||||
std::unique_ptr<RenderFramebuffer> framebuffer;
|
||||
std::unique_ptr<GuestTexture> patchedTexture;
|
||||
std::unique_ptr<GuestTexture> recreatedCubeMapTexture;
|
||||
struct GuestSurface* sourceSurface = nullptr;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue