mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 21:55:30 +03:00
Add a workaround for split-mapping shaders
Some games split shaders across multiple mappings and *also* miss the end header, so read a suitably large amount and hope that's enough for now.
This commit is contained in:
parent
704660bbeb
commit
f1aed86177
@ -73,6 +73,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
span<u8> blockMappingMirror{blockMapping.data() - mirrorBlock.data() + entry->mirror.data(), blockMapping.size()};
|
span<u8> blockMappingMirror{blockMapping.data() - mirrorBlock.data() + entry->mirror.data(), blockMapping.size()};
|
||||||
|
|
||||||
ShaderBinary binary{};
|
ShaderBinary binary{};
|
||||||
|
auto shaderSubmapping{blockMappingMirror.subspan(blockOffset)};
|
||||||
// If nothing was in the cache then do a full shader parse
|
// If nothing was in the cache then do a full shader parse
|
||||||
binary.binary = [](span<u8> mapping) {
|
binary.binary = [](span<u8> mapping) {
|
||||||
// We attempt to find the shader size by looking for "BRA $" (Infinite Loop) which is used as padding at the end of the shader
|
// We attempt to find the shader size by looking for "BRA $" (Infinite Loop) which is used as padding at the end of the shader
|
||||||
@ -87,8 +88,22 @@ namespace skyline::gpu::interconnect {
|
|||||||
return span{shaderInstructions.begin(), it}.cast<u8>();
|
return span{shaderInstructions.begin(), it}.cast<u8>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapping;
|
return span<u8>{};
|
||||||
}(blockMappingMirror.subspan(blockOffset));
|
}(shaderSubmapping);
|
||||||
|
|
||||||
|
if (!binary.binary.valid()) {
|
||||||
|
static constexpr size_t FallbackSize{0x10000}; //!< Fallback shader size for when we can't detect it with the BRA $ pattern
|
||||||
|
if (shaderSubmapping.size() > FallbackSize) {
|
||||||
|
binary.binary = shaderSubmapping;
|
||||||
|
} else {
|
||||||
|
// If the shader is split across multiple mappings then read into an internal vector to store the binary
|
||||||
|
size_t storageOffset{splitBinaryStorage.size()};
|
||||||
|
splitBinaryStorage.resize(storageOffset + FallbackSize);
|
||||||
|
auto shaderStorage{span{splitBinaryStorage}.subspan(storageOffset, FallbackSize)};
|
||||||
|
ctx.channelCtx.asCtx->gmmu.Read(shaderStorage, programBase + programOffset);
|
||||||
|
binary.binary = shaderStorage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binary.baseOffset = programOffset;
|
binary.baseOffset = programOffset;
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
span<u8> mirrorBlock{}; //!< Guest mapped memory block corresponding to `entry`
|
span<u8> mirrorBlock{}; //!< Guest mapped memory block corresponding to `entry`
|
||||||
u64 lastProgramBase{};
|
u64 lastProgramBase{};
|
||||||
u32 lastProgramOffset{};
|
u32 lastProgramOffset{};
|
||||||
|
std::vector<u8> splitBinaryStorage;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user