diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 27c07f4d90..ae5ad79ee5 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -206,55 +206,55 @@ D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(rsx::texture_wrap_mode wrap) namespace { - void get_min_filter(u8 min_filter, D3D12_FILTER_TYPE &min, D3D12_FILTER_TYPE &mip) + void get_min_filter(rsx::texture_minify_filter min_filter, D3D12_FILTER_TYPE &min, D3D12_FILTER_TYPE &mip) { switch (min_filter) { - case CELL_GCM_TEXTURE_NEAREST: + case rsx::texture_minify_filter::nearest: min = D3D12_FILTER_TYPE_POINT; mip = D3D12_FILTER_TYPE_POINT; return; - case CELL_GCM_TEXTURE_LINEAR: + case rsx::texture_minify_filter::linear: min = D3D12_FILTER_TYPE_LINEAR; mip = D3D12_FILTER_TYPE_POINT; return; - case CELL_GCM_TEXTURE_NEAREST_NEAREST: + case rsx::texture_minify_filter::nearest_nearest: min = D3D12_FILTER_TYPE_POINT; mip = D3D12_FILTER_TYPE_POINT; return; - case CELL_GCM_TEXTURE_LINEAR_NEAREST: + case rsx::texture_minify_filter::linear_nearest: min = D3D12_FILTER_TYPE_LINEAR; mip = D3D12_FILTER_TYPE_POINT; return; - case CELL_GCM_TEXTURE_NEAREST_LINEAR: + case rsx::texture_minify_filter::nearest_linear: min = D3D12_FILTER_TYPE_POINT; mip = D3D12_FILTER_TYPE_LINEAR; return; - case CELL_GCM_TEXTURE_LINEAR_LINEAR: + case rsx::texture_minify_filter::linear_linear: min = D3D12_FILTER_TYPE_LINEAR; mip = D3D12_FILTER_TYPE_LINEAR; return; - case CELL_GCM_TEXTURE_CONVOLUTION_MIN: + case rsx::texture_minify_filter::convolution_min: min = D3D12_FILTER_TYPE_LINEAR; mip = D3D12_FILTER_TYPE_POINT; return; } - throw EXCEPTION("Invalid max filter (0x%x)", min_filter); + throw EXCEPTION("Invalid max filter"); } - D3D12_FILTER_TYPE get_mag_filter(u8 mag_filter) + D3D12_FILTER_TYPE get_mag_filter(rsx::texture_magnify_filter mag_filter) { switch (mag_filter) { - case CELL_GCM_TEXTURE_NEAREST: return D3D12_FILTER_TYPE_POINT; - case CELL_GCM_TEXTURE_LINEAR: return D3D12_FILTER_TYPE_LINEAR; - case CELL_GCM_TEXTURE_CONVOLUTION_MAG: return D3D12_FILTER_TYPE_LINEAR; + case rsx::texture_magnify_filter::nearest: return D3D12_FILTER_TYPE_POINT; + case rsx::texture_magnify_filter::linear: return D3D12_FILTER_TYPE_LINEAR; + case rsx::texture_magnify_filter::convolution_mag: return D3D12_FILTER_TYPE_LINEAR; } - throw EXCEPTION("Invalid mag filter (0x%x)", mag_filter); + throw EXCEPTION("Invalid mag filter"); } } -D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter) +D3D12_FILTER get_texture_filter(rsx::texture_minify_filter min_filter, rsx::texture_magnify_filter mag_filter) { D3D12_FILTER_TYPE min, mip; get_min_filter(min_filter, min, mip); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.h b/rpcs3/Emu/RSX/D3D12/D3D12Formats.h index 0eebbf541b..c507c46510 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.h @@ -51,7 +51,7 @@ D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(rsx::texture_wrap_mode wrap); /** * Convert minify and magnify filter to D3D12_FILTER */ -D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter); +D3D12_FILTER get_texture_filter(rsx::texture_minify_filter min_filter, rsx::texture_magnify_filter mag_filter); /** * Convert draw mode to D3D12_PRIMITIVE_TOPOLOGY diff --git a/rpcs3/Emu/RSX/GCM.cpp b/rpcs3/Emu/RSX/GCM.cpp index 57dc4d0e40..645ecd9106 100644 --- a/rpcs3/Emu/RSX/GCM.cpp +++ b/rpcs3/Emu/RSX/GCM.cpp @@ -896,6 +896,16 @@ enum CELL_GCM_TEXTURE_MAX_ANISO_10 = 5, CELL_GCM_TEXTURE_MAX_ANISO_12 = 6, CELL_GCM_TEXTURE_MAX_ANISO_16 = 7, + + // Texture Filter + CELL_GCM_TEXTURE_NEAREST = 1, + CELL_GCM_TEXTURE_LINEAR = 2, + CELL_GCM_TEXTURE_NEAREST_NEAREST = 3, + CELL_GCM_TEXTURE_LINEAR_NEAREST = 4, + CELL_GCM_TEXTURE_NEAREST_LINEAR = 5, + CELL_GCM_TEXTURE_LINEAR_LINEAR = 6, + CELL_GCM_TEXTURE_CONVOLUTION_MIN = 7, + CELL_GCM_TEXTURE_CONVOLUTION_MAG = 4, }; rsx::texture_wrap_mode rsx::to_texture_wrap_mode(u8 in) @@ -930,6 +940,33 @@ rsx::texture_max_anisotropy rsx::to_texture_max_anisotropy(u8 in) throw EXCEPTION("Unknow anisotropy max mode %x", in); } +rsx::texture_minify_filter rsx::to_texture_minify_filter(u8 in) +{ + switch (in) + { + case CELL_GCM_TEXTURE_NEAREST: return rsx::texture_minify_filter::nearest; + case CELL_GCM_TEXTURE_LINEAR: return rsx::texture_minify_filter::linear; + case CELL_GCM_TEXTURE_NEAREST_NEAREST: return rsx::texture_minify_filter::nearest_nearest; + case CELL_GCM_TEXTURE_LINEAR_NEAREST: return rsx::texture_minify_filter::linear_nearest; + case CELL_GCM_TEXTURE_NEAREST_LINEAR: return rsx::texture_minify_filter::nearest_linear; + case CELL_GCM_TEXTURE_LINEAR_LINEAR: return rsx::texture_minify_filter::linear_linear; + case CELL_GCM_TEXTURE_CONVOLUTION_MIN: return rsx::texture_minify_filter::linear_linear; + } + throw EXCEPTION("Unknow minify filter %x", in); +} + + +rsx::texture_magnify_filter rsx::to_texture_magnify_filter(u8 in) +{ + switch (in) + { + case CELL_GCM_TEXTURE_NEAREST: return rsx::texture_magnify_filter::nearest; + case CELL_GCM_TEXTURE_LINEAR: return rsx::texture_magnify_filter::linear; + case CELL_GCM_TEXTURE_CONVOLUTION_MAG: return rsx::texture_magnify_filter::convolution_mag; + } + throw EXCEPTION("Unknow magnify filter %x", in); +} + rsx::surface_target rsx::to_surface_target(u8 in) { switch (in) diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 4ed5c9ac4e..29362c2df2 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -190,6 +190,28 @@ namespace rsx }; texture_max_anisotropy to_texture_max_anisotropy(u8 in); + + enum class texture_minify_filter : u8 + { + nearest, ///< no filtering, mipmap base level + linear, ///< linear filtering, mipmap base level + nearest_nearest, ///< no filtering, closest mipmap level + linear_nearest, ///< linear filtering, closest mipmap level + nearest_linear, ///< no filtering, linear mix between closest mipmap levels + linear_linear, ///< linear filtering, linear mix between closest mipmap levels + convolution_min, ///< Unknow mode but looks close to linear_linear + }; + + texture_minify_filter to_texture_minify_filter(u8 in); + + enum class texture_magnify_filter : u8 + { + nearest, ///< no filtering + linear, ///< linear filtering + convolution_mag, ///< Unknow mode but looks close to linear + }; + + texture_magnify_filter to_texture_magnify_filter(u8 in); } enum @@ -377,16 +399,6 @@ enum CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_P = 1 << 30, CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_Q = 1 << 31, - // Texture Filter - CELL_GCM_TEXTURE_NEAREST = 1, - CELL_GCM_TEXTURE_LINEAR = 2, - CELL_GCM_TEXTURE_NEAREST_NEAREST = 3, - CELL_GCM_TEXTURE_LINEAR_NEAREST = 4, - CELL_GCM_TEXTURE_NEAREST_LINEAR = 5, - CELL_GCM_TEXTURE_LINEAR_LINEAR = 6, - CELL_GCM_TEXTURE_CONVOLUTION_MIN = 7, - CELL_GCM_TEXTURE_CONVOLUTION_MAG = 4, - CELL_GCM_COLOR_MASK_B = 1 << 0, CELL_GCM_COLOR_MASK_G = 1 << 8, CELL_GCM_COLOR_MASK_R = 1 << 16, diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp index 3f97a08bf1..f78b311422 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp +++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp @@ -157,26 +157,31 @@ namespace rsx { namespace gl { - static const int gl_tex_min_filter[] = + int gl_tex_min_filter(rsx::texture_minify_filter min_filter) { - GL_NEAREST, // unused - GL_NEAREST, - GL_LINEAR, - GL_NEAREST_MIPMAP_NEAREST, - GL_LINEAR_MIPMAP_NEAREST, - GL_NEAREST_MIPMAP_LINEAR, - GL_LINEAR_MIPMAP_LINEAR, - GL_NEAREST, // CELL_GCM_TEXTURE_CONVOLUTION_MIN - }; + switch (min_filter) + { + case rsx::texture_minify_filter::nearest: return GL_NEAREST; + case rsx::texture_minify_filter::linear: return GL_LINEAR; + case rsx::texture_minify_filter::nearest_nearest: return GL_NEAREST_MIPMAP_NEAREST; + case rsx::texture_minify_filter::linear_nearest: return GL_LINEAR_MIPMAP_NEAREST; + case rsx::texture_minify_filter::nearest_linear: return GL_NEAREST_MIPMAP_LINEAR; + case rsx::texture_minify_filter::linear_linear: return GL_LINEAR_MIPMAP_LINEAR; + case rsx::texture_minify_filter::convolution_min: return GL_LINEAR_MIPMAP_LINEAR; + } + throw EXCEPTION("Unknow min filter"); + } - static const int gl_tex_mag_filter[] = + int gl_tex_mag_filter(rsx::texture_magnify_filter mag_filter) { - GL_NEAREST, // unused - GL_NEAREST, - GL_LINEAR, - GL_NEAREST, // unused - GL_LINEAR // CELL_GCM_TEXTURE_CONVOLUTION_MAG - }; + switch (mag_filter) + { + case rsx::texture_magnify_filter::nearest: return GL_NEAREST; + case rsx::texture_magnify_filter::linear: return GL_LINEAR; + case rsx::texture_magnify_filter::convolution_mag: return GL_LINEAR; + } + throw EXCEPTION("Unknow mag filter"); + } static const int gl_tex_zfunc[] = { @@ -378,7 +383,7 @@ namespace rsx glTexParameteri(m_target, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); glTexParameteri(m_target, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); - int min_filter = gl_tex_min_filter[tex.min_filter()]; + int min_filter = gl_tex_min_filter(tex.min_filter()); if (min_filter != GL_LINEAR && min_filter != GL_NEAREST) { @@ -390,7 +395,7 @@ namespace rsx } glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, min_filter); - glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]); + glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter(tex.mag_filter())); glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso())); } diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 4262aac20c..e638feec05 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -156,14 +156,14 @@ namespace rsx return float(f16((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff)); } - u8 texture::min_filter() const + rsx::texture_minify_filter texture::min_filter() const { - return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7); + return rsx::to_texture_minify_filter((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7); } - u8 texture::mag_filter() const + rsx::texture_magnify_filter texture::mag_filter() const { - return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7); + return rsx::to_texture_magnify_filter((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7); } u8 texture::convolution_filter() const diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index 7518fb9d6c..724caad77a 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -50,8 +50,8 @@ namespace rsx // Filter float bias() const; - u8 min_filter() const; - u8 mag_filter() const; + rsx::texture_minify_filter min_filter() const; + rsx::texture_magnify_filter mag_filter() const; u8 convolution_filter() const; bool a_signed() const; bool r_signed() const; diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index ebd7ff42df..295a4efe44 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -39,28 +39,28 @@ VkFormat get_compatible_depth_surface_format(const gpu_formats_support &support, throw EXCEPTION("Invalid format (0x%x)", format); } -std::tuple get_min_filter_and_mip(u8 min_filter) +std::tuple get_min_filter_and_mip(rsx::texture_minify_filter min_filter) { switch (min_filter) { - case CELL_GCM_TEXTURE_NEAREST: return std::make_tuple(VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST); - case CELL_GCM_TEXTURE_LINEAR: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST); - case CELL_GCM_TEXTURE_NEAREST_NEAREST: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST); - case CELL_GCM_TEXTURE_LINEAR_NEAREST: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST); - case CELL_GCM_TEXTURE_NEAREST_LINEAR: return std::make_tuple(VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_LINEAR); - case CELL_GCM_TEXTURE_LINEAR_LINEAR: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_LINEAR); - case CELL_GCM_TEXTURE_CONVOLUTION_MIN: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_LINEAR); + case rsx::texture_minify_filter::nearest: return std::make_tuple(VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST); + case rsx::texture_minify_filter::linear: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST); + case rsx::texture_minify_filter::nearest_nearest: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST); + case rsx::texture_minify_filter::linear_nearest: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST); + case rsx::texture_minify_filter::nearest_linear: return std::make_tuple(VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_LINEAR); + case rsx::texture_minify_filter::linear_linear: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_LINEAR); + case rsx::texture_minify_filter::convolution_min: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_LINEAR); } - throw EXCEPTION("Invalid max filter (0x%x)", min_filter); + throw EXCEPTION("Invalid max filter"); } -VkFilter get_mag_filter(u8 mag_filter) +VkFilter get_mag_filter(rsx::texture_magnify_filter mag_filter) { switch (mag_filter) { - case CELL_GCM_TEXTURE_NEAREST: return VK_FILTER_NEAREST; - case CELL_GCM_TEXTURE_LINEAR: return VK_FILTER_LINEAR; - case CELL_GCM_TEXTURE_CONVOLUTION_MAG: return VK_FILTER_LINEAR; + case rsx::texture_magnify_filter::nearest: return VK_FILTER_NEAREST; + case rsx::texture_magnify_filter::linear: return VK_FILTER_LINEAR; + case rsx::texture_magnify_filter::convolution_mag: return VK_FILTER_LINEAR; } throw EXCEPTION("Invalid mag filter (0x%x)", mag_filter); } diff --git a/rpcs3/Emu/RSX/VK/VKFormats.h b/rpcs3/Emu/RSX/VK/VKFormats.h index 471467ece2..e970166e3f 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.h +++ b/rpcs3/Emu/RSX/VK/VKFormats.h @@ -13,8 +13,8 @@ namespace vk gpu_formats_support get_optimal_tiling_supported_formats(VkPhysicalDevice physical_device); VkFormat get_compatible_depth_surface_format(const gpu_formats_support &support, rsx::surface_depth_format format); - std::tuple get_min_filter_and_mip(u8 min_filter); - VkFilter get_mag_filter(u8 mag_filter); + std::tuple get_min_filter_and_mip(rsx::texture_minify_filter min_filter); + VkFilter get_mag_filter(rsx::texture_magnify_filter mag_filter); VkSamplerAddressMode vk_wrap_mode(rsx::texture_wrap_mode gcm_wrap); float max_aniso(rsx::texture_max_anisotropy gcm_aniso); VkComponentMapping get_component_mapping(u32 format, u8 swizzle_mask);