diff options
| author | 2016-12-18 23:42:29 -0800 | |
|---|---|---|
| committer | 2017-01-29 21:31:38 -0800 | |
| commit | 8ed9f9d49f716487f14736c48a7850129a5910ba (patch) | |
| tree | 6726dd4b1a8618a7bd76b3d8fac7069ac65ca410 /src/video_core | |
| parent | Common: Optimize BitSet iterator (diff) | |
| download | yuzu-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.h | 3 | ||||
| -rw-r--r-- | src/video_core/shader/shader.cpp | 23 |
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 | ||
| 23 | OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer& input) { | 23 | OutputVertex 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 | } |