mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Serialize geometry_pipeline
This commit is contained in:
		
							parent
							
								
									acc89b2251
								
							
						
					
					
						commit
						c284192a87
					
				
					 6 changed files with 144 additions and 13 deletions
				
			
		|  | @ -2,6 +2,10 @@ | |||
| // Licensed under GPLv2 or any later version
 | ||||
| // 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/pica_state.h" | ||||
| #include "video_core/regs.h" | ||||
|  | @ -30,6 +34,13 @@ public: | |||
|      * @return if the buffer is full and the geometry shader should be invoked | ||||
|      */ | ||||
|     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.
 | ||||
|  | @ -40,7 +51,7 @@ public: | |||
| // TODO: what happens when the input size is not divisible by the output size?
 | ||||
| class GeometryPipeline_Point : public GeometryPipelineBackend { | ||||
| 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.gs.input_to_uniform == 0); | ||||
|         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_end; | ||||
|     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
 | ||||
|  | @ -86,8 +130,8 @@ private: | |||
| // value in the batch. This mode is usually used for subdivision.
 | ||||
| class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend { | ||||
| public: | ||||
|     GeometryPipeline_VariablePrimitive(const Regs& regs, Shader::ShaderSetup& setup) | ||||
|         : regs(regs), setup(setup) { | ||||
|     GeometryPipeline_VariablePrimitive() | ||||
|         : regs(g_state.regs), setup(g_state.gs) { | ||||
|         ASSERT(regs.pipeline.variable_primitive == 1); | ||||
|         ASSERT(regs.gs.input_to_uniform == 1); | ||||
|         vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; | ||||
|  | @ -144,6 +188,37 @@ private: | |||
|     unsigned int total_vertex_num; | ||||
|     Common::Vec4<float24>* buffer_cur; | ||||
|     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
 | ||||
|  | @ -151,8 +226,8 @@ private: | |||
| // particle system.
 | ||||
| class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend { | ||||
| public: | ||||
|     GeometryPipeline_FixedPrimitive(const Regs& regs, Shader::ShaderSetup& setup) | ||||
|         : regs(regs), setup(setup) { | ||||
|     GeometryPipeline_FixedPrimitive() | ||||
|         : regs(g_state.regs), setup(g_state.gs) { | ||||
|         ASSERT(regs.pipeline.variable_primitive == 0); | ||||
|         ASSERT(regs.gs.input_to_uniform == 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_end; | ||||
|     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) {} | ||||
|  | @ -231,13 +342,13 @@ void GeometryPipeline::Reconfigure() { | |||
| 
 | ||||
|     switch (state.regs.pipeline.gs_config.mode) { | ||||
|     case PipelineRegs::GSMode::Point: | ||||
|         backend = std::make_unique<GeometryPipeline_Point>(state.regs, state.gs_unit); | ||||
|         backend = std::make_unique<GeometryPipeline_Point>(); | ||||
|         break; | ||||
|     case PipelineRegs::GSMode::VariablePrimitive: | ||||
|         backend = std::make_unique<GeometryPipeline_VariablePrimitive>(state.regs, state.gs); | ||||
|         backend = std::make_unique<GeometryPipeline_VariablePrimitive>(); | ||||
|         break; | ||||
|     case PipelineRegs::GSMode::FixedPrimitive: | ||||
|         backend = std::make_unique<GeometryPipeline_FixedPrimitive>(state.regs, state.gs); | ||||
|         backend = std::make_unique<GeometryPipeline_FixedPrimitive>(); | ||||
|         break; | ||||
|     default: | ||||
|         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
 | ||||
| 
 | ||||
| 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; | ||||
|     std::unique_ptr<GeometryPipelineBackend> backend; | ||||
|     State& state; | ||||
| 
 | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int version); | ||||
| 
 | ||||
|     friend class boost::serialization::access; | ||||
| }; | ||||
| } // namespace Pica
 | ||||
|  |  | |||
|  | @ -227,7 +227,7 @@ private: | |||
|         ar & cmd_list.length; | ||||
|         ar & immediate; | ||||
|         ar & gs_unit; | ||||
|         // ar & geometry_pipeline;
 | ||||
|         ar & geometry_pipeline; | ||||
|         // ar & primitive_assembler;
 | ||||
|         ar & vs_float_regs_counter; | ||||
|         ar & vs_uniform_write_buffer; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue