diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-09-05 18:29:51 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-09-05 18:49:14 +0300 |
commit | c766d9b9dc5661693a58e01a3637f15197c2fe59 (patch) | |
tree | 6905f0fc085af0eff5cfdf74d87c4ebed412e741 /source/blender/gpu/opengl/gl_state.cc | |
parent | db21c12abedd7606a3aaf50f70e506a24d9f0e7a (diff) |
GPUTexture: GL Backend Isolation
This is a massive cleanup needed for vulkan support T68990. It provides:
- More meaningful enums with conversion functions.
- Less hacky supports of arrays and cubemaps (all considered layered).
- More inline with the stateless design of vulkan and modern GL.
- Methods Fallbacks are using framebuffer functions that are wrapped
instead of implementing inside the texture module.
What is not in there:
- API change.
- Samplers support (breaks a few effects).
# Conflicts:
# source/blender/gpu/GPU_texture.h
Diffstat (limited to 'source/blender/gpu/opengl/gl_state.cc')
-rw-r--r-- | source/blender/gpu/opengl/gl_state.cc | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc index 8f01ff13486..1fd39cf80eb 100644 --- a/source/blender/gpu/opengl/gl_state.cc +++ b/source/blender/gpu/opengl/gl_state.cc @@ -28,9 +28,11 @@ #include "gl_context.hh" #include "gl_framebuffer.hh" +#include "gl_texture.hh" + #include "gl_state.hh" -using namespace blender::gpu; +namespace blender::gpu { /* -------------------------------------------------------------------- */ /** \name GLStateManager @@ -69,6 +71,7 @@ void GLStateManager::apply_state(void) { this->set_state(this->state); this->set_mutable_state(this->mutable_state); + this->texture_bind_apply(); active_fb->apply_state(); }; @@ -419,3 +422,85 @@ void GLStateManager::set_blend(const eGPUBlend value) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Texture state managment + * \{ */ + +void GLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler, 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; + tex->is_bound_ = true; + dirty_texture_binds_ |= 1 << unit; +} + +/* Bind the texture to slot 0 for editing purpose. Used by legacy pipeline. */ +void GLStateManager::texture_bind_temp(GLTexture *tex) +{ + // BLI_assert(!GLEW_ARB_direct_state_access); + glActiveTexture(GL_TEXTURE0); + glBindTexture(tex->target_, tex->tex_id_); + /* Will reset the first texture that was originaly bound to slot 0 back before drawing. */ + dirty_texture_binds_ |= 1; + /* NOTE: This might leave this texture attached to this target even after update. + * In practice it is not causing problems as we have incorrect binding detection + * at higher level. */ +} + +void GLStateManager::texture_unbind(Texture *tex_) +{ + GLTexture *tex = static_cast<GLTexture *>(tex_); + if (!tex->is_bound_) { + return; + } + + GLuint tex_id = tex->tex_id_; + for (int i = 0; i < ARRAY_SIZE(textures_); i++) { + if (textures_[i] == tex_id) { + textures_[i] = 0; + dirty_texture_binds_ |= 1 << i; + } + } + tex->is_bound_ = false; +} + +void GLStateManager::texture_unbind_all(void) +{ + for (int i = 0; i < ARRAY_SIZE(textures_); i++) { + if (textures_[i] != 0) { + textures_[i] = 0; + dirty_texture_binds_ |= 1 << i; + } + } + this->texture_bind_apply(); +} + +void GLStateManager::texture_bind_apply(void) +{ + if (dirty_texture_binds_ == 0) { + return; + } + + if (false) { + /* TODO multibind */ + } + else { + uint64_t dirty_bind = dirty_texture_binds_; + for (int unit = 0; dirty_bind != 0; dirty_bind >>= 1, unit++) { + if (dirty_bind & 1) { + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(targets_[unit], textures_[unit]); + // glBindSampler(unit, samplers_[unit]); + } + } + dirty_texture_binds_ = 0; + } +} + +/** \} */ + +} // namespace blender::gpu
\ No newline at end of file |