mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	GPU: Added a function to retrieve the active textures for a shader stage.
TODO: A shader may not use all of these textures at the same time, shader analysis should be performed to determine which textures are actually sampled.
This commit is contained in:
		
							parent
							
								
									39e60cfeb1
								
							
						
					
					
						commit
						2c785bd06c
					
				| @ -174,53 +174,13 @@ void Maxwell3D::ProcessQueryGet() { | ||||
| void Maxwell3D::DrawArrays() { | ||||
|     LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring"); | ||||
|     if (Tegra::g_debug_context) { | ||||
|         Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, nullptr); | ||||
|     } | ||||
| 
 | ||||
|     auto& fragment_shader = state.shader_stages[static_cast<size_t>(Regs::ShaderStage::Fragment)]; | ||||
|     auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; | ||||
|     ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); | ||||
| 
 | ||||
|     GPUVAddr tic_base_address = regs.tic.TICAddress(); | ||||
| 
 | ||||
|     GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; | ||||
| 
 | ||||
|     for (GPUVAddr current_texture = tex_info_buffer.address + 0x20; | ||||
|          current_texture < tex_info_buffer_end; current_texture += 4) { | ||||
| 
 | ||||
|         Texture::TextureHandle tex_info{ | ||||
|             Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; | ||||
| 
 | ||||
|         if (tex_info.tic_id != 0 || tex_info.tsc_id != 0) { | ||||
|             GPUVAddr tic_address_gpu = | ||||
|                 tic_base_address + tex_info.tic_id * sizeof(Texture::TICEntry); | ||||
|             VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); | ||||
| 
 | ||||
|             Texture::TICEntry tic_entry; | ||||
|             Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); | ||||
| 
 | ||||
|             auto r_type = tic_entry.r_type.Value(); | ||||
|             auto g_type = tic_entry.g_type.Value(); | ||||
|             auto b_type = tic_entry.b_type.Value(); | ||||
|             auto a_type = tic_entry.a_type.Value(); | ||||
| 
 | ||||
|             // TODO(Subv): Different data types for separate components are not supported
 | ||||
|             ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); | ||||
| 
 | ||||
|             auto format = tic_entry.format.Value(); | ||||
| 
 | ||||
|             auto texture = Texture::UnswizzleTexture( | ||||
|                 memory_manager.PhysicalToVirtualAddress(tic_entry.Address()), | ||||
|                 tic_entry.format.Value(), tic_entry.Width(), tic_entry.Height()); | ||||
| 
 | ||||
|             LOG_CRITICAL(HW_GPU, | ||||
|                          "Fragment shader using texture TIC %08X TSC %08X at address %016" PRIX64, | ||||
|                          tex_info.tic_id.Value(), tex_info.tsc_id.Value(), tic_entry.Address()); | ||||
|         } | ||||
|         Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, | ||||
|                                         nullptr); | ||||
|     } | ||||
| 
 | ||||
|     if (Tegra::g_debug_context) { | ||||
|         Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); | ||||
|         Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, | ||||
|                                         nullptr); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -332,5 +292,50 @@ void Maxwell3D::ProcessCBData(u32 value) { | ||||
|     regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; | ||||
| } | ||||
| 
 | ||||
| std::vector<Texture::TICEntry> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) { | ||||
|     std::vector<Texture::TICEntry> textures; | ||||
| 
 | ||||
|     auto& fragment_shader = state.shader_stages[static_cast<size_t>(stage)]; | ||||
|     auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; | ||||
|     ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); | ||||
| 
 | ||||
|     GPUVAddr tic_base_address = regs.tic.TICAddress(); | ||||
| 
 | ||||
|     GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; | ||||
| 
 | ||||
|     // Offset into the texture constbuffer where the texture info begins.
 | ||||
|     static constexpr size_t TextureInfoOffset = 0x20; | ||||
| 
 | ||||
|     for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset; | ||||
|          current_texture < tex_info_buffer_end; current_texture += 4) { | ||||
| 
 | ||||
|         Texture::TextureHandle tex_info{ | ||||
|             Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; | ||||
| 
 | ||||
|         if (tex_info.tic_id != 0 || tex_info.tsc_id != 0) { | ||||
|             GPUVAddr tic_address_gpu = | ||||
|                 tic_base_address + tex_info.tic_id * sizeof(Texture::TICEntry); | ||||
|             VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); | ||||
| 
 | ||||
|             Texture::TICEntry tic_entry; | ||||
|             Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); | ||||
| 
 | ||||
|             auto r_type = tic_entry.r_type.Value(); | ||||
|             auto g_type = tic_entry.g_type.Value(); | ||||
|             auto b_type = tic_entry.b_type.Value(); | ||||
|             auto a_type = tic_entry.a_type.Value(); | ||||
| 
 | ||||
|             // TODO(Subv): Different data types for separate components are not supported
 | ||||
|             ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); | ||||
| 
 | ||||
|             auto format = tic_entry.format.Value(); | ||||
| 
 | ||||
|             textures.push_back(tic_entry); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return textures; | ||||
| } | ||||
| 
 | ||||
| } // namespace Engines
 | ||||
| } // namespace Tegra
 | ||||
|  | ||||
| @ -12,6 +12,7 @@ | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "video_core/memory_manager.h" | ||||
| #include "video_core/textures/texture.h" | ||||
| 
 | ||||
| namespace Tegra { | ||||
| namespace Engines { | ||||
| @ -21,12 +22,6 @@ public: | ||||
|     explicit Maxwell3D(MemoryManager& memory_manager); | ||||
|     ~Maxwell3D() = default; | ||||
| 
 | ||||
|     /// Write the value to the register identified by method.
 | ||||
|     void WriteReg(u32 method, u32 value, u32 remaining_params); | ||||
| 
 | ||||
|     /// Uploads the code for a GPU macro program associated with the specified entry.
 | ||||
|     void SubmitMacroCode(u32 entry, std::vector<u32> code); | ||||
| 
 | ||||
|     /// Register structure of the Maxwell3D engine.
 | ||||
|     /// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
 | ||||
|     struct Regs { | ||||
| @ -430,6 +425,15 @@ public: | ||||
| 
 | ||||
|     State state{}; | ||||
| 
 | ||||
|     /// Write the value to the register identified by method.
 | ||||
|     void WriteReg(u32 method, u32 value, u32 remaining_params); | ||||
| 
 | ||||
|     /// Uploads the code for a GPU macro program associated with the specified entry.
 | ||||
|     void SubmitMacroCode(u32 entry, std::vector<u32> code); | ||||
| 
 | ||||
|     /// Returns a list of enabled textures for the specified shader stage.
 | ||||
|     std::vector<Texture::TICEntry> GetStageTextures(Regs::ShaderStage stage); | ||||
| 
 | ||||
| private: | ||||
|     MemoryManager& memory_manager; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Subv
						Subv