Cleanup: GPUTexture: Clean framebuffer attachment

This commit is contained in:
2020-09-05 17:37:01 +02:00
parent 13305fb513
commit 895ec05212
6 changed files with 45 additions and 81 deletions

View File

@@ -268,11 +268,6 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter);
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp);
void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4]);
/* TODO should be private internal functions. */
void GPU_texture_attach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb, int attachment);
void GPU_texture_detach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb);
int GPU_texture_framebuffer_attachment_get(GPUTexture *tex, struct GPUFrameBuffer *fb);
int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);

View File

@@ -66,10 +66,9 @@ FrameBuffer::FrameBuffer(const char *name)
FrameBuffer::~FrameBuffer()
{
GPUFrameBuffer *gpu_fb = reinterpret_cast<GPUFrameBuffer *>(this);
for (int i = 0; i < ARRAY_SIZE(attachments_); i++) {
if (attachments_[i].tex != NULL) {
GPU_texture_detach_framebuffer(attachments_[i].tex, gpu_fb);
reinterpret_cast<Texture *>(attachments_[i].tex)->detach_from(this);
}
}
}
@@ -115,14 +114,14 @@ void FrameBuffer::attachment_set(GPUAttachmentType type, const GPUAttachment &ne
/* Unbind previous and bind new. */
/* TODO(fclem) cleanup the casts. */
if (attachment.tex) {
GPU_texture_detach_framebuffer(attachment.tex, reinterpret_cast<GPUFrameBuffer *>(this));
reinterpret_cast<Texture *>(attachment.tex)->detach_from(this);
}
attachment = new_attachment;
/* Might be null if this is for unbinding. */
if (attachment.tex) {
GPU_texture_attach_framebuffer(attachment.tex, reinterpret_cast<GPUFrameBuffer *>(this), type);
reinterpret_cast<Texture *>(attachment.tex)->attach_to(this, type);
}
else {
/* GPU_ATTACHMENT_NONE */
@@ -131,6 +130,12 @@ void FrameBuffer::attachment_set(GPUAttachmentType type, const GPUAttachment &ne
dirty_attachments_ = true;
}
void FrameBuffer::attachment_remove(GPUAttachmentType type)
{
attachments_[type] = GPU_ATTACHMENT_NONE;
dirty_attachments_ = true;
}
void FrameBuffer::recursive_downsample(int max_lvl,
void (*callback)(void *userData, int level),
void *userData)
@@ -291,14 +296,8 @@ void GPU_framebuffer_texture_cubeface_attach(
void GPU_framebuffer_texture_detach(GPUFrameBuffer *gpu_fb, GPUTexture *tex)
{
GPUAttachment attachment = GPU_ATTACHMENT_NONE;
int type = GPU_texture_framebuffer_attachment_get(tex, gpu_fb);
if (type != -1) {
reinterpret_cast<FrameBuffer *>(gpu_fb)->attachment_set((GPUAttachmentType)type, attachment);
}
else {
BLI_assert(!"Error: Texture: Framebuffer is not attached");
}
FrameBuffer *fb = reinterpret_cast<FrameBuffer *>(gpu_fb);
reinterpret_cast<Texture *>(tex)->detach_from(fb);
}
/**

View File

@@ -134,6 +134,7 @@ class FrameBuffer {
int dst_offset_y) = 0;
void attachment_set(GPUAttachmentType type, const GPUAttachment &new_attachment);
void attachment_remove(GPUAttachmentType type);
void recursive_downsample(int max_lvl,
void (*callback)(void *userData, int level),

View File

@@ -47,17 +47,16 @@ Texture::Texture(const char *name)
name_[0] = '\0';
}
for (int i = 0; i < GPU_TEX_MAX_FBO_ATTACHED; i++) {
fb[i] = NULL;
for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
fb_[i] = NULL;
}
}
Texture::~Texture()
{
for (int i = 0; i < GPU_TEX_MAX_FBO_ATTACHED; i++) {
if (fb[i] != NULL) {
FrameBuffer *framebuffer = reinterpret_cast<FrameBuffer *>(fb[i]);
framebuffer->attachment_set((GPUAttachmentType)fb_attachment[i], GPU_ATTACHMENT_NONE);
for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
if (fb_[i] != NULL) {
fb_[i]->attachment_remove(fb_attachment_[i]);
}
}
}
@@ -139,8 +138,28 @@ bool Texture::init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format)
/** \name Operation
* \{ */
void Texture::attach_to(FrameBuffer *)
void Texture::attach_to(FrameBuffer *fb, GPUAttachmentType type)
{
for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
if (fb_[i] == NULL) {
fb_attachment_[i] = type;
fb_[i] = fb;
return;
}
}
BLI_assert(!"GPU: Error: Texture: Not enough attachment");
}
void Texture::detach_from(FrameBuffer *fb)
{
for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
if (fb_[i] == fb) {
fb_[i]->attachment_remove(fb_attachment_[i]);
fb_[i] = NULL;
return;
}
}
BLI_assert(!"GPU: Error: Texture: Framebuffer is not attached");
}
void Texture::update(eGPUDataFormat format, const void *data)
@@ -662,48 +681,6 @@ int GPU_texture_opengl_bindcode(const GPUTexture *tex)
return reinterpret_cast<const Texture *>(tex)->gl_bindcode_get();
}
void GPU_texture_attach_framebuffer(GPUTexture *tex_, GPUFrameBuffer *fb, int attachment)
{
/* TODO cleanup casts */
Texture *tex = reinterpret_cast<Texture *>(tex_);
for (int i = 0; i < GPU_TEX_MAX_FBO_ATTACHED; i++) {
if (tex->fb[i] == NULL) {
tex->fb[i] = reinterpret_cast<FrameBuffer *>(fb);
tex->fb_attachment[i] = (GPUAttachmentType)attachment;
return;
}
}
BLI_assert(!"Error: Texture: Not enough Framebuffer slots");
}
/* Return previous attachment point */
void GPU_texture_detach_framebuffer(GPUTexture *tex_, GPUFrameBuffer *fb)
{
/* TODO cleanup casts */
Texture *tex = reinterpret_cast<Texture *>(tex_);
for (int i = 0; i < GPU_TEX_MAX_FBO_ATTACHED; i++) {
if (tex->fb[i] == reinterpret_cast<FrameBuffer *>(fb)) {
tex->fb[i] = NULL;
return;
}
}
BLI_assert(!"Error: Texture: Framebuffer is not attached");
}
/* Return attachment type for the given framebuffer or -1 if not attached. */
int GPU_texture_framebuffer_attachment_get(GPUTexture *tex_, GPUFrameBuffer *fb)
{
/* TODO cleanup casts */
Texture *tex = reinterpret_cast<Texture *>(tex_);
for (int i = 0; i < GPU_TEX_MAX_FBO_ATTACHED; i++) {
if (tex->fb[i] == reinterpret_cast<FrameBuffer *>(fb)) {
return tex->fb_attachment[i];
}
}
return -1;
}
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *r_size)
{
return reinterpret_cast<Texture *>(tex)->mip_size_get(lvl, r_size);

View File

@@ -74,9 +74,6 @@ class Texture {
int refcount = 1;
/** Width & Height (of source data), optional. */
int src_w = 0, src_h = 0;
/** Framebuffer references to update on deletion. */
GPUAttachmentType fb_attachment[GPU_TEX_MAX_FBO_ATTACHED];
FrameBuffer *fb[GPU_TEX_MAX_FBO_ATTACHED];
protected:
/* ---- Texture format (immutable after init). ---- */
@@ -96,6 +93,11 @@ class Texture {
/** 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];
public:
Texture(const char *name);
virtual ~Texture();
@@ -114,9 +116,9 @@ class Texture {
virtual void mip_range_set(int min, int max) = 0;
virtual void *read(int mip, eGPUDataFormat format) = 0;
void attach_to(FrameBuffer *fb);
void attach_to(FrameBuffer *fb, GPUAttachmentType type);
void detach_from(FrameBuffer *fb);
void update(eGPUDataFormat format, const void *data);
void update_mip(int mip, eGPUDataFormat format, const void *data);
virtual void update_sub(
int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data) = 0;

View File

@@ -44,16 +44,6 @@ struct GPUFrameBuffer;
namespace blender {
namespace gpu {
#if 0
class GLContext {
/** Currently bound textures. Updated before drawing. */
GLuint bound_textures[64];
GLuint bound_samplers[64];
/** All sampler objects. Last one is for icon sampling. */
GLuint samplers[GPU_SAMPLER_MAX + 1];
};
#endif
class GLTexture : public Texture {
friend class GLStateManager;