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() { | void Maxwell3D::DrawArrays() { | ||||||
|     LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring"); |     LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring"); | ||||||
|     if (Tegra::g_debug_context) { |     if (Tegra::g_debug_context) { | ||||||
|         Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, nullptr); |         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()); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (Tegra::g_debug_context) { |     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; |     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 Engines
 | ||||||
| } // namespace Tegra
 | } // namespace Tegra
 | ||||||
|  | |||||||
| @ -12,6 +12,7 @@ | |||||||
| #include "common/common_funcs.h" | #include "common/common_funcs.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "video_core/memory_manager.h" | #include "video_core/memory_manager.h" | ||||||
|  | #include "video_core/textures/texture.h" | ||||||
| 
 | 
 | ||||||
| namespace Tegra { | namespace Tegra { | ||||||
| namespace Engines { | namespace Engines { | ||||||
| @ -21,12 +22,6 @@ public: | |||||||
|     explicit Maxwell3D(MemoryManager& memory_manager); |     explicit Maxwell3D(MemoryManager& memory_manager); | ||||||
|     ~Maxwell3D() = default; |     ~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.
 |     /// Register structure of the Maxwell3D engine.
 | ||||||
|     /// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
 |     /// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
 | ||||||
|     struct Regs { |     struct Regs { | ||||||
| @ -430,6 +425,15 @@ public: | |||||||
| 
 | 
 | ||||||
|     State state{}; |     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: | private: | ||||||
|     MemoryManager& memory_manager; |     MemoryManager& memory_manager; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Subv
						Subv