summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2014-07-26 16:19:11 +0200
committerGravatar Tony Wasserka2014-08-12 13:47:31 +0200
commitd443f0a92183c94eaa0c33dddbb450eb8fe2fd07 (patch)
tree6d7f1d0a00d63ea1a60e0d77df0b8bd533e53cfd /src
parentPica: Add register definition for vertex loading and rendering. (diff)
downloadyuzu-d443f0a92183c94eaa0c33dddbb450eb8fe2fd07.tar.gz
yuzu-d443f0a92183c94eaa0c33dddbb450eb8fe2fd07.tar.xz
yuzu-d443f0a92183c94eaa0c33dddbb450eb8fe2fd07.zip
Pica: Implement vertex loading.
Diffstat (limited to '')
-rw-r--r--src/video_core/command_processor.cpp81
-rw-r--r--src/video_core/pica.h29
2 files changed, 102 insertions, 8 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 515c407ea..e909c8c32 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -4,6 +4,7 @@
4 4
5#include "pica.h" 5#include "pica.h"
6#include "command_processor.h" 6#include "command_processor.h"
7#include "math.h"
7 8
8 9
9namespace Pica { 10namespace Pica {
@@ -17,7 +18,85 @@ static inline void WritePicaReg(u32 id, u32 value) {
17 registers[id] = value; 18 registers[id] = value;
18 19
19 switch(id) { 20 switch(id) {
20 // TODO: Perform actions for anything which requires special treatment here... 21 // It seems like these trigger vertex rendering
22 case PICA_REG_INDEX(trigger_draw):
23 case PICA_REG_INDEX(trigger_draw_indexed):
24 {
25 const auto& attribute_config = registers.vertex_attributes;
26 const u8* const base_address = Memory::GetPointer(attribute_config.GetBaseAddress());
27
28 // Information about internal vertex attributes
29 const u8* vertex_attribute_sources[16];
30 u32 vertex_attribute_strides[16];
31 u32 vertex_attribute_formats[16];
32 u32 vertex_attribute_elements[16];
33 u32 vertex_attribute_element_size[16];
34
35 // Setup attribute data from loaders
36 for (int loader = 0; loader < 12; ++loader) {
37 const auto& loader_config = attribute_config.attribute_loaders[loader];
38
39 const u8* load_address = base_address + loader_config.data_offset;
40
41 // TODO: What happens if a loader overwrites a previous one's data?
42 for (int component = 0; component < loader_config.component_count; ++component) {
43 u32 attribute_index = loader_config.GetComponent(component);
44 vertex_attribute_sources[attribute_index] = load_address;
45 vertex_attribute_strides[attribute_index] = loader_config.byte_count;
46 vertex_attribute_formats[attribute_index] = (u32)attribute_config.GetFormat(attribute_index);
47 vertex_attribute_elements[attribute_index] = attribute_config.GetNumElements(attribute_index);
48 vertex_attribute_element_size[attribute_index] = attribute_config.GetElementSizeInBytes(attribute_index);
49 load_address += attribute_config.GetStride(attribute_index);
50 }
51 }
52
53 // Load vertices
54 bool is_indexed = (id == PICA_REG_INDEX(trigger_draw_indexed));
55
56 const auto& index_info = registers.index_array;
57 const u8* index_address_8 = (u8*)base_address + index_info.offset;
58 const u16* index_address_16 = (u16*)index_address_8;
59 bool index_u16 = (bool)index_info.format;
60
61 for (int index = 0; index < registers.num_vertices; ++index)
62 {
63 int vertex = is_indexed ? (index_u16 ? index_address_16[index] : index_address_8[index]) : index;
64
65 if (is_indexed) {
66 // TODO: Implement some sort of vertex cache!
67 }
68
69 // Initialize data for the current vertex
70 struct {
71 Math::Vec4<float24> attr[16];
72 } input;
73
74 for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) {
75 for (int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
76 const u8* srcdata = vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i];
77 const float srcval = (vertex_attribute_formats[i] == 0) ? *(s8*)srcdata :
78 (vertex_attribute_formats[i] == 1) ? *(u8*)srcdata :
79 (vertex_attribute_formats[i] == 2) ? *(s16*)srcdata :
80 *(float*)srcdata;
81 input.attr[i][comp] = float24::FromFloat32(srcval);
82 DEBUG_LOG(GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08x + 0x%04x: %f",
83 comp, i, vertex, index,
84 attribute_config.GetBaseAddress(),
85 vertex_attribute_sources[i] - base_address,
86 srcdata - vertex_attribute_sources[i],
87 input.attr[i][comp].ToFloat32());
88 }
89 }
90 // TODO: Run vertex data through vertex shader
91
92 if (is_indexed) {
93 // TODO: Add processed vertex to vertex cache!
94 }
95
96 // TODO: Submit vertex to primitive assembly
97 }
98 break;
99 }
21 100
22 default: 101 default:
23 break; 102 break;
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 5bd7f416e..faf124c3d 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -64,7 +64,7 @@ struct Regs {
64 64
65 inline u32 GetBaseAddress() const { 65 inline u32 GetBaseAddress() const {
66 // TODO: Ugly, should fix PhysicalToVirtualAddress instead 66 // TODO: Ugly, should fix PhysicalToVirtualAddress instead
67 return (base_address * 8) - Memory::FCRAM_PADDR + Memory::HEAP_GSP_VADDR; 67 return DecodeAddressRegister(base_address) - Memory::FCRAM_PADDR + Memory::HEAP_GSP_VADDR;
68 } 68 }
69 69
70 // Descriptor for internal vertex attributes 70 // Descriptor for internal vertex attributes
@@ -110,12 +110,12 @@ struct Regs {
110 } 110 }
111 111
112 inline int GetNumElements(int n) const { 112 inline int GetNumElements(int n) const {
113 int sizes[] = { 113 u64 sizes[] = {
114 size0, size1, size2, size3, 114 size0, size1, size2, size3,
115 size4, size5, size6, size7, 115 size4, size5, size6, size7,
116 size8, size9, size10, size11 116 size8, size9, size10, size11
117 }; 117 };
118 return sizes[n]+1; 118 return (int)sizes[n]+1;
119 } 119 }
120 120
121 inline int GetElementSizeInBytes(int n) const { 121 inline int GetElementSizeInBytes(int n) const {
@@ -128,7 +128,7 @@ struct Regs {
128 } 128 }
129 129
130 inline int GetNumTotalAttributes() const { 130 inline int GetNumTotalAttributes() const {
131 return num_extra_attributes+1; 131 return (int)num_extra_attributes+1;
132 } 132 }
133 133
134 // Attribute loaders map the source vertex data to input attributes 134 // Attribute loaders map the source vertex data to input attributes
@@ -158,12 +158,12 @@ struct Regs {
158 }; 158 };
159 159
160 inline int GetComponent(int n) const { 160 inline int GetComponent(int n) const {
161 int components[] = { 161 u64 components[] = {
162 comp0, comp1, comp2, comp3, 162 comp0, comp1, comp2, comp3,
163 comp4, comp5, comp6, comp7, 163 comp4, comp5, comp6, comp7,
164 comp8, comp9, comp10, comp11 164 comp8, comp9, comp10, comp11
165 }; 165 };
166 return components[n]; 166 return (int)components[n];
167 } 167 }
168 } attribute_loaders[12]; 168 } attribute_loaders[12];
169 } vertex_attributes; 169 } vertex_attributes;
@@ -180,7 +180,16 @@ struct Regs {
180 }; 180 };
181 } index_array; 181 } index_array;
182 182
183 INSERT_PADDING_WORDS(0xd8); 183 // Number of vertices to render
184 u32 num_vertices;
185
186 INSERT_PADDING_WORDS(0x5);
187
188 // These two trigger rendering of triangles
189 u32 trigger_draw;
190 u32 trigger_draw_indexed;
191
192 INSERT_PADDING_WORDS(0xd0);
184 193
185#undef INSERT_PADDING_WORDS_HELPER1 194#undef INSERT_PADDING_WORDS_HELPER1
186#undef INSERT_PADDING_WORDS_HELPER2 195#undef INSERT_PADDING_WORDS_HELPER2
@@ -207,6 +216,9 @@ struct Regs {
207 ADD_FIELD(viewport_size_y); 216 ADD_FIELD(viewport_size_y);
208 ADD_FIELD(vertex_attributes); 217 ADD_FIELD(vertex_attributes);
209 ADD_FIELD(index_array); 218 ADD_FIELD(index_array);
219 ADD_FIELD(num_vertices);
220 ADD_FIELD(trigger_draw);
221 ADD_FIELD(trigger_draw_indexed);
210 222
211 #undef ADD_FIELD 223 #undef ADD_FIELD
212 #endif // _MSC_VER 224 #endif // _MSC_VER
@@ -249,6 +261,9 @@ ASSERT_REG_POSITION(viewport_size_x, 0x41);
249ASSERT_REG_POSITION(viewport_size_y, 0x43); 261ASSERT_REG_POSITION(viewport_size_y, 0x43);
250ASSERT_REG_POSITION(vertex_attributes, 0x200); 262ASSERT_REG_POSITION(vertex_attributes, 0x200);
251ASSERT_REG_POSITION(index_array, 0x227); 263ASSERT_REG_POSITION(index_array, 0x227);
264ASSERT_REG_POSITION(num_vertices, 0x228);
265ASSERT_REG_POSITION(trigger_draw, 0x22e);
266ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f);
252 267
253#undef ASSERT_REG_POSITION 268#undef ASSERT_REG_POSITION
254#endif // !defined(_MSC_VER) 269#endif // !defined(_MSC_VER)