mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-11-03 20:24:43 +01:00 
			
		
		
		
	Texture Cache: make sparse texture table per channel
This commit is contained in:
		
							parent
							
								
									ffe3984353
								
							
						
					
					
						commit
						a7c1306e2d
					
				@ -1431,7 +1431,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu);
 | 
					    ForEachSparseImageInRegion(channel_state->gpu_memory.GetID(), gpu_addr, size_bytes,
 | 
				
			||||||
 | 
					                               region_check_gpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool can_rescale = info.rescaleable;
 | 
					    bool can_rescale = info.rescaleable;
 | 
				
			||||||
    bool any_rescaled = false;
 | 
					    bool any_rescaled = false;
 | 
				
			||||||
@ -1842,7 +1843,7 @@ void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, s
 | 
				
			|||||||
    if (!storage_id) {
 | 
					    if (!storage_id) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    auto& gpu_page_table = gpu_page_table_storage[*storage_id];
 | 
					    auto& gpu_page_table = gpu_page_table_storage[*storage_id * 2];
 | 
				
			||||||
    ForEachGPUPage(gpu_addr, size,
 | 
					    ForEachGPUPage(gpu_addr, size,
 | 
				
			||||||
                   [this, &gpu_page_table, &images, gpu_addr, size, func](u64 page) {
 | 
					                   [this, &gpu_page_table, &images, gpu_addr, size, func](u64 page) {
 | 
				
			||||||
                       const auto it = gpu_page_table.find(page);
 | 
					                       const auto it = gpu_page_table.find(page);
 | 
				
			||||||
@ -1882,11 +1883,18 @@ void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, s
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template <class P>
 | 
					template <class P>
 | 
				
			||||||
template <typename Func>
 | 
					template <typename Func>
 | 
				
			||||||
void TextureCache<P>::ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func) {
 | 
					void TextureCache<P>::ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr, size_t size,
 | 
				
			||||||
 | 
					                                                 Func&& func) {
 | 
				
			||||||
    using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type;
 | 
					    using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type;
 | 
				
			||||||
    static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
 | 
					    static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
 | 
				
			||||||
    boost::container::small_vector<ImageId, 8> images;
 | 
					    boost::container::small_vector<ImageId, 8> images;
 | 
				
			||||||
    ForEachGPUPage(gpu_addr, size, [this, &images, gpu_addr, size, func](u64 page) {
 | 
					    auto storage_id = getStorageID(as_id);
 | 
				
			||||||
 | 
					    if (!storage_id) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    auto& sparse_page_table = gpu_page_table_storage[*storage_id * 2 + 1];
 | 
				
			||||||
 | 
					    ForEachGPUPage(gpu_addr, size,
 | 
				
			||||||
 | 
					                   [this, &sparse_page_table, &images, gpu_addr, size, func](u64 page) {
 | 
				
			||||||
                       const auto it = sparse_page_table.find(page);
 | 
					                       const auto it = sparse_page_table.find(page);
 | 
				
			||||||
                       if (it == sparse_page_table.end()) {
 | 
					                       if (it == sparse_page_table.end()) {
 | 
				
			||||||
                           if constexpr (BOOL_BREAK) {
 | 
					                           if constexpr (BOOL_BREAK) {
 | 
				
			||||||
@ -1988,8 +1996,9 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
 | 
				
			|||||||
            sparse_maps.push_back(map_id);
 | 
					            sparse_maps.push_back(map_id);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    sparse_views.emplace(image_id, std::move(sparse_maps));
 | 
					    sparse_views.emplace(image_id, std::move(sparse_maps));
 | 
				
			||||||
    ForEachGPUPage(image.gpu_addr, image.guest_size_bytes,
 | 
					    ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, image_id](u64 page) {
 | 
				
			||||||
                   [this, image_id](u64 page) { sparse_page_table[page].push_back(image_id); });
 | 
					        (*channel_state->sparse_page_table)[page].push_back(image_id);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <class P>
 | 
					template <class P>
 | 
				
			||||||
@ -2042,7 +2051,7 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) {
 | 
					    ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) {
 | 
				
			||||||
        clear_page_table(page, sparse_page_table);
 | 
					        clear_page_table(page, (*channel_state->sparse_page_table));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    auto it = sparse_views.find(image_id);
 | 
					    auto it = sparse_views.find(image_id);
 | 
				
			||||||
    ASSERT(it != sparse_views.end());
 | 
					    ASSERT(it != sparse_views.end());
 | 
				
			||||||
@ -2496,13 +2505,15 @@ void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel
 | 
				
			|||||||
    const auto it = channel_map.find(channel.bind_id);
 | 
					    const auto it = channel_map.find(channel.bind_id);
 | 
				
			||||||
    auto* this_state = &channel_storage[it->second];
 | 
					    auto* this_state = &channel_storage[it->second];
 | 
				
			||||||
    const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()];
 | 
					    const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()];
 | 
				
			||||||
    this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id];
 | 
					    this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id * 2];
 | 
				
			||||||
 | 
					    this_state->sparse_page_table = &gpu_page_table_storage[this_as_ref.storage_id * 2 + 1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Bind a channel for execution.
 | 
					/// Bind a channel for execution.
 | 
				
			||||||
template <class P>
 | 
					template <class P>
 | 
				
			||||||
void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) {
 | 
					void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) {
 | 
				
			||||||
    gpu_page_table_storage.emplace_back();
 | 
					    gpu_page_table_storage.emplace_back();
 | 
				
			||||||
 | 
					    gpu_page_table_storage.emplace_back();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace VideoCommon
 | 
					} // namespace VideoCommon
 | 
				
			||||||
 | 
				
			|||||||
@ -86,6 +86,7 @@ public:
 | 
				
			|||||||
    std::unordered_map<TSCEntry, SamplerId> samplers;
 | 
					    std::unordered_map<TSCEntry, SamplerId> samplers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TextureCacheGPUMap* gpu_page_table;
 | 
					    TextureCacheGPUMap* gpu_page_table;
 | 
				
			||||||
 | 
					    TextureCacheGPUMap* sparse_page_table;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <class P>
 | 
					template <class P>
 | 
				
			||||||
@ -357,7 +358,7 @@ private:
 | 
				
			|||||||
    void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
 | 
					    void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template <typename Func>
 | 
					    template <typename Func>
 | 
				
			||||||
    void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func);
 | 
					    void ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Iterates over all the images in a region calling func
 | 
					    /// Iterates over all the images in a region calling func
 | 
				
			||||||
    template <typename Func>
 | 
					    template <typename Func>
 | 
				
			||||||
@ -431,7 +432,6 @@ private:
 | 
				
			|||||||
    std::unordered_map<RenderTargets, FramebufferId> framebuffers;
 | 
					    std::unordered_map<RenderTargets, FramebufferId> framebuffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table;
 | 
					    std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table;
 | 
				
			||||||
    std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>> sparse_page_table;
 | 
					 | 
				
			||||||
    std::unordered_map<ImageId, boost::container::small_vector<ImageViewId, 16>> sparse_views;
 | 
					    std::unordered_map<ImageId, boost::container::small_vector<ImageViewId, 16>> sparse_views;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DAddr virtual_invalid_space{};
 | 
					    DAddr virtual_invalid_space{};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user