properly do tls + array pod (#3529)

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3529
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2026-02-12 20:38:04 +01:00 committed by crueter
parent 6b7e54e115
commit c487a5cbc4
6 changed files with 43 additions and 369 deletions

View File

@ -200,11 +200,8 @@ private:
}
Common::VirtualBuffer<VAddr> cpu_backing_address;
inline static thread_local TranslationEntry t_slot0{};
inline static thread_local TranslationEntry t_slot1{};
inline static thread_local TranslationEntry t_slot2{};
inline static thread_local TranslationEntry t_slot3{};
inline static thread_local u32 cache_cursor = 0;
std::array<TranslationEntry, 4> t_slot{};
u32 cache_cursor = 0;
using CounterType = u8;
using CounterAtomicType = std::atomic_uint8_t;
static constexpr size_t subentries = 8 / sizeof(CounterType);

View File

@ -247,10 +247,7 @@ void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size
}
impl->multi_dev_address.Register(new_dev, start_id);
}
t_slot0 = {};
t_slot1 = {};
t_slot2 = {};
t_slot3 = {};
t_slot = {};
if (track) {
TrackContinuityImpl(address, virtual_address, size, asid);
}
@ -282,10 +279,7 @@ void DeviceMemoryManager<Traits>::Unmap(DAddr address, size_t size) {
compressed_device_addr[phys_addr - 1] = new_start | MULTI_FLAG;
}
}
t_slot0 = {};
t_slot1 = {};
t_slot2 = {};
t_slot3 = {};
t_slot = {};
}
template <typename Traits>
void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address,
@ -428,42 +422,18 @@ void DeviceMemoryManager<Traits>::ReadBlock(DAddr address, void* dest_pointer, s
const std::size_t page_offset = address & Memory::YUZU_PAGEMASK;
if (size <= Memory::YUZU_PAGESIZE - page_offset) {
const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK);
if (t_slot0.guest_page == guest_page && t_slot0.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot0.host_ptr + page_offset, size);
for (size_t i = 0; i < 4; ++i) {
if (t_slot[i].guest_page == guest_page && t_slot[i].host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot[i].host_ptr + page_offset, size);
return;
}
if (t_slot1.guest_page == guest_page && t_slot1.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot1.host_ptr + page_offset, size);
return;
}
if (t_slot2.guest_page == guest_page && t_slot2.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot2.host_ptr + page_offset, size);
return;
}
if (t_slot3.guest_page == guest_page && t_slot3.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot3.host_ptr + page_offset, size);
return;
}
const std::size_t page_index = address >> Memory::YUZU_PAGEBITS;
const auto phys_addr = compressed_physical_ptr[page_index];
if (phys_addr != 0) {
auto* const mem_ptr = GetPointerFromRaw<u8>(
(static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS));
switch (cache_cursor & 3U) {
case 0:
t_slot0 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
case 1:
t_slot1 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
case 2:
t_slot2 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
default:
t_slot3 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
}
auto* const mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS));
t_slot[cache_cursor % t_slot.size()] = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
cache_cursor = (cache_cursor + 1) & 3U;
std::memcpy(dest_pointer, mem_ptr + page_offset, size);
return;
@ -510,42 +480,18 @@ void DeviceMemoryManager<Traits>::ReadBlockUnsafe(DAddr address, void* dest_poin
const std::size_t page_offset = address & Memory::YUZU_PAGEMASK;
if (size <= Memory::YUZU_PAGESIZE - page_offset) {
const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK);
if (t_slot0.guest_page == guest_page && t_slot0.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot0.host_ptr + page_offset, size);
for (size_t i = 0; i < 4; ++i) {
if (t_slot[i].guest_page == guest_page && t_slot[i].host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot[i].host_ptr + page_offset, size);
return;
}
if (t_slot1.guest_page == guest_page && t_slot1.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot1.host_ptr + page_offset, size);
return;
}
if (t_slot2.guest_page == guest_page && t_slot2.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot2.host_ptr + page_offset, size);
return;
}
if (t_slot3.guest_page == guest_page && t_slot3.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot3.host_ptr + page_offset, size);
return;
}
const std::size_t page_index = address >> Memory::YUZU_PAGEBITS;
const auto phys_addr = compressed_physical_ptr[page_index];
if (phys_addr != 0) {
auto* const mem_ptr = GetPointerFromRaw<u8>(
(static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS));
switch (cache_cursor & 3U) {
case 0:
t_slot0 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
case 1:
t_slot1 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
case 2:
t_slot2 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
default:
t_slot3 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
}
auto* const mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS));
t_slot[cache_cursor % t_slot.size()] = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
cache_cursor = (cache_cursor + 1) & 3U;
std::memcpy(dest_pointer, mem_ptr + page_offset, size);
return;

View File

@ -783,159 +783,13 @@ void BufferCache<P>::BindHostVertexBuffer(u32 index, Buffer& buffer, u32 offset,
template <class P>
Binding& BufferCache<P>::VertexBufferSlot(u32 index) {
ASSERT(index < NUM_VERTEX_BUFFERS);
switch (index) {
case 0:
return v_buffer0;
case 1:
return v_buffer1;
case 2:
return v_buffer2;
case 3:
return v_buffer3;
case 4:
return v_buffer4;
case 5:
return v_buffer5;
case 6:
return v_buffer6;
case 7:
return v_buffer7;
case 8:
return v_buffer8;
case 9:
return v_buffer9;
case 10:
return v_buffer10;
case 11:
return v_buffer11;
case 12:
return v_buffer12;
case 13:
return v_buffer13;
case 14:
return v_buffer14;
case 15:
return v_buffer15;
#ifndef __APPLE__
case 16:
return v_buffer16;
case 17:
return v_buffer17;
case 18:
return v_buffer18;
case 19:
return v_buffer19;
case 20:
return v_buffer20;
case 21:
return v_buffer21;
case 22:
return v_buffer22;
case 23:
return v_buffer23;
case 24:
return v_buffer24;
case 25:
return v_buffer25;
case 26:
return v_buffer26;
case 27:
return v_buffer27;
case 28:
return v_buffer28;
case 29:
return v_buffer29;
case 30:
return v_buffer30;
case 31:
return v_buffer31;
#endif
default:
#ifdef __APPLE__
return v_buffer15;
#else
return v_buffer31;
#endif
}
return v_buffer[index];
}
template <class P>
const Binding& BufferCache<P>::VertexBufferSlot(u32 index) const {
ASSERT(index < NUM_VERTEX_BUFFERS);
switch (index) {
case 0:
return v_buffer0;
case 1:
return v_buffer1;
case 2:
return v_buffer2;
case 3:
return v_buffer3;
case 4:
return v_buffer4;
case 5:
return v_buffer5;
case 6:
return v_buffer6;
case 7:
return v_buffer7;
case 8:
return v_buffer8;
case 9:
return v_buffer9;
case 10:
return v_buffer10;
case 11:
return v_buffer11;
case 12:
return v_buffer12;
case 13:
return v_buffer13;
case 14:
return v_buffer14;
case 15:
return v_buffer15;
#ifndef __APPLE__
case 16:
return v_buffer16;
case 17:
return v_buffer17;
case 18:
return v_buffer18;
case 19:
return v_buffer19;
case 20:
return v_buffer20;
case 21:
return v_buffer21;
case 22:
return v_buffer22;
case 23:
return v_buffer23;
case 24:
return v_buffer24;
case 25:
return v_buffer25;
case 26:
return v_buffer26;
case 27:
return v_buffer27;
case 28:
return v_buffer28;
case 29:
return v_buffer29;
case 30:
return v_buffer30;
case 31:
return v_buffer31;
#endif
default:
#ifdef __APPLE__
return v_buffer15;
#else
return v_buffer31;
#endif
}
return v_buffer[index];
}
template <class P>

View File

@ -484,40 +484,7 @@ private:
u32 enabled_vertex_buffers_mask = 0;
u64 vertex_buffers_serial = 0;
Binding v_buffer0{};
Binding v_buffer1{};
Binding v_buffer2{};
Binding v_buffer3{};
Binding v_buffer4{};
Binding v_buffer5{};
Binding v_buffer6{};
Binding v_buffer7{};
Binding v_buffer8{};
Binding v_buffer9{};
Binding v_buffer10{};
Binding v_buffer11{};
Binding v_buffer12{};
Binding v_buffer13{};
Binding v_buffer14{};
Binding v_buffer15{};
#ifndef __APPLE__
Binding v_buffer16{};
Binding v_buffer17{};
Binding v_buffer18{};
Binding v_buffer19{};
Binding v_buffer20{};
Binding v_buffer21{};
Binding v_buffer22{};
Binding v_buffer23{};
Binding v_buffer24{};
Binding v_buffer25{};
Binding v_buffer26{};
Binding v_buffer27{};
Binding v_buffer28{};
Binding v_buffer29{};
Binding v_buffer30{};
Binding v_buffer31{};
#endif
std::array<Binding, 32> v_buffer{};
boost::container::small_vector<BufferCopy, 4> upload_copies;

View File

@ -314,58 +314,24 @@ void TextureCache<P>::CheckFeedbackLoop(std::span<const ImageViewInOut> views) {
continue;
}
if ((rt_active_mask & (1u << 0)) && view.id == render_targets.color_buffer_ids[0]) {
continue;
}
if ((rt_active_mask & (1u << 1)) && view.id == render_targets.color_buffer_ids[1]) {
continue;
}
if ((rt_active_mask & (1u << 2)) && view.id == render_targets.color_buffer_ids[2]) {
continue;
}
if ((rt_active_mask & (1u << 3)) && view.id == render_targets.color_buffer_ids[3]) {
continue;
}
if ((rt_active_mask & (1u << 4)) && view.id == render_targets.color_buffer_ids[4]) {
continue;
}
if ((rt_active_mask & (1u << 5)) && view.id == render_targets.color_buffer_ids[5]) {
continue;
}
if ((rt_active_mask & (1u << 6)) && view.id == render_targets.color_buffer_ids[6]) {
continue;
}
if ((rt_active_mask & (1u << 7)) && view.id == render_targets.color_buffer_ids[7]) {
continue;
}
if (depth_active && view.id == render_targets.depth_buffer_id) {
{
bool is_continue = false;
for (size_t i = 0; i < 8; ++i)
is_continue |= (rt_active_mask & (1u << i)) && view.id == render_targets.color_buffer_ids[i];
if (is_continue)
continue;
}
if (depth_active && view.id == render_targets.depth_buffer_id)
continue;
const ImageId view_image_id = slot_image_views[view.id].image_id;
if ((rt_active_mask & (1u << 0)) && view_image_id == rt0_image_id) {
return true;
}
if ((rt_active_mask & (1u << 1)) && view_image_id == rt1_image_id) {
return true;
}
if ((rt_active_mask & (1u << 2)) && view_image_id == rt2_image_id) {
return true;
}
if ((rt_active_mask & (1u << 3)) && view_image_id == rt3_image_id) {
return true;
}
if ((rt_active_mask & (1u << 4)) && view_image_id == rt4_image_id) {
return true;
}
if ((rt_active_mask & (1u << 5)) && view_image_id == rt5_image_id) {
return true;
}
if ((rt_active_mask & (1u << 6)) && view_image_id == rt6_image_id) {
return true;
}
if ((rt_active_mask & (1u << 7)) && view_image_id == rt7_image_id) {
return true;
{
bool is_continue = false;
for (size_t i = 0; i < 8; ++i)
is_continue |= (rt_active_mask & (1u << i)) && view_image_id == rt_image_id[i];
if (is_continue)
continue;
}
if (depth_active && view_image_id == rt_depth_image_id) {
return true;
@ -601,61 +567,12 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
rt_active_mask = 0;
const ImageViewId rt0_view = render_targets.color_buffer_ids[0];
if (rt0_view) {
rt_active_mask |= (1u << 0);
rt0_image_id = slot_image_views[rt0_view].image_id;
} else {
rt0_image_id = ImageId{};
rt_image_id = {};
for (size_t i = 0; i < rt_image_id.size(); ++i) {
if (ImageViewId const view = render_targets.color_buffer_ids[i]; view) {
rt_active_mask |= 1u << i;
rt_image_id[i] = slot_image_views[view].image_id;
}
const ImageViewId rt1_view = render_targets.color_buffer_ids[1];
if (rt1_view) {
rt_active_mask |= (1u << 1);
rt1_image_id = slot_image_views[rt1_view].image_id;
} else {
rt1_image_id = ImageId{};
}
const ImageViewId rt2_view = render_targets.color_buffer_ids[2];
if (rt2_view) {
rt_active_mask |= (1u << 2);
rt2_image_id = slot_image_views[rt2_view].image_id;
} else {
rt2_image_id = ImageId{};
}
const ImageViewId rt3_view = render_targets.color_buffer_ids[3];
if (rt3_view) {
rt_active_mask |= (1u << 3);
rt3_image_id = slot_image_views[rt3_view].image_id;
} else {
rt3_image_id = ImageId{};
}
const ImageViewId rt4_view = render_targets.color_buffer_ids[4];
if (rt4_view) {
rt_active_mask |= (1u << 4);
rt4_image_id = slot_image_views[rt4_view].image_id;
} else {
rt4_image_id = ImageId{};
}
const ImageViewId rt5_view = render_targets.color_buffer_ids[5];
if (rt5_view) {
rt_active_mask |= (1u << 5);
rt5_image_id = slot_image_views[rt5_view].image_id;
} else {
rt5_image_id = ImageId{};
}
const ImageViewId rt6_view = render_targets.color_buffer_ids[6];
if (rt6_view) {
rt_active_mask |= (1u << 6);
rt6_image_id = slot_image_views[rt6_view].image_id;
} else {
rt6_image_id = ImageId{};
}
const ImageViewId rt7_view = render_targets.color_buffer_ids[7];
if (rt7_view) {
rt_active_mask |= (1u << 7);
rt7_image_id = slot_image_views[rt7_view].image_id;
} else {
rt7_image_id = ImageId{};
}
if (depth_buffer_id) {
rt_active_mask |= (1u << NUM_RT);

View File

@ -457,14 +457,7 @@ private:
RenderTargets render_targets;
u64 render_targets_serial = 0;
u32 rt_active_mask = 0;
ImageId rt0_image_id{};
ImageId rt1_image_id{};
ImageId rt2_image_id{};
ImageId rt3_image_id{};
ImageId rt4_image_id{};
ImageId rt5_image_id{};
ImageId rt6_image_id{};
ImageId rt7_image_id{};
std::array<ImageId, 8> rt_image_id{};
ImageId rt_depth_image_id{};
u64 texture_bindings_serial = 0;
u64 last_feedback_loop_serial = 0;