Commit: 2ae1c895a2f7590d0783a27176085da45ef12bc5
Author: Clément Foucault
Date: Sun Aug 16 14:01:07 2020 +0200
Branches: master
https://developer.blender.org/rB2ae1c895a2f7590d0783a27176085da45ef12bc5
GPUState: Add GL backend and state tracking but do not use it
This is just the backend work. It is not plugged in yet because it
needs more external cleanup/refactor.
===================================================================
M source/blender/gpu/CMakeLists.txt
M source/blender/gpu/GPU_material.h
M source/blender/gpu/GPU_state.h
M source/blender/gpu/intern/gpu_state.cc
A source/blender/gpu/intern/gpu_state_private.hh
A source/blender/gpu/opengl/gl_state.cc
A source/blender/gpu/opengl/gl_state.hh
===================================================================
diff --git a/source/blender/gpu/CMakeLists.txt
b/source/blender/gpu/CMakeLists.txt
index bcf2bc42402..45b379c5e0a 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -93,6 +93,7 @@ set(SRC
opengl/gl_context.cc
opengl/gl_drawlist.cc
opengl/gl_shader.cc
+ opengl/gl_state.cc
opengl/gl_vertex_array.cc
GPU_attr_binding.h
@@ -139,6 +140,7 @@ set(SRC
intern/gpu_private.h
intern/gpu_select_private.h
intern/gpu_shader_private.hh
+ intern/gpu_state_private.hh
intern/gpu_vertex_format_private.h
opengl/gl_backend.hh
@@ -146,6 +148,7 @@ set(SRC
opengl/gl_context.hh
opengl/gl_drawlist.hh
opengl/gl_shader.hh
+ opengl/gl_state.hh
opengl/gl_vertex_array.hh
)
diff --git a/source/blender/gpu/GPU_material.h
b/source/blender/gpu/GPU_material.h
index b8957ff1819..9dcf9b7d5bb 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -112,15 +112,6 @@ typedef enum eGPUMatFlag {
GPU_MATFLAG_BARYCENTRIC = (1 << 4),
} eGPUMatFlag;
-typedef enum eGPUBlendMode {
- GPU_BLEND_SOLID = 0,
- GPU_BLEND_ADD = 1,
- GPU_BLEND_ALPHA = 2,
- GPU_BLEND_CLIP = 4,
- GPU_BLEND_ALPHA_SORT = 8,
- GPU_BLEND_ALPHA_TO_COVERAGE = 16,
-} eGPUBlendMode;
-
typedef struct GPUNodeStack {
eGPUType type;
float vec[4];
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 2a940b97104..19bb8001491 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -24,6 +24,70 @@
extern "C" {
#endif
+typedef enum eGPUWriteMask {
+ GPU_WRITE_RED = (1 << 0),
+ GPU_WRITE_GREEN = (1 << 1),
+ GPU_WRITE_BLUE = (1 << 2),
+ GPU_WRITE_ALPHA = (1 << 3),
+ GPU_WRITE_DEPTH = (1 << 4),
+ GPU_WRITE_COLOR = (GPU_WRITE_RED | GPU_WRITE_GREEN | GPU_WRITE_BLUE |
GPU_WRITE_ALPHA),
+} eGPUWriteMask;
+
+/**
+ * Defines the fixed pipeline blending equation.
+ * SRC is the output color from the shader.
+ * DST is the color from the framebuffer.
+ * The blending equation is :
+ * (SRC * A) + (DST * B).
+ * The blend mode will modify the A and B parameters.
+ */
+typedef enum eGPUBlend {
+ GPU_BLEND_NONE = 0,
+ /** Premult variants will _NOT_ multiply rgb output by alpha. */
+ GPU_BLEND_ALPHA,
+ GPU_BLEND_ALPHA_PREMULT,
+ GPU_BLEND_ADDITIVE,
+ GPU_BLEND_ADDITIVE_PREMULT,
+ GPU_BLEND_MULTIPLY,
+ GPU_BLEND_SUBTRACT,
+ /** Replace logic op: SRC * (1 - DST)
+ * NOTE: Does not modify alpha. */
+ GPU_BLEND_INVERT,
+ /** Order independant transparency.
+ * NOTE: Cannot be used as is. Needs special setup (framebuffer, shader
...). */
+ GPU_BLEND_OIT,
+ /** Special blend to add color under and multiply dst color by src alpha. */
+ GPU_BLEND_BACKGROUND,
+ /** Custom blend parameters using dual source blending : SRC0 + SRC1 * DST
+ * NOTE: Can only be used with _ONE_ Draw Buffer and shader needs to be
specialized. */
+ GPU_BLEND_CUSTOM,
+} eGPUBlend;
+
+typedef enum eGPUDepthTest {
+ GPU_DEPTH_NONE = 0,
+ GPU_DEPTH_ALWAYS,
+ GPU_DEPTH_LESS,
+ GPU_DEPTH_LESS_EQUAL,
+ GPU_DEPTH_EQUAL,
+ GPU_DEPTH_GREATER,
+ GPU_DEPTH_GREATER_EQUAL,
+} eGPUDepthTest;
+
+typedef enum eGPUStencilTest {
+ GPU_STENCIL_NONE = 0,
+ GPU_STENCIL_ALWAYS,
+ GPU_STENCIL_EQUAL,
+ GPU_STENCIL_NEQUAL,
+} eGPUStencilTest;
+
+typedef enum eGPUStencilOp {
+ GPU_STENCIL_OP_NONE = 0,
+ GPU_STENCIL_OP_REPLACE,
+ /** Special values for stencil shadows. */
+ GPU_STENCIL_OP_COUNT_DEPTH_PASS,
+ GPU_STENCIL_OP_COUNT_DEPTH_FAIL,
+} eGPUStencilOp;
+
/* These map directly to the GL_ blend functions, to minimize API add as
needed*/
typedef enum eGPUBlendFunction {
GPU_ONE,
@@ -33,21 +97,15 @@ typedef enum eGPUBlendFunction {
GPU_ZERO,
} eGPUBlendFunction;
-/* These map directly to the GL_ filter functions, to minimize API add as
needed*/
-typedef enum eGPUFilterFunction {
- GPU_NEAREST,
- GPU_LINEAR,
-} eGPUFilterFunction;
-
-typedef enum eGPUFaceCull {
+typedef enum eGPUFaceCullTest {
GPU_CULL_NONE = 0, /* Culling disabled. */
GPU_CULL_FRONT,
GPU_CULL_BACK,
-} eGPUFaceCull;
+} eGPUFaceCullTest;
typedef enum eGPUProvokingVertex {
- GPU_VERTEX_FIRST = 0,
- GPU_VERTEX_LAST, /* Default */
+ GPU_VERTEX_LAST = 0, /* Default. */
+ GPU_VERTEX_FIRST = 1, /* Follow Blender loop order. */
} eGPUProvokingVertex;
/* Initialize
@@ -62,7 +120,7 @@ void GPU_blend_set_func_separate(eGPUBlendFunction src_rgb,
eGPUBlendFunction dst_rgb,
eGPUBlendFunction src_alpha,
eGPUBlendFunction dst_alpha);
-void GPU_face_culling(eGPUFaceCull culling);
+void GPU_face_culling(eGPUFaceCullTest culling);
void GPU_front_facing(bool invert);
void GPU_provoking_vertex(eGPUProvokingVertex vert);
void GPU_depth_range(float near, float far);
diff --git a/source/blender/gpu/intern/gpu_state.cc
b/source/blender/gpu/intern/gpu_state.cc
index d697b465458..485aa3b852e 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -33,6 +33,10 @@
#include "GPU_glew.h"
#include "GPU_state.h"
+#include "gpu_state_private.hh"
+
+using namespace blender::gpu;
+
static GLenum gpu_get_gl_blendfunction(eGPUBlendFunction blend)
{
switch (blend) {
@@ -78,7 +82,7 @@ void GPU_blend_set_func_separate(eGPUBlendFunction src_rgb,
gpu_get_gl_blendfunction(dst_alpha));
}
-void GPU_face_culling(eGPUFaceCull culling)
+void GPU_face_culling(eGPUFaceCullTest culling)
{
if (culling == GPU_CULL_NONE) {
glDisable(GL_CULL_FACE);
@@ -269,6 +273,35 @@ bool GPU_mipmap_enabled(void)
return true;
}
+/* -------------------------------------------------------------------- */
+/** \name Draw State (DRW_state)
+ * \{ */
+
+void GPUStateStack::push_stack(void)
+{
+ stack[stack_top + 1] = stack[stack_top];
+ stack_top++;
+}
+
+void GPUStateStack::pop_stack(void)
+{
+ stack_top--;
+}
+
+void GPUStateStack::push_mutable_stack(void)
+{
+ mutable_stack[mutable_stack_top + 1] = mutable_stack[mutable_stack_top];
+ mutable_stack_top++;
+}
+
+void GPUStateStack::pop_mutable_stack(void)
+{
+ mutable_stack_top--;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name GPU Push/Pop State
* \{ */
diff --git a/source/blender/gpu/intern/gpu_state_private.hh
b/source/blender/gpu/intern/gpu_state_private.hh
new file mode 100644
index 00000000000..0ac538d117c
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_state_private.hh
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ *
+ * Copyright 2020, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "BLI_utildefines.h"
+
+#include "GPU_state.h"
+
+#include <cstring>
+
+namespace blender {
+namespace gpu {
+
+/* Ecapsulate all pipeline state that we need to track.
+ * Try to keep small to reduce validation time. */
+union GPUState {
+ struct {
+ eGPUWriteMask write_mask : 13;
+ eGPUBlend blend : 4;
+ eGPUFaceCullTest culling_test : 2;
+ eGPUDepthTest depth_test : 3;
+ eGPUStencilTest stencil_test : 3;
+ eGPUStencilOp stencil_op : 3;
+ eGPUProvokingVertex provoking_vert : 1;
+ /** Enable bits. */
+ uint32_t logic_op_xor : 1;
+ uint32_t invert_facing : 1;
+ uint32_t shadow_bias : 1;
+ /** Number of clip distances enabled. */
+ /* TODO(fclem) This should be a shader property. */
+ uint32_t clip_distances : 3;
+ /* TODO(fclem) remove, old opengl features. */
+ uint32_t polygon_smooth : 1;
+ uint32_t line_smooth : 1;
+ };
+ /* Here to allow fast bitwise ops. */
+ uint64_t data;
+};
+
+BLI_STATIC_ASSERT(sizeof(GPUState) == sizeof(uint64_t), "GPUState is too
big.");
+
+inline bool operator==(const GPUState &a, const GPUState &b)
+{
+ return a.data == b.data;
+}
+
+inline bool operator!=(const GPUState &a, const GPUState &b)
+{
+ return !(a == b);
+}
+
+inline GPUState operator^(const GPUState &a, const GPUState &b)
+{
+ GPUState r;
+ r.data = a.data ^ b.data;
+ return r;
+}
+
+/* Mutable state that does not require pipeline change. */
+union GPUStateMutable {
+ struct {
+ /** Offset + Extent of the drawable region inside the framebuffer. */
+ int viewport_rect[4];
+ /** Offset + Extent of the scissor region inside the framebuffer. */
+ int scissor_rect[4];
+ /** TODO remove */
+ float depth_range[2];
+ /** TODO remove, use explicit clear calls. */
+ float clear_color[4];
+ float clear_depth;
+ /** Negative if using program point size. */
+ /* TODO(fclem) should be passed as uniform to all shaders. */
+ float point_size;
+ /** Not supported on every platform. Prefer using wideline shader. */
+ float line_width;
+ /** Mutable stencil states. */
+ uint8_t stencil_write_mask;
+ uint8_t stencil_compare_mask;
+ uint8_t stencil_reference;
+ uint8_t _pad0;
+ /* IMPORTANT: ensure x64 stuct alignment. */
+ };
+ /* Here to allow fast bitwise ops. */
+ uint64_t data[9];
+};
+
+BLI_STATIC_ASSERT(sizeof(GPUStateMutable) == sizeof(GPUStateMutable::data),
+ "GPUStateMutable is too big.");
+
+inline bool operator==(const GPUStateMutable &a, const GPUStateMutable &b)
+{
+ return memcmp(&a, &b, sizeof(GPUStateMutable)) == 0;
+}
+
+inline bool operator!=(const GPUStateMutable &a, const GPUStateMutable &b)
+{
+ return !(a == b);
+}
+
+inline GPUStateMutable operator^(const GPUStateMutable &a, const
GPUStateMutable &b)
+{
+ GPUStateMutable r;
+ for (int i = 0; i < ARRAY_SIZE(a.data); i++)
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs