summaryrefslogtreecommitdiff
path: root/src/video_core/vertex_loader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/vertex_loader.cpp')
-rw-r--r--src/video_core/vertex_loader.cpp160
1 files changed, 0 insertions, 160 deletions
diff --git a/src/video_core/vertex_loader.cpp b/src/video_core/vertex_loader.cpp
deleted file mode 100644
index 37c5224a9..000000000
--- a/src/video_core/vertex_loader.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
1#include <memory>
2#include <boost/range/algorithm/fill.hpp>
3#include "common/alignment.h"
4#include "common/assert.h"
5#include "common/bit_field.h"
6#include "common/common_types.h"
7#include "common/logging/log.h"
8#include "common/vector_math.h"
9#include "core/memory.h"
10#include "video_core/debug_utils/debug_utils.h"
11#include "video_core/pica_state.h"
12#include "video_core/pica_types.h"
13#include "video_core/regs_pipeline.h"
14#include "video_core/shader/shader.h"
15#include "video_core/vertex_loader.h"
16
17namespace Pica {
18
19void VertexLoader::Setup(const PipelineRegs& regs) {
20 ASSERT_MSG(!is_setup, "VertexLoader is not intended to be setup more than once.");
21
22 const auto& attribute_config = regs.vertex_attributes;
23 num_total_attributes = attribute_config.GetNumTotalAttributes();
24
25 boost::fill(vertex_attribute_sources, 0xdeadbeef);
26
27 for (int i = 0; i < 16; i++) {
28 vertex_attribute_is_default[i] = attribute_config.IsDefaultAttribute(i);
29 }
30
31 // Setup attribute data from loaders
32 for (int loader = 0; loader < 12; ++loader) {
33 const auto& loader_config = attribute_config.attribute_loaders[loader];
34
35 u32 offset = 0;
36
37 // TODO: What happens if a loader overwrites a previous one's data?
38 for (unsigned component = 0; component < loader_config.component_count; ++component) {
39 if (component >= 12) {
40 LOG_ERROR(HW_GPU,
41 "Overflow in the vertex attribute loader %u trying to load component %u",
42 loader, component);
43 continue;
44 }
45
46 u32 attribute_index = loader_config.GetComponent(component);
47 if (attribute_index < 12) {
48 offset = Common::AlignUp(offset,
49 attribute_config.GetElementSizeInBytes(attribute_index));
50 vertex_attribute_sources[attribute_index] = loader_config.data_offset + offset;
51 vertex_attribute_strides[attribute_index] =
52 static_cast<u32>(loader_config.byte_count);
53 vertex_attribute_formats[attribute_index] =
54 attribute_config.GetFormat(attribute_index);
55 vertex_attribute_elements[attribute_index] =
56 attribute_config.GetNumElements(attribute_index);
57 offset += attribute_config.GetStride(attribute_index);
58 } else if (attribute_index < 16) {
59 // Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings,
60 // respectively
61 offset = Common::AlignUp(offset, 4);
62 offset += (attribute_index - 11) * 4;
63 } else {
64 UNREACHABLE(); // This is truly unreachable due to the number of bits for each
65 // component
66 }
67 }
68 }
69
70 is_setup = true;
71}
72
73void VertexLoader::LoadVertex(u32 base_address, int index, int vertex,
74 Shader::AttributeBuffer& input,
75 DebugUtils::MemoryAccessTracker& memory_accesses) {
76 ASSERT_MSG(is_setup, "A VertexLoader needs to be setup before loading vertices.");
77
78 for (int i = 0; i < num_total_attributes; ++i) {
79 if (vertex_attribute_elements[i] != 0) {
80 // Load per-vertex data from the loader arrays
81 u32 source_addr =
82 base_address + vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex;
83
84 if (g_debug_context && Pica::g_debug_context->recorder) {
85 memory_accesses.AddAccess(
86 source_addr,
87 vertex_attribute_elements[i] *
88 ((vertex_attribute_formats[i] == PipelineRegs::VertexAttributeFormat::FLOAT)
89 ? 4
90 : (vertex_attribute_formats[i] ==
91 PipelineRegs::VertexAttributeFormat::SHORT)
92 ? 2
93 : 1));
94 }
95
96 switch (vertex_attribute_formats[i]) {
97 case PipelineRegs::VertexAttributeFormat::BYTE: {
98 const s8* srcdata =
99 reinterpret_cast<const s8*>(Memory::GetPhysicalPointer(source_addr));
100 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
101 input.attr[i][comp] = float24::FromFloat32(srcdata[comp]);
102 }
103 break;
104 }
105 case PipelineRegs::VertexAttributeFormat::UBYTE: {
106 const u8* srcdata =
107 reinterpret_cast<const u8*>(Memory::GetPhysicalPointer(source_addr));
108 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
109 input.attr[i][comp] = float24::FromFloat32(srcdata[comp]);
110 }
111 break;
112 }
113 case PipelineRegs::VertexAttributeFormat::SHORT: {
114 const s16* srcdata =
115 reinterpret_cast<const s16*>(Memory::GetPhysicalPointer(source_addr));
116 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
117 input.attr[i][comp] = float24::FromFloat32(srcdata[comp]);
118 }
119 break;
120 }
121 case PipelineRegs::VertexAttributeFormat::FLOAT: {
122 const float* srcdata =
123 reinterpret_cast<const float*>(Memory::GetPhysicalPointer(source_addr));
124 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
125 input.attr[i][comp] = float24::FromFloat32(srcdata[comp]);
126 }
127 break;
128 }
129 }
130
131 // Default attribute values set if array elements have < 4 components. This
132 // is *not* carried over from the default attribute settings even if they're
133 // enabled for this attribute.
134 for (unsigned int comp = vertex_attribute_elements[i]; comp < 4; ++comp) {
135 input.attr[i][comp] =
136 comp == 3 ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f);
137 }
138
139 LOG_TRACE(HW_GPU, "Loaded %d components of attribute %x for vertex %x (index %x) from "
140 "0x%08x + 0x%08x + 0x%04x: %f %f %f %f",
141 vertex_attribute_elements[i], i, vertex, index, base_address,
142 vertex_attribute_sources[i], vertex_attribute_strides[i] * vertex,
143 input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(),
144 input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32());
145 } else if (vertex_attribute_is_default[i]) {
146 // Load the default attribute if we're configured to do so
147 input.attr[i] = g_state.input_default_attributes.attr[i];
148 LOG_TRACE(HW_GPU,
149 "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", i,
150 vertex, index, input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(),
151 input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32());
152 } else {
153 // TODO(yuriks): In this case, no data gets loaded and the vertex
154 // remains with the last value it had. This isn't currently maintained
155 // as global state, however, and so won't work in Citra yet.
156 }
157 }
158}
159
160} // namespace Pica