VideoCommon: Move backend_info out of VideoConfig struct.

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

View file

@ -396,32 +396,31 @@ void DolphinAnalytics::MakePerGameBuilder()
builder.AddData("cfg-gfx-vertex-rounding", g_Config.UseVertexRounding()); builder.AddData("cfg-gfx-vertex-rounding", g_Config.UseVertexRounding());
// GPU features. // GPU features.
if (g_Config.iAdapter < static_cast<int>(g_Config.backend_info.Adapters.size())) if (g_Config.iAdapter < static_cast<int>(g_backend_info.Adapters.size()))
{ {
builder.AddData("gpu-adapter", g_Config.backend_info.Adapters[g_Config.iAdapter]); builder.AddData("gpu-adapter", g_backend_info.Adapters[g_Config.iAdapter]);
} }
else if (!g_Config.backend_info.AdapterName.empty()) else if (!g_backend_info.AdapterName.empty())
{ {
builder.AddData("gpu-adapter", g_Config.backend_info.AdapterName); builder.AddData("gpu-adapter", g_backend_info.AdapterName);
} }
builder.AddData("gpu-has-exclusive-fullscreen", builder.AddData("gpu-has-exclusive-fullscreen", g_backend_info.bSupportsExclusiveFullscreen);
g_Config.backend_info.bSupportsExclusiveFullscreen); builder.AddData("gpu-has-dual-source-blend", g_backend_info.bSupportsDualSourceBlend);
builder.AddData("gpu-has-dual-source-blend", g_Config.backend_info.bSupportsDualSourceBlend); builder.AddData("gpu-has-primitive-restart", g_backend_info.bSupportsPrimitiveRestart);
builder.AddData("gpu-has-primitive-restart", g_Config.backend_info.bSupportsPrimitiveRestart); builder.AddData("gpu-has-geometry-shaders", g_backend_info.bSupportsGeometryShaders);
builder.AddData("gpu-has-geometry-shaders", g_Config.backend_info.bSupportsGeometryShaders); builder.AddData("gpu-has-3d-vision", g_backend_info.bSupports3DVision);
builder.AddData("gpu-has-3d-vision", g_Config.backend_info.bSupports3DVision); builder.AddData("gpu-has-early-z", g_backend_info.bSupportsEarlyZ);
builder.AddData("gpu-has-early-z", g_Config.backend_info.bSupportsEarlyZ); builder.AddData("gpu-has-binding-layout", g_backend_info.bSupportsBindingLayout);
builder.AddData("gpu-has-binding-layout", g_Config.backend_info.bSupportsBindingLayout); builder.AddData("gpu-has-bbox", g_backend_info.bSupportsBBox);
builder.AddData("gpu-has-bbox", g_Config.backend_info.bSupportsBBox);
builder.AddData("gpu-has-fragment-stores-and-atomics", builder.AddData("gpu-has-fragment-stores-and-atomics",
g_Config.backend_info.bSupportsFragmentStoresAndAtomics); g_backend_info.bSupportsFragmentStoresAndAtomics);
builder.AddData("gpu-has-gs-instancing", g_Config.backend_info.bSupportsGSInstancing); builder.AddData("gpu-has-gs-instancing", g_backend_info.bSupportsGSInstancing);
builder.AddData("gpu-has-post-processing", g_Config.backend_info.bSupportsPostProcessing); builder.AddData("gpu-has-post-processing", g_backend_info.bSupportsPostProcessing);
builder.AddData("gpu-has-palette-conversion", g_Config.backend_info.bSupportsPaletteConversion); builder.AddData("gpu-has-palette-conversion", g_backend_info.bSupportsPaletteConversion);
builder.AddData("gpu-has-clip-control", g_Config.backend_info.bSupportsClipControl); builder.AddData("gpu-has-clip-control", g_backend_info.bSupportsClipControl);
builder.AddData("gpu-has-ssaa", g_Config.backend_info.bSupportsSSAA); builder.AddData("gpu-has-ssaa", g_backend_info.bSupportsSSAA);
builder.AddData("gpu-has-logic-ops", g_Config.backend_info.bSupportsLogicOp); builder.AddData("gpu-has-logic-ops", g_backend_info.bSupportsLogicOp);
builder.AddData("gpu-has-framebuffer-fetch", g_Config.backend_info.bSupportsFramebufferFetch); builder.AddData("gpu-has-framebuffer-fetch", g_backend_info.bSupportsFramebufferFetch);
// NetPlay / recording. // NetPlay / recording.
builder.AddData("netplay", NetPlay::IsNetPlayRunning()); builder.AddData("netplay", NetPlay::IsNetPlayRunning());

View file

@ -271,10 +271,9 @@ void AdvancedWidget::ConnectWidgets()
void AdvancedWidget::OnBackendChanged() void AdvancedWidget::OnBackendChanged()
{ {
m_backend_multithreading->setEnabled(g_Config.backend_info.bSupportsMultithreading); m_backend_multithreading->setEnabled(g_backend_info.bSupportsMultithreading);
m_prefer_vs_for_point_line_expansion->setEnabled( m_prefer_vs_for_point_line_expansion->setEnabled(g_backend_info.bSupportsGeometryShaders &&
g_Config.backend_info.bSupportsGeometryShaders && g_backend_info.bSupportsVSLinePointExpand);
g_Config.backend_info.bSupportsVSLinePointExpand);
AddDescriptions(); AddDescriptions();
} }
@ -492,12 +491,12 @@ void AdvancedWidget::AddDescriptions()
m_enable_prog_scan->SetDescription(tr(TR_PROGRESSIVE_SCAN_DESCRIPTION)); m_enable_prog_scan->SetDescription(tr(TR_PROGRESSIVE_SCAN_DESCRIPTION));
m_backend_multithreading->SetDescription(tr(TR_BACKEND_MULTITHREADING_DESCRIPTION)); m_backend_multithreading->SetDescription(tr(TR_BACKEND_MULTITHREADING_DESCRIPTION));
QString vsexpand_extra; QString vsexpand_extra;
if (!g_Config.backend_info.bSupportsGeometryShaders) if (!g_backend_info.bSupportsGeometryShaders)
vsexpand_extra = tr("Forced on because %1 doesn't support geometry shaders.") vsexpand_extra = tr("Forced on because %1 doesn't support geometry shaders.")
.arg(tr(g_Config.backend_info.DisplayName.c_str())); .arg(tr(g_backend_info.DisplayName.c_str()));
else if (!g_Config.backend_info.bSupportsVSLinePointExpand) else if (!g_backend_info.bSupportsVSLinePointExpand)
vsexpand_extra = tr("Forced off because %1 doesn't support VS expansion.") vsexpand_extra = tr("Forced off because %1 doesn't support VS expansion.")
.arg(tr(g_Config.backend_info.DisplayName.c_str())); .arg(tr(g_backend_info.DisplayName.c_str()));
else else
vsexpand_extra = tr(IF_UNSURE_UNCHECKED); vsexpand_extra = tr(IF_UNSURE_UNCHECKED);
m_prefer_vs_for_point_line_expansion->SetDescription( m_prefer_vs_for_point_line_expansion->SetDescription(

View file

@ -343,19 +343,19 @@ void EnhancementsWidget::LoadPPShaders()
void EnhancementsWidget::OnBackendChanged() void EnhancementsWidget::OnBackendChanged()
{ {
m_output_resampling_combo->setEnabled(g_Config.backend_info.bSupportsPostProcessing); m_output_resampling_combo->setEnabled(g_backend_info.bSupportsPostProcessing);
m_configure_color_correction->setEnabled(g_Config.backend_info.bSupportsPostProcessing); m_configure_color_correction->setEnabled(g_backend_info.bSupportsPostProcessing);
m_hdr->setEnabled(g_Config.backend_info.bSupportsHDROutput); m_hdr->setEnabled(g_backend_info.bSupportsHDROutput);
// Stereoscopy // Stereoscopy
const bool supports_stereoscopy = g_Config.backend_info.bSupportsGeometryShaders; const bool supports_stereoscopy = g_backend_info.bSupportsGeometryShaders;
m_3d_mode->setEnabled(supports_stereoscopy); m_3d_mode->setEnabled(supports_stereoscopy);
m_3d_convergence->setEnabled(supports_stereoscopy); m_3d_convergence->setEnabled(supports_stereoscopy);
m_3d_depth->setEnabled(supports_stereoscopy); m_3d_depth->setEnabled(supports_stereoscopy);
m_3d_swap_eyes->setEnabled(supports_stereoscopy); m_3d_swap_eyes->setEnabled(supports_stereoscopy);
// PostProcessing // PostProcessing
const bool supports_postprocessing = g_Config.backend_info.bSupportsPostProcessing; const bool supports_postprocessing = g_backend_info.bSupportsPostProcessing;
if (!supports_postprocessing) if (!supports_postprocessing)
{ {
m_configure_pp_effect->setEnabled(false); m_configure_pp_effect->setEnabled(false);
@ -421,14 +421,14 @@ void EnhancementsWidget::UpdateAAOptions()
m_aa_combo->Reset(); m_aa_combo->Reset();
m_aa_combo->Add(tr("None"), (u32)1, false); m_aa_combo->Add(tr("None"), (u32)1, false);
std::vector<u32> aa_modes = g_Config.backend_info.AAModes; const std::vector<u32>& aa_modes = g_backend_info.AAModes;
for (const u32 aa_mode : aa_modes) for (const u32 aa_mode : aa_modes)
{ {
if (aa_mode > 1) if (aa_mode > 1)
m_aa_combo->Add(tr("%1x MSAA").arg(aa_mode), aa_mode, false); m_aa_combo->Add(tr("%1x MSAA").arg(aa_mode), aa_mode, false);
} }
if (g_Config.backend_info.bSupportsSSAA) if (g_backend_info.bSupportsSSAA)
{ {
for (const u32 aa_mode : aa_modes) for (const u32 aa_mode : aa_modes)
{ {

View file

@ -226,7 +226,7 @@ void GeneralWidget::OnEmulationStateChanged(bool running)
m_render_main_window->setEnabled(!running); m_render_main_window->setEnabled(!running);
m_enable_fullscreen->setEnabled(!running); m_enable_fullscreen->setEnabled(!running);
const bool supports_adapters = !g_Config.backend_info.Adapters.empty(); const bool supports_adapters = !g_backend_info.Adapters.empty();
m_adapter_combo->setEnabled(!running && supports_adapters); m_adapter_combo->setEnabled(!running && supports_adapters);
std::string current_backend = m_backend_combo->currentData().toString().toStdString(); std::string current_backend = m_backend_combo->currentData().toString().toStdString();
@ -362,7 +362,7 @@ void GeneralWidget::OnBackendChanged(const QString& backend_name)
m_adapter_combo->clear(); m_adapter_combo->clear();
const auto& adapters = g_Config.backend_info.Adapters; const auto& adapters = g_backend_info.Adapters;
for (const auto& adapter : adapters) for (const auto& adapter : adapters)
m_adapter_combo->addItem(QString::fromStdString(adapter)); m_adapter_combo->addItem(QString::fromStdString(adapter));

View file

@ -11,14 +11,11 @@
#include "Core/Config/GraphicsSettings.h" #include "Core/Config/GraphicsSettings.h"
#include "Core/Config/MainSettings.h" #include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "DolphinQt/Config/ConfigControls/ConfigBool.h" #include "DolphinQt/Config/ConfigControls/ConfigBool.h"
#include "DolphinQt/Config/ConfigControls/ConfigSlider.h" #include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
#include "DolphinQt/Config/GameConfigWidget.h" #include "DolphinQt/Config/GameConfigWidget.h"
#include "DolphinQt/Config/Graphics/GraphicsWindow.h" #include "DolphinQt/Config/Graphics/GraphicsWindow.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipSlider.h"
#include "DolphinQt/Settings.h"
#include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoConfig.h"
@ -135,8 +132,8 @@ void HacksWidget::CreateWidgets()
void HacksWidget::OnBackendChanged(const QString& backend_name) void HacksWidget::OnBackendChanged(const QString& backend_name)
{ {
const bool bbox = g_Config.backend_info.bSupportsBBox; const bool bbox = g_backend_info.bSupportsBBox;
const bool gpu_texture_decoding = g_Config.backend_info.bSupportsGPUTextureDecoding; const bool gpu_texture_decoding = g_backend_info.bSupportsGPUTextureDecoding;
m_gpu_texture_decoding->setEnabled(gpu_texture_decoding); m_gpu_texture_decoding->setEnabled(gpu_texture_decoding);
m_disable_bounding_box->setEnabled(bbox); m_disable_bounding_box->setEnabled(bbox);

View file

@ -75,68 +75,67 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
void VideoBackend::FillBackendInfo() void VideoBackend::FillBackendInfo()
{ {
g_Config.backend_info.api_type = APIType::D3D; g_backend_info.api_type = APIType::D3D;
g_Config.backend_info.MaxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_backend_info.MaxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
g_Config.backend_info.bUsesLowerLeftOrigin = false; g_backend_info.bUsesLowerLeftOrigin = false;
g_Config.backend_info.bSupportsExclusiveFullscreen = true; g_backend_info.bSupportsExclusiveFullscreen = true;
g_Config.backend_info.bSupportsDualSourceBlend = true; g_backend_info.bSupportsDualSourceBlend = true;
g_Config.backend_info.bSupportsPrimitiveRestart = true; g_backend_info.bSupportsPrimitiveRestart = true;
g_Config.backend_info.bSupportsGeometryShaders = true; g_backend_info.bSupportsGeometryShaders = true;
g_Config.backend_info.bSupportsComputeShaders = false; g_backend_info.bSupportsComputeShaders = false;
g_Config.backend_info.bSupports3DVision = true; g_backend_info.bSupports3DVision = true;
g_Config.backend_info.bSupportsPostProcessing = true; g_backend_info.bSupportsPostProcessing = true;
g_Config.backend_info.bSupportsPaletteConversion = true; g_backend_info.bSupportsPaletteConversion = true;
g_Config.backend_info.bSupportsClipControl = true; g_backend_info.bSupportsClipControl = true;
g_Config.backend_info.bSupportsDepthClamp = true; g_backend_info.bSupportsDepthClamp = true;
g_Config.backend_info.bSupportsReversedDepthRange = false; g_backend_info.bSupportsReversedDepthRange = false;
g_Config.backend_info.bSupportsMultithreading = false; g_backend_info.bSupportsMultithreading = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = true; g_backend_info.bSupportsGPUTextureDecoding = true;
g_Config.backend_info.bSupportsCopyToVram = true; g_backend_info.bSupportsCopyToVram = true;
g_Config.backend_info.bSupportsLargePoints = false; g_backend_info.bSupportsLargePoints = false;
g_Config.backend_info.bSupportsDepthReadback = true; g_backend_info.bSupportsDepthReadback = true;
g_Config.backend_info.bSupportsPartialDepthCopies = false; g_backend_info.bSupportsPartialDepthCopies = false;
g_Config.backend_info.bSupportsBitfield = false; g_backend_info.bSupportsBitfield = false;
g_Config.backend_info.bSupportsDynamicSamplerIndexing = false; g_backend_info.bSupportsDynamicSamplerIndexing = false;
g_Config.backend_info.bSupportsFramebufferFetch = false; g_backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = true; g_backend_info.bSupportsBackgroundCompiling = true;
g_Config.backend_info.bSupportsST3CTextures = true; g_backend_info.bSupportsST3CTextures = true;
g_Config.backend_info.bSupportsBPTCTextures = true; g_backend_info.bSupportsBPTCTextures = true;
g_Config.backend_info.bSupportsEarlyZ = true; g_backend_info.bSupportsEarlyZ = true;
g_Config.backend_info.bSupportsBBox = true; g_backend_info.bSupportsBBox = true;
g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_backend_info.bSupportsFragmentStoresAndAtomics = true;
g_Config.backend_info.bSupportsGSInstancing = true; g_backend_info.bSupportsGSInstancing = true;
g_Config.backend_info.bSupportsSSAA = true; g_backend_info.bSupportsSSAA = true;
g_Config.backend_info.bSupportsShaderBinaries = true; g_backend_info.bSupportsShaderBinaries = true;
g_Config.backend_info.bSupportsPipelineCacheData = false; g_backend_info.bSupportsPipelineCacheData = false;
g_Config.backend_info.bSupportsCoarseDerivatives = true; g_backend_info.bSupportsCoarseDerivatives = true;
g_Config.backend_info.bSupportsTextureQueryLevels = true; g_backend_info.bSupportsTextureQueryLevels = true;
g_Config.backend_info.bSupportsLodBiasInSampler = true; g_backend_info.bSupportsLodBiasInSampler = true;
g_Config.backend_info.bSupportsLogicOp = D3D::SupportsLogicOp(g_Config.iAdapter); g_backend_info.bSupportsLogicOp = D3D::SupportsLogicOp(g_Config.iAdapter);
g_Config.backend_info.bSupportsSettingObjectNames = true; g_backend_info.bSupportsSettingObjectNames = true;
g_Config.backend_info.bSupportsPartialMultisampleResolve = true; g_backend_info.bSupportsPartialMultisampleResolve = true;
g_Config.backend_info.bSupportsDynamicVertexLoader = false; g_backend_info.bSupportsDynamicVertexLoader = false;
g_Config.backend_info.bSupportsHDROutput = true; g_backend_info.bSupportsHDROutput = true;
g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames(); g_backend_info.Adapters = D3DCommon::GetAdapterNames();
g_Config.backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter); g_backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter);
// Override optional features if we are actually booting. // Override optional features if we are actually booting.
if (D3D::device) if (D3D::device)
{ {
g_Config.backend_info.bSupportsST3CTextures = g_backend_info.bSupportsST3CTextures = D3D::SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
D3D::SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) && D3D::SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
D3D::SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) && D3D::SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM);
D3D::SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM); g_backend_info.bSupportsBPTCTextures = D3D::SupportsTextureFormat(DXGI_FORMAT_BC7_UNORM);
g_Config.backend_info.bSupportsBPTCTextures = D3D::SupportsTextureFormat(DXGI_FORMAT_BC7_UNORM);
// Features only supported with a FL11.0+ device. // Features only supported with a FL11.0+ device.
const bool shader_model_5_supported = D3D::feature_level >= D3D_FEATURE_LEVEL_11_0; const bool shader_model_5_supported = D3D::feature_level >= D3D_FEATURE_LEVEL_11_0;
g_Config.backend_info.bSupportsEarlyZ = shader_model_5_supported; g_backend_info.bSupportsEarlyZ = shader_model_5_supported;
g_Config.backend_info.bSupportsBBox = shader_model_5_supported; g_backend_info.bSupportsBBox = shader_model_5_supported;
g_Config.backend_info.bSupportsFragmentStoresAndAtomics = shader_model_5_supported; g_backend_info.bSupportsFragmentStoresAndAtomics = shader_model_5_supported;
g_Config.backend_info.bSupportsGSInstancing = shader_model_5_supported; g_backend_info.bSupportsGSInstancing = shader_model_5_supported;
g_Config.backend_info.bSupportsSSAA = shader_model_5_supported; g_backend_info.bSupportsSSAA = shader_model_5_supported;
g_Config.backend_info.bSupportsGPUTextureDecoding = shader_model_5_supported; g_backend_info.bSupportsGPUTextureDecoding = shader_model_5_supported;
} }
} }

View file

@ -35,7 +35,7 @@ void StateManager::Apply()
// our bindings and sets them to null to prevent hazards. // our bindings and sets them to null to prevent hazards.
if (m_dirtyFlags.test(DirtyFlag_Framebuffer)) if (m_dirtyFlags.test(DirtyFlag_Framebuffer))
{ {
if (g_ActiveConfig.backend_info.bSupportsBBox) if (g_backend_info.bSupportsBBox)
{ {
D3D::context->OMSetRenderTargetsAndUnorderedAccessViews( D3D::context->OMSetRenderTargetsAndUnorderedAccessViews(
m_pending.framebuffer->GetNumRTVs(), m_pending.framebuffer->GetNumRTVs(),
@ -363,7 +363,7 @@ ID3D11BlendState* StateCache::Get(BlendingState state)
if (it != m_blend.end()) if (it != m_blend.end())
return it->second.Get(); return it->second.Get();
if (state.logicopenable && g_ActiveConfig.backend_info.bSupportsLogicOp) if (state.logicopenable && g_backend_info.bSupportsLogicOp)
{ {
D3D11_BLEND_DESC1 desc = {}; D3D11_BLEND_DESC1 desc = {};
D3D11_RENDER_TARGET_BLEND_DESC1& tdesc = desc.RenderTarget[0]; D3D11_RENDER_TARGET_BLEND_DESC1& tdesc = desc.RenderTarget[0];

View file

@ -54,8 +54,7 @@ std::unique_ptr<DXPipeline> DXPipeline::Create(const AbstractPipelineConfig& con
nullptr; nullptr;
// Only use the integer RTV if logic op is supported, and enabled. // Only use the integer RTV if logic op is supported, and enabled.
const bool use_logic_op = const bool use_logic_op = config.blending_state.logicopenable && g_backend_info.bSupportsLogicOp;
config.blending_state.logicopenable && g_ActiveConfig.backend_info.bSupportsLogicOp;
return std::make_unique<DXPipeline>(config, input_layout, vertex_shader->GetD3DVertexShader(), return std::make_unique<DXPipeline>(config, input_layout, vertex_shader->GetD3DVertexShader(),
geometry_shader ? geometry_shader->GetD3DGeometryShader() : geometry_shader ? geometry_shader->GetD3DGeometryShader() :

View file

@ -452,7 +452,7 @@ DXFramebuffer::Create(DXTexture* color_attachment, DXTexture* depth_attachment,
// Only create the integer RTV when logic ops are supported (Win8+). // Only create the integer RTV when logic ops are supported (Win8+).
DXGI_FORMAT integer_format = DXGI_FORMAT integer_format =
D3DCommon::GetRTVFormatForAbstractFormat(color_attachment->GetFormat(), true); D3DCommon::GetRTVFormatForAbstractFormat(color_attachment->GetFormat(), true);
if (g_ActiveConfig.backend_info.bSupportsLogicOp && integer_format != desc.Format) if (g_backend_info.bSupportsLogicOp && integer_format != desc.Format)
{ {
desc.Format = integer_format; desc.Format = integer_format;
hr = D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc, hr = D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc,

View file

@ -23,8 +23,7 @@ namespace DX12
static bool UsesDynamicVertexLoader(const AbstractPipeline* pipeline) static bool UsesDynamicVertexLoader(const AbstractPipeline* pipeline)
{ {
const AbstractPipelineUsage usage = static_cast<const DXPipeline*>(pipeline)->GetUsage(); const AbstractPipelineUsage usage = static_cast<const DXPipeline*>(pipeline)->GetUsage();
return (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader && return (g_backend_info.bSupportsDynamicVertexLoader && usage == AbstractPipelineUsage::GXUber) ||
usage == AbstractPipelineUsage::GXUber) ||
(g_ActiveConfig.UseVSForLinePointExpand() && usage != AbstractPipelineUsage::Utility); (g_ActiveConfig.UseVSForLinePointExpand() && usage != AbstractPipelineUsage::Utility);
} }

View file

@ -47,59 +47,59 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
void VideoBackend::FillBackendInfo() void VideoBackend::FillBackendInfo()
{ {
g_Config.backend_info.api_type = APIType::D3D; g_backend_info.api_type = APIType::D3D;
g_Config.backend_info.bUsesLowerLeftOrigin = false; g_backend_info.bUsesLowerLeftOrigin = false;
g_Config.backend_info.bSupportsExclusiveFullscreen = true; g_backend_info.bSupportsExclusiveFullscreen = true;
g_Config.backend_info.bSupportsDualSourceBlend = true; g_backend_info.bSupportsDualSourceBlend = true;
g_Config.backend_info.bSupportsPrimitiveRestart = true; g_backend_info.bSupportsPrimitiveRestart = true;
g_Config.backend_info.bSupportsGeometryShaders = true; g_backend_info.bSupportsGeometryShaders = true;
g_Config.backend_info.bSupports3DVision = false; g_backend_info.bSupports3DVision = false;
g_Config.backend_info.bSupportsEarlyZ = true; g_backend_info.bSupportsEarlyZ = true;
g_Config.backend_info.bSupportsBindingLayout = false; g_backend_info.bSupportsBindingLayout = false;
g_Config.backend_info.bSupportsBBox = true; g_backend_info.bSupportsBBox = true;
g_Config.backend_info.bSupportsGSInstancing = true; g_backend_info.bSupportsGSInstancing = true;
g_Config.backend_info.bSupportsPaletteConversion = true; g_backend_info.bSupportsPaletteConversion = true;
g_Config.backend_info.bSupportsPostProcessing = true; g_backend_info.bSupportsPostProcessing = true;
g_Config.backend_info.bSupportsClipControl = true; g_backend_info.bSupportsClipControl = true;
g_Config.backend_info.bSupportsSSAA = true; g_backend_info.bSupportsSSAA = true;
g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_backend_info.bSupportsFragmentStoresAndAtomics = true;
g_Config.backend_info.bSupportsDepthClamp = true; g_backend_info.bSupportsDepthClamp = true;
g_Config.backend_info.bSupportsReversedDepthRange = false; g_backend_info.bSupportsReversedDepthRange = false;
g_Config.backend_info.bSupportsComputeShaders = true; g_backend_info.bSupportsComputeShaders = true;
g_Config.backend_info.bSupportsLogicOp = true; g_backend_info.bSupportsLogicOp = true;
g_Config.backend_info.bSupportsMultithreading = false; g_backend_info.bSupportsMultithreading = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = true; g_backend_info.bSupportsGPUTextureDecoding = true;
g_Config.backend_info.bSupportsST3CTextures = false; g_backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsCopyToVram = true; g_backend_info.bSupportsCopyToVram = true;
g_Config.backend_info.bSupportsBitfield = false; g_backend_info.bSupportsBitfield = false;
g_Config.backend_info.bSupportsDynamicSamplerIndexing = false; g_backend_info.bSupportsDynamicSamplerIndexing = false;
g_Config.backend_info.bSupportsBPTCTextures = false; g_backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.bSupportsFramebufferFetch = false; g_backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = true; g_backend_info.bSupportsBackgroundCompiling = true;
g_Config.backend_info.bSupportsLargePoints = false; g_backend_info.bSupportsLargePoints = false;
g_Config.backend_info.bSupportsDepthReadback = true; g_backend_info.bSupportsDepthReadback = true;
g_Config.backend_info.bSupportsPartialDepthCopies = false; g_backend_info.bSupportsPartialDepthCopies = false;
g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames(); g_backend_info.Adapters = D3DCommon::GetAdapterNames();
g_Config.backend_info.AAModes = DXContext::GetAAModes(g_Config.iAdapter); g_backend_info.AAModes = DXContext::GetAAModes(g_Config.iAdapter);
g_Config.backend_info.bSupportsShaderBinaries = true; g_backend_info.bSupportsShaderBinaries = true;
g_Config.backend_info.bSupportsPipelineCacheData = true; g_backend_info.bSupportsPipelineCacheData = true;
g_Config.backend_info.bSupportsCoarseDerivatives = true; g_backend_info.bSupportsCoarseDerivatives = true;
g_Config.backend_info.bSupportsTextureQueryLevels = true; g_backend_info.bSupportsTextureQueryLevels = true;
g_Config.backend_info.bSupportsLodBiasInSampler = true; g_backend_info.bSupportsLodBiasInSampler = true;
g_Config.backend_info.bSupportsSettingObjectNames = true; g_backend_info.bSupportsSettingObjectNames = true;
g_Config.backend_info.bSupportsPartialMultisampleResolve = true; g_backend_info.bSupportsPartialMultisampleResolve = true;
g_Config.backend_info.bSupportsDynamicVertexLoader = true; g_backend_info.bSupportsDynamicVertexLoader = true;
g_Config.backend_info.bSupportsVSLinePointExpand = true; g_backend_info.bSupportsVSLinePointExpand = true;
g_Config.backend_info.bSupportsHDROutput = true; g_backend_info.bSupportsHDROutput = true;
// We can only check texture support once we have a device. // We can only check texture support once we have a device.
if (g_dx_context) if (g_dx_context)
{ {
g_Config.backend_info.bSupportsST3CTextures = g_backend_info.bSupportsST3CTextures =
g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) && g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) && g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM); g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM);
g_Config.backend_info.bSupportsBPTCTextures = g_backend_info.bSupportsBPTCTextures =
g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC7_UNORM); g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC7_UNORM);
} }
} }

View file

@ -334,7 +334,7 @@ void Metal::Gfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool col
static_cast<double>((color >> 24) & 0xFF) / 255.0); static_cast<double>((color >> 24) & 0xFF) / 255.0);
// clang-format on // clang-format on
float z_normalized = static_cast<float>(z & 0xFFFFFF) / 16777216.0f; float z_normalized = static_cast<float>(z & 0xFFFFFF) / 16777216.0f;
if (!g_Config.backend_info.bSupportsReversedDepthRange) if (!g_backend_info.bSupportsReversedDepthRange)
z_normalized = 1.f - z_normalized; z_normalized = 1.f - z_normalized;
g_state_tracker->BeginClearRenderPass(clear_color, z_normalized); g_state_tracker->BeginClearRenderPass(clear_color, z_normalized);
return; return;

View file

@ -81,8 +81,8 @@ bool Metal::VideoBackend::Initialize(const WindowSystemInfo& wsi)
return false; return false;
} }
Util::PopulateBackendInfo(&g_Config); Util::PopulateBackendInfo(&g_backend_info);
Util::PopulateBackendInfoAdapters(&g_Config, devs); Util::PopulateBackendInfoAdapters(&g_backend_info, devs);
// Since we haven't called InitializeShared yet, iAdapter may be out of range, // Since we haven't called InitializeShared yet, iAdapter may be out of range,
// so we have to check it ourselves. // so we have to check it ourselves.
@ -93,7 +93,7 @@ bool Metal::VideoBackend::Initialize(const WindowSystemInfo& wsi)
selected_adapter_index = 0; selected_adapter_index = 0;
} }
MRCOwned<id<MTLDevice>> adapter = std::move(devs[selected_adapter_index]); MRCOwned<id<MTLDevice>> adapter = std::move(devs[selected_adapter_index]);
Util::PopulateBackendInfoFeatures(&g_Config, adapter); Util::PopulateBackendInfoFeatures(g_Config, &g_backend_info, adapter);
#if TARGET_OS_OSX #if TARGET_OS_OSX
// This should be available on all macOS 13.3+ systems but when using OCLP drivers, some devices // This should be available on all macOS 13.3+ systems but when using OCLP drivers, some devices
@ -143,16 +143,16 @@ void Metal::VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{ {
@autoreleasepool @autoreleasepool
{ {
Util::PopulateBackendInfo(&g_Config); Util::PopulateBackendInfo(&g_backend_info);
auto adapters = Util::GetAdapterList(); auto adapters = Util::GetAdapterList();
Util::PopulateBackendInfoAdapters(&g_Config, adapters); Util::PopulateBackendInfoAdapters(&g_backend_info, adapters);
if (!adapters.empty()) if (!adapters.empty())
{ {
// Use the selected adapter, or the first to fill features. // Use the selected adapter, or the first to fill features.
size_t index = static_cast<size_t>(g_Config.iAdapter); size_t index = static_cast<size_t>(g_Config.iAdapter);
if (index >= adapters.size()) if (index >= adapters.size())
index = 0; index = 0;
Util::PopulateBackendInfoFeatures(&g_Config, adapters[index]); Util::PopulateBackendInfoFeatures(g_Config, &g_backend_info, adapters[index]);
} }
} }
} }
@ -165,9 +165,9 @@ void Metal::VideoBackend::PrepareWindow(WindowSystemInfo& wsi)
NSView* view = static_cast<NSView*>(wsi.render_surface); NSView* view = static_cast<NSView*>(wsi.render_surface);
CAMetalLayer* layer = [CAMetalLayer layer]; CAMetalLayer* layer = [CAMetalLayer layer];
Util::PopulateBackendInfo(&g_Config); Util::PopulateBackendInfo(&g_backend_info);
if (g_Config.backend_info.bSupportsHDROutput && g_Config.bHDR) if (g_backend_info.bSupportsHDROutput && g_Config.bHDR)
{ {
[layer setWantsExtendedDynamicRangeContent:YES]; [layer setWantsExtendedDynamicRangeContent:YES];
[layer setPixelFormat:MTLPixelFormatRGBA16Float]; [layer setPixelFormat:MTLPixelFormatRGBA16Float];

View file

@ -57,7 +57,7 @@ void Metal::ObjectCache::Shutdown()
static MTLCompareFunction Convert(CompareMode mode) static MTLCompareFunction Convert(CompareMode mode)
{ {
const bool invert_depth = !g_Config.backend_info.bSupportsReversedDepthRange; const bool invert_depth = !g_backend_info.bSupportsReversedDepthRange;
switch (mode) switch (mode)
{ {
case CompareMode::Never: return MTLCompareFunctionNever; case CompareMode::Never: return MTLCompareFunctionNever;

View file

@ -737,9 +737,8 @@ void Metal::StateTracker::PrepareRender()
m_current.depth_stencil = pipe->DepthStencil(); m_current.depth_stencil = pipe->DepthStencil();
[enc setDepthStencilState:g_object_cache->GetDepthStencil(m_current.depth_stencil)]; [enc setDepthStencilState:g_object_cache->GetDepthStencil(m_current.depth_stencil)];
} }
MTLDepthClipMode clip = is_gx && g_ActiveConfig.backend_info.bSupportsDepthClamp ? MTLDepthClipMode clip =
MTLDepthClipModeClamp : is_gx && g_backend_info.bSupportsDepthClamp ? MTLDepthClipModeClamp : MTLDepthClipModeClip;
MTLDepthClipModeClip;
if (clip != m_current.depth_clip_mode) if (clip != m_current.depth_clip_mode)
{ {
m_current.depth_clip_mode = clip; m_current.depth_clip_mode = clip;

View file

@ -41,10 +41,11 @@ struct Viewport
/// Gets the list of Metal devices, ordered so the system default device is first /// Gets the list of Metal devices, ordered so the system default device is first
std::vector<MRCOwned<id<MTLDevice>>> GetAdapterList(); std::vector<MRCOwned<id<MTLDevice>>> GetAdapterList();
void PopulateBackendInfo(VideoConfig* config); void PopulateBackendInfo(BackendInfo* backend_info);
void PopulateBackendInfoAdapters(VideoConfig* config, void PopulateBackendInfoAdapters(BackendInfo* backend_info,
const std::vector<MRCOwned<id<MTLDevice>>>& adapters); const std::vector<MRCOwned<id<MTLDevice>>>& adapters);
void PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice> device); void PopulateBackendInfoFeatures(const VideoConfig& config, BackendInfo* backend_info,
id<MTLDevice> device);
AbstractTextureFormat ToAbstract(MTLPixelFormat format); AbstractTextureFormat ToAbstract(MTLPixelFormat format);
MTLPixelFormat FromAbstract(AbstractTextureFormat format); MTLPixelFormat FromAbstract(AbstractTextureFormat format);

View file

@ -36,58 +36,58 @@ std::vector<MRCOwned<id<MTLDevice>>> Metal::Util::GetAdapterList()
return list; return list;
} }
void Metal::Util::PopulateBackendInfo(VideoConfig* config) void Metal::Util::PopulateBackendInfo(BackendInfo* backend_info)
{ {
config->backend_info.api_type = APIType::Metal; backend_info->api_type = APIType::Metal;
config->backend_info.bUsesLowerLeftOrigin = false; backend_info->bUsesLowerLeftOrigin = false;
config->backend_info.bSupportsExclusiveFullscreen = false; backend_info->bSupportsExclusiveFullscreen = false;
config->backend_info.bSupportsDualSourceBlend = true; backend_info->bSupportsDualSourceBlend = true;
config->backend_info.bSupportsPrimitiveRestart = true; backend_info->bSupportsPrimitiveRestart = true;
config->backend_info.bSupportsGeometryShaders = false; backend_info->bSupportsGeometryShaders = false;
config->backend_info.bSupportsComputeShaders = true; backend_info->bSupportsComputeShaders = true;
config->backend_info.bSupports3DVision = false; backend_info->bSupports3DVision = false;
config->backend_info.bSupportsEarlyZ = true; backend_info->bSupportsEarlyZ = true;
config->backend_info.bSupportsBindingLayout = true; backend_info->bSupportsBindingLayout = true;
config->backend_info.bSupportsBBox = true; backend_info->bSupportsBBox = true;
config->backend_info.bSupportsGSInstancing = false; backend_info->bSupportsGSInstancing = false;
config->backend_info.bSupportsPostProcessing = true; backend_info->bSupportsPostProcessing = true;
config->backend_info.bSupportsPaletteConversion = true; backend_info->bSupportsPaletteConversion = true;
config->backend_info.bSupportsClipControl = true; backend_info->bSupportsClipControl = true;
config->backend_info.bSupportsSSAA = true; backend_info->bSupportsSSAA = true;
config->backend_info.bSupportsFragmentStoresAndAtomics = true; backend_info->bSupportsFragmentStoresAndAtomics = true;
config->backend_info.bSupportsReversedDepthRange = false; backend_info->bSupportsReversedDepthRange = false;
config->backend_info.bSupportsLogicOp = false; backend_info->bSupportsLogicOp = false;
config->backend_info.bSupportsMultithreading = false; backend_info->bSupportsMultithreading = false;
config->backend_info.bSupportsGPUTextureDecoding = true; backend_info->bSupportsGPUTextureDecoding = true;
config->backend_info.bSupportsCopyToVram = true; backend_info->bSupportsCopyToVram = true;
config->backend_info.bSupportsBitfield = true; backend_info->bSupportsBitfield = true;
config->backend_info.bSupportsDynamicSamplerIndexing = true; backend_info->bSupportsDynamicSamplerIndexing = true;
config->backend_info.bSupportsFramebufferFetch = false; backend_info->bSupportsFramebufferFetch = false;
config->backend_info.bSupportsBackgroundCompiling = true; backend_info->bSupportsBackgroundCompiling = true;
config->backend_info.bSupportsLargePoints = true; backend_info->bSupportsLargePoints = true;
config->backend_info.bSupportsPartialDepthCopies = true; backend_info->bSupportsPartialDepthCopies = true;
config->backend_info.bSupportsDepthReadback = true; backend_info->bSupportsDepthReadback = true;
config->backend_info.bSupportsShaderBinaries = false; backend_info->bSupportsShaderBinaries = false;
config->backend_info.bSupportsPipelineCacheData = false; backend_info->bSupportsPipelineCacheData = false;
config->backend_info.bSupportsCoarseDerivatives = false; backend_info->bSupportsCoarseDerivatives = false;
config->backend_info.bSupportsTextureQueryLevels = true; backend_info->bSupportsTextureQueryLevels = true;
config->backend_info.bSupportsLodBiasInSampler = false; backend_info->bSupportsLodBiasInSampler = false;
config->backend_info.bSupportsSettingObjectNames = true; backend_info->bSupportsSettingObjectNames = true;
// Metal requires multisample resolve to be done on a render pass // Metal requires multisample resolve to be done on a render pass
config->backend_info.bSupportsPartialMultisampleResolve = false; backend_info->bSupportsPartialMultisampleResolve = false;
config->backend_info.bSupportsDynamicVertexLoader = true; backend_info->bSupportsDynamicVertexLoader = true;
config->backend_info.bSupportsVSLinePointExpand = true; backend_info->bSupportsVSLinePointExpand = true;
config->backend_info.bSupportsHDROutput = backend_info->bSupportsHDROutput =
1.0 < [[NSScreen deepestScreen] maximumPotentialExtendedDynamicRangeColorComponentValue]; 1.0 < [[NSScreen deepestScreen] maximumPotentialExtendedDynamicRangeColorComponentValue];
} }
void Metal::Util::PopulateBackendInfoAdapters(VideoConfig* config, void Metal::Util::PopulateBackendInfoAdapters(BackendInfo* backend_info,
const std::vector<MRCOwned<id<MTLDevice>>>& adapters) const std::vector<MRCOwned<id<MTLDevice>>>& adapters)
{ {
config->backend_info.Adapters.clear(); backend_info->Adapters.clear();
for (id<MTLDevice> adapter : adapters) for (id<MTLDevice> adapter : adapters)
{ {
config->backend_info.Adapters.push_back([[adapter name] UTF8String]); backend_info->Adapters.push_back([[adapter name] UTF8String]);
} }
} }
@ -238,7 +238,8 @@ fragment float4 is_helper_test() {
return DetectionResult::Unsure; return DetectionResult::Unsure;
} }
void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice> device) void Metal::Util::PopulateBackendInfoFeatures(const VideoConfig& config, BackendInfo* backend_info,
id<MTLDevice> device)
{ {
// Initialize DriverDetails first so we can use it later // Initialize DriverDetails first so we can use it later
DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN; DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN;
@ -257,9 +258,9 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice>
DriverDetails::Family::UNKNOWN, std::move(name)); DriverDetails::Family::UNKNOWN, std::move(name));
#if TARGET_OS_OSX #if TARGET_OS_OSX
config->backend_info.bSupportsDepthClamp = true; backend_info->bSupportsDepthClamp = true;
config->backend_info.bSupportsST3CTextures = true; backend_info->bSupportsST3CTextures = true;
config->backend_info.bSupportsBPTCTextures = true; backend_info->bSupportsBPTCTextures = true;
#else #else
bool supports_apple4 = false; bool supports_apple4 = false;
bool supports_bcn = false; bool supports_bcn = false;
@ -269,21 +270,21 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice>
supports_apple4 = [device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1]; supports_apple4 = [device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1];
if (@available(iOS 16.4, *)) if (@available(iOS 16.4, *))
supports_bcn = [device supportsBCTextureCompression]; supports_bcn = [device supportsBCTextureCompression];
config->backend_info.bSupportsDepthClamp = supports_apple4; backend_info->bSupportsDepthClamp = supports_apple4;
config->backend_info.bSupportsST3CTextures = supports_bcn; backend_info->bSupportsST3CTextures = supports_bcn;
config->backend_info.bSupportsBPTCTextures = supports_bcn; backend_info->bSupportsBPTCTextures = supports_bcn;
config->backend_info.bSupportsFramebufferFetch = true; backend_info->bSupportsFramebufferFetch = true;
#endif #endif
config->backend_info.AAModes.clear(); backend_info->AAModes.clear();
for (u32 i = 1; i <= 64; i <<= 1) for (u32 i = 1; i <= 64; i <<= 1)
{ {
if ([device supportsTextureSampleCount:i]) if ([device supportsTextureSampleCount:i])
config->backend_info.AAModes.push_back(i); backend_info->AAModes.push_back(i);
} }
switch (config->iManuallyUploadBuffers) switch (config.iManuallyUploadBuffers)
{ {
case TriState::Off: case TriState::Off:
g_features.manual_buffer_upload = false; g_features.manual_buffer_upload = false;
@ -310,7 +311,7 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice>
// Requires SIMD-scoped reduction operations // Requires SIMD-scoped reduction operations
g_features.subgroup_ops = g_features.subgroup_ops =
[device supportsFamily:MTLGPUFamilyMac2] || [device supportsFamily:MTLGPUFamilyApple7]; [device supportsFamily:MTLGPUFamilyMac2] || [device supportsFamily:MTLGPUFamilyApple7];
config->backend_info.bSupportsFramebufferFetch = [device supportsFamily:MTLGPUFamilyApple1]; backend_info->bSupportsFramebufferFetch = [device supportsFamily:MTLGPUFamilyApple1];
} }
if (g_features.subgroup_ops) if (g_features.subgroup_ops)
{ {
@ -325,10 +326,10 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice>
#if TARGET_OS_OSX #if TARGET_OS_OSX
if (@available(macOS 11, *)) if (@available(macOS 11, *))
if (vendor == DriverDetails::VENDOR_INTEL) if (vendor == DriverDetails::VENDOR_INTEL)
config->backend_info.bSupportsFramebufferFetch |= DetectIntelGPUFBFetch(device); backend_info->bSupportsFramebufferFetch |= DetectIntelGPUFBFetch(device);
#endif #endif
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING)) if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING))
config->backend_info.bSupportsDynamicSamplerIndexing = false; backend_info->bSupportsDynamicSamplerIndexing = false;
} }
// clang-format off // clang-format off

View file

@ -9,7 +9,6 @@
#include "VideoBackends/Null/VideoBackend.h" #include "VideoBackends/Null/VideoBackend.h"
#include "Common/Common.h" #include "Common/Common.h"
#include "Common/MsgHandler.h"
#include "VideoBackends/Null/NullBoundingBox.h" #include "VideoBackends/Null/NullBoundingBox.h"
#include "VideoBackends/Null/NullGfx.h" #include "VideoBackends/Null/NullGfx.h"
@ -17,9 +16,6 @@
#include "VideoBackends/Null/PerfQuery.h" #include "VideoBackends/Null/PerfQuery.h"
#include "VideoBackends/Null/TextureCache.h" #include "VideoBackends/Null/TextureCache.h"
#include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/Present.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoCommon.h"
#include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoConfig.h"
@ -27,46 +23,46 @@ namespace Null
{ {
void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi) void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{ {
g_Config.backend_info.api_type = APIType::Nothing; g_backend_info.api_type = APIType::Nothing;
g_Config.backend_info.MaxTextureSize = 16384; g_backend_info.MaxTextureSize = 16384;
g_Config.backend_info.bSupportsExclusiveFullscreen = true; g_backend_info.bSupportsExclusiveFullscreen = true;
g_Config.backend_info.bSupportsDualSourceBlend = true; g_backend_info.bSupportsDualSourceBlend = true;
g_Config.backend_info.bSupportsPrimitiveRestart = true; g_backend_info.bSupportsPrimitiveRestart = true;
g_Config.backend_info.bSupportsGeometryShaders = true; g_backend_info.bSupportsGeometryShaders = true;
g_Config.backend_info.bSupportsComputeShaders = false; g_backend_info.bSupportsComputeShaders = false;
g_Config.backend_info.bSupports3DVision = false; g_backend_info.bSupports3DVision = false;
g_Config.backend_info.bSupportsEarlyZ = true; g_backend_info.bSupportsEarlyZ = true;
g_Config.backend_info.bSupportsBindingLayout = true; g_backend_info.bSupportsBindingLayout = true;
g_Config.backend_info.bSupportsBBox = true; g_backend_info.bSupportsBBox = true;
g_Config.backend_info.bSupportsGSInstancing = true; g_backend_info.bSupportsGSInstancing = true;
g_Config.backend_info.bSupportsPostProcessing = false; g_backend_info.bSupportsPostProcessing = false;
g_Config.backend_info.bSupportsPaletteConversion = true; g_backend_info.bSupportsPaletteConversion = true;
g_Config.backend_info.bSupportsClipControl = true; g_backend_info.bSupportsClipControl = true;
g_Config.backend_info.bSupportsSSAA = true; g_backend_info.bSupportsSSAA = true;
g_Config.backend_info.bSupportsDepthClamp = true; g_backend_info.bSupportsDepthClamp = true;
g_Config.backend_info.bSupportsReversedDepthRange = true; g_backend_info.bSupportsReversedDepthRange = true;
g_Config.backend_info.bSupportsMultithreading = false; g_backend_info.bSupportsMultithreading = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = false; g_backend_info.bSupportsGPUTextureDecoding = false;
g_Config.backend_info.bSupportsST3CTextures = false; g_backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsBPTCTextures = false; g_backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.bSupportsFramebufferFetch = false; g_backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = false; g_backend_info.bSupportsBackgroundCompiling = false;
g_Config.backend_info.bSupportsLogicOp = false; g_backend_info.bSupportsLogicOp = false;
g_Config.backend_info.bSupportsLargePoints = false; g_backend_info.bSupportsLargePoints = false;
g_Config.backend_info.bSupportsDepthReadback = false; g_backend_info.bSupportsDepthReadback = false;
g_Config.backend_info.bSupportsPartialDepthCopies = false; g_backend_info.bSupportsPartialDepthCopies = false;
g_Config.backend_info.bSupportsShaderBinaries = false; g_backend_info.bSupportsShaderBinaries = false;
g_Config.backend_info.bSupportsPipelineCacheData = false; g_backend_info.bSupportsPipelineCacheData = false;
g_Config.backend_info.bSupportsCoarseDerivatives = false; g_backend_info.bSupportsCoarseDerivatives = false;
g_Config.backend_info.bSupportsTextureQueryLevels = false; g_backend_info.bSupportsTextureQueryLevels = false;
g_Config.backend_info.bSupportsLodBiasInSampler = false; g_backend_info.bSupportsLodBiasInSampler = false;
g_Config.backend_info.bSupportsSettingObjectNames = false; g_backend_info.bSupportsSettingObjectNames = false;
g_Config.backend_info.bSupportsPartialMultisampleResolve = true; g_backend_info.bSupportsPartialMultisampleResolve = true;
g_Config.backend_info.bSupportsDynamicVertexLoader = false; g_backend_info.bSupportsDynamicVertexLoader = false;
// aamodes: We only support 1 sample, so no MSAA // aamodes: We only support 1 sample, so no MSAA
g_Config.backend_info.Adapters.clear(); g_backend_info.Adapters.clear();
g_Config.backend_info.AAModes = {1}; g_backend_info.AAModes = {1};
} }
bool VideoBackend::Initialize(const WindowSystemInfo& wsi) bool VideoBackend::Initialize(const WindowSystemInfo& wsi)

View file

@ -283,25 +283,24 @@ bool PopulateConfig(GLContext* m_main_gl_context)
} }
// Copy the GPU name to g_Config, so Analytics can see it. // Copy the GPU name to g_Config, so Analytics can see it.
g_Config.backend_info.AdapterName = g_ogl_config.gl_renderer; g_backend_info.AdapterName = g_ogl_config.gl_renderer;
g_Config.backend_info.bSupportsDualSourceBlend = g_backend_info.bSupportsDualSourceBlend = (GLExtensions::Supports("GL_ARB_blend_func_extended") ||
(GLExtensions::Supports("GL_ARB_blend_func_extended") || GLExtensions::Supports("GL_EXT_blend_func_extended"));
GLExtensions::Supports("GL_EXT_blend_func_extended")); g_backend_info.bSupportsPrimitiveRestart =
g_Config.backend_info.bSupportsPrimitiveRestart =
!DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART) && !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART) &&
((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart")); ((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart"));
g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5"); g_backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5");
g_Config.backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") && g_backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") &&
GLExtensions::Supports("GL_ARB_sample_shading"); GLExtensions::Supports("GL_ARB_sample_shading");
g_Config.backend_info.bSupportsGeometryShaders = g_backend_info.bSupportsGeometryShaders =
GLExtensions::Version() >= 320 && GLExtensions::Version() >= 320 &&
!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_GEOMETRY_SHADERS); !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_GEOMETRY_SHADERS);
g_Config.backend_info.bSupportsPaletteConversion = g_backend_info.bSupportsPaletteConversion =
GLExtensions::Supports("GL_ARB_texture_buffer_object") || GLExtensions::Supports("GL_ARB_texture_buffer_object") ||
GLExtensions::Supports("GL_OES_texture_buffer") || GLExtensions::Supports("GL_OES_texture_buffer") ||
GLExtensions::Supports("GL_EXT_texture_buffer"); GLExtensions::Supports("GL_EXT_texture_buffer");
g_Config.backend_info.bSupportsClipControl = GLExtensions::Supports("GL_ARB_clip_control"); g_backend_info.bSupportsClipControl = GLExtensions::Supports("GL_ARB_clip_control");
g_ogl_config.bSupportsCopySubImage = g_ogl_config.bSupportsCopySubImage =
(GLExtensions::Supports("GL_ARB_copy_image") || GLExtensions::Supports("GL_NV_copy_image") || (GLExtensions::Supports("GL_ARB_copy_image") || GLExtensions::Supports("GL_NV_copy_image") ||
GLExtensions::Supports("GL_EXT_copy_image") || GLExtensions::Supports("GL_EXT_copy_image") ||
@ -311,17 +310,15 @@ bool PopulateConfig(GLContext* m_main_gl_context)
// Desktop OpenGL supports the binding layout if it supports 420pack // Desktop OpenGL supports the binding layout if it supports 420pack
// OpenGL ES 3.1 supports it implicitly without an extension // OpenGL ES 3.1 supports it implicitly without an extension
g_Config.backend_info.bSupportsBindingLayout = g_backend_info.bSupportsBindingLayout = GLExtensions::Supports("GL_ARB_shading_language_420pack");
GLExtensions::Supports("GL_ARB_shading_language_420pack");
// Clip distance support is useless without a method to clamp the depth range // Clip distance support is useless without a method to clamp the depth range
g_Config.backend_info.bSupportsDepthClamp = GLExtensions::Supports("GL_ARB_depth_clamp"); g_backend_info.bSupportsDepthClamp = GLExtensions::Supports("GL_ARB_depth_clamp");
// Desktop OpenGL supports bitfield manulipation and dynamic sampler indexing if it supports // Desktop OpenGL supports bitfield manulipation and dynamic sampler indexing if it supports
// shader5. OpenGL ES 3.1 supports it implicitly without an extension // shader5. OpenGL ES 3.1 supports it implicitly without an extension
g_Config.backend_info.bSupportsBitfield = GLExtensions::Supports("GL_ARB_gpu_shader5"); g_backend_info.bSupportsBitfield = GLExtensions::Supports("GL_ARB_gpu_shader5");
g_Config.backend_info.bSupportsDynamicSamplerIndexing = g_backend_info.bSupportsDynamicSamplerIndexing = GLExtensions::Supports("GL_ARB_gpu_shader5");
GLExtensions::Supports("GL_ARB_gpu_shader5");
g_ogl_config.bIsES = m_main_gl_context->IsGLES(); g_ogl_config.bIsES = m_main_gl_context->IsGLES();
supports_glsl_cache = GLExtensions::Supports("GL_ARB_get_program_binary"); supports_glsl_cache = GLExtensions::Supports("GL_ARB_get_program_binary");
@ -341,14 +338,12 @@ bool PopulateConfig(GLContext* m_main_gl_context)
g_ogl_config.bSupportsImageLoadStore = GLExtensions::Supports("GL_ARB_shader_image_load_store"); g_ogl_config.bSupportsImageLoadStore = GLExtensions::Supports("GL_ARB_shader_image_load_store");
g_ogl_config.bSupportsConservativeDepth = GLExtensions::Supports("GL_ARB_conservative_depth"); g_ogl_config.bSupportsConservativeDepth = GLExtensions::Supports("GL_ARB_conservative_depth");
g_ogl_config.bSupportsAniso = GLExtensions::Supports("GL_EXT_texture_filter_anisotropic"); g_ogl_config.bSupportsAniso = GLExtensions::Supports("GL_EXT_texture_filter_anisotropic");
g_Config.backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader"); g_backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader");
g_Config.backend_info.bSupportsST3CTextures = g_backend_info.bSupportsST3CTextures = GLExtensions::Supports("GL_EXT_texture_compression_s3tc");
GLExtensions::Supports("GL_EXT_texture_compression_s3tc"); g_backend_info.bSupportsBPTCTextures = GLExtensions::Supports("GL_ARB_texture_compression_bptc");
g_Config.backend_info.bSupportsBPTCTextures = g_backend_info.bSupportsCoarseDerivatives =
GLExtensions::Supports("GL_ARB_texture_compression_bptc");
g_Config.backend_info.bSupportsCoarseDerivatives =
GLExtensions::Supports("GL_ARB_derivative_control") || GLExtensions::Version() >= 450; GLExtensions::Supports("GL_ARB_derivative_control") || GLExtensions::Version() >= 450;
g_Config.backend_info.bSupportsTextureQueryLevels = g_backend_info.bSupportsTextureQueryLevels =
GLExtensions::Supports("GL_ARB_texture_query_levels") || GLExtensions::Version() >= 430; GLExtensions::Supports("GL_ARB_texture_query_levels") || GLExtensions::Version() >= 430;
if (GLExtensions::Supports("GL_ARB_shader_storage_buffer_object")) if (GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"))
@ -357,13 +352,13 @@ bool PopulateConfig(GLContext* m_main_gl_context)
GLint vs = 0; GLint vs = 0;
glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &fs); glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &fs);
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs); glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs);
g_Config.backend_info.bSupportsFragmentStoresAndAtomics = fs >= 1; g_backend_info.bSupportsFragmentStoresAndAtomics = fs >= 1;
g_Config.backend_info.bSupportsVSLinePointExpand = vs >= 1; g_backend_info.bSupportsVSLinePointExpand = vs >= 1;
} }
else else
{ {
g_Config.backend_info.bSupportsFragmentStoresAndAtomics = false; g_backend_info.bSupportsFragmentStoresAndAtomics = false;
g_Config.backend_info.bSupportsVSLinePointExpand = false; g_backend_info.bSupportsVSLinePointExpand = false;
} }
if (GLExtensions::Supports("GL_EXT_shader_framebuffer_fetch")) if (GLExtensions::Supports("GL_EXT_shader_framebuffer_fetch"))
@ -378,7 +373,7 @@ bool PopulateConfig(GLContext* m_main_gl_context)
{ {
g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchNone; g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchNone;
} }
g_Config.backend_info.bSupportsFramebufferFetch = g_backend_info.bSupportsFramebufferFetch =
g_ogl_config.SupportedFramebufferFetch != EsFbFetchType::FbFetchNone; g_ogl_config.SupportedFramebufferFetch != EsFbFetchType::FbFetchNone;
if (m_main_gl_context->IsGLES()) if (m_main_gl_context->IsGLES())
@ -398,67 +393,67 @@ bool PopulateConfig(GLContext* m_main_gl_context)
// TODO: Implement support for GL_EXT_clip_cull_distance when there is an extension for // TODO: Implement support for GL_EXT_clip_cull_distance when there is an extension for
// depth clamping. // depth clamping.
g_Config.backend_info.bSupportsDepthClamp = false; g_backend_info.bSupportsDepthClamp = false;
// GLES does not support logic op. // GLES does not support logic op.
g_Config.backend_info.bSupportsLogicOp = false; g_backend_info.bSupportsLogicOp = false;
// glReadPixels() can't be used with non-color formats. But, if we support // glReadPixels() can't be used with non-color formats. But, if we support
// ARB_get_texture_sub_image (unlikely, except maybe on NVIDIA), we can use that instead. // ARB_get_texture_sub_image (unlikely, except maybe on NVIDIA), we can use that instead.
g_Config.backend_info.bSupportsDepthReadback = g_ogl_config.bSupportsTextureSubImage; g_backend_info.bSupportsDepthReadback = g_ogl_config.bSupportsTextureSubImage;
// GL_TEXTURE_LOD_BIAS is not supported on GLES. // GL_TEXTURE_LOD_BIAS is not supported on GLES.
g_Config.backend_info.bSupportsLodBiasInSampler = false; g_backend_info.bSupportsLodBiasInSampler = false;
if (GLExtensions::Version() == 300) if (GLExtensions::Version() == 300)
{ {
g_ogl_config.eSupportedGLSLVersion = GlslEs300; g_ogl_config.eSupportedGLSLVersion = GlslEs300;
g_ogl_config.bSupportsAEP = false; g_ogl_config.bSupportsAEP = false;
g_ogl_config.bSupportsTextureStorage = true; g_ogl_config.bSupportsTextureStorage = true;
g_Config.backend_info.bSupportsGeometryShaders = false; g_backend_info.bSupportsGeometryShaders = false;
} }
else if (GLExtensions::Version() == 310) else if (GLExtensions::Version() == 310)
{ {
g_ogl_config.eSupportedGLSLVersion = GlslEs310; g_ogl_config.eSupportedGLSLVersion = GlslEs310;
g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a"); g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a");
g_Config.backend_info.bSupportsBindingLayout = true; g_backend_info.bSupportsBindingLayout = true;
g_ogl_config.bSupportsImageLoadStore = true; g_ogl_config.bSupportsImageLoadStore = true;
g_Config.backend_info.bSupportsGeometryShaders = g_ogl_config.bSupportsAEP; g_backend_info.bSupportsGeometryShaders = g_ogl_config.bSupportsAEP;
g_Config.backend_info.bSupportsComputeShaders = true; g_backend_info.bSupportsComputeShaders = true;
g_Config.backend_info.bSupportsGSInstancing = g_backend_info.bSupportsGSInstancing =
g_Config.backend_info.bSupportsGeometryShaders && g_backend_info.bSupportsGeometryShaders &&
g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone; g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone;
g_Config.backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP; g_backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP;
g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_backend_info.bSupportsFragmentStoresAndAtomics = true;
g_ogl_config.bSupportsMSAA = true; g_ogl_config.bSupportsMSAA = true;
g_ogl_config.bSupportsTextureStorage = true; g_ogl_config.bSupportsTextureStorage = true;
if (GLExtensions::Supports("GL_OES_texture_storage_multisample_2d_array")) if (GLExtensions::Supports("GL_OES_texture_storage_multisample_2d_array"))
g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageOes; g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageOes;
g_Config.backend_info.bSupportsBitfield = true; g_backend_info.bSupportsBitfield = true;
g_Config.backend_info.bSupportsDynamicSamplerIndexing = g_ogl_config.bSupportsAEP; g_backend_info.bSupportsDynamicSamplerIndexing = g_ogl_config.bSupportsAEP;
} }
else else
{ {
g_ogl_config.eSupportedGLSLVersion = GlslEs320; g_ogl_config.eSupportedGLSLVersion = GlslEs320;
g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a"); g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a");
g_Config.backend_info.bSupportsBindingLayout = true; g_backend_info.bSupportsBindingLayout = true;
g_ogl_config.bSupportsImageLoadStore = true; g_ogl_config.bSupportsImageLoadStore = true;
g_Config.backend_info.bSupportsGeometryShaders = true; g_backend_info.bSupportsGeometryShaders = true;
g_Config.backend_info.bSupportsComputeShaders = true; g_backend_info.bSupportsComputeShaders = true;
g_Config.backend_info.bSupportsGSInstancing = g_backend_info.bSupportsGSInstancing =
g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone; g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone;
g_Config.backend_info.bSupportsPaletteConversion = true; g_backend_info.bSupportsPaletteConversion = true;
g_Config.backend_info.bSupportsSSAA = true; g_backend_info.bSupportsSSAA = true;
g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_backend_info.bSupportsFragmentStoresAndAtomics = true;
g_ogl_config.bSupportsCopySubImage = true; g_ogl_config.bSupportsCopySubImage = true;
g_ogl_config.bSupportsGLBaseVertex = true; g_ogl_config.bSupportsGLBaseVertex = true;
g_ogl_config.bSupportsDebug = true; g_ogl_config.bSupportsDebug = true;
g_ogl_config.bSupportsMSAA = true; g_ogl_config.bSupportsMSAA = true;
g_ogl_config.bSupportsTextureStorage = true; g_ogl_config.bSupportsTextureStorage = true;
g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore; g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore;
g_Config.backend_info.bSupportsBitfield = true; g_backend_info.bSupportsBitfield = true;
g_Config.backend_info.bSupportsDynamicSamplerIndexing = true; g_backend_info.bSupportsDynamicSamplerIndexing = true;
g_Config.backend_info.bSupportsSettingObjectNames = true; g_backend_info.bSupportsSettingObjectNames = true;
} }
} }
else else
@ -480,7 +475,7 @@ bool PopulateConfig(GLContext* m_main_gl_context)
g_ogl_config.bSupportsImageLoadStore = false; // layout keyword is only supported on glsl150+ g_ogl_config.bSupportsImageLoadStore = false; // layout keyword is only supported on glsl150+
g_ogl_config.bSupportsConservativeDepth = g_ogl_config.bSupportsConservativeDepth =
false; // layout keyword is only supported on glsl150+ false; // layout keyword is only supported on glsl150+
g_Config.backend_info.bSupportsGeometryShaders = g_backend_info.bSupportsGeometryShaders =
false; // geometry shaders are only supported on glsl150+ false; // geometry shaders are only supported on glsl150+
} }
else if (GLExtensions::Version() == 310) else if (GLExtensions::Version() == 310)
@ -489,7 +484,7 @@ bool PopulateConfig(GLContext* m_main_gl_context)
g_ogl_config.bSupportsImageLoadStore = false; // layout keyword is only supported on glsl150+ g_ogl_config.bSupportsImageLoadStore = false; // layout keyword is only supported on glsl150+
g_ogl_config.bSupportsConservativeDepth = g_ogl_config.bSupportsConservativeDepth =
false; // layout keyword is only supported on glsl150+ false; // layout keyword is only supported on glsl150+
g_Config.backend_info.bSupportsGeometryShaders = g_backend_info.bSupportsGeometryShaders =
false; // geometry shaders are only supported on glsl150+ false; // geometry shaders are only supported on glsl150+
} }
else if (GLExtensions::Version() == 320) else if (GLExtensions::Version() == 320)
@ -517,18 +512,18 @@ bool PopulateConfig(GLContext* m_main_gl_context)
g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore; g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore;
g_ogl_config.bSupportsImageLoadStore = true; g_ogl_config.bSupportsImageLoadStore = true;
g_ogl_config.bSupportsExplicitLayoutInShader = true; g_ogl_config.bSupportsExplicitLayoutInShader = true;
g_Config.backend_info.bSupportsSSAA = true; g_backend_info.bSupportsSSAA = true;
g_Config.backend_info.bSupportsSettingObjectNames = true; g_backend_info.bSupportsSettingObjectNames = true;
// Compute shaders are core in GL4.3. // Compute shaders are core in GL4.3.
g_Config.backend_info.bSupportsComputeShaders = true; g_backend_info.bSupportsComputeShaders = true;
if (GLExtensions::Version() >= 450) if (GLExtensions::Version() >= 450)
g_ogl_config.bSupportsTextureSubImage = true; g_ogl_config.bSupportsTextureSubImage = true;
} }
else else
{ {
g_ogl_config.eSupportedGLSLVersion = Glsl400; g_ogl_config.eSupportedGLSLVersion = Glsl400;
g_Config.backend_info.bSupportsSSAA = true; g_backend_info.bSupportsSSAA = true;
if (GLExtensions::Version() == 420) if (GLExtensions::Version() == 420)
{ {
@ -547,16 +542,16 @@ bool PopulateConfig(GLContext* m_main_gl_context)
} }
// Supported by all GS-supporting ES and 4.3+ // Supported by all GS-supporting ES and 4.3+
g_Config.backend_info.bSupportsGLLayerInFS = g_Config.backend_info.bSupportsGeometryShaders && g_backend_info.bSupportsGLLayerInFS =
g_ogl_config.eSupportedGLSLVersion >= Glsl430; g_backend_info.bSupportsGeometryShaders && g_ogl_config.eSupportedGLSLVersion >= Glsl430;
g_Config.backend_info.bSupportsBBox = g_Config.backend_info.bSupportsFragmentStoresAndAtomics; g_backend_info.bSupportsBBox = g_backend_info.bSupportsFragmentStoresAndAtomics;
// Either method can do early-z tests. See PixelShaderGen for details. // Either method can do early-z tests. See PixelShaderGen for details.
g_Config.backend_info.bSupportsEarlyZ = g_backend_info.bSupportsEarlyZ =
g_ogl_config.bSupportsImageLoadStore || g_ogl_config.bSupportsConservativeDepth; g_ogl_config.bSupportsImageLoadStore || g_ogl_config.bSupportsConservativeDepth;
g_Config.backend_info.AAModes.clear(); g_backend_info.AAModes.clear();
if (g_ogl_config.bSupportsMSAA) if (g_ogl_config.bSupportsMSAA)
{ {
bool supportsGetInternalFormat = bool supportsGetInternalFormat =
@ -628,13 +623,13 @@ bool PopulateConfig(GLContext* m_main_gl_context)
// It also says "Only positive values are returned", but does not specify whether 1 is // It also says "Only positive values are returned", but does not specify whether 1 is
// included or not; it seems like NVIDIA and Intel GPUs do not include it. // included or not; it seems like NVIDIA and Intel GPUs do not include it.
// We've inserted 1 at the back of both if not present to handle this. // We've inserted 1 at the back of both if not present to handle this.
g_Config.backend_info.AAModes.clear(); g_backend_info.AAModes.clear();
g_Config.backend_info.AAModes.reserve(std::min(color_aa_modes.size(), depth_aa_modes.size())); g_backend_info.AAModes.reserve(std::min(color_aa_modes.size(), depth_aa_modes.size()));
// We only want AA modes that are supported for both the color and depth textures. Probably // We only want AA modes that are supported for both the color and depth textures. Probably
// the support is the same, though. views::reverse is used to swap the order ahead of time. // the support is the same, though. views::reverse is used to swap the order ahead of time.
std::ranges::set_intersection(color_aa_modes | std::views::reverse, std::ranges::set_intersection(color_aa_modes | std::views::reverse,
depth_aa_modes | std::views::reverse, depth_aa_modes | std::views::reverse,
std::back_inserter(g_Config.backend_info.AAModes)); std::back_inserter(g_backend_info.AAModes));
} }
else else
{ {
@ -656,17 +651,17 @@ bool PopulateConfig(GLContext* m_main_gl_context)
while (supported_max_samples > 1) while (supported_max_samples > 1)
{ {
g_Config.backend_info.AAModes.push_back(supported_max_samples); g_backend_info.AAModes.push_back(supported_max_samples);
supported_max_samples /= 2; supported_max_samples /= 2;
} }
g_Config.backend_info.AAModes.push_back(1); g_backend_info.AAModes.push_back(1);
// The UI wants ascending order // The UI wants ascending order
std::ranges::reverse(g_Config.backend_info.AAModes); std::ranges::reverse(g_backend_info.AAModes);
} }
} }
else else
{ {
g_Config.backend_info.AAModes = {1}; g_backend_info.AAModes = {1};
} }
const bool bSupportsIsHelperInvocation = g_ogl_config.bIsES ? const bool bSupportsIsHelperInvocation = g_ogl_config.bIsES ?
@ -690,12 +685,12 @@ bool PopulateConfig(GLContext* m_main_gl_context)
// We require texel buffers, image load store, and compute shaders to enable GPU texture decoding. // We require texel buffers, image load store, and compute shaders to enable GPU texture decoding.
// If the driver doesn't expose the extensions, but supports GL4.3/GLES3.1, it will still be // If the driver doesn't expose the extensions, but supports GL4.3/GLES3.1, it will still be
// enabled in the version check below. // enabled in the version check below.
g_Config.backend_info.bSupportsGPUTextureDecoding = g_backend_info.bSupportsGPUTextureDecoding = g_backend_info.bSupportsPaletteConversion &&
g_Config.backend_info.bSupportsPaletteConversion && g_backend_info.bSupportsComputeShaders &&
g_Config.backend_info.bSupportsComputeShaders && g_ogl_config.bSupportsImageLoadStore; g_ogl_config.bSupportsImageLoadStore;
// Background compiling is supported only when shared contexts aren't broken. // Background compiling is supported only when shared contexts aren't broken.
g_Config.backend_info.bSupportsBackgroundCompiling = g_backend_info.bSupportsBackgroundCompiling =
!DriverDetails::HasBug(DriverDetails::BUG_SHARED_CONTEXT_SHADER_COMPILATION); !DriverDetails::HasBug(DriverDetails::BUG_SHARED_CONTEXT_SHADER_COMPILATION);
// Program binaries are supported on GL4.1+, ARB_get_program_binary, or ES3. // Program binaries are supported on GL4.1+, ARB_get_program_binary, or ES3.
@ -706,7 +701,7 @@ bool PopulateConfig(GLContext* m_main_gl_context)
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_formats); glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_formats);
supports_glsl_cache = num_formats > 0; supports_glsl_cache = num_formats > 0;
} }
g_Config.backend_info.bSupportsPipelineCacheData = supports_glsl_cache; g_backend_info.bSupportsPipelineCacheData = supports_glsl_cache;
int samples; int samples;
glGetIntegerv(GL_SAMPLES, &samples); glGetIntegerv(GL_SAMPLES, &samples);
@ -746,19 +741,19 @@ bool PopulateConfig(GLContext* m_main_gl_context)
const std::string missing_extensions = fmt::format( const std::string missing_extensions = fmt::format(
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}", "{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ", g_backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ", g_backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ",
g_ActiveConfig.backend_info.bSupportsEarlyZ ? "" : "EarlyZ ", g_backend_info.bSupportsEarlyZ ? "" : "EarlyZ ",
g_ogl_config.bSupportsGLPinnedMemory ? "" : "PinnedMemory ", g_ogl_config.bSupportsGLPinnedMemory ? "" : "PinnedMemory ",
supports_glsl_cache ? "" : "ShaderCache ", supports_glsl_cache ? "" : "ShaderCache ",
g_ogl_config.bSupportsGLBaseVertex ? "" : "BaseVertex ", g_ogl_config.bSupportsGLBaseVertex ? "" : "BaseVertex ",
g_ogl_config.bSupportsGLBufferStorage ? "" : "BufferStorage ", g_ogl_config.bSupportsGLBufferStorage ? "" : "BufferStorage ",
g_ogl_config.bSupportsGLSync ? "" : "Sync ", g_ogl_config.bSupportsMSAA ? "" : "MSAA ", g_ogl_config.bSupportsGLSync ? "" : "Sync ", g_ogl_config.bSupportsMSAA ? "" : "MSAA ",
g_ActiveConfig.backend_info.bSupportsSSAA ? "" : "SSAA ", g_backend_info.bSupportsSSAA ? "" : "SSAA ",
g_ActiveConfig.backend_info.bSupportsGSInstancing ? "" : "GSInstancing ", g_backend_info.bSupportsGSInstancing ? "" : "GSInstancing ",
g_ActiveConfig.backend_info.bSupportsClipControl ? "" : "ClipControl ", g_backend_info.bSupportsClipControl ? "" : "ClipControl ",
g_ogl_config.bSupportsCopySubImage ? "" : "CopyImageSubData ", g_ogl_config.bSupportsCopySubImage ? "" : "CopyImageSubData ",
g_ActiveConfig.backend_info.bSupportsDepthClamp ? "" : "DepthClamp "); g_backend_info.bSupportsDepthClamp ? "" : "DepthClamp ");
if (missing_extensions.empty()) if (missing_extensions.empty())
INFO_LOG_FMT(VIDEO, "All used OGL Extensions are available."); INFO_LOG_FMT(VIDEO, "All used OGL Extensions are available.");

View file

@ -177,10 +177,10 @@ OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scal
if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC)) if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC))
m_main_gl_context->SwapInterval(g_ActiveConfig.bVSyncActive); m_main_gl_context->SwapInterval(g_ActiveConfig.bVSyncActive);
if (g_ActiveConfig.backend_info.bSupportsClipControl) if (g_backend_info.bSupportsClipControl)
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
if (g_ActiveConfig.backend_info.bSupportsDepthClamp) if (g_backend_info.bSupportsDepthClamp)
{ {
glEnable(GL_CLIP_DISTANCE0); glEnable(GL_CLIP_DISTANCE0);
glEnable(GL_CLIP_DISTANCE1); glEnable(GL_CLIP_DISTANCE1);
@ -192,7 +192,7 @@ OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scal
glGenFramebuffers(1, &m_shared_read_framebuffer); glGenFramebuffers(1, &m_shared_read_framebuffer);
glGenFramebuffers(1, &m_shared_draw_framebuffer); glGenFramebuffers(1, &m_shared_draw_framebuffer);
if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart) if (g_backend_info.bSupportsPrimitiveRestart)
GLUtil::EnablePrimitiveRestart(m_main_gl_context.get()); GLUtil::EnablePrimitiveRestart(m_main_gl_context.get());
UpdateActiveConfig(); UpdateActiveConfig();
@ -487,7 +487,7 @@ void OGLGfx::CheckForSurfaceResize()
void OGLGfx::BeginUtilityDrawing() void OGLGfx::BeginUtilityDrawing()
{ {
AbstractGfx::BeginUtilityDrawing(); AbstractGfx::BeginUtilityDrawing();
if (g_ActiveConfig.backend_info.bSupportsDepthClamp) if (g_backend_info.bSupportsDepthClamp)
{ {
glDisable(GL_CLIP_DISTANCE0); glDisable(GL_CLIP_DISTANCE0);
glDisable(GL_CLIP_DISTANCE1); glDisable(GL_CLIP_DISTANCE1);
@ -497,7 +497,7 @@ void OGLGfx::BeginUtilityDrawing()
void OGLGfx::EndUtilityDrawing() void OGLGfx::EndUtilityDrawing()
{ {
AbstractGfx::EndUtilityDrawing(); AbstractGfx::EndUtilityDrawing();
if (g_ActiveConfig.backend_info.bSupportsDepthClamp) if (g_backend_info.bSupportsDepthClamp)
{ {
glEnable(GL_CLIP_DISTANCE0); glEnable(GL_CLIP_DISTANCE0);
glEnable(GL_CLIP_DISTANCE1); glEnable(GL_CLIP_DISTANCE1);

View file

@ -113,53 +113,53 @@ bool VideoBackend::FillBackendInfo(GLContext* context)
if (!InitializeGLExtensions(context)) if (!InitializeGLExtensions(context))
return false; return false;
g_Config.backend_info.api_type = APIType::OpenGL; g_backend_info.api_type = APIType::OpenGL;
g_Config.backend_info.MaxTextureSize = 16384; g_backend_info.MaxTextureSize = 16384;
g_Config.backend_info.bUsesLowerLeftOrigin = true; g_backend_info.bUsesLowerLeftOrigin = true;
g_Config.backend_info.bSupportsExclusiveFullscreen = false; g_backend_info.bSupportsExclusiveFullscreen = false;
g_Config.backend_info.bSupportsGeometryShaders = true; g_backend_info.bSupportsGeometryShaders = true;
g_Config.backend_info.bSupportsComputeShaders = false; g_backend_info.bSupportsComputeShaders = false;
g_Config.backend_info.bSupports3DVision = false; g_backend_info.bSupports3DVision = false;
g_Config.backend_info.bSupportsPostProcessing = true; g_backend_info.bSupportsPostProcessing = true;
g_Config.backend_info.bSupportsSSAA = true; g_backend_info.bSupportsSSAA = true;
g_Config.backend_info.bSupportsReversedDepthRange = true; g_backend_info.bSupportsReversedDepthRange = true;
g_Config.backend_info.bSupportsLogicOp = true; g_backend_info.bSupportsLogicOp = true;
g_Config.backend_info.bSupportsMultithreading = false; g_backend_info.bSupportsMultithreading = false;
g_Config.backend_info.bSupportsCopyToVram = true; g_backend_info.bSupportsCopyToVram = true;
g_Config.backend_info.bSupportsLargePoints = true; g_backend_info.bSupportsLargePoints = true;
g_Config.backend_info.bSupportsDepthReadback = true; g_backend_info.bSupportsDepthReadback = true;
g_Config.backend_info.bSupportsPartialDepthCopies = true; g_backend_info.bSupportsPartialDepthCopies = true;
g_Config.backend_info.bSupportsShaderBinaries = false; g_backend_info.bSupportsShaderBinaries = false;
g_Config.backend_info.bSupportsPipelineCacheData = false; g_backend_info.bSupportsPipelineCacheData = false;
g_Config.backend_info.bSupportsLodBiasInSampler = true; g_backend_info.bSupportsLodBiasInSampler = true;
g_Config.backend_info.bSupportsPartialMultisampleResolve = true; g_backend_info.bSupportsPartialMultisampleResolve = true;
// Unneccessary since OGL doesn't use pipelines // Unneccessary since OGL doesn't use pipelines
g_Config.backend_info.bSupportsDynamicVertexLoader = false; g_backend_info.bSupportsDynamicVertexLoader = false;
// TODO: There is a bug here, if texel buffers or SSBOs/atomics are not supported the graphics // TODO: There is a bug here, if texel buffers or SSBOs/atomics are not supported the graphics
// options will show the option when it is not supported. The only way around this would be // options will show the option when it is not supported. The only way around this would be
// creating a context when calling this function to determine what is available. // creating a context when calling this function to determine what is available.
g_Config.backend_info.bSupportsGPUTextureDecoding = true; g_backend_info.bSupportsGPUTextureDecoding = true;
g_Config.backend_info.bSupportsBBox = true; g_backend_info.bSupportsBBox = true;
// Overwritten in OGLConfig.cpp later // Overwritten in OGLConfig.cpp later
g_Config.backend_info.bSupportsDualSourceBlend = true; g_backend_info.bSupportsDualSourceBlend = true;
g_Config.backend_info.bSupportsPrimitiveRestart = true; g_backend_info.bSupportsPrimitiveRestart = true;
g_Config.backend_info.bSupportsPaletteConversion = true; g_backend_info.bSupportsPaletteConversion = true;
g_Config.backend_info.bSupportsClipControl = true; g_backend_info.bSupportsClipControl = true;
g_Config.backend_info.bSupportsDepthClamp = true; g_backend_info.bSupportsDepthClamp = true;
g_Config.backend_info.bSupportsST3CTextures = false; g_backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsBPTCTextures = false; g_backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.bSupportsCoarseDerivatives = false; g_backend_info.bSupportsCoarseDerivatives = false;
g_Config.backend_info.bSupportsTextureQueryLevels = false; g_backend_info.bSupportsTextureQueryLevels = false;
g_Config.backend_info.bSupportsSettingObjectNames = false; g_backend_info.bSupportsSettingObjectNames = false;
g_Config.backend_info.bUsesExplictQuadBuffering = true; g_backend_info.bUsesExplictQuadBuffering = true;
g_Config.backend_info.Adapters.clear(); g_backend_info.Adapters.clear();
// aamodes - 1 is to stay consistent with D3D (means no AA) // aamodes - 1 is to stay consistent with D3D (means no AA)
g_Config.backend_info.AAModes = {1, 2, 4, 8}; g_backend_info.AAModes = {1, 2, 4, 8};
// check for the max vertex attributes // check for the max vertex attributes
GLint numvertexattribs = 0; GLint numvertexattribs = 0;
@ -175,7 +175,7 @@ bool VideoBackend::FillBackendInfo(GLContext* context)
// check the max texture width and height // check the max texture width and height
GLint max_texture_size = 0; GLint max_texture_size = 0;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
g_Config.backend_info.MaxTextureSize = static_cast<u32>(max_texture_size); g_backend_info.MaxTextureSize = static_cast<u32>(max_texture_size);
if (max_texture_size < 1024) if (max_texture_size < 1024)
{ {
PanicAlertFmtT("GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024.", max_texture_size); PanicAlertFmtT("GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024.", max_texture_size);

View file

@ -50,7 +50,7 @@ AbstractPipeline::CacheData OGLPipeline::GetCacheData() const
// copies of the same program combination, we set a flag on the program object so that it can't // copies of the same program combination, we set a flag on the program object so that it can't
// be retrieved again. When booting, the pipeline cache is loaded in-order, so the additional // be retrieved again. When booting, the pipeline cache is loaded in-order, so the additional
// pipelines which use the program combination will re-use the already-created object. // pipelines which use the program combination will re-use the already-created object.
if (!g_ActiveConfig.backend_info.bSupportsPipelineCacheData || m_program->binary_retrieved) if (!g_backend_info.bSupportsPipelineCacheData || m_program->binary_retrieved)
return {}; return {};
GLint program_size = 0; GLint program_size = 0;

View file

@ -31,7 +31,7 @@ OGLShader::OGLShader(ShaderStage stage, GLenum gl_type, GLuint gl_id, std::strin
: AbstractShader(stage), m_id(ProgramShaderCache::GenerateShaderID()), m_type(gl_type), : AbstractShader(stage), m_id(ProgramShaderCache::GenerateShaderID()), m_type(gl_type),
m_gl_id(gl_id), m_source(std::move(source)), m_name(std::move(name)) m_gl_id(gl_id), m_source(std::move(source)), m_name(std::move(name))
{ {
if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames) if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
{ {
glObjectLabel(GL_SHADER, m_gl_id, (GLsizei)m_name.size(), m_name.c_str()); glObjectLabel(GL_SHADER, m_gl_id, (GLsizei)m_name.size(), m_name.c_str());
} }
@ -42,7 +42,7 @@ OGLShader::OGLShader(GLuint gl_compute_program_id, std::string source, std::stri
m_type(GL_COMPUTE_SHADER), m_gl_compute_program_id(gl_compute_program_id), m_type(GL_COMPUTE_SHADER), m_gl_compute_program_id(gl_compute_program_id),
m_source(std::move(source)), m_name(std::move(name)) m_source(std::move(source)), m_name(std::move(name))
{ {
if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames) if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
{ {
glObjectLabel(GL_PROGRAM, m_gl_compute_program_id, (GLsizei)m_name.size(), m_name.c_str()); glObjectLabel(GL_PROGRAM, m_gl_compute_program_id, (GLsizei)m_name.size(), m_name.c_str());
} }

View file

@ -132,7 +132,7 @@ OGLTexture::OGLTexture(const TextureConfig& tex_config, std::string_view name)
glActiveTexture(GL_MUTABLE_TEXTURE_INDEX); glActiveTexture(GL_MUTABLE_TEXTURE_INDEX);
glBindTexture(target, m_texId); glBindTexture(target, m_texId);
if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames) if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
{ {
glObjectLabel(GL_TEXTURE, m_texId, (GLsizei)m_name.size(), m_name.c_str()); glObjectLabel(GL_TEXTURE, m_texId, (GLsizei)m_name.size(), m_name.c_str());
} }

View file

@ -38,7 +38,7 @@ VertexManager::VertexManager() = default;
VertexManager::~VertexManager() VertexManager::~VertexManager()
{ {
if (g_ActiveConfig.backend_info.bSupportsPaletteConversion) if (g_backend_info.bSupportsPaletteConversion)
{ {
glDeleteTextures(static_cast<GLsizei>(m_texel_buffer_views.size()), glDeleteTextures(static_cast<GLsizei>(m_texel_buffer_views.size()),
m_texel_buffer_views.data()); m_texel_buffer_views.data());
@ -58,13 +58,12 @@ bool VertexManager::Initialize()
m_vertex_buffer = StreamBuffer::Create(GL_ARRAY_BUFFER, VERTEX_STREAM_BUFFER_SIZE); m_vertex_buffer = StreamBuffer::Create(GL_ARRAY_BUFFER, VERTEX_STREAM_BUFFER_SIZE);
m_index_buffer = StreamBuffer::Create(GL_ELEMENT_ARRAY_BUFFER, INDEX_STREAM_BUFFER_SIZE); m_index_buffer = StreamBuffer::Create(GL_ELEMENT_ARRAY_BUFFER, INDEX_STREAM_BUFFER_SIZE);
if (g_ActiveConfig.UseVSForLinePointExpand() || if (g_ActiveConfig.UseVSForLinePointExpand() || g_backend_info.bSupportsDynamicVertexLoader)
g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
{ {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_vertex_buffer->GetGLBufferId()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_vertex_buffer->GetGLBufferId());
} }
if (g_ActiveConfig.backend_info.bSupportsPaletteConversion) if (g_backend_info.bSupportsPaletteConversion)
{ {
// The minimum MAX_TEXTURE_BUFFER_SIZE that the spec mandates is 65KB, we are asking for a 1MB // The minimum MAX_TEXTURE_BUFFER_SIZE that the spec mandates is 65KB, we are asking for a 1MB
// buffer here. This buffer is also used as storage for undecoded textures when compute shader // buffer here. This buffer is also used as storage for undecoded textures when compute shader

View file

@ -88,7 +88,7 @@ static std::string GetGLSLVersionString()
void SHADER::SetProgramVariables() void SHADER::SetProgramVariables()
{ {
if (g_ActiveConfig.backend_info.bSupportsBindingLayout) if (g_backend_info.bSupportsBindingLayout)
return; return;
// To set uniform blocks/uniforms, the program must be active. We restore the // To set uniform blocks/uniforms, the program must be active. We restore the
@ -132,7 +132,7 @@ void SHADER::SetProgramBindings(bool is_compute)
} }
if (!is_compute) if (!is_compute)
{ {
if (g_ActiveConfig.backend_info.bSupportsDualSourceBlend) if (g_backend_info.bSupportsDualSourceBlend)
{ {
// So we do support extended blending // So we do support extended blending
// So we need to set a few more things here. // So we need to set a few more things here.
@ -298,8 +298,7 @@ bool ProgramShaderCache::CompileComputeShader(SHADER& shader, std::string_view c
// We need to enable GL_ARB_compute_shader for drivers that support the extension, // We need to enable GL_ARB_compute_shader for drivers that support the extension,
// but not GLSL 4.3. Mesa is one example. // but not GLSL 4.3. Mesa is one example.
std::string full_code; std::string full_code;
if (g_ActiveConfig.backend_info.bSupportsComputeShaders && if (g_backend_info.bSupportsComputeShaders && g_ogl_config.eSupportedGLSLVersion < Glsl430)
g_ogl_config.eSupportedGLSLVersion < Glsl430)
{ {
full_code = "#extension GL_ARB_compute_shader : enable\n"; full_code = "#extension GL_ARB_compute_shader : enable\n";
} }
@ -616,7 +615,7 @@ PipelineProgram* ProgramShaderCache::GetPipelineProgram(const GLVertexFormat* ve
glAttachShader(prog->shader.glprogid, geometry_shader->GetGLShaderID()); glAttachShader(prog->shader.glprogid, geometry_shader->GetGLShaderID());
} }
if (g_ActiveConfig.backend_info.bSupportsPipelineCacheData) if (g_backend_info.bSupportsPipelineCacheData)
glProgramParameteri(prog->shader.glprogid, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); glProgramParameteri(prog->shader.glprogid, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
// Link program. // Link program.
@ -709,7 +708,7 @@ void ProgramShaderCache::CreateHeader()
} }
std::string earlyz_string; std::string earlyz_string;
if (g_ActiveConfig.backend_info.bSupportsEarlyZ) if (g_backend_info.bSupportsEarlyZ)
{ {
if (g_ogl_config.bSupportsImageLoadStore) if (g_ogl_config.bSupportsImageLoadStore)
{ {
@ -748,7 +747,7 @@ void ProgramShaderCache::CreateHeader()
g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone; g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone;
std::string binding_layout; std::string binding_layout;
if (g_ActiveConfig.backend_info.bSupportsBindingLayout) if (g_backend_info.bSupportsBindingLayout)
{ {
if (g_ogl_config.bSupportsExplicitLayoutInShader) if (g_ogl_config.bSupportsExplicitLayoutInShader)
{ {
@ -854,29 +853,28 @@ void ProgramShaderCache::CreateHeader()
, ,
GetGLSLVersionString(), v < Glsl140 ? "#extension GL_ARB_uniform_buffer_object : enable" : "", GetGLSLVersionString(), v < Glsl140 ? "#extension GL_ARB_uniform_buffer_object : enable" : "",
earlyz_string, earlyz_string,
(g_ActiveConfig.backend_info.bSupportsBindingLayout && v < GlslEs310) ? (g_backend_info.bSupportsBindingLayout && v < GlslEs310) ?
"#extension GL_ARB_shading_language_420pack : enable" : "#extension GL_ARB_shading_language_420pack : enable" :
"", "",
(g_ogl_config.bSupportsMSAA && v < Glsl150) ? (g_ogl_config.bSupportsMSAA && v < Glsl150) ?
"#extension GL_ARB_texture_multisample : enable" : "#extension GL_ARB_texture_multisample : enable" :
"", "",
binding_layout.c_str(), varying_location.c_str(), binding_layout.c_str(), varying_location.c_str(),
!is_glsles && g_ActiveConfig.backend_info.bSupportsFragmentStoresAndAtomics ? !is_glsles && g_backend_info.bSupportsFragmentStoresAndAtomics ?
"#extension GL_ARB_shader_storage_buffer_object : enable" : "#extension GL_ARB_shader_storage_buffer_object : enable" :
"", "",
v < Glsl400 && g_ActiveConfig.backend_info.bSupportsGSInstancing ? v < Glsl400 && g_backend_info.bSupportsGSInstancing ?
"#extension GL_ARB_gpu_shader5 : enable" : "#extension GL_ARB_gpu_shader5 : enable" :
"", "",
v < Glsl400 && g_ActiveConfig.backend_info.bSupportsSSAA ? v < Glsl400 && g_backend_info.bSupportsSSAA ? "#extension GL_ARB_sample_shading : enable" :
"#extension GL_ARB_sample_shading : enable" : "",
"",
SupportedESPointSize, SupportedESPointSize,
g_ogl_config.bSupportsAEP ? "#extension GL_ANDROID_extension_pack_es31a : enable" : "", g_ogl_config.bSupportsAEP ? "#extension GL_ANDROID_extension_pack_es31a : enable" : "",
v < Glsl140 && g_ActiveConfig.backend_info.bSupportsPaletteConversion ? v < Glsl140 && g_backend_info.bSupportsPaletteConversion ?
"#extension GL_ARB_texture_buffer_object : enable" : "#extension GL_ARB_texture_buffer_object : enable" :
"", "",
SupportedESTextureBuffer, SupportedESTextureBuffer,
is_glsles && g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? is_glsles && g_backend_info.bSupportsDualSourceBlend ?
"#extension GL_EXT_blend_func_extended : enable" : "#extension GL_EXT_blend_func_extended : enable" :
"" ""
@ -886,10 +884,9 @@ void ProgramShaderCache::CreateHeader()
"#extension GL_ARB_shader_image_load_store : enable" : "#extension GL_ARB_shader_image_load_store : enable" :
"", "",
framebuffer_fetch_string, shader_shuffle_string, framebuffer_fetch_string, shader_shuffle_string,
g_ActiveConfig.backend_info.bSupportsCoarseDerivatives ? g_backend_info.bSupportsCoarseDerivatives ? "#extension GL_ARB_derivative_control : enable" :
"#extension GL_ARB_derivative_control : enable" : "",
"", g_backend_info.bSupportsTextureQueryLevels ?
g_ActiveConfig.backend_info.bSupportsTextureQueryLevels ?
"#extension GL_ARB_texture_query_levels : enable" : "#extension GL_ARB_texture_query_levels : enable" :
"", "",
// Note: GL_ARB_texture_storage_multisample doesn't have an #extension, as it doesn't // Note: GL_ARB_texture_storage_multisample doesn't have an #extension, as it doesn't
@ -900,9 +897,8 @@ void ProgramShaderCache::CreateHeader()
"", "",
is_glsles ? "precision highp float;" : "", is_glsles ? "precision highp int;" : "", is_glsles ? "precision highp float;" : "", is_glsles ? "precision highp int;" : "",
is_glsles ? "precision highp sampler2DArray;" : "", is_glsles ? "precision highp sampler2DArray;" : "",
(is_glsles && g_ActiveConfig.backend_info.bSupportsPaletteConversion) ? (is_glsles && g_backend_info.bSupportsPaletteConversion) ? "precision highp usamplerBuffer;" :
"precision highp usamplerBuffer;" : "",
"",
use_multisample_2d_array_precision ? "precision highp sampler2DMSArray;" : "", use_multisample_2d_array_precision ? "precision highp sampler2DMSArray;" : "",
v >= GlslEs310 ? "precision highp image2DArray;" : ""); v >= GlslEs310 ? "precision highp image2DArray;" : "");
} }
@ -936,15 +932,15 @@ bool SharedContextAsyncShaderCompiler::WorkerThreadInitWorkerThread(void* param)
// Make the state match the main context to have a better chance of avoiding recompiles. // Make the state match the main context to have a better chance of avoiding recompiles.
if (!context->IsGLES()) if (!context->IsGLES())
glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_PROGRAM_POINT_SIZE);
if (g_ActiveConfig.backend_info.bSupportsClipControl) if (g_backend_info.bSupportsClipControl)
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
if (g_ActiveConfig.backend_info.bSupportsDepthClamp) if (g_backend_info.bSupportsDepthClamp)
{ {
glEnable(GL_CLIP_DISTANCE0); glEnable(GL_CLIP_DISTANCE0);
glEnable(GL_CLIP_DISTANCE1); glEnable(GL_CLIP_DISTANCE1);
glEnable(GL_DEPTH_CLAMP); glEnable(GL_DEPTH_CLAMP);
} }
if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart) if (g_backend_info.bSupportsPrimitiveRestart)
GLUtil::EnablePrimitiveRestart(context); GLUtil::EnablePrimitiveRestart(context);
return true; return true;

View file

@ -97,7 +97,7 @@ void SamplerCache::SetParameters(GLuint sampler_id, const SamplerState& params)
glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, params.tm1.min_lod / 16.f); glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, params.tm1.min_lod / 16.f);
glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, params.tm1.max_lod / 16.f); glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, params.tm1.max_lod / 16.f);
if (g_ActiveConfig.backend_info.bSupportsLodBiasInSampler) if (g_backend_info.bSupportsLodBiasInSampler)
{ {
glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, params.tm0.lod_bias / 256.f); glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, params.tm0.lod_bias / 256.f);
} }

View file

@ -64,37 +64,37 @@ std::optional<std::string> VideoSoftware::GetWarningMessage() const
void VideoSoftware::InitBackendInfo(const WindowSystemInfo& wsi) void VideoSoftware::InitBackendInfo(const WindowSystemInfo& wsi)
{ {
g_Config.backend_info.api_type = APIType::Nothing; g_backend_info.api_type = APIType::Nothing;
g_Config.backend_info.MaxTextureSize = 16384; g_backend_info.MaxTextureSize = 16384;
g_Config.backend_info.bUsesLowerLeftOrigin = false; g_backend_info.bUsesLowerLeftOrigin = false;
g_Config.backend_info.bSupports3DVision = false; g_backend_info.bSupports3DVision = false;
g_Config.backend_info.bSupportsDualSourceBlend = true; g_backend_info.bSupportsDualSourceBlend = true;
g_Config.backend_info.bSupportsEarlyZ = true; g_backend_info.bSupportsEarlyZ = true;
g_Config.backend_info.bSupportsPrimitiveRestart = false; g_backend_info.bSupportsPrimitiveRestart = false;
g_Config.backend_info.bSupportsMultithreading = false; g_backend_info.bSupportsMultithreading = false;
g_Config.backend_info.bSupportsComputeShaders = false; g_backend_info.bSupportsComputeShaders = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = false; g_backend_info.bSupportsGPUTextureDecoding = false;
g_Config.backend_info.bSupportsST3CTextures = false; g_backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsBPTCTextures = false; g_backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.bSupportsCopyToVram = false; g_backend_info.bSupportsCopyToVram = false;
g_Config.backend_info.bSupportsLargePoints = false; g_backend_info.bSupportsLargePoints = false;
g_Config.backend_info.bSupportsDepthReadback = false; g_backend_info.bSupportsDepthReadback = false;
g_Config.backend_info.bSupportsPartialDepthCopies = false; g_backend_info.bSupportsPartialDepthCopies = false;
g_Config.backend_info.bSupportsFramebufferFetch = false; g_backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = false; g_backend_info.bSupportsBackgroundCompiling = false;
g_Config.backend_info.bSupportsLogicOp = true; g_backend_info.bSupportsLogicOp = true;
g_Config.backend_info.bSupportsShaderBinaries = false; g_backend_info.bSupportsShaderBinaries = false;
g_Config.backend_info.bSupportsPipelineCacheData = false; g_backend_info.bSupportsPipelineCacheData = false;
g_Config.backend_info.bSupportsBBox = true; g_backend_info.bSupportsBBox = true;
g_Config.backend_info.bSupportsCoarseDerivatives = false; g_backend_info.bSupportsCoarseDerivatives = false;
g_Config.backend_info.bSupportsTextureQueryLevels = false; g_backend_info.bSupportsTextureQueryLevels = false;
g_Config.backend_info.bSupportsLodBiasInSampler = false; g_backend_info.bSupportsLodBiasInSampler = false;
g_Config.backend_info.bSupportsSettingObjectNames = false; g_backend_info.bSupportsSettingObjectNames = false;
g_Config.backend_info.bSupportsPartialMultisampleResolve = true; g_backend_info.bSupportsPartialMultisampleResolve = true;
g_Config.backend_info.bSupportsDynamicVertexLoader = false; g_backend_info.bSupportsDynamicVertexLoader = false;
// aamodes // aamodes
g_Config.backend_info.AAModes = {1}; g_backend_info.AAModes = {1};
} }
bool VideoSoftware::Initialize(const WindowSystemInfo& wsi) bool VideoSoftware::Initialize(const WindowSystemInfo& wsi)

View file

@ -206,18 +206,18 @@ bool ObjectCache::CreateDescriptorSetLayouts()
// Don't set the GS bit if geometry shaders aren't available. // Don't set the GS bit if geometry shaders aren't available.
if (g_ActiveConfig.UseVSForLinePointExpand()) if (g_ActiveConfig.UseVSForLinePointExpand())
{ {
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) if (g_backend_info.bSupportsGeometryShaders)
ubo_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].stageFlags |= VK_SHADER_STAGE_VERTEX_BIT; ubo_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].stageFlags |= VK_SHADER_STAGE_VERTEX_BIT;
else else
ubo_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; ubo_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
} }
else if (!g_ActiveConfig.backend_info.bSupportsGeometryShaders) else if (!g_backend_info.bSupportsGeometryShaders)
{ {
create_infos[DESCRIPTOR_SET_LAYOUT_STANDARD_UNIFORM_BUFFERS].bindingCount--; create_infos[DESCRIPTOR_SET_LAYOUT_STANDARD_UNIFORM_BUFFERS].bindingCount--;
} }
// Remove the dynamic vertex loader's buffer if it'll never be needed // Remove the dynamic vertex loader's buffer if it'll never be needed
if (!g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader) if (!g_backend_info.bSupportsDynamicVertexLoader)
create_infos[DESCRIPTOR_SET_LAYOUT_STANDARD_SHADER_STORAGE_BUFFERS].bindingCount--; create_infos[DESCRIPTOR_SET_LAYOUT_STANDARD_SHADER_STORAGE_BUFFERS].bindingCount--;
for (size_t i = 0; i < create_infos.size(); i++) for (size_t i = 0; i < create_infos.size(); i++)
@ -286,13 +286,13 @@ bool ObjectCache::CreatePipelineLayouts()
}}; }};
const bool ssbos_in_standard = const bool ssbos_in_standard =
g_ActiveConfig.backend_info.bSupportsBBox || g_ActiveConfig.UseVSForLinePointExpand(); g_backend_info.bSupportsBBox || g_ActiveConfig.UseVSForLinePointExpand();
// If bounding box is unsupported, don't bother with the SSBO descriptor set. // If bounding box is unsupported, don't bother with the SSBO descriptor set.
if (!ssbos_in_standard) if (!ssbos_in_standard)
pipeline_layout_info[PIPELINE_LAYOUT_STANDARD].setLayoutCount--; pipeline_layout_info[PIPELINE_LAYOUT_STANDARD].setLayoutCount--;
// If neither SSBO-using feature is supported, skip in ubershaders too // If neither SSBO-using feature is supported, skip in ubershaders too
if (!ssbos_in_standard && !g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader) if (!ssbos_in_standard && !g_backend_info.bSupportsDynamicVertexLoader)
pipeline_layout_info[PIPELINE_LAYOUT_UBER].setLayoutCount--; pipeline_layout_info[PIPELINE_LAYOUT_UBER].setLayoutCount--;
for (size_t i = 0; i < pipeline_layout_info.size(); i++) for (size_t i = 0; i < pipeline_layout_info.size(); i++)

View file

@ -387,7 +387,7 @@ bool StateTracker::Bind()
// Re-bind parts of the pipeline // Re-bind parts of the pipeline
const VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); const VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer();
const bool needs_vertex_buffer = !g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader || const bool needs_vertex_buffer = !g_backend_info.bSupportsDynamicVertexLoader ||
m_pipeline->GetUsage() != AbstractPipelineUsage::GXUber; m_pipeline->GetUsage() != AbstractPipelineUsage::GXUber;
if (needs_vertex_buffer && (m_dirty_flags & DIRTY_FLAG_VERTEX_BUFFER)) if (needs_vertex_buffer && (m_dirty_flags & DIRTY_FLAG_VERTEX_BUFFER))
{ {
@ -481,8 +481,8 @@ void StateTracker::UpdateGXDescriptorSet()
std::array<VkWriteDescriptorSet, MAX_DESCRIPTOR_WRITES> writes; std::array<VkWriteDescriptorSet, MAX_DESCRIPTOR_WRITES> writes;
u32 num_writes = 0; u32 num_writes = 0;
const bool needs_gs_ubo = g_ActiveConfig.backend_info.bSupportsGeometryShaders || const bool needs_gs_ubo =
g_ActiveConfig.UseVSForLinePointExpand(); g_backend_info.bSupportsGeometryShaders || g_ActiveConfig.UseVSForLinePointExpand();
if (m_dirty_flags & DIRTY_FLAG_GX_UBOS || m_gx_descriptor_sets[0] == VK_NULL_HANDLE) if (m_dirty_flags & DIRTY_FLAG_GX_UBOS || m_gx_descriptor_sets[0] == VK_NULL_HANDLE)
{ {
@ -535,8 +535,8 @@ void StateTracker::UpdateGXDescriptorSet()
m_dirty_flags = (m_dirty_flags & ~DIRTY_FLAG_GX_SAMPLERS) | DIRTY_FLAG_DESCRIPTOR_SETS; m_dirty_flags = (m_dirty_flags & ~DIRTY_FLAG_GX_SAMPLERS) | DIRTY_FLAG_DESCRIPTOR_SETS;
} }
const bool needs_bbox_ssbo = g_ActiveConfig.backend_info.bSupportsBBox; const bool needs_bbox_ssbo = g_backend_info.bSupportsBBox;
const bool needs_vertex_ssbo = (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader && const bool needs_vertex_ssbo = (g_backend_info.bSupportsDynamicVertexLoader &&
m_pipeline->GetUsage() == AbstractPipelineUsage::GXUber) || m_pipeline->GetUsage() == AbstractPipelineUsage::GXUber) ||
g_ActiveConfig.UseVSForLinePointExpand(); g_ActiveConfig.UseVSForLinePointExpand();
const bool needs_ssbo = needs_bbox_ssbo || needs_vertex_ssbo; const bool needs_ssbo = needs_bbox_ssbo || needs_vertex_ssbo;
@ -552,8 +552,7 @@ void StateTracker::UpdateGXDescriptorSet()
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, m_gx_descriptor_sets[2], 0, 0, 1, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, m_gx_descriptor_sets[2], 0, 0, 1,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nullptr, &m_bindings.ssbo, nullptr}; VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nullptr, &m_bindings.ssbo, nullptr};
if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader || if (g_backend_info.bSupportsDynamicVertexLoader || g_ActiveConfig.UseVSForLinePointExpand())
g_ActiveConfig.UseVSForLinePointExpand())
{ {
writes[num_writes++] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, writes[num_writes++] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
nullptr, nullptr,

View file

@ -118,7 +118,7 @@ void VKGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_en
clear_color_value.color.float32[2] = static_cast<float>((color >> 0) & 0xFF) / 255.0f; clear_color_value.color.float32[2] = static_cast<float>((color >> 0) & 0xFF) / 255.0f;
clear_color_value.color.float32[3] = static_cast<float>((color >> 24) & 0xFF) / 255.0f; clear_color_value.color.float32[3] = static_cast<float>((color >> 24) & 0xFF) / 255.0f;
clear_depth_value.depthStencil.depth = static_cast<float>(z & 0xFFFFFF) / 16777216.0f; clear_depth_value.depthStencil.depth = static_cast<float>(z & 0xFFFFFF) / 16777216.0f;
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange) if (!g_backend_info.bSupportsReversedDepthRange)
clear_depth_value.depthStencil.depth = 1.0f - clear_depth_value.depthStencil.depth; clear_depth_value.depthStencil.depth = 1.0f - clear_depth_value.depthStencil.depth;
// If we're not in a render pass (start of the frame), we can use a clear render pass // If we're not in a render pass (start of the frame), we can use a clear render pass

View file

@ -3,13 +3,10 @@
#include "VideoBackends/Vulkan/VideoBackend.h" #include "VideoBackends/Vulkan/VideoBackend.h"
#include <vector>
#include "Common/Logging/LogManager.h" #include "Common/Logging/LogManager.h"
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "VideoBackends/Vulkan/CommandBufferManager.h" #include "VideoBackends/Vulkan/CommandBufferManager.h"
#include "VideoBackends/Vulkan/Constants.h"
#include "VideoBackends/Vulkan/ObjectCache.h" #include "VideoBackends/Vulkan/ObjectCache.h"
#include "VideoBackends/Vulkan/StateTracker.h" #include "VideoBackends/Vulkan/StateTracker.h"
#include "VideoBackends/Vulkan/VKBoundingBox.h" #include "VideoBackends/Vulkan/VKBoundingBox.h"
@ -19,9 +16,7 @@
#include "VideoBackends/Vulkan/VKVertexManager.h" #include "VideoBackends/Vulkan/VKVertexManager.h"
#include "VideoBackends/Vulkan/VulkanContext.h" #include "VideoBackends/Vulkan/VulkanContext.h"
#include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/TextureCacheBase.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoConfig.h"
#if defined(VK_USE_PLATFORM_METAL_EXT) #if defined(VK_USE_PLATFORM_METAL_EXT)
@ -32,7 +27,7 @@ namespace Vulkan
{ {
void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi) void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{ {
VulkanContext::PopulateBackendInfo(&g_Config); VulkanContext::PopulateBackendInfo(&g_backend_info);
if (LoadVulkanLibrary()) if (LoadVulkanLibrary())
{ {
@ -44,7 +39,7 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
if (LoadVulkanInstanceFunctions(temp_instance)) if (LoadVulkanInstanceFunctions(temp_instance))
{ {
VulkanContext::GPUList gpu_list = VulkanContext::EnumerateGPUs(temp_instance); VulkanContext::GPUList gpu_list = VulkanContext::EnumerateGPUs(temp_instance);
VulkanContext::PopulateBackendInfoAdapters(&g_Config, gpu_list); VulkanContext::PopulateBackendInfoAdapters(&g_backend_info, gpu_list);
if (!gpu_list.empty()) if (!gpu_list.empty())
{ {
@ -55,8 +50,8 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
VkPhysicalDevice gpu = gpu_list[device_index]; VkPhysicalDevice gpu = gpu_list[device_index];
VulkanContext::PhysicalDeviceInfo properties(gpu); VulkanContext::PhysicalDeviceInfo properties(gpu);
VulkanContext::PopulateBackendInfoFeatures(&g_Config, gpu, properties); VulkanContext::PopulateBackendInfoFeatures(&g_backend_info, gpu, properties);
VulkanContext::PopulateBackendInfoMultisampleModes(&g_Config, gpu, properties); VulkanContext::PopulateBackendInfoMultisampleModes(&g_backend_info, gpu, properties);
} }
} }
@ -144,8 +139,8 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
} }
// Populate BackendInfo with as much information as we can at this point. // Populate BackendInfo with as much information as we can at this point.
VulkanContext::PopulateBackendInfo(&g_Config); VulkanContext::PopulateBackendInfo(&g_backend_info);
VulkanContext::PopulateBackendInfoAdapters(&g_Config, gpu_list); VulkanContext::PopulateBackendInfoAdapters(&g_backend_info, gpu_list);
// We need the surface before we can create a device, as some parameters depend on it. // We need the surface before we can create a device, as some parameters depend on it.
VkSurfaceKHR surface = VK_NULL_HANDLE; VkSurfaceKHR surface = VK_NULL_HANDLE;
@ -183,11 +178,11 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
// Since VulkanContext maintains a copy of the device features and properties, we can use this // Since VulkanContext maintains a copy of the device features and properties, we can use this
// to initialize the backend information, so that we don't need to enumerate everything again. // to initialize the backend information, so that we don't need to enumerate everything again.
VulkanContext::PopulateBackendInfoFeatures(&g_Config, g_vulkan_context->GetPhysicalDevice(), VulkanContext::PopulateBackendInfoFeatures(&g_backend_info, g_vulkan_context->GetPhysicalDevice(),
g_vulkan_context->GetDeviceInfo()); g_vulkan_context->GetDeviceInfo());
VulkanContext::PopulateBackendInfoMultisampleModes( VulkanContext::PopulateBackendInfoMultisampleModes(
&g_Config, g_vulkan_context->GetPhysicalDevice(), g_vulkan_context->GetDeviceInfo()); &g_backend_info, g_vulkan_context->GetPhysicalDevice(), g_vulkan_context->GetDeviceInfo());
g_Config.backend_info.bSupportsExclusiveFullscreen = g_backend_info.bSupportsExclusiveFullscreen =
enable_surface && g_vulkan_context->SupportsExclusiveFullscreen(wsi, surface); enable_surface && g_vulkan_context->SupportsExclusiveFullscreen(wsi, surface);
UpdateActiveConfig(); UpdateActiveConfig();

View file

@ -46,7 +46,7 @@ GetVulkanRasterizationState(const RasterizationState& state)
{VK_CULL_MODE_NONE, VK_CULL_MODE_BACK_BIT, VK_CULL_MODE_FRONT_BIT, {VK_CULL_MODE_NONE, VK_CULL_MODE_BACK_BIT, VK_CULL_MODE_FRONT_BIT,
VK_CULL_MODE_FRONT_AND_BACK}}; VK_CULL_MODE_FRONT_AND_BACK}};
bool depth_clamp = g_ActiveConfig.backend_info.bSupportsDepthClamp; bool depth_clamp = g_backend_info.bSupportsDepthClamp;
return { return {
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
@ -85,7 +85,7 @@ static VkPipelineDepthStencilStateCreateInfo GetVulkanDepthStencilState(const De
{ {
// Less/greater are swapped due to inverted depth. // Less/greater are swapped due to inverted depth.
VkCompareOp compare_op; VkCompareOp compare_op;
bool inverted_depth = !g_ActiveConfig.backend_info.bSupportsReversedDepthRange; bool inverted_depth = !g_backend_info.bSupportsReversedDepthRange;
switch (state.func) switch (state.func)
{ {
case CompareMode::Never: case CompareMode::Never:
@ -215,7 +215,7 @@ GetVulkanColorBlendState(const BlendingState& state,
VK_LOGIC_OP_COPY_INVERTED, VK_LOGIC_OP_OR_INVERTED, VK_LOGIC_OP_NAND, VK_LOGIC_OP_SET}}; VK_LOGIC_OP_COPY_INVERTED, VK_LOGIC_OP_OR_INVERTED, VK_LOGIC_OP_NAND, VK_LOGIC_OP_SET}};
VkBool32 vk_logic_op_enable = static_cast<VkBool32>(state.logicopenable); VkBool32 vk_logic_op_enable = static_cast<VkBool32>(state.logicopenable);
if (vk_logic_op_enable && !g_ActiveConfig.backend_info.bSupportsLogicOp) if (vk_logic_op_enable && !g_backend_info.bSupportsLogicOp)
{ {
// At the time of writing, Adreno and Mali drivers didn't support logic ops. // At the time of writing, Adreno and Mali drivers didn't support logic ops.
// The "emulation" through blending path has been removed, so just disable it completely. // The "emulation" through blending path has been removed, so just disable it completely.
@ -306,7 +306,7 @@ std::unique_ptr<VKPipeline> VKPipeline::Create(const AbstractPipelineConfig& con
// VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
// VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
// primitiveRestartEnable must be VK_FALSE // primitiveRestartEnable must be VK_FALSE
if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart && if (g_backend_info.bSupportsPrimitiveRestart &&
IsStripPrimitiveTopology(input_assembly_state.topology)) IsStripPrimitiveTopology(input_assembly_state.topology))
{ {
input_assembly_state.primitiveRestartEnable = VK_TRUE; input_assembly_state.primitiveRestartEnable = VK_TRUE;

View file

@ -19,7 +19,7 @@ VKShader::VKShader(ShaderStage stage, std::vector<u32> spv, VkShaderModule mod,
: AbstractShader(stage), m_spv(std::move(spv)), m_module(mod), : AbstractShader(stage), m_spv(std::move(spv)), m_module(mod),
m_compute_pipeline(VK_NULL_HANDLE), m_name(name) m_compute_pipeline(VK_NULL_HANDLE), m_name(name)
{ {
if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames) if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
{ {
VkDebugUtilsObjectNameInfoEXT name_info = {}; VkDebugUtilsObjectNameInfoEXT name_info = {};
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
@ -34,7 +34,7 @@ VKShader::VKShader(std::vector<u32> spv, VkPipeline compute_pipeline, std::strin
: AbstractShader(ShaderStage::Compute), m_spv(std::move(spv)), m_module(VK_NULL_HANDLE), : AbstractShader(ShaderStage::Compute), m_spv(std::move(spv)), m_module(VK_NULL_HANDLE),
m_compute_pipeline(compute_pipeline), m_name(name) m_compute_pipeline(compute_pipeline), m_name(name)
{ {
if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames) if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
{ {
VkDebugUtilsObjectNameInfoEXT name_info = {}; VkDebugUtilsObjectNameInfoEXT name_info = {};
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;

View file

@ -377,8 +377,7 @@ bool SwapChain::CreateSwapChain()
// Try without exclusive fullscreen. // Try without exclusive fullscreen.
WARN_LOG_FMT(VIDEO, "Failed to create exclusive fullscreen swapchain, trying without."); WARN_LOG_FMT(VIDEO, "Failed to create exclusive fullscreen swapchain, trying without.");
swap_chain_info.pNext = nullptr; swap_chain_info.pNext = nullptr;
g_Config.backend_info.bSupportsExclusiveFullscreen = false; g_backend_info.bSupportsExclusiveFullscreen = false;
g_ActiveConfig.backend_info.bSupportsExclusiveFullscreen = false;
m_fullscreen_supported = false; m_fullscreen_supported = false;
} }
} }
@ -601,8 +600,7 @@ bool SwapChain::RecreateSurface(void* native_handle)
// Update exclusive fullscreen support (unlikely to change). // Update exclusive fullscreen support (unlikely to change).
m_fullscreen_supported = g_vulkan_context->SupportsExclusiveFullscreen(m_wsi, m_surface); m_fullscreen_supported = g_vulkan_context->SupportsExclusiveFullscreen(m_wsi, m_surface);
g_Config.backend_info.bSupportsExclusiveFullscreen = m_fullscreen_supported; g_backend_info.bSupportsExclusiveFullscreen = m_fullscreen_supported;
g_ActiveConfig.backend_info.bSupportsExclusiveFullscreen = m_fullscreen_supported;
m_current_fullscreen_state = false; m_current_fullscreen_state = false;
m_next_fullscreen_state = false; m_next_fullscreen_state = false;

View file

@ -32,7 +32,7 @@ VKTexture::VKTexture(const TextureConfig& tex_config, VmaAllocation alloc, VkIma
: AbstractTexture(tex_config), m_alloc(alloc), m_image(image), m_layout(layout), : AbstractTexture(tex_config), m_alloc(alloc), m_image(image), m_layout(layout),
m_compute_layout(compute_layout), m_name(name) m_compute_layout(compute_layout), m_name(name)
{ {
if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames) if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
{ {
VkDebugUtilsObjectNameInfoEXT name_info = {}; VkDebugUtilsObjectNameInfoEXT name_info = {};
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;

View file

@ -8,11 +8,8 @@
#include <cstring> #include <cstring>
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/CommonFuncs.h"
#include "Common/Contains.h" #include "Common/Contains.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
#include "VideoCommon/DriverDetails.h" #include "VideoCommon/DriverDetails.h"
#include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoCommon.h"
@ -387,7 +384,7 @@ bool VulkanContext::SelectInstanceExtensions(std::vector<const char*>* extension
// VK_EXT_debug_utils // VK_EXT_debug_utils
if (AddExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, false)) if (AddExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, false))
{ {
g_Config.backend_info.bSupportsSettingObjectNames = true; g_backend_info.bSupportsSettingObjectNames = true;
} }
else if (enable_debug_utils) else if (enable_debug_utils)
{ {
@ -420,96 +417,96 @@ VulkanContext::GPUList VulkanContext::EnumerateGPUs(VkInstance instance)
return gpus; return gpus;
} }
void VulkanContext::PopulateBackendInfo(VideoConfig* config) void VulkanContext::PopulateBackendInfo(BackendInfo* backend_info)
{ {
config->backend_info.api_type = APIType::Vulkan; backend_info->api_type = APIType::Vulkan;
config->backend_info.bSupports3DVision = false; // D3D-exclusive. backend_info->bSupports3DVision = false; // D3D-exclusive.
config->backend_info.bSupportsEarlyZ = true; // Assumed support. backend_info->bSupportsEarlyZ = true; // Assumed support.
config->backend_info.bSupportsPrimitiveRestart = true; // Assumed support. backend_info->bSupportsPrimitiveRestart = true; // Assumed support.
config->backend_info.bSupportsBindingLayout = false; // Assumed support. backend_info->bSupportsBindingLayout = false; // Assumed support.
config->backend_info.bSupportsPaletteConversion = true; // Assumed support. backend_info->bSupportsPaletteConversion = true; // Assumed support.
config->backend_info.bSupportsClipControl = true; // Assumed support. backend_info->bSupportsClipControl = true; // Assumed support.
config->backend_info.bSupportsMultithreading = true; // Assumed support. backend_info->bSupportsMultithreading = true; // Assumed support.
config->backend_info.bSupportsComputeShaders = true; // Assumed support. backend_info->bSupportsComputeShaders = true; // Assumed support.
config->backend_info.bSupportsGPUTextureDecoding = true; // Assumed support. backend_info->bSupportsGPUTextureDecoding = true; // Assumed support.
config->backend_info.bSupportsBitfield = true; // Assumed support. backend_info->bSupportsBitfield = true; // Assumed support.
config->backend_info.bSupportsPartialDepthCopies = true; // Assumed support. backend_info->bSupportsPartialDepthCopies = true; // Assumed support.
config->backend_info.bSupportsShaderBinaries = true; // Assumed support. backend_info->bSupportsShaderBinaries = true; // Assumed support.
config->backend_info.bSupportsPipelineCacheData = false; // Handled via pipeline caches. backend_info->bSupportsPipelineCacheData = false; // Handled via pipeline caches.
config->backend_info.bSupportsDynamicSamplerIndexing = true; // Assumed support. backend_info->bSupportsDynamicSamplerIndexing = true; // Assumed support.
config->backend_info.bSupportsPostProcessing = true; // Assumed support. backend_info->bSupportsPostProcessing = true; // Assumed support.
config->backend_info.bSupportsBackgroundCompiling = true; // Assumed support. backend_info->bSupportsBackgroundCompiling = true; // Assumed support.
config->backend_info.bSupportsCopyToVram = true; // Assumed support. backend_info->bSupportsCopyToVram = true; // Assumed support.
config->backend_info.bSupportsReversedDepthRange = true; // Assumed support. backend_info->bSupportsReversedDepthRange = true; // Assumed support.
config->backend_info.bSupportsExclusiveFullscreen = false; // Dependent on OS and features. backend_info->bSupportsExclusiveFullscreen = false; // Dependent on OS and features.
config->backend_info.bSupportsDualSourceBlend = false; // Dependent on features. backend_info->bSupportsDualSourceBlend = false; // Dependent on features.
config->backend_info.bSupportsGeometryShaders = false; // Dependent on features. backend_info->bSupportsGeometryShaders = false; // Dependent on features.
config->backend_info.bSupportsGSInstancing = false; // Dependent on features. backend_info->bSupportsGSInstancing = false; // Dependent on features.
config->backend_info.bSupportsBBox = false; // Dependent on features. backend_info->bSupportsBBox = false; // Dependent on features.
config->backend_info.bSupportsFragmentStoresAndAtomics = false; // Dependent on features. backend_info->bSupportsFragmentStoresAndAtomics = false; // Dependent on features.
config->backend_info.bSupportsSSAA = false; // Dependent on features. backend_info->bSupportsSSAA = false; // Dependent on features.
config->backend_info.bSupportsDepthClamp = false; // Dependent on features. backend_info->bSupportsDepthClamp = false; // Dependent on features.
config->backend_info.bSupportsST3CTextures = false; // Dependent on features. backend_info->bSupportsST3CTextures = false; // Dependent on features.
config->backend_info.bSupportsBPTCTextures = false; // Dependent on features. backend_info->bSupportsBPTCTextures = false; // Dependent on features.
config->backend_info.bSupportsLogicOp = false; // Dependent on features. backend_info->bSupportsLogicOp = false; // Dependent on features.
config->backend_info.bSupportsLargePoints = false; // Dependent on features. backend_info->bSupportsLargePoints = false; // Dependent on features.
config->backend_info.bSupportsFramebufferFetch = false; // Dependent on OS and features. backend_info->bSupportsFramebufferFetch = false; // Dependent on OS and features.
config->backend_info.bSupportsCoarseDerivatives = true; // Assumed support. backend_info->bSupportsCoarseDerivatives = true; // Assumed support.
config->backend_info.bSupportsTextureQueryLevels = true; // Assumed support. backend_info->bSupportsTextureQueryLevels = true; // Assumed support.
config->backend_info.bSupportsLodBiasInSampler = false; // Dependent on OS. backend_info->bSupportsLodBiasInSampler = false; // Dependent on OS.
config->backend_info.bSupportsSettingObjectNames = false; // Dependent on features. backend_info->bSupportsSettingObjectNames = false; // Dependent on features.
config->backend_info.bSupportsPartialMultisampleResolve = true; // Assumed support. backend_info->bSupportsPartialMultisampleResolve = true; // Assumed support.
config->backend_info.bSupportsDynamicVertexLoader = true; // Assumed support. backend_info->bSupportsDynamicVertexLoader = true; // Assumed support.
config->backend_info.bSupportsVSLinePointExpand = true; // Assumed support. backend_info->bSupportsVSLinePointExpand = true; // Assumed support.
config->backend_info.bSupportsHDROutput = true; // Assumed support. backend_info->bSupportsHDROutput = true; // Assumed support.
} }
void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list) void VulkanContext::PopulateBackendInfoAdapters(BackendInfo* backend_info, const GPUList& gpu_list)
{ {
config->backend_info.Adapters.clear(); backend_info->Adapters.clear();
for (VkPhysicalDevice physical_device : gpu_list) for (VkPhysicalDevice physical_device : gpu_list)
{ {
VkPhysicalDeviceProperties properties; VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(physical_device, &properties); vkGetPhysicalDeviceProperties(physical_device, &properties);
config->backend_info.Adapters.push_back(properties.deviceName); backend_info->Adapters.push_back(properties.deviceName);
} }
} }
void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalDevice gpu, void VulkanContext::PopulateBackendInfoFeatures(BackendInfo* backend_info, VkPhysicalDevice gpu,
const PhysicalDeviceInfo& info) const PhysicalDeviceInfo& info)
{ {
config->backend_info.MaxTextureSize = info.maxImageDimension2D; backend_info->MaxTextureSize = info.maxImageDimension2D;
config->backend_info.bUsesLowerLeftOrigin = false; backend_info->bUsesLowerLeftOrigin = false;
config->backend_info.bSupportsDualSourceBlend = info.dualSrcBlend; backend_info->bSupportsDualSourceBlend = info.dualSrcBlend;
config->backend_info.bSupportsGeometryShaders = info.geometryShader; backend_info->bSupportsGeometryShaders = info.geometryShader;
config->backend_info.bSupportsGSInstancing = info.geometryShader; backend_info->bSupportsGSInstancing = info.geometryShader;
config->backend_info.bSupportsBBox = config->backend_info.bSupportsFragmentStoresAndAtomics = backend_info->bSupportsBBox = backend_info->bSupportsFragmentStoresAndAtomics =
info.fragmentStoresAndAtomics; info.fragmentStoresAndAtomics;
config->backend_info.bSupportsSSAA = info.sampleRateShading; backend_info->bSupportsSSAA = info.sampleRateShading;
config->backend_info.bSupportsLogicOp = info.logicOp; backend_info->bSupportsLogicOp = info.logicOp;
// Metal doesn't support this. // Metal doesn't support this.
config->backend_info.bSupportsLodBiasInSampler = info.driverID != VK_DRIVER_ID_MOLTENVK; backend_info->bSupportsLodBiasInSampler = info.driverID != VK_DRIVER_ID_MOLTENVK;
// Disable geometry shader when shaderTessellationAndGeometryPointSize is not supported. // Disable geometry shader when shaderTessellationAndGeometryPointSize is not supported.
// Seems this is needed for gl_Layer. // Seems this is needed for gl_Layer.
if (!info.shaderTessellationAndGeometryPointSize) if (!info.shaderTessellationAndGeometryPointSize)
{ {
config->backend_info.bSupportsGeometryShaders = VK_FALSE; backend_info->bSupportsGeometryShaders = VK_FALSE;
config->backend_info.bSupportsGSInstancing = VK_FALSE; backend_info->bSupportsGSInstancing = VK_FALSE;
} }
// Depth clamping implies shaderClipDistance and depthClamp // Depth clamping implies shaderClipDistance and depthClamp
config->backend_info.bSupportsDepthClamp = info.depthClamp && info.shaderClipDistance; backend_info->bSupportsDepthClamp = info.depthClamp && info.shaderClipDistance;
// textureCompressionBC implies BC1 through BC7, which is a superset of DXT1/3/5, which we need. // textureCompressionBC implies BC1 through BC7, which is a superset of DXT1/3/5, which we need.
config->backend_info.bSupportsST3CTextures = info.textureCompressionBC; backend_info->bSupportsST3CTextures = info.textureCompressionBC;
config->backend_info.bSupportsBPTCTextures = info.textureCompressionBC; backend_info->bSupportsBPTCTextures = info.textureCompressionBC;
// Some devices don't support point sizes >1 (e.g. Adreno). // Some devices don't support point sizes >1 (e.g. Adreno).
// If we can't use a point size above our maximum IR, use triangles instead for EFB pokes. // If we can't use a point size above our maximum IR, use triangles instead for EFB pokes.
// This means a 6x increase in the size of the vertices, though. // This means a 6x increase in the size of the vertices, though.
config->backend_info.bSupportsLargePoints = backend_info->bSupportsLargePoints =
info.largePoints && info.pointSizeRange[0] <= 1.0f && info.pointSizeRange[1] >= 16; info.largePoints && info.pointSizeRange[0] <= 1.0f && info.pointSizeRange[1] >= 16;
std::string device_name = info.deviceName; std::string device_name = info.deviceName;
@ -520,25 +517,26 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD
// We currently use a hacked MoltenVK to implement this, so don't attempt outside of MVK // We currently use a hacked MoltenVK to implement this, so don't attempt outside of MVK
if (is_moltenvk && (vendor_id == 0x106B || device_name.find("Apple") != std::string::npos)) if (is_moltenvk && (vendor_id == 0x106B || device_name.find("Apple") != std::string::npos))
{ {
config->backend_info.bSupportsFramebufferFetch = true; backend_info->bSupportsFramebufferFetch = true;
} }
// Our usage of primitive restart appears to be broken on AMD's binary drivers. // Our usage of primitive restart appears to be broken on AMD's binary drivers.
// Seems to be fine on GCN Gen 1-2, unconfirmed on GCN Gen 3, causes driver resets on GCN Gen 4. // Seems to be fine on GCN Gen 1-2, unconfirmed on GCN Gen 3, causes driver resets on GCN Gen 4.
if (DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART)) if (DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART))
config->backend_info.bSupportsPrimitiveRestart = false; backend_info->bSupportsPrimitiveRestart = false;
// Reversed depth range is broken on some drivers, or is broken when used in combination // Reversed depth range is broken on some drivers, or is broken when used in combination
// with depth clamping. Fall back to inverted depth range for these. // with depth clamping. Fall back to inverted depth range for these.
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_REVERSED_DEPTH_RANGE)) if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_REVERSED_DEPTH_RANGE))
config->backend_info.bSupportsReversedDepthRange = false; backend_info->bSupportsReversedDepthRange = false;
// Dynamic sampler indexing locks up Intel GPUs on MoltenVK/Metal // Dynamic sampler indexing locks up Intel GPUs on MoltenVK/Metal
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING)) if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING))
config->backend_info.bSupportsDynamicSamplerIndexing = false; backend_info->bSupportsDynamicSamplerIndexing = false;
} }
void VulkanContext::PopulateBackendInfoMultisampleModes(VideoConfig* config, VkPhysicalDevice gpu, void VulkanContext::PopulateBackendInfoMultisampleModes(BackendInfo* backend_info,
VkPhysicalDevice gpu,
const PhysicalDeviceInfo& info) const PhysicalDeviceInfo& info)
{ {
// Query image support for the EFB texture formats. // Query image support for the EFB texture formats.
@ -557,32 +555,32 @@ void VulkanContext::PopulateBackendInfoMultisampleModes(VideoConfig* config, VkP
efb_color_properties.sampleCounts & efb_depth_properties.sampleCounts; efb_color_properties.sampleCounts & efb_depth_properties.sampleCounts;
// No AA // No AA
config->backend_info.AAModes.clear(); backend_info->AAModes.clear();
config->backend_info.AAModes.emplace_back(1); backend_info->AAModes.emplace_back(1);
// 2xMSAA/SSAA // 2xMSAA/SSAA
if (supported_sample_counts & VK_SAMPLE_COUNT_2_BIT) if (supported_sample_counts & VK_SAMPLE_COUNT_2_BIT)
config->backend_info.AAModes.emplace_back(2); backend_info->AAModes.emplace_back(2);
// 4xMSAA/SSAA // 4xMSAA/SSAA
if (supported_sample_counts & VK_SAMPLE_COUNT_4_BIT) if (supported_sample_counts & VK_SAMPLE_COUNT_4_BIT)
config->backend_info.AAModes.emplace_back(4); backend_info->AAModes.emplace_back(4);
// 8xMSAA/SSAA // 8xMSAA/SSAA
if (supported_sample_counts & VK_SAMPLE_COUNT_8_BIT) if (supported_sample_counts & VK_SAMPLE_COUNT_8_BIT)
config->backend_info.AAModes.emplace_back(8); backend_info->AAModes.emplace_back(8);
// 16xMSAA/SSAA // 16xMSAA/SSAA
if (supported_sample_counts & VK_SAMPLE_COUNT_16_BIT) if (supported_sample_counts & VK_SAMPLE_COUNT_16_BIT)
config->backend_info.AAModes.emplace_back(16); backend_info->AAModes.emplace_back(16);
// 32xMSAA/SSAA // 32xMSAA/SSAA
if (supported_sample_counts & VK_SAMPLE_COUNT_32_BIT) if (supported_sample_counts & VK_SAMPLE_COUNT_32_BIT)
config->backend_info.AAModes.emplace_back(32); backend_info->AAModes.emplace_back(32);
// 64xMSAA/SSAA // 64xMSAA/SSAA
if (supported_sample_counts & VK_SAMPLE_COUNT_64_BIT) if (supported_sample_counts & VK_SAMPLE_COUNT_64_BIT)
config->backend_info.AAModes.emplace_back(64); backend_info->AAModes.emplace_back(64);
} }
std::unique_ptr<VulkanContext> VulkanContext::Create(VkInstance instance, VkPhysicalDevice gpu, std::unique_ptr<VulkanContext> VulkanContext::Create(VkInstance instance, VkPhysicalDevice gpu,

View file

@ -72,11 +72,11 @@ public:
// Populates backend/video config. // Populates backend/video config.
// These are public so that the backend info can be populated without creating a context. // These are public so that the backend info can be populated without creating a context.
static void PopulateBackendInfo(VideoConfig* config); static void PopulateBackendInfo(BackendInfo* backend_info);
static void PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list); static void PopulateBackendInfoAdapters(BackendInfo* backend_info, const GPUList& gpu_list);
static void PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalDevice gpu, static void PopulateBackendInfoFeatures(BackendInfo* backend_info, VkPhysicalDevice gpu,
const PhysicalDeviceInfo& info); const PhysicalDeviceInfo& info);
static void PopulateBackendInfoMultisampleModes(VideoConfig* config, VkPhysicalDevice gpu, static void PopulateBackendInfoMultisampleModes(BackendInfo* backend_info, VkPhysicalDevice gpu,
const PhysicalDeviceInfo& info); const PhysicalDeviceInfo& info);
// Creates a Vulkan device context. // Creates a Vulkan device context.

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 >> 0) & 0xFF) / 255.0f,
static_cast<float>((color >> 24) & 0xFF) / 255.0f}, static_cast<float>((color >> 24) & 0xFF) / 255.0f},
static_cast<float>(z & 0xFFFFFF) / 16777216.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; uniforms.clear_depth = 1.0f - uniforms.clear_depth;
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
@ -149,7 +149,7 @@ AbstractGfx::ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect, u
u32 fb_height) const u32 fb_height) const
{ {
MathUtil::Rectangle<int> ret = rect; MathUtil::Rectangle<int> ret = rect;
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin) if (g_backend_info.bUsesLowerLeftOrigin)
{ {
ret.top = fb_height - rect.bottom; ret.top = fb_height - rect.bottom;
ret.bottom = fb_height - rect.top; 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, // 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) // instead drawing twice and the eye selected by glDrawBuffer() (see Presenter::RenderXFBToScreen)
return g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer && 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->format = AbstractTextureFormat::BPTC;
info->block_size = 4; info->block_size = 4;
info->bytes_per_block = 16; info->bytes_per_block = 16;
if (!g_ActiveConfig.backend_info.bSupportsBPTCTextures) if (!g_backend_info.bSupportsBPTCTextures)
return false; return false;
} }
else 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, // We also need to ensure the backend supports these formats natively before loading them,
// otherwise, fallback to SOIL, which will decompress them to RGBA. // 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; return false;
// Mip levels smaller than the block size are padded to multiples of the block size. // 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 // floating-point round-trip errors. However the console GPU doesn't ever write a value
// to the depth buffer that exceeds 2^24 - 1. // to the depth buffer that exceeds 2^24 - 1.
constexpr float GX_MAX_DEPTH = 16777215.0f / 16777216.0f; 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 // 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. // 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. // 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. // 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; min_depth = GX_MAX_DEPTH;
max_depth = 0.0f; max_depth = 0.0f;
@ -246,7 +246,7 @@ void SetScissorAndViewport()
} }
float near_depth, far_depth; float near_depth, far_depth;
if (g_ActiveConfig.backend_info.bSupportsReversedDepthRange) if (g_backend_info.bSupportsReversedDepthRange)
{ {
// Set the reversed depth range. // Set the reversed depth range.
near_depth = max_depth; near_depth = max_depth;
@ -262,7 +262,7 @@ void SetScissorAndViewport()
} }
// Lower-left flip. // Lower-left flip.
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin) if (g_backend_info.bUsesLowerLeftOrigin)
y = static_cast<float>(g_gfx->GetCurrentFramebuffer()->GetHeight()) - y - height; y = static_cast<float>(g_gfx->GetCurrentFramebuffer()->GetHeight()) - y - height;
g_gfx->SetViewport(x, y, width, height, near_depth, far_depth); 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() void BoundingBox::Flush()
{ {
if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) if (!g_ActiveConfig.bBBoxEnable || !g_backend_info.bSupportsBBox)
return; return;
m_is_valid = false; m_is_valid = false;
@ -57,7 +57,7 @@ void BoundingBox::Flush()
void BoundingBox::Readback() void BoundingBox::Readback()
{ {
if (!g_ActiveConfig.backend_info.bSupportsBBox) if (!g_backend_info.bSupportsBBox)
return; return;
auto read_values = Read(0, NUM_BBOX_VALUES); auto read_values = Read(0, NUM_BBOX_VALUES);
@ -76,7 +76,7 @@ u16 BoundingBox::Get(u32 index)
{ {
ASSERT(index < NUM_BBOX_VALUES); 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]; return m_bounding_box_fallback[index];
if (!m_is_valid) if (!m_is_valid)
@ -89,7 +89,7 @@ void BoundingBox::Set(u32 index, u16 value)
{ {
ASSERT(index < NUM_BBOX_VALUES); 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; m_bounding_box_fallback[index] = value;
return; return;
@ -120,12 +120,12 @@ void BoundingBox::DoState(PointerWrap& p)
{ {
p.Do(backend_values); p.Do(backend_values);
if (g_ActiveConfig.backend_info.bSupportsBBox) if (g_backend_info.bSupportsBBox)
Write(0, backend_values); Write(0, backend_values);
} }
else else
{ {
if (g_ActiveConfig.backend_info.bSupportsBBox) if (g_backend_info.bSupportsBBox)
backend_values = Read(0, NUM_BBOX_VALUES); backend_values = Read(0, NUM_BBOX_VALUES);
p.Do(backend_values); p.Do(backend_values);

View file

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

View file

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

View file

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

View file

@ -8,7 +8,7 @@
CustomShaderCache::CustomShaderCache() 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_host_config.bits = ShaderHostConfig::GetCurrent().bits;
m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler(); m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler();

View file

@ -266,7 +266,7 @@ void IndexGenerator::Init()
{ {
using OpcodeDecoder::Primitive; 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] = AddQuads<true>;
m_primitive_table[Primitive::GX_DRAW_QUADS_2] = AddQuads_nonstandard<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.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_LINES] = AddLines_VSExpand<true, false>;
m_primitive_table[Primitive::GX_DRAW_LINE_STRIP] = AddLines_VSExpand<true, true>; 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 size_t = size.y;
int num_layers = size.z; 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"); 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 // The software renderer uses the equivalent of coarse derivatives, so use them here for
// consistency. This hasn't been hardware tested. // 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) if (per_pixel_depth)
{ {
out.Write("\t\tdepth = {};\n", out.Write("\t\tdepth = {};\n", !g_backend_info.bSupportsReversedDepthRange ? "0.0" : "1.0");
!g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? "0.0" : "1.0");
} }
// ZCOMPLOC HACK: // 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(0) uniform sampler2DArray samp0;\n";
ss << "SAMPLER_BINDING(1) uniform sampler2DArray samp1;\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 << "VARYING_LOCATION(0) in VertexData {\n";
ss << " float3 v_tex0;\n"; ss << " float3 v_tex0;\n";
@ -770,7 +770,7 @@ std::string PostProcessing::GetFooter() const
static std::string GetVertexShaderBody() static std::string GetVertexShaderBody()
{ {
std::ostringstream ss; std::ostringstream ss;
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) if (g_backend_info.bSupportsGeometryShaders)
{ {
ss << "VARYING_LOCATION(0) out VertexData {\n"; ss << "VARYING_LOCATION(0) out VertexData {\n";
ss << " float3 v_tex0;\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"; 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 // 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"; ss << " opos.y = -opos.y;\n";
} }
// OpenGL Y needs to be inverted in all passes except the last one // 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 << " if (intermediary_buffer != 0)\n";
ss << " opos.y = -opos.y;\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}; static_cast<float>(src.GetHeight()) * rcp_src_height};
builtin_uniforms.src_layer = static_cast<s32>(src_layer); builtin_uniforms.src_layer = static_cast<s32>(src_layer);
builtin_uniforms.time = static_cast<u32>(m_timer.ElapsedMs()); 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.intermediary_buffer = static_cast<s32>(intermediary_buffer);
builtin_uniforms.resampling_method = static_cast<s32>(g_ActiveConfig.output_resampling_mode); 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) switch (g_ActiveConfig.stereo_mode)
{ {
case StereoMode::QuadBuffer: case StereoMode::QuadBuffer:
return !g_ActiveConfig.backend_info.bUsesExplictQuadBuffering; return !g_backend_info.bUsesExplictQuadBuffering;
case StereoMode::Anaglyph: case StereoMode::Anaglyph:
case StereoMode::Passive: case StereoMode::Passive:
return is_intermediary_buffer; 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) const MathUtil::Rectangle<int>& source_rc)
{ {
if (g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer && if (g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer &&
g_ActiveConfig.backend_info.bUsesExplictQuadBuffering) g_backend_info.bUsesExplictQuadBuffering)
{ {
// Quad-buffered stereo is annoying on GL. // Quad-buffered stereo is annoying on GL.
g_gfx->SelectLeftBuffer(); 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 // Depth buffer is inverted for improved precision near far plane
float depth = g_framebuffer_manager->PeekEFBDepth(x, y); float depth = g_framebuffer_manager->PeekEFBDepth(x, y);
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange) if (!g_backend_info.bSupportsReversedDepthRange)
depth = 1.0f - depth; depth = 1.0f - depth;
// Convert to 24bit 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. // Convert to floating-point depth.
const EfbPokeData& point = points[i]; const EfbPokeData& point = points[i];
float depth = float(point.data & 0xFFFFFF) / 16777216.0f; float depth = float(point.data & 0xFFFFFF) / 16777216.0f;
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange) if (!g_backend_info.bSupportsReversedDepthRange)
depth = 1.0f - depth; depth = 1.0f - depth;
g_framebuffer_manager->PokeEFBDepth(point.x, point.y, depth); g_framebuffer_manager->PokeEFBDepth(point.x, point.y, depth);

View file

@ -39,7 +39,7 @@ ShaderCache::~ShaderCache()
bool ShaderCache::Initialize() 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; m_host_config.bits = ShaderHostConfig::GetCurrent().bits;
if (!CompileSharedPipelines()) if (!CompileSharedPipelines())
@ -352,7 +352,7 @@ void ShaderCache::ClearPipelineCache(T& cache, Y& disk_cache)
void ShaderCache::LoadCaches() void ShaderCache::LoadCaches()
{ {
// Ubershader caches, if present. // 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, LoadShaderCache<ShaderStage::Vertex, UberShader::VertexShaderUid>(m_uber_vs_cache, m_api_type,
"uber-vs", false); "uber-vs", false);
@ -371,7 +371,7 @@ void ShaderCache::LoadCaches()
true); true);
} }
if (g_ActiveConfig.backend_info.bSupportsPipelineCacheData) if (g_backend_info.bSupportsPipelineCacheData)
{ {
LoadPipelineCache<GXPipelineUid, SerializedGXPipelineUid>( LoadPipelineCache<GXPipelineUid, SerializedGXPipelineUid>(
m_gx_pipeline_cache, m_gx_pipeline_disk_cache, m_api_type, "specialized-pipeline", true); 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 (shader && !entry.shader)
{ {
if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries) if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
{ {
auto binary = shader->GetBinary(); auto binary = shader->GetBinary();
if (!binary.empty()) if (!binary.empty())
@ -492,7 +492,7 @@ const AbstractShader* ShaderCache::InsertVertexUberShader(const UberShader::Vert
if (shader && !entry.shader) 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(); auto binary = shader->GetBinary();
if (!binary.empty()) if (!binary.empty())
@ -514,7 +514,7 @@ const AbstractShader* ShaderCache::InsertPixelShader(const PixelShaderUid& uid,
if (shader && !entry.shader) 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(); auto binary = shader->GetBinary();
if (!binary.empty()) if (!binary.empty())
@ -536,7 +536,7 @@ const AbstractShader* ShaderCache::InsertPixelUberShader(const UberShader::Pixel
if (shader && !entry.shader) 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(); auto binary = shader->GetBinary();
if (!binary.empty()) if (!binary.empty())
@ -563,7 +563,7 @@ const AbstractShader* ShaderCache::CreateGeometryShader(const GeometryShaderUid&
if (shader && !entry.shader) 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(); auto binary = shader->GetBinary();
if (!binary.empty()) 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 // If framebuffer fetch is available, we can emulate logic ops in the fragment shader
// and don't need the below blend approximation // and don't need the below blend approximation
if (blend.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp && if (blend.logicopenable && !g_backend_info.bSupportsLogicOp &&
!g_ActiveConfig.backend_info.bSupportsFramebufferFetch) !g_backend_info.bSupportsFramebufferFetch)
{ {
if (!blend.LogicOpApproximationIsExact()) if (!blend.LogicOpApproximationIsExact())
WARN_LOG_FMT(VIDEO, WARN_LOG_FMT(VIDEO,
@ -638,8 +638,7 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
} }
const bool benefits_from_ps_dual_source_off = const bool benefits_from_ps_dual_source_off =
(!g_ActiveConfig.backend_info.bSupportsDualSourceBlend && (!g_backend_info.bSupportsDualSourceBlend && g_backend_info.bSupportsFramebufferFetch) ||
g_ActiveConfig.backend_info.bSupportsFramebufferFetch) ||
DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING); DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING);
if (benefits_from_ps_dual_source_off && !blend.RequiresDualSrc()) if (benefits_from_ps_dual_source_off && !blend.RequiresDualSrc())
{ {
@ -648,19 +647,19 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
blend.usedualsrc = false; blend.usedualsrc = false;
} }
if (g_ActiveConfig.backend_info.bSupportsFramebufferFetch) if (g_backend_info.bSupportsFramebufferFetch)
{ {
bool fbfetch_blend = false; bool fbfetch_blend = false;
if ((DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z) || 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::ForcedEarly)
{ {
ps->ztest = EmulatedZ::EarlyWithFBFetch; ps->ztest = EmulatedZ::EarlyWithFBFetch;
fbfetch_blend |= static_cast<bool>(out.blending_state.blendenable); fbfetch_blend |= static_cast<bool>(out.blending_state.blendenable);
ps->no_dual_src = true; ps->no_dual_src = true;
} }
fbfetch_blend |= blend.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp; fbfetch_blend |= blend.logicopenable && !g_backend_info.bSupportsLogicOp;
fbfetch_blend |= blend.usedualsrc && !g_ActiveConfig.backend_info.bSupportsDualSourceBlend; fbfetch_blend |= blend.usedualsrc && !g_backend_info.bSupportsDualSourceBlend;
if (fbfetch_blend) if (fbfetch_blend)
{ {
ps->no_dual_src = true; 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 // 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; ps->no_dual_src = true;
blend.usedualsrc = false; 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 // These things should be false
ASSERT(!ps->zfreeze); ASSERT(!ps->zfreeze);
@ -727,9 +726,8 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
vs->vs_expand = VSExpand::Point; vs->vs_expand = VSExpand::Point;
else else
vs->vs_expand = VSExpand::Line; vs->vs_expand = VSExpand::Line;
PrimitiveType prim = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? PrimitiveType prim = g_backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
PrimitiveType::TriangleStrip : PrimitiveType::Triangles;
PrimitiveType::Triangles;
out.rasterization_state.primitive = prim; out.rasterization_state.primitive = prim;
out.gs_uid.GetUidData()->primitive_type = static_cast<u32>(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 // 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. // 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 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; out.vertex_format = nullptr;
// If framebuffer fetch is available, we can emulate logic ops in the fragment shader // If framebuffer fetch is available, we can emulate logic ops in the fragment shader
// and don't need the below blend approximation // and don't need the below blend approximation
if (out.blending_state.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp && if (out.blending_state.logicopenable && !g_backend_info.bSupportsLogicOp &&
!g_ActiveConfig.backend_info.bSupportsFramebufferFetch) !g_backend_info.bSupportsFramebufferFetch)
{ {
if (!out.blending_state.LogicOpApproximationIsExact()) if (!out.blending_state.LogicOpApproximationIsExact())
WARN_LOG_FMT(VIDEO, WARN_LOG_FMT(VIDEO,
@ -799,7 +797,7 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
out.blending_state.ApproximateLogicOpWithBlending(); out.blending_state.ApproximateLogicOpWithBlending();
} }
if (g_ActiveConfig.backend_info.bSupportsFramebufferFetch) if (g_backend_info.bSupportsFramebufferFetch)
{ {
// Always blend in shader // Always blend in shader
out.blending_state.hex = 0; 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.blending_state.alphaupdate = in.blending_state.alphaupdate.Value();
out.ps_uid.GetUidData()->no_dual_src = true; 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) && (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) &&
!out.blending_state.RequiresDualSrc())) !out.blending_state.RequiresDualSrc()))
{ {
@ -818,9 +816,8 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
if (g_ActiveConfig.UseVSForLinePointExpand()) if (g_ActiveConfig.UseVSForLinePointExpand())
{ {
// All primitives are expanded to triangles in the vertex shader // All primitives are expanded to triangles in the vertex shader
PrimitiveType prim = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? PrimitiveType prim = g_backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
PrimitiveType::TriangleStrip : PrimitiveType::Triangles;
PrimitiveType::Triangles;
out.rasterization_state.primitive = prim; out.rasterization_state.primitive = prim;
out.gs_uid.GetUidData()->primitive_type = static_cast<u32>(prim); out.gs_uid.GetUidData()->primitive_type = static_cast<u32>(prim);
} }
@ -1345,7 +1342,7 @@ void ShaderCache::QueueUberShaderPipelines()
} }
BlendingState blend = RenderState::GetNoBlendingBlendState(); BlendingState blend = RenderState::GetNoBlendingBlendState();
QueueDummyPipeline(vuid, guid, cleared_puid, blend); 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 // 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. // compiled shaders based on some subset of the pipeline state.

View file

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

View file

@ -73,7 +73,7 @@ void Statistics::Display() const
ImGui::NextColumn(); 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("Objects", "%d", this_frame.num_drawn_objects);
draw_statistic("Vertices Loaded", "%d", this_frame.num_vertices_loaded); 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, RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const u8* palette,
TLUTFormat tlutfmt) TLUTFormat tlutfmt)
{ {
DEBUG_ASSERT(g_ActiveConfig.backend_info.bSupportsPaletteConversion); DEBUG_ASSERT(g_backend_info.bSupportsPaletteConversion);
const AbstractPipeline* pipeline = g_shader_cache->GetPaletteConversionPipeline(tlutfmt); const AbstractPipeline* pipeline = g_shader_cache->GetPaletteConversionPipeline(tlutfmt);
if (!pipeline) if (!pipeline)
@ -404,7 +404,7 @@ void TextureCacheBase::ScaleTextureCacheEntryTo(RcTcacheEntry& entry, u32 new_wi
return; return;
} }
const u32 max = g_ActiveConfig.backend_info.MaxTextureSize; const u32 max = g_backend_info.MaxTextureSize;
if (max < new_width || max < new_height) if (max < new_width || max < new_height)
{ {
ERROR_LOG_FMT(VIDEO, "Texture too big, width = {}, height = {}", new_width, 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 // EFB copies have slightly different rules as EFB copy formats have different
// meanings from texture formats. // meanings from texture formats.
if ((base_hash == entry->hash && if ((base_hash == entry->hash &&
(!texture_info.GetPaletteSize() || g_Config.backend_info.bSupportsPaletteConversion)) || (!texture_info.GetPaletteSize() || g_backend_info.bSupportsPaletteConversion)) ||
IsPlayingBackFifologWithBrokenEFBCopies) IsPlayingBackFifologWithBrokenEFBCopies)
{ {
// The texture format in VRAM must match the format that the copy was created with. Some // 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 // TODO: We should check width/height/levels for EFB copies. I'm not sure what effect
// checking width/height/levels would have. // 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; return entry;
// Note that we found an unconverted EFB copy, then continue. We'll // 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 // Disadvantage of all methods: Calling this function requires the GPU to perform a pipeline flush
// which stalls any further CPU processing. // which stalls any further CPU processing.
const bool is_xfb_copy = !is_depth_copy && !isIntensity && dstFormat == EFBCopyFormat::XFB; const bool is_xfb_copy = !is_depth_copy && !isIntensity && dstFormat == EFBCopyFormat::XFB;
bool copy_to_vram = bool copy_to_vram = g_backend_info.bSupportsCopyToVram && !g_ActiveConfig.bDisableCopyToVRAM;
g_ActiveConfig.backend_info.bSupportsCopyToVram && !g_ActiveConfig.bDisableCopyToVRAM;
bool copy_to_ram = bool copy_to_ram =
!(is_xfb_copy ? g_ActiveConfig.bSkipXFBCopyToRam : g_ActiveConfig.bSkipEFBCopyToRam) || !(is_xfb_copy ? g_ActiveConfig.bSkipXFBCopyToRam : g_ActiveConfig.bSkipEFBCopyToRam) ||
!copy_to_vram; !copy_to_vram;
@ -2851,7 +2850,7 @@ bool TextureCacheBase::CreateUtilityTextures()
if (!m_efb_encoding_framebuffer) if (!m_efb_encoding_framebuffer)
return false; return false;
if (g_ActiveConfig.backend_info.bSupportsGPUTextureDecoding) if (g_backend_info.bSupportsGPUTextureDecoding)
{ {
constexpr TextureConfig decoding_texture_config( constexpr TextureConfig decoding_texture_config(
1024, 1024, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage, 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" " float2 clamp_tb;\n"
" uint3 filter_coefficients;\n" " uint3 filter_coefficients;\n"
"}};\n"); "}};\n");
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) if (g_backend_info.bSupportsGeometryShaders)
{ {
code.Write("VARYING_LOCATION(0) in VertexData {{\n" code.Write("VARYING_LOCATION(0) in VertexData {{\n"
" float3 v_tex0;\n" " float3 v_tex0;\n"
@ -124,7 +124,7 @@ static void WriteSampleFunction(ShaderCode& code, const EFBCopyParams& params, A
if (params.depth) 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(" tex_sample.x = 1.0 - tex_sample.x;\n");
code.Write(" uint depth = uint(tex_sample.x * 16777216.0);\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 << " int texel_buffer_offset;\n";
ss << "};\n"; ss << "};\n";
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) if (g_backend_info.bSupportsGeometryShaders)
{ {
ss << "VARYING_LOCATION(0) in VertexData {\n"; ss << "VARYING_LOCATION(0) in VertexData {\n";
ss << " float3 v_tex0;\n"; ss << " float3 v_tex0;\n";

View file

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

View file

@ -156,7 +156,7 @@ DataReader VertexManagerBase::PrepareForAdditionalData(OpcodeDecoder::Primitive
u32 const needed_vertex_bytes = count * stride + 4; u32 const needed_vertex_bytes = count * stride + 4;
// We can't merge different kinds of primitives, so we have to flush here // 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_pr[primitive] :
primitive_from_gx[primitive]; primitive_from_gx[primitive];
if (m_current_primitive_type != new_primitive_type) [[unlikely]] 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.UseVSForLinePointExpand())
{ {
if (g_Config.backend_info.bSupportsPrimitiveRestart) if (g_backend_info.bSupportsPrimitiveRestart)
{ {
switch (primitive) 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) 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) 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 bounding box is enabled, we need to flush any changes first, then invalidate what we have.
if (g_bounding_box->IsEnabled() && g_ActiveConfig.bBBoxEnable && if (g_bounding_box->IsEnabled() && g_ActiveConfig.bBBoxEnable && g_backend_info.bSupportsBBox)
g_ActiveConfig.backend_info.bSupportsBBox)
{ {
g_bounding_box->Flush(); g_bounding_box->Flush();
} }
@ -1090,8 +1089,7 @@ void VertexManagerBase::RenderDrawCall(
VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(), VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(),
m_index_generator.GetIndexLen(), &base_vertex, &base_index); m_index_generator.GetIndexLen(), &base_vertex, &base_index);
if (g_ActiveConfig.backend_info.api_type != APIType::D3D && if (g_backend_info.api_type != APIType::D3D && g_ActiveConfig.UseVSForLinePointExpand() &&
g_ActiveConfig.UseVSForLinePointExpand() &&
(primitive_type == PrimitiveType::Points || primitive_type == PrimitiveType::Lines)) (primitive_type == PrimitiveType::Points || primitive_type == PrimitiveType::Lines))
{ {
// VS point/line expansion puts the vertex id at gl_VertexID << 2 // 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 // D3D has issues compiling large custom ubershaders
// use specialized shaders instead // 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( if (auto pipeline = m_custom_shader_cache->GetPipelineAsync(
current_pipeline_config, custom_shaders, current_pipeline->m_config)) 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() bool VertexShaderManager::UseVertexDepthRange()
{ {
// We can't compute the depth range in the vertex shader if we don't support depth clamp. // 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; return false;
// We need a full depth range if a ztexture is used. // We need a full depth range if a ztexture is used.
@ -148,7 +148,7 @@ bool VertexShaderManager::UseVertexDepthRange()
return true; return true;
// If an inverted depth range is unsupported, we also need to check if the range is inverted. // 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) if (xfmem.viewport.zRange < 0.0f)
return true; 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 // Oversized depth ranges are handled in the vertex shader. We need to reverse
// the far value to use the reversed-Z trick. // 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 // 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. // 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; warn_once = false;
} }
else if (!g_ActiveConfig.backend_info.bSupportsBBox) else if (!g_backend_info.bSupportsBBox)
{ {
static bool warn_once = true; static bool warn_once = true;
if (warn_once) if (warn_once)
@ -298,9 +298,9 @@ void VideoBackendBase::PopulateBackendInfo(const WindowSystemInfo& wsi)
g_Config.Refresh(); g_Config.Refresh();
// Reset backend_info so if the backend forgets to initialize something it doesn't end up using // Reset backend_info so if the backend forgets to initialize something it doesn't end up using
// a value from the previously used renderer // a value from the previously used renderer
g_Config.backend_info = {}; g_backend_info = {};
ActivateBackend(Config::Get(Config::MAIN_GFX_BACKEND)); 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); g_video_backend->InitBackendInfo(wsi);
// We validate the config after initializing the backend info, as system-specific settings // 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. // 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() || if (!g_vertex_manager->Initialize() || !g_shader_cache->Initialize() ||
!g_perf_query->Initialize() || !g_presenter->Initialize() || !g_perf_query->Initialize() || !g_presenter->Initialize() ||
!g_framebuffer_manager->Initialize() || !g_texture_cache->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()) !g_graphics_mod_manager->Initialize())
{ {
PanicAlertFmtT("Failed to initialize renderer classes"); PanicAlertFmtT("Failed to initialize renderer classes");

View file

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

View file

@ -113,6 +113,67 @@ enum ConfigChangeBits : u32
CONFIG_CHANGE_BIT_HDR = (1 << 10), 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. // NEVER inherit from this class.
struct VideoConfig final struct VideoConfig final
{ {
@ -289,84 +350,23 @@ struct VideoConfig final
// Vertex loader // Vertex loader
VertexLoaderType vertex_loader_type; 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 // Utility
bool UseVSForLinePointExpand() const bool UseVSForLinePointExpand() const
{ {
if (!backend_info.bSupportsVSLinePointExpand) if (!g_backend_info.bSupportsVSLinePointExpand)
return false; return false;
if (!backend_info.bSupportsGeometryShaders) if (!g_backend_info.bSupportsGeometryShaders)
return true; return true;
return bPreferVSForLinePointExpansion; return bPreferVSForLinePointExpansion;
} }
bool MultisamplingEnabled() const { return iMultisamples > 1; } bool MultisamplingEnabled() const { return iMultisamples > 1; }
bool ExclusiveFullscreenEnabled() const bool ExclusiveFullscreenEnabled() const
{ {
return backend_info.bSupportsExclusiveFullscreen && !bBorderlessFullscreen; return g_backend_info.bSupportsExclusiveFullscreen && !bBorderlessFullscreen;
} }
bool UseGPUTextureDecoding() const bool UseGPUTextureDecoding() const
{ {
return backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding; return g_backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding;
} }
bool UseVertexRounding() const { return bVertexRounding && iEFBScale != 1; } bool UseVertexRounding() const { return bVertexRounding && iEFBScale != 1; }
bool ManualTextureSamplingWithCustomTextureSizes() const bool ManualTextureSamplingWithCustomTextureSizes() const