This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/gpu/intern/gpu_framebuffer_private.hh
Clément Foucault db21c12abe GPUFramebuffer: Encapsulate single attachement clear
This is in preparation of using it to clear single texture.

Also includes minor cleanups about not using tex target in
assert and adding enum operators.
2020-09-05 17:49:14 +02:00

215 lines
5.8 KiB
C++

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2020 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup gpu
*
* GPU Framebuffer
* - this is a wrapper for an OpenGL framebuffer object (FBO). in practice
* multiple FBO's may be created.
* - actual FBO creation & config is deferred until GPU_framebuffer_bind or
* GPU_framebuffer_check_valid to allow creation & config while another
* opengl context is bound (since FBOs are not shared between ogl contexts).
*/
#pragma once
#include "BLI_math_vector.h"
#include "BLI_span.hh"
#include "MEM_guardedalloc.h"
#include "GPU_framebuffer.h"
struct GPUTexture;
typedef enum GPUAttachmentType : int {
GPU_FB_DEPTH_ATTACHMENT = 0,
GPU_FB_DEPTH_STENCIL_ATTACHMENT,
GPU_FB_COLOR_ATTACHMENT0,
GPU_FB_COLOR_ATTACHMENT1,
GPU_FB_COLOR_ATTACHMENT2,
GPU_FB_COLOR_ATTACHMENT3,
GPU_FB_COLOR_ATTACHMENT4,
GPU_FB_COLOR_ATTACHMENT5,
/* Number of maximum output slots.
* We support 6 outputs for now (usually we wouldn't need more to preserve fill rate). */
/* Keep in mind that GL max is GL_MAX_DRAW_BUFFERS and is at least 8, corresponding to
* the maximum number of COLOR attachments specified by glDrawBuffers. */
GPU_FB_MAX_ATTACHMENT,
GPU_FB_MAX_COLOR_ATTACHMENT = (GPU_FB_MAX_ATTACHMENT - GPU_FB_COLOR_ATTACHMENT0),
} GPUAttachmentType;
inline constexpr GPUAttachmentType operator-(GPUAttachmentType a, int b)
{
return static_cast<GPUAttachmentType>(static_cast<int>(a) - b);
}
inline constexpr GPUAttachmentType operator+(GPUAttachmentType a, int b)
{
return static_cast<GPUAttachmentType>(static_cast<int>(a) + b);
}
inline GPUAttachmentType &operator++(GPUAttachmentType &a)
{
a = a + 1;
return a;
}
inline GPUAttachmentType &operator--(GPUAttachmentType &a)
{
a = a - 1;
return a;
}
namespace blender {
namespace gpu {
#ifdef DEBUG
# define DEBUG_NAME_LEN 64
#else
# define DEBUG_NAME_LEN 16
#endif
class FrameBuffer {
protected:
/** Set of texture attachments to render to. DEPTH and DEPTH_STENCIL are mutually exclusive. */
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT];
/** Is true if internal representation need to be updated. */
bool dirty_attachments_;
/** Size of attachment textures. */
int width_, height_;
/** Debug name. */
char name_[DEBUG_NAME_LEN];
/** Frame-buffer state. */
int viewport_[4];
int scissor_[4];
bool scissor_test_ = false;
bool dirty_state_;
public:
FrameBuffer(const char *name);
virtual ~FrameBuffer();
virtual void bind(bool enabled_srgb) = 0;
virtual bool check(char err_out[256]) = 0;
virtual void clear(eGPUFrameBufferBits buffers,
const float clear_col[4],
float clear_depth,
uint clear_stencil) = 0;
virtual void clear_multi(const float (*clear_col)[4]) = 0;
virtual void clear_attachment(GPUAttachmentType type,
eGPUDataFormat data_format,
const void *clear_value) = 0;
virtual void read(eGPUFrameBufferBits planes,
eGPUDataFormat format,
const int area[4],
int channel_len,
int slot,
void *r_data) = 0;
virtual void blit_to(eGPUFrameBufferBits planes,
int src_slot,
FrameBuffer *dst,
int dst_slot,
int dst_offset_x,
int dst_offset_y) = 0;
void attachment_set(GPUAttachmentType type, const GPUAttachment &new_attachment);
void recursive_downsample(int max_lvl,
void (*callback)(void *userData, int level),
void *userData);
inline void size_set(int width, int height)
{
width_ = width;
height_ = height;
dirty_state_ = true;
}
inline void viewport_set(const int viewport[4])
{
if (!equals_v4v4_int(viewport_, viewport)) {
copy_v4_v4_int(viewport_, viewport);
dirty_state_ = true;
}
}
inline void scissor_set(const int scissor[4])
{
if (!equals_v4v4_int(scissor_, scissor)) {
copy_v4_v4_int(scissor_, scissor);
dirty_state_ = true;
}
}
inline void scissor_test_set(bool test)
{
scissor_test_ = test;
}
inline void viewport_get(int r_viewport[4]) const
{
copy_v4_v4_int(r_viewport, viewport_);
}
inline void scissor_get(int r_scissor[4]) const
{
copy_v4_v4_int(r_scissor, scissor_);
}
inline bool scissor_test_get(void) const
{
return scissor_test_;
}
inline void viewport_reset(void)
{
int viewport_rect[4] = {0, 0, width_, height_};
viewport_set(viewport_rect);
}
inline void scissor_reset(void)
{
int scissor_rect[4] = {0, 0, width_, height_};
scissor_set(scissor_rect);
}
inline GPUTexture *depth_tex(void) const
{
if (attachments_[GPU_FB_DEPTH_ATTACHMENT].tex) {
return attachments_[GPU_FB_DEPTH_ATTACHMENT].tex;
}
return attachments_[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex;
};
inline GPUTexture *color_tex(int slot) const
{
return attachments_[GPU_FB_COLOR_ATTACHMENT0 + slot].tex;
};
};
#undef DEBUG_NAME_LEN
} // namespace gpu
} // namespace blender