mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +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
					
				
					 2 changed files with 16 additions and 10 deletions
				
			
		|  | @ -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, | ||||
|  |  | |||
|  | @ -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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue