citra-emu
/
citra
Archived
1
0
Fork 0

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.
This commit is contained in:
Yuri Kunde Schlesner 2016-12-18 23:42:29 -08:00
parent d36ec905b1
commit 8ed9f9d49f
2 changed files with 16 additions and 10 deletions

View File

@ -99,7 +99,8 @@ struct Regs {
TEXCOORD1_U = 14,
TEXCOORD1_V = 15,
// TODO: Not verified
TEXCOORD0_W = 16,
VIEW_X = 18,
VIEW_Y = 19,
VIEW_Z = 20,

View File

@ -22,23 +22,28 @@ namespace Shader {
OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer& input) {
// Setup output data
OutputVertex ret;
union {
OutputVertex ret{};
std::array<float24, 24> vertex_slots;
};
static_assert(sizeof(vertex_slots) <= sizeof(ret), "Struct and array have different sizes.");
unsigned int num_attributes = regs.vs_output_total;
ASSERT(num_attributes <= 7);
for (unsigned int i = 0; i < num_attributes; ++i) {
const auto& output_register_map = regs.vs_output_attributes[i];
u32 semantics[4] = {output_register_map.map_x, output_register_map.map_y,
output_register_map.map_z, output_register_map.map_w};
Regs::VSOutputAttributes::Semantic semantics[4] = {
output_register_map.map_x, output_register_map.map_y, output_register_map.map_z,
output_register_map.map_w};
for (unsigned comp = 0; comp < 4; ++comp) {
float24* out = ((float24*)&ret) + semantics[comp];
if (semantics[comp] != Regs::VSOutputAttributes::INVALID) {
Regs::VSOutputAttributes::Semantic semantic = semantics[comp];
float24* out = &vertex_slots[semantic];
if (semantic < vertex_slots.size()) {
*out = input.attr[i][comp];
} else {
// Zero output so that attributes which aren't output won't have denormals in them,
// which would slow us down later.
memset(out, 0, sizeof(*out));
} else if (semantic != Regs::VSOutputAttributes::INVALID) {
LOG_ERROR(HW_GPU, "Invalid/unknown semantic id: %u", (unsigned int)semantic);
}
}
}