Created
September 25, 2017 15:51
-
-
Save Subv/8c9f0d4eb2e57ed6f6d1c013d6d58d13 to your computer and use it in GitHub Desktop.
Citra Vertex Loader direct-call
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/video_core/vertex_loader.cpp b/src/video_core/vertex_loader.cpp | |
index 37c5224..8f9db2e 100644 | |
--- a/src/video_core/vertex_loader.cpp | |
+++ b/src/video_core/vertex_loader.cpp | |
@@ -13,9 +13,37 @@ | |
#include "video_core/regs_pipeline.h" | |
#include "video_core/shader/shader.h" | |
#include "video_core/vertex_loader.h" | |
+#include "common/microprofile.h" | |
namespace Pica { | |
+MICROPROFILE_DEFINE(GPU_VertexLoad, "GPU", "Vertex Load", MP_RGB(50, 50, 240)); | |
+ | |
+template<typename T> | |
+static void LoadBufferAttr(Math::Vec4<float24>& attr, int index, u32 elements, PAddr address) { | |
+ const T* srcdata = | |
+ reinterpret_cast<const T*>(Memory::GetPhysicalPointer(address)); | |
+ for (unsigned int comp = 0; comp < elements; ++comp) { | |
+ attr[comp] = float24::FromFloat32(srcdata[comp]); | |
+ } | |
+ | |
+ // Default attribute values set if array elements have < 4 components. This | |
+ // is *not* carried over from the default attribute settings even if they're | |
+ // enabled for this attribute. | |
+ for (unsigned int comp = elements; comp < 4; ++comp) { | |
+ attr[comp] = | |
+ comp == 3 ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); | |
+ } | |
+} | |
+ | |
+void LoadDefaultAttr(Math::Vec4<float24>& attr, int index, u32 elements, PAddr address) { | |
+ // Load the default attribute if we're configured to do so | |
+ attr = g_state.input_default_attributes.attr[index]; | |
+} | |
+ | |
+void LoadPreviousAttr(Math::Vec4<float24>& attr, int index, u32 elements, PAddr address) { | |
+} | |
+ | |
void VertexLoader::Setup(const PipelineRegs& regs) { | |
ASSERT_MSG(!is_setup, "VertexLoader is not intended to be setup more than once."); | |
@@ -67,94 +95,49 @@ void VertexLoader::Setup(const PipelineRegs& regs) { | |
} | |
} | |
- is_setup = true; | |
-} | |
- | |
-void VertexLoader::LoadVertex(u32 base_address, int index, int vertex, | |
- Shader::AttributeBuffer& input, | |
- DebugUtils::MemoryAccessTracker& memory_accesses) { | |
- ASSERT_MSG(is_setup, "A VertexLoader needs to be setup before loading vertices."); | |
- | |
for (int i = 0; i < num_total_attributes; ++i) { | |
if (vertex_attribute_elements[i] != 0) { | |
- // Load per-vertex data from the loader arrays | |
- u32 source_addr = | |
- base_address + vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex; | |
- | |
- if (g_debug_context && Pica::g_debug_context->recorder) { | |
- memory_accesses.AddAccess( | |
- source_addr, | |
- vertex_attribute_elements[i] * | |
- ((vertex_attribute_formats[i] == PipelineRegs::VertexAttributeFormat::FLOAT) | |
- ? 4 | |
- : (vertex_attribute_formats[i] == | |
- PipelineRegs::VertexAttributeFormat::SHORT) | |
- ? 2 | |
- : 1)); | |
- } | |
- | |
switch (vertex_attribute_formats[i]) { | |
case PipelineRegs::VertexAttributeFormat::BYTE: { | |
- const s8* srcdata = | |
- reinterpret_cast<const s8*>(Memory::GetPhysicalPointer(source_addr)); | |
- for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { | |
- input.attr[i][comp] = float24::FromFloat32(srcdata[comp]); | |
- } | |
+ vertex_attribute_loader_function[i] = LoadBufferAttr<s8>; | |
break; | |
} | |
case PipelineRegs::VertexAttributeFormat::UBYTE: { | |
- const u8* srcdata = | |
- reinterpret_cast<const u8*>(Memory::GetPhysicalPointer(source_addr)); | |
- for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { | |
- input.attr[i][comp] = float24::FromFloat32(srcdata[comp]); | |
- } | |
+ vertex_attribute_loader_function[i] = LoadBufferAttr<u8>; | |
break; | |
} | |
case PipelineRegs::VertexAttributeFormat::SHORT: { | |
- const s16* srcdata = | |
- reinterpret_cast<const s16*>(Memory::GetPhysicalPointer(source_addr)); | |
- for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { | |
- input.attr[i][comp] = float24::FromFloat32(srcdata[comp]); | |
- } | |
+ vertex_attribute_loader_function[i] = LoadBufferAttr<s16>; | |
break; | |
} | |
case PipelineRegs::VertexAttributeFormat::FLOAT: { | |
- const float* srcdata = | |
- reinterpret_cast<const float*>(Memory::GetPhysicalPointer(source_addr)); | |
- for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { | |
- input.attr[i][comp] = float24::FromFloat32(srcdata[comp]); | |
- } | |
+ vertex_attribute_loader_function[i] = LoadBufferAttr<float>; | |
break; | |
} | |
} | |
- | |
- // Default attribute values set if array elements have < 4 components. This | |
- // is *not* carried over from the default attribute settings even if they're | |
- // enabled for this attribute. | |
- for (unsigned int comp = vertex_attribute_elements[i]; comp < 4; ++comp) { | |
- input.attr[i][comp] = | |
- comp == 3 ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); | |
- } | |
- | |
- LOG_TRACE(HW_GPU, "Loaded %d components of attribute %x for vertex %x (index %x) from " | |
- "0x%08x + 0x%08x + 0x%04x: %f %f %f %f", | |
- vertex_attribute_elements[i], i, vertex, index, base_address, | |
- vertex_attribute_sources[i], vertex_attribute_strides[i] * vertex, | |
- input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), | |
- input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); | |
} else if (vertex_attribute_is_default[i]) { | |
- // Load the default attribute if we're configured to do so | |
- input.attr[i] = g_state.input_default_attributes.attr[i]; | |
- LOG_TRACE(HW_GPU, | |
- "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", i, | |
- vertex, index, input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), | |
- input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); | |
+ vertex_attribute_loader_function[i] = LoadDefaultAttr; | |
} else { | |
- // TODO(yuriks): In this case, no data gets loaded and the vertex | |
- // remains with the last value it had. This isn't currently maintained | |
- // as global state, however, and so won't work in Citra yet. | |
+ vertex_attribute_loader_function[i] = LoadPreviousAttr; | |
} | |
} | |
+ | |
+ is_setup = true; | |
+} | |
+ | |
+void VertexLoader::LoadVertex(u32 base_address, int index, int vertex, | |
+ Shader::AttributeBuffer& input, | |
+ DebugUtils::MemoryAccessTracker& memory_accesses) { | |
+ MICROPROFILE_SCOPE(GPU_VertexLoad); | |
+ | |
+ ASSERT_MSG(is_setup, "A VertexLoader needs to be setup before loading vertices."); | |
+ | |
+ for (int i = 0; i < num_total_attributes; ++i) { | |
+ // Load per-vertex data from the loader arrays | |
+ u32 source_addr = | |
+ base_address + vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex; | |
+ vertex_attribute_loader_function[i](input.attr[i], i, vertex_attribute_elements[i], source_addr); | |
+ } | |
} | |
} // namespace Pica |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment