summaryrefslogtreecommitdiffstats
path: root/src/video_core/engines/fermi_2d.h
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-04-26 02:40:17 +0200
committerGitHub <noreply@github.com>2018-04-26 02:40:17 +0200
commit42d43ea741886b9592fd7dfd57c33228afacf44c (patch)
treeabfeb405b9c710816ad9ea8e06ea14854c0eb4a9 /src/video_core/engines/fermi_2d.h
parentMerge pull request #395 from lioncash/file-sys (diff)
parentGPU: Partially implemented the Fermi2D surface copy operation. (diff)
downloadyuzu-42d43ea741886b9592fd7dfd57c33228afacf44c.tar
yuzu-42d43ea741886b9592fd7dfd57c33228afacf44c.tar.gz
yuzu-42d43ea741886b9592fd7dfd57c33228afacf44c.tar.bz2
yuzu-42d43ea741886b9592fd7dfd57c33228afacf44c.tar.lz
yuzu-42d43ea741886b9592fd7dfd57c33228afacf44c.tar.xz
yuzu-42d43ea741886b9592fd7dfd57c33228afacf44c.tar.zst
yuzu-42d43ea741886b9592fd7dfd57c33228afacf44c.zip
Diffstat (limited to 'src/video_core/engines/fermi_2d.h')
-rw-r--r--src/video_core/engines/fermi_2d.h89
1 files changed, 88 insertions, 1 deletions
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h
index 8967ddede..0c5b413cc 100644
--- a/src/video_core/engines/fermi_2d.h
+++ b/src/video_core/engines/fermi_2d.h
@@ -4,19 +4,106 @@
#pragma once
+#include <array>
+#include "common/assert.h"
+#include "common/bit_field.h"
+#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "video_core/gpu.h"
+#include "video_core/memory_manager.h"
namespace Tegra {
namespace Engines {
+#define FERMI2D_REG_INDEX(field_name) \
+ (offsetof(Tegra::Engines::Fermi2D::Regs, field_name) / sizeof(u32))
+
class Fermi2D final {
public:
- Fermi2D() = default;
+ explicit Fermi2D(MemoryManager& memory_manager);
~Fermi2D() = default;
/// Write the value to the register identified by method.
void WriteReg(u32 method, u32 value);
+
+ struct Regs {
+ static constexpr size_t NUM_REGS = 0x258;
+
+ struct Surface {
+ RenderTargetFormat format;
+ BitField<0, 1, u32> linear;
+ union {
+ BitField<0, 4, u32> block_depth;
+ BitField<4, 4, u32> block_height;
+ BitField<8, 4, u32> block_width;
+ };
+ u32 depth;
+ u32 layer;
+ u32 pitch;
+ u32 width;
+ u32 height;
+ u32 address_high;
+ u32 address_low;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
+ static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size");
+
+ enum class Operation : u32 {
+ SrcCopyAnd = 0,
+ ROPAnd = 1,
+ Blend = 2,
+ SrcCopy = 3,
+ ROP = 4,
+ SrcCopyPremult = 5,
+ BlendPremult = 6,
+ };
+
+ union {
+ struct {
+ INSERT_PADDING_WORDS(0x80);
+
+ Surface dst;
+
+ INSERT_PADDING_WORDS(2);
+
+ Surface src;
+
+ INSERT_PADDING_WORDS(0x15);
+
+ Operation operation;
+
+ INSERT_PADDING_WORDS(0x9);
+
+ // TODO(Subv): This is only a guess.
+ u32 trigger;
+
+ INSERT_PADDING_WORDS(0x1A3);
+ };
+ std::array<u32, NUM_REGS> reg_array;
+ };
+ } regs{};
+
+ MemoryManager& memory_manager;
+
+private:
+ /// Performs the copy from the source surface to the destination surface as configured in the
+ /// registers.
+ void HandleSurfaceCopy();
};
+#define ASSERT_REG_POSITION(field_name, position) \
+ static_assert(offsetof(Fermi2D::Regs, field_name) == position * 4, \
+ "Field " #field_name " has invalid position")
+
+ASSERT_REG_POSITION(dst, 0x80);
+ASSERT_REG_POSITION(src, 0x8C);
+ASSERT_REG_POSITION(operation, 0xAB);
+ASSERT_REG_POSITION(trigger, 0xB5);
+#undef ASSERT_REG_POSITION
+
} // namespace Engines
} // namespace Tegra