diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/command_processor.cpp | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 8b10d7340..bbe7e63dc 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -217,57 +217,53 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 217 | // Initialize data for the current vertex | 217 | // Initialize data for the current vertex |
| 218 | VertexShader::InputVertex input; | 218 | VertexShader::InputVertex input; |
| 219 | 219 | ||
| 220 | // Load a debugging token to check whether this gets loaded by the running | ||
| 221 | // application or not. | ||
| 222 | static const float24 debug_token = float24::FromRawFloat24(0x00abcdef); | ||
| 223 | input.attr[0].w = debug_token; | ||
| 224 | |||
| 225 | for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) { | 220 | for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) { |
| 226 | // Load the default attribute if we're configured to do so, this data will be overwritten by the loader data if it's set | 221 | if (vertex_attribute_elements[i] != 0) { |
| 227 | if (attribute_config.IsDefaultAttribute(i)) { | 222 | // Default attribute values set if array elements have < 4 components. This |
| 223 | // is *not* carried over from the default attribute settings even if they're | ||
| 224 | // enabled for this attribute. | ||
| 225 | static const float24 zero = float24::FromFloat32(0.0f); | ||
| 226 | static const float24 one = float24::FromFloat32(1.0f); | ||
| 227 | input.attr[i] = Math::Vec4<float24>(zero, zero, zero, one); | ||
| 228 | |||
| 229 | // Load per-vertex data from the loader arrays | ||
| 230 | for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { | ||
| 231 | u32 source_addr = vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]; | ||
| 232 | const u8* srcdata = Memory::GetPhysicalPointer(source_addr); | ||
| 233 | |||
| 234 | if (g_debug_context && Pica::g_debug_context->recorder) { | ||
| 235 | memory_accesses.AddAccess(source_addr, | ||
| 236 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::FLOAT) ? 4 | ||
| 237 | : (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? 2 : 1); | ||
| 238 | } | ||
| 239 | |||
| 240 | const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata : | ||
| 241 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata : | ||
| 242 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? *(s16*)srcdata : | ||
| 243 | *(float*)srcdata; | ||
| 244 | |||
| 245 | input.attr[i][comp] = float24::FromFloat32(srcval); | ||
| 246 | LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f", | ||
| 247 | comp, i, vertex, index, | ||
| 248 | attribute_config.GetPhysicalBaseAddress(), | ||
| 249 | vertex_attribute_sources[i] - base_address, | ||
| 250 | vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i], | ||
| 251 | input.attr[i][comp].ToFloat32()); | ||
| 252 | } | ||
| 253 | } else if (attribute_config.IsDefaultAttribute(i)) { | ||
| 254 | // Load the default attribute if we're configured to do so | ||
| 228 | input.attr[i] = g_state.vs.default_attributes[i]; | 255 | input.attr[i] = g_state.vs.default_attributes[i]; |
| 229 | LOG_TRACE(HW_GPU, "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", | 256 | LOG_TRACE(HW_GPU, "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", |
| 230 | i, vertex, index, | 257 | i, vertex, index, |
| 231 | input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), | 258 | input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), |
| 232 | input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); | 259 | input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); |
| 233 | } | 260 | } else { |
| 234 | 261 | // TODO(yuriks): In this case, no data gets loaded and the vertex remains | |
| 235 | // Load per-vertex data from the loader arrays | 262 | // with the last value it had. This isn't currently maintained |
| 236 | for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { | 263 | // as global state, however, and so won't work in Cita yet. |
| 237 | u32 source_addr = vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]; | ||
| 238 | const u8* srcdata = Memory::GetPhysicalPointer(source_addr); | ||
| 239 | |||
| 240 | if (g_debug_context && Pica::g_debug_context->recorder) { | ||
| 241 | memory_accesses.AddAccess(source_addr, | ||
| 242 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::FLOAT) ? 4 | ||
| 243 | : (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? 2 : 1); | ||
| 244 | } | ||
| 245 | |||
| 246 | const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata : | ||
| 247 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata : | ||
| 248 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? *(s16*)srcdata : | ||
| 249 | *(float*)srcdata; | ||
| 250 | |||
| 251 | input.attr[i][comp] = float24::FromFloat32(srcval); | ||
| 252 | LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f", | ||
| 253 | comp, i, vertex, index, | ||
| 254 | attribute_config.GetPhysicalBaseAddress(), | ||
| 255 | vertex_attribute_sources[i] - base_address, | ||
| 256 | vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i], | ||
| 257 | input.attr[i][comp].ToFloat32()); | ||
| 258 | } | 264 | } |
| 259 | } | 265 | } |
| 260 | 266 | ||
| 261 | // HACK: Some games do not initialize the vertex position's w component. This leads | ||
| 262 | // to critical issues since it messes up perspective division. As a | ||
| 263 | // workaround, we force the fourth component to 1.0 if we find this to be the | ||
| 264 | // case. | ||
| 265 | // To do this, we additionally have to assume that the first input attribute | ||
| 266 | // is the vertex position, since there's no information about this other than | ||
| 267 | // the empiric observation that this is usually the case. | ||
| 268 | if (input.attr[0].w == debug_token) | ||
| 269 | input.attr[0].w = float24::FromFloat32(1.0); | ||
| 270 | |||
| 271 | if (g_debug_context) | 267 | if (g_debug_context) |
| 272 | g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input); | 268 | g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input); |
| 273 | 269 | ||