mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	memory_manager: Make GpuToCpuAddress return an optional.
This commit is contained in:
		
							parent
							
								
									9e11a76e92
								
							
						
					
					
						commit
						239ac8abe2
					
				@ -90,9 +90,9 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GPU::ProcessCommandList(GPUVAddr address, u32 size) {
 | 
					void GPU::ProcessCommandList(GPUVAddr address, u32 size) {
 | 
				
			||||||
    const VAddr head_address = memory_manager->GpuToCpuAddress(address);
 | 
					    const boost::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address);
 | 
				
			||||||
    VAddr current_addr = head_address;
 | 
					    VAddr current_addr = *head_address;
 | 
				
			||||||
    while (current_addr < head_address + size * sizeof(CommandHeader)) {
 | 
					    while (current_addr < *head_address + size * sizeof(CommandHeader)) {
 | 
				
			||||||
        const CommandHeader header = {Memory::Read32(current_addr)};
 | 
					        const CommandHeader header = {Memory::Read32(current_addr)};
 | 
				
			||||||
        current_addr += sizeof(u32);
 | 
					        current_addr += sizeof(u32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -145,7 +145,7 @@ void Maxwell3D::ProcessQueryGet() {
 | 
				
			|||||||
    GPUVAddr sequence_address = regs.query.QueryAddress();
 | 
					    GPUVAddr sequence_address = regs.query.QueryAddress();
 | 
				
			||||||
    // Since the sequence address is given as a GPU VAddr, we have to convert it to an application
 | 
					    // Since the sequence address is given as a GPU VAddr, we have to convert it to an application
 | 
				
			||||||
    // VAddr before writing.
 | 
					    // VAddr before writing.
 | 
				
			||||||
    VAddr address = memory_manager.GpuToCpuAddress(sequence_address);
 | 
					    boost::optional<VAddr> address = memory_manager.GpuToCpuAddress(sequence_address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO(Subv): Support the other query units.
 | 
					    // TODO(Subv): Support the other query units.
 | 
				
			||||||
    ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop,
 | 
					    ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop,
 | 
				
			||||||
@ -153,7 +153,7 @@ void Maxwell3D::ProcessQueryGet() {
 | 
				
			|||||||
    ASSERT_MSG(regs.query.query_get.short_query,
 | 
					    ASSERT_MSG(regs.query.query_get.short_query,
 | 
				
			||||||
               "Writing the entire query result structure is unimplemented");
 | 
					               "Writing the entire query result structure is unimplemented");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u32 value = Memory::Read32(address);
 | 
					    u32 value = Memory::Read32(*address);
 | 
				
			||||||
    u32 result = 0;
 | 
					    u32 result = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO(Subv): Support the other query variables
 | 
					    // TODO(Subv): Support the other query variables
 | 
				
			||||||
@ -173,7 +173,7 @@ void Maxwell3D::ProcessQueryGet() {
 | 
				
			|||||||
    case Regs::QueryMode::Write2: {
 | 
					    case Regs::QueryMode::Write2: {
 | 
				
			||||||
        // Write the current query sequence to the sequence address.
 | 
					        // Write the current query sequence to the sequence address.
 | 
				
			||||||
        u32 sequence = regs.query.query_sequence;
 | 
					        u32 sequence = regs.query.query_sequence;
 | 
				
			||||||
        Memory::Write32(address, sequence);
 | 
					        Memory::Write32(*address, sequence);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO(Subv): Write the proper query response structure to the address when not using short
 | 
					        // TODO(Subv): Write the proper query response structure to the address when not using short
 | 
				
			||||||
        // mode.
 | 
					        // mode.
 | 
				
			||||||
@ -225,9 +225,10 @@ void Maxwell3D::ProcessCBData(u32 value) {
 | 
				
			|||||||
    // Don't allow writing past the end of the buffer.
 | 
					    // Don't allow writing past the end of the buffer.
 | 
				
			||||||
    ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size);
 | 
					    ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    VAddr address = memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos);
 | 
					    boost::optional<VAddr> address =
 | 
				
			||||||
 | 
					        memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Memory::Write32(address, value);
 | 
					    Memory::Write32(*address, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Increment the current buffer position.
 | 
					    // Increment the current buffer position.
 | 
				
			||||||
    regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;
 | 
					    regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;
 | 
				
			||||||
@ -237,10 +238,10 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
 | 
				
			|||||||
    GPUVAddr tic_base_address = regs.tic.TICAddress();
 | 
					    GPUVAddr tic_base_address = regs.tic.TICAddress();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry);
 | 
					    GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry);
 | 
				
			||||||
    VAddr tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu);
 | 
					    boost::optional<VAddr> tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Texture::TICEntry tic_entry;
 | 
					    Texture::TICEntry tic_entry;
 | 
				
			||||||
    Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry));
 | 
					    Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASSERT_MSG(tic_entry.header_version == Texture::TICHeaderVersion::BlockLinear ||
 | 
					    ASSERT_MSG(tic_entry.header_version == Texture::TICHeaderVersion::BlockLinear ||
 | 
				
			||||||
                   tic_entry.header_version == Texture::TICHeaderVersion::Pitch,
 | 
					                   tic_entry.header_version == Texture::TICHeaderVersion::Pitch,
 | 
				
			||||||
@ -267,10 +268,10 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
 | 
				
			|||||||
    GPUVAddr tsc_base_address = regs.tsc.TSCAddress();
 | 
					    GPUVAddr tsc_base_address = regs.tsc.TSCAddress();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry);
 | 
					    GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry);
 | 
				
			||||||
    VAddr tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu);
 | 
					    boost::optional<VAddr> tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Texture::TSCEntry tsc_entry;
 | 
					    Texture::TSCEntry tsc_entry;
 | 
				
			||||||
    Memory::ReadBlock(tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry));
 | 
					    Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry));
 | 
				
			||||||
    return tsc_entry;
 | 
					    return tsc_entry;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -292,7 +293,7 @@ std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderSt
 | 
				
			|||||||
         current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) {
 | 
					         current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Texture::TextureHandle tex_handle{
 | 
					        Texture::TextureHandle tex_handle{
 | 
				
			||||||
            Memory::Read32(memory_manager.GpuToCpuAddress(current_texture))};
 | 
					            Memory::Read32(*memory_manager.GpuToCpuAddress(current_texture))};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Texture::FullTextureInfo tex_info{};
 | 
					        Texture::FullTextureInfo tex_info{};
 | 
				
			||||||
        // TODO(Subv): Use the shader to determine which textures are actually accessed.
 | 
					        // TODO(Subv): Use the shader to determine which textures are actually accessed.
 | 
				
			||||||
 | 
				
			|||||||
@ -73,9 +73,14 @@ boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
 | 
				
			|||||||
    return {};
 | 
					    return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VAddr MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) {
 | 
					boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) {
 | 
				
			||||||
    VAddr base_addr = PageSlot(gpu_addr);
 | 
					    VAddr base_addr = PageSlot(gpu_addr);
 | 
				
			||||||
    ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped));
 | 
					    ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (base_addr == static_cast<u64>(PageStatus::Allocated)) {
 | 
				
			||||||
 | 
					        return {};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return base_addr + (gpu_addr & PAGE_MASK);
 | 
					    return base_addr + (gpu_addr & PAGE_MASK);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <array>
 | 
					#include <array>
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <boost/optional.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "common/common_types.h"
 | 
					#include "common/common_types.h"
 | 
				
			||||||
#include "core/memory.h"
 | 
					#include "core/memory.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,7 +25,7 @@ public:
 | 
				
			|||||||
    GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align);
 | 
					    GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align);
 | 
				
			||||||
    GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size);
 | 
					    GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size);
 | 
				
			||||||
    GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size);
 | 
					    GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size);
 | 
				
			||||||
    VAddr GpuToCpuAddress(GPUVAddr gpu_addr);
 | 
					    boost::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static constexpr u64 PAGE_BITS = 16;
 | 
					    static constexpr u64 PAGE_BITS = 16;
 | 
				
			||||||
    static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS;
 | 
					    static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS;
 | 
				
			||||||
 | 
				
			|||||||
@ -150,7 +150,7 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
 | 
				
			|||||||
        u64 size = end - start + 1;
 | 
					        u64 size = end - start + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Copy vertex array data
 | 
					        // Copy vertex array data
 | 
				
			||||||
        const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(start)};
 | 
					        const VAddr data_addr{*memory_manager->GpuToCpuAddress(start)};
 | 
				
			||||||
        res_cache.FlushRegion(data_addr, size, nullptr);
 | 
					        res_cache.FlushRegion(data_addr, size, nullptr);
 | 
				
			||||||
        Memory::ReadBlock(data_addr, array_ptr, size);
 | 
					        Memory::ReadBlock(data_addr, array_ptr, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -233,8 +233,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) {
 | 
				
			|||||||
        // Fetch program code from memory
 | 
					        // Fetch program code from memory
 | 
				
			||||||
        GLShader::ProgramCode program_code;
 | 
					        GLShader::ProgramCode program_code;
 | 
				
			||||||
        const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset};
 | 
					        const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset};
 | 
				
			||||||
        const VAddr cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)};
 | 
					        const boost::optional<VAddr> cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)};
 | 
				
			||||||
        Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64));
 | 
					        Memory::ReadBlock(*cpu_address, program_code.data(), program_code.size() * sizeof(u64));
 | 
				
			||||||
        GLShader::ShaderSetup setup{std::move(program_code)};
 | 
					        GLShader::ShaderSetup setup{std::move(program_code)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        GLShader::ShaderEntries shader_resources;
 | 
					        GLShader::ShaderEntries shader_resources;
 | 
				
			||||||
@ -394,9 +394,9 @@ void RasterizerOpenGL::DrawArrays() {
 | 
				
			|||||||
    GLintptr index_buffer_offset = 0;
 | 
					    GLintptr index_buffer_offset = 0;
 | 
				
			||||||
    if (is_indexed) {
 | 
					    if (is_indexed) {
 | 
				
			||||||
        const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager;
 | 
					        const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager;
 | 
				
			||||||
        const VAddr index_data_addr{
 | 
					        const boost::optional<VAddr> index_data_addr{
 | 
				
			||||||
            memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())};
 | 
					            memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())};
 | 
				
			||||||
        Memory::ReadBlock(index_data_addr, offseted_buffer, index_buffer_size);
 | 
					        Memory::ReadBlock(*index_data_addr, offseted_buffer, index_buffer_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        index_buffer_offset = buffer_offset;
 | 
					        index_buffer_offset = buffer_offset;
 | 
				
			||||||
        offseted_buffer += index_buffer_size;
 | 
					        offseted_buffer += index_buffer_size;
 | 
				
			||||||
@ -659,9 +659,9 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr
 | 
				
			|||||||
        buffer_draw_state.enabled = true;
 | 
					        buffer_draw_state.enabled = true;
 | 
				
			||||||
        buffer_draw_state.bindpoint = current_bindpoint + bindpoint;
 | 
					        buffer_draw_state.bindpoint = current_bindpoint + bindpoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        VAddr addr = gpu.memory_manager->GpuToCpuAddress(buffer.address);
 | 
					        boost::optional<VAddr> addr = gpu.memory_manager->GpuToCpuAddress(buffer.address);
 | 
				
			||||||
        std::vector<u8> data(used_buffer.GetSize() * sizeof(float));
 | 
					        std::vector<u8> data(used_buffer.GetSize() * sizeof(float));
 | 
				
			||||||
        Memory::ReadBlock(addr, data.data(), data.size());
 | 
					        Memory::ReadBlock(*addr, data.data(), data.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo);
 | 
					        glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo);
 | 
				
			||||||
        glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW);
 | 
					        glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW);
 | 
				
			||||||
 | 
				
			|||||||
@ -1028,7 +1028,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
 | 
				
			|||||||
    auto& gpu = Core::System::GetInstance().GPU();
 | 
					    auto& gpu = Core::System::GetInstance().GPU();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SurfaceParams params;
 | 
					    SurfaceParams params;
 | 
				
			||||||
    params.addr = gpu.memory_manager->GpuToCpuAddress(config.tic.Address());
 | 
					    params.addr = *gpu.memory_manager->GpuToCpuAddress(config.tic.Address());
 | 
				
			||||||
    params.width = config.tic.Width();
 | 
					    params.width = config.tic.Width();
 | 
				
			||||||
    params.height = config.tic.Height();
 | 
					    params.height = config.tic.Height();
 | 
				
			||||||
    params.is_tiled = config.tic.IsTiled();
 | 
					    params.is_tiled = config.tic.IsTiled();
 | 
				
			||||||
@ -1106,7 +1106,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
 | 
				
			|||||||
    color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
 | 
					    color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
 | 
				
			||||||
    SurfaceParams depth_params = color_params;
 | 
					    SurfaceParams depth_params = color_params;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    color_params.addr = memory_manager->GpuToCpuAddress(config.Address());
 | 
					    color_params.addr = *memory_manager->GpuToCpuAddress(config.Address());
 | 
				
			||||||
    color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format);
 | 
					    color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format);
 | 
				
			||||||
    color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format);
 | 
					    color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format);
 | 
				
			||||||
    color_params.UpdateParams();
 | 
					    color_params.UpdateParams();
 | 
				
			||||||
 | 
				
			|||||||
@ -378,10 +378,10 @@ void GraphicsSurfaceWidget::OnUpdate() {
 | 
				
			|||||||
    // TODO: Implement a good way to visualize alpha components!
 | 
					    // TODO: Implement a good way to visualize alpha components!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
 | 
					    QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
 | 
				
			||||||
    VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address);
 | 
					    boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto unswizzled_data =
 | 
					    auto unswizzled_data =
 | 
				
			||||||
        Tegra::Texture::UnswizzleTexture(address, surface_format, surface_width, surface_height);
 | 
					        Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format,
 | 
					    auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format,
 | 
				
			||||||
                                                      surface_width, surface_height);
 | 
					                                                      surface_width, surface_height);
 | 
				
			||||||
@ -437,9 +437,9 @@ void GraphicsSurfaceWidget::SaveSurface() {
 | 
				
			|||||||
            pixmap->save(&file, "PNG");
 | 
					            pixmap->save(&file, "PNG");
 | 
				
			||||||
    } else if (selectedFilter == bin_filter) {
 | 
					    } else if (selectedFilter == bin_filter) {
 | 
				
			||||||
        auto& gpu = Core::System::GetInstance().GPU();
 | 
					        auto& gpu = Core::System::GetInstance().GPU();
 | 
				
			||||||
        VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address);
 | 
					        boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const u8* buffer = Memory::GetPointer(address);
 | 
					        const u8* buffer = Memory::GetPointer(*address);
 | 
				
			||||||
        ASSERT_MSG(buffer != nullptr, "Memory not accessible");
 | 
					        ASSERT_MSG(buffer != nullptr, "Memory not accessible");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QFile file(filename);
 | 
					        QFile file(filename);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user