summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-04-21 18:31:30 +0200
committerbunnei <bunneidev@gmail.com>2018-04-24 23:49:19 +0200
commit239ac8abe228b9080741ba7d50d9e13cc4a1ceae (patch)
tree14b6df493ec5ff15faf2c7b71e45fe7d8ebb53df
parentmemory_manager: Use GPUVAdddr, not PAddr, for GPU addresses. (diff)
downloadyuzu-239ac8abe228b9080741ba7d50d9e13cc4a1ceae.tar
yuzu-239ac8abe228b9080741ba7d50d9e13cc4a1ceae.tar.gz
yuzu-239ac8abe228b9080741ba7d50d9e13cc4a1ceae.tar.bz2
yuzu-239ac8abe228b9080741ba7d50d9e13cc4a1ceae.tar.lz
yuzu-239ac8abe228b9080741ba7d50d9e13cc4a1ceae.tar.xz
yuzu-239ac8abe228b9080741ba7d50d9e13cc4a1ceae.tar.zst
yuzu-239ac8abe228b9080741ba7d50d9e13cc4a1ceae.zip
-rw-r--r--src/video_core/command_processor.cpp6
-rw-r--r--src/video_core/engines/maxwell_3d.cpp21
-rw-r--r--src/video_core/memory_manager.cpp7
-rw-r--r--src/video_core/memory_manager.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp14
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp4
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.cpp8
7 files changed, 37 insertions, 28 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 7850ae103..2c04daba3 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -90,9 +90,9 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params)
}
void GPU::ProcessCommandList(GPUVAddr address, u32 size) {
- const VAddr head_address = memory_manager->GpuToCpuAddress(address);
- VAddr current_addr = head_address;
- while (current_addr < head_address + size * sizeof(CommandHeader)) {
+ const boost::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address);
+ VAddr current_addr = *head_address;
+ while (current_addr < *head_address + size * sizeof(CommandHeader)) {
const CommandHeader header = {Memory::Read32(current_addr)};
current_addr += sizeof(u32);
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 8d7d627b8..4e9aed380 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -145,7 +145,7 @@ void Maxwell3D::ProcessQueryGet() {
GPUVAddr sequence_address = regs.query.QueryAddress();
// Since the sequence address is given as a GPU VAddr, we have to convert it to an application
// 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.
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,
"Writing the entire query result structure is unimplemented");
- u32 value = Memory::Read32(address);
+ u32 value = Memory::Read32(*address);
u32 result = 0;
// TODO(Subv): Support the other query variables
@@ -173,7 +173,7 @@ void Maxwell3D::ProcessQueryGet() {
case Regs::QueryMode::Write2: {
// Write the current query sequence to the sequence address.
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
// mode.
@@ -225,9 +225,10 @@ void Maxwell3D::ProcessCBData(u32 value) {
// Don't allow writing past the end of the buffer.
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.
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_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;
- 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 ||
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_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;
- Memory::ReadBlock(tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry));
+ Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry));
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)) {
Texture::TextureHandle tex_handle{
- Memory::Read32(memory_manager.GpuToCpuAddress(current_texture))};
+ Memory::Read32(*memory_manager.GpuToCpuAddress(current_texture))};
Texture::FullTextureInfo tex_info{};
// TODO(Subv): Use the shader to determine which textures are actually accessed.
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 3f21071c0..9bbbb7e65 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -73,9 +73,14 @@ boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
return {};
}
-VAddr MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) {
+boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) {
VAddr base_addr = PageSlot(gpu_addr);
ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped));
+
+ if (base_addr == static_cast<u64>(PageStatus::Allocated)) {
+ return {};
+ }
+
return base_addr + (gpu_addr & PAGE_MASK);
}
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index 4710cb21f..246c8fb7e 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -6,6 +6,9 @@
#include <array>
#include <memory>
+
+#include <boost/optional.hpp>
+
#include "common/common_types.h"
#include "core/memory.h"
@@ -22,7 +25,7 @@ public:
GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align);
GPUVAddr MapBufferEx(VAddr cpu_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_SIZE = 1 << PAGE_BITS;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 8568d6762..71612790b 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -150,7 +150,7 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
u64 size = end - start + 1;
// 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);
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
GLShader::ProgramCode program_code;
const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset};
- const VAddr cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)};
- Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64));
+ const boost::optional<VAddr> cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)};
+ Memory::ReadBlock(*cpu_address, program_code.data(), program_code.size() * sizeof(u64));
GLShader::ShaderSetup setup{std::move(program_code)};
GLShader::ShaderEntries shader_resources;
@@ -394,9 +394,9 @@ void RasterizerOpenGL::DrawArrays() {
GLintptr index_buffer_offset = 0;
if (is_indexed) {
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::ReadBlock(index_data_addr, offseted_buffer, index_buffer_size);
+ Memory::ReadBlock(*index_data_addr, offseted_buffer, index_buffer_size);
index_buffer_offset = buffer_offset;
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.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));
- Memory::ReadBlock(addr, data.data(), data.size());
+ Memory::ReadBlock(*addr, data.data(), data.size());
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 46f0f25aa..ced648c12 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -1028,7 +1028,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
auto& gpu = Core::System::GetInstance().GPU();
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.height = config.tic.Height();
params.is_tiled = config.tic.IsTiled();
@@ -1106,7 +1106,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
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.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format);
color_params.UpdateParams();
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp
index 5cadb807e..1fbca8ad0 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.cpp
+++ b/src/yuzu/debugger/graphics/graphics_surface.cpp
@@ -378,10 +378,10 @@ void GraphicsSurfaceWidget::OnUpdate() {
// TODO: Implement a good way to visualize alpha components!
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 =
- 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,
surface_width, surface_height);
@@ -437,9 +437,9 @@ void GraphicsSurfaceWidget::SaveSurface() {
pixmap->save(&file, "PNG");
} else if (selectedFilter == bin_filter) {
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");
QFile file(filename);