mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Clipper: Compact buffers on each clipping pass
Use a new buffer management scheme in the clipper that allows using a bounded minimal amount of buffer space. Even though it copies more data it is still slightly faster likely due to using less cache.
This commit is contained in:
		
							parent
							
								
									da04976437
								
							
						
					
					
						commit
						7e9bc85cc8
					
				
					 1 changed files with 27 additions and 28 deletions
				
			
		|  | @ -100,13 +100,15 @@ static void InitScreenCoordinates(OutputVertex& vtx) | |||
| void ProcessTriangle(OutputVertex &v0, OutputVertex &v1, OutputVertex &v2) { | ||||
|     using boost::container::static_vector; | ||||
| 
 | ||||
|     // TODO (neobrain):
 | ||||
|     // The list of output vertices has some fixed maximum size,
 | ||||
|     // however I haven't taken the time to figure out what it is exactly.
 | ||||
|     // For now, we hence just assume a maximal size of 256 vertices.
 | ||||
|     static const size_t MAX_VERTICES = 256; | ||||
|     static_vector<OutputVertex, MAX_VERTICES> buffer_vertices; | ||||
|     static_vector<OutputVertex*, MAX_VERTICES> output_list = { &v0, &v1, &v2 }; | ||||
|     // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at
 | ||||
|     // the new edge (or less in degenerate cases). As such, we can say that each clipping plane
 | ||||
|     // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a
 | ||||
|     // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9.
 | ||||
|     static const size_t MAX_VERTICES = 9; | ||||
|     static_vector<OutputVertex, MAX_VERTICES> buffer_a = { v0, v1, v2 }; | ||||
|     static_vector<OutputVertex, MAX_VERTICES> buffer_b; | ||||
|     auto* output_list = &buffer_a; | ||||
|     auto* input_list  = &buffer_b; | ||||
| 
 | ||||
|     // Simple implementation of the Sutherland-Hodgman clipping algorithm.
 | ||||
|     // TODO: Make this less inefficient (currently lots of useless buffering overhead happens here)
 | ||||
|  | @ -117,48 +119,45 @@ void ProcessTriangle(OutputVertex &v0, OutputVertex &v1, OutputVertex &v2) { | |||
|                        ClippingEdge(ClippingEdge::POS_Z, float24::FromFloat32(+1.0)), | ||||
|                        ClippingEdge(ClippingEdge::NEG_Z, float24::FromFloat32(-1.0)) }) { | ||||
| 
 | ||||
|         const static_vector<OutputVertex*, MAX_VERTICES> input_list = output_list; | ||||
|         output_list.clear(); | ||||
|         std::swap(input_list, output_list); | ||||
|         output_list->clear(); | ||||
| 
 | ||||
|         const OutputVertex* reference_vertex = input_list.back(); | ||||
|         const OutputVertex* reference_vertex = &input_list->back(); | ||||
| 
 | ||||
|         for (const auto& vertex : input_list) { | ||||
|         for (const auto& vertex : *input_list) { | ||||
|             // NOTE: This algorithm changes vertex order in some cases!
 | ||||
|             if (edge.IsInside(*vertex)) { | ||||
|             if (edge.IsInside(vertex)) { | ||||
|                 if (edge.IsOutSide(*reference_vertex)) { | ||||
|                     buffer_vertices.push_back(edge.GetIntersection(*vertex, *reference_vertex)); | ||||
|                     output_list.push_back(&(buffer_vertices.back())); | ||||
|                     output_list->push_back(edge.GetIntersection(vertex, *reference_vertex)); | ||||
|                 } | ||||
| 
 | ||||
|                 output_list.push_back(vertex); | ||||
|                 output_list->push_back(vertex); | ||||
|             } else if (edge.IsInside(*reference_vertex)) { | ||||
|                 buffer_vertices.push_back(edge.GetIntersection(*vertex, *reference_vertex)); | ||||
|                 output_list.push_back(&(buffer_vertices.back())); | ||||
|                 output_list->push_back(edge.GetIntersection(vertex, *reference_vertex)); | ||||
|             } | ||||
| 
 | ||||
|             reference_vertex = vertex; | ||||
|             reference_vertex = &vertex; | ||||
|         } | ||||
| 
 | ||||
|         // Need to have at least a full triangle to continue...
 | ||||
|         if (output_list.size() < 3) | ||||
|         if (output_list->size() < 3) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     InitScreenCoordinates(*(output_list[0])); | ||||
|     InitScreenCoordinates(*(output_list[1])); | ||||
|     InitScreenCoordinates((*output_list)[0]); | ||||
|     InitScreenCoordinates((*output_list)[1]); | ||||
| 
 | ||||
|     for (size_t i = 0; i < output_list.size() - 2; i ++) { | ||||
|         OutputVertex& vtx0 = *(output_list[0]); | ||||
|         OutputVertex& vtx1 = *(output_list[i+1]); | ||||
|         OutputVertex& vtx2 = *(output_list[i+2]); | ||||
|     for (size_t i = 0; i < output_list->size() - 2; i ++) { | ||||
|         OutputVertex& vtx0 = (*output_list)[0]; | ||||
|         OutputVertex& vtx1 = (*output_list)[i+1]; | ||||
|         OutputVertex& vtx2 = (*output_list)[i+2]; | ||||
| 
 | ||||
|         InitScreenCoordinates(vtx2); | ||||
| 
 | ||||
|         LOG_TRACE(Render_Software, | ||||
|                   "Triangle %lu/%lu (%lu buffer vertices) at position (%.3f, %.3f, %.3f, %.3f), " | ||||
|                   "Triangle %lu/%lu at position (%.3f, %.3f, %.3f, %.3f), " | ||||
|                   "(%.3f, %.3f, %.3f, %.3f), (%.3f, %.3f, %.3f, %.3f) and " | ||||
|                   "screen position (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f)", | ||||
|                   i,output_list.size(), buffer_vertices.size(), | ||||
|                   i, output_list->size(), | ||||
|                   vtx0.pos.x.ToFloat32(), vtx0.pos.y.ToFloat32(), vtx0.pos.z.ToFloat32(), vtx0.pos.w.ToFloat32(), | ||||
|                   vtx1.pos.x.ToFloat32(), vtx1.pos.y.ToFloat32(), vtx1.pos.z.ToFloat32(), vtx1.pos.w.ToFloat32(), | ||||
|                   vtx2.pos.x.ToFloat32(), vtx2.pos.y.ToFloat32(), vtx2.pos.z.ToFloat32(), vtx2.pos.w.ToFloat32(), | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue