Compare commits
	
		
			1 Commits
		
	
	
		
			such-a-san
			...
			tex-filter
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | b94374009e | 
| @@ -184,11 +184,6 @@ | ||||
|              <string>Bicubic</string> | ||||
|             </property> | ||||
|            </item> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>Nearest Neighbor</string> | ||||
|             </property> | ||||
|            </item> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>ScaleForce</string> | ||||
| @@ -199,11 +194,11 @@ | ||||
|              <string>xBRZ</string> | ||||
|             </property> | ||||
|            </item> | ||||
|             <item> | ||||
|               <property name="text"> | ||||
|                 <string>MMPX</string> | ||||
|               </property> | ||||
|             </item> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>MMPX</string> | ||||
|             </property> | ||||
|            </item> | ||||
|           </widget> | ||||
|          </item> | ||||
|         </layout> | ||||
|   | ||||
| @@ -71,11 +71,17 @@ void ConfigureGraphics::SetConfiguration() { | ||||
|                                           !Settings::values.physical_device.UsingGlobal()); | ||||
|         ConfigurationShared::SetPerGameSetting(ui->physical_device_combo, | ||||
|                                                &Settings::values.physical_device); | ||||
|         ConfigurationShared::SetPerGameSetting(ui->texture_sampling_combobox, | ||||
|                                                &Settings::values.texture_sampling); | ||||
|         ConfigurationShared::SetHighlight(ui->widget_texture_sampling, | ||||
|                                           !Settings::values.texture_sampling.UsingGlobal()); | ||||
|     } else { | ||||
|         ui->graphics_api_combo->setCurrentIndex( | ||||
|             static_cast<int>(Settings::values.graphics_api.GetValue())); | ||||
|         ui->physical_device_combo->setCurrentIndex( | ||||
|             static_cast<int>(Settings::values.physical_device.GetValue())); | ||||
|         ui->texture_sampling_combobox->setCurrentIndex( | ||||
|             static_cast<int>(Settings::values.texture_sampling.GetValue())); | ||||
|     } | ||||
|  | ||||
|     ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader.GetValue()); | ||||
| @@ -106,6 +112,8 @@ void ConfigureGraphics::ApplyConfiguration() { | ||||
|                                              use_hw_shader); | ||||
|     ConfigurationShared::ApplyPerGameSetting(&Settings::values.shaders_accurate_mul, | ||||
|                                              ui->toggle_accurate_mul, shaders_accurate_mul); | ||||
|     ConfigurationShared::ApplyPerGameSetting(&Settings::values.texture_sampling, | ||||
|                                              ui->texture_sampling_combobox); | ||||
|     ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache, | ||||
|                                              ui->toggle_disk_shader_cache, use_disk_shader_cache); | ||||
|     ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync_new, ui->toggle_vsync_new, | ||||
| @@ -132,6 +140,7 @@ void ConfigureGraphics::SetupPerGameUI() { | ||||
|                                          Settings::values.use_vsync_new.UsingGlobal()); | ||||
|         ui->toggle_async_shaders->setEnabled( | ||||
|             Settings::values.async_shader_compilation.UsingGlobal()); | ||||
|         ui->widget_texture_sampling->setEnabled(Settings::values.texture_sampling.UsingGlobal()); | ||||
|         ui->toggle_async_present->setEnabled(Settings::values.async_presentation.UsingGlobal()); | ||||
|         ui->graphics_api_combo->setEnabled(Settings::values.graphics_api.UsingGlobal()); | ||||
|         ui->physical_device_combo->setEnabled(Settings::values.physical_device.UsingGlobal()); | ||||
| @@ -148,6 +157,10 @@ void ConfigureGraphics::SetupPerGameUI() { | ||||
|         ui->physical_device_combo, ui->physical_device_group, | ||||
|         static_cast<u32>(Settings::values.physical_device.GetValue(true))); | ||||
|  | ||||
|     ConfigurationShared::SetColoredComboBox( | ||||
|         ui->texture_sampling_combobox, ui->widget_texture_sampling, | ||||
|         static_cast<int>(Settings::values.texture_sampling.GetValue(true))); | ||||
|  | ||||
|     ConfigurationShared::SetColoredTristate(ui->toggle_hw_shader, Settings::values.use_hw_shader, | ||||
|                                             use_hw_shader); | ||||
|     ConfigurationShared::SetColoredTristate( | ||||
|   | ||||
| @@ -212,6 +212,53 @@ | ||||
|       <string>Advanced</string> | ||||
|      </property> | ||||
|      <layout class="QVBoxLayout" name="verticalLayout_2"> | ||||
|       <item> | ||||
|        <widget class="QWidget" name="widget_texture_sampling" native="true"> | ||||
|         <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||||
|          <property name="leftMargin"> | ||||
|           <number>0</number> | ||||
|          </property> | ||||
|          <property name="topMargin"> | ||||
|           <number>0</number> | ||||
|          </property> | ||||
|          <property name="rightMargin"> | ||||
|           <number>0</number> | ||||
|          </property> | ||||
|          <property name="bottomMargin"> | ||||
|           <number>0</number> | ||||
|          </property> | ||||
|          <item> | ||||
|           <widget class="QLabel" name="texture_sampling_label"> | ||||
|            <property name="toolTip"> | ||||
|             <string><html><head/><body><p>Overrides the sampling filter used by games. This can be useful in certain cases with poorly behaved games when upscaling. If unsure set this to Game Controlled</p></body></html></string> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Texture Sampling</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QComboBox" name="texture_sampling_combobox"> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>Game Controlled</string> | ||||
|             </property> | ||||
|            </item> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>Nearest Neighbor</string> | ||||
|             </property> | ||||
|            </item> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>Linear</string> | ||||
|             </property> | ||||
|            </item> | ||||
|           </widget> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QCheckBox" name="toggle_disk_shader_cache"> | ||||
|         <property name="toolTip"> | ||||
|   | ||||
| @@ -46,8 +46,6 @@ std::string_view GetTextureFilterName(TextureFilter filter) { | ||||
|         return "Anime4K"; | ||||
|     case TextureFilter::Bicubic: | ||||
|         return "Bicubic"; | ||||
|     case TextureFilter::NearestNeighbor: | ||||
|         return "NearestNeighbor"; | ||||
|     case TextureFilter::ScaleForce: | ||||
|         return "ScaleForce"; | ||||
|     case TextureFilter::xBRZ: | ||||
| @@ -59,6 +57,19 @@ std::string_view GetTextureFilterName(TextureFilter filter) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| std::string_view GetTextureSamplingName(TextureSampling sampling) { | ||||
|     switch (sampling) { | ||||
|     case TextureSampling::GameControlled: | ||||
|         return "GameControlled"; | ||||
|     case TextureSampling::NearestNeighbor: | ||||
|         return "NearestNeighbor"; | ||||
|     case TextureSampling::Linear: | ||||
|         return "Linear"; | ||||
|     default: | ||||
|         return "Invalid"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| Values values = {}; | ||||
| @@ -87,6 +98,8 @@ void LogSettings() { | ||||
|     log_setting("Renderer_PostProcessingShader", values.pp_shader_name.GetValue()); | ||||
|     log_setting("Renderer_FilterMode", values.filter_mode.GetValue()); | ||||
|     log_setting("Renderer_TextureFilter", GetTextureFilterName(values.texture_filter.GetValue())); | ||||
|     log_setting("Renderer_TextureSampling", | ||||
|                 GetTextureSamplingName(values.texture_sampling.GetValue())); | ||||
|     log_setting("Stereoscopy_Render3d", values.render_3d.GetValue()); | ||||
|     log_setting("Stereoscopy_Factor3d", values.factor_3d.GetValue()); | ||||
|     log_setting("Stereoscopy_MonoRenderOption", values.mono_render_option.GetValue()); | ||||
| @@ -175,6 +188,7 @@ void RestoreGlobalState(bool is_powered_on) { | ||||
|     values.resolution_factor.SetGlobal(true); | ||||
|     values.frame_limit.SetGlobal(true); | ||||
|     values.texture_filter.SetGlobal(true); | ||||
|     values.texture_sampling.SetGlobal(true); | ||||
|     values.layout_option.SetGlobal(true); | ||||
|     values.swap_screen.SetGlobal(true); | ||||
|     values.upright_screen.SetGlobal(true); | ||||
|   | ||||
| @@ -72,10 +72,15 @@ enum class TextureFilter : u32 { | ||||
|     None = 0, | ||||
|     Anime4K = 1, | ||||
|     Bicubic = 2, | ||||
|     NearestNeighbor = 3, | ||||
|     ScaleForce = 4, | ||||
|     xBRZ = 5, | ||||
|     MMPX = 6 | ||||
|     ScaleForce = 3, | ||||
|     xBRZ = 4, | ||||
|     MMPX = 5, | ||||
| }; | ||||
|  | ||||
| enum class TextureSampling : u32 { | ||||
|     GameControlled = 0, | ||||
|     NearestNeighbor = 1, | ||||
|     Linear = 2, | ||||
| }; | ||||
|  | ||||
| namespace NativeButton { | ||||
| @@ -451,6 +456,8 @@ struct Values { | ||||
|     SwitchableSetting<u32, true> resolution_factor{1, 0, 10, "resolution_factor"}; | ||||
|     SwitchableSetting<u16, true> frame_limit{100, 0, 1000, "frame_limit"}; | ||||
|     SwitchableSetting<TextureFilter> texture_filter{TextureFilter::None, "texture_filter"}; | ||||
|     SwitchableSetting<TextureSampling> texture_sampling{TextureSampling::GameControlled, | ||||
|                                                         "texture_sampling"}; | ||||
|  | ||||
|     SwitchableSetting<LayoutOption> layout_option{LayoutOption::Default, "layout_option"}; | ||||
|     SwitchableSetting<bool> swap_screen{false, "swap_screen"}; | ||||
|   | ||||
| @@ -7,7 +7,6 @@ set(SHADER_FILES | ||||
|     format_reinterpreter/rgba4_to_rgb5a1.frag | ||||
|     format_reinterpreter/vulkan_d24s8_to_rgba8.comp | ||||
|     texture_filtering/bicubic.frag | ||||
|     texture_filtering/nearest_neighbor.frag | ||||
|     texture_filtering/refine.frag | ||||
|     texture_filtering/scale_force.frag | ||||
|     texture_filtering/xbrz_freescale.frag | ||||
|   | ||||
| @@ -1,15 +0,0 @@ | ||||
| // Copyright 2023 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| //? #version 430 core | ||||
| precision mediump float; | ||||
|  | ||||
| layout(location = 0) in vec2 tex_coord; | ||||
| layout(location = 0) out vec4 frag_color; | ||||
|  | ||||
| layout(binding = 2) uniform sampler2D input_texture; | ||||
|  | ||||
| void main() { | ||||
|     frag_color = texture(input_texture, tex_coord); | ||||
| } | ||||
| @@ -361,10 +361,25 @@ typename T::Sampler& RasterizerCache<T>::GetSampler(SamplerId sampler_id) { | ||||
| template <class T> | ||||
| typename T::Sampler& RasterizerCache<T>::GetSampler( | ||||
|     const Pica::TexturingRegs::TextureConfig& config) { | ||||
|     using TextureFilter = Pica::TexturingRegs::TextureConfig::TextureFilter; | ||||
|  | ||||
|     const auto get_filter = [](TextureFilter filter) { | ||||
|         switch (Settings::values.texture_sampling.GetValue()) { | ||||
|         case Settings::TextureSampling::GameControlled: | ||||
|             return filter; | ||||
|         case Settings::TextureSampling::NearestNeighbor: | ||||
|             return TextureFilter::Nearest; | ||||
|         case Settings::TextureSampling::Linear: | ||||
|             return TextureFilter::Linear; | ||||
|         default: | ||||
|             return filter; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     const SamplerParams params = { | ||||
|         .mag_filter = config.mag_filter, | ||||
|         .min_filter = config.min_filter, | ||||
|         .mip_filter = config.mip_filter, | ||||
|         .mag_filter = get_filter(config.mag_filter), | ||||
|         .min_filter = get_filter(config.min_filter), | ||||
|         .mip_filter = get_filter(config.mip_filter), | ||||
|         .wrap_s = config.wrap_s, | ||||
|         .wrap_t = config.wrap_t, | ||||
|         .border_color = config.border_color.raw, | ||||
|   | ||||
| @@ -15,7 +15,6 @@ | ||||
| #include "video_core/host_shaders/full_screen_triangle_vert.h" | ||||
| #include "video_core/host_shaders/texture_filtering/bicubic_frag.h" | ||||
| #include "video_core/host_shaders/texture_filtering/mmpx_frag.h" | ||||
| #include "video_core/host_shaders/texture_filtering/nearest_neighbor_frag.h" | ||||
| #include "video_core/host_shaders/texture_filtering/refine_frag.h" | ||||
| #include "video_core/host_shaders/texture_filtering/scale_force_frag.h" | ||||
| #include "video_core/host_shaders/texture_filtering/x_gradient_frag.h" | ||||
| @@ -58,7 +57,6 @@ BlitHelper::BlitHelper(const Driver& driver_) | ||||
|     : driver{driver_}, linear_sampler{CreateSampler(GL_LINEAR)}, | ||||
|       nearest_sampler{CreateSampler(GL_NEAREST)}, bicubic_program{CreateProgram( | ||||
|                                                       HostShaders::BICUBIC_FRAG)}, | ||||
|       nearest_program{CreateProgram(HostShaders::NEAREST_NEIGHBOR_FRAG)}, | ||||
|       scale_force_program{CreateProgram(HostShaders::SCALE_FORCE_FRAG)}, | ||||
|       xbrz_program{CreateProgram(HostShaders::XBRZ_FREESCALE_FRAG)}, | ||||
|       mmpx_program{CreateProgram(HostShaders::MMPX_FRAG)}, gradient_x_program{CreateProgram( | ||||
| @@ -175,9 +173,6 @@ bool BlitHelper::Filter(Surface& surface, const VideoCore::TextureBlit& blit) { | ||||
|     case TextureFilter::Bicubic: | ||||
|         FilterBicubic(surface, blit); | ||||
|         break; | ||||
|     case TextureFilter::NearestNeighbor: | ||||
|         FilterNearest(surface, blit); | ||||
|         break; | ||||
|     case TextureFilter::ScaleForce: | ||||
|         FilterScaleForce(surface, blit); | ||||
|         break; | ||||
| @@ -257,14 +252,6 @@ void BlitHelper::FilterBicubic(Surface& surface, const VideoCore::TextureBlit& b | ||||
|     Draw(bicubic_program, surface.Handle(), draw_fbo.handle, blit.dst_level, blit.dst_rect); | ||||
| } | ||||
|  | ||||
| void BlitHelper::FilterNearest(Surface& surface, const VideoCore::TextureBlit& blit) { | ||||
|     const OpenGLState prev_state = OpenGLState::GetCurState(); | ||||
|     SCOPE_EXIT({ prev_state.Apply(); }); | ||||
|     state.texture_units[2].texture_2d = surface.Handle(0); | ||||
|     SetParams(nearest_program, surface.RealExtent(false), blit.src_rect); | ||||
|     Draw(nearest_program, surface.Handle(), draw_fbo.handle, blit.dst_level, blit.dst_rect); | ||||
| } | ||||
|  | ||||
| void BlitHelper::FilterScaleForce(Surface& surface, const VideoCore::TextureBlit& blit) { | ||||
|     const OpenGLState prev_state = OpenGLState::GetCurState(); | ||||
|     SCOPE_EXIT({ prev_state.Apply(); }); | ||||
|   | ||||
| @@ -33,20 +33,13 @@ public: | ||||
|  | ||||
| private: | ||||
|     void FilterAnime4K(Surface& surface, const VideoCore::TextureBlit& blit); | ||||
|  | ||||
|     void FilterBicubic(Surface& surface, const VideoCore::TextureBlit& blit); | ||||
|  | ||||
|     void FilterNearest(Surface& surface, const VideoCore::TextureBlit& blit); | ||||
|  | ||||
|     void FilterScaleForce(Surface& surface, const VideoCore::TextureBlit& blit); | ||||
|  | ||||
|     void FilterXbrz(Surface& surface, const VideoCore::TextureBlit& blit); | ||||
|  | ||||
|     void FilterMMPX(Surface& surface, const VideoCore::TextureBlit& blit); | ||||
|  | ||||
|     void SetParams(OGLProgram& program, const VideoCore::Extent& src_extent, | ||||
|                    Common::Rectangle<u32> src_rect); | ||||
|  | ||||
|     void Draw(OGLProgram& program, GLuint dst_tex, GLuint dst_fbo, u32 dst_level, | ||||
|               Common::Rectangle<u32> dst_rect); | ||||
|  | ||||
| @@ -59,7 +52,6 @@ private: | ||||
|     OGLSampler nearest_sampler; | ||||
|  | ||||
|     OGLProgram bicubic_program; | ||||
|     OGLProgram nearest_program; | ||||
|     OGLProgram scale_force_program; | ||||
|     OGLProgram xbrz_program; | ||||
|     OGLProgram mmpx_program; | ||||
|   | ||||
| @@ -35,10 +35,7 @@ public: | ||||
|                        const VideoCore::BufferTextureCopy& copy); | ||||
|  | ||||
| private: | ||||
|     /// Creates compute pipelines used for blit | ||||
|     vk::Pipeline MakeComputePipeline(vk::ShaderModule shader, vk::PipelineLayout layout); | ||||
|  | ||||
|     /// Creates graphics pipelines used for blit | ||||
|     vk::Pipeline MakeDepthStencilBlitPipeline(); | ||||
|  | ||||
| private: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user