summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_rasterizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index b556ea65b..0260a28ce 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -68,6 +68,12 @@ void RasterizerOpenGL::InitObjects() {
uniform_tev_cfg.updates_combiner_buffer_color_alpha = glGetUniformLocation(shader.handle, (tev_ref_str + ".updates_combiner_buffer_color_alpha").c_str());
}
+ // Create sampler objects
+ for (int i = 0; i < texture_samplers.size(); ++i) {
+ texture_samplers[i].Create();
+ state.texture_units[i].sampler = texture_samplers[i].sampler.handle;
+ }
+
// Generate VBO and VAO
vertex_buffer.Create();
vertex_array.Create();
@@ -445,6 +451,45 @@ void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) {
res_cache.NotifyFlush(addr, size);
}
+void RasterizerOpenGL::SamplerInfo::Create() {
+ sampler.Create();
+ mag_filter = min_filter = TextureConfig::Linear;
+ wrap_s = wrap_t = TextureConfig::Repeat;
+ border_color = 0;
+
+ glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // default is GL_LINEAR_MIPMAP_LINEAR
+ // Other attributes have correct defaults
+}
+
+void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Pica::Regs::TextureConfig& config) {
+ GLuint s = sampler.handle;
+
+ if (mag_filter != config.mag_filter) {
+ mag_filter = config.mag_filter;
+ glSamplerParameteri(s, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(mag_filter));
+ }
+ if (min_filter != config.min_filter) {
+ min_filter = config.min_filter;
+ glSamplerParameteri(s, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(min_filter));
+ }
+
+ if (wrap_s != config.wrap_s) {
+ wrap_s = config.wrap_s;
+ glSamplerParameteri(s, GL_TEXTURE_WRAP_S, PicaToGL::WrapMode(wrap_s));
+ }
+ if (wrap_t != config.wrap_t) {
+ wrap_t = config.wrap_t;
+ glSamplerParameteri(s, GL_TEXTURE_WRAP_T, PicaToGL::WrapMode(wrap_t));
+ }
+
+ if (wrap_s == TextureConfig::ClampToBorder || wrap_t == TextureConfig::ClampToBorder) {
+ if (border_color != config.border_color.raw) {
+ auto gl_color = PicaToGL::ColorRGBA8(border_color);
+ glSamplerParameterfv(s, GL_TEXTURE_BORDER_COLOR, gl_color.data());
+ }
+ }
+}
+
void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height) {
GLint internal_format;
@@ -772,6 +817,7 @@ void RasterizerOpenGL::SyncDrawState() {
const auto& texture = pica_textures[texture_index];
if (texture.enabled) {
+ texture_samplers[texture_index].SyncWithConfig(texture.config);
res_cache.LoadAndBindTexture(state, texture_index, texture);
} else {
state.texture_units[texture_index].texture_2d = 0;