GPUTexture: Add support for samplers

This just add back the support.
This commit also includes a bit of cleanup.

# Conflicts:
#	source/blender/gpu/GPU_texture.h
This commit is contained in:
2020-09-05 17:31:53 +02:00
parent c766d9b9dc
commit 31c77a14af
10 changed files with 109 additions and 30 deletions

View File

@@ -1566,8 +1566,7 @@ static void icon_draw_cache_texture_flush_ex(GPUTexture *texture,
const int img_binding = GPU_shader_get_texture_binding(shader, "image"); const int img_binding = GPU_shader_get_texture_binding(shader, "image");
const int data_loc = GPU_shader_get_uniform(shader, "calls_data"); const int data_loc = GPU_shader_get_uniform(shader, "calls_data");
GPU_texture_bind(texture, img_binding); GPU_texture_bind_ex(texture, GPU_SAMPLER_ICON, img_binding, false);
GPU_sampler_icon_bind(img_binding);
GPU_shader_uniform_vector( GPU_shader_uniform_vector(
shader, data_loc, 4, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache); shader, data_loc, 4, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache);
@@ -1718,8 +1717,7 @@ static void icon_draw_texture(float x,
GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, (float[4]){x1, y1, x2, y2}); GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, (float[4]){x1, y1, x2, y2});
GPU_shader_uniform_vector(shader, rect_geom_loc, 4, 1, (float[4]){x, y, x + w, y + h}); GPU_shader_uniform_vector(shader, rect_geom_loc, 4, 1, (float[4]){x, y, x + w, y + h});
GPU_texture_bind(texture, img_binding); GPU_texture_bind_ex(texture, GPU_SAMPLER_ICON, img_binding, false);
GPU_sampler_icon_bind(img_binding);
GPUBatch *quad = GPU_batch_preset_quad(); GPUBatch *quad = GPU_batch_preset_quad();
GPU_batch_set_shader(quad, shader); GPU_batch_set_shader(quad, shader);

View File

@@ -66,11 +66,7 @@ ENUM_OPERATORS(eGPUSamplerState)
extern "C" { extern "C" {
#endif #endif
#define GPU_SAMPLER_DEFAULT GPU_SAMPLER_FILTER void GPU_samplers_update(void);
#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);
/* GPU Texture /* GPU Texture
* - always returns unsigned char RGBA textures * - 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_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size);
void GPU_sampler_icon_bind(int unit);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -43,6 +43,8 @@ class GPUBackend {
static GPUBackend *get(void); static GPUBackend *get(void);
virtual void samplers_update(void) = 0;
virtual GPUContext *context_alloc(void *ghost_window) = 0; virtual GPUContext *context_alloc(void *ghost_window) = 0;
virtual Batch *batch_alloc(void) = 0; virtual Batch *batch_alloc(void) = 0;

View File

@@ -386,13 +386,11 @@ void gpu_extensions_init(void)
} }
GPU_invalid_tex_init(); GPU_invalid_tex_init();
GPU_samplers_init();
} }
void gpu_extensions_exit(void) void gpu_extensions_exit(void)
{ {
GPU_invalid_tex_free(); GPU_invalid_tex_free();
GPU_samplers_free();
} }
bool GPU_mem_stats_supported(void) bool GPU_mem_stats_supported(void)

View File

@@ -482,6 +482,7 @@ void GPU_texture_bind_ex(GPUTexture *tex_,
const bool UNUSED(set_number)) const bool UNUSED(set_number))
{ {
Texture *tex = reinterpret_cast<Texture *>(tex_); 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); 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. * 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. */ GPUBackend::get()->samplers_update();
}
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. */
} }
/** \} */ /** \} */

View File

@@ -43,11 +43,25 @@ class GLBackend : public GPUBackend {
GLSharedOrphanLists shared_orphan_list_; GLSharedOrphanLists shared_orphan_list_;
public: public:
GLBackend()
{
GLTexture::samplers_init();
}
~GLBackend()
{
GLTexture::samplers_free();
}
static GLBackend *get(void) static GLBackend *get(void)
{ {
return static_cast<GLBackend *>(GPUBackend::get()); return static_cast<GLBackend *>(GPUBackend::get());
} }
void samplers_update(void) override
{
GLTexture::samplers_update();
};
GPUContext *context_alloc(void *ghost_window) GPUContext *context_alloc(void *ghost_window)
{ {
return new GLContext(ghost_window, shared_orphan_list_); return new GLContext(ghost_window, shared_orphan_list_);

View File

@@ -427,13 +427,13 @@ void GLStateManager::set_blend(const eGPUBlend value)
/** \name Texture state managment /** \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()); BLI_assert(unit < GPU_max_textures());
GLTexture *tex = static_cast<GLTexture *>(tex_); GLTexture *tex = static_cast<GLTexture *>(tex_);
targets_[unit] = tex->target_; targets_[unit] = tex->target_;
textures_[unit] = tex->tex_id_; textures_[unit] = tex->tex_id_;
samplers_[unit] = sampler; samplers_[unit] = GLTexture::samplers_[sampler_type];
tex->is_bound_ = true; tex->is_bound_ = true;
dirty_texture_binds_ |= 1 << unit; dirty_texture_binds_ |= 1 << unit;
} }
@@ -462,6 +462,7 @@ void GLStateManager::texture_unbind(Texture *tex_)
for (int i = 0; i < ARRAY_SIZE(textures_); i++) { for (int i = 0; i < ARRAY_SIZE(textures_); i++) {
if (textures_[i] == tex_id) { if (textures_[i] == tex_id) {
textures_[i] = 0; textures_[i] = 0;
samplers_[i] = 0;
dirty_texture_binds_ |= 1 << i; dirty_texture_binds_ |= 1 << i;
} }
} }
@@ -473,6 +474,7 @@ void GLStateManager::texture_unbind_all(void)
for (int i = 0; i < ARRAY_SIZE(textures_); i++) { for (int i = 0; i < ARRAY_SIZE(textures_); i++) {
if (textures_[i] != 0) { if (textures_[i] != 0) {
textures_[i] = 0; textures_[i] = 0;
samplers_[i] = 0;
dirty_texture_binds_ |= 1 << i; dirty_texture_binds_ |= 1 << i;
} }
} }
@@ -494,7 +496,7 @@ void GLStateManager::texture_bind_apply(void)
if (dirty_bind & 1) { if (dirty_bind & 1) {
glActiveTexture(GL_TEXTURE0 + unit); glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(targets_[unit], textures_[unit]); glBindTexture(targets_[unit], textures_[unit]);
// glBindSampler(unit, samplers_[unit]); glBindSampler(unit, samplers_[unit]);
} }
} }
dirty_texture_binds_ = 0; dirty_texture_binds_ = 0;

View File

@@ -23,6 +23,8 @@
#include "BKE_global.h" #include "BKE_global.h"
#include "DNA_userdef_types.h"
#include "GPU_extensions.h" #include "GPU_extensions.h"
#include "GPU_framebuffer.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. */ /* TODO(fclem) Legacy. Should be removed at some point. */
uint GLTexture::gl_bindcode_get(void) const uint GLTexture::gl_bindcode_get(void) const
{ {

View File

@@ -58,6 +58,9 @@ class GLTexture : public Texture {
friend class GLStateManager; friend class GLStateManager;
private: private:
/** All samplers states. */
static GLuint samplers_[GPU_SAMPLER_MAX];
/** Target to bind the texture to (GL_TEXTURE_1D, GL_TEXTURE_2D, etc...)*/ /** Target to bind the texture to (GL_TEXTURE_1D, GL_TEXTURE_2D, etc...)*/
GLenum target_ = -1; GLenum target_ = -1;
/** opengl identifier for texture. */ /** opengl identifier for texture. */
@@ -85,6 +88,10 @@ class GLTexture : public Texture {
/* TODO(fclem) Legacy. Should be removed at some point. */ /* TODO(fclem) Legacy. Should be removed at some point. */
uint gl_bindcode_get(void) const override; uint gl_bindcode_get(void) const override;
static void samplers_init(void);
static void samplers_free(void);
static void samplers_update(void);
protected: protected:
bool init_internal(void) override; bool init_internal(void) override;
bool init_internal(GPUVertBuf *vbo) override; bool init_internal(GPUVertBuf *vbo) override;

View File

@@ -364,8 +364,7 @@ static void rna_userdef_load_ui_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA *ptr) static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{ {
GPU_samplers_free(); GPU_samplers_update();
GPU_samplers_init();
rna_userdef_update(bmain, scene, ptr); rna_userdef_update(bmain, scene, ptr);
} }