summaryrefslogtreecommitdiffstats
path: root/src/video_core/engines
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/engines')
-rw-r--r--src/video_core/engines/engine_upload.cpp6
-rw-r--r--src/video_core/engines/engine_upload.h6
-rw-r--r--src/video_core/engines/fermi_2d.cpp25
-rw-r--r--src/video_core/engines/fermi_2d.h53
-rw-r--r--src/video_core/engines/maxwell_3d.cpp12
-rw-r--r--src/video_core/engines/maxwell_dma.cpp2
-rw-r--r--src/video_core/engines/maxwell_dma.h4
-rw-r--r--src/video_core/engines/shader_bytecode.h83
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"),