VideoCore: Use union to index into Regs struct

Also remove some unused members.
This commit is contained in:
Yuri Kunde Schlesner 2017-01-28 13:58:51 -08:00
parent 2889372e47
commit 602f57da38
2 changed files with 28 additions and 46 deletions

View File

@ -49,19 +49,23 @@ MICROPROFILE_DEFINE(GPU_Drawing, "GPU", "Drawing", MP_RGB(50, 50, 240));
static void WritePicaReg(u32 id, u32 value, u32 mask) { static void WritePicaReg(u32 id, u32 value, u32 mask) {
auto& regs = g_state.regs; auto& regs = g_state.regs;
if (id >= regs.NumIds()) if (id >= Regs::NUM_REGS) {
LOG_ERROR(HW_GPU,
"Commandlist tried to write to invalid register 0x%03X (value: %08X, mask: %X)",
id, value, mask);
return; return;
}
// TODO: Figure out how register masking acts on e.g. vs.uniform_setup.set_value // TODO: Figure out how register masking acts on e.g. vs.uniform_setup.set_value
u32 old_value = regs[id]; u32 old_value = regs.reg_array[id];
const u32 write_mask = expand_bits_to_bytes[mask]; const u32 write_mask = expand_bits_to_bytes[mask];
regs[id] = (old_value & ~write_mask) | (value & write_mask); regs.reg_array[id] = (old_value & ~write_mask) | (value & write_mask);
// Double check for is_pica_tracing to avoid call overhead // Double check for is_pica_tracing to avoid call overhead
if (DebugUtils::IsPicaTracing()) { if (DebugUtils::IsPicaTracing()) {
DebugUtils::OnPicaRegWrite({(u16)id, (u16)mask, regs[id]}); DebugUtils::OnPicaRegWrite({(u16)id, (u16)mask, regs.reg_array[id]});
} }
if (g_debug_context) if (g_debug_context)

View File

@ -45,6 +45,10 @@ namespace Pica {
#endif // _MSC_VER #endif // _MSC_VER
struct Regs { struct Regs {
static constexpr size_t NUM_REGS = 0x300;
union {
struct {
INSERT_PADDING_WORDS(0x10); INSERT_PADDING_WORDS(0x10);
u32 trigger_irq; u32 trigger_irq;
INSERT_PADDING_WORDS(0x2f); INSERT_PADDING_WORDS(0x2f);
@ -56,35 +60,16 @@ struct Regs {
ShaderRegs gs; ShaderRegs gs;
ShaderRegs vs; ShaderRegs vs;
INSERT_PADDING_WORDS(0x20); INSERT_PADDING_WORDS(0x20);
};
std::array<u32, NUM_REGS> reg_array;
};
// Map register indices to names readable by humans // Map register indices to names readable by humans
// Used for debugging purposes, so performance is not an issue here
static std::string GetCommandName(int index); static std::string GetCommandName(int index);
static constexpr size_t NumIds() {
return sizeof(Regs) / sizeof(u32);
}
const u32& operator[](int index) const {
const u32* content = reinterpret_cast<const u32*>(this);
return content[index];
}
u32& operator[](int index) {
u32* content = reinterpret_cast<u32*>(this);
return content[index];
}
private:
/*
* Most physical addresses which Pica registers refer to are 8-byte aligned.
* This function should be used to get the address from a raw register value.
*/
static inline u32 DecodeAddressRegister(u32 register_value) {
return register_value * 8;
}
}; };
static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Regs struct has wrong size");
// TODO: MSVC does not support using offsetof() on non-static data members even though this // TODO: MSVC does not support using offsetof() on non-static data members even though this
// is technically allowed since C++11. This macro should be enabled once MSVC adds // is technically allowed since C++11. This macro should be enabled once MSVC adds
// support for that. // support for that.
@ -154,11 +139,4 @@ ASSERT_REG_POSITION(vs, 0x2b0);
#undef ASSERT_REG_POSITION #undef ASSERT_REG_POSITION
#endif // !defined(_MSC_VER) #endif // !defined(_MSC_VER)
// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value
// anyway.
static_assert(sizeof(Regs) <= 0x300 * sizeof(u32),
"Register set structure larger than it should be");
static_assert(sizeof(Regs) >= 0x300 * sizeof(u32),
"Register set structure smaller than it should be");
} // namespace Pica } // namespace Pica