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:
Diffstat (limited to 'source/blender/gpu/opengl/gl_state.cc')
-rw-r--r--source/blender/gpu/opengl/gl_state.cc95
1 files changed, 95 insertions, 0 deletions
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 1678760e9cd..93753768928 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -76,6 +76,7 @@ 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();
};
@@ -538,4 +539,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