Merge pull request #2215 from ReinUsesLisp/samplers

gl_rasterizer: Encapsulate sampler queries into methods
master
bunnei 2019-03-12 13:10:53 +07:00 committed by GitHub
commit 2ad44a453f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 64 deletions

@ -804,104 +804,87 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
void RasterizerOpenGL::SamplerInfo::Create() { void RasterizerOpenGL::SamplerInfo::Create() {
sampler.Create(); sampler.Create();
mag_filter = min_filter = Tegra::Texture::TextureFilter::Linear; mag_filter = Tegra::Texture::TextureFilter::Linear;
wrap_u = wrap_v = wrap_p = Tegra::Texture::WrapMode::Wrap; min_filter = Tegra::Texture::TextureFilter::Linear;
uses_depth_compare = false; wrap_u = Tegra::Texture::WrapMode::Wrap;
wrap_v = Tegra::Texture::WrapMode::Wrap;
wrap_p = Tegra::Texture::WrapMode::Wrap;
use_depth_compare = false;
depth_compare_func = Tegra::Texture::DepthCompareFunc::Never; depth_compare_func = Tegra::Texture::DepthCompareFunc::Never;
// default is GL_LINEAR_MIPMAP_LINEAR // OpenGL's default is GL_LINEAR_MIPMAP_LINEAR
glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Other attributes have correct defaults
glSamplerParameteri(sampler.handle, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); glSamplerParameteri(sampler.handle, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
// Other attributes have correct defaults
} }
void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) { void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) {
const GLuint s = sampler.handle; const GLuint sampler_id = sampler.handle;
if (mag_filter != config.mag_filter) { if (mag_filter != config.mag_filter) {
mag_filter = config.mag_filter; mag_filter = config.mag_filter;
glSamplerParameteri( glSamplerParameteri(
s, GL_TEXTURE_MAG_FILTER, sampler_id, GL_TEXTURE_MAG_FILTER,
MaxwellToGL::TextureFilterMode(mag_filter, Tegra::Texture::TextureMipmapFilter::None)); MaxwellToGL::TextureFilterMode(mag_filter, Tegra::Texture::TextureMipmapFilter::None));
} }
if (min_filter != config.min_filter || mip_filter != config.mip_filter) { if (min_filter != config.min_filter || mipmap_filter != config.mipmap_filter) {
min_filter = config.min_filter; min_filter = config.min_filter;
mip_filter = config.mip_filter; mipmap_filter = config.mipmap_filter;
glSamplerParameteri(s, GL_TEXTURE_MIN_FILTER, glSamplerParameteri(sampler_id, GL_TEXTURE_MIN_FILTER,
MaxwellToGL::TextureFilterMode(min_filter, mip_filter)); MaxwellToGL::TextureFilterMode(min_filter, mipmap_filter));
} }
if (wrap_u != config.wrap_u) { if (wrap_u != config.wrap_u) {
wrap_u = config.wrap_u; wrap_u = config.wrap_u;
glSamplerParameteri(s, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(wrap_u)); glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(wrap_u));
} }
if (wrap_v != config.wrap_v) { if (wrap_v != config.wrap_v) {
wrap_v = config.wrap_v; wrap_v = config.wrap_v;
glSamplerParameteri(s, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(wrap_v)); glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(wrap_v));
} }
if (wrap_p != config.wrap_p) { if (wrap_p != config.wrap_p) {
wrap_p = config.wrap_p; wrap_p = config.wrap_p;
glSamplerParameteri(s, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(wrap_p)); glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(wrap_p));
} }
if (uses_depth_compare != (config.depth_compare_enabled == 1)) { if (const bool enabled = config.depth_compare_enabled == 1; use_depth_compare != enabled) {
uses_depth_compare = (config.depth_compare_enabled == 1); use_depth_compare = enabled;
if (uses_depth_compare) { glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_MODE,
glSamplerParameteri(s, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); use_depth_compare ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE);
} else {
glSamplerParameteri(s, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
} }
if (depth_compare_func != config.depth_compare_func) { if (depth_compare_func != config.depth_compare_func) {
depth_compare_func = config.depth_compare_func; depth_compare_func = config.depth_compare_func;
glSamplerParameteri(s, GL_TEXTURE_COMPARE_FUNC, glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_FUNC,
MaxwellToGL::DepthCompareFunc(depth_compare_func)); MaxwellToGL::DepthCompareFunc(depth_compare_func));
} }
GLvec4 new_border_color; if (const auto new_border_color = config.GetBorderColor(); border_color != new_border_color) {
if (config.srgb_conversion) {
new_border_color[0] = config.srgb_border_color_r / 255.0f;
new_border_color[1] = config.srgb_border_color_g / 255.0f;
new_border_color[2] = config.srgb_border_color_g / 255.0f;
} else {
new_border_color[0] = config.border_color_r;
new_border_color[1] = config.border_color_g;
new_border_color[2] = config.border_color_b;
}
new_border_color[3] = config.border_color_a;
if (border_color != new_border_color) {
border_color = new_border_color; border_color = new_border_color;
glSamplerParameterfv(s, GL_TEXTURE_BORDER_COLOR, border_color.data()); glSamplerParameterfv(sampler_id, GL_TEXTURE_BORDER_COLOR, border_color.data());
} }
const float anisotropic_max = static_cast<float>(1 << config.max_anisotropy.Value()); if (const float anisotropic = config.GetMaxAnisotropy(); max_anisotropic != anisotropic) {
if (anisotropic_max != max_anisotropic) { max_anisotropic = anisotropic;
max_anisotropic = anisotropic_max;
if (GLAD_GL_ARB_texture_filter_anisotropic) { if (GLAD_GL_ARB_texture_filter_anisotropic) {
glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropic); glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropic);
} else if (GLAD_GL_EXT_texture_filter_anisotropic) { } else if (GLAD_GL_EXT_texture_filter_anisotropic) {
glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropic); glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropic);
} }
} }
const float lod_min = static_cast<float>(config.min_lod_clamp.Value()) / 256.0f;
if (lod_min != min_lod) {
min_lod = lod_min;
glSamplerParameterf(s, GL_TEXTURE_MIN_LOD, min_lod);
}
const float lod_max = static_cast<float>(config.max_lod_clamp.Value()) / 256.0f; if (const float min = config.GetMinLod(); min_lod != min) {
if (lod_max != max_lod) { min_lod = min;
max_lod = lod_max; glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, min_lod);
glSamplerParameterf(s, GL_TEXTURE_MAX_LOD, max_lod);
} }
const u32 bias = config.mip_lod_bias.Value(); if (const float max = config.GetMaxLod(); max_lod != max) {
// Sign extend the 13-bit value. max_lod = max;
constexpr u32 mask = 1U << (13 - 1); glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, max_lod);
const float bias_lod = static_cast<s32>((bias ^ mask) - mask) / 256.f; }
if (lod_bias != bias_lod) {
lod_bias = bias_lod; if (const float bias = config.GetLodBias(); lod_bias != bias) {
glSamplerParameterf(s, GL_TEXTURE_LOD_BIAS, lod_bias); lod_bias = bias;
glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, lod_bias);
} }
} }

@ -94,11 +94,12 @@ private:
private: private:
Tegra::Texture::TextureFilter mag_filter = Tegra::Texture::TextureFilter::Nearest; Tegra::Texture::TextureFilter mag_filter = Tegra::Texture::TextureFilter::Nearest;
Tegra::Texture::TextureFilter min_filter = Tegra::Texture::TextureFilter::Nearest; Tegra::Texture::TextureFilter min_filter = Tegra::Texture::TextureFilter::Nearest;
Tegra::Texture::TextureMipmapFilter mip_filter = Tegra::Texture::TextureMipmapFilter::None; Tegra::Texture::TextureMipmapFilter mipmap_filter =
Tegra::Texture::TextureMipmapFilter::None;
Tegra::Texture::WrapMode wrap_u = Tegra::Texture::WrapMode::ClampToEdge; Tegra::Texture::WrapMode wrap_u = Tegra::Texture::WrapMode::ClampToEdge;
Tegra::Texture::WrapMode wrap_v = Tegra::Texture::WrapMode::ClampToEdge; Tegra::Texture::WrapMode wrap_v = Tegra::Texture::WrapMode::ClampToEdge;
Tegra::Texture::WrapMode wrap_p = Tegra::Texture::WrapMode::ClampToEdge; Tegra::Texture::WrapMode wrap_p = Tegra::Texture::WrapMode::ClampToEdge;
bool uses_depth_compare = false; bool use_depth_compare = false;
Tegra::Texture::DepthCompareFunc depth_compare_func = Tegra::Texture::DepthCompareFunc depth_compare_func =
Tegra::Texture::DepthCompareFunc::Always; Tegra::Texture::DepthCompareFunc::Always;
GLvec4 border_color = {}; GLvec4 border_color = {};

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <array>
#include "common/assert.h" #include "common/assert.h"
#include "common/bit_field.h" #include "common/bit_field.h"
#include "common/common_funcs.h" #include "common/common_funcs.h"
@ -293,7 +294,7 @@ struct TSCEntry {
union { union {
BitField<0, 2, TextureFilter> mag_filter; BitField<0, 2, TextureFilter> mag_filter;
BitField<4, 2, TextureFilter> min_filter; BitField<4, 2, TextureFilter> min_filter;
BitField<6, 2, TextureMipmapFilter> mip_filter; BitField<6, 2, TextureMipmapFilter> mipmap_filter;
BitField<9, 1, u32> cubemap_interface_filtering; BitField<9, 1, u32> cubemap_interface_filtering;
BitField<12, 13, u32> mip_lod_bias; BitField<12, 13, u32> mip_lod_bias;
}; };
@ -306,10 +307,33 @@ struct TSCEntry {
BitField<12, 8, u32> srgb_border_color_g; BitField<12, 8, u32> srgb_border_color_g;
BitField<20, 8, u32> srgb_border_color_b; BitField<20, 8, u32> srgb_border_color_b;
}; };
float border_color_r; std::array<f32, 4> border_color;
float border_color_g;
float border_color_b; float GetMaxAnisotropy() const {
float border_color_a; return static_cast<float>(1U << max_anisotropy);
}
float GetMinLod() const {
return static_cast<float>(min_lod_clamp) / 256.0f;
}
float GetMaxLod() const {
return static_cast<float>(max_lod_clamp) / 256.0f;
}
float GetLodBias() const {
// Sign extend the 13-bit value.
constexpr u32 mask = 1U << (13 - 1);
return static_cast<float>((mip_lod_bias ^ mask) - mask) / 256.0f;
}
std::array<float, 4> GetBorderColor() const {
if (srgb_conversion) {
return {srgb_border_color_r / 255.0f, srgb_border_color_g / 255.0f,
srgb_border_color_b / 255.0f, border_color[3]};
}
return border_color;
}
}; };
static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size");