2014-12-14 20:23:13 +00:00
|
|
|
// Copyright 2013 Dolphin Emulator Project
|
|
|
|
// Licensed under GPLv2
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include <cfloat>
|
|
|
|
#include <cmath>
|
|
|
|
|
2014-12-14 20:44:33 +00:00
|
|
|
#include "VideoCommon/BPMemory.h"
|
2014-12-14 20:23:13 +00:00
|
|
|
#include "VideoCommon/GeometryShaderGen.h"
|
|
|
|
#include "VideoCommon/GeometryShaderManager.h"
|
|
|
|
#include "VideoCommon/VideoCommon.h"
|
|
|
|
#include "VideoCommon/VideoConfig.h"
|
|
|
|
#include "VideoCommon/XFMemory.h"
|
|
|
|
|
2014-12-15 23:21:07 +00:00
|
|
|
static const int LINE_PT_TEX_OFFSETS[8] = {
|
|
|
|
0, 16, 8, 4, 2, 1, 1, 1
|
2014-12-14 20:44:33 +00:00
|
|
|
};
|
2014-12-14 20:23:13 +00:00
|
|
|
|
|
|
|
GeometryShaderConstants GeometryShaderManager::constants;
|
|
|
|
bool GeometryShaderManager::dirty;
|
|
|
|
|
2014-12-20 12:01:37 +00:00
|
|
|
static bool s_projection_changed;
|
|
|
|
|
2014-12-14 20:23:13 +00:00
|
|
|
void GeometryShaderManager::Init()
|
|
|
|
{
|
|
|
|
memset(&constants, 0, sizeof(constants));
|
|
|
|
|
|
|
|
Dirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeometryShaderManager::Shutdown()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeometryShaderManager::Dirty()
|
|
|
|
{
|
2014-12-17 02:11:23 +00:00
|
|
|
SetViewportChanged();
|
|
|
|
SetProjectionChanged();
|
|
|
|
SetLinePtWidthChanged();
|
|
|
|
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
SetTexCoordChanged(i);
|
2014-12-14 20:23:13 +00:00
|
|
|
|
|
|
|
dirty = true;
|
|
|
|
}
|
|
|
|
|
2014-12-20 12:01:37 +00: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 13:06:16 +00:00
|
|
|
float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) * (g_ActiveConfig.iStereoDepthPercentage / 100.0f);
|
2014-12-20 12:01:37 +00:00
|
|
|
constants.stereoparams[0] = (g_ActiveConfig.bStereoSwapEyes) ? offset : -offset;
|
|
|
|
constants.stereoparams[1] = (g_ActiveConfig.bStereoSwapEyes) ? -offset : offset;
|
2014-12-21 13:06:16 +00:00
|
|
|
constants.stereoparams[2] = (g_ActiveConfig.iStereoConvergence / 10.0f) * (g_ActiveConfig.iStereoConvergencePercentage / 100.0f);
|
2014-12-20 12:01:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
constants.stereoparams[0] = constants.stereoparams[1] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
dirty = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-17 02:11:23 +00:00
|
|
|
void GeometryShaderManager::SetViewportChanged()
|
2014-12-14 20:23:13 +00:00
|
|
|
{
|
2014-12-17 02:11:23 +00:00
|
|
|
constants.lineptparams[0] = 2.0f * xfmem.viewport.wd;
|
|
|
|
constants.lineptparams[1] = -2.0f * xfmem.viewport.ht;
|
|
|
|
dirty = true;
|
|
|
|
}
|
2014-12-14 20:44:33 +00:00
|
|
|
|
2014-12-17 02:11:23 +00:00
|
|
|
void GeometryShaderManager::SetProjectionChanged()
|
|
|
|
{
|
2014-12-20 12:01:37 +00:00
|
|
|
s_projection_changed = true;
|
2014-12-14 20:23:13 +00:00
|
|
|
}
|
|
|
|
|
2014-12-14 20:44:33 +00:00
|
|
|
void GeometryShaderManager::SetLinePtWidthChanged()
|
|
|
|
{
|
2014-12-17 02:11:23 +00: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 20:44:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GeometryShaderManager::SetTexCoordChanged(u8 texmapid)
|
|
|
|
{
|
|
|
|
TCoordInfo& tc = bpmem.texcoords[texmapid];
|
2014-12-15 23:21:07 +00: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 20:44:33 +00:00
|
|
|
dirty = true;
|
|
|
|
}
|
|
|
|
|
2014-12-14 20:23:13 +00:00
|
|
|
void GeometryShaderManager::DoState(PointerWrap &p)
|
|
|
|
{
|
|
|
|
if (p.GetMode() == PointerWrap::MODE_READ)
|
|
|
|
{
|
|
|
|
// Reload current state from global GPU state
|
|
|
|
// NOTE: This requires that all GPU memory has been loaded already.
|
|
|
|
Dirty();
|
|
|
|
}
|
|
|
|
}
|