diff --git a/rpcs3/Emu/RSX/Core/RSXVertexTypes.h b/rpcs3/Emu/RSX/Core/RSXVertexTypes.h index 21f1770487..51cad0a4b4 100644 --- a/rpcs3/Emu/RSX/Core/RSXVertexTypes.h +++ b/rpcs3/Emu/RSX/Core/RSXVertexTypes.h @@ -86,6 +86,7 @@ namespace rsx rsx::simple_array interleaved_blocks{}; // Interleaved blocks to be uploaded as-is std::vector> volatile_blocks{}; // Volatile data blocks (immediate draw vertex data for example) rsx::simple_array referenced_registers{}; // Volatile register data + u16 attribute_mask = 0; // ATTRn mask std::array attribute_placement = fill_array(attribute_buffer_placement::none); @@ -108,6 +109,7 @@ namespace rsx void clear() { m_num_used_blocks = 0; + attribute_mask = 0; interleaved_blocks.clear(); volatile_blocks.clear(); referenced_registers.clear(); @@ -117,15 +119,20 @@ namespace rsx { // Criteria: At least one array stream has to be defined to feed vertex positions // This stream cannot be a const register as the vertices cannot create a zero-area primitive - if (!interleaved_blocks.empty() && interleaved_blocks[0]->attribute_stride != 0) return true; if (!volatile_blocks.empty()) return true; - for (u8 index = 0; index < limits::vertex_count; ++index) + for (u16 ref_mask = attribute_mask, index = 0; ref_mask; ++index, ref_mask >>= 1) { + if (!(ref_mask & 1)) + { + // Disabled + continue; + } + switch (attribute_placement[index]) { case attribute_buffer_placement::transient: diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 3b6a227802..2df6e0cb60 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2210,6 +2210,7 @@ namespace rsx const u32 input_mask = state.vertex_attrib_input_mask() & current_vp_metadata.referenced_inputs_mask; result.clear(); + result.attribute_mask = static_cast(input_mask); if (state.current_draw_clause.command == rsx::draw_command::inlined_array) { @@ -2219,6 +2220,7 @@ namespace rsx for (u8 index = 0; index < rsx::limits::vertex_count; ++index) { auto &vinfo = state.vertex_arrays_info[index]; + result.attribute_placement[index] = attribute_buffer_placement::none; if (vinfo.size() > 0) { @@ -2233,7 +2235,7 @@ namespace rsx } else if (state.register_vertex_info[index].size > 0 && input_mask & (1u << index)) { - //Reads from register + // Reads from register result.referenced_registers.push_back(index); result.attribute_placement[index] = attribute_buffer_placement::transient; } @@ -2262,8 +2264,10 @@ namespace rsx continue; } - //Check for interleaving - const auto &info = state.vertex_arrays_info[index]; + // Always reset attribute placement by default + result.attribute_placement[index] = attribute_buffer_placement::none; + + // Check for interleaving if (rsx::method_registers.current_draw_clause.is_immediate_draw && rsx::method_registers.current_draw_clause.command != rsx::draw_command::indexed) { @@ -2290,6 +2294,7 @@ namespace rsx continue; } + const auto& info = state.vertex_arrays_info[index]; if (!info.size()) { if (state.register_vertex_info[index].size > 0)