mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	VideoCore: Split shader regs from Regs struct
This commit is contained in:
		
							parent
							
								
									8fca90b5d5
								
							
						
					
					
						commit
						f7c7f422c6
					
				
					 9 changed files with 116 additions and 102 deletions
				
			
		|  | @ -36,6 +36,7 @@ set(HEADERS | |||
|             regs_lighting.h | ||||
|             regs_pipeline.h | ||||
|             regs_rasterizer.h | ||||
|             regs_shader.h | ||||
|             regs_texturing.h | ||||
|             renderer_base.h | ||||
|             renderer_opengl/gl_rasterizer.h | ||||
|  |  | |||
|  | @ -88,7 +88,7 @@ std::shared_ptr<DebugContext> g_debug_context; // TODO: Get rid of this global | |||
| 
 | ||||
| namespace DebugUtils { | ||||
| 
 | ||||
| void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, | ||||
| void DumpShader(const std::string& filename, const ShaderRegs& config, | ||||
|                 const Shader::ShaderSetup& setup, | ||||
|                 const RasterizerRegs::VSOutputAttributes* output_attributes) { | ||||
|     struct StuffToWrite { | ||||
|  |  | |||
|  | @ -182,7 +182,7 @@ namespace DebugUtils { | |||
| #define PICA_DUMP_TEXTURES 0 | ||||
| #define PICA_LOG_TEV 0 | ||||
| 
 | ||||
| void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, | ||||
| void DumpShader(const std::string& filename, const ShaderRegs& config, | ||||
|                 const Shader::ShaderSetup& setup, | ||||
|                 const RasterizerRegs::VSOutputAttributes* output_attributes); | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ | |||
| #include "video_core/regs_lighting.h" | ||||
| #include "video_core/regs_pipeline.h" | ||||
| #include "video_core/regs_rasterizer.h" | ||||
| #include "video_core/regs_shader.h" | ||||
| #include "video_core/regs_texturing.h" | ||||
| 
 | ||||
| namespace Pica { | ||||
|  | @ -57,97 +58,8 @@ struct Regs { | |||
|     FramebufferRegs framebuffer; | ||||
|     LightingRegs lighting; | ||||
|     PipelineRegs pipeline; | ||||
| 
 | ||||
|     struct ShaderConfig { | ||||
|         BitField<0, 16, u32> bool_uniforms; | ||||
| 
 | ||||
|         union { | ||||
|             BitField<0, 8, u32> x; | ||||
|             BitField<8, 8, u32> y; | ||||
|             BitField<16, 8, u32> z; | ||||
|             BitField<24, 8, u32> w; | ||||
|         } int_uniforms[4]; | ||||
| 
 | ||||
|         INSERT_PADDING_WORDS(0x4); | ||||
| 
 | ||||
|         union { | ||||
|             // Number of input attributes to shader unit - 1
 | ||||
|             BitField<0, 4, u32> max_input_attribute_index; | ||||
|         }; | ||||
| 
 | ||||
|         // Offset to shader program entry point (in words)
 | ||||
|         BitField<0, 16, u32> main_offset; | ||||
| 
 | ||||
|         /// Maps input attributes to registers. 4-bits per attribute, specifying a register index
 | ||||
|         u32 input_attribute_to_register_map_low; | ||||
|         u32 input_attribute_to_register_map_high; | ||||
| 
 | ||||
|         unsigned int GetRegisterForAttribute(unsigned int attribute_index) const { | ||||
|             u64 map = ((u64)input_attribute_to_register_map_high << 32) | | ||||
|                       (u64)input_attribute_to_register_map_low; | ||||
|             return (map >> (attribute_index * 4)) & 0b1111; | ||||
|         } | ||||
| 
 | ||||
|         BitField<0, 16, u32> output_mask; | ||||
| 
 | ||||
|         // 0x28E, CODETRANSFER_END
 | ||||
|         INSERT_PADDING_WORDS(0x2); | ||||
| 
 | ||||
|         struct { | ||||
|             enum Format : u32 { | ||||
|                 FLOAT24 = 0, | ||||
|                 FLOAT32 = 1, | ||||
|             }; | ||||
| 
 | ||||
|             bool IsFloat32() const { | ||||
|                 return format == FLOAT32; | ||||
|             } | ||||
| 
 | ||||
|             union { | ||||
|                 // Index of the next uniform to write to
 | ||||
|                 // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid
 | ||||
|                 // indices
 | ||||
|                 // TODO: Maybe the uppermost index is for the geometry shader? Investigate!
 | ||||
|                 BitField<0, 7, u32> index; | ||||
| 
 | ||||
|                 BitField<31, 1, Format> format; | ||||
|             }; | ||||
| 
 | ||||
|             // Writing to these registers sets the current uniform.
 | ||||
|             u32 set_value[8]; | ||||
| 
 | ||||
|         } uniform_setup; | ||||
| 
 | ||||
|         INSERT_PADDING_WORDS(0x2); | ||||
| 
 | ||||
|         struct { | ||||
|             // Offset of the next instruction to write code to.
 | ||||
|             // Incremented with each instruction write.
 | ||||
|             u32 offset; | ||||
| 
 | ||||
|             // Writing to these registers sets the "current" word in the shader program.
 | ||||
|             u32 set_word[8]; | ||||
|         } program; | ||||
| 
 | ||||
|         INSERT_PADDING_WORDS(0x1); | ||||
| 
 | ||||
|         // This register group is used to load an internal table of swizzling patterns,
 | ||||
|         // which are indexed by each shader instruction to specify vector component swizzling.
 | ||||
|         struct { | ||||
|             // Offset of the next swizzle pattern to write code to.
 | ||||
|             // Incremented with each instruction write.
 | ||||
|             u32 offset; | ||||
| 
 | ||||
|             // Writing to these registers sets the current swizzle pattern in the table.
 | ||||
|             u32 set_word[8]; | ||||
|         } swizzle_patterns; | ||||
| 
 | ||||
|         INSERT_PADDING_WORDS(0x2); | ||||
|     }; | ||||
| 
 | ||||
|     ShaderConfig gs; | ||||
|     ShaderConfig vs; | ||||
| 
 | ||||
|     ShaderRegs gs; | ||||
|     ShaderRegs vs; | ||||
|     INSERT_PADDING_WORDS(0x20); | ||||
| 
 | ||||
|     // Map register indices to names readable by humans
 | ||||
|  | @ -247,9 +159,6 @@ ASSERT_REG_POSITION(vs, 0x2b0); | |||
| #undef ASSERT_REG_POSITION | ||||
| #endif // !defined(_MSC_VER)
 | ||||
| 
 | ||||
| static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32), | ||||
|               "ShaderConfig structure has incorrect size"); | ||||
| 
 | ||||
| // The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value
 | ||||
| // anyway.
 | ||||
| static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), | ||||
|  |  | |||
							
								
								
									
										104
									
								
								src/video_core/regs_shader.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/video_core/regs_shader.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,104 @@ | |||
| // Copyright 2017 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| 
 | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| 
 | ||||
| namespace Pica { | ||||
| 
 | ||||
| struct ShaderRegs { | ||||
|     BitField<0, 16, u32> bool_uniforms; | ||||
| 
 | ||||
|     union { | ||||
|         BitField<0, 8, u32> x; | ||||
|         BitField<8, 8, u32> y; | ||||
|         BitField<16, 8, u32> z; | ||||
|         BitField<24, 8, u32> w; | ||||
|     } int_uniforms[4]; | ||||
| 
 | ||||
|     INSERT_PADDING_WORDS(0x4); | ||||
| 
 | ||||
|     union { | ||||
|         // Number of input attributes to shader unit - 1
 | ||||
|         BitField<0, 4, u32> max_input_attribute_index; | ||||
|     }; | ||||
| 
 | ||||
|     // Offset to shader program entry point (in words)
 | ||||
|     BitField<0, 16, u32> main_offset; | ||||
| 
 | ||||
|     /// Maps input attributes to registers. 4-bits per attribute, specifying a register index
 | ||||
|     u32 input_attribute_to_register_map_low; | ||||
|     u32 input_attribute_to_register_map_high; | ||||
| 
 | ||||
|     unsigned int GetRegisterForAttribute(unsigned int attribute_index) const { | ||||
|         u64 map = ((u64)input_attribute_to_register_map_high << 32) | | ||||
|                   (u64)input_attribute_to_register_map_low; | ||||
|         return (map >> (attribute_index * 4)) & 0b1111; | ||||
|     } | ||||
| 
 | ||||
|     BitField<0, 16, u32> output_mask; | ||||
| 
 | ||||
|     // 0x28E, CODETRANSFER_END
 | ||||
|     INSERT_PADDING_WORDS(0x2); | ||||
| 
 | ||||
|     struct { | ||||
|         enum Format : u32 { | ||||
|             FLOAT24 = 0, | ||||
|             FLOAT32 = 1, | ||||
|         }; | ||||
| 
 | ||||
|         bool IsFloat32() const { | ||||
|             return format == FLOAT32; | ||||
|         } | ||||
| 
 | ||||
|         union { | ||||
|             // Index of the next uniform to write to
 | ||||
|             // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid
 | ||||
|             // indices
 | ||||
|             // TODO: Maybe the uppermost index is for the geometry shader? Investigate!
 | ||||
|             BitField<0, 7, u32> index; | ||||
| 
 | ||||
|             BitField<31, 1, Format> format; | ||||
|         }; | ||||
| 
 | ||||
|         // Writing to these registers sets the current uniform.
 | ||||
|         u32 set_value[8]; | ||||
| 
 | ||||
|     } uniform_setup; | ||||
| 
 | ||||
|     INSERT_PADDING_WORDS(0x2); | ||||
| 
 | ||||
|     struct { | ||||
|         // Offset of the next instruction to write code to.
 | ||||
|         // Incremented with each instruction write.
 | ||||
|         u32 offset; | ||||
| 
 | ||||
|         // Writing to these registers sets the "current" word in the shader program.
 | ||||
|         u32 set_word[8]; | ||||
|     } program; | ||||
| 
 | ||||
|     INSERT_PADDING_WORDS(0x1); | ||||
| 
 | ||||
|     // This register group is used to load an internal table of swizzling patterns,
 | ||||
|     // which are indexed by each shader instruction to specify vector component swizzling.
 | ||||
|     struct { | ||||
|         // Offset of the next swizzle pattern to write code to.
 | ||||
|         // Incremented with each instruction write.
 | ||||
|         u32 offset; | ||||
| 
 | ||||
|         // Writing to these registers sets the current swizzle pattern in the table.
 | ||||
|         u32 set_word[8]; | ||||
|     } swizzle_patterns; | ||||
| 
 | ||||
|     INSERT_PADDING_WORDS(0x2); | ||||
| }; | ||||
| 
 | ||||
| static_assert(sizeof(ShaderRegs) == 0x30 * sizeof(u32), "ShaderRegs struct has incorrect size"); | ||||
| 
 | ||||
| } // namespace Pica
 | ||||
|  | @ -66,7 +66,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const RasterizerRegs& regs, Attri | |||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void UnitState::LoadInput(const Regs::ShaderConfig& config, const AttributeBuffer& input) { | ||||
| void UnitState::LoadInput(const ShaderRegs& config, const AttributeBuffer& input) { | ||||
|     const unsigned max_attribute = config.max_input_attribute_index; | ||||
| 
 | ||||
|     for (unsigned attr = 0; attr <= max_attribute; ++attr) { | ||||
|  | @ -75,7 +75,7 @@ void UnitState::LoadInput(const Regs::ShaderConfig& config, const AttributeBuffe | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void UnitState::WriteOutput(const Regs::ShaderConfig& config, AttributeBuffer& output) { | ||||
| void UnitState::WriteOutput(const ShaderRegs& config, AttributeBuffer& output) { | ||||
|     unsigned int output_i = 0; | ||||
|     for (unsigned int reg : Common::BitSet<u32>(config.output_mask)) { | ||||
|         output.attr[output_i++] = registers.output[reg]; | ||||
|  |  | |||
|  | @ -116,9 +116,9 @@ struct UnitState { | |||
|      * @param config Shader configuration registers corresponding to the unit. | ||||
|      * @param input Attribute buffer to load into the input registers. | ||||
|      */ | ||||
|     void LoadInput(const Regs::ShaderConfig& config, const AttributeBuffer& input); | ||||
|     void LoadInput(const ShaderRegs& config, const AttributeBuffer& input); | ||||
| 
 | ||||
|     void WriteOutput(const Regs::ShaderConfig& config, AttributeBuffer& output); | ||||
|     void WriteOutput(const ShaderRegs& config, AttributeBuffer& output); | ||||
| }; | ||||
| 
 | ||||
| struct ShaderSetup { | ||||
|  |  | |||
|  | @ -669,7 +669,7 @@ void InterpreterEngine::Run(const ShaderSetup& setup, UnitState& state) const { | |||
| 
 | ||||
| DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup, | ||||
|                                                     const AttributeBuffer& input, | ||||
|                                                     const Regs::ShaderConfig& config) const { | ||||
|                                                     const ShaderRegs& config) const { | ||||
|     UnitState state; | ||||
|     DebugData<true> debug_data; | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ public: | |||
|      * @return Debug information for this shader with regards to the given vertex | ||||
|      */ | ||||
|     DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const AttributeBuffer& input, | ||||
|                                      const Regs::ShaderConfig& config) const; | ||||
|                                      const ShaderRegs& config) const; | ||||
| }; | ||||
| 
 | ||||
| } // namespace
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue