mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	video_core/command_processor: attempt accelerate draw in draw trigger
This commit is contained in:
		
							parent
							
								
									9b448a0739
								
							
						
					
					
						commit
						ede0d15fec
					
				
					 2 changed files with 34 additions and 6 deletions
				
			
		|  | @ -286,6 +286,38 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|         if (g_debug_context) |         if (g_debug_context) | ||||||
|             g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); |             g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); | ||||||
| 
 | 
 | ||||||
|  |         PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler; | ||||||
|  | 
 | ||||||
|  |         bool accelerate_draw = VideoCore::g_hw_shader_enabled && primitive_assembler.IsEmpty(); | ||||||
|  | 
 | ||||||
|  |         if (regs.pipeline.use_gs == PipelineRegs::UseGS::No) { | ||||||
|  |             auto topology = primitive_assembler.GetTopology(); | ||||||
|  |             if (topology == PipelineRegs::TriangleTopology::Shader || | ||||||
|  |                 topology == PipelineRegs::TriangleTopology::List) { | ||||||
|  |                 accelerate_draw = accelerate_draw && (regs.pipeline.num_vertices % 3) == 0; | ||||||
|  |             } | ||||||
|  |             // TODO (wwylele): for Strip/Fan topology, if the primitive assember is not restarted
 | ||||||
|  |             // after this draw call, the buffered vertex from this draw should "leak" to the next
 | ||||||
|  |             // draw, in which case we should buffer the vertex into the software primitive assember,
 | ||||||
|  |             // or disable accelerate draw completely. However, there is not game found yet that does
 | ||||||
|  |             // this, so this is left unimplemented for now. Revisit this when an issue is found in
 | ||||||
|  |             // games.
 | ||||||
|  |         } else { | ||||||
|  |             if (VideoCore::g_hw_shader_accurate_gs) { | ||||||
|  |                 accelerate_draw = false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         bool is_indexed = (id == PICA_REG_INDEX(pipeline.trigger_draw_indexed)); | ||||||
|  | 
 | ||||||
|  |         if (accelerate_draw && | ||||||
|  |             VideoCore::g_renderer->Rasterizer()->AccelerateDrawBatch(is_indexed)) { | ||||||
|  |             if (g_debug_context) { | ||||||
|  |                 g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         // Processes information about internal vertex attributes to figure out how a vertex is
 |         // Processes information about internal vertex attributes to figure out how a vertex is
 | ||||||
|         // loaded.
 |         // loaded.
 | ||||||
|         // Later, these can be compiled and cached.
 |         // Later, these can be compiled and cached.
 | ||||||
|  | @ -294,15 +326,11 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|         Shader::OutputVertex::ValidateSemantics(regs.rasterizer); |         Shader::OutputVertex::ValidateSemantics(regs.rasterizer); | ||||||
| 
 | 
 | ||||||
|         // Load vertices
 |         // Load vertices
 | ||||||
|         bool is_indexed = (id == PICA_REG_INDEX(pipeline.trigger_draw_indexed)); |  | ||||||
| 
 |  | ||||||
|         const auto& index_info = regs.pipeline.index_array; |         const auto& index_info = regs.pipeline.index_array; | ||||||
|         const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset); |         const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset); | ||||||
|         const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8); |         const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8); | ||||||
|         bool index_u16 = index_info.format != 0; |         bool index_u16 = index_info.format != 0; | ||||||
| 
 | 
 | ||||||
|         PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler; |  | ||||||
| 
 |  | ||||||
|         if (g_debug_context && g_debug_context->recorder) { |         if (g_debug_context && g_debug_context->recorder) { | ||||||
|             for (int i = 0; i < 3; ++i) { |             for (int i = 0; i < 3; ++i) { | ||||||
|                 const auto texture = regs.texturing.GetTextures()[i]; |                 const auto texture = regs.texturing.GetTextures()[i]; | ||||||
|  |  | ||||||
|  | @ -46,12 +46,12 @@ struct PrimitiveAssembler { | ||||||
|     void Reconfigure(PipelineRegs::TriangleTopology topology); |     void Reconfigure(PipelineRegs::TriangleTopology topology); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Is our internal state empty? |      * Returns whether the PrimitiveAssembler has an empty internal buffer. | ||||||
|      */ |      */ | ||||||
|     bool IsEmpty() const; |     bool IsEmpty() const; | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * What is our triangle topology? |      * Returns the current topology. | ||||||
|      */ |      */ | ||||||
|     PipelineRegs::TriangleTopology GetTopology() const; |     PipelineRegs::TriangleTopology GetTopology() const; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue