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

Reply via email to