| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2014 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 16:54:31 -05:00
										 |  |  | #include <cstring>
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 16:54:31 -05:00
										 |  |  | #include "Common/ChunkFile.h"
 | 
					
						
							|  |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | #include "VideoCommon/BPMemory.h"
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | #include "VideoCommon/GeometryShaderManager.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/VideoConfig.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/XFMemory.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static const int LINE_PT_TEX_OFFSETS[8] = {0, 16, 8, 4, 2, 1, 1, 1}; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | GeometryShaderConstants GeometryShaderManager::constants; | 
					
						
							|  |  |  | bool GeometryShaderManager::dirty; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-20 13:01:37 +01:00
										 |  |  | static bool s_projection_changed; | 
					
						
							| 
									
										
										
										
											2014-12-26 17:58:59 +01:00
										 |  |  | static bool s_viewport_changed; | 
					
						
							| 
									
										
										
										
											2014-12-20 13:01:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | void GeometryShaderManager::Init() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-12-10 17:07:28 -05:00
										 |  |  |   constants = {}; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // Init any intial constants which aren't zero when bpmem is zero.
 | 
					
						
							|  |  |  |   SetViewportChanged(); | 
					
						
							|  |  |  |   SetProjectionChanged(); | 
					
						
							| 
									
										
										
										
											2015-01-16 05:29:39 +13:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   dirty = true; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GeometryShaderManager::Dirty() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // This function is called after a savestate is loaded.
 | 
					
						
							|  |  |  |   // Any constants that can changed based on settings should be re-calculated
 | 
					
						
							|  |  |  |   s_projection_changed = true; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   dirty = true; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-20 13:01:37 +01:00
										 |  |  | void GeometryShaderManager::SetConstants() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (s_projection_changed && g_ActiveConfig.iStereoMode > 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     s_projection_changed = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (xfmem.projection.type == GX_PERSPECTIVE) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) * | 
					
						
							|  |  |  |                      (g_ActiveConfig.iStereoDepthPercentage / 100.0f); | 
					
						
							|  |  |  |       constants.stereoparams[0] = g_ActiveConfig.bStereoSwapEyes ? offset : -offset; | 
					
						
							|  |  |  |       constants.stereoparams[1] = g_ActiveConfig.bStereoSwapEyes ? -offset : offset; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       constants.stereoparams[0] = constants.stereoparams[1] = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constants.stereoparams[2] = (float)(g_ActiveConfig.iStereoConvergence * | 
					
						
							|  |  |  |                                         (g_ActiveConfig.iStereoConvergencePercentage / 100.0f)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dirty = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (s_viewport_changed) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     s_viewport_changed = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constants.lineptparams[0] = 2.0f * xfmem.viewport.wd; | 
					
						
							|  |  |  |     constants.lineptparams[1] = -2.0f * xfmem.viewport.ht; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dirty = true; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-20 13:01:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-17 03:11:23 +01:00
										 |  |  | void GeometryShaderManager::SetViewportChanged() | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   s_viewport_changed = true; | 
					
						
							| 
									
										
										
										
											2014-12-17 03:11:23 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-17 03:11:23 +01:00
										 |  |  | void GeometryShaderManager::SetProjectionChanged() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   s_projection_changed = true; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | void GeometryShaderManager::SetLinePtWidthChanged() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   constants.lineptparams[2] = bpmem.lineptwidth.linesize / 6.f; | 
					
						
							|  |  |  |   constants.lineptparams[3] = bpmem.lineptwidth.pointsize / 6.f; | 
					
						
							|  |  |  |   constants.texoffset[2] = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.lineoff]; | 
					
						
							|  |  |  |   constants.texoffset[3] = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.pointoff]; | 
					
						
							|  |  |  |   dirty = true; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GeometryShaderManager::SetTexCoordChanged(u8 texmapid) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   TCoordInfo& tc = bpmem.texcoords[texmapid]; | 
					
						
							|  |  |  |   int bitmask = 1 << texmapid; | 
					
						
							|  |  |  |   constants.texoffset[0] &= ~bitmask; | 
					
						
							|  |  |  |   constants.texoffset[0] |= tc.s.line_offset << texmapid; | 
					
						
							|  |  |  |   constants.texoffset[1] &= ~bitmask; | 
					
						
							|  |  |  |   constants.texoffset[1] |= tc.s.point_offset << texmapid; | 
					
						
							|  |  |  |   dirty = true; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | void GeometryShaderManager::DoState(PointerWrap& p) | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   p.Do(s_projection_changed); | 
					
						
							|  |  |  |   p.Do(s_viewport_changed); | 
					
						
							| 
									
										
										
										
											2015-01-16 05:29:39 +13:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   p.Do(constants); | 
					
						
							| 
									
										
										
										
											2015-01-16 05:29:39 +13:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (p.GetMode() == PointerWrap::MODE_READ) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // Fixup the current state from global GPU state
 | 
					
						
							|  |  |  |     // NOTE: This requires that all GPU memory has been loaded already.
 | 
					
						
							|  |  |  |     Dirty(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | } |