diff --git a/rpcs3/rpcs3qt/rsx_debugger.cpp b/rpcs3/rpcs3qt/rsx_debugger.cpp index 4951f60896..a2b87cd4e4 100644 --- a/rpcs3/rpcs3qt/rsx_debugger.cpp +++ b/rpcs3/rpcs3qt/rsx_debugger.cpp @@ -498,7 +498,7 @@ void rsx_debugger::OnClickDrawCalls() //m_list_index_buffer->insertColumn(0, "Index", 0, 700); if (frame_debug.draw_calls[draw_id].state.index_type() == rsx::index_array_type::u16) { - u16 *index_buffer = reinterpret_cast(frame_debug.draw_calls[draw_id].index.data()); + auto index_buffer = ref_ptr(frame_debug.draw_calls[draw_id].index); for (u32 i = 0; i < frame_debug.draw_calls[draw_id].vertex_count; ++i) { m_list_index_buffer->insertItem(i, qstr(std::to_string(index_buffer[i]))); @@ -506,7 +506,7 @@ void rsx_debugger::OnClickDrawCalls() } if (frame_debug.draw_calls[draw_id].state.index_type() == rsx::index_array_type::u32) { - u32 *index_buffer = reinterpret_cast(frame_debug.draw_calls[draw_id].index.data()); + auto index_buffer = ref_ptr(frame_debug.draw_calls[draw_id].index); for (u32 i = 0; i < frame_debug.draw_calls[draw_id].vertex_count; ++i) { m_list_index_buffer->insertItem(i, qstr(std::to_string(index_buffer[i]))); diff --git a/rpcs3/util/types.hpp b/rpcs3/util/types.hpp index 2edc9fd414..8b0c12a285 100644 --- a/rpcs3/util/types.hpp +++ b/rpcs3/util/types.hpp @@ -1218,6 +1218,113 @@ constexpr void write_to_ptr(U&& array, const T& value) ensure(!"Unimplemented"); } +constexpr struct aref_tag_t{} aref_tag{}; + +template +class aref final +{ + U* m_ptr; + + static_assert(sizeof(std::decay_t) % sizeof(U) == 0); + +public: + aref() = delete; + + constexpr aref(const aref&) = default; + + explicit constexpr aref(aref_tag_t, U* ptr) + : m_ptr(ptr) + { + } + + constexpr T value() const + { + return read_from_ptr(m_ptr); + } + + constexpr operator T() const + { + return read_from_ptr(m_ptr); + } + + aref& operator=(const aref&) = delete; + + constexpr aref& operator=(const T& value) const + { + write_to_ptr(m_ptr, value); + return *this; + } + + template requires (std::is_convertible_v) && PtrSame + aref ref(MT T2::*const mptr) const + { + return aref(aref_tag, m_ptr + offset32(mptr) / sizeof(U)); + } + + template > requires (std::is_convertible_v) && PtrSame + aref ref(MT T2::*const mptr, usz index) const + { + return aref(aref_tag, m_ptr + offset32(mptr) / sizeof(U) + sizeof(ET) / sizeof(U) * index); + } +}; + +template +class aref +{ + U* m_ptr; + + static_assert(sizeof(std::decay_t) % sizeof(U) == 0); + +public: + aref() = delete; + + constexpr aref(const aref&) = default; + + explicit constexpr aref(aref_tag_t, U* ptr) + : m_ptr(ptr) + { + } + + aref& operator=(const aref&) = delete; + + constexpr aref operator[](usz index) const + { + return aref(aref_tag, m_ptr + index * (sizeof(T) / sizeof(U))); + } +}; + +template +class aref +{ + U* m_ptr; + + static_assert(sizeof(std::decay_t) % sizeof(U) == 0); + +public: + aref() = delete; + + constexpr aref(const aref&) = default; + + explicit constexpr aref(aref_tag_t, U* ptr) + : m_ptr(ptr) + { + } + + aref& operator=(const aref&) = delete; + + constexpr aref operator[](usz index) const + { + return aref(aref_tag, m_ptr + index * (sizeof(T) / sizeof(U))); + } +}; + +// Reference object of type T, see read_from_ptr +template +constexpr auto ref_ptr(U&& array, usz pos = 0) -> aref> +{ + return aref>(aref_tag, &array[pos]); +} + namespace utils { struct serial;