mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-22 12:40:06 +00:00
Serialize geometry_pipeline
This commit is contained in:
parent
acc89b2251
commit
c284192a87
6
TODO
6
TODO
@ -11,7 +11,7 @@
|
|||||||
✔ GPU regs @done(19-08-13 15:41)
|
✔ GPU regs @done(19-08-13 15:41)
|
||||||
✔ LCD regs @done(19-08-13 15:41)
|
✔ LCD regs @done(19-08-13 15:41)
|
||||||
☐ Video core @started(19-08-13 16:43)
|
☐ Video core @started(19-08-13 16:43)
|
||||||
☐ Geometry pipeline
|
✔ Geometry pipeline @done(19-12-22 15:52)
|
||||||
✔ PICA state @done(19-08-13 15:41)
|
✔ PICA state @done(19-08-13 15:41)
|
||||||
☐ Primitive assembly
|
☐ Primitive assembly
|
||||||
✔ Shader @done(19-08-13 16:03)
|
✔ Shader @done(19-08-13 16:03)
|
||||||
@ -35,9 +35,11 @@
|
|||||||
✔ Server session @done(19-08-13 16:44)
|
✔ Server session @done(19-08-13 16:44)
|
||||||
✔ Session @done(19-08-13 16:44)
|
✔ Session @done(19-08-13 16:44)
|
||||||
☐ Shared memory
|
☐ Shared memory
|
||||||
☐ Shared page @started(19-08-13 16:44)
|
✘ Shared page @started(19-08-13 16:44) @cancelled(19-12-22 11:19)
|
||||||
|
Not needed right now as shared_page is read-only and derived from other data
|
||||||
☐ SVC
|
☐ SVC
|
||||||
☐ Thread @started(19-08-13 16:45)
|
☐ Thread @started(19-08-13 16:45)
|
||||||
|
This requires refactoring wakeup_callback to be an object ref
|
||||||
✔ Timer @done(19-08-13 16:45)
|
✔ Timer @done(19-08-13 16:45)
|
||||||
☐ VM Manager @started(19-08-13 16:46)
|
☐ VM Manager @started(19-08-13 16:46)
|
||||||
✔ Wait object @done(19-08-13 16:46)
|
✔ Wait object @done(19-08-13 16:46)
|
||||||
|
2
externals/boost
vendored
2
externals/boost
vendored
@ -1 +1 @@
|
|||||||
Subproject commit f4850c2975a0d977b7479664b8d4a6f03300a042
|
Subproject commit 55725b7796c7faa0a4af869e412d0410bd47612d
|
@ -119,7 +119,8 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version)
|
|||||||
ar & current_process;
|
ar & current_process;
|
||||||
ar & *thread_manager.get();
|
ar & *thread_manager.get();
|
||||||
ar & *config_mem_handler.get();
|
ar & *config_mem_handler.get();
|
||||||
ar & *shared_page_handler.get();
|
// Shared page data is read-only at the moment, so doesn't need serializing
|
||||||
|
//ar & *shared_page_handler.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
SERIALIZE_IMPL(KernelSystem)
|
SERIALIZE_IMPL(KernelSystem)
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <boost/serialization/base_object.hpp>
|
||||||
|
#include <boost/serialization/export.hpp>
|
||||||
|
#include <boost/serialization/unique_ptr.hpp>
|
||||||
|
#include "common/archives.h"
|
||||||
#include "video_core/geometry_pipeline.h"
|
#include "video_core/geometry_pipeline.h"
|
||||||
#include "video_core/pica_state.h"
|
#include "video_core/pica_state.h"
|
||||||
#include "video_core/regs.h"
|
#include "video_core/regs.h"
|
||||||
@ -30,6 +34,13 @@ public:
|
|||||||
* @return if the buffer is full and the geometry shader should be invoked
|
* @return if the buffer is full and the geometry shader should be invoked
|
||||||
*/
|
*/
|
||||||
virtual bool SubmitVertex(const Shader::AttributeBuffer& input) = 0;
|
virtual bool SubmitVertex(const Shader::AttributeBuffer& input) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int file_version)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
// In the Point mode, vertex attributes are sent to the input registers in the geometry shader unit.
|
// In the Point mode, vertex attributes are sent to the input registers in the geometry shader unit.
|
||||||
@ -40,7 +51,7 @@ public:
|
|||||||
// TODO: what happens when the input size is not divisible by the output size?
|
// TODO: what happens when the input size is not divisible by the output size?
|
||||||
class GeometryPipeline_Point : public GeometryPipelineBackend {
|
class GeometryPipeline_Point : public GeometryPipelineBackend {
|
||||||
public:
|
public:
|
||||||
GeometryPipeline_Point(const Regs& regs, Shader::GSUnitState& unit) : regs(regs), unit(unit) {
|
GeometryPipeline_Point() : regs(g_state.regs), unit(g_state.gs_unit) {
|
||||||
ASSERT(regs.pipeline.variable_primitive == 0);
|
ASSERT(regs.pipeline.variable_primitive == 0);
|
||||||
ASSERT(regs.gs.input_to_uniform == 0);
|
ASSERT(regs.gs.input_to_uniform == 0);
|
||||||
vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1;
|
vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1;
|
||||||
@ -79,6 +90,39 @@ private:
|
|||||||
Common::Vec4<float24>* buffer_cur;
|
Common::Vec4<float24>* buffer_cur;
|
||||||
Common::Vec4<float24>* buffer_end;
|
Common::Vec4<float24>* buffer_end;
|
||||||
unsigned int vs_output_num;
|
unsigned int vs_output_num;
|
||||||
|
|
||||||
|
template <typename Class, class Archive>
|
||||||
|
static void serialize_common(Class* self, Archive& ar, const unsigned int version)
|
||||||
|
{
|
||||||
|
ar & boost::serialization::base_object<GeometryPipelineBackend>(*self);
|
||||||
|
ar & self->attribute_buffer;
|
||||||
|
ar & self->vs_output_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void save(Archive & ar, const unsigned int version) const
|
||||||
|
{
|
||||||
|
serialize_common(this, ar, version);
|
||||||
|
auto buffer_idx = static_cast<u32>(buffer_cur - attribute_buffer.attr);
|
||||||
|
auto buffer_size = static_cast<u32>(buffer_end - attribute_buffer.attr);
|
||||||
|
ar << buffer_idx;
|
||||||
|
ar << buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void load(Archive & ar, const unsigned int version)
|
||||||
|
{
|
||||||
|
serialize_common(this, ar, version);
|
||||||
|
u32 buffer_idx, buffer_size;
|
||||||
|
ar >> buffer_idx;
|
||||||
|
ar >> buffer_size;
|
||||||
|
buffer_cur = attribute_buffer.attr + buffer_idx;
|
||||||
|
buffer_end = attribute_buffer.attr + buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
// In VariablePrimitive mode, vertex attributes are buffered into the uniform registers in the
|
// In VariablePrimitive mode, vertex attributes are buffered into the uniform registers in the
|
||||||
@ -86,8 +130,8 @@ private:
|
|||||||
// value in the batch. This mode is usually used for subdivision.
|
// value in the batch. This mode is usually used for subdivision.
|
||||||
class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend {
|
class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend {
|
||||||
public:
|
public:
|
||||||
GeometryPipeline_VariablePrimitive(const Regs& regs, Shader::ShaderSetup& setup)
|
GeometryPipeline_VariablePrimitive()
|
||||||
: regs(regs), setup(setup) {
|
: regs(g_state.regs), setup(g_state.gs) {
|
||||||
ASSERT(regs.pipeline.variable_primitive == 1);
|
ASSERT(regs.pipeline.variable_primitive == 1);
|
||||||
ASSERT(regs.gs.input_to_uniform == 1);
|
ASSERT(regs.gs.input_to_uniform == 1);
|
||||||
vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1;
|
vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1;
|
||||||
@ -144,6 +188,37 @@ private:
|
|||||||
unsigned int total_vertex_num;
|
unsigned int total_vertex_num;
|
||||||
Common::Vec4<float24>* buffer_cur;
|
Common::Vec4<float24>* buffer_cur;
|
||||||
unsigned int vs_output_num;
|
unsigned int vs_output_num;
|
||||||
|
|
||||||
|
template <typename Class, class Archive>
|
||||||
|
static void serialize_common(Class* self, Archive& ar, const unsigned int version)
|
||||||
|
{
|
||||||
|
ar & boost::serialization::base_object<GeometryPipelineBackend>(*self);
|
||||||
|
ar & self->need_index;
|
||||||
|
ar & self->main_vertex_num;
|
||||||
|
ar & self->total_vertex_num;
|
||||||
|
ar & self->vs_output_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void save(Archive & ar, const unsigned int version) const
|
||||||
|
{
|
||||||
|
serialize_common(this, ar, version);
|
||||||
|
auto buffer_idx = static_cast<u32>(buffer_cur - setup.uniforms.f);
|
||||||
|
ar << buffer_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void load(Archive & ar, const unsigned int version)
|
||||||
|
{
|
||||||
|
serialize_common(this, ar, version);
|
||||||
|
u32 buffer_idx;
|
||||||
|
ar >> buffer_idx;
|
||||||
|
buffer_cur = setup.uniforms.f + buffer_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
// In FixedPrimitive mode, vertex attributes are buffered into the uniform registers in the geometry
|
// In FixedPrimitive mode, vertex attributes are buffered into the uniform registers in the geometry
|
||||||
@ -151,8 +226,8 @@ private:
|
|||||||
// particle system.
|
// particle system.
|
||||||
class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend {
|
class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend {
|
||||||
public:
|
public:
|
||||||
GeometryPipeline_FixedPrimitive(const Regs& regs, Shader::ShaderSetup& setup)
|
GeometryPipeline_FixedPrimitive()
|
||||||
: regs(regs), setup(setup) {
|
: regs(g_state.regs), setup(g_state.gs) {
|
||||||
ASSERT(regs.pipeline.variable_primitive == 0);
|
ASSERT(regs.pipeline.variable_primitive == 0);
|
||||||
ASSERT(regs.gs.input_to_uniform == 1);
|
ASSERT(regs.gs.input_to_uniform == 1);
|
||||||
vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1;
|
vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1;
|
||||||
@ -190,6 +265,42 @@ private:
|
|||||||
Common::Vec4<float24>* buffer_cur;
|
Common::Vec4<float24>* buffer_cur;
|
||||||
Common::Vec4<float24>* buffer_end;
|
Common::Vec4<float24>* buffer_end;
|
||||||
unsigned int vs_output_num;
|
unsigned int vs_output_num;
|
||||||
|
|
||||||
|
template <typename Class, class Archive>
|
||||||
|
static void serialize_common(Class* self, Archive& ar, const unsigned int version)
|
||||||
|
{
|
||||||
|
ar & boost::serialization::base_object<GeometryPipelineBackend>(*self);
|
||||||
|
ar & self->vs_output_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void save(Archive & ar, const unsigned int version) const
|
||||||
|
{
|
||||||
|
serialize_common(this, ar, version);
|
||||||
|
auto buffer_offset = static_cast<u32>(buffer_begin - setup.uniforms.f);
|
||||||
|
auto buffer_idx = static_cast<u32>(buffer_cur - setup.uniforms.f);
|
||||||
|
auto buffer_size = static_cast<u32>(buffer_end - setup.uniforms.f);
|
||||||
|
ar << buffer_offset;
|
||||||
|
ar << buffer_idx;
|
||||||
|
ar << buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void load(Archive & ar, const unsigned int version)
|
||||||
|
{
|
||||||
|
serialize_common(this, ar, version);
|
||||||
|
u32 buffer_offset, buffer_idx, buffer_size;
|
||||||
|
ar >> buffer_offset;
|
||||||
|
ar >> buffer_idx;
|
||||||
|
ar >> buffer_size;
|
||||||
|
buffer_begin = setup.uniforms.f + buffer_offset;
|
||||||
|
buffer_cur = setup.uniforms.f + buffer_idx;
|
||||||
|
buffer_end = setup.uniforms.f + buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
GeometryPipeline::GeometryPipeline(State& state) : state(state) {}
|
GeometryPipeline::GeometryPipeline(State& state) : state(state) {}
|
||||||
@ -231,13 +342,13 @@ void GeometryPipeline::Reconfigure() {
|
|||||||
|
|
||||||
switch (state.regs.pipeline.gs_config.mode) {
|
switch (state.regs.pipeline.gs_config.mode) {
|
||||||
case PipelineRegs::GSMode::Point:
|
case PipelineRegs::GSMode::Point:
|
||||||
backend = std::make_unique<GeometryPipeline_Point>(state.regs, state.gs_unit);
|
backend = std::make_unique<GeometryPipeline_Point>();
|
||||||
break;
|
break;
|
||||||
case PipelineRegs::GSMode::VariablePrimitive:
|
case PipelineRegs::GSMode::VariablePrimitive:
|
||||||
backend = std::make_unique<GeometryPipeline_VariablePrimitive>(state.regs, state.gs);
|
backend = std::make_unique<GeometryPipeline_VariablePrimitive>();
|
||||||
break;
|
break;
|
||||||
case PipelineRegs::GSMode::FixedPrimitive:
|
case PipelineRegs::GSMode::FixedPrimitive:
|
||||||
backend = std::make_unique<GeometryPipeline_FixedPrimitive>(state.regs, state.gs);
|
backend = std::make_unique<GeometryPipeline_FixedPrimitive>();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -271,4 +382,16 @@ void GeometryPipeline::SubmitVertex(const Shader::AttributeBuffer& input) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void GeometryPipeline::serialize(Archive& ar, const unsigned int version) {
|
||||||
|
// vertex_handler and shader_engine are always set to the same value
|
||||||
|
ar & backend;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Pica
|
} // namespace Pica
|
||||||
|
|
||||||
|
BOOST_SERIALIZATION_ASSUME_ABSTRACT(Pica::GeometryPipelineBackend)
|
||||||
|
SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_Point)
|
||||||
|
SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_VariablePrimitive)
|
||||||
|
SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_FixedPrimitive)
|
||||||
|
SERIALIZE_IMPL(Pica::GeometryPipeline)
|
||||||
|
@ -45,5 +45,10 @@ private:
|
|||||||
Shader::ShaderEngine* shader_engine;
|
Shader::ShaderEngine* shader_engine;
|
||||||
std::unique_ptr<GeometryPipelineBackend> backend;
|
std::unique_ptr<GeometryPipelineBackend> backend;
|
||||||
State& state;
|
State& state;
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int version);
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
} // namespace Pica
|
} // namespace Pica
|
||||||
|
@ -227,7 +227,7 @@ private:
|
|||||||
ar & cmd_list.length;
|
ar & cmd_list.length;
|
||||||
ar & immediate;
|
ar & immediate;
|
||||||
ar & gs_unit;
|
ar & gs_unit;
|
||||||
// ar & geometry_pipeline;
|
ar & geometry_pipeline;
|
||||||
// ar & primitive_assembler;
|
// ar & primitive_assembler;
|
||||||
ar & vs_float_regs_counter;
|
ar & vs_float_regs_counter;
|
||||||
ar & vs_uniform_write_buffer;
|
ar & vs_uniform_write_buffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user