diff options
author | bunnei <bunneidev@gmail.com> | 2018-04-26 02:40:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-26 02:40:17 +0200 |
commit | 42d43ea741886b9592fd7dfd57c33228afacf44c (patch) | |
tree | abfeb405b9c710816ad9ea8e06ea14854c0eb4a9 /src/video_core/engines/fermi_2d.h | |
parent | Merge pull request #395 from lioncash/file-sys (diff) | |
parent | GPU: Partially implemented the Fermi2D surface copy operation. (diff) | |
download | yuzu-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.h | 89 |
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 |