summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2016-12-18 23:42:29 -0800
committerGravatar Yuri Kunde Schlesner2017-01-29 21:31:38 -0800
commit8ed9f9d49f716487f14736c48a7850129a5910ba (patch)
tree6726dd4b1a8618a7bd76b3d8fac7069ac65ca410 /src/video_core
parentCommon: Optimize BitSet iterator (diff)
downloadyuzu-8ed9f9d49f716487f14736c48a7850129a5910ba.tar.gz
yuzu-8ed9f9d49f716487f14736c48a7850129a5910ba.tar.xz
yuzu-8ed9f9d49f716487f14736c48a7850129a5910ba.zip
VideoCore/Shader: Clean up OutputVertex::FromAttributeBuffer
This also fixes a long-standing but neverthless harmless memory corruption bug, whech the padding of the OutputVertex struct would get corrupted by unused attributes.
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/pica.h3
-rw-r--r--src/video_core/shader/shader.cpp23
2 files changed, 16 insertions, 10 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index ac81a3d0f..e326f7727 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -99,7 +99,8 @@ struct Regs {
99 TEXCOORD1_U = 14, 99 TEXCOORD1_U = 14,
100 TEXCOORD1_V = 15, 100 TEXCOORD1_V = 15,
101 101
102 // TODO: Not verified 102 TEXCOORD0_W = 16,
103
103 VIEW_X = 18, 104 VIEW_X = 18,
104 VIEW_Y = 19, 105 VIEW_Y = 19,
105 VIEW_Z = 20, 106 VIEW_Z = 20,
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 99a22c2dd..2c6e45ac4 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -22,23 +22,28 @@ namespace Shader {
22 22
23OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer& input) { 23OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer& input) {
24 // Setup output data 24 // Setup output data
25 OutputVertex ret; 25 union {
26 OutputVertex ret{};
27 std::array<float24, 24> vertex_slots;
28 };
29 static_assert(sizeof(vertex_slots) <= sizeof(ret), "Struct and array have different sizes.");
26 30
27 unsigned int num_attributes = regs.vs_output_total; 31 unsigned int num_attributes = regs.vs_output_total;
32 ASSERT(num_attributes <= 7);
28 for (unsigned int i = 0; i < num_attributes; ++i) { 33 for (unsigned int i = 0; i < num_attributes; ++i) {
29 const auto& output_register_map = regs.vs_output_attributes[i]; 34 const auto& output_register_map = regs.vs_output_attributes[i];
30 35
31 u32 semantics[4] = {output_register_map.map_x, output_register_map.map_y, 36 Regs::VSOutputAttributes::Semantic semantics[4] = {
32 output_register_map.map_z, output_register_map.map_w}; 37 output_register_map.map_x, output_register_map.map_y, output_register_map.map_z,
38 output_register_map.map_w};
33 39
34 for (unsigned comp = 0; comp < 4; ++comp) { 40 for (unsigned comp = 0; comp < 4; ++comp) {
35 float24* out = ((float24*)&ret) + semantics[comp]; 41 Regs::VSOutputAttributes::Semantic semantic = semantics[comp];
36 if (semantics[comp] != Regs::VSOutputAttributes::INVALID) { 42 float24* out = &vertex_slots[semantic];
43 if (semantic < vertex_slots.size()) {
37 *out = input.attr[i][comp]; 44 *out = input.attr[i][comp];
38 } else { 45 } else if (semantic != Regs::VSOutputAttributes::INVALID) {
39 // Zero output so that attributes which aren't output won't have denormals in them, 46 LOG_ERROR(HW_GPU, "Invalid/unknown semantic id: %u", (unsigned int)semantic);
40 // which would slow us down later.
41 memset(out, 0, sizeof(*out));
42 } 47 }
43 } 48 }
44 } 49 }