Files
test/source/blender/draw/intern/draw_state.h
Campbell Barton e955c94ed3 License Headers: Set copyright to "Blender Authors", add AUTHORS
Listing the "Blender Foundation" as copyright holder implied the Blender
Foundation holds copyright to files which may include work from many
developers.

While keeping copyright on headers makes sense for isolated libraries,
Blender's own code may be refactored or moved between files in a way
that makes the per file copyright holders less meaningful.

Copyright references to the "Blender Foundation" have been replaced with
"Blender Authors", with the exception of `./extern/` since these this
contains libraries which are more isolated, any changed to license
headers there can be handled on a case-by-case basis.

Some directories in `./intern/` have also been excluded:

- `./intern/cycles/` it's own `AUTHORS` file is planned.
- `./intern/opensubdiv/`.

An "AUTHORS" file has been added, using the chromium projects authors
file as a template.

Design task: #110784

Ref !110783.
2023-08-16 00:20:26 +10:00

229 lines
7.1 KiB
C++

/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "BLI_utildefines.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file
* \ingroup draw
*
* Internal Pipeline State tracking. It is higher level than GPU state as everything fits a single
* enum.
*/
/**
* DRWState is a bit-mask that stores the current render state and the desired render state. Based
* on the differences the minimum state changes can be invoked to setup the desired render state.
*
* The Write Stencil, Stencil test, Depth test and Blend state options are mutual exclusive
* therefore they aren't ordered as a bit mask.
*/
typedef enum {
/** To be used for compute passes. */
DRW_STATE_NO_DRAW = 0,
/** Write mask */
DRW_STATE_WRITE_DEPTH = (1 << 0),
DRW_STATE_WRITE_COLOR = (1 << 1),
/* Write Stencil. These options are mutual exclusive and packed into 2 bits */
DRW_STATE_WRITE_STENCIL = (1 << 2),
DRW_STATE_WRITE_STENCIL_SHADOW_PASS = (2 << 2),
DRW_STATE_WRITE_STENCIL_SHADOW_FAIL = (3 << 2),
/** Depth test. These options are mutual exclusive and packed into 3 bits */
DRW_STATE_DEPTH_ALWAYS = (1 << 4),
DRW_STATE_DEPTH_LESS = (2 << 4),
DRW_STATE_DEPTH_LESS_EQUAL = (3 << 4),
DRW_STATE_DEPTH_EQUAL = (4 << 4),
DRW_STATE_DEPTH_GREATER = (5 << 4),
DRW_STATE_DEPTH_GREATER_EQUAL = (6 << 4),
/** Culling test */
DRW_STATE_CULL_BACK = (1 << 7),
DRW_STATE_CULL_FRONT = (1 << 8),
/** Stencil test. These options are mutually exclusive and packed into 2 bits. */
DRW_STATE_STENCIL_ALWAYS = (1 << 9),
DRW_STATE_STENCIL_EQUAL = (2 << 9),
DRW_STATE_STENCIL_NEQUAL = (3 << 9),
/** Blend state. These options are mutual exclusive and packed into 4 bits */
DRW_STATE_BLEND_ADD = (1 << 11),
/** Same as additive but let alpha accumulate without pre-multiply. */
DRW_STATE_BLEND_ADD_FULL = (2 << 11),
/** Standard alpha blending. */
DRW_STATE_BLEND_ALPHA = (3 << 11),
/** Use that if color is already pre-multiply by alpha. */
DRW_STATE_BLEND_ALPHA_PREMUL = (4 << 11),
DRW_STATE_BLEND_BACKGROUND = (5 << 11),
DRW_STATE_BLEND_OIT = (6 << 11),
DRW_STATE_BLEND_MUL = (7 << 11),
DRW_STATE_BLEND_SUB = (8 << 11),
/** Use dual source blending. WARNING: Only one color buffer allowed. */
DRW_STATE_BLEND_CUSTOM = (9 << 11),
DRW_STATE_LOGIC_INVERT = (10 << 11),
DRW_STATE_BLEND_ALPHA_UNDER_PREMUL = (11 << 11),
DRW_STATE_IN_FRONT_SELECT = (1 << 27),
DRW_STATE_SHADOW_OFFSET = (1 << 28),
DRW_STATE_CLIP_PLANES = (1 << 29),
DRW_STATE_FIRST_VERTEX_CONVENTION = (1 << 30),
/** DO NOT USE. Assumed always enabled. Only used internally. */
DRW_STATE_PROGRAM_POINT_SIZE = (1u << 31),
} DRWState;
ENUM_OPERATORS(DRWState, DRW_STATE_PROGRAM_POINT_SIZE);
#define DRW_STATE_DEFAULT \
(DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL)
#define DRW_STATE_BLEND_ENABLED \
(DRW_STATE_BLEND_ADD | DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_ALPHA | \
DRW_STATE_BLEND_ALPHA_PREMUL | DRW_STATE_BLEND_BACKGROUND | DRW_STATE_BLEND_OIT | \
DRW_STATE_BLEND_MUL | DRW_STATE_BLEND_SUB | DRW_STATE_BLEND_CUSTOM | DRW_STATE_LOGIC_INVERT)
#define DRW_STATE_RASTERIZER_ENABLED \
(DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_STENCIL | \
DRW_STATE_WRITE_STENCIL_SHADOW_PASS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL)
#define DRW_STATE_DEPTH_TEST_ENABLED \
(DRW_STATE_DEPTH_ALWAYS | DRW_STATE_DEPTH_LESS | DRW_STATE_DEPTH_LESS_EQUAL | \
DRW_STATE_DEPTH_EQUAL | DRW_STATE_DEPTH_GREATER | DRW_STATE_DEPTH_GREATER_EQUAL)
#define DRW_STATE_STENCIL_TEST_ENABLED \
(DRW_STATE_STENCIL_ALWAYS | DRW_STATE_STENCIL_EQUAL | DRW_STATE_STENCIL_NEQUAL)
#define DRW_STATE_WRITE_STENCIL_ENABLED \
(DRW_STATE_WRITE_STENCIL | DRW_STATE_WRITE_STENCIL_SHADOW_PASS | \
DRW_STATE_WRITE_STENCIL_SHADOW_FAIL)
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
namespace blender::draw {
/* -------------------------------------------------------------------- */
/** \name DRWState to GPU state conversion
* \{ */
static inline eGPUWriteMask to_write_mask(DRWState state)
{
eGPUWriteMask write_mask = GPU_WRITE_NONE;
if (state & DRW_STATE_WRITE_DEPTH) {
write_mask |= GPU_WRITE_DEPTH;
}
if (state & DRW_STATE_WRITE_COLOR) {
write_mask |= GPU_WRITE_COLOR;
}
if (state & DRW_STATE_WRITE_STENCIL_ENABLED) {
write_mask |= GPU_WRITE_STENCIL;
}
return write_mask;
}
static inline eGPUFaceCullTest to_face_cull_test(DRWState state)
{
switch (state & (DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT)) {
case DRW_STATE_CULL_BACK:
return GPU_CULL_BACK;
case DRW_STATE_CULL_FRONT:
return GPU_CULL_FRONT;
default:
return GPU_CULL_NONE;
}
}
static inline eGPUDepthTest to_depth_test(DRWState state)
{
switch (state & DRW_STATE_DEPTH_TEST_ENABLED) {
case DRW_STATE_DEPTH_LESS:
return GPU_DEPTH_LESS;
case DRW_STATE_DEPTH_LESS_EQUAL:
return GPU_DEPTH_LESS_EQUAL;
case DRW_STATE_DEPTH_EQUAL:
return GPU_DEPTH_EQUAL;
case DRW_STATE_DEPTH_GREATER:
return GPU_DEPTH_GREATER;
case DRW_STATE_DEPTH_GREATER_EQUAL:
return GPU_DEPTH_GREATER_EQUAL;
case DRW_STATE_DEPTH_ALWAYS:
return GPU_DEPTH_ALWAYS;
default:
return GPU_DEPTH_NONE;
}
}
static inline eGPUStencilOp to_stencil_op(DRWState state)
{
switch (state & DRW_STATE_WRITE_STENCIL_ENABLED) {
case DRW_STATE_WRITE_STENCIL:
return GPU_STENCIL_OP_REPLACE;
case DRW_STATE_WRITE_STENCIL_SHADOW_PASS:
return GPU_STENCIL_OP_COUNT_DEPTH_PASS;
case DRW_STATE_WRITE_STENCIL_SHADOW_FAIL:
return GPU_STENCIL_OP_COUNT_DEPTH_FAIL;
default:
return GPU_STENCIL_OP_NONE;
}
}
static inline eGPUStencilTest to_stencil_test(DRWState state)
{
switch (state & DRW_STATE_STENCIL_TEST_ENABLED) {
case DRW_STATE_STENCIL_ALWAYS:
return GPU_STENCIL_ALWAYS;
case DRW_STATE_STENCIL_EQUAL:
return GPU_STENCIL_EQUAL;
case DRW_STATE_STENCIL_NEQUAL:
return GPU_STENCIL_NEQUAL;
default:
return GPU_STENCIL_NONE;
}
}
static inline eGPUBlend to_blend(DRWState state)
{
switch (state & DRW_STATE_BLEND_ENABLED) {
case DRW_STATE_BLEND_ADD:
return GPU_BLEND_ADDITIVE;
case DRW_STATE_BLEND_ADD_FULL:
return GPU_BLEND_ADDITIVE_PREMULT;
case DRW_STATE_BLEND_ALPHA:
return GPU_BLEND_ALPHA;
case DRW_STATE_BLEND_ALPHA_PREMUL:
return GPU_BLEND_ALPHA_PREMULT;
case DRW_STATE_BLEND_BACKGROUND:
return GPU_BLEND_BACKGROUND;
case DRW_STATE_BLEND_OIT:
return GPU_BLEND_OIT;
case DRW_STATE_BLEND_MUL:
return GPU_BLEND_MULTIPLY;
case DRW_STATE_BLEND_SUB:
return GPU_BLEND_SUBTRACT;
case DRW_STATE_BLEND_CUSTOM:
return GPU_BLEND_CUSTOM;
case DRW_STATE_LOGIC_INVERT:
return GPU_BLEND_INVERT;
case DRW_STATE_BLEND_ALPHA_UNDER_PREMUL:
return GPU_BLEND_ALPHA_UNDER_PREMUL;
default:
return GPU_BLEND_NONE;
}
}
static inline eGPUProvokingVertex to_provoking_vertex(DRWState state)
{
switch (state & DRW_STATE_FIRST_VERTEX_CONVENTION) {
case DRW_STATE_FIRST_VERTEX_CONVENTION:
return GPU_VERTEX_FIRST;
default:
return GPU_VERTEX_LAST;
}
}
/** \} */
}; // namespace blender::draw
#endif