diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-08-16 15:01:07 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-08-18 22:30:10 +0300 |
commit | 2ae1c895a2f7590d0783a27176085da45ef12bc5 (patch) | |
tree | e4cb63134deaca31908b4e9ddfff96614bfa1e0e /source/blender/gpu/intern | |
parent | 2eddfa85e00d9efa7571721e605a331ca4cd5bc6 (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.cc | 35 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_state_private.hh | 164 |
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 |