| 
									
										
										
										
											2018-02-11 21:34:20 -05:00
										 |  |  | // Copyright 2018 yuzu Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  | #include <array>
 | 
					
						
							| 
									
										
										
										
											2019-03-05 20:25:01 -05:00
										 |  |  | #include <cstddef>
 | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  | #include <vector>
 | 
					
						
							|  |  |  | #include "common/bit_field.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  | #include "common/common_funcs.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-11 21:34:20 -05:00
										 |  |  | #include "common/common_types.h"
 | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  | #include "video_core/engines/engine_upload.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-23 23:20:56 -05:00
										 |  |  | #include "video_core/gpu.h"
 | 
					
						
							| 
									
										
										
										
											2019-04-05 18:21:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  | namespace Core { | 
					
						
							|  |  |  | class System; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-05 18:21:15 -04:00
										 |  |  | namespace Tegra { | 
					
						
							|  |  |  | class MemoryManager; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-11 21:34:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  | namespace VideoCore { | 
					
						
							|  |  |  | class RasterizerInterface; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 18:14:17 -04:00
										 |  |  | namespace Tegra::Engines { | 
					
						
							| 
									
										
										
										
											2018-02-11 21:34:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 20:49:31 -03:00
										 |  |  | #define KEPLER_COMPUTE_REG_INDEX(field_name)                                                       \
 | 
					
						
							|  |  |  |     (offsetof(Tegra::Engines::KeplerCompute::Regs, field_name) / sizeof(u32)) | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 20:49:31 -03:00
										 |  |  | class KeplerCompute final { | 
					
						
							| 
									
										
										
										
											2018-02-11 23:44:12 -05:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  |     explicit KeplerCompute(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 
					
						
							|  |  |  |                            MemoryManager& memory_manager); | 
					
						
							| 
									
										
										
										
											2019-01-22 20:49:31 -03:00
										 |  |  |     ~KeplerCompute(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static constexpr std::size_t NumConstBuffers = 8; | 
					
						
							| 
									
										
										
										
											2018-02-11 21:34:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  |     struct Regs { | 
					
						
							|  |  |  |         static constexpr std::size_t NUM_REGS = 0xCF8; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |             struct { | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  |                 INSERT_PADDING_WORDS(0x60); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 Upload::Data upload; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 struct { | 
					
						
							|  |  |  |                     union { | 
					
						
							|  |  |  |                         BitField<0, 1, u32> linear; | 
					
						
							|  |  |  |                     }; | 
					
						
							|  |  |  |                 } exec_upload; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 u32 data_upload; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 INSERT_PADDING_WORDS(0x3F); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 struct { | 
					
						
							|  |  |  |                     u32 address; | 
					
						
							|  |  |  |                     GPUVAddr Address() const { | 
					
						
							|  |  |  |                         return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address) << 8)); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } launch_desc_loc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 INSERT_PADDING_WORDS(0x1); | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 20:49:31 -03:00
										 |  |  |                 u32 launch; | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  |                 INSERT_PADDING_WORDS(0x4A7); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 struct { | 
					
						
							|  |  |  |                     u32 address_high; | 
					
						
							|  |  |  |                     u32 address_low; | 
					
						
							|  |  |  |                     u32 limit; | 
					
						
							|  |  |  |                     GPUVAddr Address() const { | 
					
						
							|  |  |  |                         return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 
					
						
							|  |  |  |                                                      address_low); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } tsc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 INSERT_PADDING_WORDS(0x3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 struct { | 
					
						
							|  |  |  |                     u32 address_high; | 
					
						
							|  |  |  |                     u32 address_low; | 
					
						
							|  |  |  |                     u32 limit; | 
					
						
							|  |  |  |                     GPUVAddr Address() const { | 
					
						
							|  |  |  |                         return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 
					
						
							|  |  |  |                                                      address_low); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } tic; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 INSERT_PADDING_WORDS(0x22); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 struct { | 
					
						
							|  |  |  |                     u32 address_high; | 
					
						
							|  |  |  |                     u32 address_low; | 
					
						
							|  |  |  |                     GPUVAddr Address() const { | 
					
						
							|  |  |  |                         return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 
					
						
							|  |  |  |                                                      address_low); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } code_loc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 INSERT_PADDING_WORDS(0x3FE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 u32 texture_const_buffer_index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 INSERT_PADDING_WORDS(0x374); | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  |             }; | 
					
						
							|  |  |  |             std::array<u32, NUM_REGS> reg_array; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     } regs{}; | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     struct LaunchParams { | 
					
						
							|  |  |  |         static constexpr std::size_t NUM_LAUNCH_PARAMETERS = 0x40; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         INSERT_PADDING_WORDS(0x8); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         u32 program_start; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         INSERT_PADDING_WORDS(0x2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         BitField<30, 1, u32> linked_tsc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         BitField<0, 31, u32> grid_dim_x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |             BitField<0, 16, u32> grid_dim_y; | 
					
						
							|  |  |  |             BitField<16, 16, u32> grid_dim_z; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         INSERT_PADDING_WORDS(0x3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         BitField<0, 16, u32> shared_alloc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         BitField<0, 31, u32> block_dim_x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |             BitField<0, 16, u32> block_dim_y; | 
					
						
							|  |  |  |             BitField<16, 16, u32> block_dim_z; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |             BitField<0, 8, u32> const_buffer_enable_mask; | 
					
						
							|  |  |  |             BitField<29, 2, u32> cache_layout; | 
					
						
							|  |  |  |         } memory_config; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         INSERT_PADDING_WORDS(0x8); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         struct { | 
					
						
							|  |  |  |             u32 address_low; | 
					
						
							|  |  |  |             union { | 
					
						
							|  |  |  |                 BitField<0, 8, u32> address_high; | 
					
						
							|  |  |  |                 BitField<15, 17, u32> size; | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |             GPUVAddr Address() const { | 
					
						
							|  |  |  |                 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high.Value()) << 32) | | 
					
						
							|  |  |  |                                              address_low); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } const_buffer_config[8]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |             BitField<0, 20, u32> local_pos_alloc; | 
					
						
							|  |  |  |             BitField<27, 5, u32> barrier_alloc; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |             BitField<0, 20, u32> local_neg_alloc; | 
					
						
							|  |  |  |             BitField<24, 5, u32> gpr_alloc; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         INSERT_PADDING_WORDS(0x11); | 
					
						
							|  |  |  |     } launch_description; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |         u32 write_offset = 0; | 
					
						
							|  |  |  |         u32 copy_size = 0; | 
					
						
							|  |  |  |         std::vector<u8> inner_buffer; | 
					
						
							|  |  |  |     } state{}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  |     static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), | 
					
						
							| 
									
										
										
										
											2019-01-22 20:49:31 -03:00
										 |  |  |                   "KeplerCompute Regs has wrong size"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  |     static_assert(sizeof(LaunchParams) == LaunchParams::NUM_LAUNCH_PARAMETERS * sizeof(u32), | 
					
						
							|  |  |  |                   "KeplerCompute LaunchParams has wrong size"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 23:44:12 -05:00
										 |  |  |     /// Write the value to the register identified by method.
 | 
					
						
							| 
									
										
										
										
											2018-11-23 23:20:56 -05:00
										 |  |  |     void CallMethod(const GPU::MethodCall& method_call); | 
					
						
							| 
									
										
										
										
											2019-04-05 18:25:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  |     Core::System& system; | 
					
						
							|  |  |  |     VideoCore::RasterizerInterface& rasterizer; | 
					
						
							| 
									
										
										
										
											2019-04-05 18:25:20 -04:00
										 |  |  |     MemoryManager& memory_manager; | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  |     Upload::State upload_state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void ProcessLaunch(); | 
					
						
							| 
									
										
										
										
											2018-02-11 23:44:12 -05:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-02-11 21:34:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  | #define ASSERT_REG_POSITION(field_name, position)                                                  \
 | 
					
						
							| 
									
										
										
										
											2019-01-22 20:49:31 -03:00
										 |  |  |     static_assert(offsetof(KeplerCompute::Regs, field_name) == position * 4,                       \ | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  |                   "Field " #field_name " has invalid position") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  | #define ASSERT_LAUNCH_PARAM_POSITION(field_name, position)                                         \
 | 
					
						
							|  |  |  |     static_assert(offsetof(KeplerCompute::LaunchParams, field_name) == position * 4,               \ | 
					
						
							|  |  |  |                   "Field " #field_name " has invalid position") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASSERT_REG_POSITION(upload, 0x60); | 
					
						
							|  |  |  | ASSERT_REG_POSITION(exec_upload, 0x6C); | 
					
						
							|  |  |  | ASSERT_REG_POSITION(data_upload, 0x6D); | 
					
						
							| 
									
										
										
										
											2019-01-22 20:49:31 -03:00
										 |  |  | ASSERT_REG_POSITION(launch, 0xAF); | 
					
						
							| 
									
										
										
										
											2019-04-22 19:05:43 -04:00
										 |  |  | ASSERT_REG_POSITION(tsc, 0x557); | 
					
						
							|  |  |  | ASSERT_REG_POSITION(tic, 0x55D); | 
					
						
							|  |  |  | ASSERT_REG_POSITION(code_loc, 0x582); | 
					
						
							|  |  |  | ASSERT_REG_POSITION(texture_const_buffer_index, 0x982); | 
					
						
							|  |  |  | ASSERT_LAUNCH_PARAM_POSITION(program_start, 0x8); | 
					
						
							|  |  |  | ASSERT_LAUNCH_PARAM_POSITION(grid_dim_x, 0xC); | 
					
						
							|  |  |  | ASSERT_LAUNCH_PARAM_POSITION(shared_alloc, 0x11); | 
					
						
							|  |  |  | ASSERT_LAUNCH_PARAM_POSITION(block_dim_x, 0x12); | 
					
						
							|  |  |  | ASSERT_LAUNCH_PARAM_POSITION(memory_config, 0x14); | 
					
						
							|  |  |  | ASSERT_LAUNCH_PARAM_POSITION(const_buffer_config, 0x1D); | 
					
						
							| 
									
										
										
										
											2018-09-25 19:41:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef ASSERT_REG_POSITION
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 18:14:17 -04:00
										 |  |  | } // namespace Tegra::Engines
 |