mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #929 from neobrain/geoshader_definitions
Pica/Shader: Add geometry shader definitions.
This commit is contained in:
		
						commit
						aa6dfdb827
					
				
					 6 changed files with 169 additions and 156 deletions
				
			
		|  | @ -259,7 +259,7 @@ void GraphicsVertexShaderModel::OnUpdate() | ||||||
|     for (auto pattern : Pica::g_state.vs.swizzle_data) |     for (auto pattern : Pica::g_state.vs.swizzle_data) | ||||||
|         info.swizzle_info.push_back({pattern}); |         info.swizzle_info.push_back({pattern}); | ||||||
| 
 | 
 | ||||||
|     info.labels.insert({ Pica::g_state.regs.vs_main_offset, "main" }); |     info.labels.insert({ Pica::g_state.regs.vs.main_offset, "main" }); | ||||||
| 
 | 
 | ||||||
|     endResetModel(); |     endResetModel(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -45,7 +45,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|     if (GPU::g_skip_frame && id != PICA_REG_INDEX(trigger_irq)) |     if (GPU::g_skip_frame && id != PICA_REG_INDEX(trigger_irq)) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     // TODO: Figure out how register masking acts on e.g. vs_uniform_setup.set_value
 |     // TODO: Figure out how register masking acts on e.g. vs.uniform_setup.set_value
 | ||||||
|     u32 old_value = regs[id]; |     u32 old_value = regs[id]; | ||||||
|     regs[id] = (old_value & ~mask) | (value & mask); |     regs[id] = (old_value & ~mask) | (value & mask); | ||||||
| 
 | 
 | ||||||
|  | @ -282,7 +282,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|                                                                    &geometry_dumper, _1, _2, _3)); |                                                                    &geometry_dumper, _1, _2, _3)); | ||||||
| 
 | 
 | ||||||
|                 // Send to vertex shader
 |                 // Send to vertex shader
 | ||||||
|                 VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes()); |                 VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes(), g_state.regs.vs, g_state.vs); | ||||||
| 
 | 
 | ||||||
|                 if (is_indexed) { |                 if (is_indexed) { | ||||||
|                     // TODO: Add processed vertex to vertex cache!
 |                     // TODO: Add processed vertex to vertex cache!
 | ||||||
|  | @ -321,35 +321,35 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case PICA_REG_INDEX(vs_bool_uniforms): |         case PICA_REG_INDEX(vs.bool_uniforms): | ||||||
|             for (unsigned i = 0; i < 16; ++i) |             for (unsigned i = 0; i < 16; ++i) | ||||||
|                 g_state.vs.uniforms.b[i] = (regs.vs_bool_uniforms.Value() & (1 << i)) != 0; |                 g_state.vs.uniforms.b[i] = (regs.vs.bool_uniforms.Value() & (1 << i)) != 0; | ||||||
| 
 | 
 | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[0], 0x2b1): |         case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[1], 0x2b2): |         case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[1], 0x2b2): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[2], 0x2b3): |         case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[2], 0x2b3): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[3], 0x2b4): |         case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[3], 0x2b4): | ||||||
|         { |         { | ||||||
|             int index = (id - PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[0], 0x2b1)); |             int index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1)); | ||||||
|             auto values = regs.vs_int_uniforms[index]; |             auto values = regs.vs.int_uniforms[index]; | ||||||
|             g_state.vs.uniforms.i[index] = Math::Vec4<u8>(values.x, values.y, values.z, values.w); |             g_state.vs.uniforms.i[index] = Math::Vec4<u8>(values.x, values.y, values.z, values.w); | ||||||
|             LOG_TRACE(HW_GPU, "Set integer uniform %d to %02x %02x %02x %02x", |             LOG_TRACE(HW_GPU, "Set integer uniform %d to %02x %02x %02x %02x", | ||||||
|                       index, values.x.Value(), values.y.Value(), values.z.Value(), values.w.Value()); |                       index, values.x.Value(), values.y.Value(), values.z.Value(), values.w.Value()); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[0], 0x2c1): |         case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[0], 0x2c1): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[1], 0x2c2): |         case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[1], 0x2c2): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[2], 0x2c3): |         case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[2], 0x2c3): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[3], 0x2c4): |         case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[3], 0x2c4): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[4], 0x2c5): |         case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[4], 0x2c5): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[5], 0x2c6): |         case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[5], 0x2c6): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[6], 0x2c7): |         case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[6], 0x2c7): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[7], 0x2c8): |         case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[7], 0x2c8): | ||||||
|         { |         { | ||||||
|             auto& uniform_setup = regs.vs_uniform_setup; |             auto& uniform_setup = regs.vs.uniform_setup; | ||||||
| 
 | 
 | ||||||
|             // TODO: Does actual hardware indeed keep an intermediate buffer or does
 |             // TODO: Does actual hardware indeed keep an intermediate buffer or does
 | ||||||
|             //       it directly write the values?
 |             //       it directly write the values?
 | ||||||
|  | @ -392,32 +392,32 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // 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): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[2], 0x2ce): |         case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[2], 0x2ce): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[3], 0x2cf): |         case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[3], 0x2cf): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[4], 0x2d0): |         case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[4], 0x2d0): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[5], 0x2d1): |         case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[5], 0x2d1): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[6], 0x2d2): |         case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[6], 0x2d2): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_program.set_word[7], 0x2d3): |         case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[7], 0x2d3): | ||||||
|         { |         { | ||||||
|             g_state.vs.program_code[regs.vs_program.offset] = value; |             g_state.vs.program_code[regs.vs.program.offset] = value; | ||||||
|             regs.vs_program.offset++; |             regs.vs.program.offset++; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Load swizzle pattern data
 |         // Load swizzle pattern data
 | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_swizzle_patterns.set_word[0], 0x2d6): |         case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[0], 0x2d6): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_swizzle_patterns.set_word[1], 0x2d7): |         case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[1], 0x2d7): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_swizzle_patterns.set_word[2], 0x2d8): |         case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[2], 0x2d8): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_swizzle_patterns.set_word[3], 0x2d9): |         case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[3], 0x2d9): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_swizzle_patterns.set_word[4], 0x2da): |         case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[4], 0x2da): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_swizzle_patterns.set_word[5], 0x2db): |         case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[5], 0x2db): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_swizzle_patterns.set_word[6], 0x2dc): |         case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[6], 0x2dc): | ||||||
|         case PICA_REG_INDEX_WORKAROUND(vs_swizzle_patterns.set_word[7], 0x2dd): |         case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[7], 0x2dd): | ||||||
|         { |         { | ||||||
|             g_state.vs.swizzle_data[regs.vs_swizzle_patterns.offset] = value; |             g_state.vs.swizzle_data[regs.vs.swizzle_patterns.offset] = value; | ||||||
|             regs.vs_swizzle_patterns.offset++; |             regs.vs.swizzle_patterns.offset++; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -788,25 +788,27 @@ struct Regs { | ||||||
|         List   = 0, |         List   = 0, | ||||||
|         Strip  = 1, |         Strip  = 1, | ||||||
|         Fan    = 2, |         Fan    = 2, | ||||||
|         ListIndexed = 3, // TODO: No idea if this is correct
 |         Shader = 3, // Programmable setup unit implemented in a geometry shader
 | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     BitField<8, 2, TriangleTopology> triangle_topology; |     BitField<8, 2, TriangleTopology> triangle_topology; | ||||||
| 
 | 
 | ||||||
|     INSERT_PADDING_WORDS(0x51); |     INSERT_PADDING_WORDS(0x21); | ||||||
|  | 
 | ||||||
|  |     struct ShaderConfig { | ||||||
|  |         BitField<0, 16, u32> bool_uniforms; | ||||||
| 
 | 
 | ||||||
|     BitField<0, 16, u32> vs_bool_uniforms; |  | ||||||
|         union { |         union { | ||||||
|             BitField< 0, 8, u32> x; |             BitField< 0, 8, u32> x; | ||||||
|             BitField< 8, 8, u32> y; |             BitField< 8, 8, u32> y; | ||||||
|             BitField<16, 8, u32> z; |             BitField<16, 8, u32> z; | ||||||
|             BitField<24, 8, u32> w; |             BitField<24, 8, u32> w; | ||||||
|     } vs_int_uniforms[4]; |         } int_uniforms[4]; | ||||||
| 
 | 
 | ||||||
|         INSERT_PADDING_WORDS(0x5); |         INSERT_PADDING_WORDS(0x5); | ||||||
| 
 | 
 | ||||||
|         // Offset to shader program entry point (in words)
 |         // Offset to shader program entry point (in words)
 | ||||||
|     BitField<0, 16, u32> vs_main_offset; |         BitField<0, 16, u32> main_offset; | ||||||
| 
 | 
 | ||||||
|         union { |         union { | ||||||
|             BitField< 0, 4, u64> attribute0_register; |             BitField< 0, 4, u64> attribute0_register; | ||||||
|  | @ -835,8 +837,9 @@ struct Regs { | ||||||
|                 }; |                 }; | ||||||
|                 return (int)fields[attribute_index]; |                 return (int)fields[attribute_index]; | ||||||
|             } |             } | ||||||
|     } vs_input_register_map; |         } input_register_map; | ||||||
| 
 | 
 | ||||||
|  |         // OUTMAP_MASK, 0x28E, CODETRANSFER_END
 | ||||||
|         INSERT_PADDING_WORDS(0x3); |         INSERT_PADDING_WORDS(0x3); | ||||||
| 
 | 
 | ||||||
|         struct { |         struct { | ||||||
|  | @ -853,16 +856,16 @@ struct Regs { | ||||||
|             union { |             union { | ||||||
|                 // Index of the next uniform to write to
 |                 // 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: 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<0, 7, u32> index; | ||||||
| 
 | 
 | ||||||
|                 BitField<31, 1, Format> format; |                 BitField<31, 1, Format> format; | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|         // Writing to these registers sets the "current" uniform.
 |             // Writing to these registers sets the current uniform.
 | ||||||
|         // TODO: It's not clear how the hardware stores what the "current" uniform is.
 |  | ||||||
|             u32 set_value[8]; |             u32 set_value[8]; | ||||||
| 
 | 
 | ||||||
|     } vs_uniform_setup; |         } uniform_setup; | ||||||
| 
 | 
 | ||||||
|         INSERT_PADDING_WORDS(0x2); |         INSERT_PADDING_WORDS(0x2); | ||||||
| 
 | 
 | ||||||
|  | @ -872,9 +875,8 @@ struct Regs { | ||||||
|             u32 offset; |             u32 offset; | ||||||
| 
 | 
 | ||||||
|             // Writing to these registers sets the "current" word in the shader program.
 |             // Writing to these registers sets the "current" word in the shader program.
 | ||||||
|         // TODO: It's not clear how the hardware stores what the "current" word is.
 |  | ||||||
|             u32 set_word[8]; |             u32 set_word[8]; | ||||||
|     } vs_program; |         } program; | ||||||
| 
 | 
 | ||||||
|         INSERT_PADDING_WORDS(0x1); |         INSERT_PADDING_WORDS(0x1); | ||||||
| 
 | 
 | ||||||
|  | @ -885,12 +887,17 @@ struct Regs { | ||||||
|             // Incremented with each instruction write.
 |             // Incremented with each instruction write.
 | ||||||
|             u32 offset; |             u32 offset; | ||||||
| 
 | 
 | ||||||
|         // Writing to these registers sets the "current" swizzle pattern in the table.
 |             // Writing to these registers sets the current swizzle pattern in the table.
 | ||||||
|         // TODO: It's not clear how the hardware stores what the "current" swizzle pattern is.
 |  | ||||||
|             u32 set_word[8]; |             u32 set_word[8]; | ||||||
|     } vs_swizzle_patterns; |         } swizzle_patterns; | ||||||
| 
 | 
 | ||||||
|     INSERT_PADDING_WORDS(0x22); |         INSERT_PADDING_WORDS(0x2); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     ShaderConfig gs; | ||||||
|  |     ShaderConfig vs; | ||||||
|  | 
 | ||||||
|  |     INSERT_PADDING_WORDS(0x20); | ||||||
| 
 | 
 | ||||||
|     // Map register indices to names readable by humans
 |     // Map register indices to names readable by humans
 | ||||||
|     // Used for debugging purposes, so performance is not an issue here
 |     // Used for debugging purposes, so performance is not an issue here
 | ||||||
|  | @ -937,13 +944,20 @@ struct Regs { | ||||||
|         ADD_FIELD(vs_default_attributes_setup); |         ADD_FIELD(vs_default_attributes_setup); | ||||||
|         ADD_FIELD(command_buffer); |         ADD_FIELD(command_buffer); | ||||||
|         ADD_FIELD(triangle_topology); |         ADD_FIELD(triangle_topology); | ||||||
|         ADD_FIELD(vs_bool_uniforms); |         ADD_FIELD(gs.bool_uniforms); | ||||||
|         ADD_FIELD(vs_int_uniforms); |         ADD_FIELD(gs.int_uniforms); | ||||||
|         ADD_FIELD(vs_main_offset); |         ADD_FIELD(gs.main_offset); | ||||||
|         ADD_FIELD(vs_input_register_map); |         ADD_FIELD(gs.input_register_map); | ||||||
|         ADD_FIELD(vs_uniform_setup); |         ADD_FIELD(gs.uniform_setup); | ||||||
|         ADD_FIELD(vs_program); |         ADD_FIELD(gs.program); | ||||||
|         ADD_FIELD(vs_swizzle_patterns); |         ADD_FIELD(gs.swizzle_patterns); | ||||||
|  |         ADD_FIELD(vs.bool_uniforms); | ||||||
|  |         ADD_FIELD(vs.int_uniforms); | ||||||
|  |         ADD_FIELD(vs.main_offset); | ||||||
|  |         ADD_FIELD(vs.input_register_map); | ||||||
|  |         ADD_FIELD(vs.uniform_setup); | ||||||
|  |         ADD_FIELD(vs.program); | ||||||
|  |         ADD_FIELD(vs.swizzle_patterns); | ||||||
| 
 | 
 | ||||||
|         #undef ADD_FIELD |         #undef ADD_FIELD | ||||||
| 
 | 
 | ||||||
|  | @ -1015,17 +1029,14 @@ ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f); | ||||||
| ASSERT_REG_POSITION(vs_default_attributes_setup, 0x232); | ASSERT_REG_POSITION(vs_default_attributes_setup, 0x232); | ||||||
| ASSERT_REG_POSITION(command_buffer, 0x238); | ASSERT_REG_POSITION(command_buffer, 0x238); | ||||||
| ASSERT_REG_POSITION(triangle_topology, 0x25e); | ASSERT_REG_POSITION(triangle_topology, 0x25e); | ||||||
| ASSERT_REG_POSITION(vs_bool_uniforms, 0x2b0); | ASSERT_REG_POSITION(gs, 0x280); | ||||||
| ASSERT_REG_POSITION(vs_int_uniforms, 0x2b1); | ASSERT_REG_POSITION(vs, 0x2b0); | ||||||
| ASSERT_REG_POSITION(vs_main_offset, 0x2ba); |  | ||||||
| ASSERT_REG_POSITION(vs_input_register_map, 0x2bb); |  | ||||||
| ASSERT_REG_POSITION(vs_uniform_setup, 0x2c0); |  | ||||||
| ASSERT_REG_POSITION(vs_program, 0x2cb); |  | ||||||
| ASSERT_REG_POSITION(vs_swizzle_patterns, 0x2d5); |  | ||||||
| 
 | 
 | ||||||
| #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 anyway.
 | // 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), "Register set structure larger than it should be"); | static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), "Register set structure larger than it should be"); | ||||||
| static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), "Register set structure smaller than it should be"); | static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), "Register set structure smaller than it should be"); | ||||||
|  | @ -1135,7 +1146,7 @@ struct State { | ||||||
|     Regs regs; |     Regs regs; | ||||||
| 
 | 
 | ||||||
|     /// Vertex shader memory
 |     /// Vertex shader memory
 | ||||||
|     struct { |     struct ShaderSetup { | ||||||
|         struct { |         struct { | ||||||
|             Math::Vec4<float24> f[96]; |             Math::Vec4<float24> f[96]; | ||||||
|             std::array<bool, 16> b; |             std::array<bool, 16> b; | ||||||
|  | @ -1146,7 +1157,10 @@ struct State { | ||||||
| 
 | 
 | ||||||
|         std::array<u32, 1024> program_code; |         std::array<u32, 1024> program_code; | ||||||
|         std::array<u32, 1024> swizzle_data; |         std::array<u32, 1024> swizzle_data; | ||||||
|     } vs; |     }; | ||||||
|  | 
 | ||||||
|  |     ShaderSetup vs; | ||||||
|  |     ShaderSetup gs; | ||||||
| 
 | 
 | ||||||
|     /// Current Pica command list
 |     /// Current Pica command list
 | ||||||
|     struct { |     struct { | ||||||
|  |  | ||||||
|  | @ -20,8 +20,9 @@ template<typename VertexType> | ||||||
| void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler) | void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler) | ||||||
| { | { | ||||||
|     switch (topology) { |     switch (topology) { | ||||||
|  |         // TODO: Figure out what's different with TriangleTopology::Shader.
 | ||||||
|         case Regs::TriangleTopology::List: |         case Regs::TriangleTopology::List: | ||||||
|         case Regs::TriangleTopology::ListIndexed: |         case Regs::TriangleTopology::Shader: | ||||||
|             if (buffer_index < 2) { |             if (buffer_index < 2) { | ||||||
|                 buffer[buffer_index++] = vtx; |                 buffer[buffer_index++] = vtx; | ||||||
|             } else { |             } else { | ||||||
|  |  | ||||||
|  | @ -546,20 +546,18 @@ static void ProcessShaderCode(VertexShaderState& state) { | ||||||
| 
 | 
 | ||||||
| static Common::Profiling::TimingCategory shader_category("Vertex Shader"); | static Common::Profiling::TimingCategory shader_category("Vertex Shader"); | ||||||
| 
 | 
 | ||||||
| OutputVertex RunShader(const InputVertex& input, int num_attributes) { | OutputVertex RunShader(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const State::ShaderSetup& setup) { | ||||||
|     Common::Profiling::ScopeTimer timer(shader_category); |     Common::Profiling::ScopeTimer timer(shader_category); | ||||||
| 
 | 
 | ||||||
|     const auto& regs = g_state.regs; |  | ||||||
|     const auto& vs = g_state.vs; |  | ||||||
|     VertexShaderState state; |     VertexShaderState state; | ||||||
| 
 | 
 | ||||||
|     const u32* main = &vs.program_code[regs.vs_main_offset]; |     const u32* main = &setup.program_code[config.main_offset]; | ||||||
|     state.program_counter = (u32*)main; |     state.program_counter = (u32*)main; | ||||||
|     state.debug.max_offset = 0; |     state.debug.max_offset = 0; | ||||||
|     state.debug.max_opdesc_id = 0; |     state.debug.max_opdesc_id = 0; | ||||||
| 
 | 
 | ||||||
|     // Setup input register table
 |     // Setup input register table
 | ||||||
|     const auto& attribute_register_map = regs.vs_input_register_map; |     const auto& attribute_register_map = config.input_register_map; | ||||||
|     float24 dummy_register; |     float24 dummy_register; | ||||||
|     boost::fill(state.input_register_table, &dummy_register); |     boost::fill(state.input_register_table, &dummy_register); | ||||||
| 
 | 
 | ||||||
|  | @ -584,16 +582,16 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes) { | ||||||
|     state.conditional_code[1] = false; |     state.conditional_code[1] = false; | ||||||
| 
 | 
 | ||||||
|     ProcessShaderCode(state); |     ProcessShaderCode(state); | ||||||
|     DebugUtils::DumpShader(vs.program_code.data(), state.debug.max_offset, vs.swizzle_data.data(), |     DebugUtils::DumpShader(setup.program_code.data(), state.debug.max_offset, setup.swizzle_data.data(), | ||||||
|                            state.debug.max_opdesc_id, regs.vs_main_offset, |                            state.debug.max_opdesc_id, config.main_offset, | ||||||
|                            regs.vs_output_attributes); |                            g_state.regs.vs_output_attributes); // TODO: Don't hardcode VS here
 | ||||||
| 
 | 
 | ||||||
|     // Setup output data
 |     // Setup output data
 | ||||||
|     OutputVertex ret; |     OutputVertex ret; | ||||||
|     // TODO(neobrain): Under some circumstances, up to 16 attributes may be output. We need to
 |     // TODO(neobrain): Under some circumstances, up to 16 attributes may be output. We need to
 | ||||||
|     // figure out what those circumstances are and enable the remaining outputs then.
 |     // figure out what those circumstances are and enable the remaining outputs then.
 | ||||||
|     for (int i = 0; i < 7; ++i) { |     for (int i = 0; i < 7; ++i) { | ||||||
|         const auto& output_register_map = regs.vs_output_attributes[i]; |         const auto& output_register_map = g_state.regs.vs_output_attributes[i]; // TODO: Don't hardcode VS here
 | ||||||
| 
 | 
 | ||||||
|         u32 semantics[4] = { |         u32 semantics[4] = { | ||||||
|             output_register_map.map_x, output_register_map.map_y, |             output_register_map.map_x, output_register_map.map_y, | ||||||
|  |  | ||||||
|  | @ -65,7 +65,7 @@ struct OutputVertex { | ||||||
| static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); | static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); | ||||||
| static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size"); | static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size"); | ||||||
| 
 | 
 | ||||||
| OutputVertex RunShader(const InputVertex& input, int num_attributes); | OutputVertex RunShader(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const State::ShaderSetup& setup); | ||||||
| 
 | 
 | ||||||
| } // namespace
 | } // namespace
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue