Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-08-16 15:01:07 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-08-18 22:30:10 +0300
commit2ae1c895a2f7590d0783a27176085da45ef12bc5 (patch)
treee4cb63134deaca31908b4e9ddfff96614bfa1e0e /source/blender/gpu/intern
parent2eddfa85e00d9efa7571721e605a331ca4cd5bc6 (diff)
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.
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_state.cc35
-rw-r--r--source/blender/gpu/intern/gpu_state_private.hh164
2 files changed, 198 insertions, 1 deletions
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++) {
+ r.data[i] = a.data[i] ^ b.data[i];
+ }
+ return r;
+}
+
+#define GPU_STATE_STACK_LEN 4
+
+class GPUStateStack {
+ private:
+ /** Stack of state for quick temporary modification of the state. */
+ GPUState stack[GPU_STATE_STACK_LEN];
+ GPUStateMutable mutable_stack[GPU_STATE_STACK_LEN];
+ int stack_top = 0;
+ int mutable_stack_top = 0;
+
+ public:
+ virtual void set_state(GPUState &state) = 0;
+ virtual void set_mutable_state(GPUStateMutable &state) = 0;
+
+ void push_stack(void);
+ void pop_stack(void);
+
+ void push_mutable_stack(void);
+ void pop_mutable_stack(void);
+
+ inline GPUState &stack_top_get(void);
+ inline GPUStateMutable &mutable_stack_top_get(void);
+};
+
+inline GPUState &GPUStateStack::stack_top_get(void)
+{
+ return stack[stack_top];
+}
+
+inline GPUStateMutable &GPUStateStack::mutable_stack_top_get(void)
+{
+ return mutable_stack[mutable_stack_top];
+}
+
+} // namespace gpu
+} // namespace blender