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