mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-04-29 14:59:26 -04:00
Merge pull request #21 from SamoZ256/metal-mesh-shaders-check
Check for mesh shaders support
This commit is contained in:
commit
1367e11d26
14 changed files with 71 additions and 37 deletions
|
@ -258,6 +258,7 @@ void InfoLog_PrintActiveSettings()
|
|||
else if (ActiveSettings::GetGraphicsAPI() == GraphicAPI::kMetal)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Async compile: {}", GetConfig().async_compile.GetValue() ? "true" : "false");
|
||||
cemuLog_log(LogType::Force, "Force mesh shaders: {}", GetConfig().force_mesh_shaders.GetValue() ? "true" : "false");
|
||||
cemuLog_log(LogType::Force, "Fast math: {}", g_current_game_profile->GetFastMath() ? "true" : "false");
|
||||
cemuLog_log(LogType::Force, "Buffer cache type: {}", g_current_game_profile->GetBufferCacheMode());
|
||||
cemuLog_log(LogType::Force, "Position invariance: {}", g_current_game_profile->GetPositionInvariance());
|
||||
|
|
|
@ -510,7 +510,7 @@ void LatteSHRC_UpdateVSBaseHash(uint8* vertexShaderPtr, uint32 vertexShaderSize,
|
|||
vsHash += tmp;
|
||||
|
||||
auto primitiveType = LatteGPUState.contextNew.VGT_PRIMITIVE_TYPE.get_PRIMITIVE_MODE();
|
||||
// TODO: include always in the hash in case of geometry shader or rect shader
|
||||
// TODO: include always in the hash in case of geometry shader or rect shader on Metal
|
||||
if (primitiveType == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS)
|
||||
{
|
||||
vsHash += 13ULL;
|
||||
|
@ -528,7 +528,9 @@ void LatteSHRC_UpdateVSBaseHash(uint8* vertexShaderPtr, uint32 vertexShaderSize,
|
|||
#if ENABLE_METAL
|
||||
if (g_renderer->GetType() == RendererAPI::Metal)
|
||||
{
|
||||
if (usesGeometryShader || _activeFetchShader->mtlFetchVertexManually)
|
||||
bool isRectVertexShader = (primitiveType == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS);
|
||||
|
||||
if ((usesGeometryShader || isRectVertexShader) || _activeFetchShader->mtlFetchVertexManually)
|
||||
{
|
||||
for (sint32 g = 0; g < _activeFetchShader->bufferGroups.size(); g++)
|
||||
{
|
||||
|
@ -542,7 +544,7 @@ void LatteSHRC_UpdateVSBaseHash(uint8* vertexShaderPtr, uint32 vertexShaderSize,
|
|||
}
|
||||
}
|
||||
|
||||
if (!usesGeometryShader)
|
||||
if (!(usesGeometryShader || isRectVertexShader))
|
||||
{
|
||||
if (LatteGPUState.contextNew.IsRasterizationEnabled())
|
||||
vsHash += 51ULL;
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
#include "Common/MemPtr.h"
|
||||
#include "HW/Latte/ISA/LatteReg.h"
|
||||
#if ENABLE_METAL
|
||||
#include "HW/Latte/Renderer/Metal/MetalCommon.h"
|
||||
#endif
|
||||
|
||||
// Defined in LatteTextureLegacy.cpp
|
||||
Latte::E_GX2SURFFMT LatteTexture_ReconstructGX2Format(const Latte::LATTE_SQ_TEX_RESOURCE_WORD1_N& texUnitWord1, const Latte::LATTE_SQ_TEX_RESOURCE_WORD4_N& texUnitWord4);
|
||||
|
@ -557,9 +560,9 @@ namespace LatteDecompiler
|
|||
}
|
||||
if (g_renderer->GetType() == RendererAPI::Metal)
|
||||
{
|
||||
bool isRectVertexShader = (static_cast<LattePrimitiveMode>(decompilerContext->contextRegisters[mmVGT_PRIMITIVE_TYPE]) == LattePrimitiveMode::RECTS);
|
||||
bool usesGeometryShader = UseGeometryShader(*decompilerContext->contextRegistersNew, decompilerContext->options->usesGeometryShader);
|
||||
|
||||
if (decompilerContext->shaderType == LatteConst::ShaderType::Vertex && (decompilerContext->options->usesGeometryShader || isRectVertexShader))
|
||||
if (decompilerContext->shaderType == LatteConst::ShaderType::Vertex && usesGeometryShader)
|
||||
decompilerContext->hasUniformVarBlock = true; // uf_verticesPerInstance
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3933,8 +3933,8 @@ static void LatteDecompiler_emitAttributeImport(LatteDecompilerShaderContext* sh
|
|||
|
||||
void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, LatteDecompilerShader* shader)
|
||||
{
|
||||
bool isRectVertexShader = (static_cast<LattePrimitiveMode>(shaderContext->contextRegisters[mmVGT_PRIMITIVE_TYPE]) == LattePrimitiveMode::RECTS);
|
||||
bool usesGeometryShader = (shaderContext->options->usesGeometryShader || isRectVertexShader);
|
||||
bool isRectVertexShader = UseRectEmulation(*shaderContext->contextRegistersNew);
|
||||
bool usesGeometryShader = UseGeometryShader(*shaderContext->contextRegistersNew, shaderContext->options->usesGeometryShader);
|
||||
bool fetchVertexManually = (usesGeometryShader || (shaderContext->fetchShader && shaderContext->fetchShader->mtlFetchVertexManually));
|
||||
|
||||
// Rasterization
|
||||
|
@ -3953,7 +3953,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||
src->add("#include <metal_stdlib>" _CRLF);
|
||||
src->add("using namespace metal;" _CRLF);
|
||||
// header part (definitions for inputs and outputs)
|
||||
LatteDecompiler::emitHeader(shaderContext, isRectVertexShader, fetchVertexManually, rasterizationEnabled);
|
||||
LatteDecompiler::emitHeader(shaderContext, isRectVertexShader, usesGeometryShader, fetchVertexManually, rasterizationEnabled);
|
||||
// helper functions
|
||||
LatteDecompiler_emitHelperFunctions(shaderContext, src);
|
||||
const char* functionType = "";
|
||||
|
@ -4131,7 +4131,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||
}
|
||||
// start of main
|
||||
src->addFmt("{} {} main0(", functionType, outputTypeName);
|
||||
LatteDecompiler::emitInputs(shaderContext, isRectVertexShader, fetchVertexManually);
|
||||
LatteDecompiler::emitInputs(shaderContext, isRectVertexShader, usesGeometryShader, fetchVertexManually);
|
||||
src->add(") {" _CRLF);
|
||||
if (fetchVertexManually && (shader->shaderType == LatteConst::ShaderType::Vertex || shader->shaderType == LatteConst::ShaderType::Geometry))
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace LatteDecompiler
|
||||
{
|
||||
static void _emitUniformVariables(LatteDecompilerShaderContext* decompilerContext, bool isRectVertexShader)
|
||||
static void _emitUniformVariables(LatteDecompilerShaderContext* decompilerContext, bool usesGeometryShader)
|
||||
{
|
||||
auto src = decompilerContext->shaderSource;
|
||||
|
||||
|
@ -87,7 +87,7 @@ namespace LatteDecompiler
|
|||
}
|
||||
// define verticesPerInstance + streamoutBufferBaseX
|
||||
if ((shader->shaderType == LatteConst::ShaderType::Vertex &&
|
||||
(decompilerContext->options->usesGeometryShader || isRectVertexShader)) ||
|
||||
usesGeometryShader) ||
|
||||
(decompilerContext->analyzer.useSSBOForStreamout &&
|
||||
(shader->shaderType == LatteConst::ShaderType::Vertex && !decompilerContext->options->usesGeometryShader) ||
|
||||
(shader->shaderType == LatteConst::ShaderType::Geometry)))
|
||||
|
@ -270,7 +270,7 @@ namespace LatteDecompiler
|
|||
src->add("};" _CRLF _CRLF);
|
||||
}
|
||||
|
||||
static void _emitInputsAndOutputs(LatteDecompilerShaderContext* decompilerContext, bool isRectVertexShader, bool fetchVertexManually, bool rasterizationEnabled)
|
||||
static void _emitInputsAndOutputs(LatteDecompilerShaderContext* decompilerContext, bool isRectVertexShader, bool usesGeometryShader, bool fetchVertexManually, bool rasterizationEnabled)
|
||||
{
|
||||
auto src = decompilerContext->shaderSource;
|
||||
|
||||
|
@ -304,7 +304,7 @@ namespace LatteDecompiler
|
|||
src->add("};" _CRLF _CRLF);
|
||||
}
|
||||
|
||||
if (!decompilerContext->options->usesGeometryShader)
|
||||
if (!usesGeometryShader || isRectVertexShader)
|
||||
{
|
||||
if (decompilerContext->shaderType == LatteConst::ShaderType::Vertex && rasterizationEnabled)
|
||||
_emitVSOutputs(decompilerContext, isRectVertexShader);
|
||||
|
@ -357,11 +357,11 @@ namespace LatteDecompiler
|
|||
}
|
||||
}
|
||||
|
||||
static void emitHeader(LatteDecompilerShaderContext* decompilerContext, bool isRectVertexShader, bool fetchVertexManually, bool rasterizationEnabled)
|
||||
static void emitHeader(LatteDecompilerShaderContext* decompilerContext, bool isRectVertexShader, bool usesGeometryShader, bool fetchVertexManually, bool rasterizationEnabled)
|
||||
{
|
||||
auto src = decompilerContext->shaderSource;
|
||||
|
||||
if ((decompilerContext->options->usesGeometryShader || isRectVertexShader) && (decompilerContext->shaderType == LatteConst::ShaderType::Vertex || decompilerContext->shaderType == LatteConst::ShaderType::Geometry))
|
||||
if (usesGeometryShader && (decompilerContext->shaderType == LatteConst::ShaderType::Vertex || decompilerContext->shaderType == LatteConst::ShaderType::Geometry))
|
||||
{
|
||||
LattePrimitiveMode vsOutPrimType = decompilerContext->contextRegistersNew->VGT_PRIMITIVE_TYPE.get_PRIMITIVE_MODE();
|
||||
src->addFmt("#define VERTICES_PER_VERTEX_PRIMITIVE {}" _CRLF, GetVerticesPerPrimitive(vsOutPrimType));
|
||||
|
@ -399,11 +399,11 @@ namespace LatteDecompiler
|
|||
if(dump_shaders_enabled)
|
||||
decompilerContext->shaderSource->add("// start of shader inputs/outputs, predetermined by Cemu. Do not touch" _CRLF);
|
||||
// uniform variables
|
||||
_emitUniformVariables(decompilerContext, isRectVertexShader);
|
||||
_emitUniformVariables(decompilerContext, usesGeometryShader);
|
||||
// uniform buffers
|
||||
_emitUniformBuffers(decompilerContext);
|
||||
// inputs and outputs
|
||||
_emitInputsAndOutputs(decompilerContext, isRectVertexShader, fetchVertexManually, rasterizationEnabled);
|
||||
_emitInputsAndOutputs(decompilerContext, isRectVertexShader, usesGeometryShader, fetchVertexManually, rasterizationEnabled);
|
||||
|
||||
if (dump_shaders_enabled)
|
||||
decompilerContext->shaderSource->add("// end of shader inputs/outputs" _CRLF);
|
||||
|
@ -491,14 +491,14 @@ namespace LatteDecompiler
|
|||
}
|
||||
}
|
||||
|
||||
static void emitInputs(LatteDecompilerShaderContext* decompilerContext, bool isRectVertexShader, bool fetchVertexManually)
|
||||
static void emitInputs(LatteDecompilerShaderContext* decompilerContext, bool isRectVertexShader, bool usesGeometryShader, bool fetchVertexManually)
|
||||
{
|
||||
auto src = decompilerContext->shaderSource;
|
||||
|
||||
switch (decompilerContext->shaderType)
|
||||
{
|
||||
case LatteConst::ShaderType::Vertex:
|
||||
if (decompilerContext->options->usesGeometryShader || isRectVertexShader)
|
||||
if (usesGeometryShader)
|
||||
{
|
||||
src->add("object_data ObjectPayload& objectPayload [[payload]]");
|
||||
src->add(", mesh_grid_properties meshGridProperties");
|
||||
|
|
|
@ -210,3 +210,12 @@ inline bool PrimitiveRequiresConnection(LattePrimitiveMode primitiveMode)
|
|||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool UseRectEmulation(const LatteContextRegister& lcr) {
|
||||
const LattePrimitiveMode primitiveMode = lcr.VGT_PRIMITIVE_TYPE.get_PRIMITIVE_MODE();
|
||||
return (primitiveMode == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS);
|
||||
}
|
||||
|
||||
inline bool UseGeometryShader(const LatteContextRegister& lcr, bool hasGeometryShader) {
|
||||
return hasGeometryShader || UseRectEmulation(lcr);
|
||||
}
|
||||
|
|
|
@ -283,16 +283,15 @@ MetalPipelineCompiler::~MetalPipelineCompiler()
|
|||
|
||||
m_binaryArchiveURL->release();
|
||||
*/
|
||||
m_pipelineDescriptor->release();
|
||||
if (m_pipelineDescriptor)
|
||||
m_pipelineDescriptor->release();
|
||||
}
|
||||
|
||||
void MetalPipelineCompiler::InitFromState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr)
|
||||
{
|
||||
// Check if the pipeline uses a geometry shader
|
||||
const LattePrimitiveMode primitiveMode = static_cast<LattePrimitiveMode>(lcr.VGT_PRIMITIVE_TYPE.get_PRIMITIVE_MODE());
|
||||
bool isPrimitiveRect = (primitiveMode == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS);
|
||||
|
||||
m_usesGeometryShader = (geometryShader != nullptr || isPrimitiveRect);
|
||||
m_usesGeometryShader = UseGeometryShader(lcr, geometryShader != nullptr);
|
||||
if (m_usesGeometryShader && !m_mtlr->SupportsMeshShaders())
|
||||
return;
|
||||
|
||||
// Rasterization
|
||||
m_rasterizationEnabled = lcr.IsRasterizationEnabled();
|
||||
|
@ -301,7 +300,7 @@ void MetalPipelineCompiler::InitFromState(const LatteFetchShader* fetchShader, c
|
|||
m_vertexShaderMtl = static_cast<RendererShaderMtl*>(vertexShader->shader);
|
||||
if (geometryShader)
|
||||
m_geometryShaderMtl = static_cast<RendererShaderMtl*>(geometryShader->shader);
|
||||
else if (isPrimitiveRect)
|
||||
else if (UseRectEmulation(lcr))
|
||||
m_geometryShaderMtl = rectsEmulationGS_generate(m_mtlr, vertexShader, lcr);
|
||||
else
|
||||
m_geometryShaderMtl = nullptr;
|
||||
|
@ -315,6 +314,9 @@ void MetalPipelineCompiler::InitFromState(const LatteFetchShader* fetchShader, c
|
|||
|
||||
bool MetalPipelineCompiler::Compile(bool forceCompile, bool isRenderThread, bool showInOverlay)
|
||||
{
|
||||
if (m_usesGeometryShader && !m_mtlr->SupportsMeshShaders())
|
||||
return false;
|
||||
|
||||
if (forceCompile)
|
||||
{
|
||||
// if some shader stages are not compiled yet, compile them now
|
||||
|
|
|
@ -30,7 +30,7 @@ private:
|
|||
bool m_usesGeometryShader;
|
||||
bool m_rasterizationEnabled;
|
||||
|
||||
NS::Object* m_pipelineDescriptor;
|
||||
NS::Object* m_pipelineDescriptor = nullptr;
|
||||
|
||||
void InitFromStateRender(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const class MetalAttachmentsInfo& lastUsedAttachmentsInfo, const class MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr);
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "Cemu/Logging/CemuLogging.h"
|
||||
#include "Cafe/HW/Latte/Core/FetchShader.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteConst.h"
|
||||
#include "HW/Latte/Renderer/Metal/MetalCommon.h"
|
||||
#include "config/CemuConfig.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
|
||||
|
@ -171,6 +170,7 @@ MetalRenderer::MetalRenderer()
|
|||
m_supportsFramebufferFetch = GetConfig().framebuffer_fetch.GetValue() ? m_device->supportsFamily(MTL::GPUFamilyApple2) : false;
|
||||
m_hasUnifiedMemory = m_device->hasUnifiedMemory();
|
||||
m_supportsMetal3 = m_device->supportsFamily(MTL::GPUFamilyMetal3);
|
||||
m_supportsMeshShaders = (m_supportsMetal3 && (m_vendor != GfxVendor::Intel || GetConfig().force_mesh_shaders.GetValue())); // Intel GPUs have issues with mesh shaders
|
||||
m_recommendedMaxVRAMUsage = m_device->recommendedMaxWorkingSetSize();
|
||||
m_pixelFormatSupport = MetalPixelFormatSupport(m_device);
|
||||
|
||||
|
@ -1134,9 +1134,11 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||
// Primitive type
|
||||
const LattePrimitiveMode primitiveMode = LatteGPUState.contextNew.VGT_PRIMITIVE_TYPE.get_PRIMITIVE_MODE();
|
||||
auto mtlPrimitiveType = GetMtlPrimitiveType(primitiveMode);
|
||||
bool isPrimitiveRect = (primitiveMode == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS);
|
||||
|
||||
bool usesGeometryShader = (geometryShader != nullptr || isPrimitiveRect);
|
||||
bool usesGeometryShader = UseGeometryShader(LatteGPUState.contextNew, geometryShader != nullptr);
|
||||
if (usesGeometryShader && !m_supportsMeshShaders)
|
||||
return;
|
||||
|
||||
bool fetchVertexManually = (usesGeometryShader || fetchShader->mtlFetchVertexManually);
|
||||
|
||||
// Index buffer
|
||||
|
@ -1293,7 +1295,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||
|
||||
// todo - how does culling behave with rects?
|
||||
// right now we just assume that their winding is always CW
|
||||
if (isPrimitiveRect)
|
||||
if (primitiveMode == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS)
|
||||
{
|
||||
if (frontFace == Latte::LATTE_PA_SU_SC_MODE_CNTL::E_FRONTFACE::CW)
|
||||
cullFront = cullBack;
|
||||
|
@ -1380,7 +1382,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||
|
||||
// Uniform buffers, textures and samplers
|
||||
BindStageResources(renderCommandEncoder, vertexShader, usesGeometryShader);
|
||||
if (geometryShader)
|
||||
if (usesGeometryShader && geometryShader)
|
||||
BindStageResources(renderCommandEncoder, geometryShader, usesGeometryShader);
|
||||
BindStageResources(renderCommandEncoder, pixelShader, usesGeometryShader);
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalAttachmentsInfo.h"
|
||||
#include "Foundation/NSAutoreleasePool.hpp"
|
||||
|
||||
enum MetalGeneralShaderType
|
||||
{
|
||||
|
@ -385,6 +384,11 @@ public:
|
|||
return m_supportsMetal3;
|
||||
}
|
||||
|
||||
bool SupportsMeshShaders() const
|
||||
{
|
||||
return m_supportsMeshShaders;
|
||||
}
|
||||
|
||||
//MTL::StorageMode GetOptimalTextureStorageMode() const
|
||||
//{
|
||||
// return (m_isAppleGPU ? MTL::StorageModeShared : MTL::StorageModePrivate);
|
||||
|
@ -483,6 +487,7 @@ private:
|
|||
bool m_supportsFramebufferFetch;
|
||||
bool m_hasUnifiedMemory;
|
||||
bool m_supportsMetal3;
|
||||
bool m_supportsMeshShaders;
|
||||
uint32 m_recommendedMaxVRAMUsage;
|
||||
MetalPixelFormatSupport m_pixelFormatSupport;
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ void CemuConfig::Load(XMLConfigParser& parser)
|
|||
fullscreen_scaling = graphic.get("FullscreenScaling", kKeepAspectRatio);
|
||||
async_compile = graphic.get("AsyncCompile", async_compile);
|
||||
vk_accurate_barriers = graphic.get("vkAccurateBarriers", true); // this used to be "VulkanAccurateBarriers" but because we changed the default to true in 1.27.1 the option name had to be changed
|
||||
force_mesh_shaders = graphic.get("ForceMeshShaders", false);
|
||||
|
||||
auto overlay_node = graphic.get("Overlay");
|
||||
if(overlay_node.valid())
|
||||
|
@ -477,6 +478,7 @@ void CemuConfig::Save(XMLConfigParser& parser)
|
|||
graphic.set("mtlDevice", mtl_graphic_device_uuid);
|
||||
graphic.set("VSync", vsync);
|
||||
graphic.set("GX2DrawdoneSync", gx2drawdone_sync);
|
||||
graphic.set("ForceMeshShaders", force_mesh_shaders);
|
||||
//graphic.set("PrecompiledShaders", precompiled_shaders.GetValue());
|
||||
graphic.set("UpscaleFilter", upscale_filter);
|
||||
graphic.set("DownscaleFilter", downscale_filter);
|
||||
|
|
|
@ -494,6 +494,7 @@ struct CemuConfig
|
|||
ConfigValue<bool> gx2drawdone_sync { true };
|
||||
ConfigValue<bool> render_upside_down{ false };
|
||||
ConfigValue<bool> async_compile{ true };
|
||||
ConfigValue<bool> force_mesh_shaders{ false };
|
||||
|
||||
ConfigValue<bool> vk_accurate_barriers{ true };
|
||||
|
||||
|
|
|
@ -367,6 +367,10 @@ wxPanel* GeneralSettings2::AddGraphicsPage(wxNotebook* notebook)
|
|||
m_gx2drawdone_sync->SetToolTip(_("If synchronization is requested by the game, the emulated CPU will wait for the GPU to finish all operations.\nThis is more accurate behavior, but may cause lower performance"));
|
||||
graphic_misc_row->Add(m_gx2drawdone_sync, 0, wxALL, 5);
|
||||
|
||||
m_force_mesh_shaders = new wxCheckBox(box, wxID_ANY, _("Force mesh shaders"));
|
||||
m_force_mesh_shaders->SetToolTip(_("Force mesh shaders on all GPUs that support them. Mesh shaders are disabled by default on Intel GPUs due to potential stability issues"));
|
||||
graphic_misc_row->Add(m_force_mesh_shaders, 0, wxALL, 5);
|
||||
|
||||
box_sizer->Add(graphic_misc_row, 1, wxEXPAND, 5);
|
||||
graphics_panel_sizer->Add(box_sizer, 0, wxEXPAND | wxALL, 5);
|
||||
}
|
||||
|
@ -1100,6 +1104,7 @@ void GeneralSettings2::StoreConfig()
|
|||
|
||||
config.vsync = m_vsync->GetSelection();
|
||||
config.gx2drawdone_sync = m_gx2drawdone_sync->IsChecked();
|
||||
config.force_mesh_shaders = m_force_mesh_shaders->IsChecked();
|
||||
config.async_compile = m_async_compile->IsChecked();
|
||||
|
||||
config.upscale_filter = m_upscale_filter->GetSelection();
|
||||
|
@ -1580,12 +1585,14 @@ void GeneralSettings2::HandleGraphicsApiSelection()
|
|||
|
||||
m_gx2drawdone_sync->Enable();
|
||||
m_async_compile->Disable();
|
||||
m_force_mesh_shaders->Disable();
|
||||
}
|
||||
else if (m_graphic_api->GetSelection() == 1)
|
||||
{
|
||||
// Vulkan
|
||||
m_gx2drawdone_sync->Disable();
|
||||
m_async_compile->Enable();
|
||||
m_force_mesh_shaders->Disable();
|
||||
|
||||
m_vsync->AppendString(_("Off"));
|
||||
m_vsync->AppendString(_("Double buffering"));
|
||||
|
@ -1623,11 +1630,10 @@ void GeneralSettings2::HandleGraphicsApiSelection()
|
|||
// Metal
|
||||
m_gx2drawdone_sync->Disable();
|
||||
m_async_compile->Enable();
|
||||
m_force_mesh_shaders->Enable();
|
||||
|
||||
// TODO: vsync options
|
||||
m_vsync->AppendString(_("Off"));
|
||||
m_vsync->AppendString(_("Double buffering"));
|
||||
m_vsync->AppendString(_("Triple buffering"));
|
||||
m_vsync->AppendString(_("On"));
|
||||
|
||||
m_vsync->Select(selection);
|
||||
|
||||
|
@ -1708,6 +1714,7 @@ void GeneralSettings2::ApplyConfig()
|
|||
m_vsync->SetSelection(config.vsync);
|
||||
m_async_compile->SetValue(config.async_compile);
|
||||
m_gx2drawdone_sync->SetValue(config.gx2drawdone_sync);
|
||||
m_force_mesh_shaders->SetValue(config.force_mesh_shaders);
|
||||
m_upscale_filter->SetSelection(config.upscale_filter);
|
||||
m_downscale_filter->SetSelection(config.downscale_filter);
|
||||
m_fullscreen_scaling->SetSelection(config.fullscreen_scaling);
|
||||
|
|
|
@ -53,7 +53,7 @@ private:
|
|||
// Graphics
|
||||
wxChoice* m_graphic_api, * m_graphic_device;
|
||||
wxChoice* m_vsync;
|
||||
wxCheckBox *m_async_compile, *m_gx2drawdone_sync;
|
||||
wxCheckBox *m_async_compile, *m_gx2drawdone_sync, *m_force_mesh_shaders;
|
||||
wxRadioBox* m_upscale_filter, *m_downscale_filter, *m_fullscreen_scaling;
|
||||
wxChoice* m_overlay_position, *m_notification_position, *m_overlay_scale, *m_notification_scale;
|
||||
wxCheckBox* m_controller_profile_name, *m_controller_low_battery, *m_shader_compiling, *m_friends_data;
|
||||
|
|
Loading…
Add table
Reference in a new issue