early-access version 4026
This commit is contained in:
		| @@ -1,7 +1,7 @@ | ||||
| yuzu emulator early access | ||||
| ============= | ||||
|  | ||||
| This is the source code for early-access 4025. | ||||
| This is the source code for early-access 4026. | ||||
|  | ||||
| ## Legal Notice | ||||
|  | ||||
|   | ||||
| @@ -74,6 +74,11 @@ std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | ||||
|     case IR::Attribute::ClipDistance7: { | ||||
|         const u32 base{static_cast<u32>(IR::Attribute::ClipDistance0)}; | ||||
|         const u32 index{static_cast<u32>(attr) - base}; | ||||
|         if (index >= ctx.profile.max_user_clip_distances) { | ||||
|             LOG_WARNING(Shader, "Ignoring clip distance store {} >= {} supported", index, | ||||
|                         ctx.profile.max_user_clip_distances); | ||||
|             return std::nullopt; | ||||
|         } | ||||
|         const Id clip_num{ctx.Const(index)}; | ||||
|         return OutputAccessChain(ctx, ctx.output_f32, ctx.clip_distances, clip_num); | ||||
|     } | ||||
|   | ||||
| @@ -1533,7 +1533,8 @@ void EmitContext::DefineOutputs(const IR::Program& program) { | ||||
|         if (stage == Stage::Fragment) { | ||||
|             throw NotImplementedException("Storing ClipDistance in fragment stage"); | ||||
|         } | ||||
|         const Id type{TypeArray(F32[1], Const(8U))}; | ||||
|         const Id type{TypeArray( | ||||
|             F32[1], Const(std::min(info.used_clip_distances, profile.max_user_clip_distances)))}; | ||||
|         clip_distances = DefineOutput(*this, type, invocations, spv::BuiltIn::ClipDistance); | ||||
|     } | ||||
|     if (info.stores[IR::Attribute::Layer] && | ||||
|   | ||||
| @@ -913,7 +913,11 @@ void GatherInfoFromHeader(Environment& env, Info& info) { | ||||
|         } | ||||
|         for (size_t index = 0; index < 8; ++index) { | ||||
|             const u16 mask{header.vtg.omap_systemc.clip_distances}; | ||||
|             info.stores.Set(IR::Attribute::ClipDistance0 + index, ((mask >> index) & 1) != 0); | ||||
|             const bool used{((mask >> index) & 1) != 0}; | ||||
|             info.stores.Set(IR::Attribute::ClipDistance0 + index, used); | ||||
|             if (used) { | ||||
|                 info.used_clip_distances = static_cast<u32>(index) + 1; | ||||
|             } | ||||
|         } | ||||
|         info.stores.Set(IR::Attribute::PrimitiveId, | ||||
|                         header.vtg.omap_systemb.primitive_array_id != 0); | ||||
|   | ||||
| @@ -87,6 +87,8 @@ struct Profile { | ||||
|     bool has_broken_robust{}; | ||||
|  | ||||
|     u64 min_ssbo_alignment{}; | ||||
|  | ||||
|     u32 max_user_clip_distances{}; | ||||
| }; | ||||
|  | ||||
| } // namespace Shader | ||||
|   | ||||
| @@ -227,6 +227,8 @@ struct Info { | ||||
|     bool requires_layer_emulation{}; | ||||
|     IR::Attribute emulated_layer{}; | ||||
|  | ||||
|     u32 used_clip_distances{}; | ||||
|  | ||||
|     boost::container::static_vector<ConstantBufferDescriptor, MAX_CBUFS> | ||||
|         constant_buffer_descriptors; | ||||
|     boost::container::static_vector<StorageBufferDescriptor, MAX_SSBOS> storage_buffers_descriptors; | ||||
|   | ||||
| @@ -233,6 +233,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo | ||||
|           .ignore_nan_fp_comparisons = true, | ||||
|           .gl_max_compute_smem_size = device.GetMaxComputeSharedMemorySize(), | ||||
|           .min_ssbo_alignment = device.GetShaderStorageBufferAlignment(), | ||||
|           .max_user_clip_distances = 8, | ||||
|       }, | ||||
|       host_info{ | ||||
|           .support_float64 = true, | ||||
|   | ||||
| @@ -563,22 +563,27 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bi | ||||
|         } | ||||
|         buffer_handles.push_back(handle); | ||||
|     } | ||||
|     const u32 device_max = device.GetMaxVertexInputBindings(); | ||||
|     const u32 min_binding = std::min(bindings.min_index, device_max); | ||||
|     const u32 max_binding = std::min(bindings.max_index, device_max); | ||||
|     const u32 binding_count = max_binding - min_binding; | ||||
|     if (binding_count == 0) { | ||||
|         return; | ||||
|     } | ||||
|     if (device.IsExtExtendedDynamicStateSupported()) { | ||||
|         scheduler.Record([this, bindings_ = std::move(bindings), | ||||
|                           buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { | ||||
|             cmdbuf.BindVertexBuffers2EXT(bindings_.min_index, | ||||
|                                          std::min(bindings_.max_index - bindings_.min_index, | ||||
|                                                   device.GetMaxVertexInputBindings()), | ||||
|                                          buffer_handles_.data(), bindings_.offsets.data(), | ||||
|                                          bindings_.sizes.data(), bindings_.strides.data()); | ||||
|         scheduler.Record([bindings_ = std::move(bindings), | ||||
|                           buffer_handles_ = std::move(buffer_handles), | ||||
|                           binding_count](vk::CommandBuffer cmdbuf) { | ||||
|             cmdbuf.BindVertexBuffers2EXT(bindings_.min_index, binding_count, buffer_handles_.data(), | ||||
|                                          bindings_.offsets.data(), bindings_.sizes.data(), | ||||
|                                          bindings_.strides.data()); | ||||
|         }); | ||||
|     } else { | ||||
|         scheduler.Record([this, bindings_ = std::move(bindings), | ||||
|                           buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { | ||||
|             cmdbuf.BindVertexBuffers(bindings_.min_index, | ||||
|                                      std::min(bindings_.max_index - bindings_.min_index, | ||||
|                                               device.GetMaxVertexInputBindings()), | ||||
|                                      buffer_handles_.data(), bindings_.offsets.data()); | ||||
|         scheduler.Record([bindings_ = std::move(bindings), | ||||
|                           buffer_handles_ = std::move(buffer_handles), | ||||
|                           binding_count](vk::CommandBuffer cmdbuf) { | ||||
|             cmdbuf.BindVertexBuffers(bindings_.min_index, binding_count, buffer_handles_.data(), | ||||
|                                      bindings_.offsets.data()); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -374,6 +374,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device | ||||
|         .has_broken_robust = | ||||
|             device.IsNvidia() && device.GetNvidiaArch() <= NvidiaArchitecture::Arch_Pascal, | ||||
|         .min_ssbo_alignment = device.GetStorageBufferAlignment(), | ||||
|         .max_user_clip_distances = device.GetMaxUserClipDistances(), | ||||
|     }; | ||||
|  | ||||
|     host_info = Shader::HostTranslateInfo{ | ||||
|   | ||||
| @@ -695,6 +695,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | ||||
|             std::min(properties.properties.limits.maxVertexInputBindings, 16U); | ||||
|     } | ||||
|  | ||||
|     if (is_turnip) { | ||||
|         LOG_WARNING(Render_Vulkan, "Turnip requires higher-than-reported binding limits"); | ||||
|         properties.properties.limits.maxVertexInputBindings = 32; | ||||
|     } | ||||
|  | ||||
|     if (!extensions.extended_dynamic_state && extensions.extended_dynamic_state2) { | ||||
|         LOG_INFO(Render_Vulkan, | ||||
|                  "Removing extendedDynamicState2 due to missing extendedDynamicState"); | ||||
|   | ||||
| @@ -651,6 +651,10 @@ public: | ||||
|         return properties.properties.limits.maxViewports; | ||||
|     } | ||||
|  | ||||
|     u32 GetMaxUserClipDistances() const { | ||||
|         return properties.properties.limits.maxClipDistances; | ||||
|     } | ||||
|  | ||||
|     bool SupportsConditionalBarriers() const { | ||||
|         return supports_conditional_barriers; | ||||
|     } | ||||
|   | ||||
| @@ -193,8 +193,8 @@ void ConfigureUi::RequestGameListUpdate() { | ||||
| void ConfigureUi::SetConfiguration() { | ||||
|     ui->theme_combobox->setCurrentIndex( | ||||
|         ui->theme_combobox->findData(QString::fromStdString(UISettings::values.theme))); | ||||
|     ui->language_combobox->setCurrentIndex( | ||||
|         ui->language_combobox->findData(QString::fromStdString(UISettings::values.language))); | ||||
|     ui->language_combobox->setCurrentIndex(ui->language_combobox->findData( | ||||
|         QString::fromStdString(UISettings::values.language.GetValue()))); | ||||
|     ui->show_add_ons->setChecked(UISettings::values.show_add_ons.GetValue()); | ||||
|     ui->show_compat->setChecked(UISettings::values.show_compat.GetValue()); | ||||
|     ui->show_size->setChecked(UISettings::values.show_size.GetValue()); | ||||
|   | ||||
| @@ -187,7 +187,6 @@ void QtConfig::ReadPathValues() { | ||||
|     BeginGroup(Settings::TranslateCategory(Settings::Category::Paths)); | ||||
|  | ||||
|     UISettings::values.roms_path = ReadStringSetting(std::string("romsPath")); | ||||
|     UISettings::values.symbols_path = ReadStringSetting(std::string("symbolsPath")); | ||||
|     UISettings::values.game_dir_deprecated = | ||||
|         ReadStringSetting(std::string("gameListRootDir"), std::string(".")); | ||||
|     UISettings::values.game_dir_deprecated_deepscan = | ||||
| @@ -225,8 +224,6 @@ void QtConfig::ReadPathValues() { | ||||
|     UISettings::values.recent_files = | ||||
|         QString::fromStdString(ReadStringSetting(std::string("recentFiles"))) | ||||
|             .split(QStringLiteral(", "), Qt::SkipEmptyParts, Qt::CaseSensitive); | ||||
|     UISettings::values.language = | ||||
|         ReadStringSetting(std::string("language"), std::make_optional(std::string(""))); | ||||
|  | ||||
|     EndGroup(); | ||||
| } | ||||
| @@ -409,7 +406,6 @@ void QtConfig::SavePathValues() { | ||||
|     BeginGroup(Settings::TranslateCategory(Settings::Category::Paths)); | ||||
|  | ||||
|     WriteSetting(std::string("romsPath"), UISettings::values.roms_path); | ||||
|     WriteSetting(std::string("symbolsPath"), UISettings::values.symbols_path); | ||||
|     BeginArray(std::string("gamedirs")); | ||||
|     for (int i = 0; i < UISettings::values.game_dirs.size(); ++i) { | ||||
|         SetArrayIndex(i); | ||||
| @@ -422,7 +418,6 @@ void QtConfig::SavePathValues() { | ||||
|  | ||||
|     WriteSetting(std::string("recentFiles"), | ||||
|                  UISettings::values.recent_files.join(QStringLiteral(", ")).toStdString()); | ||||
|     WriteSetting(std::string("language"), UISettings::values.language); | ||||
|  | ||||
|     EndGroup(); | ||||
| } | ||||
|   | ||||
| @@ -5147,12 +5147,12 @@ void GMainWindow::UpdateUITheme() { | ||||
| void GMainWindow::LoadTranslation() { | ||||
|     bool loaded; | ||||
|  | ||||
|     if (UISettings::values.language.empty()) { | ||||
|     if (UISettings::values.language.GetValue().empty()) { | ||||
|         // If the selected language is empty, use system locale | ||||
|         loaded = translator.load(QLocale(), {}, {}, QStringLiteral(":/languages/")); | ||||
|     } else { | ||||
|         // Otherwise load from the specified file | ||||
|         loaded = translator.load(QString::fromStdString(UISettings::values.language), | ||||
|         loaded = translator.load(QString::fromStdString(UISettings::values.language.GetValue()), | ||||
|                                  QStringLiteral(":/languages/")); | ||||
|     } | ||||
|  | ||||
| @@ -5164,7 +5164,7 @@ void GMainWindow::LoadTranslation() { | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnLanguageChanged(const QString& locale) { | ||||
|     if (UISettings::values.language != std::string("en")) { | ||||
|     if (UISettings::values.language.GetValue() != std::string("en")) { | ||||
|         qApp->removeTranslator(&translator); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -154,12 +154,11 @@ struct Values { | ||||
|     Setting<u32> screenshot_height{linkage, 0, "screenshot_height", Category::Screenshots}; | ||||
|  | ||||
|     std::string roms_path; | ||||
|     std::string symbols_path; | ||||
|     std::string game_dir_deprecated; | ||||
|     bool game_dir_deprecated_deepscan; | ||||
|     QVector<GameDir> game_dirs; | ||||
|     QStringList recent_files; | ||||
|     std::string language; | ||||
|     Setting<std::string> language{linkage, {}, "language", Category::Paths}; | ||||
|  | ||||
|     std::string theme; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user