|
@@ -60,6 +60,46 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
|
|
|
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D);
|
|
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
|
|
+ // Load default vertex input attributes
|
|
|
|
|
+ case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[0], 0x233):
|
|
|
|
|
+ case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[1], 0x234):
|
|
|
|
|
+ case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[2], 0x235):
|
|
|
|
|
+ {
|
|
|
|
|
+ // TODO: Does actual hardware indeed keep an intermediate buffer or does
|
|
|
|
|
+ // it directly write the values?
|
|
|
|
|
+ default_attr_write_buffer[default_attr_counter++] = value;
|
|
|
|
|
+
|
|
|
|
|
+ // Default attributes are written in a packed format such that four float24 values are encoded in
|
|
|
|
|
+ // three 32-bit numbers. We write to internal memory once a full such vector is
|
|
|
|
|
+ // written.
|
|
|
|
|
+ if (default_attr_counter >= 3) {
|
|
|
|
|
+ default_attr_counter = 0;
|
|
|
|
|
+
|
|
|
|
|
+ auto& setup = regs.vs_default_attributes_setup;
|
|
|
|
|
+
|
|
|
|
|
+ if (setup.index >= 16) {
|
|
|
|
|
+ LOG_ERROR(HW_GPU, "Invalid VS default attribute index %d", (int)setup.index);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index];
|
|
|
|
|
+
|
|
|
|
|
+ // NOTE: The destination component order indeed is "backwards"
|
|
|
|
|
+ attribute.w = float24::FromRawFloat24(default_attr_write_buffer[0] >> 8);
|
|
|
|
|
+ attribute.z = float24::FromRawFloat24(((default_attr_write_buffer[0] & 0xFF) << 16) | ((default_attr_write_buffer[1] >> 16) & 0xFFFF));
|
|
|
|
|
+ attribute.y = float24::FromRawFloat24(((default_attr_write_buffer[1] & 0xFFFF) << 8) | ((default_attr_write_buffer[2] >> 24) & 0xFF));
|
|
|
|
|
+ attribute.x = float24::FromRawFloat24(default_attr_write_buffer[2] & 0xFFFFFF);
|
|
|
|
|
+
|
|
|
|
|
+ LOG_TRACE(HW_GPU, "Set default VS attribute %x to (%f %f %f %f)", (int)setup.index,
|
|
|
|
|
+ attribute.x.ToFloat32(), attribute.y.ToFloat32(), attribute.z.ToFloat32(),
|
|
|
|
|
+ attribute.w.ToFloat32());
|
|
|
|
|
+
|
|
|
|
|
+ // TODO: Verify that this actually modifies the register!
|
|
|
|
|
+ setup.index = setup.index + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[0], 0x23c):
|
|
case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[0], 0x23c):
|
|
|
case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[1], 0x23d):
|
|
case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[1], 0x23d):
|
|
|
{
|
|
{
|
|
@@ -351,46 +391,6 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Load default vertex input attributes
|
|
|
|
|
- case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[0], 0x233):
|
|
|
|
|
- case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[1], 0x234):
|
|
|
|
|
- case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[2], 0x235):
|
|
|
|
|
- {
|
|
|
|
|
- // TODO: Does actual hardware indeed keep an intermediate buffer or does
|
|
|
|
|
- // it directly write the values?
|
|
|
|
|
- default_attr_write_buffer[default_attr_counter++] = value;
|
|
|
|
|
-
|
|
|
|
|
- // Default attributes are written in a packed format such that four float24 values are encoded in
|
|
|
|
|
- // three 32-bit numbers. We write to internal memory once a full such vector is
|
|
|
|
|
- // written.
|
|
|
|
|
- if (default_attr_counter >= 3) {
|
|
|
|
|
- default_attr_counter = 0;
|
|
|
|
|
-
|
|
|
|
|
- auto& setup = regs.vs_default_attributes_setup;
|
|
|
|
|
-
|
|
|
|
|
- if (setup.index >= 16) {
|
|
|
|
|
- LOG_ERROR(HW_GPU, "Invalid VS default attribute index %d", (int)setup.index);
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index];
|
|
|
|
|
-
|
|
|
|
|
- // NOTE: The destination component order indeed is "backwards"
|
|
|
|
|
- attribute.w = float24::FromRawFloat24(default_attr_write_buffer[0] >> 8);
|
|
|
|
|
- attribute.z = float24::FromRawFloat24(((default_attr_write_buffer[0] & 0xFF) << 16) | ((default_attr_write_buffer[1] >> 16) & 0xFFFF));
|
|
|
|
|
- attribute.y = float24::FromRawFloat24(((default_attr_write_buffer[1] & 0xFFFF) << 8) | ((default_attr_write_buffer[2] >> 24) & 0xFF));
|
|
|
|
|
- attribute.x = float24::FromRawFloat24(default_attr_write_buffer[2] & 0xFFFFFF);
|
|
|
|
|
-
|
|
|
|
|
- LOG_TRACE(HW_GPU, "Set default VS attribute %x to (%f %f %f %f)", (int)setup.index,
|
|
|
|
|
- attribute.x.ToFloat32(), attribute.y.ToFloat32(), attribute.z.ToFloat32(),
|
|
|
|
|
- attribute.w.ToFloat32());
|
|
|
|
|
-
|
|
|
|
|
- // TODO: Verify that this actually modifies the register!
|
|
|
|
|
- setup.index = setup.index + 1;
|
|
|
|
|
- }
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
// Load shader program code
|
|
// Load shader program code
|
|
|
case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[0], 0x2cc):
|
|
case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[0], 0x2cc):
|
|
|
case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[1], 0x2cd):
|
|
case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[1], 0x2cd):
|