summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-07-24 19:18:17 -0400
committerGravatar FernandoS272019-07-25 20:41:42 -0400
commita452ff983dc736e16b0f1c0b01d162bfb6655c79 (patch)
treee2b6662a5f3dd884f4354bbabec82af33ad2cd77 /src
parentMerge pull request #2704 from FernandoS27/conditional (diff)
downloadyuzu-a452ff983dc736e16b0f1c0b01d162bfb6655c79.tar.gz
yuzu-a452ff983dc736e16b0f1c0b01d162bfb6655c79.tar.xz
yuzu-a452ff983dc736e16b0f1c0b01d162bfb6655c79.zip
MaxwellDMA: Fixes, corrections and relaxations.
This commit fixes offsets on Linear -> Tiled copies, corrects z pos fortiled->linear copies, corrects bytes_per_pixel calculation in tiled -> linear copies and relaxes some limitations set by latest dma fixes refactors.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_dma.cpp42
-rw-r--r--src/video_core/textures/decoders.cpp14
-rw-r--r--src/video_core/textures/decoders.h3
3 files changed, 36 insertions, 23 deletions
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index b5f57e534..a71d98e36 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -5,6 +5,7 @@
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/settings.h"
8#include "video_core/engines/maxwell_3d.h" 9#include "video_core/engines/maxwell_3d.h"
9#include "video_core/engines/maxwell_dma.h" 10#include "video_core/engines/maxwell_dma.h"
10#include "video_core/memory_manager.h" 11#include "video_core/memory_manager.h"
@@ -84,13 +85,17 @@ void MaxwellDMA::HandleCopy() {
84 ASSERT(regs.exec.enable_2d == 1); 85 ASSERT(regs.exec.enable_2d == 1);
85 86
86 if (regs.exec.is_dst_linear && !regs.exec.is_src_linear) { 87 if (regs.exec.is_dst_linear && !regs.exec.is_src_linear) {
87 ASSERT(regs.src_params.size_z == 1); 88 ASSERT(regs.src_params.BlockDepth() == 0);
88 // If the input is tiled and the output is linear, deswizzle the input and copy it over. 89 // If the input is tiled and the output is linear, deswizzle the input and copy it over.
89 const u32 src_bytes_per_pixel = regs.src_pitch / regs.src_params.size_x; 90 const u32 bytes_per_pixel = regs.dst_pitch / regs.x_count;
90 const std::size_t src_size = Texture::CalculateSize( 91 const std::size_t src_size = Texture::CalculateSize(
91 true, src_bytes_per_pixel, regs.src_params.size_x, regs.src_params.size_y, 92 true, bytes_per_pixel, regs.src_params.size_x, regs.src_params.size_y,
92 regs.src_params.size_z, regs.src_params.BlockHeight(), regs.src_params.BlockDepth()); 93 regs.src_params.size_z, regs.src_params.BlockHeight(), regs.src_params.BlockDepth());
93 94
95 const std::size_t src_layer_size = Texture::CalculateSize(
96 true, bytes_per_pixel, regs.src_params.size_x, regs.src_params.size_y, 1,
97 regs.src_params.BlockHeight(), regs.src_params.BlockDepth());
98
94 const std::size_t dst_size = regs.dst_pitch * regs.y_count; 99 const std::size_t dst_size = regs.dst_pitch * regs.y_count;
95 100
96 if (read_buffer.size() < src_size) { 101 if (read_buffer.size() < src_size) {
@@ -104,23 +109,23 @@ void MaxwellDMA::HandleCopy() {
104 memory_manager.ReadBlock(source, read_buffer.data(), src_size); 109 memory_manager.ReadBlock(source, read_buffer.data(), src_size);
105 memory_manager.ReadBlock(dest, write_buffer.data(), dst_size); 110 memory_manager.ReadBlock(dest, write_buffer.data(), dst_size);
106 111
107 Texture::UnswizzleSubrect(regs.x_count, regs.y_count, regs.dst_pitch, 112 Texture::UnswizzleSubrect(
108 regs.src_params.size_x, src_bytes_per_pixel, read_buffer.data(), 113 regs.x_count, regs.y_count, regs.dst_pitch, regs.src_params.size_x, bytes_per_pixel,
109 write_buffer.data(), regs.src_params.BlockHeight(), 114 read_buffer.data() + src_layer_size * regs.src_params.pos_z, write_buffer.data(),
110 regs.src_params.pos_x, regs.src_params.pos_y); 115 regs.src_params.BlockHeight(), regs.src_params.pos_x, regs.src_params.pos_y);
111 116
112 memory_manager.WriteBlock(dest, write_buffer.data(), dst_size); 117 memory_manager.WriteBlock(dest, write_buffer.data(), dst_size);
113 } else { 118 } else {
114 ASSERT(regs.dst_params.BlockDepth() == 0); 119 ASSERT(regs.dst_params.BlockDepth() == 0);
115 120
116 const u32 src_bytes_per_pixel = regs.src_pitch / regs.x_count; 121 const u32 bytes_per_pixel = regs.src_pitch / regs.x_count;
117 122
118 const std::size_t dst_size = Texture::CalculateSize( 123 const std::size_t dst_size = Texture::CalculateSize(
119 true, src_bytes_per_pixel, regs.dst_params.size_x, regs.dst_params.size_y, 124 true, bytes_per_pixel, regs.dst_params.size_x, regs.dst_params.size_y,
120 regs.dst_params.size_z, regs.dst_params.BlockHeight(), regs.dst_params.BlockDepth()); 125 regs.dst_params.size_z, regs.dst_params.BlockHeight(), regs.dst_params.BlockDepth());
121 126
122 const std::size_t dst_layer_size = Texture::CalculateSize( 127 const std::size_t dst_layer_size = Texture::CalculateSize(
123 true, src_bytes_per_pixel, regs.dst_params.size_x, regs.dst_params.size_y, 1, 128 true, bytes_per_pixel, regs.dst_params.size_x, regs.dst_params.size_y, 1,
124 regs.dst_params.BlockHeight(), regs.dst_params.BlockDepth()); 129 regs.dst_params.BlockHeight(), regs.dst_params.BlockDepth());
125 130
126 const std::size_t src_size = regs.src_pitch * regs.y_count; 131 const std::size_t src_size = regs.src_pitch * regs.y_count;
@@ -133,14 +138,19 @@ void MaxwellDMA::HandleCopy() {
133 write_buffer.resize(dst_size); 138 write_buffer.resize(dst_size);
134 } 139 }
135 140
136 memory_manager.ReadBlock(source, read_buffer.data(), src_size); 141 if (Settings::values.use_accurate_gpu_emulation) {
137 memory_manager.ReadBlock(dest, write_buffer.data(), dst_size); 142 memory_manager.ReadBlock(source, read_buffer.data(), src_size);
143 memory_manager.ReadBlock(dest, write_buffer.data(), dst_size);
144 } else {
145 memory_manager.ReadBlockUnsafe(source, read_buffer.data(), src_size);
146 memory_manager.ReadBlockUnsafe(dest, write_buffer.data(), dst_size);
147 }
138 148
139 // If the input is linear and the output is tiled, swizzle the input and copy it over. 149 // If the input is linear and the output is tiled, swizzle the input and copy it over.
140 Texture::SwizzleSubrect(regs.x_count, regs.y_count, regs.src_pitch, regs.dst_params.size_x, 150 Texture::SwizzleSubrect(
141 src_bytes_per_pixel, 151 regs.x_count, regs.y_count, regs.src_pitch, regs.dst_params.size_x, bytes_per_pixel,
142 write_buffer.data() + dst_layer_size * regs.dst_params.pos_z, 152 write_buffer.data() + dst_layer_size * regs.dst_params.pos_z, read_buffer.data(),
143 read_buffer.data(), regs.dst_params.BlockHeight()); 153 regs.dst_params.BlockHeight(), regs.dst_params.pos_x, regs.dst_params.pos_y);
144 154
145 memory_manager.WriteBlock(dest, write_buffer.data(), dst_size); 155 memory_manager.WriteBlock(dest, write_buffer.data(), dst_size);
146 } 156 }
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 7e8295944..7df5f1452 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -257,19 +257,21 @@ std::vector<u8> UnswizzleTexture(u8* address, u32 tile_size_x, u32 tile_size_y,
257 257
258void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, 258void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width,
259 u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, 259 u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data,
260 u32 block_height_bit) { 260 u32 block_height_bit, u32 offset_x, u32 offset_y) {
261 const u32 block_height = 1U << block_height_bit; 261 const u32 block_height = 1U << block_height_bit;
262 const u32 image_width_in_gobs{(swizzled_width * bytes_per_pixel + (gob_size_x - 1)) / 262 const u32 image_width_in_gobs{(swizzled_width * bytes_per_pixel + (gob_size_x - 1)) /
263 gob_size_x}; 263 gob_size_x};
264 for (u32 line = 0; line < subrect_height; ++line) { 264 for (u32 line = 0; line < subrect_height; ++line) {
265 const u32 dst_y = line + offset_y;
265 const u32 gob_address_y = 266 const u32 gob_address_y =
266 (line / (gob_size_y * block_height)) * gob_size * block_height * image_width_in_gobs + 267 (dst_y / (gob_size_y * block_height)) * gob_size * block_height * image_width_in_gobs +
267 ((line % (gob_size_y * block_height)) / gob_size_y) * gob_size; 268 ((dst_y % (gob_size_y * block_height)) / gob_size_y) * gob_size;
268 const auto& table = legacy_swizzle_table[line % gob_size_y]; 269 const auto& table = legacy_swizzle_table[dst_y % gob_size_y];
269 for (u32 x = 0; x < subrect_width; ++x) { 270 for (u32 x = 0; x < subrect_width; ++x) {
271 const u32 dst_x = x + offset_x;
270 const u32 gob_address = 272 const u32 gob_address =
271 gob_address_y + (x * bytes_per_pixel / gob_size_x) * gob_size * block_height; 273 gob_address_y + (dst_x * bytes_per_pixel / gob_size_x) * gob_size * block_height;
272 const u32 swizzled_offset = gob_address + table[(x * bytes_per_pixel) % gob_size_x]; 274 const u32 swizzled_offset = gob_address + table[(dst_x * bytes_per_pixel) % gob_size_x];
273 u8* source_line = unswizzled_data + line * source_pitch + x * bytes_per_pixel; 275 u8* source_line = unswizzled_data + line * source_pitch + x * bytes_per_pixel;
274 u8* dest_addr = swizzled_data + swizzled_offset; 276 u8* dest_addr = swizzled_data + swizzled_offset;
275 277
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index eaec9b5a5..f1e3952bc 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -44,7 +44,8 @@ std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height
44 44
45/// Copies an untiled subrectangle into a tiled surface. 45/// Copies an untiled subrectangle into a tiled surface.
46void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, 46void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width,
47 u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height); 47 u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height,
48 u32 offset_x, u32 offset_y);
48 49
49/// Copies a tiled subrectangle into a linear surface. 50/// Copies a tiled subrectangle into a linear surface.
50void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width, 51void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width,