summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/command_processor.cpp55
-rw-r--r--src/video_core/debug_utils/debug_utils.h4
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp6
3 files changed, 63 insertions, 2 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 110caec76..2095e7b15 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -123,12 +123,50 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
123 PrimitiveAssembler<VertexShader::OutputVertex> primitive_assembler(regs.triangle_topology.Value()); 123 PrimitiveAssembler<VertexShader::OutputVertex> primitive_assembler(regs.triangle_topology.Value());
124 PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value()); 124 PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value());
125 125
126 if (g_debug_context) {
127 for (int i = 0; i < 3; ++i) {
128 const auto texture = regs.GetTextures()[i];
129 if (!texture.enabled)
130 continue;
131
132 u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress());
133 if (g_debug_context && Pica::g_debug_context->recorder)
134 g_debug_context->recorder->MemoryAccessed(texture_data, Pica::Regs::NibblesPerPixel(texture.format) * texture.config.width / 2 * texture.config.height, texture.config.GetPhysicalAddress());
135 }
136 }
137
138 // map physical start address to size
139 std::map<u32, u32> accessed_ranges;
140 static auto SimplifyRanges = [](std::map<u32, u32>& ranges) {
141 for (auto it = ranges.begin(); it != ranges.end(); ++it) {
142
143 // Combine overlapping ranges ... artificially extend first range by 32 bytes to merge "close" ranges
144 auto it2 = std::next(it);
145 while (it2 != ranges.end() && it->first + it->second + 32 >= it2->first) {
146 it->second = std::max(it->second, it2->first + it2->second - it->first);
147 it2 = ranges.erase(it2);
148 }
149 }
150 };
151
152 static auto AddMemoryAccess = [](std::map<u32, u32>& ranges, u32 paddr, u32 size) {
153 // Create new range or extend existing one
154 ranges[paddr] = std::max(ranges[paddr], size);
155
156 // Simplify ranges...
157 SimplifyRanges(ranges);
158 };
159
126 for (unsigned int index = 0; index < regs.num_vertices; ++index) 160 for (unsigned int index = 0; index < regs.num_vertices; ++index)
127 { 161 {
128 unsigned int vertex = is_indexed ? (index_u16 ? index_address_16[index] : index_address_8[index]) : index; 162 unsigned int vertex = is_indexed ? (index_u16 ? index_address_16[index] : index_address_8[index]) : index;
129 163
130 if (is_indexed) { 164 if (is_indexed) {
131 // TODO: Implement some sort of vertex cache! 165 // TODO: Implement some sort of vertex cache!
166 if (g_debug_context && Pica::g_debug_context->recorder) {
167 int size = index_u16 ? 2 : 1;
168 AddMemoryAccess(accessed_ranges, base_address + index_info.offset + size*index, size);
169 }
132 } 170 }
133 171
134 // Initialize data for the current vertex 172 // Initialize data for the current vertex
@@ -151,7 +189,14 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
151 189
152 // Load per-vertex data from the loader arrays 190 // Load per-vertex data from the loader arrays
153 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { 191 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
154 const u8* srcdata = Memory::GetPhysicalPointer(vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]); 192 u32 source_addr = vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i];
193 const u8* srcdata = Memory::GetPhysicalPointer(source_addr);
194
195 if (g_debug_context && Pica::g_debug_context->recorder) {
196 AddMemoryAccess(accessed_ranges, source_addr,
197 (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::FLOAT) ? 4
198 : (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? 2 : 1);
199 }
155 200
156 const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata : 201 const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata :
157 (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata : 202 (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata :
@@ -213,14 +258,20 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
213 } 258 }
214 } 259 }
215 260
261 for (auto& range : accessed_ranges) {
262 g_debug_context->recorder->MemoryAccessed(Memory::GetPhysicalPointer(range.first),
263 range.second, range.first);
264 }
265
216 if (Settings::values.use_hw_renderer) { 266 if (Settings::values.use_hw_renderer) {
217 VideoCore::g_renderer->hw_rasterizer->DrawTriangles(); 267 VideoCore::g_renderer->hw_rasterizer->DrawTriangles();
218 } 268 }
219 269
220 geometry_dumper.Dump(); 270 geometry_dumper.Dump();
221 271
222 if (g_debug_context) 272 if (g_debug_context) {
223 g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); 273 g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
274 }
224 275
225 break; 276 break;
226 } 277 }
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h
index 7926d64ec..2573292e2 100644
--- a/src/video_core/debug_utils/debug_utils.h
+++ b/src/video_core/debug_utils/debug_utils.h
@@ -14,6 +14,8 @@
14 14
15#include "common/vector_math.h" 15#include "common/vector_math.h"
16 16
17#include "core/tracer/recorder.h"
18
17#include "video_core/pica.h" 19#include "video_core/pica.h"
18 20
19namespace Pica { 21namespace Pica {
@@ -129,6 +131,8 @@ public:
129 Event active_breakpoint; 131 Event active_breakpoint;
130 bool at_breakpoint = false; 132 bool at_breakpoint = false;
131 133
134 std::shared_ptr<CiTrace::Recorder> recorder = nullptr;
135
132private: 136private:
133 /** 137 /**
134 * Private default constructor to make sure people always construct this through Construct() 138 * Private default constructor to make sure people always construct this through Construct()
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 9799f74fa..96e12839a 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -22,6 +22,8 @@
22#include "video_core/renderer_opengl/gl_shader_util.h" 22#include "video_core/renderer_opengl/gl_shader_util.h"
23#include "video_core/renderer_opengl/gl_shaders.h" 23#include "video_core/renderer_opengl/gl_shaders.h"
24 24
25#include "video_core/debug_utils/debug_utils.h"
26
25/** 27/**
26 * Vertex structure that the drawn screen rectangles are composed of. 28 * Vertex structure that the drawn screen rectangles are composed of.
27 */ 29 */
@@ -129,6 +131,10 @@ void RendererOpenGL::SwapBuffers() {
129 hw_rasterizer->Reset(); 131 hw_rasterizer->Reset();
130 } 132 }
131 } 133 }
134
135 if (Pica::g_debug_context && Pica::g_debug_context->recorder) {
136 Pica::g_debug_context->recorder->FrameFinished();
137 }
132} 138}
133 139
134/** 140/**