Skip to content
Snippets Groups Projects
Commit 1ddcd0e6 authored by ReinUsesLisp's avatar ReinUsesLisp
Browse files

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.
parent f09d1dff
No related branches found
No related tags found
No related merge requests found
......@@ -5,12 +5,12 @@ add_library(video_core STATIC
debug_utils/debug_utils.h
engines/fermi_2d.cpp
engines/fermi_2d.h
engines/kepler_compute.cpp
engines/kepler_compute.h
engines/kepler_memory.cpp
engines/kepler_memory.h
engines/maxwell_3d.cpp
engines/maxwell_3d.h
engines/maxwell_compute.cpp
engines/maxwell_compute.h
engines/maxwell_dma.cpp
engines/maxwell_dma.h
engines/shader_bytecode.h
......
......@@ -4,22 +4,28 @@
#include "common/logging/log.h"
#include "core/core.h"
#include "video_core/engines/maxwell_compute.h"
#include "core/memory.h"
#include "video_core/engines/kepler_compute.h"
#include "video_core/memory_manager.h"
namespace Tegra::Engines {
void MaxwellCompute::CallMethod(const GPU::MethodCall& method_call) {
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 MaxwellCompute register, increase the size of the Regs structure");
"Invalid KeplerCompute 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();
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;
}
......
......@@ -10,47 +10,48 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "video_core/gpu.h"
#include "video_core/memory_manager.h"
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:
MaxwellCompute() = default;
~MaxwellCompute() = default;
explicit KeplerCompute(MemoryManager& memory_manager);
~KeplerCompute();
static constexpr std::size_t NumConstBuffers = 8;
struct Regs {
static constexpr std::size_t NUM_REGS = 0xCF8;
union {
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;
};
} regs{};
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.
void CallMethod(const GPU::MethodCall& method_call);
};
#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")
ASSERT_REG_POSITION(compute, 0x281);
ASSERT_REG_POSITION(launch, 0xAF);
#undef ASSERT_REG_POSITION
......
......@@ -6,9 +6,9 @@
#include "core/core_timing.h"
#include "core/memory.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/maxwell_3d.h"
#include "video_core/engines/maxwell_compute.h"
#include "video_core/engines/maxwell_dma.h"
#include "video_core/gpu.h"
#include "video_core/rasterizer_interface.h"
......@@ -31,7 +31,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
dma_pusher = std::make_unique<Tegra::DmaPusher>(*this);
maxwell_3d = std::make_unique<Engines::Maxwell3D>(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);
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:
maxwell_3d->CallMethod(method_call);
break;
case EngineID::MAXWELL_COMPUTE_B:
maxwell_compute->CallMethod(method_call);
case EngineID::KEPLER_COMPUTE_B:
kepler_compute->CallMethod(method_call);
break;
case EngineID::MAXWELL_DMA_COPY_A:
maxwell_dma->CallMethod(method_call);
......
......@@ -102,15 +102,15 @@ struct FramebufferConfig {
namespace Engines {
class Fermi2D;
class Maxwell3D;
class MaxwellCompute;
class MaxwellDMA;
class KeplerCompute;
class KeplerMemory;
} // namespace Engines
enum class EngineID {
FERMI_TWOD_A = 0x902D, // 2D Engine
MAXWELL_B = 0xB197, // 3D Engine
MAXWELL_COMPUTE_B = 0xB1C0,
KEPLER_COMPUTE_B = 0xB1C0,
KEPLER_INLINE_TO_MEMORY_B = 0xA140,
MAXWELL_DMA_COPY_A = 0xB0B5,
};
......@@ -208,7 +208,7 @@ private:
/// 2D engine
std::unique_ptr<Engines::Fermi2D> fermi_2d;
/// Compute engine
std::unique_ptr<Engines::MaxwellCompute> maxwell_compute;
std::unique_ptr<Engines::KeplerCompute> kepler_compute;
/// DMA engine
std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
/// Inline memory engine
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment