summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-03-23 18:56:27 -0500
committerGravatar Subv2018-03-24 11:31:53 -0500
commit2c785bd06c8f979fbb869d533204b29d93973d83 (patch)
treec5f800ae155cddb0b36c3ac54febbf8169c709e5 /src
parentFrontend: Updated the surface view debug widget to work with Maxwell surfaces. (diff)
downloadyuzu-2c785bd06c8f979fbb869d533204b29d93973d83.tar.gz
yuzu-2c785bd06c8f979fbb869d533204b29d93973d83.tar.xz
yuzu-2c785bd06c8f979fbb869d533204b29d93973d83.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp93
-rw-r--r--src/video_core/engines/maxwell_3d.h16
2 files changed, 59 insertions, 50 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index aa375f51f..c962887ca 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -174,53 +174,13 @@ void Maxwell3D::ProcessQueryGet() {
174void Maxwell3D::DrawArrays() { 174void Maxwell3D::DrawArrays() {
175 LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring"); 175 LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring");
176 if (Tegra::g_debug_context) { 176 if (Tegra::g_debug_context) {
177 Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, nullptr); 177 Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch,
178 } 178 nullptr);
179
180 auto& fragment_shader = state.shader_stages[static_cast<size_t>(Regs::ShaderStage::Fragment)];
181 auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index];
182 ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0);
183
184 GPUVAddr tic_base_address = regs.tic.TICAddress();
185
186 GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size;
187
188 for (GPUVAddr current_texture = tex_info_buffer.address + 0x20;
189 current_texture < tex_info_buffer_end; current_texture += 4) {
190
191 Texture::TextureHandle tex_info{
192 Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))};
193
194 if (tex_info.tic_id != 0 || tex_info.tsc_id != 0) {
195 GPUVAddr tic_address_gpu =
196 tic_base_address + tex_info.tic_id * sizeof(Texture::TICEntry);
197 VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu);
198
199 Texture::TICEntry tic_entry;
200 Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry));
201
202 auto r_type = tic_entry.r_type.Value();
203 auto g_type = tic_entry.g_type.Value();
204 auto b_type = tic_entry.b_type.Value();
205 auto a_type = tic_entry.a_type.Value();
206
207 // TODO(Subv): Different data types for separate components are not supported
208 ASSERT(r_type == g_type && r_type == b_type && r_type == a_type);
209
210 auto format = tic_entry.format.Value();
211
212 auto texture = Texture::UnswizzleTexture(
213 memory_manager.PhysicalToVirtualAddress(tic_entry.Address()),
214 tic_entry.format.Value(), tic_entry.Width(), tic_entry.Height());
215
216 LOG_CRITICAL(HW_GPU,
217 "Fragment shader using texture TIC %08X TSC %08X at address %016" PRIX64,
218 tex_info.tic_id.Value(), tex_info.tsc_id.Value(), tic_entry.Address());
219 }
220 } 179 }
221 180
222 if (Tegra::g_debug_context) { 181 if (Tegra::g_debug_context) {
223 Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); 182 Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch,
183 nullptr);
224 } 184 }
225} 185}
226 186
@@ -332,5 +292,50 @@ void Maxwell3D::ProcessCBData(u32 value) {
332 regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; 292 regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;
333} 293}
334 294
295std::vector<Texture::TICEntry> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) {
296 std::vector<Texture::TICEntry> textures;
297
298 auto& fragment_shader = state.shader_stages[static_cast<size_t>(stage)];
299 auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index];
300 ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0);
301
302 GPUVAddr tic_base_address = regs.tic.TICAddress();
303
304 GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size;
305
306 // Offset into the texture constbuffer where the texture info begins.
307 static constexpr size_t TextureInfoOffset = 0x20;
308
309 for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset;
310 current_texture < tex_info_buffer_end; current_texture += 4) {
311
312 Texture::TextureHandle tex_info{
313 Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))};
314
315 if (tex_info.tic_id != 0 || tex_info.tsc_id != 0) {
316 GPUVAddr tic_address_gpu =
317 tic_base_address + tex_info.tic_id * sizeof(Texture::TICEntry);
318 VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu);
319
320 Texture::TICEntry tic_entry;
321 Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry));
322
323 auto r_type = tic_entry.r_type.Value();
324 auto g_type = tic_entry.g_type.Value();
325 auto b_type = tic_entry.b_type.Value();
326 auto a_type = tic_entry.a_type.Value();
327
328 // TODO(Subv): Different data types for separate components are not supported
329 ASSERT(r_type == g_type && r_type == b_type && r_type == a_type);
330
331 auto format = tic_entry.format.Value();
332
333 textures.push_back(tic_entry);
334 }
335 }
336
337 return textures;
338}
339
335} // namespace Engines 340} // namespace Engines
336} // namespace Tegra 341} // namespace Tegra
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 545d7ff35..441cc0c19 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -12,6 +12,7 @@
12#include "common/common_funcs.h" 12#include "common/common_funcs.h"
13#include "common/common_types.h" 13#include "common/common_types.h"
14#include "video_core/memory_manager.h" 14#include "video_core/memory_manager.h"
15#include "video_core/textures/texture.h"
15 16
16namespace Tegra { 17namespace Tegra {
17namespace Engines { 18namespace Engines {
@@ -21,12 +22,6 @@ public:
21 explicit Maxwell3D(MemoryManager& memory_manager); 22 explicit Maxwell3D(MemoryManager& memory_manager);
22 ~Maxwell3D() = default; 23 ~Maxwell3D() = default;
23 24
24 /// Write the value to the register identified by method.
25 void WriteReg(u32 method, u32 value, u32 remaining_params);
26
27 /// Uploads the code for a GPU macro program associated with the specified entry.
28 void SubmitMacroCode(u32 entry, std::vector<u32> code);
29
30 /// Register structure of the Maxwell3D engine. 25 /// Register structure of the Maxwell3D engine.
31 /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. 26 /// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
32 struct Regs { 27 struct Regs {
@@ -430,6 +425,15 @@ public:
430 425
431 State state{}; 426 State state{};
432 427
428 /// Write the value to the register identified by method.
429 void WriteReg(u32 method, u32 value, u32 remaining_params);
430
431 /// Uploads the code for a GPU macro program associated with the specified entry.
432 void SubmitMacroCode(u32 entry, std::vector<u32> code);
433
434 /// Returns a list of enabled textures for the specified shader stage.
435 std::vector<Texture::TICEntry> GetStageTextures(Regs::ShaderStage stage);
436
433private: 437private:
434 MemoryManager& memory_manager; 438 MemoryManager& memory_manager;
435 439