mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-06-28 09:45:45 +02:00
[shader_recompiler/ir] fix potential CBuf collision when count mismatches
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
74a6607f8e
commit
46ebff3fca
2 changed files with 17 additions and 12 deletions
|
|
@ -38,10 +38,11 @@ struct CbufWordKeyHash {
|
||||||
struct HandleKey {
|
struct HandleKey {
|
||||||
u32 index, offset, shift_left;
|
u32 index, offset, shift_left;
|
||||||
u32 sec_index, sec_offset, sec_shift_left;
|
u32 sec_index, sec_offset, sec_shift_left;
|
||||||
|
u32 count;
|
||||||
bool has_secondary;
|
bool has_secondary;
|
||||||
constexpr bool operator==(const HandleKey& o) const noexcept {
|
constexpr bool operator==(const HandleKey& o) const noexcept {
|
||||||
return std::tie(index, offset, shift_left, sec_index, sec_offset, sec_shift_left, has_secondary)
|
return std::tie(index, offset, shift_left, sec_index, sec_offset, sec_shift_left, count, has_secondary)
|
||||||
== std::tie(o.index, o.offset, o.shift_left, o.sec_index, o.sec_offset, o.sec_shift_left, o.has_secondary);
|
== std::tie(o.index, o.offset, o.shift_left, o.sec_index, o.sec_offset, o.sec_shift_left, o.count, o.has_secondary);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct HandleKeyHash {
|
struct HandleKeyHash {
|
||||||
|
|
@ -50,8 +51,8 @@ struct HandleKeyHash {
|
||||||
h ^= (size_t(k.shift_left) << 1);
|
h ^= (size_t(k.shift_left) << 1);
|
||||||
h ^= (size_t(k.sec_index) << 33) ^ (size_t(k.sec_offset) << 2);
|
h ^= (size_t(k.sec_index) << 33) ^ (size_t(k.sec_offset) << 2);
|
||||||
h ^= (size_t(k.sec_shift_left) << 3);
|
h ^= (size_t(k.sec_shift_left) << 3);
|
||||||
h ^= k.has_secondary ? 0x9e3779b97f4a7c15ULL : 0ULL;
|
h ^= (size_t(k.count) << 7);
|
||||||
return h;
|
return h ^ (k.has_secondary ? 0x9e3779b97f4a7c15ULL : 0ULL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -270,21 +270,25 @@ bool IsTextureInstruction(const IR::Inst& inst) {
|
||||||
|
|
||||||
static inline u32 ReadCbufCached(Environment& env, u32 index, u32 offset) {
|
static inline u32 ReadCbufCached(Environment& env, u32 index, u32 offset) {
|
||||||
const CbufWordKey k{index, offset};
|
const CbufWordKey k{index, offset};
|
||||||
if (auto it = env.cbuf_word_cache.find(k); it != env.cbuf_word_cache.end()) return it->second;
|
if (auto it = env.cbuf_word_cache.find(k); it != env.cbuf_word_cache.end())
|
||||||
|
return it->second;
|
||||||
const u32 v = env.ReadCbufValue(index, offset);
|
const u32 v = env.ReadCbufValue(index, offset);
|
||||||
env.cbuf_word_cache.emplace(k, v);
|
env.cbuf_word_cache.emplace(k, v);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 GetTextureHandleCached(Environment& env, const ConstBufferAddr& cbuf) {
|
static inline u32 GetTextureHandleCached(Environment& env, const ConstBufferAddr& cbuf) {
|
||||||
const u32 sec_idx = cbuf.has_secondary ? cbuf.secondary_index : cbuf.index;
|
// Must all be uniquely different variables
|
||||||
const u32 sec_off = cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset;
|
// If has secondary, then it will be cbuf.secondary_{index|offset}, else its 0.
|
||||||
const HandleKey hk{cbuf.index, cbuf.offset, cbuf.shift_left,
|
// So we can just hand it out the raw variable without using sec_idx or sec_off
|
||||||
sec_idx, sec_off, cbuf.secondary_shift_left, cbuf.has_secondary};
|
// because comparing 0 against 0 will yield true.
|
||||||
if (auto it = env.handle_cache.find(hk); it != env.handle_cache.end()) return it->second;
|
const HandleKey hk{cbuf.index, cbuf.offset, cbuf.shift_left, cbuf.secondary_index, cbuf.secondary_offset, cbuf.secondary_shift_left, cbuf.count, cbuf.has_secondary};
|
||||||
|
if (auto it = env.handle_cache.find(hk); it != env.handle_cache.end())
|
||||||
|
return it->second;
|
||||||
|
const u32 sec_idx = cbuf.has_secondary ? cbuf.secondary_index : cbuf.index;
|
||||||
|
const u32 sec_off = cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset;
|
||||||
const u32 lhs = ReadCbufCached(env, cbuf.index, cbuf.offset) << cbuf.shift_left;
|
const u32 lhs = ReadCbufCached(env, cbuf.index, cbuf.offset) << cbuf.shift_left;
|
||||||
const u32 rhs = ReadCbufCached(env, sec_idx, sec_off) << cbuf.secondary_shift_left;
|
const u32 rhs = ReadCbufCached(env, sec_idx, sec_off) << cbuf.secondary_shift_left;
|
||||||
const u32 handle = lhs | rhs;
|
const u32 handle = lhs | rhs;
|
||||||
env.handle_cache.emplace(hk, handle);
|
env.handle_cache.emplace(hk, handle);
|
||||||
return handle;
|
return handle;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue