ShaderGen: Implement vertex ubershaders

This commit is contained in:
Stenzek
2017-07-30 17:43:59 +10:00
parent 7d78cf0f6f
commit 745d541527
13 changed files with 739 additions and 5 deletions
+1
View File
@@ -34,6 +34,7 @@ set(SRCS
Statistics.cpp
UberShaderCommon.cpp
UberShaderPixel.cpp
UberShaderVertex.cpp
TextureCacheBase.cpp
TextureConfig.cpp
TextureConversionShader.cpp
+9 -1
View File
@@ -44,6 +44,11 @@ struct PixelShaderConstants
struct VertexShaderConstants
{
u32 components; // .x
u32 xfmem_dualTexInfo; // .y
u32 xfmem_numColorChans; // .z
u32 pad1; // .w
float4 posnormalmatrix[6];
float4 projection[4];
int4 materials[4];
@@ -60,7 +65,10 @@ struct VertexShaderConstants
float4 normalmatrices[32];
float4 posttransformmatrices[64];
float4 pixelcentercorrection;
float4 viewport;
float viewport[2]; // .xy
float pad2[2]; // .zw
uint4 xfmem_pack1[8]; // .x - texMtxInfo, .y - postMtxInfo, [0..1].z = color, [0..1].w = alpha
};
struct GeometryShaderConstants
+10 -2
View File
@@ -318,7 +318,10 @@ inline const char* GetInterpolationQualifier(bool msaa, bool ssaa,
#define I_LINEPTPARAMS "clinept"
#define I_TEXOFFSET "ctexoffset"
static const char s_shader_uniforms[] = "\tfloat4 " I_POSNORMALMATRIX "[6];\n"
static const char s_shader_uniforms[] = "\tuint components;\n"
"\tuint xfmem_dualTexInfo;\n"
"\tuint xfmem_numColorChans;\n"
"\tfloat4 " I_POSNORMALMATRIX "[6];\n"
"\tfloat4 " I_PROJECTION "[4];\n"
"\tint4 " I_MATERIALS "[4];\n"
"\tLight " I_LIGHTS "[8];\n"
@@ -327,4 +330,9 @@ static const char s_shader_uniforms[] = "\tfloat4 " I_POSNORMALMATRIX "[6];\n"
"\tfloat4 " I_NORMALMATRICES "[32];\n"
"\tfloat4 " I_POSTTRANSFORMMATRICES "[64];\n"
"\tfloat4 " I_PIXELCENTERCORRECTION ";\n"
"\tfloat2 " I_VIEWPORT_SIZE ";\n";
"\tfloat2 " I_VIEWPORT_SIZE ";\n"
"\tuint4 xfmem_pack1[8];\n"
"\t#define xfmem_texMtxInfo(i) (xfmem_pack1[(i)].x)\n"
"\t#define xfmem_postMtxInfo(i) (xfmem_pack1[(i)].y)\n"
"\t#define xfmem_color(i) (xfmem_pack1[(i)].z)\n"
"\t#define xfmem_alpha(i) (xfmem_pack1[(i)].w)\n";
+1 -1
View File
@@ -24,4 +24,4 @@ void WriteUberShaderCommonHeader(ShaderCode& out, APIType api_type,
"}\n\n");
}
}
}
}
@@ -20,5 +20,4 @@ std::string BitfieldExtract(const std::string& source, T type)
return StringFromFormat("bitfieldExtract(%s, %u, %u)", source.c_str(),
static_cast<u32>(type.StartBit()), static_cast<u32>(type.NumBits()));
}
} // namespace UberShader
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,28 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <functional>
#include "VideoCommon/PixelShaderGen.h"
namespace UberShader
{
#pragma pack(1)
struct vertex_ubershader_uid_data
{
u32 num_texgens : 4;
u32 NumValues() const { return sizeof(vertex_ubershader_uid_data); }
};
#pragma pack()
typedef ShaderUid<vertex_ubershader_uid_data> VertexShaderUid;
VertexShaderUid GetVertexShaderUid();
ShaderCode GenVertexShader(APIType api_type, const ShaderHostConfig& host_config,
const vertex_ubershader_uid_data* uid_data);
void EnumerateVertexShaderUids(const std::function<void(const VertexShaderUid&)>& callback);
}
@@ -277,6 +277,7 @@ int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bo
}
s_current_vtx_fmt = loader->m_native_vertex_format;
g_current_components = loader->m_native_components;
VertexShaderManager::SetVertexFormat(loader->m_native_components);
// if cull mode is CULL_ALL, tell VertexManager to skip triangles and quads.
// They still need to go through vertex loading, because we need to calculate a zfreeze refrence
@@ -30,6 +30,7 @@ alignas(16) static float g_fProjectionMatrix[16];
// track changes
static bool bTexMatricesChanged[2], bPosNormalMatrixChanged, bProjectionChanged, bViewportChanged;
static bool bTexMtxInfoChanged, bLightingConfigChanged;
static BitSet32 nMaterialsChanged;
static int nTransformMatricesChanged[2]; // min,max
static int nNormalMatricesChanged[2]; // min,max
@@ -193,6 +194,8 @@ void VertexShaderManager::Init()
bPosNormalMatrixChanged = false;
bProjectionChanged = true;
bViewportChanged = false;
bTexMtxInfoChanged = false;
bLightingConfigChanged = false;
std::memset(&xfmem, 0, sizeof(xfmem));
constants = {};
@@ -561,6 +564,32 @@ void VertexShaderManager::SetConstants()
dirty = true;
}
if (bTexMtxInfoChanged)
{
bTexMtxInfoChanged = false;
constants.xfmem_dualTexInfo = xfmem.dualTexTrans.enabled;
for (size_t i = 0; i < ArraySize(xfmem.texMtxInfo); i++)
constants.xfmem_pack1[i][0] = xfmem.texMtxInfo[i].hex;
for (size_t i = 0; i < ArraySize(xfmem.postMtxInfo); i++)
constants.xfmem_pack1[i][1] = xfmem.postMtxInfo[i].hex;
dirty = true;
}
if (bLightingConfigChanged)
{
bLightingConfigChanged = false;
for (size_t i = 0; i < 2; i++)
{
constants.xfmem_pack1[i][2] = xfmem.color[i].hex;
constants.xfmem_pack1[i][3] = xfmem.alpha[i].hex;
}
constants.xfmem_numColorChans = xfmem.numChan.numColorChans;
dirty = true;
}
}
void VertexShaderManager::InvalidateXFRange(int start, int end)
@@ -758,6 +787,27 @@ void VertexShaderManager::ResetView()
bProjectionChanged = true;
}
void VertexShaderManager::SetVertexFormat(u32 components)
{
if (components != constants.components)
{
constants.components = components;
dirty = true;
}
}
void VertexShaderManager::SetTexMatrixInfoChanged(int index)
{
// TODO: Should we track this with more precision, like which indices changed?
// The whole vertex constants are probably going to be uploaded regardless.
bTexMtxInfoChanged = true;
}
void VertexShaderManager::SetLightingConfigChanged()
{
bLightingConfigChanged = true;
}
void VertexShaderManager::TransformToClipSpace(const float* data, float* out, u32 MtxIdx)
{
const float* world_matrix = &xfmem.posMatrices[(MtxIdx & 0x3f) * 4];
@@ -800,6 +850,8 @@ void VertexShaderManager::DoState(PointerWrap& p)
p.Do(bPosNormalMatrixChanged);
p.Do(bProjectionChanged);
p.Do(bViewportChanged);
p.Do(bTexMtxInfoChanged);
p.Do(bLightingConfigChanged);
p.Do(constants);
@@ -36,6 +36,10 @@ public:
static void RotateView(float x, float y);
static void ResetView();
static void SetVertexFormat(u32 components);
static void SetTexMatrixInfoChanged(int index);
static void SetLightingConfigChanged();
// data: 3 floats representing the X, Y and Z vertex model coordinates and the posmatrix index.
// out: 4 floats which will be initialized with the corresponding clip space coordinates
// NOTE: g_fProjectionMatrix must be up to date when this is called
@@ -75,6 +75,7 @@
<ClCompile Include="TextureCacheBase.cpp" />
<ClCompile Include="TextureConfig.cpp" />
<ClCompile Include="TextureConversionShader.cpp" />
<ClCompile Include="UberShaderVertex.cpp" />
<ClCompile Include="VertexLoader.cpp" />
<ClCompile Include="VertexLoaderBase.cpp" />
<ClCompile Include="VertexLoaderX64.cpp" />
@@ -137,6 +138,7 @@
<ClInclude Include="TextureConfig.h" />
<ClInclude Include="TextureConversionShader.h" />
<ClInclude Include="TextureDecoder.h" />
<ClInclude Include="UberShaderVertex.h" />
<ClInclude Include="VertexLoader.h" />
<ClInclude Include="VertexLoaderBase.h" />
<ClInclude Include="VertexLoaderManager.h" />
@@ -185,6 +185,9 @@
<ClCompile Include="UberShaderCommon.cpp">
<Filter>Shader Generators</Filter>
</ClCompile>
<ClCompile Include="UberShaderVertex.cpp">
<Filter>Shader Generators</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CommandProcessor.h" />
@@ -350,6 +353,9 @@
<ClInclude Include="UberShaderCommon.h">
<Filter>Shader Generators</Filter>
</ClInclude>
<ClInclude Include="UberShaderVertex.h">
<Filter>Shader Generators</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />
+5
View File
@@ -56,6 +56,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src)
case XFMEM_SETNUMCHAN:
if (xfmem.numChan.numColorChans != (newValue & 3))
g_vertex_manager->Flush();
VertexShaderManager::SetLightingConfigChanged();
break;
case XFMEM_SETCHAN0_AMBCOLOR: // Channel Ambient Color
@@ -88,11 +89,13 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src)
case XFMEM_SETCHAN1_ALPHA:
if (((u32*)&xfmem)[address] != (newValue & 0x7fff))
g_vertex_manager->Flush();
VertexShaderManager::SetLightingConfigChanged();
break;
case XFMEM_DUALTEX:
if (xfmem.dualTexTrans.enabled != (newValue & 1))
g_vertex_manager->Flush();
VertexShaderManager::SetTexMatrixInfoChanged(-1);
break;
case XFMEM_SETMATRIXINDA:
@@ -146,6 +149,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src)
case XFMEM_SETTEXMTXINFO + 6:
case XFMEM_SETTEXMTXINFO + 7:
g_vertex_manager->Flush();
VertexShaderManager::SetTexMatrixInfoChanged(address - XFMEM_SETTEXMTXINFO);
nextAddress = XFMEM_SETTEXMTXINFO + 8;
break;
@@ -159,6 +163,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src)
case XFMEM_SETPOSMTXINFO + 6:
case XFMEM_SETPOSMTXINFO + 7:
g_vertex_manager->Flush();
VertexShaderManager::SetTexMatrixInfoChanged(address - XFMEM_SETPOSMTXINFO);
nextAddress = XFMEM_SETPOSMTXINFO + 8;
break;