Просмотр исходного кода

fix sampler configuration, thanks to Marcos for his investigation

Rodolfo Bogado 7 лет назад
Родитель
Сommit
81a9c5fe6f

+ 38 - 17
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -735,9 +735,8 @@ void RasterizerOpenGL::SamplerInfo::Create() {
     glSamplerParameteri(sampler.handle, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
 }
 
-void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::FullTextureInfo& info) {
+void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) {
     const GLuint s = sampler.handle;
-    const Tegra::Texture::TSCEntry& config = info.tsc;
     if (mag_filter != config.mag_filter) {
         mag_filter = config.mag_filter;
         glSamplerParameteri(
@@ -779,28 +778,50 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::FullTex
                             MaxwellToGL::DepthCompareFunc(depth_compare_func));
     }
 
-    const GLvec4 new_border_color = {{config.border_color_r, config.border_color_g,
-                                      config.border_color_b, config.border_color_a}};
+    GLvec4 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;
         glSamplerParameterfv(s, GL_TEXTURE_BORDER_COLOR, border_color.data());
     }
 
-    if (info.tic.use_header_opt_control == 0) {
+    const float anisotropic_max = static_cast<float>(1 << config.max_anisotropy.Value());
+    if (anisotropic_max != max_anisotropic) {
+        max_anisotropic = anisotropic_max;
         if (GLAD_GL_ARB_texture_filter_anisotropic) {
-            glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY,
-                                static_cast<float>(1 << info.tic.max_anisotropy.Value()));
+            glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropic);
         } else if (GLAD_GL_EXT_texture_filter_anisotropic) {
-            glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY_EXT,
-                                static_cast<float>(1 << info.tic.max_anisotropy.Value()));
+            glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropic);
         }
-        glSamplerParameterf(s, GL_TEXTURE_MIN_LOD,
-                            static_cast<float>(info.tic.res_min_mip_level.Value()));
-        glSamplerParameterf(s, GL_TEXTURE_MAX_LOD,
-                            static_cast<float>(info.tic.res_max_mip_level.Value() == 0
-                                                   ? 16
-                                                   : info.tic.res_max_mip_level.Value()));
-        glSamplerParameterf(s, GL_TEXTURE_LOD_BIAS, info.tic.mip_lod_bias.Value() / 256.f);
+    }
+    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 (lod_max != max_lod) {
+        max_lod = lod_max;
+        glSamplerParameterf(s, GL_TEXTURE_MAX_LOD, max_lod);
+    }
+    const u32 bias = config.mip_lod_bias.Value();
+    // Sign extend the 13-bit value.
+    const u32 mask = 1U << (13 - 1);
+    const float bias_lod = static_cast<s32>((bias ^ mask) - mask) / 256.f;
+    if (lod_bias != bias_lod) {
+        lod_bias = bias_lod;
+        glSamplerParameterf(s, GL_TEXTURE_LOD_BIAS, lod_bias);
     }
 }
 
@@ -899,7 +920,7 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
             continue;
         }
 
-        texture_samplers[current_bindpoint].SyncWithConfig(texture);
+        texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc);
         Surface surface = res_cache.GetTextureSurface(texture, entry);
         if (surface != nullptr) {
             state.texture_units[current_bindpoint].texture = surface->Texture().handle;

+ 5 - 1
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -88,7 +88,7 @@ private:
         /// SamplerInfo struct.
         void Create();
         /// Syncs the sampler object with the config, updating any necessary state.
-        void SyncWithConfig(const Tegra::Texture::FullTextureInfo& info);
+        void SyncWithConfig(const Tegra::Texture::TSCEntry& info);
 
     private:
         Tegra::Texture::TextureFilter mag_filter;
@@ -100,6 +100,10 @@ private:
         bool uses_depth_compare;
         Tegra::Texture::DepthCompareFunc depth_compare_func;
         GLvec4 border_color;
+        float min_lod;
+        float max_lod;
+        float lod_bias;
+        float max_anisotropic;
     };
 
     /**

+ 14 - 1
src/video_core/textures/texture.h

@@ -190,6 +190,7 @@ struct TICEntry {
     union {
         BitField<0, 4, u32> res_min_mip_level;
         BitField<4, 4, u32> res_max_mip_level;
+        BitField<12, 12, u32> min_lod_clamp;
     };
 
     GPUVAddr Address() const {
@@ -284,13 +285,25 @@ struct TSCEntry {
         BitField<6, 3, WrapMode> wrap_p;
         BitField<9, 1, u32> depth_compare_enabled;
         BitField<10, 3, DepthCompareFunc> depth_compare_func;
+        BitField<13, 1, u32> srgb_conversion;
+        BitField<20, 3, u32> max_anisotropy;
     };
     union {
         BitField<0, 2, TextureFilter> mag_filter;
         BitField<4, 2, TextureFilter> min_filter;
         BitField<6, 2, TextureMipmapFilter> mip_filter;
+        BitField<9, 1, u32> cubemap_interface_filtering;
+        BitField<12, 13, u32> mip_lod_bias;
+    };
+    union {
+        BitField<0, 12, u32> min_lod_clamp;
+        BitField<12, 12, u32> max_lod_clamp;
+        BitField<24, 8, u32> srgb_border_color_r;
+    };
+    union {
+        BitField<12, 8, u32> srgb_border_color_g;
+        BitField<20, 8, u32> srgb_border_color_b;
     };
-    INSERT_PADDING_BYTES(8);
     float border_color_r;
     float border_color_g;
     float border_color_b;