aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/command_processor.cpp
diff options
context:
space:
mode:
authordarkf <lw9k123@gmail.com>2014-12-29 19:47:41 -0800
committerdarkf <lw9k123@gmail.com>2014-12-29 19:47:41 -0800
commit8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch)
treef1c7c3393fa726435b5b90bf335567c93e528ef1 /src/video_core/command_processor.cpp
parenta19354acedbfeafd28219c48a1ec32f76dd17a54 (diff)
parent3d14eb285382740b144e5b047cb2ad072f6129ea (diff)
Fix merge conflicts
Diffstat (limited to 'src/video_core/command_processor.cpp')
-rw-r--r--src/video_core/command_processor.cpp70
1 files changed, 56 insertions, 14 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 1ec727698..9602779f4 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -1,5 +1,5 @@
// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2
+// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "clipper.h"
@@ -8,6 +8,8 @@
#include "pica.h"
#include "primitive_assembly.h"
#include "vertex_shader.h"
+#include "core/hle/service/gsp_gpu.h"
+#include "core/hw/gpu.h"
#include "debug_utils/debug_utils.h"
@@ -30,24 +32,40 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
if (id >= registers.NumIds())
return;
+ // If we're skipping this frame, only allow trigger IRQ
+ if (GPU::g_skip_frame && id != PICA_REG_INDEX(trigger_irq))
+ return;
+
// TODO: Figure out how register masking acts on e.g. vs_uniform_setup.set_value
u32 old_value = registers[id];
registers[id] = (old_value & ~mask) | (value & mask);
+ if (g_debug_context)
+ g_debug_context->OnEvent(DebugContext::Event::CommandLoaded, reinterpret_cast<void*>(&id));
+
DebugUtils::OnPicaRegWrite(id, registers[id]);
switch(id) {
+ // Trigger IRQ
+ case PICA_REG_INDEX(trigger_irq):
+ GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D);
+ return;
+
// It seems like these trigger vertex rendering
case PICA_REG_INDEX(trigger_draw):
case PICA_REG_INDEX(trigger_draw_indexed):
{
DebugUtils::DumpTevStageConfig(registers.GetTevStages());
+ if (g_debug_context)
+ g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr);
+
const auto& attribute_config = registers.vertex_attributes;
- const u8* const base_address = Memory::GetPointer(attribute_config.GetBaseAddress());
+ const u32 base_address = attribute_config.GetPhysicalBaseAddress();
// Information about internal vertex attributes
- const u8* vertex_attribute_sources[16];
+ u32 vertex_attribute_sources[16];
+ std::fill(vertex_attribute_sources, &vertex_attribute_sources[16], 0xdeadbeef);
u32 vertex_attribute_strides[16];
u32 vertex_attribute_formats[16];
u32 vertex_attribute_elements[16];
@@ -57,10 +75,10 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
for (int loader = 0; loader < 12; ++loader) {
const auto& loader_config = attribute_config.attribute_loaders[loader];
- const u8* load_address = base_address + loader_config.data_offset;
+ u32 load_address = base_address + loader_config.data_offset;
// TODO: What happens if a loader overwrites a previous one's data?
- for (int component = 0; component < loader_config.component_count; ++component) {
+ for (unsigned component = 0; component < loader_config.component_count; ++component) {
u32 attribute_index = loader_config.GetComponent(component);
vertex_attribute_sources[attribute_index] = load_address;
vertex_attribute_strides[attribute_index] = static_cast<u32>(loader_config.byte_count);
@@ -75,9 +93,9 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
bool is_indexed = (id == PICA_REG_INDEX(trigger_draw_indexed));
const auto& index_info = registers.index_array;
- const u8* index_address_8 = (u8*)base_address + index_info.offset;
+ const u8* index_address_8 = Memory::GetPointer(PAddrToVAddr(base_address + index_info.offset));
const u16* index_address_16 = (u16*)index_address_8;
- bool index_u16 = (bool)index_info.format;
+ bool index_u16 = index_info.format != 0;
DebugUtils::GeometryDumper geometry_dumper;
PrimitiveAssembler<VertexShader::OutputVertex> clipper_primitive_assembler(registers.triangle_topology.Value());
@@ -96,21 +114,31 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) {
for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
- const u8* srcdata = vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i];
+ const u8* srcdata = Memory::GetPointer(PAddrToVAddr(vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]));
+
+ // TODO(neobrain): Ocarina of Time 3D has GetNumTotalAttributes return 8,
+ // yet only provides 2 valid source data addresses. Need to figure out
+ // what's wrong there, until then we just continue when address lookup fails
+ if (srcdata == nullptr)
+ continue;
+
const float srcval = (vertex_attribute_formats[i] == 0) ? *(s8*)srcdata :
(vertex_attribute_formats[i] == 1) ? *(u8*)srcdata :
(vertex_attribute_formats[i] == 2) ? *(s16*)srcdata :
*(float*)srcdata;
input.attr[i][comp] = float24::FromFloat32(srcval);
- DEBUG_LOG(GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f",
+ LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f",
comp, i, vertex, index,
- attribute_config.GetBaseAddress(),
+ attribute_config.GetPhysicalBaseAddress(),
vertex_attribute_sources[i] - base_address,
- srcdata - vertex_attribute_sources[i],
+ vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i],
input.attr[i][comp].ToFloat32());
}
}
+ if (g_debug_context)
+ g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input);
+
// NOTE: When dumping geometry, we simply assume that the first input attribute
// corresponds to the position for now.
DebugUtils::GeometryDumper::Vertex dumped_vertex = {
@@ -132,9 +160,19 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
clipper_primitive_assembler.SubmitVertex(output, Clipper::ProcessTriangle);
}
geometry_dumper.Dump();
+
+ if (g_debug_context)
+ g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
+
break;
}
+ case PICA_REG_INDEX(vs_bool_uniforms):
+ for (unsigned i = 0; i < 16; ++i)
+ VertexShader::GetBoolUniform(i) = (registers.vs_bool_uniforms.Value() & (1 << i)) != 0;
+
+ break;
+
case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[0], 0x2c1):
case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[1], 0x2c2):
case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[2], 0x2c3):
@@ -160,7 +198,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
auto& uniform = VertexShader::GetFloatUniform(uniform_setup.index);
if (uniform_setup.index > 95) {
- ERROR_LOG(GPU, "Invalid VS uniform index %d", (int)uniform_setup.index);
+ LOG_ERROR(HW_GPU, "Invalid VS uniform index %d", (int)uniform_setup.index);
break;
}
@@ -176,7 +214,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
uniform.x = float24::FromRawFloat24(uniform_write_buffer[2] & 0xFFFFFF);
}
- DEBUG_LOG(GPU, "Set uniform %x to (%f %f %f %f)", (int)uniform_setup.index,
+ LOG_TRACE(HW_GPU, "Set uniform %x to (%f %f %f %f)", (int)uniform_setup.index,
uniform.x.ToFloat32(), uniform.y.ToFloat32(), uniform.z.ToFloat32(),
uniform.w.ToFloat32());
@@ -229,6 +267,9 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
default:
break;
}
+
+ if (g_debug_context)
+ g_debug_context->OnEvent(DebugContext::Event::CommandProcessed, reinterpret_cast<void*>(&id));
}
static std::ptrdiff_t ExecuteCommandBlock(const u32* first_command_word) {
@@ -259,8 +300,9 @@ static std::ptrdiff_t ExecuteCommandBlock(const u32* first_command_word) {
void ProcessCommandList(const u32* list, u32 size) {
u32* read_pointer = (u32*)list;
+ u32 list_length = size / sizeof(u32);
- while (read_pointer < list + size) {
+ while (read_pointer < list + list_length) {
read_pointer += ExecuteCommandBlock(read_pointer);
}
}