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:
authorSergey Sharybin <sergey@blender.org>2021-09-22 11:59:49 +0300
committerSergey Sharybin <sergey@blender.org>2021-09-22 15:28:56 +0300
commit2526a355bcae7292d6945903def69f982f88990d (patch)
treeab6984d1195d1a3de183669bc084fa3c936b1193 /intern/cycles/blender
parent7633548d60ccba95005efee41e836f90d0379f79 (diff)
Fix bad image drawing during rendering on certain GPUs
Reported by Thomas DInges: the default cube render in Cycles has jagged edges during rendering. Happens on AMD Radeon RX 5500 XT. Force linear interpolation at zoom level 1 and less. Reviewed by @fclem
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/blender_gpu_display.cpp26
-rw-r--r--intern/cycles/blender/blender_gpu_display.h4
-rw-r--r--intern/cycles/blender/blender_session.cpp7
-rw-r--r--intern/cycles/blender/blender_session.h4
4 files changed, 40 insertions, 1 deletions
diff --git a/intern/cycles/blender/blender_gpu_display.cpp b/intern/cycles/blender/blender_gpu_display.cpp
index aa2a9c17a8a..c5c3a2bd155 100644
--- a/intern/cycles/blender/blender_gpu_display.cpp
+++ b/intern/cycles/blender/blender_gpu_display.cpp
@@ -475,6 +475,11 @@ void BlenderGPUDisplay::clear()
texture_.need_clear = true;
}
+void BlenderGPUDisplay::set_zoom(float zoom_x, float zoom_y)
+{
+ zoom_ = make_float2(zoom_x, zoom_y);
+}
+
void BlenderGPUDisplay::do_draw(const GPUDisplayParams &params)
{
/* See do_update_begin() for why no locking is required here. */
@@ -508,6 +513,27 @@ void BlenderGPUDisplay::do_draw(const GPUDisplayParams &params)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
+ /* Trick to keep sharp rendering without jagged edges on all GPUs.
+ *
+ * The idea here is to enforce driver to use linear interpolation when the image is not zoomed
+ * in.
+ * For the render result with a resolution divider in effect we always use nearest interpolation.
+ *
+ * Use explicit MIN assignment to make sure the driver does not have an undefined behavior at
+ * the zoom level 1. The MAG filter is always NEAREST. */
+ const float zoomed_width = params.size.x * zoom_.x;
+ const float zoomed_height = params.size.y * zoom_.y;
+ if (texture_.width != params.size.x || texture_.height != params.size.y) {
+ /* Resolution divider is different from 1, force enarest interpolation. */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ else if (zoomed_width - params.size.x > 0.5f || zoomed_height - params.size.y > 0.5f) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
+
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
texture_update_if_needed();
diff --git a/intern/cycles/blender/blender_gpu_display.h b/intern/cycles/blender/blender_gpu_display.h
index 1014c96cee4..89420567037 100644
--- a/intern/cycles/blender/blender_gpu_display.h
+++ b/intern/cycles/blender/blender_gpu_display.h
@@ -107,6 +107,8 @@ class BlenderGPUDisplay : public GPUDisplay {
virtual void clear() override;
+ void set_zoom(float zoom_x, float zoom_y);
+
protected:
virtual bool do_update_begin(const GPUDisplayParams &params,
int texture_width,
@@ -206,6 +208,8 @@ class BlenderGPUDisplay : public GPUDisplay {
void *gl_render_sync_ = nullptr;
void *gl_upload_sync_ = nullptr;
+
+ float2 zoom_ = make_float2(1.0f, 1.0f);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 5aafa605526..d65d89a7ddd 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -158,7 +158,9 @@ void BlenderSession::create_session()
/* Create GPU display. */
if (!b_engine.is_preview() && !headless) {
- session->set_gpu_display(make_unique<BlenderGPUDisplay>(b_engine, b_scene));
+ unique_ptr<BlenderGPUDisplay> gpu_display = make_unique<BlenderGPUDisplay>(b_engine, b_scene);
+ gpu_display_ = gpu_display.get();
+ session->set_gpu_display(move(gpu_display));
}
/* Viewport and preview (as in, material preview) does not do tiled rendering, so can inform
@@ -878,6 +880,9 @@ void BlenderSession::draw(BL::SpaceImageEditor &space_image)
draw_state_.last_pass_index = pass_index;
}
+ BL::Array<float, 2> zoom = space_image.zoom();
+ gpu_display_->set_zoom(zoom[0], zoom[1]);
+
session->draw();
}
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index cf52359ea5d..11e2657a325 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -29,6 +29,7 @@
CCL_NAMESPACE_BEGIN
+class BlenderGPUDisplay;
class BlenderSync;
class ImageMetaData;
class Scene;
@@ -159,6 +160,9 @@ class BlenderSession {
int last_pass_index = -1;
} draw_state_;
+ /* NOTE: The BlenderSession references the GPU display. */
+ BlenderGPUDisplay *gpu_display_ = nullptr;
+
vector<string> full_buffer_files_;
};