GPUFrameBuffer: Document and cleanup header
No fonctional changes.
This commit is contained in:
@@ -4,12 +4,21 @@
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*
|
||||
* GPU Frame-buffer
|
||||
* - 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).
|
||||
* A `GPUFramebuffer` is a wrapper for a frame-buffer object (FBO) from the underlying graphic API.
|
||||
*
|
||||
* A `GPUFramebuffer` is limited to one context and thus cannot be shared across different
|
||||
* contexts. In the case this is needed, one must recreate the same `GPUFramebuffer` in each
|
||||
* context.
|
||||
*
|
||||
* Note that actual FBO creation & config is deferred until `GPU_framebuffer_bind` or
|
||||
* `GPU_framebuffer_check_valid` is called. This means the context the `GPUFramebuffer` is bound
|
||||
* with is the one active when `GPU_framebuffer_bind` is called.
|
||||
*
|
||||
* When a `GPUTexture` is attached to a `GPUFramebuffer` a reference is created. Deleting either
|
||||
* does not require any unbinding.
|
||||
*
|
||||
* A `GPUOffScreen` is a convenience type that holds a `GPUFramebuffer` and its associated
|
||||
* `GPUTexture`s. It is useful for quick drawing surface configuration.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -30,37 +39,102 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct GPUAttachment {
|
||||
struct GPUTexture *tex;
|
||||
GPUTexture *tex;
|
||||
int layer, mip;
|
||||
} GPUAttachment;
|
||||
|
||||
typedef enum eGPUBackBuffer {
|
||||
GPU_BACKBUFFER_LEFT = 0,
|
||||
GPU_BACKBUFFER_RIGHT,
|
||||
} eGPUBackBuffer;
|
||||
|
||||
/** Opaque type hiding blender::gpu::FrameBuffer. */
|
||||
typedef struct GPUFrameBuffer GPUFrameBuffer;
|
||||
|
||||
typedef struct GPUOffScreen GPUOffScreen;
|
||||
|
||||
GPUFrameBuffer *GPU_framebuffer_create(const char *name);
|
||||
void GPU_framebuffer_free(GPUFrameBuffer *fb);
|
||||
void GPU_framebuffer_bind(GPUFrameBuffer *fb);
|
||||
|
||||
const char *GPU_framebuffer_get_name(GPUFrameBuffer *fb);
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Creation
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Workaround for binding a SRGB frame-buffer without doing the SRGB transform.
|
||||
* Create a #GPUFrameBuffer object. It is not configured and not bound to a specific context until
|
||||
* `GPU_framebuffer_bind()` is called.
|
||||
*/
|
||||
GPUFrameBuffer *GPU_framebuffer_create(const char *name);
|
||||
|
||||
/**
|
||||
* Returns the current context active framebuffer.
|
||||
* Return nullptr if no context is active.
|
||||
*/
|
||||
GPUFrameBuffer *GPU_framebuffer_active_get(void);
|
||||
|
||||
/**
|
||||
* Returns the default (back-left) frame-buffer. It will always exists even if it's just a dummy.
|
||||
* Return nullptr if no context is active.
|
||||
*/
|
||||
GPUFrameBuffer *GPU_framebuffer_back_get(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Free
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Create a #GPUFrameBuffer object. It is not configured and not bound to a specific context until
|
||||
* `GPU_framebuffer_bind()` is called.
|
||||
*/
|
||||
void GPU_framebuffer_free(GPUFrameBuffer *framebuffer);
|
||||
|
||||
#define GPU_FRAMEBUFFER_FREE_SAFE(fb) \
|
||||
do { \
|
||||
if (fb != NULL) { \
|
||||
GPU_framebuffer_free(fb); \
|
||||
fb = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Binding
|
||||
* \{ */
|
||||
|
||||
typedef enum eGPUBackBuffer {
|
||||
/** Default framebuffer of a window. Always available. */
|
||||
GPU_BACKBUFFER_LEFT = 0,
|
||||
/** Right buffer of a window. Only available if window was created using stereo-view. */
|
||||
GPU_BACKBUFFER_RIGHT,
|
||||
} eGPUBackBuffer;
|
||||
|
||||
/**
|
||||
* Binds the active context's window frame-buffer.
|
||||
* Note that `GPU_BACKBUFFER_RIGHT` is only available if the window was created using stereo-view.
|
||||
*/
|
||||
void GPU_backbuffer_bind(eGPUBackBuffer back_buffer_type);
|
||||
|
||||
/**
|
||||
* Binds a #GPUFrameBuffer making it the active framebuffer for all geometry rendering.
|
||||
*/
|
||||
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer);
|
||||
|
||||
/**
|
||||
* Same as `GPU_framebuffer_bind` but do not enable the SRGB transform.
|
||||
*/
|
||||
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *framebuffer);
|
||||
|
||||
/**
|
||||
* Binds back the active context's default frame-buffer.
|
||||
* Equivalent to `GPU_backbuffer_bind(GPU_BACKBUFFER_LEFT)`.
|
||||
*/
|
||||
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb);
|
||||
void GPU_framebuffer_restore(void);
|
||||
|
||||
/* Advanced binding control. */
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Advanced binding control
|
||||
* \{ */
|
||||
|
||||
typedef struct GPULoadStore {
|
||||
eGPULoadOp load_action;
|
||||
eGPUStoreOp store_action;
|
||||
} GPULoadStore;
|
||||
|
||||
/* Empty bind point. */
|
||||
#define NULL_LOAD_STORE \
|
||||
{ \
|
||||
GPU_LOADACTION_DONT_CARE, GPU_STOREACTION_DONT_CARE \
|
||||
@@ -85,37 +159,20 @@ typedef struct GPULoadStore {
|
||||
* })
|
||||
* \encode
|
||||
*/
|
||||
void GPU_framebuffer_bind_loadstore(GPUFrameBuffer *fb,
|
||||
void GPU_framebuffer_bind_loadstore(GPUFrameBuffer *framebuffer,
|
||||
const GPULoadStore *load_store_actions,
|
||||
uint actions_len);
|
||||
uint load_store_actions_len);
|
||||
#define GPU_framebuffer_bind_ex(_fb, ...) \
|
||||
{ \
|
||||
GPULoadStore actions[] = __VA_ARGS__; \
|
||||
GPU_framebuffer_bind_loadstore(_fb, actions, (sizeof(actions) / sizeof(GPULoadStore))); \
|
||||
}
|
||||
|
||||
bool GPU_framebuffer_bound(GPUFrameBuffer *fb);
|
||||
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]);
|
||||
/** \} */
|
||||
|
||||
GPUFrameBuffer *GPU_framebuffer_active_get(void);
|
||||
/**
|
||||
* Returns the default frame-buffer. Will always exists even if it's just a dummy.
|
||||
*/
|
||||
GPUFrameBuffer *GPU_framebuffer_back_get(void);
|
||||
|
||||
#define GPU_FRAMEBUFFER_FREE_SAFE(fb) \
|
||||
do { \
|
||||
if (fb != NULL) { \
|
||||
GPU_framebuffer_free(fb); \
|
||||
fb = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Frame-buffer setup: You need to call #GPU_framebuffer_bind for these
|
||||
* to be effective. */
|
||||
|
||||
void GPU_framebuffer_texture_attach_ex(GPUFrameBuffer *gpu_fb, GPUAttachment attachment, int slot);
|
||||
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, struct GPUTexture *tex);
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Attachments
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* How to use #GPU_framebuffer_ensure_config().
|
||||
@@ -151,110 +208,347 @@ void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, struct GPUTexture *tex);
|
||||
* Setting #GPUAttachment.mip to -1 will leave the texture in this slot.
|
||||
* Setting #GPUAttachment.tex to NULL will detach the texture in this slot.
|
||||
*/
|
||||
void GPU_framebuffer_config_array(GPUFrameBuffer *fb, const GPUAttachment *config, int config_len);
|
||||
void GPU_framebuffer_config_array(GPUFrameBuffer *framebuffer,
|
||||
const GPUAttachment *config,
|
||||
int config_len);
|
||||
|
||||
/** Empty bind point. */
|
||||
#define GPU_ATTACHMENT_NONE \
|
||||
{ \
|
||||
NULL, -1, 0, \
|
||||
}
|
||||
/** Leave currently bound texture in this slot. DEPRECATED: Specify all textures for clarity. */
|
||||
#define GPU_ATTACHMENT_LEAVE \
|
||||
{ \
|
||||
NULL, -1, -1, \
|
||||
}
|
||||
#define GPU_ATTACHMENT_TEXTURE(_tex) \
|
||||
/** Bind the first mip level of a texture (all layers). */
|
||||
#define GPU_ATTACHMENT_TEXTURE(_texture) \
|
||||
{ \
|
||||
_tex, -1, 0, \
|
||||
_texture, -1, 0, \
|
||||
}
|
||||
#define GPU_ATTACHMENT_TEXTURE_MIP(_tex, _mip) \
|
||||
/** Bind the \a _mip level of a texture (all layers). */
|
||||
#define GPU_ATTACHMENT_TEXTURE_MIP(_texture, _mip) \
|
||||
{ \
|
||||
_tex, -1, _mip, \
|
||||
_texture, -1, _mip, \
|
||||
}
|
||||
#define GPU_ATTACHMENT_TEXTURE_LAYER(_tex, _layer) \
|
||||
/** Bind the \a _layer layer of the first mip level of a texture. */
|
||||
#define GPU_ATTACHMENT_TEXTURE_LAYER(_texture, _layer) \
|
||||
{ \
|
||||
_tex, _layer, 0, \
|
||||
_texture, _layer, 0, \
|
||||
}
|
||||
#define GPU_ATTACHMENT_TEXTURE_LAYER_MIP(_tex, _layer, _mip) \
|
||||
/** Bind the \a _layer layer of the \a _mip level of a texture. */
|
||||
#define GPU_ATTACHMENT_TEXTURE_LAYER_MIP(_texture, _layer, _mip) \
|
||||
{ \
|
||||
_tex, _layer, _mip, \
|
||||
}
|
||||
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE(_tex, _face) \
|
||||
{ \
|
||||
_tex, _face, 0, \
|
||||
}
|
||||
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(_tex, _face, _mip) \
|
||||
{ \
|
||||
_tex, _face, _mip, \
|
||||
_texture, _layer, _mip, \
|
||||
}
|
||||
|
||||
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip);
|
||||
/** NOTE: The cube-face variants are equivalent to the layer ones but give better semantic. */
|
||||
|
||||
/** Bind the first mip level of a cube-map \a _face texture. */
|
||||
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE(_texture, _face) \
|
||||
{ \
|
||||
_texture, _face, 0, \
|
||||
}
|
||||
/** Bind the \a _mip level of a cube-map \a _face texture. */
|
||||
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(_texture, _face, _mip) \
|
||||
{ \
|
||||
_texture, _face, _mip, \
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach an entire texture mip level to a #GPUFrameBuffer.
|
||||
* Changes will only take effect next time `GPU_framebuffer_bind()` is called.
|
||||
* \a slot is the color texture slot to bind this texture to. Must be 0 if it is the depth texture.
|
||||
* \a mip is the mip level of this texture to attach to the framebuffer.
|
||||
* DEPRECATED: Prefer using multiple #GPUFrameBuffer with different configurations with
|
||||
* `GPU_framebuffer_config_array()`.
|
||||
*/
|
||||
void GPU_framebuffer_texture_attach(GPUFrameBuffer *framebuffer,
|
||||
GPUTexture *texture,
|
||||
int slot,
|
||||
int mip);
|
||||
|
||||
/**
|
||||
* Attach a single layer of an array texture mip level to a #GPUFrameBuffer.
|
||||
* Changes will only take effect next time `GPU_framebuffer_bind()` is called.
|
||||
* \a slot is the color texture slot to bind this texture to. Must be 0 if it is the depth texture.
|
||||
* \a layer is the layer of this array texture to attach to the framebuffer.
|
||||
* \a mip is the mip level of this texture to attach to the framebuffer.
|
||||
* DEPRECATED: Prefer using multiple #GPUFrameBuffer with different configurations with
|
||||
* `GPU_framebuffer_config_array()`.
|
||||
*/
|
||||
void GPU_framebuffer_texture_layer_attach(
|
||||
GPUFrameBuffer *fb, GPUTexture *tex, int slot, int layer, int mip);
|
||||
GPUFrameBuffer *framebuffer, GPUTexture *texture, int slot, int layer, int mip);
|
||||
|
||||
/**
|
||||
* Attach a single cube-face of an cube-map texture mip level to a #GPUFrameBuffer.
|
||||
* Changes will only take effect next time `GPU_framebuffer_bind()` is called.
|
||||
* \a slot is the color texture slot to bind this texture to. Must be 0 if it is the depth texture.
|
||||
* \a face is the cube-face of this cube-map texture to attach to the framebuffer.
|
||||
* \a mip is the mip level of this texture to attach to the framebuffer.
|
||||
* DEPRECATED: Prefer using multiple #GPUFrameBuffer with different configurations with
|
||||
* `GPU_framebuffer_config_array()`.
|
||||
*/
|
||||
void GPU_framebuffer_texture_cubeface_attach(
|
||||
GPUFrameBuffer *fb, GPUTexture *tex, int slot, int face, int mip);
|
||||
GPUFrameBuffer *framebuffer, GPUTexture *texture, int slot, int face, int mip);
|
||||
|
||||
/**
|
||||
* Detach a texture from a #GPUFrameBuffer. The texture must be attached.
|
||||
* Changes will only take effect next time `GPU_framebuffer_bind()` is called.
|
||||
* DEPRECATED: Prefer using multiple #GPUFrameBuffer with different configurations with
|
||||
* `GPU_framebuffer_config_array()`.
|
||||
*/
|
||||
void GPU_framebuffer_texture_detach(GPUFrameBuffer *framebuffer, GPUTexture *texture);
|
||||
|
||||
/**
|
||||
* Checks a framebuffer current configuration for errors.
|
||||
* Checks for texture size mismatch, incompatible attachment, incomplete textures etc...
|
||||
* \note This binds the framebuffer to the active context.
|
||||
* \a err_out is an error output buffer.
|
||||
* \return false if the framebuffer is invalid.
|
||||
*/
|
||||
bool GPU_framebuffer_check_valid(GPUFrameBuffer *framebuffer, char err_out[256]);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Empty framebuffer
|
||||
*
|
||||
* An empty framebuffer is a framebuffer with no attachments. This allow to rasterize geometry
|
||||
* without creating any dummy attachments and write some computation results using other means
|
||||
* (SSBOs, Images).
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Default size is used if the framebuffer contains no attachments.
|
||||
* It needs to be re-specified each time an attachment is added.
|
||||
*/
|
||||
void GPU_framebuffer_default_size(GPUFrameBuffer *gpu_fb, int width, int height);
|
||||
void GPU_framebuffer_default_size(GPUFrameBuffer *framebuffer, int width, int height);
|
||||
|
||||
/* Frame-buffer operations. */
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal state
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Viewport and scissor size is stored per frame-buffer.
|
||||
* It is only reset to its original dimensions explicitly OR when binding the frame-buffer after
|
||||
* modifying its attachments.
|
||||
* Set a the viewport offset and size.
|
||||
* These are reset to the original dimensions explicitly (using `GPU_framebuffer_viewport_reset()`)
|
||||
* or when binding the frame-buffer after modifying its attachments.
|
||||
*
|
||||
* \note Viewport and scissor size is stored per frame-buffer.
|
||||
*/
|
||||
void GPU_framebuffer_viewport_set(GPUFrameBuffer *fb, int x, int y, int w, int h);
|
||||
void GPU_framebuffer_viewport_get(GPUFrameBuffer *fb, int r_viewport[4]);
|
||||
/**
|
||||
* Reset to its attachment(s) size.
|
||||
*/
|
||||
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *fb);
|
||||
void GPU_framebuffer_viewport_set(
|
||||
GPUFrameBuffer *framebuffer, int x, int y, int width, int height);
|
||||
|
||||
void GPU_framebuffer_clear(GPUFrameBuffer *fb,
|
||||
/**
|
||||
* Return the viewport offset and size in a int quadruple: (x, y, width, height).
|
||||
* \note Viewport and scissor size is stored per frame-buffer.
|
||||
*/
|
||||
void GPU_framebuffer_viewport_get(GPUFrameBuffer *framebuffer, int r_viewport[4]);
|
||||
|
||||
/**
|
||||
* Reset a framebuffer viewport bounds to its attachment(s) size.
|
||||
* \note Viewport and scissor size is stored per frame-buffer.
|
||||
*/
|
||||
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *framebuffer);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Clearing
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Clear the framebuffer attachments.
|
||||
* \a buffers controls the types of attachments to clear. Setting GPU_COLOR_BIT will clear *all*
|
||||
* the color attachment.
|
||||
* Each attachment gets cleared to the value of its type:
|
||||
* - color attachments gets cleared to \a clear_col .
|
||||
* - depth attachment gets cleared to \a clear_depth .
|
||||
* - stencil attachment gets cleared to \a clear_stencil .
|
||||
*
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
*/
|
||||
void GPU_framebuffer_clear(GPUFrameBuffer *framebuffer,
|
||||
eGPUFrameBufferBits buffers,
|
||||
const float clear_col[4],
|
||||
float clear_depth,
|
||||
unsigned int clear_stencil);
|
||||
|
||||
#define GPU_framebuffer_clear_color(fb, col) \
|
||||
GPU_framebuffer_clear(fb, GPU_COLOR_BIT, col, 0.0f, 0x00)
|
||||
|
||||
#define GPU_framebuffer_clear_depth(fb, depth) \
|
||||
GPU_framebuffer_clear(fb, GPU_DEPTH_BIT, NULL, depth, 0x00)
|
||||
|
||||
#define GPU_framebuffer_clear_color_depth(fb, col, depth) \
|
||||
GPU_framebuffer_clear(fb, GPU_COLOR_BIT | GPU_DEPTH_BIT, col, depth, 0x00)
|
||||
|
||||
#define GPU_framebuffer_clear_stencil(fb, stencil) \
|
||||
GPU_framebuffer_clear(fb, GPU_STENCIL_BIT, NULL, 0.0f, stencil)
|
||||
|
||||
#define GPU_framebuffer_clear_depth_stencil(fb, depth, stencil) \
|
||||
GPU_framebuffer_clear(fb, GPU_DEPTH_BIT | GPU_STENCIL_BIT, NULL, depth, stencil)
|
||||
|
||||
#define GPU_framebuffer_clear_color_depth_stencil(fb, col, depth, stencil) \
|
||||
GPU_framebuffer_clear(fb, GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT, col, depth, stencil)
|
||||
/**
|
||||
* Clear all color attachment textures with the value \a clear_col .
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
*/
|
||||
void GPU_framebuffer_clear_color(GPUFrameBuffer *fb, const float clear_col[4]);
|
||||
|
||||
/**
|
||||
* Clear all textures attached to this frame-buffer with a different color.
|
||||
* Clear the depth attachment texture with the value \a clear_depth .
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
*/
|
||||
void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4]);
|
||||
void GPU_framebuffer_clear_depth(GPUFrameBuffer *fb, float clear_depth);
|
||||
|
||||
void GPU_framebuffer_read_depth(
|
||||
GPUFrameBuffer *fb, int x, int y, int w, int h, eGPUDataFormat format, void *data);
|
||||
void GPU_framebuffer_read_color(GPUFrameBuffer *fb,
|
||||
/**
|
||||
* Clear the stencil attachment with the value \a clear_stencil .
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
*/
|
||||
void GPU_framebuffer_clear_stencil(GPUFrameBuffer *fb, uint clear_stencil);
|
||||
|
||||
/**
|
||||
* Clear all color attachment textures with the value \a clear_col and the depth attachment texture
|
||||
* with the value \a clear_depth .
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
*/
|
||||
void GPU_framebuffer_clear_color_depth(GPUFrameBuffer *fb,
|
||||
const float clear_col[4],
|
||||
float clear_depth);
|
||||
|
||||
/**
|
||||
* Clear the depth attachment texture with the value \a clear_depth and the stencil attachment with
|
||||
* the value \a clear_stencil .
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
*/
|
||||
void GPU_framebuffer_clear_depth_stencil(GPUFrameBuffer *fb,
|
||||
float clear_depth,
|
||||
uint clear_stencil);
|
||||
/**
|
||||
* Clear the depth attachment texture with the value \a clear_depth , the stencil attachment with
|
||||
* the value \a clear_stencil and all the color attachments with the value \a clear_col .
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
*/
|
||||
void GPU_framebuffer_clear_color_depth_stencil(GPUFrameBuffer *fb,
|
||||
const float clear_col[4],
|
||||
float clear_depth,
|
||||
uint clear_stencil);
|
||||
|
||||
/**
|
||||
* Clear each color attachment texture attached to this frame-buffer with a different color.
|
||||
* IMPORTANT: The size of `clear_colors` must match the number of color attachments.
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
*/
|
||||
void GPU_framebuffer_multi_clear(GPUFrameBuffer *framebuffer, const float (*clear_colors)[4]);
|
||||
|
||||
/**
|
||||
* Clear all color attachment textures of the active framebuffer with the given red, green, blue,
|
||||
* alpha values.
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
* DEPRECATED: Use `GPU_framebuffer_clear_color` with explicit framebuffer.
|
||||
*/
|
||||
void GPU_clear_color(float red, float green, float blue, float alpha);
|
||||
|
||||
/**
|
||||
* Clear the depth attachment texture of the active framebuffer with the given depth value.
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
* DEPRECATED: Use `GPU_framebuffer_clear_color` with explicit framebuffer.
|
||||
*/
|
||||
void GPU_clear_depth(float depth);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Debugging introspection API.
|
||||
* \{ */
|
||||
|
||||
const char *GPU_framebuffer_get_name(GPUFrameBuffer *framebuffer);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Python API & meta-data
|
||||
*
|
||||
* These are not intrinsic properties of a framebuffer but they are stored inside the
|
||||
* gpu::FrameBuffer structure for tracking purpose.
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Reference of a pointer that needs to be cleaned when deallocating the frame-buffer.
|
||||
* Points to #BPyGPUFrameBuffer.fb
|
||||
*/
|
||||
#ifndef GPU_NO_USE_PY_REFERENCES
|
||||
void **GPU_framebuffer_py_reference_get(GPUFrameBuffer *framebuffer);
|
||||
void GPU_framebuffer_py_reference_set(GPUFrameBuffer *framebuffer, void **py_ref);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Keep a stack of bound framebuffer to allow scoped binding of framebuffer in python.
|
||||
* This is also used by #GPUOffScreen to save/restore the current framebuffers.
|
||||
* \note This isn't thread safe.
|
||||
*/
|
||||
/* TODO(fclem): This has nothing to do with the GPU module and should be move to the pyGPU module.
|
||||
*/
|
||||
void GPU_framebuffer_push(GPUFrameBuffer *framebuffer);
|
||||
GPUFrameBuffer *GPU_framebuffer_pop(void);
|
||||
uint GPU_framebuffer_stack_level_get(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Deprecated
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Return true if \a framebuffer is the active framebuffer of the active context.
|
||||
* \note return false if no context is active.
|
||||
* \note this is undefined behavior if \a framebuffer is `nullptr`.
|
||||
* DEPRECATED: Kept only because of Python GPU API. */
|
||||
bool GPU_framebuffer_bound(GPUFrameBuffer *framebuffer);
|
||||
|
||||
/**
|
||||
* Read a region of the framebuffer depth attachment and copy it to \a r_data .
|
||||
* The pixel data will be converted to \a data_format but it needs to be compatible with the
|
||||
* attachment type. DEPRECATED: Prefer using `GPU_texture_read()`.
|
||||
*/
|
||||
void GPU_framebuffer_read_depth(GPUFrameBuffer *framebuffer,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h,
|
||||
int channels,
|
||||
int slot,
|
||||
eGPUDataFormat format,
|
||||
void *data);
|
||||
int width,
|
||||
int height,
|
||||
eGPUDataFormat data_format,
|
||||
void *r_data);
|
||||
|
||||
/**
|
||||
* Read_slot and write_slot are only used for color buffers.
|
||||
* Read a region of a framebuffer color attachment and copy it to \a r_data .
|
||||
* The pixel data will be converted to \a data_format but it needs to be compatible with the
|
||||
* attachment type. DEPRECATED: Prefer using `GPU_texture_read()`.
|
||||
*/
|
||||
void GPU_framebuffer_read_color(GPUFrameBuffer *framebuffer,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
int slot,
|
||||
eGPUDataFormat data_format,
|
||||
void *r_data);
|
||||
|
||||
/**
|
||||
* Read a the color of the window screen as it is currently displayed (so the previously rendered
|
||||
* back-buffer).
|
||||
* DEPRECATED: This isn't even working correctly on some implementation.
|
||||
* TODO: Emulate this by doing some slow texture copy on the backend side or try to read the areas
|
||||
* offscreen textures directly.
|
||||
*/
|
||||
void GPU_frontbuffer_read_pixels(
|
||||
int x, int y, int width, int height, int channels, eGPUDataFormat data_format, void *r_data);
|
||||
|
||||
/**
|
||||
* Copy the content of \a fb_read attachments to the \a fb_read attachments.
|
||||
* The attachments types are chosen by \a blit_buffers .
|
||||
* Only one color buffer can by copied at a time and its index is chosen by \a read_slot and \a
|
||||
* write_slot.
|
||||
* The source and destination framebuffers dimensions have to match.
|
||||
* DEPRECATED: Prefer using `GPU_texture_copy()`.
|
||||
*/
|
||||
void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
|
||||
int read_slot,
|
||||
@@ -262,50 +556,101 @@ void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
|
||||
int write_slot,
|
||||
eGPUFrameBufferBits blit_buffers);
|
||||
|
||||
void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
|
||||
int max_lvl,
|
||||
void (*callback)(void *userData, int level),
|
||||
/**
|
||||
* Call \a per_level_callback after binding each framebuffer attachment mip level
|
||||
* up until \a max_level .
|
||||
* Each attachment texture sampler mip range is set to not overlap the currently processed level.
|
||||
* This is used for generating custom mip-map chains where each level needs access to the one
|
||||
* above.
|
||||
* DEPRECATED: Prefer using a compute shader with arbitrary imageLoad/Store for this purpose
|
||||
* as it is clearer and likely faster with optimizations.
|
||||
*/
|
||||
void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *framebuffer,
|
||||
int max_level,
|
||||
void (*per_level_callback)(void *userData, int level),
|
||||
void *userData);
|
||||
|
||||
#ifndef GPU_NO_USE_PY_REFERENCES
|
||||
void **GPU_framebuffer_py_reference_get(GPUFrameBuffer *gpu_fb);
|
||||
void GPU_framebuffer_py_reference_set(GPUFrameBuffer *gpu_fb, void **py_ref);
|
||||
#endif
|
||||
/** \} */
|
||||
|
||||
void GPU_framebuffer_push(GPUFrameBuffer *fb);
|
||||
GPUFrameBuffer *GPU_framebuffer_pop(void);
|
||||
uint GPU_framebuffer_stack_level_get(void);
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name GPU OffScreen
|
||||
*
|
||||
* A `GPUOffScreen` is a convenience type that holds a `GPUFramebuffer` and its associated
|
||||
* `GPUTexture`s. It is useful for quick drawing surface configuration.
|
||||
* NOTE: They are still limited by the same single context limitation as #GPUFrameBuffer.
|
||||
* \{ */
|
||||
|
||||
/* GPU OffScreen
|
||||
* - wrapper around frame-buffer and texture for simple off-screen drawing
|
||||
*/
|
||||
|
||||
GPUOffScreen *GPU_offscreen_create(
|
||||
int width, int height, bool depth, eGPUTextureFormat format, char err_out[256]);
|
||||
void GPU_offscreen_free(GPUOffScreen *ofs);
|
||||
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save);
|
||||
void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore);
|
||||
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, eGPUDataFormat format, void *pixels);
|
||||
void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y);
|
||||
int GPU_offscreen_width(const GPUOffScreen *ofs);
|
||||
int GPU_offscreen_height(const GPUOffScreen *ofs);
|
||||
struct GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs);
|
||||
typedef struct GPUOffScreen GPUOffScreen;
|
||||
|
||||
/**
|
||||
* Create a #GPUOffScreen with attachment size of \a width by \a height pixels.
|
||||
* If \a with_depth_buffer is true, a depth buffer attachment will also be created.
|
||||
* \a format is the format of the color buffer.
|
||||
* If \a err_out is not `nullptr` it will be use to write any configuration error message..
|
||||
* \note This function binds the framebuffer to the active context.
|
||||
*/
|
||||
GPUOffScreen *GPU_offscreen_create(
|
||||
int width, int height, bool with_depth_buffer, eGPUTextureFormat format, char err_out[256]);
|
||||
|
||||
/**
|
||||
* Free a #GPUOffScreen.
|
||||
*/
|
||||
void GPU_offscreen_free(GPUOffScreen *offscreen);
|
||||
|
||||
/**
|
||||
* Unbind a #GPUOffScreen from a #GPUContext.
|
||||
* If \a save is true, it will save the currently bound framebuffer into a stack.
|
||||
*/
|
||||
/* TODO(fclem): Remove the `save` parameter and always save/restore. */
|
||||
void GPU_offscreen_bind(GPUOffScreen *offscreen, bool save);
|
||||
|
||||
/**
|
||||
* Unbind a #GPUOffScreen from a #GPUContext.
|
||||
* If \a restore is true, it will restore the previously bound framebuffer. If false, it will bind
|
||||
* the window back-buffer.
|
||||
*/
|
||||
/* TODO(fclem): Remove the `save` parameter and always save/restore. */
|
||||
void GPU_offscreen_unbind(GPUOffScreen *offscreen, bool restore);
|
||||
|
||||
/**
|
||||
* Read the whole color texture of the a #GPUOffScreen.
|
||||
* The pixel data will be converted to \a data_format but it needs to be compatible with the
|
||||
* attachment type.
|
||||
* IMPORTANT: \a r_data must be big enough for all pixels in \a data_format .
|
||||
*/
|
||||
void GPU_offscreen_read_pixels(GPUOffScreen *offscreen, eGPUDataFormat data_format, void *r_data);
|
||||
|
||||
/**
|
||||
* Blit the offscreen color texture to the active framebuffer at the `(x, y)` location.
|
||||
*/
|
||||
void GPU_offscreen_draw_to_screen(GPUOffScreen *offscreen, int x, int y);
|
||||
|
||||
/**
|
||||
* Return the width of a #GPUOffScreen.
|
||||
*/
|
||||
int GPU_offscreen_width(const GPUOffScreen *offscreen);
|
||||
|
||||
/**
|
||||
* Return the height of a #GPUOffScreen.
|
||||
*/
|
||||
int GPU_offscreen_height(const GPUOffScreen *offscreen);
|
||||
|
||||
/**
|
||||
* Return the color texture of a #GPUOffScreen. Does not give ownership.
|
||||
* \note only to be used by viewport code!
|
||||
*/
|
||||
void GPU_offscreen_viewport_data_get(GPUOffScreen *ofs,
|
||||
struct GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *offscreen);
|
||||
|
||||
/**
|
||||
* Return the internals of a #GPUOffScreen. Does not give ownership.
|
||||
* \note only to be used by viewport code!
|
||||
*/
|
||||
void GPU_offscreen_viewport_data_get(GPUOffScreen *offscreen,
|
||||
GPUFrameBuffer **r_fb,
|
||||
struct GPUTexture **r_color,
|
||||
struct GPUTexture **r_depth);
|
||||
|
||||
void GPU_clear_color(float red, float green, float blue, float alpha);
|
||||
void GPU_clear_depth(float depth);
|
||||
|
||||
void GPU_frontbuffer_read_pixels(
|
||||
int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data);
|
||||
|
||||
void GPU_backbuffer_bind(eGPUBackBuffer buffer);
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -311,7 +311,9 @@ bool GPU_framebuffer_check_valid(GPUFrameBuffer *gpu_fb, char err_out[256])
|
||||
return unwrap(gpu_fb)->check(err_out);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_texture_attach_ex(GPUFrameBuffer *gpu_fb, GPUAttachment attachment, int slot)
|
||||
static void gpu_framebuffer_texture_attach_ex(GPUFrameBuffer *gpu_fb,
|
||||
GPUAttachment attachment,
|
||||
int slot)
|
||||
{
|
||||
Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
|
||||
GPUAttachmentType type = tex->attachment_type(slot);
|
||||
@@ -321,21 +323,21 @@ void GPU_framebuffer_texture_attach_ex(GPUFrameBuffer *gpu_fb, GPUAttachment att
|
||||
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
|
||||
{
|
||||
GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_MIP(tex, mip);
|
||||
GPU_framebuffer_texture_attach_ex(fb, attachment, slot);
|
||||
gpu_framebuffer_texture_attach_ex(fb, attachment, slot);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_texture_layer_attach(
|
||||
GPUFrameBuffer *fb, GPUTexture *tex, int slot, int layer, int mip)
|
||||
{
|
||||
GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_LAYER_MIP(tex, layer, mip);
|
||||
GPU_framebuffer_texture_attach_ex(fb, attachment, slot);
|
||||
gpu_framebuffer_texture_attach_ex(fb, attachment, slot);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_texture_cubeface_attach(
|
||||
GPUFrameBuffer *fb, GPUTexture *tex, int slot, int face, int mip)
|
||||
{
|
||||
GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(tex, face, mip);
|
||||
GPU_framebuffer_texture_attach_ex(fb, attachment, slot);
|
||||
gpu_framebuffer_texture_attach_ex(fb, attachment, slot);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
|
||||
@@ -408,6 +410,42 @@ void GPU_framebuffer_clear(GPUFrameBuffer *gpu_fb,
|
||||
unwrap(gpu_fb)->clear(buffers, clear_col, clear_depth, clear_stencil);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_color(GPUFrameBuffer *fb, const float clear_col[4])
|
||||
{
|
||||
GPU_framebuffer_clear(fb, GPU_COLOR_BIT, clear_col, 0.0f, 0x00);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_depth(GPUFrameBuffer *fb, float clear_depth)
|
||||
{
|
||||
GPU_framebuffer_clear(fb, GPU_DEPTH_BIT, NULL, clear_depth, 0x00);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_color_depth(GPUFrameBuffer *fb,
|
||||
const float clear_col[4],
|
||||
float clear_depth)
|
||||
{
|
||||
GPU_framebuffer_clear(fb, GPU_COLOR_BIT | GPU_DEPTH_BIT, clear_col, clear_depth, 0x00);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_stencil(GPUFrameBuffer *fb, uint clear_stencil)
|
||||
{
|
||||
GPU_framebuffer_clear(fb, GPU_STENCIL_BIT, NULL, 0.0f, clear_stencil);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_depth_stencil(GPUFrameBuffer *fb, float clear_depth, uint clear_stencil)
|
||||
{
|
||||
GPU_framebuffer_clear(fb, GPU_DEPTH_BIT | GPU_STENCIL_BIT, NULL, clear_depth, clear_stencil);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_color_depth_stencil(GPUFrameBuffer *fb,
|
||||
const float clear_col[4],
|
||||
float clear_depth,
|
||||
uint clear_stencil)
|
||||
{
|
||||
GPU_framebuffer_clear(
|
||||
fb, GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT, clear_col, clear_depth, clear_stencil);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_multi_clear(GPUFrameBuffer *gpu_fb, const float (*clear_cols)[4])
|
||||
{
|
||||
unwrap(gpu_fb)->clear_multi(clear_cols);
|
||||
|
||||
Reference in New Issue
Block a user