Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_state.h
- This file was added.
| /* SPDX-License-Identifier: GPL-2.0-or-later | |||||
| * Copyright 2022 Blender Foundation. */ | |||||
| #pragma once | |||||
| #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 | |||||