rsx/common: Use typed class for texture filters.

This commit is contained in:
Vincent Lejeune 2016-03-30 20:00:09 +02:00
parent d971c4e0f6
commit 73233fd347
9 changed files with 120 additions and 66 deletions

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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()));
}

View File

@ -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

View File

@ -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;

View File

@ -39,28 +39,28 @@ VkFormat get_compatible_depth_surface_format(const gpu_formats_support &support,
throw EXCEPTION("Invalid format (0x%x)", format);
}
std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(u8 min_filter)
std::tuple<VkFilter, VkSamplerMipmapMode> 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);
}

View File

@ -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<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(u8 min_filter);
VkFilter get_mag_filter(u8 mag_filter);
std::tuple<VkFilter, VkSamplerMipmapMode> 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);