GLTexture: Add Feedback loop check

The check is better than before as we take into
consideration the attached mip level.
This commit is contained in:
Clément Foucault 2020-09-05 17:36:13 +02:00
parent 14926a81b6
commit 71872e3809
5 changed files with 41 additions and 1 deletions

View File

@ -91,11 +91,12 @@ class Texture {
/** Number of mipmaps this texture has (Max miplvl). */
/* TODO(fclem) Should become immutable and the need for mipmaps should be specified upfront. */
int mipmaps_ = -1;
/** For error checking */
int mip_min_ = 0, mip_max_ = 0;
/** For debugging */
char name_[DEBUG_NAME_LEN];
private:
/** Framebuffer references to update on deletion. */
GPUAttachmentType fb_attachment_[GPU_TEX_MAX_FBO_ATTACHED];
FrameBuffer *fb_[GPU_TEX_MAX_FBO_ATTACHED];

View File

@ -39,6 +39,9 @@ class GLStateManager;
* Implementation of FrameBuffer object using OpenGL.
**/
class GLFrameBuffer : public FrameBuffer {
/* For debugging purpose. */
friend class GLTexture;
private:
/** OpenGL handle. */
GLuint fbo_id_ = 0;

View File

@ -434,6 +434,9 @@ void GLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler_type,
{
BLI_assert(unit < GPU_max_textures());
GLTexture *tex = static_cast<GLTexture *>(tex_);
if (G.debug & G_DEBUG_GPU) {
tex->check_feedback_loop();
}
/* Eliminate redundant binds. */
if ((textures_[unit] == tex->tex_id_) &&
(samplers_[unit] == GLTexture::samplers_[sampler_type])) {

View File

@ -446,6 +446,8 @@ void GLTexture::swizzle_set(const char swizzle[4])
void GLTexture::mip_range_set(int min, int max)
{
BLI_assert(min <= max && min >= 0 && max <= mipmaps_);
mip_min_ = min;
mip_max_ = max;
if (GLEW_ARB_direct_state_access) {
glTextureParameteri(tex_id_, GL_TEXTURE_BASE_LEVEL, min);
glTextureParameteri(tex_id_, GL_TEXTURE_MAX_LEVEL, max);
@ -649,6 +651,35 @@ bool GLTexture::proxy_check(int mip)
/** \} */
void GLTexture::check_feedback_loop(void)
{
/* Recursive downsample workaround break this check.
* See recursive_downsample() for more infos. */
if (GPU_mip_render_workaround()) {
return;
}
GLFrameBuffer *fb = static_cast<GLFrameBuffer *>(GPU_context_active_get()->active_fb);
for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
if (fb_[i] == fb) {
GPUAttachmentType type = fb_attachment_[i];
GPUAttachment attachment = fb->attachments_[type];
if (attachment.mip <= mip_max_ && attachment.mip >= mip_min_) {
char msg[256];
SNPRINTF(msg,
"Feedback loop: Trying to bind a texture (%s) with mip range %d-%d but mip %d is "
"attached to the active framebuffer (%s)",
name_,
mip_min_,
mip_max_,
attachment.mip,
fb->name_);
debug::raise_gl_error(msg);
}
return;
}
}
}
/* TODO(fclem) Legacy. Should be removed at some point. */
uint GLTexture::gl_bindcode_get(void) const
{

View File

@ -75,6 +75,8 @@ class GLTexture : public Texture {
void mip_range_set(int min, int max) override;
void *read(int mip, eGPUDataFormat format) override;
void check_feedback_loop(void);
/* TODO(fclem) Legacy. Should be removed at some point. */
uint gl_bindcode_get(void) const override;