1 // Copyright 2014 Dolphin Emulator Project 2 // Licensed under GPLv2+ 3 // Refer to the license.txt file included. 4 5 #include <cstring> 6 7 #include "Common/ChunkFile.h" 8 #include "Common/CommonTypes.h" 9 #include "VideoCommon/BPMemory.h" 10 #include "VideoCommon/GeometryShaderManager.h" 11 #include "VideoCommon/VideoConfig.h" 12 #include "VideoCommon/XFMemory.h" 13 14 static const int LINE_PT_TEX_OFFSETS[8] = {0, 16, 8, 4, 2, 1, 1, 1}; 15 16 GeometryShaderConstants GeometryShaderManager::constants; 17 bool GeometryShaderManager::dirty; 18 19 static bool s_projection_changed; 20 static bool s_viewport_changed; 21 Init()22void GeometryShaderManager::Init() 23 { 24 constants = {}; 25 26 // Init any intial constants which aren't zero when bpmem is zero. 27 SetViewportChanged(); 28 SetProjectionChanged(); 29 30 dirty = true; 31 } 32 Dirty()33void GeometryShaderManager::Dirty() 34 { 35 // This function is called after a savestate is loaded. 36 // Any constants that can changed based on settings should be re-calculated 37 s_projection_changed = true; 38 39 dirty = true; 40 } 41 SetConstants()42void GeometryShaderManager::SetConstants() 43 { 44 if (s_projection_changed && g_ActiveConfig.stereo_mode != StereoMode::Off) 45 { 46 s_projection_changed = false; 47 48 if (xfmem.projection.type == GX_PERSPECTIVE) 49 { 50 float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) * 51 (g_ActiveConfig.iStereoDepthPercentage / 100.0f); 52 constants.stereoparams[0] = g_ActiveConfig.bStereoSwapEyes ? offset : -offset; 53 constants.stereoparams[1] = g_ActiveConfig.bStereoSwapEyes ? -offset : offset; 54 } 55 else 56 { 57 constants.stereoparams[0] = constants.stereoparams[1] = 0; 58 } 59 60 constants.stereoparams[2] = (float)(g_ActiveConfig.iStereoConvergence * 61 (g_ActiveConfig.iStereoConvergencePercentage / 100.0f)); 62 63 dirty = true; 64 } 65 66 if (s_viewport_changed) 67 { 68 s_viewport_changed = false; 69 70 constants.lineptparams[0] = 2.0f * xfmem.viewport.wd; 71 constants.lineptparams[1] = -2.0f * xfmem.viewport.ht; 72 73 dirty = true; 74 } 75 } 76 SetViewportChanged()77void GeometryShaderManager::SetViewportChanged() 78 { 79 s_viewport_changed = true; 80 } 81 SetProjectionChanged()82void GeometryShaderManager::SetProjectionChanged() 83 { 84 s_projection_changed = true; 85 } 86 SetLinePtWidthChanged()87void GeometryShaderManager::SetLinePtWidthChanged() 88 { 89 constants.lineptparams[2] = bpmem.lineptwidth.linesize / 6.f; 90 constants.lineptparams[3] = bpmem.lineptwidth.pointsize / 6.f; 91 constants.texoffset[2] = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.lineoff]; 92 constants.texoffset[3] = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.pointoff]; 93 dirty = true; 94 } 95 SetTexCoordChanged(u8 texmapid)96void GeometryShaderManager::SetTexCoordChanged(u8 texmapid) 97 { 98 TCoordInfo& tc = bpmem.texcoords[texmapid]; 99 int bitmask = 1 << texmapid; 100 constants.texoffset[0] &= ~bitmask; 101 constants.texoffset[0] |= tc.s.line_offset << texmapid; 102 constants.texoffset[1] &= ~bitmask; 103 constants.texoffset[1] |= tc.s.point_offset << texmapid; 104 dirty = true; 105 } 106 DoState(PointerWrap & p)107void GeometryShaderManager::DoState(PointerWrap& p) 108 { 109 p.Do(s_projection_changed); 110 p.Do(s_viewport_changed); 111 112 p.Do(constants); 113 114 if (p.GetMode() == PointerWrap::MODE_READ) 115 { 116 // Fixup the current state from global GPU state 117 // NOTE: This requires that all GPU memory has been loaded already. 118 Dirty(); 119 } 120 } 121