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/fermi_2d.h2
-rw-r--r--src/video_core/engines/kepler_memory.cpp45
-rw-r--r--src/video_core/engines/kepler_memory.h90
-rw-r--r--src/video_core/engines/maxwell_3d.cpp13
-rw-r--r--src/video_core/engines/maxwell_3d.h28
-rw-r--r--src/video_core/engines/maxwell_dma.cpp2
-rw-r--r--src/video_core/engines/maxwell_dma.h2
-rw-r--r--src/video_core/engines/shader_bytecode.h28
8 files changed, 177 insertions, 33 deletions
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h
index dcf9ef8b9..021b83eaa 100644
--- a/src/video_core/engines/fermi_2d.h
+++ b/src/video_core/engines/fermi_2d.h
@@ -26,7 +26,7 @@ public:
void WriteReg(u32 method, u32 value);
struct Regs {
- static constexpr size_t NUM_REGS = 0x258;
+ static constexpr std::size_t NUM_REGS = 0x258;
struct Surface {
RenderTargetFormat format;
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp
new file mode 100644
index 000000000..66ae6332d
--- /dev/null
+++ b/src/video_core/engines/kepler_memory.cpp
@@ -0,0 +1,45 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/logging/log.h"
+#include "core/memory.h"
+#include "video_core/engines/kepler_memory.h"
+
+namespace Tegra::Engines {
+
+KeplerMemory::KeplerMemory(MemoryManager& memory_manager) : memory_manager(memory_manager) {}
+KeplerMemory::~KeplerMemory() = default;
+
+void KeplerMemory::WriteReg(u32 method, u32 value) {
+ ASSERT_MSG(method < Regs::NUM_REGS,
+ "Invalid KeplerMemory register, increase the size of the Regs structure");
+
+ regs.reg_array[method] = value;
+
+ switch (method) {
+ case KEPLERMEMORY_REG_INDEX(exec): {
+ state.write_offset = 0;
+ break;
+ }
+ case KEPLERMEMORY_REG_INDEX(data): {
+ ProcessData(value);
+ break;
+ }
+ }
+}
+
+void KeplerMemory::ProcessData(u32 data) {
+ ASSERT_MSG(regs.exec.linear, "Non-linear uploads are not supported");
+ ASSERT(regs.dest.x == 0 && regs.dest.y == 0 && regs.dest.z == 0);
+
+ GPUVAddr address = regs.dest.Address();
+ VAddr dest_address =
+ *memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32));
+
+ Memory::Write32(dest_address, data);
+
+ state.write_offset++;
+}
+
+} // namespace Tegra::Engines
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h
new file mode 100644
index 000000000..b0d0078cf
--- /dev/null
+++ b/src/video_core/engines/kepler_memory.h
@@ -0,0 +1,90 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#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/memory_manager.h"
+
+namespace Tegra::Engines {
+
+#define KEPLERMEMORY_REG_INDEX(field_name) \
+ (offsetof(Tegra::Engines::KeplerMemory::Regs, field_name) / sizeof(u32))
+
+class KeplerMemory final {
+public:
+ KeplerMemory(MemoryManager& memory_manager);
+ ~KeplerMemory();
+
+ /// Write the value to the register identified by method.
+ void WriteReg(u32 method, u32 value);
+
+ struct Regs {
+ static constexpr size_t NUM_REGS = 0x7F;
+
+ union {
+ struct {
+ INSERT_PADDING_WORDS(0x60);
+
+ u32 line_length_in;
+ u32 line_count;
+
+ struct {
+ u32 address_high;
+ u32 address_low;
+ u32 pitch;
+ u32 block_dimensions;
+ u32 width;
+ u32 height;
+ u32 depth;
+ u32 z;
+ u32 x;
+ u32 y;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ } dest;
+
+ struct {
+ union {
+ BitField<0, 1, u32> linear;
+ };
+ } exec;
+
+ u32 data;
+
+ INSERT_PADDING_WORDS(0x11);
+ };
+ std::array<u32, NUM_REGS> reg_array;
+ };
+ } regs{};
+
+ struct {
+ u32 write_offset = 0;
+ } state{};
+
+private:
+ MemoryManager& memory_manager;
+
+ void ProcessData(u32 data);
+};
+
+#define ASSERT_REG_POSITION(field_name, position) \
+ static_assert(offsetof(KeplerMemory::Regs, field_name) == position * 4, \
+ "Field " #field_name " has invalid position")
+
+ASSERT_REG_POSITION(line_length_in, 0x60);
+ASSERT_REG_POSITION(line_count, 0x61);
+ASSERT_REG_POSITION(dest, 0x62);
+ASSERT_REG_POSITION(exec, 0x6C);
+ASSERT_REG_POSITION(data, 0x6D);
+#undef ASSERT_REG_POSITION
+
+} // namespace Tegra::Engines
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 329079ddd..8afd26fe9 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -248,8 +248,8 @@ void Maxwell3D::DrawArrays() {
void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) {
// Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage.
- auto& shader = state.shader_stages[static_cast<size_t>(stage)];
- auto& bind_data = regs.cb_bind[static_cast<size_t>(stage)];
+ auto& shader = state.shader_stages[static_cast<std::size_t>(stage)];
+ auto& bind_data = regs.cb_bind[static_cast<std::size_t>(stage)];
auto& buffer = shader.const_buffers[bind_data.index];
@@ -316,14 +316,14 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) const {
std::vector<Texture::FullTextureInfo> textures;
- auto& fragment_shader = state.shader_stages[static_cast<size_t>(stage)];
+ auto& fragment_shader = state.shader_stages[static_cast<std::size_t>(stage)];
auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index];
ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0);
GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size;
// Offset into the texture constbuffer where the texture info begins.
- static constexpr size_t TextureInfoOffset = 0x20;
+ static constexpr std::size_t TextureInfoOffset = 0x20;
for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset;
current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) {
@@ -360,8 +360,9 @@ std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderSt
return textures;
}
-Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, size_t offset) const {
- auto& shader = state.shader_stages[static_cast<size_t>(stage)];
+Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage,
+ std::size_t offset) const {
+ auto& shader = state.shader_stages[static_cast<std::size_t>(stage)];
auto& tex_info_buffer = shader.const_buffers[regs.tex_cb_index];
ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0);
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index d3be900a4..b81b0723d 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -34,17 +34,17 @@ public:
/// Register structure of the Maxwell3D engine.
/// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
struct Regs {
- static constexpr size_t NUM_REGS = 0xE00;
-
- static constexpr size_t NumRenderTargets = 8;
- static constexpr size_t NumViewports = 16;
- static constexpr size_t NumCBData = 16;
- static constexpr size_t NumVertexArrays = 32;
- static constexpr size_t NumVertexAttributes = 32;
- static constexpr size_t MaxShaderProgram = 6;
- static constexpr size_t MaxShaderStage = 5;
+ static constexpr std::size_t NUM_REGS = 0xE00;
+
+ static constexpr std::size_t NumRenderTargets = 8;
+ static constexpr std::size_t NumViewports = 16;
+ static constexpr std::size_t NumCBData = 16;
+ static constexpr std::size_t NumVertexArrays = 32;
+ static constexpr std::size_t NumVertexAttributes = 32;
+ static constexpr std::size_t MaxShaderProgram = 6;
+ static constexpr std::size_t MaxShaderStage = 5;
// Maximum number of const buffers per shader stage.
- static constexpr size_t MaxConstBuffers = 18;
+ static constexpr std::size_t MaxConstBuffers = 18;
enum class QueryMode : u32 {
Write = 0,
@@ -443,9 +443,9 @@ public:
}
};
- bool IsShaderConfigEnabled(size_t index) const {
+ bool IsShaderConfigEnabled(std::size_t index) const {
// The VertexB is always enabled.
- if (index == static_cast<size_t>(Regs::ShaderProgram::VertexB)) {
+ if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) {
return true;
}
return shader_config[index].enable != 0;
@@ -571,7 +571,7 @@ public:
BitField<25, 3, u32> map_7;
};
- u32 GetMap(size_t index) const {
+ u32 GetMap(std::size_t index) const {
const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3,
map_4, map_5, map_6, map_7};
ASSERT(index < maps.size());
@@ -925,7 +925,7 @@ public:
std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const;
/// Returns the texture information for a specific texture in a specific shader stage.
- Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const;
+ Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const;
private:
VideoCore::RasterizerInterface& rasterizer;
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index c24d33d5c..aa7481b8c 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -50,7 +50,7 @@ void MaxwellDMA::HandleCopy() {
ASSERT(regs.dst_params.pos_y == 0);
if (regs.exec.is_dst_linear == regs.exec.is_src_linear) {
- size_t copy_size = regs.x_count;
+ std::size_t copy_size = regs.x_count;
// When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D
// buffer of length `x_count`, otherwise we copy a 2D buffer of size (x_count, y_count).
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h
index 7882f16e0..311ccb616 100644
--- a/src/video_core/engines/maxwell_dma.h
+++ b/src/video_core/engines/maxwell_dma.h
@@ -23,7 +23,7 @@ public:
void WriteReg(u32 method, u32 value);
struct Regs {
- static constexpr size_t NUM_REGS = 0x1D6;
+ static constexpr std::size_t NUM_REGS = 0x1D6;
struct Parameters {
union {
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 58f2904ce..6e555ea03 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -20,10 +20,10 @@ namespace Tegra::Shader {
struct Register {
/// Number of registers
- static constexpr size_t NumRegisters = 256;
+ static constexpr std::size_t NumRegisters = 256;
/// Register 255 is special cased to always be 0
- static constexpr size_t ZeroIndex = 255;
+ static constexpr std::size_t ZeroIndex = 255;
enum class Size : u64 {
Byte = 0,
@@ -67,6 +67,13 @@ private:
u64 value{};
};
+enum class AttributeSize : u64 {
+ Word = 0,
+ DoubleWord = 1,
+ TripleWord = 2,
+ QuadWord = 3,
+};
+
union Attribute {
Attribute() = default;
@@ -87,9 +94,10 @@ union Attribute {
};
union {
+ BitField<20, 10, u64> immediate;
BitField<22, 2, u64> element;
BitField<24, 6, Index> index;
- BitField<47, 3, u64> size;
+ BitField<47, 3, AttributeSize> size;
} fmt20;
union {
@@ -584,7 +592,7 @@ union Instruction {
BitField<31, 4, u64> component_mask;
BitField<55, 3, TextureProcessMode> process_mode;
- bool IsComponentEnabled(size_t component) const {
+ bool IsComponentEnabled(std::size_t component) const {
return ((1ull << component) & component_mask) != 0;
}
} tex;
@@ -599,7 +607,7 @@ union Instruction {
BitField<29, 2, TextureType> texture_type;
BitField<31, 4, u64> component_mask;
- bool IsComponentEnabled(size_t component) const {
+ bool IsComponentEnabled(std::size_t component) const {
return ((1ull << component) & component_mask) != 0;
}
} tmml;
@@ -646,7 +654,7 @@ union Instruction {
return gpr28.Value() != Register::ZeroIndex;
}
- bool IsComponentEnabled(size_t component) const {
+ bool IsComponentEnabled(std::size_t component) const {
static constexpr std::array<std::array<u32, 8>, 4> mask_lut{{
{},
{0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc},
@@ -654,7 +662,7 @@ union Instruction {
{0x7, 0xb, 0xd, 0xe, 0xf},
}};
- size_t index{gpr0.Value() != Register::ZeroIndex ? 1U : 0U};
+ std::size_t index{gpr0.Value() != Register::ZeroIndex ? 1U : 0U};
index |= gpr28.Value() != Register::ZeroIndex ? 2 : 0;
u32 mask = mask_lut[index][component_mask_selector];
@@ -939,7 +947,7 @@ public:
private:
struct Detail {
private:
- static constexpr size_t opcode_bitsize = 16;
+ static constexpr std::size_t opcode_bitsize = 16;
/**
* Generates the mask and the expected value after masking from a given bitstring.
@@ -948,8 +956,8 @@ private:
*/
static auto GetMaskAndExpect(const char* const bitstring) {
u16 mask = 0, expect = 0;
- for (size_t i = 0; i < opcode_bitsize; i++) {
- const size_t bit_position = opcode_bitsize - i - 1;
+ for (std::size_t i = 0; i < opcode_bitsize; i++) {
+ const std::size_t bit_position = opcode_bitsize - i - 1;
switch (bitstring[i]) {
case '0':
mask |= 1 << bit_position;