Преглед изворни кода

kepler_compute: Fixup assert and rename engines

When I originally added the compute assert I used the wrong
documentation. This addresses that.

The dispatch register was tested with homebrew against hardware and is
triggered by some games (e.g. Super Mario Odyssey). What exactly is
missing to get a valid program bound by this engine requires more
investigation.
ReinUsesLisp пре 7 година
родитељ
комит
1ddcd0e6f0

+ 2 - 2
src/video_core/CMakeLists.txt

@@ -5,12 +5,12 @@ add_library(video_core STATIC
     debug_utils/debug_utils.h
     debug_utils/debug_utils.h
     engines/fermi_2d.cpp
     engines/fermi_2d.cpp
     engines/fermi_2d.h
     engines/fermi_2d.h
+    engines/kepler_compute.cpp
+    engines/kepler_compute.h
     engines/kepler_memory.cpp
     engines/kepler_memory.cpp
     engines/kepler_memory.h
     engines/kepler_memory.h
     engines/maxwell_3d.cpp
     engines/maxwell_3d.cpp
     engines/maxwell_3d.h
     engines/maxwell_3d.h
-    engines/maxwell_compute.cpp
-    engines/maxwell_compute.h
     engines/maxwell_dma.cpp
     engines/maxwell_dma.cpp
     engines/maxwell_dma.h
     engines/maxwell_dma.h
     engines/shader_bytecode.h
     engines/shader_bytecode.h

+ 34 - 0
src/video_core/engines/kepler_compute.cpp

@@ -0,0 +1,34 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/memory.h"
+#include "video_core/engines/kepler_compute.h"
+#include "video_core/memory_manager.h"
+
+namespace Tegra::Engines {
+
+KeplerCompute::KeplerCompute(MemoryManager& memory_manager) : memory_manager{memory_manager} {}
+
+KeplerCompute::~KeplerCompute() = default;
+
+void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) {
+    ASSERT_MSG(method_call.method < Regs::NUM_REGS,
+               "Invalid KeplerCompute register, increase the size of the Regs structure");
+
+    regs.reg_array[method_call.method] = method_call.argument;
+
+    switch (method_call.method) {
+    case KEPLER_COMPUTE_REG_INDEX(launch):
+        // Abort execution since compute shaders can be used to alter game memory (e.g. CUDA
+        // kernels)
+        UNREACHABLE_MSG("Compute shaders are not implemented");
+        break;
+    default:
+        break;
+    }
+}
+
+} // namespace Tegra::Engines

+ 16 - 15
src/video_core/engines/maxwell_compute.h → src/video_core/engines/kepler_compute.h

@@ -10,47 +10,48 @@
 #include "common/common_funcs.h"
 #include "common/common_funcs.h"
 #include "common/common_types.h"
 #include "common/common_types.h"
 #include "video_core/gpu.h"
 #include "video_core/gpu.h"
+#include "video_core/memory_manager.h"
 
 
 namespace Tegra::Engines {
 namespace Tegra::Engines {
 
 
-#define MAXWELL_COMPUTE_REG_INDEX(field_name)                                                      \
-    (offsetof(Tegra::Engines::MaxwellCompute::Regs, field_name) / sizeof(u32))
+#define KEPLER_COMPUTE_REG_INDEX(field_name)                                                       \
+    (offsetof(Tegra::Engines::KeplerCompute::Regs, field_name) / sizeof(u32))
 
 
-class MaxwellCompute final {
+class KeplerCompute final {
 public:
 public:
-    MaxwellCompute() = default;
-    ~MaxwellCompute() = default;
+    explicit KeplerCompute(MemoryManager& memory_manager);
+    ~KeplerCompute();
+
+    static constexpr std::size_t NumConstBuffers = 8;
 
 
     struct Regs {
     struct Regs {
         static constexpr std::size_t NUM_REGS = 0xCF8;
         static constexpr std::size_t NUM_REGS = 0xCF8;
 
 
         union {
         union {
             struct {
             struct {
-                INSERT_PADDING_WORDS(0x281);
+                INSERT_PADDING_WORDS(0xAF);
 
 
-                union {
-                    u32 compute_end;
-                    BitField<0, 1, u32> unknown;
-                } compute;
+                u32 launch;
 
 
-                INSERT_PADDING_WORDS(0xA76);
+                INSERT_PADDING_WORDS(0xC48);
             };
             };
             std::array<u32, NUM_REGS> reg_array;
             std::array<u32, NUM_REGS> reg_array;
         };
         };
     } regs{};
     } regs{};
-
     static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32),
     static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32),
-                  "MaxwellCompute Regs has wrong size");
+                  "KeplerCompute Regs has wrong size");
+
+    MemoryManager& memory_manager;
 
 
     /// Write the value to the register identified by method.
     /// Write the value to the register identified by method.
     void CallMethod(const GPU::MethodCall& method_call);
     void CallMethod(const GPU::MethodCall& method_call);
 };
 };
 
 
 #define ASSERT_REG_POSITION(field_name, position)                                                  \
 #define ASSERT_REG_POSITION(field_name, position)                                                  \
-    static_assert(offsetof(MaxwellCompute::Regs, field_name) == position * 4,                      \
+    static_assert(offsetof(KeplerCompute::Regs, field_name) == position * 4,                       \
                   "Field " #field_name " has invalid position")
                   "Field " #field_name " has invalid position")
 
 
-ASSERT_REG_POSITION(compute, 0x281);
+ASSERT_REG_POSITION(launch, 0xAF);
 
 
 #undef ASSERT_REG_POSITION
 #undef ASSERT_REG_POSITION
 
 

+ 0 - 28
src/video_core/engines/maxwell_compute.cpp

@@ -1,28 +0,0 @@
-// Copyright 2018 yuzu Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "common/logging/log.h"
-#include "core/core.h"
-#include "video_core/engines/maxwell_compute.h"
-
-namespace Tegra::Engines {
-
-void MaxwellCompute::CallMethod(const GPU::MethodCall& method_call) {
-    ASSERT_MSG(method_call.method < Regs::NUM_REGS,
-               "Invalid MaxwellCompute register, increase the size of the Regs structure");
-
-    regs.reg_array[method_call.method] = method_call.argument;
-
-    switch (method_call.method) {
-    case MAXWELL_COMPUTE_REG_INDEX(compute): {
-        LOG_CRITICAL(HW_GPU, "Compute shaders are not implemented");
-        UNREACHABLE();
-        break;
-    }
-    default:
-        break;
-    }
-}
-
-} // namespace Tegra::Engines

+ 4 - 4
src/video_core/gpu.cpp

@@ -6,9 +6,9 @@
 #include "core/core_timing.h"
 #include "core/core_timing.h"
 #include "core/memory.h"
 #include "core/memory.h"
 #include "video_core/engines/fermi_2d.h"
 #include "video_core/engines/fermi_2d.h"
+#include "video_core/engines/kepler_compute.h"
 #include "video_core/engines/kepler_memory.h"
 #include "video_core/engines/kepler_memory.h"
 #include "video_core/engines/maxwell_3d.h"
 #include "video_core/engines/maxwell_3d.h"
-#include "video_core/engines/maxwell_compute.h"
 #include "video_core/engines/maxwell_dma.h"
 #include "video_core/engines/maxwell_dma.h"
 #include "video_core/gpu.h"
 #include "video_core/gpu.h"
 #include "video_core/rasterizer_interface.h"
 #include "video_core/rasterizer_interface.h"
@@ -31,7 +31,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
     dma_pusher = std::make_unique<Tegra::DmaPusher>(*this);
     dma_pusher = std::make_unique<Tegra::DmaPusher>(*this);
     maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
     maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
     fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager);
     fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager);
-    maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
+    kepler_compute = std::make_unique<Engines::KeplerCompute>(*memory_manager);
     maxwell_dma = std::make_unique<Engines::MaxwellDMA>(rasterizer, *memory_manager);
     maxwell_dma = std::make_unique<Engines::MaxwellDMA>(rasterizer, *memory_manager);
     kepler_memory = std::make_unique<Engines::KeplerMemory>(rasterizer, *memory_manager);
     kepler_memory = std::make_unique<Engines::KeplerMemory>(rasterizer, *memory_manager);
 }
 }
@@ -245,8 +245,8 @@ void GPU::CallEngineMethod(const MethodCall& method_call) {
     case EngineID::MAXWELL_B:
     case EngineID::MAXWELL_B:
         maxwell_3d->CallMethod(method_call);
         maxwell_3d->CallMethod(method_call);
         break;
         break;
-    case EngineID::MAXWELL_COMPUTE_B:
-        maxwell_compute->CallMethod(method_call);
+    case EngineID::KEPLER_COMPUTE_B:
+        kepler_compute->CallMethod(method_call);
         break;
         break;
     case EngineID::MAXWELL_DMA_COPY_A:
     case EngineID::MAXWELL_DMA_COPY_A:
         maxwell_dma->CallMethod(method_call);
         maxwell_dma->CallMethod(method_call);

+ 3 - 3
src/video_core/gpu.h

@@ -102,15 +102,15 @@ struct FramebufferConfig {
 namespace Engines {
 namespace Engines {
 class Fermi2D;
 class Fermi2D;
 class Maxwell3D;
 class Maxwell3D;
-class MaxwellCompute;
 class MaxwellDMA;
 class MaxwellDMA;
+class KeplerCompute;
 class KeplerMemory;
 class KeplerMemory;
 } // namespace Engines
 } // namespace Engines
 
 
 enum class EngineID {
 enum class EngineID {
     FERMI_TWOD_A = 0x902D, // 2D Engine
     FERMI_TWOD_A = 0x902D, // 2D Engine
     MAXWELL_B = 0xB197,    // 3D Engine
     MAXWELL_B = 0xB197,    // 3D Engine
-    MAXWELL_COMPUTE_B = 0xB1C0,
+    KEPLER_COMPUTE_B = 0xB1C0,
     KEPLER_INLINE_TO_MEMORY_B = 0xA140,
     KEPLER_INLINE_TO_MEMORY_B = 0xA140,
     MAXWELL_DMA_COPY_A = 0xB0B5,
     MAXWELL_DMA_COPY_A = 0xB0B5,
 };
 };
@@ -208,7 +208,7 @@ private:
     /// 2D engine
     /// 2D engine
     std::unique_ptr<Engines::Fermi2D> fermi_2d;
     std::unique_ptr<Engines::Fermi2D> fermi_2d;
     /// Compute engine
     /// Compute engine
-    std::unique_ptr<Engines::MaxwellCompute> maxwell_compute;
+    std::unique_ptr<Engines::KeplerCompute> kepler_compute;
     /// DMA engine
     /// DMA engine
     std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
     std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
     /// Inline memory engine
     /// Inline memory engine