summaryrefslogtreecommitdiffstats
path: root/src/video_core/engines
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-01-22 07:47:56 +0100
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-02-03 08:58:40 +0100
commit2bdbb90af74683bd8bb7e25d5353c39fb8037f8c (patch)
tree443865c07c307ddc4ac41e82387395bde95641e6 /src/video_core/engines
parentmaxwell_3d: Allow sampler handles with TSC id zero (diff)
downloadyuzu-2bdbb90af74683bd8bb7e25d5353c39fb8037f8c.tar
yuzu-2bdbb90af74683bd8bb7e25d5353c39fb8037f8c.tar.gz
yuzu-2bdbb90af74683bd8bb7e25d5353c39fb8037f8c.tar.bz2
yuzu-2bdbb90af74683bd8bb7e25d5353c39fb8037f8c.tar.lz
yuzu-2bdbb90af74683bd8bb7e25d5353c39fb8037f8c.tar.xz
yuzu-2bdbb90af74683bd8bb7e25d5353c39fb8037f8c.tar.zst
yuzu-2bdbb90af74683bd8bb7e25d5353c39fb8037f8c.zip
Diffstat (limited to 'src/video_core/engines')
-rw-r--r--src/video_core/engines/fermi_2d.cpp16
-rw-r--r--src/video_core/engines/kepler_memory.cpp11
-rw-r--r--src/video_core/engines/maxwell_3d.cpp46
-rw-r--r--src/video_core/engines/maxwell_dma.cpp22
4 files changed, 54 insertions, 41 deletions
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp
index 80f70e332..9f1533263 100644
--- a/src/video_core/engines/fermi_2d.cpp
+++ b/src/video_core/engines/fermi_2d.cpp
@@ -42,8 +42,10 @@ void Fermi2D::HandleSurfaceCopy() {
// TODO(Subv): Only raw copies are implemented.
ASSERT(regs.operation == Regs::Operation::SrcCopy);
- const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source);
- const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest);
+ const auto source_cpu = memory_manager.GpuToCpuAddress(source);
+ const auto dest_cpu = memory_manager.GpuToCpuAddress(dest);
+ ASSERT_MSG(source_cpu, "Invalid source GPU address");
+ ASSERT_MSG(dest_cpu, "Invalid destination GPU address");
u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format);
u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format);
@@ -52,22 +54,22 @@ void Fermi2D::HandleSurfaceCopy() {
// All copies here update the main memory, so mark all rasterizer states as invalid.
Core::System::GetInstance().GPU().Maxwell3D().dirty_flags.OnMemoryWrite();
- rasterizer.FlushRegion(source_cpu, src_bytes_per_pixel * regs.src.width * regs.src.height);
+ rasterizer.FlushRegion(*source_cpu, src_bytes_per_pixel * regs.src.width * regs.src.height);
// We have to invalidate the destination region to evict any outdated surfaces from the
// cache. We do this before actually writing the new data because the destination address
// might contain a dirty surface that will have to be written back to memory.
- rasterizer.InvalidateRegion(dest_cpu,
+ rasterizer.InvalidateRegion(*dest_cpu,
dst_bytes_per_pixel * regs.dst.width * regs.dst.height);
if (regs.src.linear == regs.dst.linear) {
// If the input layout and the output layout are the same, just perform a raw copy.
ASSERT(regs.src.BlockHeight() == regs.dst.BlockHeight());
- Memory::CopyBlock(dest_cpu, source_cpu,
+ Memory::CopyBlock(*dest_cpu, *source_cpu,
src_bytes_per_pixel * regs.dst.width * regs.dst.height);
return;
}
- u8* src_buffer = Memory::GetPointer(source_cpu);
- u8* dst_buffer = Memory::GetPointer(dest_cpu);
+ u8* src_buffer = Memory::GetPointer(*source_cpu);
+ u8* dst_buffer = Memory::GetPointer(*dest_cpu);
if (!regs.src.linear && regs.dst.linear) {
// If the input is tiled and the output is linear, deswizzle the input and copy it over.
Texture::CopySwizzledData(regs.src.width, regs.src.height, regs.src.depth,
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp
index 4880191fc..5c1029ddf 100644
--- a/src/video_core/engines/kepler_memory.cpp
+++ b/src/video_core/engines/kepler_memory.cpp
@@ -39,16 +39,17 @@ void KeplerMemory::ProcessData(u32 data) {
ASSERT_MSG(regs.exec.linear, "Non-linear uploads are not supported");
ASSERT(regs.dest.x == 0 && regs.dest.y == 0 && regs.dest.z == 0);
- GPUVAddr address = regs.dest.Address();
- VAddr dest_address =
- *memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32));
+ const GPUVAddr address = regs.dest.Address();
+ const auto dest_address =
+ memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32));
+ ASSERT_MSG(dest_address, "Invalid GPU address");
// We have to invalidate the destination region to evict any outdated surfaces from the cache.
// We do this before actually writing the new data because the destination address might contain
// a dirty surface that will have to be written back to memory.
- rasterizer.InvalidateRegion(dest_address, sizeof(u32));
+ rasterizer.InvalidateRegion(*dest_address, sizeof(u32));
- Memory::Write32(dest_address, data);
+ Memory::Write32(*dest_address, data);
Core::System::GetInstance().GPU().Maxwell3D().dirty_flags.OnMemoryWrite();
state.write_offset++;
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 2cd6d6094..10eae6a65 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -273,7 +273,8 @@ 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.
- std::optional<VAddr> address = memory_manager.GpuToCpuAddress(sequence_address);
+ const auto address = memory_manager.GpuToCpuAddress(sequence_address);
+ ASSERT_MSG(address, "Invalid GPU address");
// TODO(Subv): Support the other query units.
ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop,
@@ -386,14 +387,14 @@ void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) {
void Maxwell3D::ProcessCBData(u32 value) {
// Write the input value to the current const buffer at the current position.
- GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
+ const GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
ASSERT(buffer_address != 0);
// Don't allow writing past the end of the buffer.
ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size);
- std::optional<VAddr> address =
- memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos);
+ const auto address = memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos);
+ ASSERT_MSG(address, "Invalid GPU address");
Memory::Write32(*address, value);
dirty_flags.OnMemoryWrite();
@@ -403,10 +404,11 @@ void Maxwell3D::ProcessCBData(u32 value) {
}
Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
- GPUVAddr tic_base_address = regs.tic.TICAddress();
+ const GPUVAddr tic_base_address = regs.tic.TICAddress();
- GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry);
- std::optional<VAddr> tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu);
+ const GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry);
+ const auto tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu);
+ ASSERT_MSG(tic_address_cpu, "Invalid GPU address");
Texture::TICEntry tic_entry;
Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry));
@@ -415,10 +417,10 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
tic_entry.header_version == Texture::TICHeaderVersion::Pitch,
"TIC versions other than BlockLinear or Pitch are unimplemented");
- auto r_type = tic_entry.r_type.Value();
- auto g_type = tic_entry.g_type.Value();
- auto b_type = tic_entry.b_type.Value();
- auto a_type = tic_entry.a_type.Value();
+ const auto r_type = tic_entry.r_type.Value();
+ const auto g_type = tic_entry.g_type.Value();
+ const auto b_type = tic_entry.b_type.Value();
+ const auto a_type = tic_entry.a_type.Value();
// TODO(Subv): Different data types for separate components are not supported
ASSERT(r_type == g_type && r_type == b_type && r_type == a_type);
@@ -427,10 +429,11 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
}
Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
- GPUVAddr tsc_base_address = regs.tsc.TSCAddress();
+ const GPUVAddr tsc_base_address = regs.tsc.TSCAddress();
- GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry);
- std::optional<VAddr> tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu);
+ const GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry);
+ const auto tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu);
+ ASSERT_MSG(tsc_address_cpu, "Invalid GPU address");
Texture::TSCEntry tsc_entry;
Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry));
@@ -452,8 +455,10 @@ std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderSt
for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset;
current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) {
- Texture::TextureHandle tex_handle{
- Memory::Read32(*memory_manager.GpuToCpuAddress(current_texture))};
+ const auto address = memory_manager.GpuToCpuAddress(current_texture);
+ ASSERT_MSG(address, "Invalid GPU address");
+
+ const Texture::TextureHandle tex_handle{Memory::Read32(*address)};
Texture::FullTextureInfo tex_info{};
// TODO(Subv): Use the shader to determine which textures are actually accessed.
@@ -483,12 +488,15 @@ Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage,
auto& tex_info_buffer = shader.const_buffers[regs.tex_cb_index];
ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0);
- GPUVAddr tex_info_address = tex_info_buffer.address + offset * sizeof(Texture::TextureHandle);
+ const GPUVAddr tex_info_address =
+ tex_info_buffer.address + offset * sizeof(Texture::TextureHandle);
ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size);
- std::optional<VAddr> tex_address_cpu = memory_manager.GpuToCpuAddress(tex_info_address);
- Texture::TextureHandle tex_handle{Memory::Read32(*tex_address_cpu)};
+ const auto tex_address_cpu = memory_manager.GpuToCpuAddress(tex_info_address);
+ ASSERT_MSG(tex_address_cpu, "Invalid GPU address");
+
+ const Texture::TextureHandle tex_handle{Memory::Read32(*tex_address_cpu)};
Texture::FullTextureInfo tex_info{};
tex_info.index = static_cast<u32>(offset);
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 06462f570..d6c41a5ae 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -39,8 +39,10 @@ void MaxwellDMA::HandleCopy() {
const GPUVAddr source = regs.src_address.Address();
const GPUVAddr dest = regs.dst_address.Address();
- const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source);
- const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest);
+ const auto source_cpu = memory_manager.GpuToCpuAddress(source);
+ const auto dest_cpu = memory_manager.GpuToCpuAddress(dest);
+ ASSERT_MSG(source_cpu, "Invalid source GPU address");
+ ASSERT_MSG(dest_cpu, "Invalid destination GPU address");
// TODO(Subv): Perform more research and implement all features of this engine.
ASSERT(regs.exec.enable_swizzle == 0);
@@ -64,7 +66,7 @@ void MaxwellDMA::HandleCopy() {
// buffer of length `x_count`, otherwise we copy a 2D image of dimensions (x_count,
// y_count).
if (!regs.exec.enable_2d) {
- Memory::CopyBlock(dest_cpu, source_cpu, regs.x_count);
+ Memory::CopyBlock(*dest_cpu, *source_cpu, regs.x_count);
return;
}
@@ -73,8 +75,8 @@ void MaxwellDMA::HandleCopy() {
// rectangle. There is no need to manually flush/invalidate the regions because
// CopyBlock does that for us.
for (u32 line = 0; line < regs.y_count; ++line) {
- const VAddr source_line = source_cpu + line * regs.src_pitch;
- const VAddr dest_line = dest_cpu + line * regs.dst_pitch;
+ const VAddr source_line = *source_cpu + line * regs.src_pitch;
+ const VAddr dest_line = *dest_cpu + line * regs.dst_pitch;
Memory::CopyBlock(dest_line, source_line, regs.x_count);
}
return;
@@ -87,12 +89,12 @@ void MaxwellDMA::HandleCopy() {
const auto FlushAndInvalidate = [&](u32 src_size, u64 dst_size) {
// TODO(Subv): For now, manually flush the regions until we implement GPU-accelerated
// copying.
- rasterizer.FlushRegion(source_cpu, src_size);
+ rasterizer.FlushRegion(*source_cpu, src_size);
// We have to invalidate the destination region to evict any outdated surfaces from the
// cache. We do this before actually writing the new data because the destination address
// might contain a dirty surface that will have to be written back to memory.
- rasterizer.InvalidateRegion(dest_cpu, dst_size);
+ rasterizer.InvalidateRegion(*dest_cpu, dst_size);
};
if (regs.exec.is_dst_linear && !regs.exec.is_src_linear) {
@@ -105,8 +107,8 @@ void MaxwellDMA::HandleCopy() {
copy_size * src_bytes_per_pixel);
Texture::UnswizzleSubrect(regs.x_count, regs.y_count, regs.dst_pitch,
- regs.src_params.size_x, src_bytes_per_pixel, source_cpu, dest_cpu,
- regs.src_params.BlockHeight(), regs.src_params.pos_x,
+ regs.src_params.size_x, src_bytes_per_pixel, *source_cpu,
+ *dest_cpu, regs.src_params.BlockHeight(), regs.src_params.pos_x,
regs.src_params.pos_y);
} else {
ASSERT(regs.dst_params.size_z == 1);
@@ -119,7 +121,7 @@ void MaxwellDMA::HandleCopy() {
// If the input is linear and the output is tiled, swizzle the input and copy it over.
Texture::SwizzleSubrect(regs.x_count, regs.y_count, regs.src_pitch, regs.dst_params.size_x,
- src_bpp, dest_cpu, source_cpu, regs.dst_params.BlockHeight());
+ src_bpp, *dest_cpu, *source_cpu, regs.dst_params.BlockHeight());
}
}