diff options
| author | 2020-04-27 00:18:46 -0400 | |
|---|---|---|
| committer | 2020-04-27 00:18:46 -0400 | |
| commit | 6c7d8073be9ab0ce92d346742989800895beeffe (patch) | |
| tree | 298da9383d7f883102643f0ab146dda72d9f5358 /src/video_core/engines | |
| parent | Merge pull request #3795 from vitor-k/fix-folder (diff) | |
| parent | Clang Format. (diff) | |
| download | yuzu-6c7d8073be9ab0ce92d346742989800895beeffe.tar.gz yuzu-6c7d8073be9ab0ce92d346742989800895beeffe.tar.xz yuzu-6c7d8073be9ab0ce92d346742989800895beeffe.zip | |
Merge pull request #3742 from FernandoS27/command-list
Optimize GPU Command Lists and Introduce Fast GPU Time Option
Diffstat (limited to 'src/video_core/engines')
| -rw-r--r-- | src/video_core/engines/fermi_2d.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.h | 3 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.h | 3 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.h | 3 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 74 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 4 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.h | 3 |
10 files changed, 117 insertions, 0 deletions
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index bace6affb..8a47614d2 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -28,6 +28,12 @@ void Fermi2D::CallMethod(const GPU::MethodCall& method_call) { | |||
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | void Fermi2D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { | ||
| 32 | for (std::size_t i = 0; i < amount; i++) { | ||
| 33 | CallMethod({method, base_start[i], 0, methods_pending - static_cast<u32>(i)}); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 31 | static std::pair<u32, u32> DelimitLine(u32 src_1, u32 src_2, u32 dst_1, u32 dst_2, u32 src_line) { | 37 | static std::pair<u32, u32> DelimitLine(u32 src_1, u32 src_2, u32 dst_1, u32 dst_2, u32 src_line) { |
| 32 | const u32 line_a = src_2 - src_1; | 38 | const u32 line_a = src_2 - src_1; |
| 33 | const u32 line_b = dst_2 - dst_1; | 39 | const u32 line_b = dst_2 - dst_1; |
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index dba342c70..939a5966d 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -39,6 +39,9 @@ public: | |||
| 39 | /// Write the value to the register identified by method. | 39 | /// Write the value to the register identified by method. |
| 40 | void CallMethod(const GPU::MethodCall& method_call); | 40 | void CallMethod(const GPU::MethodCall& method_call); |
| 41 | 41 | ||
| 42 | /// Write multiple values to the register identified by method. | ||
| 43 | void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); | ||
| 44 | |||
| 42 | enum class Origin : u32 { | 45 | enum class Origin : u32 { |
| 43 | Center = 0, | 46 | Center = 0, |
| 44 | Corner = 1, | 47 | Corner = 1, |
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 368c75a66..00a12175f 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp | |||
| @@ -51,6 +51,13 @@ void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) { | |||
| 51 | } | 51 | } |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | void KeplerCompute::CallMultiMethod(u32 method, const u32* base_start, u32 amount, | ||
| 55 | u32 methods_pending) { | ||
| 56 | for (std::size_t i = 0; i < amount; i++) { | ||
| 57 | CallMethod({method, base_start[i], 0, methods_pending - static_cast<u32>(i)}); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 54 | Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) const { | 61 | Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) const { |
| 55 | const std::bitset<8> cbuf_mask = launch_description.const_buffer_enable_mask.Value(); | 62 | const std::bitset<8> cbuf_mask = launch_description.const_buffer_enable_mask.Value(); |
| 56 | ASSERT(cbuf_mask[regs.tex_cb_index]); | 63 | ASSERT(cbuf_mask[regs.tex_cb_index]); |
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h index eeb79c56f..fe55fdfd0 100644 --- a/src/video_core/engines/kepler_compute.h +++ b/src/video_core/engines/kepler_compute.h | |||
| @@ -202,6 +202,9 @@ public: | |||
| 202 | /// Write the value to the register identified by method. | 202 | /// Write the value to the register identified by method. |
| 203 | void CallMethod(const GPU::MethodCall& method_call); | 203 | void CallMethod(const GPU::MethodCall& method_call); |
| 204 | 204 | ||
| 205 | /// Write multiple values to the register identified by method. | ||
| 206 | void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); | ||
| 207 | |||
| 205 | Texture::FullTextureInfo GetTexture(std::size_t offset) const; | 208 | Texture::FullTextureInfo GetTexture(std::size_t offset) const; |
| 206 | 209 | ||
| 207 | /// Given a texture handle, returns the TSC and TIC entries. | 210 | /// Given a texture handle, returns the TSC and TIC entries. |
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp index 597872e43..586ff15dc 100644 --- a/src/video_core/engines/kepler_memory.cpp +++ b/src/video_core/engines/kepler_memory.cpp | |||
| @@ -41,4 +41,11 @@ void KeplerMemory::CallMethod(const GPU::MethodCall& method_call) { | |||
| 41 | } | 41 | } |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void KeplerMemory::CallMultiMethod(u32 method, const u32* base_start, u32 amount, | ||
| 45 | u32 methods_pending) { | ||
| 46 | for (std::size_t i = 0; i < amount; i++) { | ||
| 47 | CallMethod({method, base_start[i], 0, methods_pending - static_cast<u32>(i)}); | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 44 | } // namespace Tegra::Engines | 51 | } // namespace Tegra::Engines |
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h index 396fb6e86..bb26fb030 100644 --- a/src/video_core/engines/kepler_memory.h +++ b/src/video_core/engines/kepler_memory.h | |||
| @@ -40,6 +40,9 @@ public: | |||
| 40 | /// Write the value to the register identified by method. | 40 | /// Write the value to the register identified by method. |
| 41 | void CallMethod(const GPU::MethodCall& method_call); | 41 | void CallMethod(const GPU::MethodCall& method_call); |
| 42 | 42 | ||
| 43 | /// Write multiple values to the register identified by method. | ||
| 44 | void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); | ||
| 45 | |||
| 43 | struct Regs { | 46 | struct Regs { |
| 44 | static constexpr size_t NUM_REGS = 0x7F; | 47 | static constexpr size_t NUM_REGS = 0x7F; |
| 45 | 48 | ||
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2824ed707..39e3b66a2 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -280,6 +280,58 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { | |||
| 280 | } | 280 | } |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, | ||
| 284 | u32 methods_pending) { | ||
| 285 | // Methods after 0xE00 are special, they're actually triggers for some microcode that was | ||
| 286 | // uploaded to the GPU during initialization. | ||
| 287 | if (method >= MacroRegistersStart) { | ||
| 288 | // We're trying to execute a macro | ||
| 289 | if (executing_macro == 0) { | ||
| 290 | // A macro call must begin by writing the macro method's register, not its argument. | ||
| 291 | ASSERT_MSG((method % 2) == 0, | ||
| 292 | "Can't start macro execution by writing to the ARGS register"); | ||
| 293 | executing_macro = method; | ||
| 294 | } | ||
| 295 | |||
| 296 | for (std::size_t i = 0; i < amount; i++) { | ||
| 297 | macro_params.push_back(base_start[i]); | ||
| 298 | } | ||
| 299 | |||
| 300 | // Call the macro when there are no more parameters in the command buffer | ||
| 301 | if (amount == methods_pending) { | ||
| 302 | CallMacroMethod(executing_macro, macro_params.size(), macro_params.data()); | ||
| 303 | macro_params.clear(); | ||
| 304 | } | ||
| 305 | return; | ||
| 306 | } | ||
| 307 | switch (method) { | ||
| 308 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]): | ||
| 309 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]): | ||
| 310 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]): | ||
| 311 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]): | ||
| 312 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]): | ||
| 313 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]): | ||
| 314 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]): | ||
| 315 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]): | ||
| 316 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]): | ||
| 317 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]): | ||
| 318 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]): | ||
| 319 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]): | ||
| 320 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]): | ||
| 321 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]): | ||
| 322 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]): | ||
| 323 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): { | ||
| 324 | ProcessCBMultiData(method, base_start, amount); | ||
| 325 | break; | ||
| 326 | } | ||
| 327 | default: { | ||
| 328 | for (std::size_t i = 0; i < amount; i++) { | ||
| 329 | CallMethod({method, base_start[i], 0, methods_pending - static_cast<u32>(i)}); | ||
| 330 | } | ||
| 331 | } | ||
| 332 | } | ||
| 333 | } | ||
| 334 | |||
| 283 | void Maxwell3D::StepInstance(const MMEDrawMode expected_mode, const u32 count) { | 335 | void Maxwell3D::StepInstance(const MMEDrawMode expected_mode, const u32 count) { |
| 284 | if (mme_draw.current_mode == MMEDrawMode::Undefined) { | 336 | if (mme_draw.current_mode == MMEDrawMode::Undefined) { |
| 285 | if (mme_draw.gl_begin_consume) { | 337 | if (mme_draw.gl_begin_consume) { |
| @@ -570,6 +622,28 @@ void Maxwell3D::StartCBData(u32 method) { | |||
| 570 | ProcessCBData(regs.const_buffer.cb_data[cb_data_state.id]); | 622 | ProcessCBData(regs.const_buffer.cb_data[cb_data_state.id]); |
| 571 | } | 623 | } |
| 572 | 624 | ||
| 625 | void Maxwell3D::ProcessCBMultiData(u32 method, const u32* start_base, u32 amount) { | ||
| 626 | if (cb_data_state.current != method) { | ||
| 627 | if (cb_data_state.current != null_cb_data) { | ||
| 628 | FinishCBData(); | ||
| 629 | } | ||
| 630 | constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]); | ||
| 631 | cb_data_state.start_pos = regs.const_buffer.cb_pos; | ||
| 632 | cb_data_state.id = method - first_cb_data; | ||
| 633 | cb_data_state.current = method; | ||
| 634 | cb_data_state.counter = 0; | ||
| 635 | } | ||
| 636 | const std::size_t id = cb_data_state.id; | ||
| 637 | const std::size_t size = amount; | ||
| 638 | std::size_t i = 0; | ||
| 639 | for (; i < size; i++) { | ||
| 640 | cb_data_state.buffer[id][cb_data_state.counter] = start_base[i]; | ||
| 641 | cb_data_state.counter++; | ||
| 642 | } | ||
| 643 | // Increment the current buffer position. | ||
| 644 | regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4 * amount; | ||
| 645 | } | ||
| 646 | |||
| 573 | void Maxwell3D::FinishCBData() { | 647 | void Maxwell3D::FinishCBData() { |
| 574 | // Write the input value to the current const buffer at the current position. | 648 | // Write the input value to the current const buffer at the current position. |
| 575 | const GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); | 649 | const GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 7bbc6600b..3dfba8197 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -1359,6 +1359,9 @@ public: | |||
| 1359 | /// Write the value to the register identified by method. | 1359 | /// Write the value to the register identified by method. |
| 1360 | void CallMethod(const GPU::MethodCall& method_call); | 1360 | void CallMethod(const GPU::MethodCall& method_call); |
| 1361 | 1361 | ||
| 1362 | /// Write multiple values to the register identified by method. | ||
| 1363 | void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); | ||
| 1364 | |||
| 1362 | /// Write the value to the register identified by method. | 1365 | /// Write the value to the register identified by method. |
| 1363 | void CallMethodFromMME(const GPU::MethodCall& method_call); | 1366 | void CallMethodFromMME(const GPU::MethodCall& method_call); |
| 1364 | 1367 | ||
| @@ -1512,6 +1515,7 @@ private: | |||
| 1512 | /// Handles a write to the CB_DATA[i] register. | 1515 | /// Handles a write to the CB_DATA[i] register. |
| 1513 | void StartCBData(u32 method); | 1516 | void StartCBData(u32 method); |
| 1514 | void ProcessCBData(u32 value); | 1517 | void ProcessCBData(u32 value); |
| 1518 | void ProcessCBMultiData(u32 method, const u32* start_base, u32 amount); | ||
| 1515 | void FinishCBData(); | 1519 | void FinishCBData(); |
| 1516 | 1520 | ||
| 1517 | /// Handles a write to the CB_BIND register. | 1521 | /// Handles a write to the CB_BIND register. |
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 3bfed6ab8..6630005b0 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -36,6 +36,13 @@ void MaxwellDMA::CallMethod(const GPU::MethodCall& method_call) { | |||
| 36 | #undef MAXWELLDMA_REG_INDEX | 36 | #undef MAXWELLDMA_REG_INDEX |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount, | ||
| 40 | u32 methods_pending) { | ||
| 41 | for (std::size_t i = 0; i < amount; i++) { | ||
| 42 | CallMethod({method, base_start[i], 0, methods_pending - static_cast<u32>(i)}); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 39 | void MaxwellDMA::HandleCopy() { | 46 | void MaxwellDMA::HandleCopy() { |
| 40 | LOG_TRACE(HW_GPU, "Requested a DMA copy"); | 47 | LOG_TRACE(HW_GPU, "Requested a DMA copy"); |
| 41 | 48 | ||
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index 4f40d1d1f..c43ed8194 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h | |||
| @@ -35,6 +35,9 @@ public: | |||
| 35 | /// Write the value to the register identified by method. | 35 | /// Write the value to the register identified by method. |
| 36 | void CallMethod(const GPU::MethodCall& method_call); | 36 | void CallMethod(const GPU::MethodCall& method_call); |
| 37 | 37 | ||
| 38 | /// Write multiple values to the register identified by method. | ||
| 39 | void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); | ||
| 40 | |||
| 38 | struct Regs { | 41 | struct Regs { |
| 39 | static constexpr std::size_t NUM_REGS = 0x1D6; | 42 | static constexpr std::size_t NUM_REGS = 0x1D6; |
| 40 | 43 | ||