| 
									
										
										
										
											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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <cfloat>
 | 
					
						
							|  |  |  | #include <cmath>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | #include "VideoCommon/BPMemory.h"
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | #include "VideoCommon/GeometryShaderGen.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/GeometryShaderManager.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/VideoCommon.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/VideoConfig.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/XFMemory.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-16 00:21:07 +01:00
										 |  |  | static const int LINE_PT_TEX_OFFSETS[8] = { | 
					
						
							|  |  |  | 	0, 16, 8, 4, 2, 1, 1, 1 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											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() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	memset(&constants, 0, sizeof(constants)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-16 05:29:39 +13:00
										 |  |  | 	// Init any intial constants which aren't zero when bpmem is zero.
 | 
					
						
							|  |  |  | 	SetViewportChanged(); | 
					
						
							|  |  |  | 	SetProjectionChanged(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dirty = true; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GeometryShaderManager::Shutdown() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GeometryShaderManager::Dirty() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-16 05:29:39 +13: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
										 |  |  | 
 | 
					
						
							|  |  |  | 	dirty = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-20 13:01:37 +01:00
										 |  |  | void GeometryShaderManager::SetConstants() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (s_projection_changed && g_ActiveConfig.iStereoMode > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		s_projection_changed = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (xfmem.projection.type == GX_PERSPECTIVE) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-12-21 14:06:16 +01:00
										 |  |  | 			float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) * (g_ActiveConfig.iStereoDepthPercentage / 100.0f); | 
					
						
							| 
									
										
										
										
											2014-12-21 14:18:21 +01:00
										 |  |  | 			constants.stereoparams[0] = g_ActiveConfig.bStereoSwapEyes ? offset : -offset; | 
					
						
							|  |  |  | 			constants.stereoparams[1] = g_ActiveConfig.bStereoSwapEyes ? -offset : offset; | 
					
						
							| 
									
										
										
										
											2014-12-20 13:01:37 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			constants.stereoparams[0] = constants.stereoparams[1] = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-10 22:14:21 +02:00
										 |  |  | 		constants.stereoparams[2] = (float)(g_ActiveConfig.iStereoConvergence * (g_ActiveConfig.iStereoConvergencePercentage / 100.0f)); | 
					
						
							| 
									
										
										
										
											2015-01-02 15:27:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-20 13:01:37 +01:00
										 |  |  | 		dirty = true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-26 17:58:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-12-26 17:58:59 +01: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() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-12-20 13:01:37 +01:00
										 |  |  | 	s_projection_changed = true; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | void GeometryShaderManager::SetLinePtWidthChanged() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-12-17 03:11:23 +01: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) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	TCoordInfo& tc = bpmem.texcoords[texmapid]; | 
					
						
							| 
									
										
										
										
											2014-12-16 00:21:07 +01:00
										 |  |  | 	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; | 
					
						
							| 
									
										
										
										
											2014-12-14 21:44:33 +01:00
										 |  |  | 	dirty = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | void GeometryShaderManager::DoState(PointerWrap &p) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-16 05:29:39 +13:00
										 |  |  | 	p.Do(s_projection_changed); | 
					
						
							|  |  |  | 	p.Do(s_viewport_changed); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p.Do(constants); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | 	if (p.GetMode() == PointerWrap::MODE_READ) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-01-16 05:29:39 +13:00
										 |  |  | 		// Fixup the current state from global GPU state
 | 
					
						
							| 
									
										
										
										
											2014-12-14 21:23:13 +01:00
										 |  |  | 		// NOTE: This requires that all GPU memory has been loaded already.
 | 
					
						
							|  |  |  | 		Dirty(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |