mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #1015 from yuriks/vertex-caching
Videocore: Implement simple vertex caching
This commit is contained in:
		
						commit
						bd6131bdc0
					
				
					 1 changed files with 90 additions and 63 deletions
				
			
		|  | @ -206,18 +206,42 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
|                 std::map<u32, u32> ranges; | ||||
|             } memory_accesses; | ||||
| 
 | ||||
|             // Simple circular-replacement vertex cache
 | ||||
|             // The size has been tuned for optimal balance between hit-rate and the cost of lookup
 | ||||
|             const size_t VERTEX_CACHE_SIZE = 32; | ||||
|             std::array<u16, VERTEX_CACHE_SIZE> vertex_cache_ids; | ||||
|             std::array<VertexShader::OutputVertex, VERTEX_CACHE_SIZE> vertex_cache; | ||||
| 
 | ||||
|             unsigned int vertex_cache_pos = 0; | ||||
|             vertex_cache_ids.fill(-1); | ||||
| 
 | ||||
|             for (unsigned int index = 0; index < regs.num_vertices; ++index) | ||||
|             { | ||||
|                 unsigned int vertex = is_indexed ? (index_u16 ? index_address_16[index] : index_address_8[index]) : index; | ||||
| 
 | ||||
|                 // -1 is a common special value used for primitive restart. Since it's unknown if
 | ||||
|                 // the PICA supports it, and it would mess up the caching, guard against it here.
 | ||||
|                 ASSERT(vertex != -1); | ||||
| 
 | ||||
|                 bool vertex_cache_hit = false; | ||||
|                 VertexShader::OutputVertex output; | ||||
| 
 | ||||
|                 if (is_indexed) { | ||||
|                     // TODO: Implement some sort of vertex cache!
 | ||||
|                     if (g_debug_context && Pica::g_debug_context->recorder) { | ||||
|                         int size = index_u16 ? 2 : 1; | ||||
|                         memory_accesses.AddAccess(base_address + index_info.offset + size * index, size); | ||||
|                     } | ||||
| 
 | ||||
|                     for (unsigned int i = 0; i < VERTEX_CACHE_SIZE; ++i) { | ||||
|                         if (vertex == vertex_cache_ids[i]) { | ||||
|                             output = vertex_cache[i]; | ||||
|                             vertex_cache_hit = true; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (!vertex_cache_hit) { | ||||
|                     // Initialize data for the current vertex
 | ||||
|                     VertexShader::InputVertex input; | ||||
| 
 | ||||
|  | @ -262,9 +286,9 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
|                                       input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), | ||||
|                                       input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); | ||||
|                         } else { | ||||
|                         // TODO(yuriks): In this case, no data gets loaded and the vertex remains
 | ||||
|                         //              with the last value it had. This isn't currently maintained
 | ||||
|                         //              as global state, however, and so won't work in Cita yet.
 | ||||
|                             // TODO(yuriks): In this case, no data gets loaded and the vertex
 | ||||
|                             // remains with the last value it had. This isn't currently maintained
 | ||||
|                             // as global state, however, and so won't work in Citra yet.
 | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|  | @ -284,10 +308,13 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| #endif | ||||
| 
 | ||||
|                     // Send to vertex shader
 | ||||
|                 VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes(), g_state.regs.vs, g_state.vs); | ||||
|                     output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes(), g_state.regs.vs, g_state.vs); | ||||
| 
 | ||||
|                     if (is_indexed) { | ||||
|                     // TODO: Add processed vertex to vertex cache!
 | ||||
|                         vertex_cache[vertex_cache_pos] = output; | ||||
|                         vertex_cache_ids[vertex_cache_pos] = vertex; | ||||
|                         vertex_cache_pos = (vertex_cache_pos + 1) % VERTEX_CACHE_SIZE; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (Settings::values.use_hw_renderer) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue