Cleanup: GPUState: Remove stack from the state manager and rename it

This commit is contained in:
Clément Foucault
2020-08-17 00:34:06 +02:00
parent d10f000322
commit 482a51aabf
8 changed files with 75 additions and 125 deletions

View File

@@ -824,10 +824,12 @@
#define GL_SOURCE0_ALPHA DO_NOT_USE_GL_SOURCE0_ALPHA #define GL_SOURCE0_ALPHA DO_NOT_USE_GL_SOURCE0_ALPHA
#undef GL_SOURCE0_RGB #undef GL_SOURCE0_RGB
#define GL_SOURCE0_RGB DO_NOT_USE_GL_SOURCE0_RGB #define GL_SOURCE0_RGB DO_NOT_USE_GL_SOURCE0_RGB
#undef GL_SOURCE1_ALPHA #if 0 /* Those are reused as new valid enum! GL_SRC1_COLOR etc... */
#define GL_SOURCE1_ALPHA DO_NOT_USE_GL_SOURCE1_ALPHA # undef GL_SOURCE1_ALPHA
#undef GL_SOURCE1_RGB # define GL_SOURCE1_ALPHA DO_NOT_USE_GL_SOURCE1_ALPHA
#define GL_SOURCE1_RGB DO_NOT_USE_GL_SOURCE1_RGB # undef GL_SOURCE1_RGB
# define GL_SOURCE1_RGB DO_NOT_USE_GL_SOURCE1_RGB
#endif
#undef GL_SOURCE2_ALPHA #undef GL_SOURCE2_ALPHA
#define GL_SOURCE2_ALPHA DO_NOT_USE_GL_SOURCE2_ALPHA #define GL_SOURCE2_ALPHA DO_NOT_USE_GL_SOURCE2_ALPHA
#undef GL_SOURCE2_RGB #undef GL_SOURCE2_RGB

View File

@@ -70,7 +70,7 @@ GPUContext::GPUContext()
GPUContext::~GPUContext() GPUContext::~GPUContext()
{ {
GPU_matrix_state_discard(matrix_state); GPU_matrix_state_discard(matrix_state);
delete state_stack; delete state_manager;
} }
bool GPUContext::is_active_on_thread(void) bool GPUContext::is_active_on_thread(void)

View File

@@ -46,7 +46,7 @@ struct GPUContext {
GPUShader *shader = NULL; GPUShader *shader = NULL;
GPUFrameBuffer *current_fbo = NULL; GPUFrameBuffer *current_fbo = NULL;
GPUMatrixState *matrix_state = NULL; GPUMatrixState *matrix_state = NULL;
blender::gpu::GPUStateStack *state_stack = NULL; blender::gpu::GPUStateManager *state_manager = NULL;
protected: protected:
/** Thread on which this context is active. */ /** Thread on which this context is active. */

View File

@@ -38,15 +38,12 @@
#include "gpu_state_private.hh" #include "gpu_state_private.hh"
/* TODO remove */
#include "gl_state.hh"
using namespace blender::gpu; using namespace blender::gpu;
#define SET_STATE(_prefix, _state, _value) \ #define SET_STATE(_prefix, _state, _value) \
do { \ do { \
GPUStateStack *stack = GPU_context_active_get()->state_stack; \ GPUStateManager *stack = GPU_context_active_get()->state_manager; \
auto &state_object = stack->_prefix##stack_top_get(); \ auto &state_object = stack->_prefix##state; \
state_object._state = _value; \ state_object._state = _value; \
/* TODO remove this and only push state at draw time. */ \ /* TODO remove this and only push state at draw time. */ \
stack->set_##_prefix##state(state_object); \ stack->set_##_prefix##state(state_object); \
@@ -107,8 +104,8 @@ void GPU_write_mask(eGPUWriteMask mask)
void GPU_color_mask(bool r, bool g, bool b, bool a) void GPU_color_mask(bool r, bool g, bool b, bool a)
{ {
GPUStateStack *stack = GPU_context_active_get()->state_stack; GPUStateManager *stack = GPU_context_active_get()->state_manager;
auto &state = stack->stack_top_get(); auto &state = stack->state;
eGPUWriteMask write_mask = state.write_mask; eGPUWriteMask write_mask = state.write_mask;
SET_FLAG_FROM_TEST(write_mask, r, GPU_WRITE_RED); SET_FLAG_FROM_TEST(write_mask, r, GPU_WRITE_RED);
SET_FLAG_FROM_TEST(write_mask, g, GPU_WRITE_GREEN); SET_FLAG_FROM_TEST(write_mask, g, GPU_WRITE_GREEN);
@@ -121,8 +118,8 @@ void GPU_color_mask(bool r, bool g, bool b, bool a)
void GPU_depth_mask(bool depth) void GPU_depth_mask(bool depth)
{ {
GPUStateStack *stack = GPU_context_active_get()->state_stack; GPUStateManager *stack = GPU_context_active_get()->state_manager;
auto &state = stack->stack_top_get(); auto &state = stack->state;
eGPUWriteMask write_mask = state.write_mask; eGPUWriteMask write_mask = state.write_mask;
SET_FLAG_FROM_TEST(write_mask, depth, GPU_WRITE_DEPTH); SET_FLAG_FROM_TEST(write_mask, depth, GPU_WRITE_DEPTH);
state.write_mask = write_mask; state.write_mask = write_mask;
@@ -143,8 +140,8 @@ void GPU_clip_distances(int distances_enabled)
void GPU_depth_range(float near, float far) void GPU_depth_range(float near, float far)
{ {
GPUStateStack *stack = GPU_context_active_get()->state_stack; GPUStateManager *stack = GPU_context_active_get()->state_manager;
auto &state = stack->mutable_stack_top_get(); auto &state = stack->mutable_state;
copy_v2_fl2(state.depth_range, near, far); copy_v2_fl2(state.depth_range, near, far);
/* TODO remove this and only push state at draw time. */ /* TODO remove this and only push state at draw time. */
stack->set_mutable_state(state); stack->set_mutable_state(state);
@@ -166,8 +163,8 @@ void GPU_point_size(float size)
/* TODO remove and use program point size everywhere */ /* TODO remove and use program point size everywhere */
void GPU_program_point_size(bool enable) void GPU_program_point_size(bool enable)
{ {
GPUStateStack *stack = GPU_context_active_get()->state_stack; GPUStateManager *stack = GPU_context_active_get()->state_manager;
auto &state = stack->mutable_stack_top_get(); auto &state = stack->mutable_state;
/* Set point size sign negative to disable. */ /* Set point size sign negative to disable. */
state.point_size = fabsf(state.point_size) * (enable ? 1 : -1); state.point_size = fabsf(state.point_size) * (enable ? 1 : -1);
/* TODO remove this and only push state at draw time. */ /* TODO remove this and only push state at draw time. */
@@ -176,8 +173,8 @@ void GPU_program_point_size(bool enable)
void GPU_scissor_test(bool enable) void GPU_scissor_test(bool enable)
{ {
GPUStateStack *stack = GPU_context_active_get()->state_stack; GPUStateManager *stack = GPU_context_active_get()->state_manager;
auto &state = stack->mutable_stack_top_get(); auto &state = stack->mutable_state;
/* Set point size sign negative to disable. */ /* Set point size sign negative to disable. */
state.scissor_rect[2] = abs(state.scissor_rect[2]) * (enable ? 1 : -1); state.scissor_rect[2] = abs(state.scissor_rect[2]) * (enable ? 1 : -1);
/* TODO remove this and only push state at draw time. */ /* TODO remove this and only push state at draw time. */
@@ -186,8 +183,8 @@ void GPU_scissor_test(bool enable)
void GPU_scissor(int x, int y, int width, int height) void GPU_scissor(int x, int y, int width, int height)
{ {
GPUStateStack *stack = GPU_context_active_get()->state_stack; GPUStateManager *stack = GPU_context_active_get()->state_manager;
auto &state = stack->mutable_stack_top_get(); auto &state = stack->mutable_state;
int scissor_rect[4] = {x, y, width, height}; int scissor_rect[4] = {x, y, width, height};
copy_v4_v4_int(state.scissor_rect, scissor_rect); copy_v4_v4_int(state.scissor_rect, scissor_rect);
/* TODO remove this and only push state at draw time. */ /* TODO remove this and only push state at draw time. */
@@ -196,8 +193,8 @@ void GPU_scissor(int x, int y, int width, int height)
void GPU_viewport(int x, int y, int width, int height) void GPU_viewport(int x, int y, int width, int height)
{ {
GPUStateStack *stack = GPU_context_active_get()->state_stack; GPUStateManager *stack = GPU_context_active_get()->state_manager;
auto &state = stack->mutable_stack_top_get(); auto &state = stack->mutable_state;
int viewport_rect[4] = {x, y, width, height}; int viewport_rect[4] = {x, y, width, height};
copy_v4_v4_int(state.viewport_rect, viewport_rect); copy_v4_v4_int(state.viewport_rect, viewport_rect);
/* TODO remove this and only push state at draw time. */ /* TODO remove this and only push state at draw time. */
@@ -212,31 +209,31 @@ void GPU_viewport(int x, int y, int width, int height)
eGPUBlend GPU_blend_get() eGPUBlend GPU_blend_get()
{ {
GPUState &state = GPU_context_active_get()->state_stack->stack_top_get(); GPUState &state = GPU_context_active_get()->state_manager->state;
return state.blend; return state.blend;
} }
eGPUWriteMask GPU_write_mask_get() eGPUWriteMask GPU_write_mask_get()
{ {
GPUState &state = GPU_context_active_get()->state_stack->stack_top_get(); GPUState &state = GPU_context_active_get()->state_manager->state;
return state.write_mask; return state.write_mask;
} }
bool GPU_depth_test_enabled() bool GPU_depth_test_enabled()
{ {
GPUState &state = GPU_context_active_get()->state_stack->stack_top_get(); GPUState &state = GPU_context_active_get()->state_manager->state;
return state.depth_test != GPU_DEPTH_NONE; return state.depth_test != GPU_DEPTH_NONE;
} }
void GPU_scissor_get(int coords[4]) void GPU_scissor_get(int coords[4])
{ {
GPUStateMutable &state = GPU_context_active_get()->state_stack->mutable_stack_top_get(); GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state;
copy_v4_v4_int(coords, state.scissor_rect); copy_v4_v4_int(coords, state.scissor_rect);
} }
void GPU_viewport_size_get_f(float coords[4]) void GPU_viewport_size_get_f(float coords[4])
{ {
GPUStateMutable &state = GPU_context_active_get()->state_stack->mutable_stack_top_get(); GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
coords[i] = state.viewport_rect[i]; coords[i] = state.viewport_rect[i];
} }
@@ -244,13 +241,13 @@ void GPU_viewport_size_get_f(float coords[4])
void GPU_viewport_size_get_i(int coords[4]) void GPU_viewport_size_get_i(int coords[4])
{ {
GPUStateMutable &state = GPU_context_active_get()->state_stack->mutable_stack_top_get(); GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state;
copy_v4_v4_int(coords, state.viewport_rect); copy_v4_v4_int(coords, state.viewport_rect);
} }
bool GPU_depth_mask_get(void) bool GPU_depth_mask_get(void)
{ {
GPUState &state = GPU_context_active_get()->state_stack->stack_top_get(); GPUState &state = GPU_context_active_get()->state_manager->state;
return (state.write_mask & GPU_WRITE_DEPTH) != 0; return (state.write_mask & GPU_WRITE_DEPTH) != 0;
} }
@@ -262,34 +259,6 @@ bool GPU_mipmap_enabled(void)
/** \} */ /** \} */
/* -------------------------------------------------------------------- */
/** \name GPUStateStack
* \{ */
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 Context Utils /** \name Context Utils
* \{ */ * \{ */

View File

@@ -79,6 +79,8 @@ inline GPUState operator^(const GPUState &a, const GPUState &b)
/* Mutable state that does not require pipeline change. */ /* Mutable state that does not require pipeline change. */
union GPUStateMutable { union GPUStateMutable {
struct { struct {
/* Viewport State */
/** TODO put inside GPUFramebuffer. */
/** Offset + Extent of the drawable region inside the framebuffer. */ /** Offset + Extent of the drawable region inside the framebuffer. */
int viewport_rect[4]; int viewport_rect[4];
/** Offset + Extent of the scissor region inside the framebuffer. */ /** Offset + Extent of the scissor region inside the framebuffer. */
@@ -126,41 +128,17 @@ inline GPUStateMutable operator^(const GPUStateMutable &a, const GPUStateMutable
return r; return r;
} }
#define GPU_STATE_STACK_LEN 4 class GPUStateManager {
public:
class GPUStateStack { GPUState state;
private: GPUStateMutable mutable_state;
/** 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: public:
virtual ~GPUStateStack(){}; virtual ~GPUStateManager(){};
virtual void set_state(GPUState &state) = 0; virtual void set_state(const GPUState &state) = 0;
virtual void set_mutable_state(GPUStateMutable &state) = 0; virtual void set_mutable_state(const 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 gpu
} // namespace blender } // namespace blender

View File

@@ -57,7 +57,7 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
state_stack = new GLStateStack(); state_manager = new GLStateManager();
} }
GLContext::~GLContext() GLContext::~GLContext()

View File

@@ -21,23 +21,20 @@
*/ */
#include "BLI_math_base.h" #include "BLI_math_base.h"
#include "BLI_utildefines.h"
#include "BKE_global.h"
#include "GPU_extensions.h" #include "GPU_extensions.h"
#include "GPU_glew.h"
#include "GPU_state.h" #include "glew-mx.h"
#include "gl_state.hh" #include "gl_state.hh"
using namespace blender::gpu; using namespace blender::gpu;
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/** \name GLStateStack /** \name GLStateManager
* \{ */ * \{ */
void GLStateStack::set_state(GPUState &state) void GLStateManager::set_state(const GPUState &state)
{ {
GPUState changed = state ^ current_; GPUState changed = state ^ current_;
@@ -52,7 +49,7 @@ void GLStateStack::set_state(GPUState &state)
} }
if (changed.stencil_test != 0 || changed.stencil_op != 0) { if (changed.stencil_test != 0 || changed.stencil_op != 0) {
set_stencil_test(state.stencil_test, state.stencil_op); set_stencil_test(state.stencil_test, state.stencil_op);
set_stencil_mask(state.stencil_test, mutable_stack_top_get()); set_stencil_mask(state.stencil_test, mutable_state);
} }
if (changed.clip_distances != 0) { if (changed.clip_distances != 0) {
set_clip_distances(state.clip_distances, current_.clip_distances); set_clip_distances(state.clip_distances, current_.clip_distances);
@@ -94,11 +91,14 @@ void GLStateStack::set_state(GPUState &state)
current_ = state; current_ = state;
} }
void GLStateStack::set_mutable_state(GPUStateMutable &state) void GLStateManager::set_mutable_state(const GPUStateMutable &state)
{ {
GPUStateMutable changed = state ^ current_mutable_; GPUStateMutable changed = state ^ current_mutable_;
glViewport(UNPACK4(state.viewport_rect)); if ((changed.viewport_rect[0] != 0) || (changed.viewport_rect[1] != 0) ||
(changed.viewport_rect[2] != 0) || (changed.viewport_rect[3] != 0)) {
glViewport(UNPACK4(state.viewport_rect));
}
if ((changed.scissor_rect[0] != 0) || (changed.scissor_rect[1] != 0) || if ((changed.scissor_rect[0] != 0) || (changed.scissor_rect[1] != 0) ||
(changed.scissor_rect[2] != 0) || (changed.scissor_rect[3] != 0)) { (changed.scissor_rect[2] != 0) || (changed.scissor_rect[3] != 0)) {
@@ -113,12 +113,14 @@ void GLStateStack::set_mutable_state(GPUStateMutable &state)
} }
/* TODO remove, should be uniform. */ /* TODO remove, should be uniform. */
if (state.point_size > 0.0f) { if (changed.point_size != 0) {
glEnable(GL_PROGRAM_POINT_SIZE); if (state.point_size > 0.0f) {
glPointSize(state.point_size); glEnable(GL_PROGRAM_POINT_SIZE);
} glPointSize(state.point_size);
else { }
glDisable(GL_PROGRAM_POINT_SIZE); else {
glDisable(GL_PROGRAM_POINT_SIZE);
}
} }
if (changed.line_width != 0) { if (changed.line_width != 0) {
@@ -145,7 +147,7 @@ void GLStateStack::set_mutable_state(GPUStateMutable &state)
/** \name State set functions /** \name State set functions
* \{ */ * \{ */
void GLStateStack::set_write_mask(const eGPUWriteMask value) void GLStateManager::set_write_mask(const eGPUWriteMask value)
{ {
glDepthMask((value & GPU_WRITE_DEPTH) != 0); glDepthMask((value & GPU_WRITE_DEPTH) != 0);
glColorMask((value & GPU_WRITE_RED) != 0, glColorMask((value & GPU_WRITE_RED) != 0,
@@ -154,7 +156,7 @@ void GLStateStack::set_write_mask(const eGPUWriteMask value)
(value & GPU_WRITE_ALPHA) != 0); (value & GPU_WRITE_ALPHA) != 0);
} }
void GLStateStack::set_depth_test(const eGPUDepthTest value) void GLStateManager::set_depth_test(const eGPUDepthTest value)
{ {
GLenum func; GLenum func;
switch (value) { switch (value) {
@@ -188,7 +190,7 @@ void GLStateStack::set_depth_test(const eGPUDepthTest value)
} }
} }
void GLStateStack::set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation) void GLStateManager::set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation)
{ {
switch (operation) { switch (operation) {
case GPU_STENCIL_OP_REPLACE: case GPU_STENCIL_OP_REPLACE:
@@ -215,7 +217,7 @@ void GLStateStack::set_stencil_test(const eGPUStencilTest test, const eGPUStenci
} }
} }
void GLStateStack::set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable state) void GLStateManager::set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable state)
{ {
GLenum func; GLenum func;
switch (test) { switch (test) {
@@ -239,7 +241,7 @@ void GLStateStack::set_stencil_mask(const eGPUStencilTest test, const GPUStateMu
glStencilFunc(func, state.stencil_reference, state.stencil_compare_mask); glStencilFunc(func, state.stencil_reference, state.stencil_compare_mask);
} }
void GLStateStack::set_clip_distances(const int new_dist_len, const int old_dist_len) void GLStateManager::set_clip_distances(const int new_dist_len, const int old_dist_len)
{ {
for (int i = 0; i < new_dist_len; i++) { for (int i = 0; i < new_dist_len; i++) {
glEnable(GL_CLIP_DISTANCE0 + i); glEnable(GL_CLIP_DISTANCE0 + i);
@@ -249,7 +251,7 @@ void GLStateStack::set_clip_distances(const int new_dist_len, const int old_dist
} }
} }
void GLStateStack::set_logic_op(const bool enable) void GLStateManager::set_logic_op(const bool enable)
{ {
if (enable) { if (enable) {
glEnable(GL_COLOR_LOGIC_OP); glEnable(GL_COLOR_LOGIC_OP);
@@ -260,12 +262,12 @@ void GLStateStack::set_logic_op(const bool enable)
} }
} }
void GLStateStack::set_facing(const bool invert) void GLStateManager::set_facing(const bool invert)
{ {
glFrontFace((invert) ? GL_CW : GL_CCW); glFrontFace((invert) ? GL_CW : GL_CCW);
} }
void GLStateStack::set_backface_culling(const eGPUFaceCullTest test) void GLStateManager::set_backface_culling(const eGPUFaceCullTest test)
{ {
if (test != GPU_CULL_NONE) { if (test != GPU_CULL_NONE) {
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@@ -276,14 +278,14 @@ void GLStateStack::set_backface_culling(const eGPUFaceCullTest test)
} }
} }
void GLStateStack::set_provoking_vert(const eGPUProvokingVertex vert) void GLStateManager::set_provoking_vert(const eGPUProvokingVertex vert)
{ {
GLenum value = (vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION : GLenum value = (vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION :
GL_LAST_VERTEX_CONVENTION; GL_LAST_VERTEX_CONVENTION;
glProvokingVertex(value); glProvokingVertex(value);
} }
void GLStateStack::set_shadow_bias(const bool enable) void GLStateManager::set_shadow_bias(const bool enable)
{ {
if (enable) { if (enable) {
glEnable(GL_POLYGON_OFFSET_FILL); glEnable(GL_POLYGON_OFFSET_FILL);
@@ -297,7 +299,7 @@ void GLStateStack::set_shadow_bias(const bool enable)
} }
} }
void GLStateStack::set_blend(const eGPUBlend value) void GLStateManager::set_blend(const eGPUBlend value)
{ {
/** /**
* Factors to the equation. * Factors to the equation.

View File

@@ -31,18 +31,17 @@
namespace blender { namespace blender {
namespace gpu { namespace gpu {
class GLStateStack : public GPUStateStack { class GLStateManager : public GPUStateManager {
private: private:
/** Current state of the GL implementation. Avoids resetting the whole state for every change. */ /** Current state of the GL implementation. Avoids resetting the whole state for every change. */
GPUState current_; GPUState current_;
GPUStateMutable current_mutable_; GPUStateMutable current_mutable_;
public: public:
void set_state(GPUState &state) override; void set_state(const GPUState &state) override;
void set_mutable_state(GPUStateMutable &state) override; void set_mutable_state(const GPUStateMutable &state) override;
public: private:
/* TODO to become private */
static void set_write_mask(const eGPUWriteMask value); static void set_write_mask(const eGPUWriteMask value);
static void set_depth_test(const eGPUDepthTest value); static void set_depth_test(const eGPUDepthTest value);
static void set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation); static void set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation);
@@ -55,7 +54,7 @@ class GLStateStack : public GPUStateStack {
static void set_shadow_bias(const bool enable); static void set_shadow_bias(const bool enable);
static void set_blend(const eGPUBlend value); static void set_blend(const eGPUBlend value);
MEM_CXX_CLASS_ALLOC_FUNCS("GLStateStack") MEM_CXX_CLASS_ALLOC_FUNCS("GLStateManager")
}; };
} // namespace gpu } // namespace gpu