mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-26 15:54:18 +01:00
Split-out hash from ShaderBinary struct
This isn't necessary for pipeline creation and creates some difficulty with pipeline caching.
This commit is contained in:
parent
de10ab1219
commit
bc7e1eb380
@ -67,7 +67,6 @@ namespace skyline::gpu::interconnect {
|
|||||||
|
|
||||||
struct ShaderBinary {
|
struct ShaderBinary {
|
||||||
span<u8> binary;
|
span<u8> binary;
|
||||||
u64 hash;
|
|
||||||
u32 baseOffset;
|
u32 baseOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
namespace skyline::gpu::interconnect {
|
namespace skyline::gpu::interconnect {
|
||||||
/* Pipeline Stage */
|
/* Pipeline Stage */
|
||||||
ShaderBinary ShaderCache::Lookup(InterconnectContext &ctx, u64 programBase, u32 programOffset) {
|
std::pair<ShaderBinary, u64> ShaderCache::Lookup(InterconnectContext &ctx, u64 programBase, u32 programOffset) {
|
||||||
lastProgramBase = programBase;
|
lastProgramBase = programBase;
|
||||||
lastProgramOffset = programOffset;
|
lastProgramOffset = programOffset;
|
||||||
auto[blockMapping, blockOffset]{ctx.channelCtx.asCtx->gmmu.LookupBlock(programBase + programOffset)};
|
auto[blockMapping, blockOffset]{ctx.channelCtx.asCtx->gmmu.LookupBlock(programBase + programOffset)};
|
||||||
@ -91,11 +91,11 @@ namespace skyline::gpu::interconnect {
|
|||||||
}(blockMappingMirror.subspan(blockOffset));
|
}(blockMappingMirror.subspan(blockOffset));
|
||||||
|
|
||||||
binary.baseOffset = programOffset;
|
binary.baseOffset = programOffset;
|
||||||
binary.hash = XXH64(binary.binary.data(), binary.binary.size_bytes(), 0);
|
|
||||||
|
|
||||||
entry->cache.insert({blockMapping.data() + blockOffset, binary});
|
u64 hash{XXH64(binary.binary.data(), binary.binary.size_bytes(), 0)};
|
||||||
|
entry->cache.insert({blockMapping.data() + blockOffset, {binary, hash}});
|
||||||
|
|
||||||
return binary;
|
return {binary, hash};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderCache::Refresh(InterconnectContext &ctx, u64 programBase, u32 programOffset) {
|
bool ShaderCache::Refresh(InterconnectContext &ctx, u64 programBase, u32 programOffset) {
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
namespace skyline::gpu::interconnect {
|
namespace skyline::gpu::interconnect {
|
||||||
|
/**
|
||||||
|
* @brief Caches guest shader binaries and their memory locations
|
||||||
|
*/
|
||||||
class ShaderCache {
|
class ShaderCache {
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@ -14,7 +17,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
*/
|
*/
|
||||||
struct MirrorEntry {
|
struct MirrorEntry {
|
||||||
span<u8> mirror;
|
span<u8> mirror;
|
||||||
tsl::robin_map<u8 *, ShaderBinary> cache;
|
tsl::robin_map<u8 *, std::pair<ShaderBinary, u64>> cache;
|
||||||
std::optional<nce::NCE::TrapHandle> trap;
|
std::optional<nce::NCE::TrapHandle> trap;
|
||||||
|
|
||||||
static constexpr u32 SkipTrapThreshold{20}; //!< Threshold for the number of times a mirror trap needs to be hit before we fallback to always hashing
|
static constexpr u32 SkipTrapThreshold{20}; //!< Threshold for the number of times a mirror trap needs to be hit before we fallback to always hashing
|
||||||
@ -34,7 +37,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
u32 lastProgramOffset{};
|
u32 lastProgramOffset{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShaderBinary Lookup(InterconnectContext &ctx, u64 programBase, u32 programOffset);
|
/**
|
||||||
|
* @brief Returns the shader binary located at the given address
|
||||||
|
*/
|
||||||
|
std::pair<ShaderBinary, u64> Lookup(InterconnectContext &ctx, u64 programBase, u32 programOffset);
|
||||||
|
|
||||||
bool Refresh(InterconnectContext &ctx, u64 programBase, u32 programOffset);
|
bool Refresh(InterconnectContext &ctx, u64 programBase, u32 programOffset);
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ namespace skyline::gpu::interconnect::kepler_compute {
|
|||||||
: engine{manager, dirtyHandle, engine} {}
|
: engine{manager, dirtyHandle, engine} {}
|
||||||
|
|
||||||
void PipelineStageState::Flush(InterconnectContext &ctx, u32 programOffset) {
|
void PipelineStageState::Flush(InterconnectContext &ctx, u32 programOffset) {
|
||||||
binary = cache.Lookup(ctx, engine->programRegion, programOffset);
|
std::tie(binary, hash) = cache.Lookup(ctx, engine->programRegion, programOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PipelineStageState::Refresh(InterconnectContext &ctx, u32 programOffset) {
|
bool PipelineStageState::Refresh(InterconnectContext &ctx, u32 programOffset) {
|
||||||
@ -32,7 +32,7 @@ namespace skyline::gpu::interconnect::kepler_compute {
|
|||||||
|
|
||||||
Pipeline *PipelineState::Update(InterconnectContext &ctx, StateUpdateBuilder &builder, Textures &textures, ConstantBufferSet &constantBuffers, const QMD &qmd) {
|
Pipeline *PipelineState::Update(InterconnectContext &ctx, StateUpdateBuilder &builder, Textures &textures, ConstantBufferSet &constantBuffers, const QMD &qmd) {
|
||||||
const auto &stage{pipelineStage.UpdateGet(ctx, qmd.programOffset)};
|
const auto &stage{pipelineStage.UpdateGet(ctx, qmd.programOffset)};
|
||||||
packedState.shaderHash = stage.binary.hash;
|
packedState.shaderHash = stage.hash;
|
||||||
packedState.dimensions = {qmd.ctaThreadDimension0, qmd.ctaThreadDimension1, qmd.ctaThreadDimension2};
|
packedState.dimensions = {qmd.ctaThreadDimension0, qmd.ctaThreadDimension1, qmd.ctaThreadDimension2};
|
||||||
packedState.localMemorySize = qmd.shaderLocalMemoryLowSize + qmd.shaderLocalMemoryHighSize;
|
packedState.localMemorySize = qmd.shaderLocalMemoryLowSize + qmd.shaderLocalMemoryHighSize;
|
||||||
packedState.sharedMemorySize = qmd.sharedMemorySize;
|
packedState.sharedMemorySize = qmd.sharedMemorySize;
|
||||||
|
@ -26,6 +26,7 @@ namespace skyline::gpu::interconnect::kepler_compute {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ShaderBinary binary;
|
ShaderBinary binary;
|
||||||
|
u64 hash{};
|
||||||
|
|
||||||
PipelineStageState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
|
PipelineStageState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
|
||||||
|
|
||||||
|
@ -256,11 +256,11 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
throw exception("Shader type mismatch: {} != {}!", engine->pipeline.shader.type, static_cast<u8>(shaderType));
|
throw exception("Shader type mismatch: {} != {}!", engine->pipeline.shader.type, static_cast<u8>(shaderType));
|
||||||
|
|
||||||
if (!engine->pipeline.shader.enable && shaderType != engine::Pipeline::Shader::Type::Vertex) {
|
if (!engine->pipeline.shader.enable && shaderType != engine::Pipeline::Shader::Type::Vertex) {
|
||||||
binary.hash = 0;
|
hash = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
binary = cache.Lookup(ctx, engine->programRegion, engine->pipeline.programOffset);
|
std::tie(binary, hash) = cache.Lookup(ctx, engine->programRegion, engine->pipeline.programOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PipelineStageState::Refresh(InterconnectContext &ctx) {
|
bool PipelineStageState::Refresh(InterconnectContext &ctx) {
|
||||||
@ -495,7 +495,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
std::array<ShaderBinary, engine::PipelineCount> shaderBinaries;
|
std::array<ShaderBinary, engine::PipelineCount> shaderBinaries;
|
||||||
for (size_t i{}; i < engine::PipelineCount; i++) {
|
for (size_t i{}; i < engine::PipelineCount; i++) {
|
||||||
const auto &stage{pipelineStages[i].UpdateGet(ctx)};
|
const auto &stage{pipelineStages[i].UpdateGet(ctx)};
|
||||||
packedState.shaderHashes[i] = stage.binary.hash;
|
packedState.shaderHashes[i] = stage.hash;
|
||||||
shaderBinaries[i] = stage.binary;
|
shaderBinaries[i] = stage.binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ShaderBinary binary;
|
ShaderBinary binary;
|
||||||
|
u64 hash;
|
||||||
|
|
||||||
PipelineStageState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine, u8 shaderType);
|
PipelineStageState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine, u8 shaderType);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user