mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
ShaderGen: Pass host config to shader generation functions
Also moves the host config checks to common.
This commit is contained in:
@ -29,6 +29,7 @@ set(SRCS
|
||||
PostProcessing.cpp
|
||||
RenderBase.cpp
|
||||
RenderState.cpp
|
||||
ShaderGenCommon.cpp
|
||||
Statistics.cpp
|
||||
TextureCacheBase.cpp
|
||||
TextureConfig.cpp
|
||||
|
@ -37,22 +37,25 @@ GeometryShaderUid GetGeometryShaderUid(u32 primitive_type)
|
||||
return out;
|
||||
}
|
||||
|
||||
static void EmitVertex(ShaderCode& out, const geometry_shader_uid_data* uid_data,
|
||||
const char* vertex, APIType ApiType, bool wireframe, bool pixel_lighting,
|
||||
static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config,
|
||||
const geometry_shader_uid_data* uid_data, const char* vertex,
|
||||
APIType ApiType, bool wireframe, bool pixel_lighting,
|
||||
bool first_vertex = false);
|
||||
static void EndPrimitive(ShaderCode& out, const geometry_shader_uid_data* uid_data, APIType ApiType,
|
||||
bool wireframe, bool pixel_lighting);
|
||||
static void EndPrimitive(ShaderCode& out, const ShaderHostConfig& host_config,
|
||||
const geometry_shader_uid_data* uid_data, APIType ApiType, bool wireframe,
|
||||
bool pixel_lighting);
|
||||
|
||||
ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid_data* uid_data)
|
||||
ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
|
||||
const geometry_shader_uid_data* uid_data)
|
||||
{
|
||||
ShaderCode out;
|
||||
// Non-uid template parameters will write to the dummy data (=> gets optimized out)
|
||||
|
||||
const bool wireframe = g_ActiveConfig.bWireFrame;
|
||||
const bool wireframe = host_config.wireframe;
|
||||
const bool pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||
const bool msaa = g_ActiveConfig.IsMSAAEnabled();
|
||||
const bool ssaa = g_ActiveConfig.IsSSAAEnabled();
|
||||
const bool stereo = g_ActiveConfig.IsStereoEnabled();
|
||||
const bool msaa = host_config.msaa;
|
||||
const bool ssaa = host_config.ssaa;
|
||||
const bool stereo = host_config.stereo;
|
||||
const unsigned int vertex_in = uid_data->primitive_type + 1;
|
||||
unsigned int vertex_out = uid_data->primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4;
|
||||
|
||||
@ -62,7 +65,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid
|
||||
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
||||
{
|
||||
// Insert layout parameters
|
||||
if (g_ActiveConfig.backend_info.bSupportsGSInstancing)
|
||||
if (host_config.backend_gs_instancing)
|
||||
{
|
||||
out.Write("layout(%s, invocations = %d) in;\n", primitives_ogl[uid_data->primitive_type],
|
||||
stereo ? 2 : 1);
|
||||
@ -96,7 +99,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid
|
||||
|
||||
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
||||
{
|
||||
if (g_ActiveConfig.backend_info.bSupportsGSInstancing)
|
||||
if (host_config.backend_gs_instancing)
|
||||
out.Write("#define InstanceID gl_InvocationID\n");
|
||||
|
||||
out.Write("VARYING_LOCATION(0) in VertexData {\n");
|
||||
@ -125,7 +128,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid
|
||||
|
||||
out.Write("};\n");
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsGSInstancing)
|
||||
if (host_config.backend_gs_instancing)
|
||||
{
|
||||
out.Write("[maxvertexcount(%d)]\n[instance(%d)]\n", vertex_out, stereo ? 2 : 1);
|
||||
out.Write("void main(%s VS_OUTPUT o[%d], inout %sStream<VertexData> output, in uint "
|
||||
@ -197,7 +200,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid
|
||||
{
|
||||
// If the GPU supports invocation we don't need a for loop and can simply use the
|
||||
// invocation identifier to determine which layer we're rendering.
|
||||
if (g_ActiveConfig.backend_info.bSupportsGSInstancing)
|
||||
if (host_config.backend_gs_instancing)
|
||||
out.Write("\tint eye = InstanceID;\n");
|
||||
else
|
||||
out.Write("\tfor (int eye = 0; eye < 2; ++eye) {\n");
|
||||
@ -213,7 +216,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid
|
||||
out.Write("\tVS_OUTPUT f;\n");
|
||||
AssignVSOutputMembers(out, "f", "vs[i]", uid_data->numTexGens, pixel_lighting);
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsDepthClamp &&
|
||||
if (host_config.backend_depth_clamp &&
|
||||
DriverDetails::HasBug(DriverDetails::BUG_BROKEN_CLIP_DISTANCE))
|
||||
{
|
||||
// On certain GPUs we have to consume the clip distance from the vertex shader
|
||||
@ -263,8 +266,8 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid
|
||||
}
|
||||
out.Write("\t}\n");
|
||||
|
||||
EmitVertex(out, uid_data, "l", ApiType, wireframe, pixel_lighting, true);
|
||||
EmitVertex(out, uid_data, "r", ApiType, wireframe, pixel_lighting);
|
||||
EmitVertex(out, host_config, uid_data, "l", ApiType, wireframe, pixel_lighting, true);
|
||||
EmitVertex(out, host_config, uid_data, "r", ApiType, wireframe, pixel_lighting);
|
||||
}
|
||||
else if (uid_data->primitive_type == PRIMITIVE_POINTS)
|
||||
{
|
||||
@ -292,21 +295,21 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid
|
||||
}
|
||||
out.Write("\t}\n");
|
||||
|
||||
EmitVertex(out, uid_data, "ll", ApiType, wireframe, pixel_lighting, true);
|
||||
EmitVertex(out, uid_data, "lr", ApiType, wireframe, pixel_lighting);
|
||||
EmitVertex(out, uid_data, "ul", ApiType, wireframe, pixel_lighting);
|
||||
EmitVertex(out, uid_data, "ur", ApiType, wireframe, pixel_lighting);
|
||||
EmitVertex(out, host_config, uid_data, "ll", ApiType, wireframe, pixel_lighting, true);
|
||||
EmitVertex(out, host_config, uid_data, "lr", ApiType, wireframe, pixel_lighting);
|
||||
EmitVertex(out, host_config, uid_data, "ul", ApiType, wireframe, pixel_lighting);
|
||||
EmitVertex(out, host_config, uid_data, "ur", ApiType, wireframe, pixel_lighting);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVertex(out, uid_data, "f", ApiType, wireframe, pixel_lighting, true);
|
||||
EmitVertex(out, host_config, uid_data, "f", ApiType, wireframe, pixel_lighting, true);
|
||||
}
|
||||
|
||||
out.Write("\t}\n");
|
||||
|
||||
EndPrimitive(out, uid_data, ApiType, wireframe, pixel_lighting);
|
||||
EndPrimitive(out, host_config, uid_data, ApiType, wireframe, pixel_lighting);
|
||||
|
||||
if (stereo && !g_ActiveConfig.backend_info.bSupportsGSInstancing)
|
||||
if (stereo && !host_config.backend_gs_instancing)
|
||||
out.Write("\t}\n");
|
||||
|
||||
out.Write("}\n");
|
||||
@ -314,9 +317,9 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid
|
||||
return out;
|
||||
}
|
||||
|
||||
static void EmitVertex(ShaderCode& out, const geometry_shader_uid_data* uid_data,
|
||||
const char* vertex, APIType ApiType, bool wireframe, bool pixel_lighting,
|
||||
bool first_vertex)
|
||||
static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config,
|
||||
const geometry_shader_uid_data* uid_data, const char* vertex,
|
||||
APIType ApiType, bool wireframe, bool pixel_lighting, bool first_vertex)
|
||||
{
|
||||
if (wireframe && first_vertex)
|
||||
out.Write("\tif (i == 0) first = %s;\n", vertex);
|
||||
@ -324,7 +327,7 @@ static void EmitVertex(ShaderCode& out, const geometry_shader_uid_data* uid_data
|
||||
if (ApiType == APIType::OpenGL)
|
||||
{
|
||||
out.Write("\tgl_Position = %s.pos;\n", vertex);
|
||||
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||
if (host_config.backend_depth_clamp)
|
||||
{
|
||||
out.Write("\tgl_ClipDistance[0] = %s.clipDist0;\n", vertex);
|
||||
out.Write("\tgl_ClipDistance[1] = %s.clipDist1;\n", vertex);
|
||||
@ -349,11 +352,12 @@ static void EmitVertex(ShaderCode& out, const geometry_shader_uid_data* uid_data
|
||||
out.Write("\toutput.Append(ps);\n");
|
||||
}
|
||||
|
||||
static void EndPrimitive(ShaderCode& out, const geometry_shader_uid_data* uid_data, APIType ApiType,
|
||||
bool wireframe, bool pixel_lighting)
|
||||
static void EndPrimitive(ShaderCode& out, const ShaderHostConfig& host_config,
|
||||
const geometry_shader_uid_data* uid_data, APIType ApiType, bool wireframe,
|
||||
bool pixel_lighting)
|
||||
{
|
||||
if (wireframe)
|
||||
EmitVertex(out, uid_data, "first", ApiType, wireframe, pixel_lighting);
|
||||
EmitVertex(out, host_config, uid_data, "first", ApiType, wireframe, pixel_lighting);
|
||||
|
||||
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
||||
out.Write("\tEndPrimitive();\n");
|
||||
|
@ -25,5 +25,6 @@ struct geometry_shader_uid_data
|
||||
|
||||
typedef ShaderUid<geometry_shader_uid_data> GeometryShaderUid;
|
||||
|
||||
ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid_data* uid_data);
|
||||
ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
|
||||
const geometry_shader_uid_data* uid_data);
|
||||
GeometryShaderUid GetGeometryShaderUid(u32 primitive_type);
|
||||
|
@ -345,14 +345,15 @@ static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data);
|
||||
static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data,
|
||||
bool use_dual_source);
|
||||
|
||||
ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data* uid_data)
|
||||
ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
|
||||
const pixel_shader_uid_data* uid_data)
|
||||
{
|
||||
ShaderCode out;
|
||||
|
||||
const bool per_pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||
const bool msaa = g_ActiveConfig.IsMSAAEnabled();
|
||||
const bool ssaa = g_ActiveConfig.IsSSAAEnabled();
|
||||
const bool stereo = g_ActiveConfig.IsStereoEnabled();
|
||||
const bool msaa = host_config.msaa;
|
||||
const bool ssaa = host_config.ssaa;
|
||||
const bool stereo = host_config.stereo;
|
||||
const u32 numStages = uid_data->genMode_numtevstages + 1;
|
||||
|
||||
out.Write("//Pixel Shader for TEV stages\n");
|
||||
@ -501,7 +502,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data*
|
||||
|
||||
// Only use dual-source blending when required on drivers that don't support it very well.
|
||||
const bool use_dual_source =
|
||||
g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
|
||||
host_config.backend_dual_source_blend &&
|
||||
(!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) ||
|
||||
uid_data->useDstAlpha);
|
||||
|
||||
@ -529,7 +530,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data*
|
||||
out.Write("#define depth gl_FragDepth\n");
|
||||
|
||||
// We need to always use output blocks for Vulkan, but geometry shaders are also optional.
|
||||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders || ApiType == APIType::Vulkan)
|
||||
if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan)
|
||||
{
|
||||
out.Write("VARYING_LOCATION(0) in VertexData {\n");
|
||||
GenerateVSOutputMembers(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting,
|
||||
@ -560,7 +561,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data*
|
||||
|
||||
out.Write("void main()\n{\n");
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders || ApiType == APIType::Vulkan)
|
||||
if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan)
|
||||
{
|
||||
for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i)
|
||||
out.Write("\tfloat3 uv%d = tex%d;\n", i, i);
|
||||
@ -713,7 +714,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data*
|
||||
out.Write("\tint zCoord = int(" I_ZSLOPE ".z + " I_ZSLOPE ".x * screenpos.x + " I_ZSLOPE
|
||||
".y * screenpos.y);\n");
|
||||
}
|
||||
else if (!g_ActiveConfig.bFastDepthCalc)
|
||||
else if (!host_config.fast_depth_calc)
|
||||
{
|
||||
// FastDepth means to trust the depth generated in perspective division.
|
||||
// It should be correct, but it seems not to be as accurate as required. TODO: Find out why!
|
||||
|
@ -157,5 +157,6 @@ struct pixel_shader_uid_data
|
||||
|
||||
typedef ShaderUid<pixel_shader_uid_data> PixelShaderUid;
|
||||
|
||||
ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data* uid_data);
|
||||
ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
|
||||
const pixel_shader_uid_data* uid_data);
|
||||
PixelShaderUid GetPixelShaderUid();
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/PostProcessing.h"
|
||||
#include "VideoCommon/ShaderGenCommon.h"
|
||||
#include "VideoCommon/Statistics.h"
|
||||
#include "VideoCommon/TextureCacheBase.h"
|
||||
#include "VideoCommon/TextureDecoder.h"
|
||||
@ -96,6 +97,8 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height)
|
||||
{
|
||||
m_aspect_wide = SConfig::GetInstance().m_wii_aspect_ratio != 0;
|
||||
}
|
||||
|
||||
m_last_host_config_bits = ShaderHostConfig::GetCurrent().bits;
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
@ -315,6 +318,17 @@ void Renderer::SaveScreenshot(const std::string& filename, bool wait_for_complet
|
||||
}
|
||||
}
|
||||
|
||||
bool Renderer::CheckForHostConfigChanges()
|
||||
{
|
||||
ShaderHostConfig new_host_config = ShaderHostConfig::GetCurrent();
|
||||
if (new_host_config.bits == m_last_host_config_bits)
|
||||
return false;
|
||||
|
||||
OSD::AddMessage("Video config changed, reloading shaders.", OSD::Duration::NORMAL);
|
||||
m_last_host_config_bits = new_host_config.bits;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create On-Screen-Messages
|
||||
void Renderer::DrawDebugText()
|
||||
{
|
||||
|
@ -147,6 +147,8 @@ protected:
|
||||
std::tuple<int, int> CalculateTargetScale(int x, int y) const;
|
||||
bool CalculateTargetSize();
|
||||
|
||||
bool CheckForHostConfigChanges();
|
||||
|
||||
void CheckFifoRecording();
|
||||
void RecordVideoMemory();
|
||||
|
||||
@ -182,6 +184,8 @@ protected:
|
||||
Common::Event m_surface_changed;
|
||||
void* m_new_surface_handle = nullptr;
|
||||
|
||||
u32 m_last_host_config_bits = 0;
|
||||
|
||||
private:
|
||||
void RunFrameDumps();
|
||||
void ShutdownFrameDumping();
|
||||
|
75
Source/Core/VideoCommon/ShaderGenCommon.cpp
Normal file
75
Source/Core/VideoCommon/ShaderGenCommon.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "VideoCommon/ShaderGenCommon.h"
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
ShaderHostConfig ShaderHostConfig::GetCurrent()
|
||||
{
|
||||
ShaderHostConfig bits = {};
|
||||
bits.msaa = g_ActiveConfig.iMultisamples > 1;
|
||||
bits.ssaa = g_ActiveConfig.iMultisamples > 1 && g_ActiveConfig.bSSAA &&
|
||||
g_ActiveConfig.backend_info.bSupportsSSAA;
|
||||
bits.stereo = g_ActiveConfig.iStereoMode > 0;
|
||||
bits.wireframe = g_ActiveConfig.bWireFrame;
|
||||
bits.per_pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||
bits.vertex_rounding = g_ActiveConfig.UseVertexRounding();
|
||||
bits.fast_depth_calc = g_ActiveConfig.bFastDepthCalc;
|
||||
bits.bounding_box = g_ActiveConfig.bBBoxEnable;
|
||||
bits.backend_dual_source_blend = g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
|
||||
bits.backend_geometry_shaders = g_ActiveConfig.backend_info.bSupportsGeometryShaders;
|
||||
bits.backend_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ;
|
||||
bits.backend_bbox = g_ActiveConfig.backend_info.bSupportsBBox;
|
||||
bits.backend_gs_instancing = g_ActiveConfig.backend_info.bSupportsGSInstancing;
|
||||
bits.backend_clip_control = g_ActiveConfig.backend_info.bSupportsClipControl;
|
||||
bits.backend_ssaa = g_ActiveConfig.backend_info.bSupportsSSAA;
|
||||
bits.backend_atomics = g_ActiveConfig.backend_info.bSupportsFragmentStoresAndAtomics;
|
||||
bits.backend_depth_clamp = g_ActiveConfig.backend_info.bSupportsDepthClamp;
|
||||
bits.backend_reversed_depth_range = g_ActiveConfig.backend_info.bSupportsReversedDepthRange;
|
||||
return bits;
|
||||
}
|
||||
|
||||
std::string GetDiskShaderCacheFileName(APIType api_type, const char* type, bool include_gameid,
|
||||
bool include_host_config)
|
||||
{
|
||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||
|
||||
std::string filename = File::GetUserPath(D_SHADERCACHE_IDX);
|
||||
switch (api_type)
|
||||
{
|
||||
case APIType::D3D:
|
||||
filename += "D3D";
|
||||
break;
|
||||
case APIType::OpenGL:
|
||||
filename += "OpenGL";
|
||||
break;
|
||||
case APIType::Vulkan:
|
||||
filename += "Vulkan";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
filename += '-';
|
||||
filename += type;
|
||||
|
||||
if (include_gameid)
|
||||
{
|
||||
filename += '-';
|
||||
filename += SConfig::GetInstance().GetGameID();
|
||||
}
|
||||
|
||||
if (include_host_config)
|
||||
{
|
||||
// We're using 18 bits, so 5 hex characters.
|
||||
ShaderHostConfig host_config = ShaderHostConfig::GetCurrent();
|
||||
filename += StringFromFormat("-%05X", host_config.bits);
|
||||
}
|
||||
|
||||
filename += ".cache";
|
||||
return filename;
|
||||
}
|
@ -151,6 +151,41 @@ private:
|
||||
std::vector<bool> constant_usage; // TODO: Is vector<bool> appropriate here?
|
||||
};
|
||||
|
||||
// Host config contains the settings which can influence generated shaders.
|
||||
union ShaderHostConfig
|
||||
{
|
||||
u32 bits;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 msaa : 1;
|
||||
u32 ssaa : 1;
|
||||
u32 stereo : 1;
|
||||
u32 wireframe : 1;
|
||||
u32 per_pixel_lighting : 1;
|
||||
u32 vertex_rounding : 1;
|
||||
u32 fast_depth_calc : 1;
|
||||
u32 bounding_box : 1;
|
||||
u32 backend_dual_source_blend : 1;
|
||||
u32 backend_geometry_shaders : 1;
|
||||
u32 backend_early_z : 1;
|
||||
u32 backend_bbox : 1;
|
||||
u32 backend_gs_instancing : 1;
|
||||
u32 backend_clip_control : 1;
|
||||
u32 backend_ssaa : 1;
|
||||
u32 backend_atomics : 1;
|
||||
u32 backend_depth_clamp : 1;
|
||||
u32 backend_reversed_depth_range : 1;
|
||||
u32 pad : 14;
|
||||
};
|
||||
|
||||
static ShaderHostConfig GetCurrent();
|
||||
};
|
||||
|
||||
// Gets the filename of the specified type of cache object (e.g. vertex shader, pipeline).
|
||||
std::string GetDiskShaderCacheFileName(APIType api_type, const char* type, bool include_gameid,
|
||||
bool include_host_config);
|
||||
|
||||
template <class T>
|
||||
inline void DefineOutputMember(T& object, APIType api_type, const char* qualifier, const char* type,
|
||||
const char* name, int var_index, const char* semantic = "",
|
||||
|
@ -76,14 +76,15 @@ VertexShaderUid GetVertexShaderUid()
|
||||
return out;
|
||||
}
|
||||
|
||||
ShaderCode GenerateVertexShaderCode(APIType api_type, const vertex_shader_uid_data* uid_data)
|
||||
ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& host_config,
|
||||
const vertex_shader_uid_data* uid_data)
|
||||
{
|
||||
ShaderCode out;
|
||||
|
||||
const bool per_pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||
const bool msaa = g_ActiveConfig.IsMSAAEnabled();
|
||||
const bool ssaa = g_ActiveConfig.IsSSAAEnabled();
|
||||
const bool vertex_rounding = g_ActiveConfig.UseVertexRounding();
|
||||
const bool msaa = host_config.msaa;
|
||||
const bool ssaa = host_config.ssaa;
|
||||
const bool vertex_rounding = host_config.vertex_rounding;
|
||||
|
||||
out.Write("%s", s_lighting_struct);
|
||||
|
||||
@ -128,7 +129,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const vertex_shader_uid_da
|
||||
}
|
||||
|
||||
// We need to always use output blocks for Vulkan, but geometry shaders are also optional.
|
||||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders || api_type == APIType::Vulkan)
|
||||
if (host_config.backend_geometry_shaders || api_type == APIType::Vulkan)
|
||||
{
|
||||
out.Write("VARYING_LOCATION(0) out VertexData {\n");
|
||||
GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, per_pixel_lighting,
|
||||
@ -415,7 +416,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const vertex_shader_uid_da
|
||||
// If we can disable the incorrect depth clipping planes using depth clamping, then we can do
|
||||
// our own depth clipping and calculate the depth range before the perspective divide if
|
||||
// necessary.
|
||||
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||
if (host_config.backend_depth_clamp)
|
||||
{
|
||||
// Since we're adjusting z for the depth range before the perspective divide, we have to do our
|
||||
// own clipping. We want to clip so that -w <= z <= 0, which matches the console -1..0 range.
|
||||
@ -440,7 +441,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const vertex_shader_uid_da
|
||||
out.Write("o.pos.z = o.pos.w * " I_PIXELCENTERCORRECTION ".w - "
|
||||
"o.pos.z * " I_PIXELCENTERCORRECTION ".z;\n");
|
||||
|
||||
if (!g_ActiveConfig.backend_info.bSupportsClipControl)
|
||||
if (!host_config.backend_clip_control)
|
||||
{
|
||||
// If the graphics API doesn't support a depth range of 0..1, then we need to map z to
|
||||
// the -1..1 range. Unfortunately we have to use a substraction, which is a lossy floating-point
|
||||
@ -485,7 +486,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const vertex_shader_uid_da
|
||||
|
||||
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
|
||||
{
|
||||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders || api_type == APIType::Vulkan)
|
||||
if (host_config.backend_geometry_shaders || api_type == APIType::Vulkan)
|
||||
{
|
||||
AssignVSOutputMembers(out, "vs", "o", uid_data->numTexGens, per_pixel_lighting);
|
||||
}
|
||||
@ -505,7 +506,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const vertex_shader_uid_da
|
||||
out.Write("colors_1 = o.colors_1;\n");
|
||||
}
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||
if (host_config.backend_depth_clamp)
|
||||
{
|
||||
out.Write("gl_ClipDistance[0] = o.clipDist0;\n");
|
||||
out.Write("gl_ClipDistance[1] = o.clipDist1;\n");
|
||||
|
@ -65,4 +65,5 @@ struct vertex_shader_uid_data
|
||||
typedef ShaderUid<vertex_shader_uid_data> VertexShaderUid;
|
||||
|
||||
VertexShaderUid GetVertexShaderUid();
|
||||
ShaderCode GenerateVertexShaderCode(APIType api_type, const vertex_shader_uid_data* uid_data);
|
||||
ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& host_config,
|
||||
const vertex_shader_uid_data* uid_data);
|
||||
|
@ -65,6 +65,7 @@
|
||||
<ClCompile Include="RenderBase.cpp" />
|
||||
<ClCompile Include="RenderState.cpp" />
|
||||
<ClCompile Include="LightingShaderGen.cpp" />
|
||||
<ClCompile Include="ShaderGenCommon.cpp" />
|
||||
<ClCompile Include="Statistics.cpp" />
|
||||
<ClCompile Include="GeometryShaderGen.cpp" />
|
||||
<ClCompile Include="GeometryShaderManager.cpp" />
|
||||
|
@ -173,6 +173,9 @@
|
||||
<ClCompile Include="AbstractTexture.cpp">
|
||||
<Filter>Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ShaderGenCommon.cpp">
|
||||
<Filter>Shader Generators</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CommandProcessor.h" />
|
||||
|
@ -4,12 +4,9 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Core/Config/GraphicsSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Movie.h"
|
||||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
@ -191,109 +188,3 @@ bool VideoConfig::IsVSync()
|
||||
{
|
||||
return bVSync && !Core::GetIsThrottlerTempDisabled();
|
||||
}
|
||||
|
||||
bool VideoConfig::IsStereoEnabled() const
|
||||
{
|
||||
return iStereoMode > 0;
|
||||
}
|
||||
|
||||
bool VideoConfig::IsMSAAEnabled() const
|
||||
{
|
||||
return iMultisamples > 1;
|
||||
}
|
||||
|
||||
bool VideoConfig::IsSSAAEnabled() const
|
||||
{
|
||||
return iMultisamples > 1 && bSSAA && backend_info.bSupportsSSAA;
|
||||
}
|
||||
|
||||
union HostConfigBits
|
||||
{
|
||||
u32 bits;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 msaa : 1;
|
||||
u32 ssaa : 1;
|
||||
u32 stereo : 1;
|
||||
u32 wireframe : 1;
|
||||
u32 per_pixel_lighting : 1;
|
||||
u32 vertex_rounding : 1;
|
||||
u32 fast_depth_calc : 1;
|
||||
u32 bounding_box : 1;
|
||||
u32 backend_dual_source_blend : 1;
|
||||
u32 backend_geometry_shaders : 1;
|
||||
u32 backend_early_z : 1;
|
||||
u32 backend_bbox : 1;
|
||||
u32 backend_gs_instancing : 1;
|
||||
u32 backend_clip_control : 1;
|
||||
u32 backend_ssaa : 1;
|
||||
u32 backend_atomics : 1;
|
||||
u32 backend_depth_clamp : 1;
|
||||
u32 backend_reversed_depth_range : 1;
|
||||
u32 pad : 14;
|
||||
};
|
||||
};
|
||||
|
||||
u32 VideoConfig::GetHostConfigBits() const
|
||||
{
|
||||
HostConfigBits bits = {};
|
||||
bits.msaa = IsMSAAEnabled();
|
||||
bits.ssaa = IsSSAAEnabled();
|
||||
bits.stereo = IsStereoEnabled();
|
||||
bits.wireframe = bWireFrame;
|
||||
bits.per_pixel_lighting = bEnablePixelLighting;
|
||||
bits.vertex_rounding = UseVertexRounding();
|
||||
bits.fast_depth_calc = bFastDepthCalc;
|
||||
bits.bounding_box = bBBoxEnable;
|
||||
bits.backend_dual_source_blend = backend_info.bSupportsDualSourceBlend;
|
||||
bits.backend_geometry_shaders = backend_info.bSupportsGeometryShaders;
|
||||
bits.backend_early_z = backend_info.bSupportsEarlyZ;
|
||||
bits.backend_bbox = backend_info.bSupportsBBox;
|
||||
bits.backend_gs_instancing = backend_info.bSupportsGSInstancing;
|
||||
bits.backend_clip_control = backend_info.bSupportsClipControl;
|
||||
bits.backend_ssaa = backend_info.bSupportsSSAA;
|
||||
bits.backend_atomics = backend_info.bSupportsFragmentStoresAndAtomics;
|
||||
bits.backend_depth_clamp = backend_info.bSupportsDepthClamp;
|
||||
bits.backend_reversed_depth_range = backend_info.bSupportsReversedDepthRange;
|
||||
return bits.bits;
|
||||
}
|
||||
|
||||
std::string VideoConfig::GetDiskCacheFileName(APIType api_type, const char* type,
|
||||
bool include_gameid, bool include_host_config) const
|
||||
{
|
||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||
|
||||
std::string filename = File::GetUserPath(D_SHADERCACHE_IDX);
|
||||
switch (api_type)
|
||||
{
|
||||
case APIType::D3D:
|
||||
filename += "D3D";
|
||||
break;
|
||||
case APIType::OpenGL:
|
||||
filename += "OpenGL";
|
||||
break;
|
||||
case APIType::Vulkan:
|
||||
filename += "Vulkan";
|
||||
break;
|
||||
}
|
||||
|
||||
filename += '-';
|
||||
filename += type;
|
||||
|
||||
if (include_gameid)
|
||||
{
|
||||
filename += '-';
|
||||
filename += SConfig::GetInstance().GetGameID();
|
||||
}
|
||||
|
||||
if (include_host_config)
|
||||
{
|
||||
// We're using 18 bits, so 5 hex characters.
|
||||
filename += StringFromFormat("-%05X", GetHostConfigBits());
|
||||
}
|
||||
|
||||
filename += ".cache";
|
||||
return filename;
|
||||
}
|
||||
|
@ -224,14 +224,6 @@ struct VideoConfig final
|
||||
return backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding;
|
||||
}
|
||||
bool UseVertexRounding() const { return bVertexRounding && iEFBScale != SCALE_1X; }
|
||||
bool IsStereoEnabled() const;
|
||||
bool IsMSAAEnabled() const;
|
||||
bool IsSSAAEnabled() const;
|
||||
// Host config contains the settings which can influence generated shaders.
|
||||
u32 GetHostConfigBits() const;
|
||||
// Gets the filename of the specified type of cache object (e.g. vertex shader, pipeline).
|
||||
std::string GetDiskCacheFileName(APIType api_type, const char* type, bool include_gameid,
|
||||
bool include_host_config) const;
|
||||
};
|
||||
|
||||
extern VideoConfig g_Config;
|
||||
|
Reference in New Issue
Block a user