2015-05-23 22:55:12 -06:00
|
|
|
// Copyright 2014 Dolphin Emulator Project
|
2021-07-04 19:22:19 -06:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2014-12-14 13:23:13 -07:00
|
|
|
|
2021-12-09 19:22:16 -07:00
|
|
|
#include "VideoCommon/GeometryShaderManager.h"
|
|
|
|
|
2016-01-17 14:54:31 -07:00
|
|
|
#include <cstring>
|
2014-12-14 13:23:13 -07:00
|
|
|
|
2016-01-17 14:54:31 -07:00
|
|
|
#include "Common/ChunkFile.h"
|
|
|
|
#include "Common/CommonTypes.h"
|
2014-12-14 13:44:33 -07:00
|
|
|
#include "VideoCommon/BPMemory.h"
|
2022-07-22 23:47:04 -06:00
|
|
|
#include "VideoCommon/RenderState.h"
|
2014-12-14 13:23:13 -07:00
|
|
|
#include "VideoCommon/VideoConfig.h"
|
|
|
|
#include "VideoCommon/XFMemory.h"
|
|
|
|
|
2022-12-29 07:27:48 -07:00
|
|
|
static constexpr int LINE_PT_TEX_OFFSETS[8] = {0, 16, 8, 4, 2, 1, 1, 1};
|
2014-12-20 05:01:37 -07:00
|
|
|
|
2014-12-14 13:23:13 -07:00
|
|
|
void GeometryShaderManager::Init()
|
|
|
|
{
|
2016-12-10 15:07:28 -07:00
|
|
|
constants = {};
|
2014-12-14 13:23:13 -07:00
|
|
|
|
2015-01-15 09:29:39 -07:00
|
|
|
// Init any intial constants which aren't zero when bpmem is zero.
|
|
|
|
SetViewportChanged();
|
|
|
|
SetProjectionChanged();
|
|
|
|
|
|
|
|
dirty = true;
|
2014-12-14 13:23:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void GeometryShaderManager::Dirty()
|
|
|
|
{
|
2015-01-15 09:29:39 -07:00
|
|
|
// This function is called after a savestate is loaded.
|
|
|
|
// Any constants that can changed based on settings should be re-calculated
|
2022-12-29 07:27:48 -07:00
|
|
|
m_projection_changed = true;
|
2014-12-14 13:23:13 -07:00
|
|
|
|
2022-07-22 23:47:04 -06:00
|
|
|
// Uses EFB scale config
|
|
|
|
SetLinePtWidthChanged();
|
|
|
|
|
2014-12-14 13:23:13 -07:00
|
|
|
dirty = true;
|
|
|
|
}
|
|
|
|
|
2022-12-29 07:27:48 -07:00
|
|
|
void GeometryShaderManager::SetVSExpand(VSExpand expand)
|
2022-07-22 23:47:04 -06:00
|
|
|
{
|
2022-12-29 07:27:48 -07:00
|
|
|
if (constants.vs_expand != expand)
|
2022-07-22 23:47:04 -06:00
|
|
|
{
|
2022-12-29 07:27:48 -07:00
|
|
|
constants.vs_expand = expand;
|
|
|
|
dirty = true;
|
2022-07-22 23:47:04 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeometryShaderManager::SetConstants(PrimitiveType prim)
|
2014-12-20 05:01:37 -07:00
|
|
|
{
|
2022-12-29 07:27:48 -07:00
|
|
|
if (m_projection_changed && g_ActiveConfig.stereo_mode != StereoMode::Off)
|
2014-12-20 05:01:37 -07:00
|
|
|
{
|
2022-12-29 07:27:48 -07:00
|
|
|
m_projection_changed = false;
|
2016-06-24 02:43:46 -06:00
|
|
|
|
2021-02-10 17:01:42 -07:00
|
|
|
if (xfmem.projection.type == ProjectionType::Perspective)
|
2014-12-20 05:01:37 -07:00
|
|
|
{
|
2014-12-21 06:06:16 -07:00
|
|
|
float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) *
|
|
|
|
(g_ActiveConfig.iStereoDepthPercentage / 100.0f);
|
2014-12-21 06:18:21 -07:00
|
|
|
constants.stereoparams[0] = g_ActiveConfig.bStereoSwapEyes ? offset : -offset;
|
|
|
|
constants.stereoparams[1] = g_ActiveConfig.bStereoSwapEyes ? -offset : offset;
|
2014-12-20 05:01:37 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
constants.stereoparams[0] = constants.stereoparams[1] = 0;
|
|
|
|
}
|
2016-06-24 02:43:46 -06:00
|
|
|
|
2015-09-10 14:14:21 -06:00
|
|
|
constants.stereoparams[2] = (float)(g_ActiveConfig.iStereoConvergence *
|
|
|
|
(g_ActiveConfig.iStereoConvergencePercentage / 100.0f));
|
2016-06-24 02:43:46 -06:00
|
|
|
|
2014-12-20 05:01:37 -07:00
|
|
|
dirty = true;
|
|
|
|
}
|
2016-06-24 02:43:46 -06:00
|
|
|
|
2022-07-22 23:47:04 -06:00
|
|
|
if (g_ActiveConfig.UseVSForLinePointExpand())
|
|
|
|
{
|
|
|
|
if (prim == PrimitiveType::Points)
|
|
|
|
SetVSExpand(VSExpand::Point);
|
|
|
|
else if (prim == PrimitiveType::Lines)
|
|
|
|
SetVSExpand(VSExpand::Line);
|
|
|
|
else
|
|
|
|
SetVSExpand(VSExpand::None);
|
|
|
|
}
|
|
|
|
|
2022-12-29 07:27:48 -07:00
|
|
|
if (m_viewport_changed)
|
2014-12-26 09:58:59 -07:00
|
|
|
{
|
2022-12-29 07:27:48 -07:00
|
|
|
m_viewport_changed = false;
|
2016-06-24 02:43:46 -06:00
|
|
|
|
2014-12-26 09:58:59 -07:00
|
|
|
constants.lineptparams[0] = 2.0f * xfmem.viewport.wd;
|
|
|
|
constants.lineptparams[1] = -2.0f * xfmem.viewport.ht;
|
2016-06-24 02:43:46 -06:00
|
|
|
|
2014-12-26 09:58:59 -07:00
|
|
|
dirty = true;
|
|
|
|
}
|
2014-12-20 05:01:37 -07:00
|
|
|
}
|
|
|
|
|
2014-12-16 19:11:23 -07:00
|
|
|
void GeometryShaderManager::SetViewportChanged()
|
2014-12-14 13:23:13 -07:00
|
|
|
{
|
2022-12-29 07:27:48 -07:00
|
|
|
m_viewport_changed = true;
|
2014-12-16 19:11:23 -07:00
|
|
|
}
|
2014-12-14 13:44:33 -07:00
|
|
|
|
2014-12-16 19:11:23 -07:00
|
|
|
void GeometryShaderManager::SetProjectionChanged()
|
|
|
|
{
|
2022-12-29 07:27:48 -07:00
|
|
|
m_projection_changed = true;
|
2014-12-14 13:23:13 -07:00
|
|
|
}
|
|
|
|
|
2014-12-14 13:44:33 -07:00
|
|
|
void GeometryShaderManager::SetLinePtWidthChanged()
|
|
|
|
{
|
2014-12-16 19:11:23 -07: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 13:44:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void GeometryShaderManager::SetTexCoordChanged(u8 texmapid)
|
|
|
|
{
|
|
|
|
TCoordInfo& tc = bpmem.texcoords[texmapid];
|
2014-12-15 16:21:07 -07: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 13:44:33 -07:00
|
|
|
dirty = true;
|
|
|
|
}
|
|
|
|
|
2014-12-14 13:23:13 -07:00
|
|
|
void GeometryShaderManager::DoState(PointerWrap& p)
|
|
|
|
{
|
2022-12-29 07:27:48 -07:00
|
|
|
p.Do(m_projection_changed);
|
|
|
|
p.Do(m_viewport_changed);
|
2015-01-15 09:29:39 -07:00
|
|
|
|
|
|
|
p.Do(constants);
|
|
|
|
|
2022-05-17 23:29:05 -06:00
|
|
|
if (p.IsReadMode())
|
2014-12-14 13:23:13 -07:00
|
|
|
{
|
2015-01-15 09:29:39 -07:00
|
|
|
// Fixup the current state from global GPU state
|
2014-12-14 13:23:13 -07:00
|
|
|
// NOTE: This requires that all GPU memory has been loaded already.
|
|
|
|
Dirty();
|
|
|
|
}
|
|
|
|
}
|