mirror of
https://github.com/citra-emu/citra-nightly.git
synced 2024-12-26 15:45:29 +00:00
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:
parent
d36ec905b1
commit
8ed9f9d49f
|
@ -99,7 +99,8 @@ struct Regs {
|
||||||
TEXCOORD1_U = 14,
|
TEXCOORD1_U = 14,
|
||||||
TEXCOORD1_V = 15,
|
TEXCOORD1_V = 15,
|
||||||
|
|
||||||
// TODO: Not verified
|
TEXCOORD0_W = 16,
|
||||||
|
|
||||||
VIEW_X = 18,
|
VIEW_X = 18,
|
||||||
VIEW_Y = 19,
|
VIEW_Y = 19,
|
||||||
VIEW_Z = 20,
|
VIEW_Z = 20,
|
||||||
|
|
|
@ -22,23 +22,28 @@ namespace Shader {
|
||||||
|
|
||||||
OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer& input) {
|
OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer& input) {
|
||||||
// Setup output data
|
// 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;
|
unsigned int num_attributes = regs.vs_output_total;
|
||||||
|
ASSERT(num_attributes <= 7);
|
||||||
for (unsigned int i = 0; i < num_attributes; ++i) {
|
for (unsigned int i = 0; i < num_attributes; ++i) {
|
||||||
const auto& output_register_map = regs.vs_output_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,
|
Regs::VSOutputAttributes::Semantic semantics[4] = {
|
||||||
output_register_map.map_z, output_register_map.map_w};
|
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) {
|
for (unsigned comp = 0; comp < 4; ++comp) {
|
||||||
float24* out = ((float24*)&ret) + semantics[comp];
|
Regs::VSOutputAttributes::Semantic semantic = semantics[comp];
|
||||||
if (semantics[comp] != Regs::VSOutputAttributes::INVALID) {
|
float24* out = &vertex_slots[semantic];
|
||||||
|
if (semantic < vertex_slots.size()) {
|
||||||
*out = input.attr[i][comp];
|
*out = input.attr[i][comp];
|
||||||
} else {
|
} else if (semantic != Regs::VSOutputAttributes::INVALID) {
|
||||||
// Zero output so that attributes which aren't output won't have denormals in them,
|
LOG_ERROR(HW_GPU, "Invalid/unknown semantic id: %u", (unsigned int)semantic);
|
||||||
// which would slow us down later.
|
|
||||||
memset(out, 0, sizeof(*out));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue