diff options
Diffstat (limited to 'src/video_core/engines')
-rw-r--r-- | src/video_core/engines/engine_upload.cpp | 6 | ||||
-rw-r--r-- | src/video_core/engines/engine_upload.h | 6 | ||||
-rw-r--r-- | src/video_core/engines/fermi_2d.cpp | 25 | ||||
-rw-r--r-- | src/video_core/engines/fermi_2d.h | 53 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 12 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 2 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_dma.h | 4 | ||||
-rw-r--r-- | src/video_core/engines/shader_bytecode.h | 83 |
8 files changed, 147 insertions, 44 deletions
diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp index 082a40cd9..d44ad0cd8 100644 --- a/src/video_core/engines/engine_upload.cpp +++ b/src/video_core/engines/engine_upload.cpp @@ -36,10 +36,10 @@ void State::ProcessData(const u32 data, const bool is_last_call) { } else { UNIMPLEMENTED_IF(regs.dest.z != 0); UNIMPLEMENTED_IF(regs.dest.depth != 1); - UNIMPLEMENTED_IF(regs.dest.BlockWidth() != 1); - UNIMPLEMENTED_IF(regs.dest.BlockDepth() != 1); + UNIMPLEMENTED_IF(regs.dest.BlockWidth() != 0); + UNIMPLEMENTED_IF(regs.dest.BlockDepth() != 0); const std::size_t dst_size = Tegra::Texture::CalculateSize( - true, 1, regs.dest.width, regs.dest.height, 1, regs.dest.BlockHeight(), 1); + true, 1, regs.dest.width, regs.dest.height, 1, regs.dest.BlockHeight(), 0); tmp_buffer.resize(dst_size); memory_manager.ReadBlock(address, tmp_buffer.data(), dst_size); Tegra::Texture::SwizzleKepler(regs.dest.width, regs.dest.height, regs.dest.x, regs.dest.y, diff --git a/src/video_core/engines/engine_upload.h b/src/video_core/engines/engine_upload.h index ef4f5839a..462da419e 100644 --- a/src/video_core/engines/engine_upload.h +++ b/src/video_core/engines/engine_upload.h @@ -39,15 +39,15 @@ struct Registers { } u32 BlockWidth() const { - return 1U << block_width.Value(); + return block_width.Value(); } u32 BlockHeight() const { - return 1U << block_height.Value(); + return block_height.Value(); } u32 BlockDepth() const { - return 1U << block_depth.Value(); + return block_depth.Value(); } } dest; }; diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 55966eef1..0ee228e28 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp @@ -4,7 +4,6 @@ #include "common/assert.h" #include "common/logging/log.h" -#include "common/math_util.h" #include "video_core/engines/fermi_2d.h" #include "video_core/memory_manager.h" #include "video_core/rasterizer_interface.h" @@ -35,21 +34,31 @@ void Fermi2D::HandleSurfaceCopy() { static_cast<u32>(regs.operation)); // TODO(Subv): Only raw copies are implemented. - ASSERT(regs.operation == Regs::Operation::SrcCopy); + ASSERT(regs.operation == Operation::SrcCopy); const u32 src_blit_x1{static_cast<u32>(regs.blit_src_x >> 32)}; const u32 src_blit_y1{static_cast<u32>(regs.blit_src_y >> 32)}; - const u32 src_blit_x2{ - static_cast<u32>((regs.blit_src_x + (regs.blit_dst_width * regs.blit_du_dx)) >> 32)}; - const u32 src_blit_y2{ - static_cast<u32>((regs.blit_src_y + (regs.blit_dst_height * regs.blit_dv_dy)) >> 32)}; - + u32 src_blit_x2, src_blit_y2; + if (regs.blit_control.origin == Origin::Corner) { + src_blit_x2 = + static_cast<u32>((regs.blit_src_x + (regs.blit_du_dx * regs.blit_dst_width)) >> 32); + src_blit_y2 = + static_cast<u32>((regs.blit_src_y + (regs.blit_dv_dy * regs.blit_dst_height)) >> 32); + } else { + src_blit_x2 = static_cast<u32>((regs.blit_src_x >> 32) + regs.blit_dst_width); + src_blit_y2 = static_cast<u32>((regs.blit_src_y >> 32) + regs.blit_dst_height); + } const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2}; const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y, regs.blit_dst_x + regs.blit_dst_width, regs.blit_dst_y + regs.blit_dst_height}; + Config copy_config; + copy_config.operation = regs.operation; + copy_config.filter = regs.blit_control.filter; + copy_config.src_rect = src_rect; + copy_config.dst_rect = dst_rect; - if (!rasterizer.AccelerateSurfaceCopy(regs.src, regs.dst, src_rect, dst_rect)) { + if (!rasterizer.AccelerateSurfaceCopy(regs.src, regs.dst, copy_config)) { UNIMPLEMENTED(); } } diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 45f59a4d9..05421d185 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -9,6 +9,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/math_util.h" #include "video_core/gpu.h" namespace Tegra { @@ -38,6 +39,26 @@ public: /// Write the value to the register identified by method. void CallMethod(const GPU::MethodCall& method_call); + enum class Origin : u32 { + Center = 0, + Corner = 1, + }; + + enum class Filter : u32 { + PointSample = 0, // Nearest + Linear = 1, + }; + + enum class Operation : u32 { + SrcCopyAnd = 0, + ROPAnd = 1, + Blend = 2, + SrcCopy = 3, + ROP = 4, + SrcCopyPremult = 5, + BlendPremult = 6, + }; + struct Regs { static constexpr std::size_t NUM_REGS = 0x258; @@ -63,32 +84,19 @@ public: } u32 BlockWidth() const { - // The block width is stored in log2 format. - return 1 << block_width; + return block_width.Value(); } u32 BlockHeight() const { - // The block height is stored in log2 format. - return 1 << block_height; + return block_height.Value(); } u32 BlockDepth() const { - // The block depth is stored in log2 format. - return 1 << block_depth; + return block_depth.Value(); } }; 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); @@ -105,7 +113,11 @@ public: INSERT_PADDING_WORDS(0x177); - u32 blit_control; + union { + u32 raw; + BitField<0, 1, Origin> origin; + BitField<4, 1, Filter> filter; + } blit_control; INSERT_PADDING_WORDS(0x8); @@ -124,6 +136,13 @@ public: }; } regs{}; + struct Config { + Operation operation; + Filter filter; + Common::Rectangle<u32> src_rect; + Common::Rectangle<u32> dst_rect; + }; + private: VideoCore::RasterizerInterface& rasterizer; MemoryManager& memory_manager; diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 08d553696..8755b8af4 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -430,14 +430,10 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { Texture::TICEntry tic_entry; memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry)); - ASSERT_MSG(tic_entry.header_version == Texture::TICHeaderVersion::BlockLinear || - tic_entry.header_version == Texture::TICHeaderVersion::Pitch, - "TIC versions other than BlockLinear or Pitch are unimplemented"); - - const auto r_type = tic_entry.r_type.Value(); - const auto g_type = tic_entry.g_type.Value(); - const auto b_type = tic_entry.b_type.Value(); - const auto a_type = tic_entry.a_type.Value(); + const auto r_type{tic_entry.r_type.Value()}; + const auto g_type{tic_entry.g_type.Value()}; + const auto b_type{tic_entry.b_type.Value()}; + const auto a_type{tic_entry.a_type.Value()}; // TODO(Subv): Different data types for separate components are not supported DEBUG_ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 3a5dfef0c..afb9578d0 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -111,7 +111,7 @@ void MaxwellDMA::HandleCopy() { memory_manager.WriteBlock(dest, write_buffer.data(), dst_size); } else { - ASSERT(regs.dst_params.BlockDepth() == 1); + ASSERT(regs.dst_params.BlockDepth() == 0); const u32 src_bytes_per_pixel = regs.src_pitch / regs.x_count; diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index e5942f671..17b015ca7 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h @@ -59,11 +59,11 @@ public: }; u32 BlockHeight() const { - return 1 << block_height; + return block_height.Value(); } u32 BlockDepth() const { - return 1 << block_depth; + return block_depth.Value(); } }; diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index ffb3ec3e0..404d4f5aa 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -4,6 +4,7 @@ #pragma once +#include <array> #include <bitset> #include <optional> #include <tuple> @@ -126,6 +127,15 @@ union Sampler { u64 value{}; }; +union Image { + Image() = default; + + constexpr explicit Image(u64 value) : value{value} {} + + BitField<36, 13, u64> index; + u64 value; +}; + } // namespace Tegra::Shader namespace std { @@ -344,6 +354,26 @@ enum class TextureMiscMode : u64 { PTP, }; +enum class SurfaceDataMode : u64 { + P = 0, + D_BA = 1, +}; + +enum class OutOfBoundsStore : u64 { + Ignore = 0, + Clamp = 1, + Trap = 2, +}; + +enum class ImageType : u64 { + Texture1D = 0, + TextureBuffer = 1, + Texture1DArray = 2, + Texture2D = 3, + Texture2DArray = 4, + Texture3D = 5, +}; + enum class IsberdMode : u64 { None = 0, Patch = 1, @@ -398,7 +428,7 @@ enum class LmemLoadCacheManagement : u64 { CV = 3, }; -enum class LmemStoreCacheManagement : u64 { +enum class StoreCacheManagement : u64 { Default = 0, CG = 1, CS = 2, @@ -811,7 +841,7 @@ union Instruction { } ld_l; union { - BitField<44, 2, LmemStoreCacheManagement> cache_management; + BitField<44, 2, StoreCacheManagement> cache_management; } st_l; union { @@ -1232,6 +1262,20 @@ union Instruction { } texs; union { + BitField<28, 1, u64> is_array; + BitField<29, 2, TextureType> texture_type; + BitField<35, 1, u64> aoffi; + BitField<49, 1, u64> nodep_flag; + BitField<50, 1, u64> ms; // Multisample? + BitField<54, 1, u64> cl; + BitField<55, 1, u64> process_mode; + + TextureProcessMode GetTextureProcessMode() const { + return process_mode == 0 ? TextureProcessMode::LZ : TextureProcessMode::LL; + } + } tld; + + union { BitField<49, 1, u64> nodep_flag; BitField<53, 4, u64> texture_info; @@ -1281,6 +1325,35 @@ union Instruction { } tlds; union { + BitField<24, 2, StoreCacheManagement> cache_management; + BitField<33, 3, ImageType> image_type; + BitField<49, 2, OutOfBoundsStore> out_of_bounds_store; + BitField<51, 1, u64> is_immediate; + BitField<52, 1, SurfaceDataMode> mode; + + BitField<20, 3, StoreType> store_data_layout; + BitField<20, 4, u64> component_mask_selector; + + bool IsComponentEnabled(std::size_t component) const { + ASSERT(mode == SurfaceDataMode::P); + constexpr u8 R = 0b0001; + constexpr u8 G = 0b0010; + constexpr u8 B = 0b0100; + constexpr u8 A = 0b1000; + constexpr std::array<u8, 16> mask = { + 0, (R), (G), (R | G), (B), (R | B), + (G | B), (R | G | B), (A), (R | A), (G | A), (R | G | A), + (B | A), (R | B | A), (G | B | A), (R | G | B | A)}; + return std::bitset<4>{mask.at(component_mask_selector)}.test(component); + } + + StoreType GetStoreDataLayout() const { + ASSERT(mode == SurfaceDataMode::D_BA); + return store_data_layout; + } + } sust; + + union { BitField<20, 24, u64> target; BitField<5, 1, u64> constant_buffer; @@ -1371,6 +1444,7 @@ union Instruction { Attribute attribute; Sampler sampler; + Image image; u64 value; }; @@ -1408,11 +1482,13 @@ public: TXQ, // Texture Query TXQ_B, // Texture Query Bindless TEXS, // Texture Fetch with scalar/non-vec4 source/destinations + TLD, // Texture Load TLDS, // Texture Load with scalar/non-vec4 source/destinations TLD4, // Texture Load 4 TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations TMML_B, // Texture Mip Map Level TMML, // Texture Mip Map Level + SUST, // Surface Store EXIT, IPA, OUT_R, // Emit vertex/primitive @@ -1543,6 +1619,7 @@ public: Synch, Memory, Texture, + Image, FloatSet, FloatSetPredicate, IntegerSet, @@ -1682,11 +1759,13 @@ private: INST("1101111101001---", Id::TXQ, Type::Texture, "TXQ"), INST("1101111101010---", Id::TXQ_B, Type::Texture, "TXQ_B"), INST("1101-00---------", Id::TEXS, Type::Texture, "TEXS"), + INST("11011100--11----", Id::TLD, Type::Texture, "TLD"), INST("1101101---------", Id::TLDS, Type::Texture, "TLDS"), INST("110010----111---", Id::TLD4, Type::Texture, "TLD4"), INST("1101111100------", Id::TLD4S, Type::Texture, "TLD4S"), INST("110111110110----", Id::TMML_B, Type::Texture, "TMML_B"), INST("1101111101011---", Id::TMML, Type::Texture, "TMML"), + INST("11101011001-----", Id::SUST, Type::Image, "SUST"), INST("11100000--------", Id::IPA, Type::Trivial, "IPA"), INST("1111101111100---", Id::OUT_R, Type::Trivial, "OUT_R"), INST("1110111111010---", Id::ISBERD, Type::Trivial, "ISBERD"), |