VideoCore: Split shader regs from Regs struct
This commit is contained in:
		| @@ -36,6 +36,7 @@ set(HEADERS | |||||||
|             regs_lighting.h |             regs_lighting.h | ||||||
|             regs_pipeline.h |             regs_pipeline.h | ||||||
|             regs_rasterizer.h |             regs_rasterizer.h | ||||||
|  |             regs_shader.h | ||||||
|             regs_texturing.h |             regs_texturing.h | ||||||
|             renderer_base.h |             renderer_base.h | ||||||
|             renderer_opengl/gl_rasterizer.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 { | 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 Shader::ShaderSetup& setup, | ||||||
|                 const RasterizerRegs::VSOutputAttributes* output_attributes) { |                 const RasterizerRegs::VSOutputAttributes* output_attributes) { | ||||||
|     struct StuffToWrite { |     struct StuffToWrite { | ||||||
|   | |||||||
| @@ -182,7 +182,7 @@ namespace DebugUtils { | |||||||
| #define PICA_DUMP_TEXTURES 0 | #define PICA_DUMP_TEXTURES 0 | ||||||
| #define PICA_LOG_TEV 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 Shader::ShaderSetup& setup, | ||||||
|                 const RasterizerRegs::VSOutputAttributes* output_attributes); |                 const RasterizerRegs::VSOutputAttributes* output_attributes); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ | |||||||
| #include "video_core/regs_lighting.h" | #include "video_core/regs_lighting.h" | ||||||
| #include "video_core/regs_pipeline.h" | #include "video_core/regs_pipeline.h" | ||||||
| #include "video_core/regs_rasterizer.h" | #include "video_core/regs_rasterizer.h" | ||||||
|  | #include "video_core/regs_shader.h" | ||||||
| #include "video_core/regs_texturing.h" | #include "video_core/regs_texturing.h" | ||||||
|  |  | ||||||
| namespace Pica { | namespace Pica { | ||||||
| @@ -57,97 +58,8 @@ struct Regs { | |||||||
|     FramebufferRegs framebuffer; |     FramebufferRegs framebuffer; | ||||||
|     LightingRegs lighting; |     LightingRegs lighting; | ||||||
|     PipelineRegs pipeline; |     PipelineRegs pipeline; | ||||||
|  |     ShaderRegs gs; | ||||||
|     struct ShaderConfig { |     ShaderRegs vs; | ||||||
|         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; |  | ||||||
|  |  | ||||||
|     INSERT_PADDING_WORDS(0x20); |     INSERT_PADDING_WORDS(0x20); | ||||||
|  |  | ||||||
|     // Map register indices to names readable by humans |     // Map register indices to names readable by humans | ||||||
| @@ -247,9 +159,6 @@ ASSERT_REG_POSITION(vs, 0x2b0); | |||||||
| #undef ASSERT_REG_POSITION | #undef ASSERT_REG_POSITION | ||||||
| #endif // !defined(_MSC_VER) | #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 | // The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value | ||||||
| // anyway. | // anyway. | ||||||
| static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), | 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; |     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; |     const unsigned max_attribute = config.max_input_attribute_index; | ||||||
|  |  | ||||||
|     for (unsigned attr = 0; attr <= max_attribute; ++attr) { |     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; |     unsigned int output_i = 0; | ||||||
|     for (unsigned int reg : Common::BitSet<u32>(config.output_mask)) { |     for (unsigned int reg : Common::BitSet<u32>(config.output_mask)) { | ||||||
|         output.attr[output_i++] = registers.output[reg]; |         output.attr[output_i++] = registers.output[reg]; | ||||||
|   | |||||||
| @@ -116,9 +116,9 @@ struct UnitState { | |||||||
|      * @param config Shader configuration registers corresponding to the unit. |      * @param config Shader configuration registers corresponding to the unit. | ||||||
|      * @param input Attribute buffer to load into the input registers. |      * @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 { | struct ShaderSetup { | ||||||
|   | |||||||
| @@ -669,7 +669,7 @@ void InterpreterEngine::Run(const ShaderSetup& setup, UnitState& state) const { | |||||||
|  |  | ||||||
| DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup, | DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup, | ||||||
|                                                     const AttributeBuffer& input, |                                                     const AttributeBuffer& input, | ||||||
|                                                     const Regs::ShaderConfig& config) const { |                                                     const ShaderRegs& config) const { | ||||||
|     UnitState state; |     UnitState state; | ||||||
|     DebugData<true> debug_data; |     DebugData<true> debug_data; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ public: | |||||||
|      * @return Debug information for this shader with regards to the given vertex |      * @return Debug information for this shader with regards to the given vertex | ||||||
|      */ |      */ | ||||||
|     DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const AttributeBuffer& input, |     DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const AttributeBuffer& input, | ||||||
|                                      const Regs::ShaderConfig& config) const; |                                      const ShaderRegs& config) const; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace | } // namespace | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user