mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	general: Fixes for Tales of the Abyss (#7381)
* geometry_pipeline: Remove unneeded assert * Has been hw-tested that gs works correctly even when not in exclusive mode * pica_core: Propagate output_mask to gs * Has been hw-tested to occur under the same conditions that other uniforms are shared * regs_shader: Intialize GPUREG_SH_INPUTBUFFER_CONFIG to default value * Default value verified on hw. Tales of Abyss does not update the number of vertex attributes for the geometry unit and expects it to be 2 * texture_codec: Align buffer sizes to bpp * Prevents out of bounds texture reads when launching TOA from the HOME menu * pica_core: Make default value more clear
This commit is contained in:
		
							parent
							
								
									89e13a85a7
								
							
						
					
					
						commit
						bea863efff
					
				
					 5 changed files with 21 additions and 6 deletions
				
			
		|  | @ -337,7 +337,6 @@ void GeometryPipeline::Reconfigure() { | |||
|     // The following assumes that when geometry shader is in use, the shader unit 3 is configured as
 | ||||
|     // a geometry shader unit.
 | ||||
|     // TODO: what happens if this is not true?
 | ||||
|     ASSERT(regs.pipeline.gs_unit_exclusive_configuration == 1); | ||||
|     ASSERT(regs.gs.shader_mode == ShaderRegs::ShaderMode::GS); | ||||
|     ASSERT(regs.pipeline.use_gs == PipelineRegs::UseGS::Yes); | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ PicaCore::PicaCore(Memory::MemorySystem& memory_, std::shared_ptr<DebugContext> | |||
|                                                                                    gs_unit, | ||||
|                                                                                    gs_setup}, | ||||
|       shader_engine{CreateEngine(Settings::values.use_shader_jit.GetValue())} { | ||||
|     SetFramebufferDefaults(); | ||||
|     InitializeRegs(); | ||||
| 
 | ||||
|     const auto submit_vertex = [this](const AttributeBuffer& buffer) { | ||||
|         const auto add_triangle = [this](const OutputVertex& v0, const OutputVertex& v1, | ||||
|  | @ -54,7 +54,7 @@ PicaCore::PicaCore(Memory::MemorySystem& memory_, std::shared_ptr<DebugContext> | |||
| 
 | ||||
| PicaCore::~PicaCore() = default; | ||||
| 
 | ||||
| void PicaCore::SetFramebufferDefaults() { | ||||
| void PicaCore::InitializeRegs() { | ||||
|     auto& framebuffer_top = regs.framebuffer_config[0]; | ||||
|     auto& framebuffer_sub = regs.framebuffer_config[1]; | ||||
| 
 | ||||
|  | @ -77,6 +77,11 @@ void PicaCore::SetFramebufferDefaults() { | |||
|     framebuffer_sub.stride = 3 * 240; | ||||
|     framebuffer_sub.color_format.Assign(PixelFormat::RGB8); | ||||
|     framebuffer_sub.active_fb = 0; | ||||
| 
 | ||||
|     // Tales of Abyss expects this register to have the following default values.
 | ||||
|     auto& gs = regs.internal.gs; | ||||
|     gs.max_input_attribute_index.Assign(1); | ||||
|     gs.shader_mode.Assign(ShaderRegs::ShaderMode::VS); | ||||
| } | ||||
| 
 | ||||
| void PicaCore::BindRasterizer(VideoCore::RasterizerInterface* rasterizer) { | ||||
|  | @ -254,6 +259,13 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) { | |||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     case PICA_REG_INDEX(vs.output_mask): | ||||
|         if (!regs.internal.pipeline.gs_unit_exclusive_configuration && | ||||
|             regs.internal.pipeline.use_gs == PipelineRegs::UseGS::No) { | ||||
|             regs.internal.gs.output_mask.Assign(value); | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case PICA_REG_INDEX(vs.bool_uniforms): | ||||
|         vs_setup.WriteUniformBoolReg(regs.internal.vs.bool_uniforms.Value()); | ||||
|         if (!regs.internal.pipeline.gs_unit_exclusive_configuration && | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ public: | |||
|     void ProcessCmdList(PAddr list, u32 size); | ||||
| 
 | ||||
| private: | ||||
|     void SetFramebufferDefaults(); | ||||
|     void InitializeRegs(); | ||||
| 
 | ||||
|     void WriteInternalReg(u32 id, u32 value, u32 mask); | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ struct ShaderRegs { | |||
| 
 | ||||
|     union { | ||||
|         // Number of input attributes to shader unit - 1
 | ||||
|         u32 input_buffer_config; | ||||
|         BitField<0, 4, u32> max_input_attribute_index; | ||||
|         BitField<8, 8, u32> input_to_uniform; | ||||
|         BitField<24, 8, ShaderMode> shader_mode; | ||||
|  |  | |||
|  | @ -341,8 +341,8 @@ static constexpr void MortonCopy(u32 width, u32 height, u32 start_offset, u32 en | |||
|  */ | ||||
| template <bool decode, PixelFormat format, bool converted = false> | ||||
| static constexpr void LinearCopy(std::span<u8> src_buffer, std::span<u8> dst_buffer) { | ||||
|     const std::size_t src_size = src_buffer.size(); | ||||
|     const std::size_t dst_size = dst_buffer.size(); | ||||
|     std::size_t src_size = src_buffer.size(); | ||||
|     std::size_t dst_size = dst_buffer.size(); | ||||
| 
 | ||||
|     if constexpr (converted) { | ||||
|         constexpr u32 encoded_bytes_per_pixel = GetFormatBpp(format) / 8; | ||||
|  | @ -352,6 +352,9 @@ static constexpr void LinearCopy(std::span<u8> src_buffer, std::span<u8> dst_buf | |||
|         constexpr u32 dst_bytes_per_pixel = | ||||
|             decode ? decoded_bytes_per_pixel : encoded_bytes_per_pixel; | ||||
| 
 | ||||
|         src_size = Common::AlignDown(src_size, src_bytes_per_pixel); | ||||
|         dst_size = Common::AlignDown(dst_size, dst_bytes_per_pixel); | ||||
| 
 | ||||
|         for (std::size_t src_index = 0, dst_index = 0; src_index < src_size && dst_index < dst_size; | ||||
|              src_index += src_bytes_per_pixel, dst_index += dst_bytes_per_pixel) { | ||||
|             const auto src_pixel = src_buffer.subspan(src_index, src_bytes_per_pixel); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue