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:
authorHans Goudey <h.goudey@me.com>2020-09-13 01:42:27 +0300
committerHans Goudey <h.goudey@me.com>2020-09-13 01:42:27 +0300
commit3eaca737531a917e60350bd74d52849b612831da (patch)
tree8950b659cbafcaa55e4ebfee64999a2fc382a606 /source/blender/gpu
parent5545d833154e017f3948db9970b8d770ea8e8f9b (diff)
parent8f6740b2754ff1f5c936ee95e2cd7ed837627608 (diff)
Merge branch 'property-search-single-tab' into property-search-start-end-operators
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt3
-rw-r--r--source/blender/gpu/GPU_capabilities.h2
-rw-r--r--source/blender/gpu/GPU_common.h4
-rw-r--r--source/blender/gpu/GPU_debug.h35
-rw-r--r--source/blender/gpu/GPU_state.h12
-rw-r--r--source/blender/gpu/GPU_texture.h5
-rw-r--r--source/blender/gpu/GPU_vertex_buffer.h3
-rw-r--r--source/blender/gpu/intern/gpu_capabilities.cc5
-rw-r--r--source/blender/gpu/intern/gpu_capabilities_private.hh3
-rw-r--r--source/blender/gpu/intern/gpu_context_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_debug.cc44
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc2
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c1
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh1
-rw-r--r--source/blender/gpu/intern/gpu_state.cc46
-rw-r--r--source/blender/gpu/intern/gpu_state_private.hh16
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc21
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer.cc7
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc2
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc15
-rw-r--r--source/blender/gpu/opengl/gl_context.hh2
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc22
-rw-r--r--source/blender/gpu/opengl/gl_drawlist.hh1
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc37
-rw-r--r--source/blender/gpu/opengl/gl_state.cc108
-rw-r--r--source/blender/gpu/opengl/gl_state.hh27
-rw-r--r--source/blender/gpu/opengl/gl_vertex_buffer.cc5
-rw-r--r--source/blender/gpu/opengl/gl_vertex_buffer.hh2
29 files changed, 301 insertions, 134 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 72dc610f3c8..b7ffa59538a 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -62,7 +62,6 @@ set(SRC
intern/gpu_capabilities.cc
intern/gpu_codegen.c
intern/gpu_context.cc
- intern/gpu_debug.cc
intern/gpu_drawlist.cc
intern/gpu_framebuffer.cc
intern/gpu_immediate.cc
@@ -113,10 +112,8 @@ set(SRC
GPU_capabilities.h
GPU_common.h
GPU_context.h
- GPU_debug.h
GPU_drawlist.h
GPU_framebuffer.h
- GPU_glew.h
GPU_immediate.h
GPU_immediate_util.h
GPU_index_buffer.h
diff --git a/source/blender/gpu/GPU_capabilities.h b/source/blender/gpu/GPU_capabilities.h
index b8a48735548..9d55fe73708 100644
--- a/source/blender/gpu/GPU_capabilities.h
+++ b/source/blender/gpu/GPU_capabilities.h
@@ -45,6 +45,8 @@ bool GPU_depth_blitting_workaround(void);
bool GPU_use_main_context_workaround(void);
bool GPU_crappy_amd_driver(void);
+bool GPU_shader_image_load_store_support(void);
+
bool GPU_mem_stats_supported(void);
void GPU_mem_stats_get(int *totalmem, int *freemem);
diff --git a/source/blender/gpu/GPU_common.h b/source/blender/gpu/GPU_common.h
index 8fd1baba2f7..1be74701176 100644
--- a/source/blender/gpu/GPU_common.h
+++ b/source/blender/gpu/GPU_common.h
@@ -32,10 +32,6 @@
# define TRUST_NO_ONE 1
#endif
-#if defined(WITH_OPENGL)
-# include <GL/glew.h>
-#endif
-
#include "BLI_sys_types.h"
#include <stdbool.h>
#include <stdint.h>
diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h
deleted file mode 100644
index 09dc02c0fc6..00000000000
--- a/source/blender/gpu/GPU_debug.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup gpu
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* prints something if debug mode is active only */
-void GPU_print_error_debug(const char *str);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 5e872001267..a857736acd5 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -35,6 +35,14 @@ typedef enum eGPUWriteMask {
ENUM_OPERATORS(eGPUWriteMask)
+typedef enum eGPUBarrier {
+ GPU_BARRIER_NONE = 0,
+ GPU_BARRIER_SHADER_IMAGE_ACCESS = (1 << 0),
+ GPU_BARRIER_TEXTURE_FETCH = (1 << 1),
+} eGPUBarrier;
+
+ENUM_OPERATORS(eGPUBarrier)
+
/**
* Defines the fixed pipeline blending equation.
* SRC is the output color from the shader.
@@ -151,6 +159,10 @@ eGPUStencilTest GPU_stencil_test_get(void);
void GPU_flush(void);
void GPU_finish(void);
+void GPU_apply_state(void);
+void GPU_force_state(void);
+
+void GPU_memory_barrier(eGPUBarrier barrier);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 2ce2ba093cf..99a7c6a5f0c 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -243,6 +243,10 @@ void GPU_texture_bind_ex(GPUTexture *tex, eGPUSamplerState state, int unit, cons
void GPU_texture_unbind(GPUTexture *tex);
void GPU_texture_unbind_all(void);
+void GPU_texture_image_bind(GPUTexture *tex, int unit);
+void GPU_texture_image_unbind(GPUTexture *tex);
+void GPU_texture_image_unbind_all(void);
+
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src);
void GPU_texture_generate_mipmap(GPUTexture *tex);
@@ -253,7 +257,6 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter);
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp);
void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4]);
-int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);
int GPU_texture_orig_width(const GPUTexture *tex);
diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h
index 2af9929db35..36caee10072 100644
--- a/source/blender/gpu/GPU_vertex_buffer.h
+++ b/source/blender/gpu/GPU_vertex_buffer.h
@@ -139,6 +139,9 @@ GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts);
void GPU_vertbuf_use(GPUVertBuf *);
+/* XXX do not use. */
+void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, void *data);
+
/* Metrics */
uint GPU_vertbuf_get_memory_usage(void);
diff --git a/source/blender/gpu/intern/gpu_capabilities.cc b/source/blender/gpu/intern/gpu_capabilities.cc
index a79ce27ba63..63e29654e1c 100644
--- a/source/blender/gpu/intern/gpu_capabilities.cc
+++ b/source/blender/gpu/intern/gpu_capabilities.cc
@@ -102,6 +102,11 @@ bool GPU_crappy_amd_driver(void)
return GCaps.broken_amd_driver;
}
+bool GPU_shader_image_load_store_support(void)
+{
+ return GCaps.shader_image_load_store_support;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_capabilities_private.hh b/source/blender/gpu/intern/gpu_capabilities_private.hh
index a51525fa932..abe5b706a7d 100644
--- a/source/blender/gpu/intern/gpu_capabilities_private.hh
+++ b/source/blender/gpu/intern/gpu_capabilities_private.hh
@@ -42,6 +42,7 @@ struct GPUCapabilities {
int max_textures_geom = 0;
int max_textures_frag = 0;
bool mem_stats_support = false;
+ bool shader_image_load_store_support = false;
/* OpenGL related workarounds. */
bool mip_render_workaround = false;
bool depth_blitting_workaround = false;
@@ -52,4 +53,4 @@ struct GPUCapabilities {
extern GPUCapabilities GCaps;
-} // namespace blender::gpu \ No newline at end of file
+} // namespace blender::gpu
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index bc07bea4bb1..38f94b8dde9 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -46,7 +46,7 @@ class Context {
Shader *shader = NULL;
FrameBuffer *active_fb = NULL;
GPUMatrixState *matrix_state = NULL;
- GPUStateManager *state_manager = NULL;
+ StateManager *state_manager = NULL;
Immediate *imm = NULL;
/**
diff --git a/source/blender/gpu/intern/gpu_debug.cc b/source/blender/gpu/intern/gpu_debug.cc
deleted file mode 100644
index f179a241926..00000000000
--- a/source/blender/gpu/intern/gpu_debug.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup gpu
- */
-
-#include "BLI_compiler_attrs.h"
-#include "BLI_sys_types.h"
-#include "BLI_system.h"
-#include "BLI_utildefines.h"
-
-#include "BKE_global.h"
-
-#include "GPU_debug.h"
-#include "GPU_glew.h"
-#include "intern/gpu_private.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-void GPU_print_error_debug(const char *str)
-{
- if (G.debug & G_DEBUG) {
- fprintf(stderr, "GPU: %s\n", str);
- }
-}
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index 9c3a88e30f0..8d781978857 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -416,7 +416,7 @@ static void immEndVertex(void) /* and move on to the next vertex */
printf("copying %s from vertex %u to %u\n", a->name, imm->vertex_idx - 1, imm->vertex_idx);
#endif
- GLubyte *data = imm->vertex_data + a->offset;
+ uchar *data = imm->vertex_data + a->offset;
memcpy(data, data - imm->vertex_format.stride, a->sz);
/* TODO: consolidate copy of adjacent attributes */
}
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 769b52bf593..c76ce0f1094 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -28,7 +28,6 @@
#include <string.h>
#include "GPU_framebuffer.h"
-#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "GPU_select.h"
#include "GPU_state.h"
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index f76339d3adb..fce6fda5f14 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -63,6 +63,7 @@ class ShaderInterface {
/** Enabled bindpoints that needs to be fed with data. */
uint16_t enabled_attr_mask_ = 0;
uint16_t enabled_ubo_mask_ = 0;
+ uint8_t enabled_ima_mask_ = 0;
uint64_t enabled_tex_mask_ = 0;
/** Location of builtin uniforms. Fast access, no lookup needed. */
int32_t builtins_[GPU_NUM_UNIFORMS];
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index be523020e8a..b63abb3d57f 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -30,7 +30,6 @@
#include "BKE_global.h"
-#include "GPU_glew.h"
#include "GPU_state.h"
#include "gpu_context_private.hh"
@@ -41,7 +40,7 @@ using namespace blender::gpu;
#define SET_STATE(_prefix, _state, _value) \
do { \
- GPUStateManager *stack = Context::get()->state_manager; \
+ StateManager *stack = Context::get()->state_manager; \
auto &state_object = stack->_prefix##state; \
state_object._state = (_value); \
} while (0)
@@ -105,7 +104,7 @@ void GPU_write_mask(eGPUWriteMask mask)
void GPU_color_mask(bool r, bool g, bool b, bool a)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
uint32_t write_mask = state.write_mask;
SET_FLAG_FROM_TEST(write_mask, r, (uint32_t)GPU_WRITE_RED);
@@ -117,7 +116,7 @@ void GPU_color_mask(bool r, bool g, bool b, bool a)
void GPU_depth_mask(bool depth)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
uint32_t write_mask = state.write_mask;
SET_FLAG_FROM_TEST(write_mask, depth, (uint32_t)GPU_WRITE_DEPTH);
@@ -142,7 +141,7 @@ void GPU_state_set(eGPUWriteMask write_mask,
eGPUStencilOp stencil_op,
eGPUProvokingVertex provoking_vert)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
state.write_mask = (uint32_t)write_mask;
state.blend = (uint32_t)blend;
@@ -161,7 +160,7 @@ void GPU_state_set(eGPUWriteMask write_mask,
void GPU_depth_range(float near, float far)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->mutable_state;
copy_v2_fl2(state.depth_range, near, far);
}
@@ -173,7 +172,7 @@ void GPU_line_width(float width)
void GPU_point_size(float size)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->mutable_state;
/* Keep the sign of point_size since it represents the enable state. */
state.point_size = size * ((state.point_size > 0.0) ? 1.0f : -1.0f);
@@ -185,7 +184,7 @@ void GPU_point_size(float size)
/* TODO remove and use program point size everywhere */
void GPU_program_point_size(bool enable)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->mutable_state;
/* Set point size sign negative to disable. */
state.point_size = fabsf(state.point_size) * (enable ? 1 : -1);
@@ -306,18 +305,35 @@ void GPU_finish(void)
Context::get()->finish();
}
+void GPU_apply_state(void)
+{
+ Context::get()->state_manager->apply_state();
+}
+
+/* Will set all the states regardless of the current ones. */
+void GPU_force_state(void)
+{
+ Context::get()->state_manager->force_state();
+}
+
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Default OpenGL State
- *
- * This is called on startup, for opengl offscreen render.
- * Generally we should always return to this state when
- * temporarily modifying the state for drawing, though that are (undocumented)
- * exceptions that we should try to get rid of.
+/** \name Synchronisation Utils
+ * \{ */
+
+void GPU_memory_barrier(eGPUBarrier barrier)
+{
+ Context::get()->state_manager->issue_barrier(barrier);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Default State
* \{ */
-GPUStateManager::GPUStateManager(void)
+StateManager::StateManager(void)
{
/* Set default state. */
state.write_mask = GPU_WRITE_COLOR;
diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh
index 9fee45e7bd4..b8d247ec175 100644
--- a/source/blender/gpu/intern/gpu_state_private.hh
+++ b/source/blender/gpu/intern/gpu_state_private.hh
@@ -98,9 +98,6 @@ union GPUStateMutable {
/* Viewport State */
/** 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;
@@ -152,21 +149,28 @@ inline GPUStateMutable operator~(const GPUStateMutable &a)
* State manager keeping track of the draw state and applying it before drawing.
* Base class which is then specialized for each implementation (GL, VK, ...).
**/
-class GPUStateManager {
+class StateManager {
public:
GPUState state;
GPUStateMutable mutable_state;
public:
- GPUStateManager();
- virtual ~GPUStateManager(){};
+ StateManager();
+ virtual ~StateManager(){};
virtual void apply_state(void) = 0;
+ virtual void force_state(void) = 0;
+
+ virtual void issue_barrier(eGPUBarrier barrier_bits) = 0;
virtual void texture_bind(Texture *tex, eGPUSamplerState sampler, int unit) = 0;
virtual void texture_unbind(Texture *tex) = 0;
virtual void texture_unbind_all(void) = 0;
+ virtual void image_bind(Texture *tex, int unit) = 0;
+ virtual void image_unbind(Texture *tex) = 0;
+ virtual void image_unbind_all(void) = 0;
+
virtual void texture_unpack_row_length_set(uint len) = 0;
};
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index b22fd53f0f6..eb6881164b2 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -418,6 +418,21 @@ void GPU_texture_unbind_all(void)
Context::get()->state_manager->texture_unbind_all();
}
+void GPU_texture_image_bind(GPUTexture *tex, int unit)
+{
+ Context::get()->state_manager->image_bind(unwrap(tex), unit);
+}
+
+void GPU_texture_image_unbind(GPUTexture *tex)
+{
+ Context::get()->state_manager->image_unbind(unwrap(tex));
+}
+
+void GPU_texture_image_unbind_all(void)
+{
+ Context::get()->state_manager->image_unbind_all();
+}
+
void GPU_texture_generate_mipmap(GPUTexture *tex)
{
reinterpret_cast<Texture *>(tex)->generate_mipmap();
@@ -498,12 +513,6 @@ void GPU_texture_ref(GPUTexture *tex)
reinterpret_cast<Texture *>(tex)->refcount++;
}
-/* TODO(fclem) Remove! This is broken as it is! */
-int GPU_texture_target(const GPUTexture *UNUSED(tex))
-{
- return GL_TEXTURE_2D;
-}
-
int GPU_texture_width(const GPUTexture *tex)
{
return reinterpret_cast<const Texture *>(tex)->width_get();
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.cc b/source/blender/gpu/intern/gpu_vertex_buffer.cc
index 4cc2af889e6..ea149aaa254 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.cc
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc
@@ -324,4 +324,11 @@ void GPU_vertbuf_use(GPUVertBuf *verts)
unwrap(verts)->upload();
}
+/* XXX this is just a wrapper for the use of the Hair refine workaround.
+ * To be used with GPU_vertbuf_use(). */
+void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, void *data)
+{
+ unwrap(verts)->update_sub(start, len, data);
+}
+
/** \} */ \ No newline at end of file
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
index f1de0a2ac96..3cce7e79857 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
@@ -95,6 +95,8 @@ class VertBuf {
}
}
+ virtual void update_sub(uint start, uint len, void *data) = 0;
+
protected:
virtual void acquire_data(void) = 0;
virtual void resize_data(void) = 0;
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index ac8439167e3..3b0aa055588 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -70,7 +70,7 @@ static uint comp_sz(GPUVertCompType type)
#if TRUST_NO_ONE
assert(type <= GPU_COMP_F32); /* other types have irregular sizes (not bytes) */
#endif
- const GLubyte sizes[] = {1, 1, 2, 2, 4, 4, 4};
+ const uint sizes[] = {1, 1, 2, 2, 4, 4, 4};
return sizes[type];
}
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index edaa84cdcf8..46e048d7f7c 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -210,6 +210,7 @@ static void detect_workarounds(void)
GLContext::debug_layer_workaround = true;
GLContext::unused_fb_slot_workaround = true;
/* Turn off extensions. */
+ GCaps.shader_image_load_store_support = false;
GLContext::base_instance_support = false;
GLContext::clear_texture_support = false;
GLContext::copy_image_support = false;
@@ -250,17 +251,20 @@ static void detect_workarounds(void)
(strstr(version, "4.5.13399") || strstr(version, "4.5.13417") ||
strstr(version, "4.5.13422"))) {
GLContext::unused_fb_slot_workaround = true;
+ GCaps.shader_image_load_store_support = false;
GCaps.broken_amd_driver = true;
}
/* We have issues with this specific renderer. (see T74024) */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) &&
strstr(renderer, "AMD VERDE")) {
GLContext::unused_fb_slot_workaround = true;
+ GCaps.shader_image_load_store_support = false;
GCaps.broken_amd_driver = true;
}
/* Fix slowdown on this particular driver. (see T77641) */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) &&
strstr(version, "Mesa 19.3.4")) {
+ GCaps.shader_image_load_store_support = false;
GCaps.broken_amd_driver = true;
}
/* There is an issue with the #glBlitFramebuffer on MacOS with radeon pro graphics.
@@ -349,10 +353,10 @@ static void detect_workarounds(void)
}
/** Internal capabilities. */
-GLint GLContext::max_texture_3d_size;
-GLint GLContext::max_cubemap_size;
-GLint GLContext::max_ubo_size;
-GLint GLContext::max_ubo_binds;
+GLint GLContext::max_cubemap_size = 0;
+GLint GLContext::max_texture_3d_size = 0;
+GLint GLContext::max_ubo_binds = 0;
+GLint GLContext::max_ubo_size = 0;
/** Extensions. */
bool GLContext::base_instance_support = false;
bool GLContext::clear_texture_support = false;
@@ -383,6 +387,7 @@ void GLBackend::capabilities_init(void)
glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_geom);
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &GCaps.max_textures);
GCaps.mem_stats_support = GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo;
+ GCaps.shader_image_load_store_support = GLEW_ARB_shader_image_load_store;
/* GL specific capabilities. */
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GLContext::max_texture_3d_size);
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size);
@@ -413,4 +418,4 @@ void GLBackend::capabilities_init(void)
/** \} */
-} // namespace blender::gpu \ No newline at end of file
+} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index 9822c842ce7..4d9c2470db0 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -56,8 +56,8 @@ class GLSharedOrphanLists {
class GLContext : public Context {
public:
/** Capabilities. */
- static GLint max_texture_3d_size;
static GLint max_cubemap_size;
+ static GLint max_texture_3d_size;
static GLint max_ubo_size;
static GLint max_ubo_binds;
/** Extensions. */
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index de88fdc154c..747d8ee2e3e 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -200,13 +200,16 @@ void check_gl_resources(const char *info)
* be big enough to feed the data range the shader awaits. */
uint16_t ubo_needed = interface->enabled_ubo_mask_;
ubo_needed &= ~ctx->bound_ubo_slots;
-
/* NOTE: This only check binding. To be valid, the bound texture needs to
* be the same format/target the shader expects. */
uint64_t tex_needed = interface->enabled_tex_mask_;
tex_needed &= ~GLContext::state_manager_active_get()->bound_texture_slots();
+ /* NOTE: This only check binding. To be valid, the bound image needs to
+ * be the same format/target the shader expects. */
+ uint8_t ima_needed = interface->enabled_ima_mask_;
+ ima_needed &= ~GLContext::state_manager_active_get()->bound_image_slots();
- if (ubo_needed == 0 && tex_needed == 0) {
+ if (ubo_needed == 0 && tex_needed == 0 && ima_needed == 0) {
return;
}
@@ -223,6 +226,7 @@ void check_gl_resources(const char *info)
for (int i = 0; tex_needed != 0; i++, tex_needed >>= 1) {
if ((tex_needed & 1) != 0) {
+ /* FIXME: texture_get might return an image input instead. */
const ShaderInput *tex_input = interface->texture_get(i);
const char *tex_name = interface->input_name_get(tex_input);
const char *sh_name = ctx->shader->name_get();
@@ -231,6 +235,18 @@ void check_gl_resources(const char *info)
debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg, NULL);
}
}
+
+ for (int i = 0; ima_needed != 0; i++, ima_needed >>= 1) {
+ if ((ima_needed & 1) != 0) {
+ /* FIXME: texture_get might return a texture input instead. */
+ const ShaderInput *tex_input = interface->texture_get(i);
+ const char *tex_name = interface->input_name_get(tex_input);
+ const char *sh_name = ctx->shader->name_get();
+ char msg[256];
+ SNPRINTF(msg, "Missing Image bind at slot %d : %s > %s : %s", i, sh_name, tex_name, info);
+ debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg, NULL);
+ }
+ }
}
void raise_gl_error(const char *info)
@@ -243,7 +259,7 @@ void raise_gl_error(const char *info)
/* -------------------------------------------------------------------- */
/** \name Object Label
*
- * Useful for debugging through renderdoc. Only defined if using --debug-gpu.
+ * Useful for debugging through render-doc. Only defined if using `--debug-gpu`.
* Make sure to bind the object first so that it gets defined by the GL implementation.
* \{ */
diff --git a/source/blender/gpu/opengl/gl_drawlist.hh b/source/blender/gpu/opengl/gl_drawlist.hh
index 3a731559e3a..5c1e698c0a1 100644
--- a/source/blender/gpu/opengl/gl_drawlist.hh
+++ b/source/blender/gpu/opengl/gl_drawlist.hh
@@ -31,7 +31,6 @@
#include "BLI_sys_types.h"
#include "GPU_batch.h"
-#include "GPU_glew.h"
#include "gpu_drawlist_private.hh"
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index d611efcd975..2d55c222e9c 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -100,6 +100,31 @@ static inline int sampler_binding(int32_t program,
return -1;
}
}
+
+static inline int image_binding(int32_t program,
+ uint32_t uniform_index,
+ int32_t uniform_location,
+ int *image_len)
+{
+ /* Identify image uniforms and asign image units to them. */
+ GLint type;
+ glGetActiveUniformsiv(program, 1, &uniform_index, GL_UNIFORM_TYPE, &type);
+
+ switch (type) {
+ case GL_IMAGE_1D:
+ case GL_IMAGE_2D:
+ case GL_IMAGE_3D: {
+ /* For now just assign a consecutive index. In the future, we should set it in
+ * the shader using layout(binding = i) and query its value. */
+ int binding = *image_len;
+ glUniform1i(uniform_location, binding);
+ (*image_len)++;
+ return binding;
+ }
+ default:
+ return -1;
+ }
+}
/** \} */
/* -------------------------------------------------------------------- */
@@ -207,8 +232,8 @@ GLShaderInterface::GLShaderInterface(GLuint program)
enabled_ubo_mask_ |= (1 << input->binding);
}
- /* Uniforms */
- for (int i = 0, sampler = 0; i < active_uniform_len; i++) {
+ /* Uniforms & samplers & images */
+ for (int i = 0, sampler = 0, image = 0; i < active_uniform_len; i++) {
if (BLI_BITMAP_TEST(uniforms_from_blocks, i)) {
continue;
}
@@ -224,6 +249,12 @@ GLShaderInterface::GLShaderInterface(GLuint program)
name_buffer_offset += this->set_input_name(input, name, name_len);
enabled_tex_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
+
+ if (input->binding == -1) {
+ input->binding = image_binding(program, i, input->location, &image);
+
+ enabled_ima_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
+ }
}
/* Builtin Uniforms */
@@ -296,4 +327,4 @@ void GLShaderInterface::ref_remove(GLVaoCache *ref)
/** \} */
-} // namespace blender::gpu \ No newline at end of file
+} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 1678760e9cd..cd24fa0e0e4 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -42,7 +42,7 @@ namespace blender::gpu {
/** \name GLStateManager
* \{ */
-GLStateManager::GLStateManager(void) : GPUStateManager()
+GLStateManager::GLStateManager(void) : StateManager()
{
/* Set other states that never change. */
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
@@ -76,9 +76,21 @@ void GLStateManager::apply_state(void)
this->set_state(this->state);
this->set_mutable_state(this->mutable_state);
this->texture_bind_apply();
+ this->image_bind_apply();
active_fb->apply_state();
};
+void GLStateManager::force_state(void)
+{
+ /* Little exception for clip distances since they need to keep the old count correct. */
+ uint32_t clip_distances = current_.clip_distances;
+ current_ = ~this->state;
+ current_.clip_distances = clip_distances;
+ current_mutable_ = ~this->mutable_state;
+ this->set_state(this->state);
+ this->set_mutable_state(this->mutable_state);
+};
+
void GLStateManager::set_state(const GPUState &state)
{
GPUState changed = state ^ current_;
@@ -538,4 +550,98 @@ uint64_t GLStateManager::bound_texture_slots(void)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Image Binding (from image load store)
+ * \{ */
+
+void GLStateManager::image_bind(Texture *tex_, int unit)
+{
+ /* Minimum support is 8 image in the fragment shader. No image for other stages. */
+ BLI_assert(GPU_shader_image_load_store_support() && unit < 8);
+ GLTexture *tex = static_cast<GLTexture *>(tex_);
+ if (G.debug & G_DEBUG_GPU) {
+ tex->check_feedback_loop();
+ }
+ images_[unit] = tex->tex_id_;
+ formats_[unit] = to_gl_internal_format(tex->format_);
+ tex->is_bound_ = true;
+ dirty_image_binds_ |= 1ULL << unit;
+}
+
+void GLStateManager::image_unbind(Texture *tex_)
+{
+ GLTexture *tex = static_cast<GLTexture *>(tex_);
+ if (!tex->is_bound_) {
+ return;
+ }
+
+ GLuint tex_id = tex->tex_id_;
+ for (int i = 0; i < ARRAY_SIZE(images_); i++) {
+ if (images_[i] == tex_id) {
+ images_[i] = 0;
+ dirty_image_binds_ |= 1ULL << i;
+ }
+ }
+ tex->is_bound_ = false;
+}
+
+void GLStateManager::image_unbind_all(void)
+{
+ for (int i = 0; i < ARRAY_SIZE(images_); i++) {
+ if (images_[i] != 0) {
+ images_[i] = 0;
+ dirty_image_binds_ |= 1ULL << i;
+ }
+ }
+ this->image_bind_apply();
+}
+
+void GLStateManager::image_bind_apply(void)
+{
+ if (dirty_image_binds_ == 0) {
+ return;
+ }
+ uint32_t dirty_bind = dirty_image_binds_;
+ dirty_image_binds_ = 0;
+
+ int first = bitscan_forward_uint(dirty_bind);
+ int last = 32 - bitscan_reverse_uint(dirty_bind);
+ int count = last - first;
+
+ if (GLContext::multi_bind_support) {
+ glBindImageTextures(first, count, images_ + first);
+ }
+ else {
+ for (int unit = first; unit < last; unit++) {
+ if ((dirty_bind >> unit) & 1UL) {
+ glBindImageTexture(unit, images_[unit], 0, GL_TRUE, 0, GL_READ_WRITE, formats_[unit]);
+ }
+ }
+ }
+}
+
+uint8_t GLStateManager::bound_image_slots(void)
+{
+ uint8_t bound_slots = 0;
+ for (int i = 0; i < ARRAY_SIZE(images_); i++) {
+ if (images_[i] != 0) {
+ bound_slots |= 1ULL << i;
+ }
+ }
+ return bound_slots;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Memory barrier
+ * \{ */
+
+void GLStateManager::issue_barrier(eGPUBarrier barrier_bits)
+{
+ glMemoryBarrier(to_gl(barrier_bits));
+}
+
+/** \} */
+
} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
index fb2ed3403f7..cab654006c6 100644
--- a/source/blender/gpu/opengl/gl_state.hh
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -40,7 +40,7 @@ class GLTexture;
* State manager keeping track of the draw state and applying it before drawing.
* Opengl Implementation.
**/
-class GLStateManager : public GPUStateManager {
+class GLStateManager : public StateManager {
public:
/** Anothter reference to the active framebuffer. */
GLFrameBuffer *active_fb = nullptr;
@@ -64,19 +64,31 @@ class GLStateManager : public GPUStateManager {
GLuint samplers_[64] = {0};
uint64_t dirty_texture_binds_ = 0;
+ GLuint images_[8] = {0};
+ GLenum formats_[8] = {0};
+ uint8_t dirty_image_binds_ = 0;
+
public:
GLStateManager();
void apply_state(void) override;
+ void force_state(void) override;
+
+ void issue_barrier(eGPUBarrier barrier_bits) override;
void texture_bind(Texture *tex, eGPUSamplerState sampler, int unit) override;
void texture_bind_temp(GLTexture *tex);
void texture_unbind(Texture *tex) override;
void texture_unbind_all(void) override;
+ void image_bind(Texture *tex, int unit) override;
+ void image_unbind(Texture *tex) override;
+ void image_unbind_all(void) override;
+
void texture_unpack_row_length_set(uint len) override;
uint64_t bound_texture_slots(void);
+ uint8_t bound_image_slots(void);
private:
static void set_write_mask(const eGPUWriteMask value);
@@ -95,9 +107,22 @@ class GLStateManager : public GPUStateManager {
void set_mutable_state(const GPUStateMutable &state);
void texture_bind_apply(void);
+ void image_bind_apply(void);
MEM_CXX_CLASS_ALLOC_FUNCS("GLStateManager")
};
+static inline GLbitfield to_gl(eGPUBarrier barrier_bits)
+{
+ GLbitfield barrier = 0;
+ if (barrier_bits & GPU_BARRIER_SHADER_IMAGE_ACCESS) {
+ barrier |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
+ }
+ if (barrier_bits & GPU_BARRIER_TEXTURE_FETCH) {
+ barrier |= GL_TEXTURE_FETCH_BARRIER_BIT;
+ }
+ return barrier;
+}
+
} // namespace gpu
} // namespace blender
diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc
index a724c94775e..d97fc2c1600 100644
--- a/source/blender/gpu/opengl/gl_vertex_buffer.cc
+++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc
@@ -106,4 +106,9 @@ void GLVertBuf::bind(void)
}
}
+void GLVertBuf::update_sub(uint start, uint len, void *data)
+{
+ glBufferSubData(GL_ARRAY_BUFFER, start, len, data);
+}
+
} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.hh b/source/blender/gpu/opengl/gl_vertex_buffer.hh
index eee5222f467..e2bf6cd00e8 100644
--- a/source/blender/gpu/opengl/gl_vertex_buffer.hh
+++ b/source/blender/gpu/opengl/gl_vertex_buffer.hh
@@ -45,6 +45,8 @@ class GLVertBuf : public VertBuf {
public:
void bind(void);
+ void update_sub(uint start, uint len, void *data) override;
+
protected:
void acquire_data(void) override;
void resize_data(void) override;