diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_texture.h | 8 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_backend.hh | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_extensions.cc | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.cc | 16 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_backend.hh | 14 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_state.cc | 8 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_texture.cc | 73 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_texture.hh | 7 |
8 files changed, 106 insertions, 24 deletions
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index e56866c5259..667fca776ad 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -66,11 +66,7 @@ ENUM_OPERATORS(eGPUSamplerState) extern "C" { #endif -#define GPU_SAMPLER_DEFAULT GPU_SAMPLER_FILTER -#define GPU_SAMPLER_REPEAT (GPU_SAMPLER_REPEAT_S | GPU_SAMPLER_REPEAT_T | GPU_SAMPLER_REPEAT_R) - -void GPU_samplers_init(void); -void GPU_samplers_free(void); +void GPU_samplers_update(void); /* GPU Texture * - always returns unsigned char RGBA textures @@ -294,8 +290,6 @@ int GPU_texture_opengl_bindcode(const GPUTexture *tex); void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size); -void GPU_sampler_icon_bind(int unit); - #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh index 06aff94dffe..330c7d59b6d 100644 --- a/source/blender/gpu/intern/gpu_backend.hh +++ b/source/blender/gpu/intern/gpu_backend.hh @@ -43,6 +43,8 @@ class GPUBackend { static GPUBackend *get(void); + virtual void samplers_update(void) = 0; + virtual GPUContext *context_alloc(void *ghost_window) = 0; virtual Batch *batch_alloc(void) = 0; diff --git a/source/blender/gpu/intern/gpu_extensions.cc b/source/blender/gpu/intern/gpu_extensions.cc index 6fe08d81cda..b473e719211 100644 --- a/source/blender/gpu/intern/gpu_extensions.cc +++ b/source/blender/gpu/intern/gpu_extensions.cc @@ -386,13 +386,11 @@ void gpu_extensions_init(void) } GPU_invalid_tex_init(); - GPU_samplers_init(); } void gpu_extensions_exit(void) { GPU_invalid_tex_free(); - GPU_samplers_free(); } bool GPU_mem_stats_supported(void) diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index 9d431ef4648..d75dc9b728a 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -482,6 +482,7 @@ void GPU_texture_bind_ex(GPUTexture *tex_, const bool UNUSED(set_number)) { Texture *tex = reinterpret_cast<Texture *>(tex_); + state = (state >= GPU_SAMPLER_MAX) ? tex->sampler_state : state; GPU_context_active_get()->state_manager->texture_bind(tex, state, unit); } @@ -717,19 +718,10 @@ void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *r_size) * Override texture sampler state for one sampler unit only. * \{ */ -void GPU_samplers_init(void) +/* Update user defined sampler states. */ +void GPU_samplers_update(void) { - /* TODO(fclem) port samplers to GLTextures. */ -} - -void GPU_sampler_icon_bind(int UNUSED(unit)) -{ - /* TODO(fclem) port samplers to GLTextures. */ -} - -void GPU_samplers_free(void) -{ - /* TODO(fclem) port samplers to GLTextures. */ + GPUBackend::get()->samplers_update(); } /** \} */ diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index 6029ff9e309..f769d9c1cfe 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -43,11 +43,25 @@ class GLBackend : public GPUBackend { GLSharedOrphanLists shared_orphan_list_; public: + GLBackend() + { + GLTexture::samplers_init(); + } + ~GLBackend() + { + GLTexture::samplers_free(); + } + static GLBackend *get(void) { return static_cast<GLBackend *>(GPUBackend::get()); } + void samplers_update(void) override + { + GLTexture::samplers_update(); + }; + GPUContext *context_alloc(void *ghost_window) { return new GLContext(ghost_window, shared_orphan_list_); diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc index 1fd39cf80eb..6bb7e41252c 100644 --- a/source/blender/gpu/opengl/gl_state.cc +++ b/source/blender/gpu/opengl/gl_state.cc @@ -427,13 +427,13 @@ void GLStateManager::set_blend(const eGPUBlend value) /** \name Texture state managment * \{ */ -void GLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler, int unit) +void GLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler_type, int unit) { BLI_assert(unit < GPU_max_textures()); GLTexture *tex = static_cast<GLTexture *>(tex_); targets_[unit] = tex->target_; textures_[unit] = tex->tex_id_; - samplers_[unit] = sampler; + samplers_[unit] = GLTexture::samplers_[sampler_type]; tex->is_bound_ = true; dirty_texture_binds_ |= 1 << unit; } @@ -462,6 +462,7 @@ void GLStateManager::texture_unbind(Texture *tex_) for (int i = 0; i < ARRAY_SIZE(textures_); i++) { if (textures_[i] == tex_id) { textures_[i] = 0; + samplers_[i] = 0; dirty_texture_binds_ |= 1 << i; } } @@ -473,6 +474,7 @@ void GLStateManager::texture_unbind_all(void) for (int i = 0; i < ARRAY_SIZE(textures_); i++) { if (textures_[i] != 0) { textures_[i] = 0; + samplers_[i] = 0; dirty_texture_binds_ |= 1 << i; } } @@ -494,7 +496,7 @@ void GLStateManager::texture_bind_apply(void) if (dirty_bind & 1) { glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(targets_[unit], textures_[unit]); - // glBindSampler(unit, samplers_[unit]); + glBindSampler(unit, samplers_[unit]); } } dirty_texture_binds_ = 0; diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 7c72dc6a5c3..b9a7347c8ed 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -23,6 +23,8 @@ #include "BKE_global.h" +#include "DNA_userdef_types.h" + #include "GPU_extensions.h" #include "GPU_framebuffer.h" @@ -424,6 +426,77 @@ struct GPUFrameBuffer *GLTexture::framebuffer_get(void) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Sampler objects + * \{ */ + +GLuint GLTexture::samplers_[GPU_SAMPLER_MAX] = {0}; + +void GLTexture::samplers_init(void) +{ + glGenSamplers(GPU_SAMPLER_MAX, samplers_); + for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) { + eGPUSamplerState state = static_cast<eGPUSamplerState>(i); + GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE; + GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type; + GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type; + GLenum wrap_r = (state & GPU_SAMPLER_REPEAT_R) ? GL_REPEAT : clamp_type; + GLenum mag_filter = (state & GPU_SAMPLER_FILTER) ? GL_LINEAR : GL_NEAREST; + GLenum min_filter = (state & GPU_SAMPLER_FILTER) ? + ((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) : + ((state & GPU_SAMPLER_MIPMAP) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST); + GLenum compare_mode = (state & GPU_SAMPLER_COMPARE) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE; + + glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_S, wrap_s); + glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_T, wrap_t); + glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_R, wrap_r); + glSamplerParameteri(samplers_[i], GL_TEXTURE_MIN_FILTER, min_filter); + glSamplerParameteri(samplers_[i], GL_TEXTURE_MAG_FILTER, mag_filter); + glSamplerParameteri(samplers_[i], GL_TEXTURE_COMPARE_MODE, compare_mode); + glSamplerParameteri(samplers_[i], GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + + /** Other states are left to default: + * - GL_TEXTURE_BORDER_COLOR is {0, 0, 0, 0}. + * - GL_TEXTURE_MIN_LOD is -1000. + * - GL_TEXTURE_MAX_LOD is 1000. + * - GL_TEXTURE_LOD_BIAS is 0.0f. + **/ + } + samplers_update(); + + /* Custom sampler for icons. */ + GLuint icon_sampler = samplers_[GPU_SAMPLER_ICON]; + glSamplerParameteri(icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameterf(icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f); +} + +void GLTexture::samplers_update(void) +{ + if (!GLEW_EXT_texture_filter_anisotropic) { + return; + } + + float max_anisotropy = 1.0f; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy); + + float aniso_filter = max_ff(max_anisotropy, U.anisotropic_filter); + + for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) { + eGPUSamplerState state = static_cast<eGPUSamplerState>(i); + if (state & GPU_SAMPLER_MIPMAP) { + glSamplerParameterf(samplers_[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso_filter); + } + } +} + +void GLTexture::samplers_free(void) +{ + glDeleteSamplers(GPU_SAMPLER_MAX, samplers_); +} + +/** \} */ + /* TODO(fclem) Legacy. Should be removed at some point. */ uint GLTexture::gl_bindcode_get(void) const { diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh index 0e054d7996a..36da89dad8e 100644 --- a/source/blender/gpu/opengl/gl_texture.hh +++ b/source/blender/gpu/opengl/gl_texture.hh @@ -58,6 +58,9 @@ class GLTexture : public Texture { friend class GLStateManager; private: + /** All samplers states. */ + static GLuint samplers_[GPU_SAMPLER_MAX]; + /** Target to bind the texture to (GL_TEXTURE_1D, GL_TEXTURE_2D, etc...)*/ GLenum target_ = -1; /** opengl identifier for texture. */ @@ -85,6 +88,10 @@ class GLTexture : public Texture { /* TODO(fclem) Legacy. Should be removed at some point. */ uint gl_bindcode_get(void) const override; + static void samplers_init(void); + static void samplers_free(void); + static void samplers_update(void); + protected: bool init_internal(void) override; bool init_internal(GPUVertBuf *vbo) override; |