VideoCommon: Move backend_info out of VideoConfig struct.

This commit is contained in:
Jordan Woyak 2025-03-07 14:43:39 -06:00
commit c18c039089
62 changed files with 741 additions and 788 deletions

View file

@ -76,7 +76,7 @@ void AbstractGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool co
static_cast<float>((color >> 0) & 0xFF) / 255.0f,
static_cast<float>((color >> 24) & 0xFF) / 255.0f},
static_cast<float>(z & 0xFFFFFF) / 16777216.0f};
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (!g_backend_info.bSupportsReversedDepthRange)
uniforms.clear_depth = 1.0f - uniforms.clear_depth;
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
@ -149,7 +149,7 @@ AbstractGfx::ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect, u
u32 fb_height) const
{
MathUtil::Rectangle<int> ret = rect;
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
if (g_backend_info.bUsesLowerLeftOrigin)
{
ret.top = fb_height - rect.bottom;
ret.bottom = fb_height - rect.top;
@ -177,5 +177,5 @@ bool AbstractGfx::UseGeometryShaderForUI() const
// OpenGL doesn't render to a 2-layer backbuffer like D3D/Vulkan for quad-buffered stereo,
// instead drawing twice and the eye selected by glDrawBuffer() (see Presenter::RenderXFBToScreen)
return g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer &&
!g_ActiveConfig.backend_info.bUsesExplictQuadBuffering;
!g_backend_info.bUsesExplictQuadBuffering;
}

View file

@ -360,7 +360,7 @@ static bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
info->format = AbstractTextureFormat::BPTC;
info->block_size = 4;
info->bytes_per_block = 16;
if (!g_ActiveConfig.backend_info.bSupportsBPTCTextures)
if (!g_backend_info.bSupportsBPTCTextures)
return false;
}
else
@ -418,7 +418,7 @@ static bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
// We also need to ensure the backend supports these formats natively before loading them,
// otherwise, fallback to SOIL, which will decompress them to RGBA.
if (needs_s3tc && !g_ActiveConfig.backend_info.bSupportsST3CTextures)
if (needs_s3tc && !g_backend_info.bSupportsST3CTextures)
return false;
// Mip levels smaller than the block size are padded to multiples of the block size.

View file

@ -221,7 +221,7 @@ void SetScissorAndViewport()
// floating-point round-trip errors. However the console GPU doesn't ever write a value
// to the depth buffer that exceeds 2^24 - 1.
constexpr float GX_MAX_DEPTH = 16777215.0f / 16777216.0f;
if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
if (!g_backend_info.bSupportsDepthClamp)
{
// There's no way to support oversized depth ranges in this situation. Let's just clamp the
// range to the maximum value supported by the console GPU and hope for the best.
@ -233,7 +233,7 @@ void SetScissorAndViewport()
{
// We need to ensure depth values are clamped the maximum value supported by the console GPU.
// Taking into account whether the depth range is inverted or not.
if (xfmem.viewport.zRange < 0.0f && g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (xfmem.viewport.zRange < 0.0f && g_backend_info.bSupportsReversedDepthRange)
{
min_depth = GX_MAX_DEPTH;
max_depth = 0.0f;
@ -246,7 +246,7 @@ void SetScissorAndViewport()
}
float near_depth, far_depth;
if (g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (g_backend_info.bSupportsReversedDepthRange)
{
// Set the reversed depth range.
near_depth = max_depth;
@ -262,7 +262,7 @@ void SetScissorAndViewport()
}
// Lower-left flip.
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
if (g_backend_info.bUsesLowerLeftOrigin)
y = static_cast<float>(g_gfx->GetCurrentFramebuffer()->GetHeight()) - y - height;
g_gfx->SetViewport(x, y, width, height, near_depth, far_depth);

View file

@ -29,7 +29,7 @@ void BoundingBox::Disable(PixelShaderManager& pixel_shader_manager)
void BoundingBox::Flush()
{
if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
if (!g_ActiveConfig.bBBoxEnable || !g_backend_info.bSupportsBBox)
return;
m_is_valid = false;
@ -57,7 +57,7 @@ void BoundingBox::Flush()
void BoundingBox::Readback()
{
if (!g_ActiveConfig.backend_info.bSupportsBBox)
if (!g_backend_info.bSupportsBBox)
return;
auto read_values = Read(0, NUM_BBOX_VALUES);
@ -76,7 +76,7 @@ u16 BoundingBox::Get(u32 index)
{
ASSERT(index < NUM_BBOX_VALUES);
if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
if (!g_ActiveConfig.bBBoxEnable || !g_backend_info.bSupportsBBox)
return m_bounding_box_fallback[index];
if (!m_is_valid)
@ -89,7 +89,7 @@ void BoundingBox::Set(u32 index, u16 value)
{
ASSERT(index < NUM_BBOX_VALUES);
if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
if (!g_ActiveConfig.bBBoxEnable || !g_backend_info.bSupportsBBox)
{
m_bounding_box_fallback[index] = value;
return;
@ -120,12 +120,12 @@ void BoundingBox::DoState(PointerWrap& p)
{
p.Do(backend_values);
if (g_ActiveConfig.backend_info.bSupportsBBox)
if (g_backend_info.bSupportsBBox)
Write(0, backend_values);
}
else
{
if (g_ActiveConfig.backend_info.bSupportsBBox)
if (g_backend_info.bSupportsBBox)
backend_values = Read(0, NUM_BBOX_VALUES);
p.Do(backend_values);

View file

@ -217,7 +217,7 @@ std::tuple<u32, u32> FramebufferManager::CalculateTargetSize()
else
m_efb_scale = g_ActiveConfig.iEFBScale;
const u32 max_size = g_ActiveConfig.backend_info.MaxTextureSize;
const u32 max_size = g_backend_info.MaxTextureSize;
if (max_size < EFB_WIDTH * m_efb_scale)
m_efb_scale = max_size / EFB_WIDTH;
@ -253,7 +253,7 @@ bool FramebufferManager::CreateEFBFramebuffer()
if (g_ActiveConfig.MultisamplingEnabled())
{
u32 flags = 0;
if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
if (!g_backend_info.bSupportsPartialMultisampleResolve)
flags |= AbstractTextureFlag_RenderTarget;
m_efb_resolve_color_texture = g_gfx->CreateTexture(
TextureConfig(efb_color_texture_config.width, efb_color_texture_config.height, 1,
@ -263,7 +263,7 @@ bool FramebufferManager::CreateEFBFramebuffer()
if (!m_efb_resolve_color_texture)
return false;
if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
if (!g_backend_info.bSupportsPartialMultisampleResolve)
{
m_efb_color_resolve_framebuffer =
g_gfx->CreateFramebuffer(m_efb_resolve_color_texture.get(), nullptr);
@ -291,8 +291,7 @@ bool FramebufferManager::CreateEFBFramebuffer()
// Clear the renderable textures out.
g_gfx->SetAndClearFramebuffer(m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}},
g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f :
0.0f);
g_backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f);
// Pixel Shader uses EFB scale as a constant, dirty that in case it changed
Core::System::GetInstance().GetPixelShaderManager().Dirty();
@ -328,7 +327,7 @@ AbstractTexture* FramebufferManager::ResolveEFBColorTexture(const MathUtil::Rect
clamped_region.ClampUL(0, 0, GetEFBWidth(), GetEFBHeight());
// Resolve to our already-created texture.
if (g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
if (g_backend_info.bSupportsPartialMultisampleResolve)
{
for (u32 layer = 0; layer < GetEFBLayers(); layer++)
{
@ -479,7 +478,7 @@ MathUtil::Rectangle<int> FramebufferManager::GetEFBCacheTileRect(u32 tile_index)
u32 FramebufferManager::PeekEFBColor(u32 x, u32 y)
{
// The y coordinate here assumes upper-left origin, but the readback texture is lower-left in GL.
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
if (g_backend_info.bUsesLowerLeftOrigin)
y = EFB_HEIGHT - 1 - y;
u32 tile_index;
@ -502,7 +501,7 @@ u32 FramebufferManager::PeekEFBColor(u32 x, u32 y)
float FramebufferManager::PeekEFBDepth(u32 x, u32 y)
{
// The y coordinate here assumes upper-left origin, but the readback texture is lower-left in GL.
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
if (g_backend_info.bUsesLowerLeftOrigin)
y = EFB_HEIGHT - 1 - y;
u32 tile_index;
@ -654,7 +653,7 @@ bool FramebufferManager::CompileReadbackPipelines()
if (!m_efb_depth_resolve_pipeline)
return false;
if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
if (!g_backend_info.bSupportsPartialMultisampleResolve)
{
config.framebuffer_state.color_texture_format = GetEFBColorFormat();
auto color_resolve_shader = g_gfx->CreateShaderFromSource(
@ -717,8 +716,8 @@ bool FramebufferManager::CreateReadbackFramebuffer()
// Since we can't partially copy from a depth buffer directly to the staging texture in D3D, we
// use an intermediate buffer to avoid copying the whole texture.
if (!g_ActiveConfig.backend_info.bSupportsDepthReadback ||
(IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) ||
if (!g_backend_info.bSupportsDepthReadback ||
(IsUsingTiledEFBCache() && !g_backend_info.bSupportsPartialDepthCopies) ||
!AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
GetEFBDepthCopyFormat()) ||
GetEFBScale() != 1)
@ -792,11 +791,10 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async
// Force the path through the intermediate texture, as we can't do an image copy from a depth
// buffer directly to a staging texture (must be the whole resource).
const bool force_intermediate_copy =
depth &&
(!g_ActiveConfig.backend_info.bSupportsDepthReadback ||
(!g_ActiveConfig.backend_info.bSupportsPartialDepthCopies && IsUsingTiledEFBCache()) ||
!AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
GetEFBDepthCopyFormat()));
depth && (!g_backend_info.bSupportsDepthReadback ||
(!g_backend_info.bSupportsPartialDepthCopies && IsUsingTiledEFBCache()) ||
!AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
GetEFBDepthCopyFormat()));
// Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on.
EFBCacheData& data = depth ? m_efb_depth_cache : m_efb_color_cache;
@ -956,7 +954,7 @@ void FramebufferManager::PokeEFBColor(u32 x, u32 y, u32 color)
CreatePokeVertices(&m_color_poke_vertices, x, y, 0.0f, color);
// See comment above for reasoning for lower-left coordinates.
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
if (g_backend_info.bUsesLowerLeftOrigin)
y = EFB_HEIGHT - 1 - y;
// Update the peek cache if it's valid, since we know the color of the pixel now.
@ -974,7 +972,7 @@ void FramebufferManager::PokeEFBDepth(u32 x, u32 y, float depth)
CreatePokeVertices(&m_depth_poke_vertices, x, y, depth, 0);
// See comment above for reasoning for lower-left coordinates.
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
if (g_backend_info.bUsesLowerLeftOrigin)
y = EFB_HEIGHT - 1 - y;
// Update the peek cache if it's valid, since we know the color of the pixel now.
@ -988,7 +986,7 @@ void FramebufferManager::CreatePokeVertices(std::vector<EFBPokeVertex>* destinat
{
const float cs_pixel_width = 1.0f / EFB_WIDTH * 2.0f;
const float cs_pixel_height = 1.0f / EFB_HEIGHT * 2.0f;
if (g_ActiveConfig.backend_info.bSupportsLargePoints)
if (g_backend_info.bSupportsLargePoints)
{
// GPU will expand the point to a quad.
const float cs_x = (static_cast<float>(x) + 0.5f) * cs_pixel_width - 1.0f;
@ -1076,8 +1074,7 @@ bool FramebufferManager::CompilePokePipelines()
config.geometry_shader = IsEFBStereo() ? g_shader_cache->GetColorGeometryShader() : nullptr;
config.pixel_shader = g_shader_cache->GetColorPixelShader();
config.rasterization_state = RenderState::GetNoCullRasterizationState(
g_ActiveConfig.backend_info.bSupportsLargePoints ? PrimitiveType::Points :
PrimitiveType::Triangles);
g_backend_info.bSupportsLargePoints ? PrimitiveType::Points : PrimitiveType::Triangles);
config.depth_state = RenderState::GetNoDepthTestingDepthState();
config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = GetEFBFramebufferState();
@ -1155,8 +1152,7 @@ void FramebufferManager::DoLoadState(PointerWrap& p)
{
WARN_LOG_FMT(VIDEO, "Failed to deserialize EFB contents. Clearing instead.");
g_gfx->SetAndClearFramebuffer(m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}},
g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f :
0.0f);
g_backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f);
return;
}

View file

@ -20,7 +20,7 @@ namespace
{
APIType GetAPIType()
{
return g_ActiveConfig.backend_info.api_type;
return g_backend_info.api_type;
}
void EmitUniformBufferDeclaration(ShaderCode& code)
@ -109,7 +109,7 @@ void EmitVertexMainDeclaration(ShaderCode& code, u32 num_tex_inputs, u32 num_col
if (position_input)
code.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawpos;\n", ShaderAttrib::Position);
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
if (g_backend_info.bSupportsGeometryShaders)
{
code.Write("VARYING_LOCATION(0) out VertexData {{\n");
for (u32 i = 0; i < num_tex_outputs; i++)
@ -146,7 +146,7 @@ void EmitPixelMainDeclaration(ShaderCode& code, u32 num_tex_inputs, u32 num_colo
case APIType::OpenGL:
case APIType::Vulkan:
{
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
if (g_backend_info.bSupportsGeometryShaders)
{
code.Write("VARYING_LOCATION(0) in VertexData {{\n");
for (u32 i = 0; i < num_tex_inputs; i++)
@ -406,7 +406,7 @@ std::string GenerateEFBPokeVertexShader()
code.Write("{{\n"
" v_col0 = rawcolor0;\n"
" opos = float4(rawpos.xyz, 1.0f);\n");
if (g_ActiveConfig.backend_info.bSupportsLargePoints)
if (g_backend_info.bSupportsLargePoints)
code.Write(" gl_PointSize = rawpos.w;\n");
// NDC space is flipped in Vulkan.

View file

@ -378,8 +378,8 @@ void EnumerateGeometryShaderUids(const std::function<void(const GeometryShaderUi
GeometryShaderUid uid;
const std::array<PrimitiveType, 3> primitive_lut = {
{g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
PrimitiveType::Triangles,
{g_backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
PrimitiveType::Triangles,
PrimitiveType::Lines, PrimitiveType::Points}};
for (PrimitiveType primitive : primitive_lut)
{

View file

@ -8,7 +8,7 @@
CustomShaderCache::CustomShaderCache()
{
m_api_type = g_ActiveConfig.backend_info.api_type;
m_api_type = g_backend_info.api_type;
m_host_config.bits = ShaderHostConfig::GetCurrent().bits;
m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler();

View file

@ -266,7 +266,7 @@ void IndexGenerator::Init()
{
using OpcodeDecoder::Primitive;
if (g_Config.backend_info.bSupportsPrimitiveRestart)
if (g_backend_info.bSupportsPrimitiveRestart)
{
m_primitive_table[Primitive::GX_DRAW_QUADS] = AddQuads<true>;
m_primitive_table[Primitive::GX_DRAW_QUADS_2] = AddQuads_nonstandard<true>;
@ -284,7 +284,7 @@ void IndexGenerator::Init()
}
if (g_Config.UseVSForLinePointExpand())
{
if (g_Config.backend_info.bSupportsPrimitiveRestart)
if (g_backend_info.bSupportsPrimitiveRestart)
{
m_primitive_table[Primitive::GX_DRAW_LINES] = AddLines_VSExpand<true, false>;
m_primitive_table[Primitive::GX_DRAW_LINE_STRIP] = AddLines_VSExpand<true, true>;

View file

@ -642,7 +642,7 @@ uint WrapCoord(int coord, uint wrap, int size) {{
int size_t = size.y;
int num_layers = size.z;
)");
if (g_ActiveConfig.backend_info.bSupportsTextureQueryLevels)
if (g_backend_info.bSupportsTextureQueryLevels)
{
out.Write(" int number_of_levels = textureQueryLevels(tex);\n");
}
@ -671,7 +671,7 @@ uint WrapCoord(int coord, uint wrap, int size) {{
)");
}
if (g_ActiveConfig.backend_info.bSupportsCoarseDerivatives)
if (g_backend_info.bSupportsCoarseDerivatives)
{
// The software renderer uses the equivalent of coarse derivatives, so use them here for
// consistency. This hasn't been hardware tested.
@ -1922,8 +1922,7 @@ static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_dat
}
if (per_pixel_depth)
{
out.Write("\t\tdepth = {};\n",
!g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? "0.0" : "1.0");
out.Write("\t\tdepth = {};\n", !g_backend_info.bSupportsReversedDepthRange ? "0.0" : "1.0");
}
// ZCOMPLOC HACK:

View file

@ -685,7 +685,7 @@ std::string PostProcessing::GetHeader(bool user_post_process) const
ss << "SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n";
ss << "SAMPLER_BINDING(1) uniform sampler2DArray samp1;\n";
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
if (g_backend_info.bSupportsGeometryShaders)
{
ss << "VARYING_LOCATION(0) in VertexData {\n";
ss << " float3 v_tex0;\n";
@ -770,7 +770,7 @@ std::string PostProcessing::GetFooter() const
static std::string GetVertexShaderBody()
{
std::ostringstream ss;
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
if (g_backend_info.bSupportsGeometryShaders)
{
ss << "VARYING_LOCATION(0) out VertexData {\n";
ss << " float3 v_tex0;\n";
@ -789,12 +789,12 @@ static std::string GetVertexShaderBody()
ss << " v_tex0 = float3(src_rect.xy + (src_rect.zw * v_tex0.xy), float(src_layer));\n";
// Vulkan Y needs to be inverted on every pass
if (g_ActiveConfig.backend_info.api_type == APIType::Vulkan)
if (g_backend_info.api_type == APIType::Vulkan)
{
ss << " opos.y = -opos.y;\n";
}
// OpenGL Y needs to be inverted in all passes except the last one
else if (g_ActiveConfig.backend_info.api_type == APIType::OpenGL)
else if (g_backend_info.api_type == APIType::OpenGL)
{
ss << " if (intermediary_buffer != 0)\n";
ss << " opos.y = -opos.y;\n";
@ -887,7 +887,7 @@ void PostProcessing::FillUniformBuffer(const MathUtil::Rectangle<int>& src,
static_cast<float>(src.GetHeight()) * rcp_src_height};
builtin_uniforms.src_layer = static_cast<s32>(src_layer);
builtin_uniforms.time = static_cast<u32>(m_timer.ElapsedMs());
builtin_uniforms.graphics_api = static_cast<s32>(g_ActiveConfig.backend_info.api_type);
builtin_uniforms.graphics_api = static_cast<s32>(g_backend_info.api_type);
builtin_uniforms.intermediary_buffer = static_cast<s32>(intermediary_buffer);
builtin_uniforms.resampling_method = static_cast<s32>(g_ActiveConfig.output_resampling_mode);
@ -1009,7 +1009,7 @@ static bool UseGeometryShaderForPostProcess(bool is_intermediary_buffer)
switch (g_ActiveConfig.stereo_mode)
{
case StereoMode::QuadBuffer:
return !g_ActiveConfig.backend_info.bUsesExplictQuadBuffering;
return !g_backend_info.bUsesExplictQuadBuffering;
case StereoMode::Anaglyph:
case StereoMode::Passive:
return is_intermediary_buffer;

View file

@ -787,7 +787,7 @@ void Presenter::RenderXFBToScreen(const MathUtil::Rectangle<int>& target_rc,
const MathUtil::Rectangle<int>& source_rc)
{
if (g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer &&
g_ActiveConfig.backend_info.bUsesExplictQuadBuffering)
g_backend_info.bUsesExplictQuadBuffering)
{
// Quad-buffered stereo is annoying on GL.
g_gfx->SelectLeftBuffer();

View file

@ -88,7 +88,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
{
// Depth buffer is inverted for improved precision near far plane
float depth = g_framebuffer_manager->PeekEFBDepth(x, y);
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (!g_backend_info.bSupportsReversedDepthRange)
depth = 1.0f - depth;
// Convert to 24bit depth
@ -133,7 +133,7 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num
// Convert to floating-point depth.
const EfbPokeData& point = points[i];
float depth = float(point.data & 0xFFFFFF) / 16777216.0f;
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (!g_backend_info.bSupportsReversedDepthRange)
depth = 1.0f - depth;
g_framebuffer_manager->PokeEFBDepth(point.x, point.y, depth);

View file

@ -39,7 +39,7 @@ ShaderCache::~ShaderCache()
bool ShaderCache::Initialize()
{
m_api_type = g_ActiveConfig.backend_info.api_type;
m_api_type = g_backend_info.api_type;
m_host_config.bits = ShaderHostConfig::GetCurrent().bits;
if (!CompileSharedPipelines())
@ -352,7 +352,7 @@ void ShaderCache::ClearPipelineCache(T& cache, Y& disk_cache)
void ShaderCache::LoadCaches()
{
// Ubershader caches, if present.
if (g_ActiveConfig.backend_info.bSupportsShaderBinaries)
if (g_backend_info.bSupportsShaderBinaries)
{
LoadShaderCache<ShaderStage::Vertex, UberShader::VertexShaderUid>(m_uber_vs_cache, m_api_type,
"uber-vs", false);
@ -371,7 +371,7 @@ void ShaderCache::LoadCaches()
true);
}
if (g_ActiveConfig.backend_info.bSupportsPipelineCacheData)
if (g_backend_info.bSupportsPipelineCacheData)
{
LoadPipelineCache<GXPipelineUid, SerializedGXPipelineUid>(
m_gx_pipeline_cache, m_gx_pipeline_disk_cache, m_api_type, "specialized-pipeline", true);
@ -470,7 +470,7 @@ const AbstractShader* ShaderCache::InsertVertexShader(const VertexShaderUid& uid
if (shader && !entry.shader)
{
if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
{
auto binary = shader->GetBinary();
if (!binary.empty())
@ -492,7 +492,7 @@ const AbstractShader* ShaderCache::InsertVertexUberShader(const UberShader::Vert
if (shader && !entry.shader)
{
if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
{
auto binary = shader->GetBinary();
if (!binary.empty())
@ -514,7 +514,7 @@ const AbstractShader* ShaderCache::InsertPixelShader(const PixelShaderUid& uid,
if (shader && !entry.shader)
{
if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
{
auto binary = shader->GetBinary();
if (!binary.empty())
@ -536,7 +536,7 @@ const AbstractShader* ShaderCache::InsertPixelUberShader(const UberShader::Pixel
if (shader && !entry.shader)
{
if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
{
auto binary = shader->GetBinary();
if (!binary.empty())
@ -563,7 +563,7 @@ const AbstractShader* ShaderCache::CreateGeometryShader(const GeometryShaderUid&
if (shader && !entry.shader)
{
if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
{
auto binary = shader->GetBinary();
if (!binary.empty())
@ -623,8 +623,8 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
// If framebuffer fetch is available, we can emulate logic ops in the fragment shader
// and don't need the below blend approximation
if (blend.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp &&
!g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
if (blend.logicopenable && !g_backend_info.bSupportsLogicOp &&
!g_backend_info.bSupportsFramebufferFetch)
{
if (!blend.LogicOpApproximationIsExact())
WARN_LOG_FMT(VIDEO,
@ -638,8 +638,7 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
}
const bool benefits_from_ps_dual_source_off =
(!g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
g_ActiveConfig.backend_info.bSupportsFramebufferFetch) ||
(!g_backend_info.bSupportsDualSourceBlend && g_backend_info.bSupportsFramebufferFetch) ||
DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING);
if (benefits_from_ps_dual_source_off && !blend.RequiresDualSrc())
{
@ -648,19 +647,19 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
blend.usedualsrc = false;
}
if (g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
if (g_backend_info.bSupportsFramebufferFetch)
{
bool fbfetch_blend = false;
if ((DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z) ||
!g_ActiveConfig.backend_info.bSupportsEarlyZ) &&
!g_backend_info.bSupportsEarlyZ) &&
ps->ztest == EmulatedZ::ForcedEarly)
{
ps->ztest = EmulatedZ::EarlyWithFBFetch;
fbfetch_blend |= static_cast<bool>(out.blending_state.blendenable);
ps->no_dual_src = true;
}
fbfetch_blend |= blend.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp;
fbfetch_blend |= blend.usedualsrc && !g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
fbfetch_blend |= blend.logicopenable && !g_backend_info.bSupportsLogicOp;
fbfetch_blend |= blend.usedualsrc && !g_backend_info.bSupportsDualSourceBlend;
if (fbfetch_blend)
{
ps->no_dual_src = true;
@ -685,13 +684,13 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
}
// force dual src off if we can't support it
if (!g_ActiveConfig.backend_info.bSupportsDualSourceBlend)
if (!g_backend_info.bSupportsDualSourceBlend)
{
ps->no_dual_src = true;
blend.usedualsrc = false;
}
if (ps->ztest == EmulatedZ::ForcedEarly && !g_ActiveConfig.backend_info.bSupportsEarlyZ)
if (ps->ztest == EmulatedZ::ForcedEarly && !g_backend_info.bSupportsEarlyZ)
{
// These things should be false
ASSERT(!ps->zfreeze);
@ -727,9 +726,8 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
vs->vs_expand = VSExpand::Point;
else
vs->vs_expand = VSExpand::Line;
PrimitiveType prim = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ?
PrimitiveType::TriangleStrip :
PrimitiveType::Triangles;
PrimitiveType prim = g_backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
PrimitiveType::Triangles;
out.rasterization_state.primitive = prim;
out.gs_uid.GetUidData()->primitive_type = static_cast<u32>(prim);
}
@ -785,13 +783,13 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
// GXUberPipelineUid is not trivially copyable because RasterizationState and BlendingState aren't
// either, but we can pretend it is for now. This will be improved after PR #10848 is finished.
memcpy(static_cast<void*>(&out), static_cast<const void*>(&in), sizeof(out)); // Copy padding
if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
if (g_backend_info.bSupportsDynamicVertexLoader)
out.vertex_format = nullptr;
// If framebuffer fetch is available, we can emulate logic ops in the fragment shader
// and don't need the below blend approximation
if (out.blending_state.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp &&
!g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
if (out.blending_state.logicopenable && !g_backend_info.bSupportsLogicOp &&
!g_backend_info.bSupportsFramebufferFetch)
{
if (!out.blending_state.LogicOpApproximationIsExact())
WARN_LOG_FMT(VIDEO,
@ -799,7 +797,7 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
out.blending_state.ApproximateLogicOpWithBlending();
}
if (g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
if (g_backend_info.bSupportsFramebufferFetch)
{
// Always blend in shader
out.blending_state.hex = 0;
@ -807,7 +805,7 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
out.blending_state.alphaupdate = in.blending_state.alphaupdate.Value();
out.ps_uid.GetUidData()->no_dual_src = true;
}
else if (!g_ActiveConfig.backend_info.bSupportsDualSourceBlend ||
else if (!g_backend_info.bSupportsDualSourceBlend ||
(DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) &&
!out.blending_state.RequiresDualSrc()))
{
@ -818,9 +816,8 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
if (g_ActiveConfig.UseVSForLinePointExpand())
{
// All primitives are expanded to triangles in the vertex shader
PrimitiveType prim = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ?
PrimitiveType::TriangleStrip :
PrimitiveType::Triangles;
PrimitiveType prim = g_backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
PrimitiveType::Triangles;
out.rasterization_state.primitive = prim;
out.gs_uid.GetUidData()->primitive_type = static_cast<u32>(prim);
}
@ -1345,7 +1342,7 @@ void ShaderCache::QueueUberShaderPipelines()
}
BlendingState blend = RenderState::GetNoBlendingBlendState();
QueueDummyPipeline(vuid, guid, cleared_puid, blend);
if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
if (g_backend_info.bSupportsDynamicVertexLoader)
{
// Not all GPUs need all the pipeline state compiled into shaders, so they tend to key
// compiled shaders based on some subset of the pipeline state.

View file

@ -16,38 +16,37 @@ 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.ssaa =
g_ActiveConfig.iMultisamples > 1 && g_ActiveConfig.bSSAA && g_backend_info.bSupportsSSAA;
bits.stereo = g_ActiveConfig.stereo_mode != StereoMode::Off;
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;
bits.backend_bitfield = g_ActiveConfig.backend_info.bSupportsBitfield;
bits.backend_dynamic_sampler_indexing =
g_ActiveConfig.backend_info.bSupportsDynamicSamplerIndexing;
bits.backend_shader_framebuffer_fetch = g_ActiveConfig.backend_info.bSupportsFramebufferFetch;
bits.backend_logic_op = g_ActiveConfig.backend_info.bSupportsLogicOp;
bits.backend_palette_conversion = g_ActiveConfig.backend_info.bSupportsPaletteConversion;
bits.backend_dual_source_blend = g_backend_info.bSupportsDualSourceBlend;
bits.backend_geometry_shaders = g_backend_info.bSupportsGeometryShaders;
bits.backend_early_z = g_backend_info.bSupportsEarlyZ;
bits.backend_bbox = g_backend_info.bSupportsBBox;
bits.backend_gs_instancing = g_backend_info.bSupportsGSInstancing;
bits.backend_clip_control = g_backend_info.bSupportsClipControl;
bits.backend_ssaa = g_backend_info.bSupportsSSAA;
bits.backend_atomics = g_backend_info.bSupportsFragmentStoresAndAtomics;
bits.backend_depth_clamp = g_backend_info.bSupportsDepthClamp;
bits.backend_reversed_depth_range = g_backend_info.bSupportsReversedDepthRange;
bits.backend_bitfield = g_backend_info.bSupportsBitfield;
bits.backend_dynamic_sampler_indexing = g_backend_info.bSupportsDynamicSamplerIndexing;
bits.backend_shader_framebuffer_fetch = g_backend_info.bSupportsFramebufferFetch;
bits.backend_logic_op = g_backend_info.bSupportsLogicOp;
bits.backend_palette_conversion = g_backend_info.bSupportsPaletteConversion;
bits.enable_validation_layer = g_ActiveConfig.bEnableValidationLayer;
bits.manual_texture_sampling = !g_ActiveConfig.bFastTextureSampling;
bits.manual_texture_sampling_custom_texture_sizes =
g_ActiveConfig.ManualTextureSamplingWithCustomTextureSizes();
bits.backend_sampler_lod_bias = g_ActiveConfig.backend_info.bSupportsLodBiasInSampler;
bits.backend_dynamic_vertex_loader = g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader;
bits.backend_sampler_lod_bias = g_backend_info.bSupportsLodBiasInSampler;
bits.backend_dynamic_vertex_loader = g_backend_info.bSupportsDynamicVertexLoader;
bits.backend_vs_point_line_expand = g_ActiveConfig.UseVSForLinePointExpand();
bits.backend_gl_layer_in_fs = g_ActiveConfig.backend_info.bSupportsGLLayerInFS;
bits.backend_gl_layer_in_fs = g_backend_info.bSupportsGLLayerInFS;
return bits;
}
@ -348,7 +347,7 @@ const char* GetInterpolationQualifier(bool msaa, bool ssaa, bool in_glsl_interfa
// Without GL_ARB_shading_language_420pack support, the interpolation qualifier must be
// "centroid in" and not "centroid", even within an interface block.
if (in_glsl_interface_block && !g_ActiveConfig.backend_info.bSupportsBindingLayout)
if (in_glsl_interface_block && !g_backend_info.bSupportsBindingLayout)
{
if (!ssaa)
return in ? "centroid in" : "centroid out";

View file

@ -73,7 +73,7 @@ void Statistics::Display() const
ImGui::NextColumn();
};
if (g_ActiveConfig.backend_info.api_type == APIType::Nothing)
if (g_backend_info.api_type == APIType::Nothing)
{
draw_statistic("Objects", "%d", this_frame.num_drawn_objects);
draw_statistic("Vertices Loaded", "%d", this_frame.num_vertices_loaded);

View file

@ -285,7 +285,7 @@ bool TextureCacheBase::DidLinkedAssetsChange(const TCacheEntry& entry)
RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const u8* palette,
TLUTFormat tlutfmt)
{
DEBUG_ASSERT(g_ActiveConfig.backend_info.bSupportsPaletteConversion);
DEBUG_ASSERT(g_backend_info.bSupportsPaletteConversion);
const AbstractPipeline* pipeline = g_shader_cache->GetPaletteConversionPipeline(tlutfmt);
if (!pipeline)
@ -404,7 +404,7 @@ void TextureCacheBase::ScaleTextureCacheEntryTo(RcTcacheEntry& entry, u32 new_wi
return;
}
const u32 max = g_ActiveConfig.backend_info.MaxTextureSize;
const u32 max = g_backend_info.MaxTextureSize;
if (max < new_width || max < new_height)
{
ERROR_LOG_FMT(VIDEO, "Texture too big, width = {}, height = {}", new_width, new_height);
@ -1416,7 +1416,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
// EFB copies have slightly different rules as EFB copy formats have different
// meanings from texture formats.
if ((base_hash == entry->hash &&
(!texture_info.GetPaletteSize() || g_Config.backend_info.bSupportsPaletteConversion)) ||
(!texture_info.GetPaletteSize() || g_backend_info.bSupportsPaletteConversion)) ||
IsPlayingBackFifologWithBrokenEFBCopies)
{
// The texture format in VRAM must match the format that the copy was created with. Some
@ -1451,7 +1451,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
// TODO: We should check width/height/levels for EFB copies. I'm not sure what effect
// checking width/height/levels would have.
if (!texture_info.GetPaletteSize() || !g_Config.backend_info.bSupportsPaletteConversion)
if (!texture_info.GetPaletteSize() || !g_backend_info.bSupportsPaletteConversion)
return entry;
// Note that we found an unconverted EFB copy, then continue. We'll
@ -2239,8 +2239,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(
// Disadvantage of all methods: Calling this function requires the GPU to perform a pipeline flush
// which stalls any further CPU processing.
const bool is_xfb_copy = !is_depth_copy && !isIntensity && dstFormat == EFBCopyFormat::XFB;
bool copy_to_vram =
g_ActiveConfig.backend_info.bSupportsCopyToVram && !g_ActiveConfig.bDisableCopyToVRAM;
bool copy_to_vram = g_backend_info.bSupportsCopyToVram && !g_ActiveConfig.bDisableCopyToVRAM;
bool copy_to_ram =
!(is_xfb_copy ? g_ActiveConfig.bSkipXFBCopyToRam : g_ActiveConfig.bSkipEFBCopyToRam) ||
!copy_to_vram;
@ -2851,7 +2850,7 @@ bool TextureCacheBase::CreateUtilityTextures()
if (!m_efb_encoding_framebuffer)
return false;
if (g_ActiveConfig.backend_info.bSupportsGPUTextureDecoding)
if (g_backend_info.bSupportsGPUTextureDecoding)
{
constexpr TextureConfig decoding_texture_config(
1024, 1024, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage,

View file

@ -62,7 +62,7 @@ static void WriteHeader(ShaderCode& code, APIType api_type)
" float2 clamp_tb;\n"
" uint3 filter_coefficients;\n"
"}};\n");
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
if (g_backend_info.bSupportsGeometryShaders)
{
code.Write("VARYING_LOCATION(0) in VertexData {{\n"
" float3 v_tex0;\n"
@ -124,7 +124,7 @@ static void WriteSampleFunction(ShaderCode& code, const EFBCopyParams& params, A
if (params.depth)
{
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (!g_backend_info.bSupportsReversedDepthRange)
code.Write(" tex_sample.x = 1.0 - tex_sample.x;\n");
code.Write(" uint depth = uint(tex_sample.x * 16777216.0);\n"
@ -1191,7 +1191,7 @@ float4 DecodePixel(int val)
ss << " int texel_buffer_offset;\n";
ss << "};\n";
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
if (g_backend_info.bSupportsGeometryShaders)
{
ss << "VARYING_LOCATION(0) in VertexData {\n";
ss << " float3 v_tex0;\n";

View file

@ -69,7 +69,7 @@ ShaderCode GenerateVertexShader(APIType api_type)
ShaderCode out;
WriteHeader(api_type, out);
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
if (g_backend_info.bSupportsGeometryShaders)
{
out.Write("VARYING_LOCATION(0) out VertexData {{\n"
" float3 v_tex0;\n"
@ -110,7 +110,7 @@ ShaderCode GeneratePixelShader(APIType api_type, const UidData* uid_data)
mono_depth ? "0.0" : "uv.z");
if (uid_data->is_depth_copy)
{
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (!g_backend_info.bSupportsReversedDepthRange)
out.Write(" tex_sample.x = 1.0 - tex_sample.x;\n");
out.Write(" uint depth = uint(tex_sample.x * 16777216.0);\n"
@ -123,7 +123,7 @@ ShaderCode GeneratePixelShader(APIType api_type, const UidData* uid_data)
"}}\n");
}
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
if (g_backend_info.bSupportsGeometryShaders)
{
out.Write("VARYING_LOCATION(0) in VertexData {{\n"
" float3 v_tex0;\n"

View file

@ -156,7 +156,7 @@ DataReader VertexManagerBase::PrepareForAdditionalData(OpcodeDecoder::Primitive
u32 const needed_vertex_bytes = count * stride + 4;
// We can't merge different kinds of primitives, so we have to flush here
PrimitiveType new_primitive_type = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ?
PrimitiveType new_primitive_type = g_backend_info.bSupportsPrimitiveRestart ?
primitive_from_gx_pr[primitive] :
primitive_from_gx[primitive];
if (m_current_primitive_type != new_primitive_type) [[unlikely]]
@ -243,7 +243,7 @@ u32 VertexManagerBase::GetRemainingIndices(OpcodeDecoder::Primitive primitive) c
{
if (g_Config.UseVSForLinePointExpand())
{
if (g_Config.backend_info.bSupportsPrimitiveRestart)
if (g_backend_info.bSupportsPrimitiveRestart)
{
switch (primitive)
{
@ -287,7 +287,7 @@ u32 VertexManagerBase::GetRemainingIndices(OpcodeDecoder::Primitive primitive) c
}
}
}
else if (g_Config.backend_info.bSupportsPrimitiveRestart)
else if (g_backend_info.bSupportsPrimitiveRestart)
{
switch (primitive)
{
@ -348,8 +348,7 @@ void VertexManagerBase::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 nu
void VertexManagerBase::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex)
{
// If bounding box is enabled, we need to flush any changes first, then invalidate what we have.
if (g_bounding_box->IsEnabled() && g_ActiveConfig.bBBoxEnable &&
g_ActiveConfig.backend_info.bSupportsBBox)
if (g_bounding_box->IsEnabled() && g_ActiveConfig.bBBoxEnable && g_backend_info.bSupportsBBox)
{
g_bounding_box->Flush();
}
@ -1090,8 +1089,7 @@ void VertexManagerBase::RenderDrawCall(
VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(),
m_index_generator.GetIndexLen(), &base_vertex, &base_index);
if (g_ActiveConfig.backend_info.api_type != APIType::D3D &&
g_ActiveConfig.UseVSForLinePointExpand() &&
if (g_backend_info.api_type != APIType::D3D && g_ActiveConfig.UseVSForLinePointExpand() &&
(primitive_type == PrimitiveType::Points || primitive_type == PrimitiveType::Lines))
{
// VS point/line expansion puts the vertex id at gl_VertexID << 2
@ -1131,7 +1129,7 @@ const AbstractPipeline* VertexManagerBase::GetCustomPipeline(
{
// D3D has issues compiling large custom ubershaders
// use specialized shaders instead
if (g_ActiveConfig.backend_info.api_type == APIType::D3D)
if (g_backend_info.api_type == APIType::D3D)
{
if (auto pipeline = m_custom_shader_cache->GetPipelineAsync(
current_pipeline_config, custom_shaders, current_pipeline->m_config))

View file

@ -140,7 +140,7 @@ void VertexShaderManager::SetProjectionMatrix(XFStateManager& xf_state_manager)
bool VertexShaderManager::UseVertexDepthRange()
{
// We can't compute the depth range in the vertex shader if we don't support depth clamp.
if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
if (!g_backend_info.bSupportsDepthClamp)
return false;
// We need a full depth range if a ztexture is used.
@ -148,7 +148,7 @@ bool VertexShaderManager::UseVertexDepthRange()
return true;
// If an inverted depth range is unsupported, we also need to check if the range is inverted.
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (!g_backend_info.bSupportsReversedDepthRange)
{
if (xfmem.viewport.zRange < 0.0f)
return true;
@ -370,7 +370,7 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures,
{
// Oversized depth ranges are handled in the vertex shader. We need to reverse
// the far value to use the reversed-Z trick.
if (g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
if (g_backend_info.bSupportsReversedDepthRange)
{
// Sometimes the console also tries to use the reversed-Z trick. We can only do
// that with the expected accuracy if the backend can reverse the depth range.

View file

@ -187,7 +187,7 @@ u16 VideoBackendBase::Video_GetBoundingBox(int index)
}
warn_once = false;
}
else if (!g_ActiveConfig.backend_info.bSupportsBBox)
else if (!g_backend_info.bSupportsBBox)
{
static bool warn_once = true;
if (warn_once)
@ -298,9 +298,9 @@ void VideoBackendBase::PopulateBackendInfo(const WindowSystemInfo& wsi)
g_Config.Refresh();
// Reset backend_info so if the backend forgets to initialize something it doesn't end up using
// a value from the previously used renderer
g_Config.backend_info = {};
g_backend_info = {};
ActivateBackend(Config::Get(Config::MAIN_GFX_BACKEND));
g_Config.backend_info.DisplayName = g_video_backend->GetDisplayName();
g_backend_info.DisplayName = g_video_backend->GetDisplayName();
g_video_backend->InitBackendInfo(wsi);
// We validate the config after initializing the backend info, as system-specific settings
// such as anti-aliasing, or the selected adapter may be invalid, and should be checked.
@ -372,7 +372,7 @@ bool VideoBackendBase::InitializeShared(std::unique_ptr<AbstractGfx> gfx,
if (!g_vertex_manager->Initialize() || !g_shader_cache->Initialize() ||
!g_perf_query->Initialize() || !g_presenter->Initialize() ||
!g_framebuffer_manager->Initialize() || !g_texture_cache->Initialize() ||
(g_ActiveConfig.backend_info.bSupportsBBox && !g_bounding_box->Initialize()) ||
(g_backend_info.bSupportsBBox && !g_bounding_box->Initialize()) ||
!g_graphics_mod_manager->Initialize())
{
PanicAlertFmtT("Failed to initialize renderer classes");

View file

@ -8,7 +8,6 @@
#include "Common/CPUDetect.h"
#include "Common/CommonTypes.h"
#include "Common/Contains.h"
#include "Common/StringUtil.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/GraphicsSettings.h"
@ -24,19 +23,16 @@
#include "VideoCommon/Fifo.h"
#include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/FreeLookCamera.h"
#include "VideoCommon/GraphicsModSystem/Config/GraphicsMod.h"
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/Present.h"
#include "VideoCommon/ShaderGenCommon.h"
#include "VideoCommon/TextureCacheBase.h"
#include "VideoCommon/VertexManagerBase.h"
#include "VideoCommon/VideoCommon.h"
VideoConfig g_Config;
VideoConfig g_ActiveConfig;
BackendInfo g_backend_info;
static bool s_has_registered_callback = false;
static bool IsVSyncActive(bool enabled)
@ -213,15 +209,15 @@ void VideoConfig::Refresh()
void VideoConfig::VerifyValidity()
{
// TODO: Check iMaxAnisotropy value
if (iAdapter < 0 || iAdapter > ((int)backend_info.Adapters.size() - 1))
if (iAdapter < 0 || iAdapter > ((int)g_backend_info.Adapters.size() - 1))
iAdapter = 0;
if (!Common::Contains(backend_info.AAModes, iMultisamples))
if (!Common::Contains(g_backend_info.AAModes, iMultisamples))
iMultisamples = 1;
if (stereo_mode != StereoMode::Off)
{
if (!backend_info.bSupportsGeometryShaders)
if (!g_backend_info.bSupportsGeometryShaders)
{
OSD::AddMessage(
"Stereoscopic 3D isn't supported by your GPU, support for OpenGL 3.2 is required.",
@ -253,7 +249,7 @@ static u32 GetNumAutoShaderPreCompilerThreads()
u32 VideoConfig::GetShaderCompilerThreads() const
{
if (!backend_info.bSupportsBackgroundCompiling)
if (!g_backend_info.bSupportsBackgroundCompiling)
return 0;
if (iShaderCompilerThreads >= 0)
@ -268,7 +264,7 @@ u32 VideoConfig::GetShaderPrecompilerThreads() const
if (!bWaitForShadersBeforeStarting)
return GetShaderCompilerThreads();
if (!backend_info.bSupportsBackgroundCompiling)
if (!g_backend_info.bSupportsBackgroundCompiling)
return 0;
if (iShaderPrecompilerThreads >= 0)

View file

@ -113,6 +113,67 @@ enum ConfigChangeBits : u32
CONFIG_CHANGE_BIT_HDR = (1 << 10),
};
// Static config per API
struct BackendInfo
{
APIType api_type = APIType::Nothing;
std::string DisplayName;
std::vector<std::string> Adapters; // for D3D
std::vector<u32> AAModes;
// TODO: merge AdapterName and Adapters array
std::string AdapterName; // for OpenGL
u32 MaxTextureSize = 16384;
bool bUsesLowerLeftOrigin = false;
bool bUsesExplictQuadBuffering = false;
bool bSupportsExclusiveFullscreen = false; // Note: Vulkan can change this at runtime.
bool bSupportsDualSourceBlend = false;
bool bSupportsPrimitiveRestart = false;
bool bSupportsGeometryShaders = false;
bool bSupportsComputeShaders = false;
bool bSupports3DVision = false;
bool bSupportsEarlyZ = false; // needed by PixelShaderGen, so must stay in VideoCommon
bool bSupportsBindingLayout = false; // Needed by ShaderGen, so must stay in VideoCommon
bool bSupportsBBox = false;
bool bSupportsGSInstancing = false; // Needed by GeometryShaderGen, so must stay in VideoCommon
bool bSupportsPostProcessing = false;
bool bSupportsPaletteConversion = false;
bool bSupportsClipControl = false; // Needed by VertexShaderGen, so must stay in VideoCommon
bool bSupportsSSAA = false;
bool bSupportsFragmentStoresAndAtomics = false; // a.k.a. OpenGL SSBOs a.k.a. Direct3D UAVs
bool bSupportsDepthClamp = false; // Needed by VertexShaderGen, so must stay in VideoCommon
bool bSupportsReversedDepthRange = false;
bool bSupportsLogicOp = false;
bool bSupportsMultithreading = false;
bool bSupportsGPUTextureDecoding = false;
bool bSupportsST3CTextures = false;
bool bSupportsCopyToVram = false;
bool bSupportsBitfield = false; // Needed by UberShaders, so must stay in VideoCommon
// Needed by UberShaders, so must stay in VideoCommon
bool bSupportsDynamicSamplerIndexing = false;
bool bSupportsBPTCTextures = false;
bool bSupportsFramebufferFetch = false; // Used as an alternative to dual-source blend on GLES
bool bSupportsBackgroundCompiling = false;
bool bSupportsLargePoints = false;
bool bSupportsPartialDepthCopies = false;
bool bSupportsDepthReadback = false;
bool bSupportsShaderBinaries = false;
bool bSupportsPipelineCacheData = false;
bool bSupportsCoarseDerivatives = false;
bool bSupportsTextureQueryLevels = false;
bool bSupportsLodBiasInSampler = false;
bool bSupportsSettingObjectNames = false;
bool bSupportsPartialMultisampleResolve = false;
bool bSupportsDynamicVertexLoader = false;
bool bSupportsVSLinePointExpand = false;
bool bSupportsGLLayerInFS = true;
bool bSupportsHDROutput = false;
};
extern BackendInfo g_backend_info;
// NEVER inherit from this class.
struct VideoConfig final
{
@ -289,84 +350,23 @@ struct VideoConfig final
// Vertex loader
VertexLoaderType vertex_loader_type;
// Static config per API
// TODO: Move this out of VideoConfig
struct
{
APIType api_type = APIType::Nothing;
std::string DisplayName;
std::vector<std::string> Adapters; // for D3D
std::vector<u32> AAModes;
// TODO: merge AdapterName and Adapters array
std::string AdapterName; // for OpenGL
u32 MaxTextureSize = 16384;
bool bUsesLowerLeftOrigin = false;
bool bUsesExplictQuadBuffering = false;
bool bSupportsExclusiveFullscreen = false;
bool bSupportsDualSourceBlend = false;
bool bSupportsPrimitiveRestart = false;
bool bSupportsGeometryShaders = false;
bool bSupportsComputeShaders = false;
bool bSupports3DVision = false;
bool bSupportsEarlyZ = false; // needed by PixelShaderGen, so must stay in VideoCommon
bool bSupportsBindingLayout = false; // Needed by ShaderGen, so must stay in VideoCommon
bool bSupportsBBox = false;
bool bSupportsGSInstancing = false; // Needed by GeometryShaderGen, so must stay in VideoCommon
bool bSupportsPostProcessing = false;
bool bSupportsPaletteConversion = false;
bool bSupportsClipControl = false; // Needed by VertexShaderGen, so must stay in VideoCommon
bool bSupportsSSAA = false;
bool bSupportsFragmentStoresAndAtomics = false; // a.k.a. OpenGL SSBOs a.k.a. Direct3D UAVs
bool bSupportsDepthClamp = false; // Needed by VertexShaderGen, so must stay in VideoCommon
bool bSupportsReversedDepthRange = false;
bool bSupportsLogicOp = false;
bool bSupportsMultithreading = false;
bool bSupportsGPUTextureDecoding = false;
bool bSupportsST3CTextures = false;
bool bSupportsCopyToVram = false;
bool bSupportsBitfield = false; // Needed by UberShaders, so must stay in VideoCommon
// Needed by UberShaders, so must stay in VideoCommon
bool bSupportsDynamicSamplerIndexing = false;
bool bSupportsBPTCTextures = false;
bool bSupportsFramebufferFetch = false; // Used as an alternative to dual-source blend on GLES
bool bSupportsBackgroundCompiling = false;
bool bSupportsLargePoints = false;
bool bSupportsPartialDepthCopies = false;
bool bSupportsDepthReadback = false;
bool bSupportsShaderBinaries = false;
bool bSupportsPipelineCacheData = false;
bool bSupportsCoarseDerivatives = false;
bool bSupportsTextureQueryLevels = false;
bool bSupportsLodBiasInSampler = false;
bool bSupportsSettingObjectNames = false;
bool bSupportsPartialMultisampleResolve = false;
bool bSupportsDynamicVertexLoader = false;
bool bSupportsVSLinePointExpand = false;
bool bSupportsGLLayerInFS = true;
bool bSupportsHDROutput = false;
} backend_info;
// Utility
bool UseVSForLinePointExpand() const
{
if (!backend_info.bSupportsVSLinePointExpand)
if (!g_backend_info.bSupportsVSLinePointExpand)
return false;
if (!backend_info.bSupportsGeometryShaders)
if (!g_backend_info.bSupportsGeometryShaders)
return true;
return bPreferVSForLinePointExpansion;
}
bool MultisamplingEnabled() const { return iMultisamples > 1; }
bool ExclusiveFullscreenEnabled() const
{
return backend_info.bSupportsExclusiveFullscreen && !bBorderlessFullscreen;
return g_backend_info.bSupportsExclusiveFullscreen && !bBorderlessFullscreen;
}
bool UseGPUTextureDecoding() const
{
return backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding;
return g_backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding;
}
bool UseVertexRounding() const { return bVertexRounding && iEFBScale != 1; }
bool ManualTextureSamplingWithCustomTextureSizes() const