aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/render/vulkan.h1
-rw-r--r--include/wlr/render/wlr_renderer.h12
-rw-r--r--render/gles2/pass.c13
-rw-r--r--render/pixman/pass.c9
-rw-r--r--render/vulkan/pass.c1
-rw-r--r--render/vulkan/renderer.c17
6 files changed, 50 insertions, 3 deletions
diff --git a/include/render/vulkan.h b/include/render/vulkan.h
index f901f5f1..c4766e73 100644
--- a/include/render/vulkan.h
+++ b/include/render/vulkan.h
@@ -125,6 +125,7 @@ void vulkan_format_props_finish(struct wlr_vk_format_props *props);
struct wlr_vk_pipeline_layout_key {
const struct wlr_vk_format *ycbcr_format;
+ enum wlr_scale_filter_mode filter_mode;
};
struct wlr_vk_pipeline_layout {
diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h
index a150930c..a7d0241e 100644
--- a/include/wlr/render/wlr_renderer.h
+++ b/include/wlr/render/wlr_renderer.h
@@ -196,6 +196,16 @@ enum wlr_render_blend_mode {
WLR_RENDER_BLEND_MODE_NONE,
};
+/**
+ * Filter modes.
+ */
+enum wlr_scale_filter_mode {
+ /* bilinear texture filtering (default) */
+ WLR_SCALE_FILTER_BILINEAR,
+ /* nearest texture filtering */
+ WLR_SCALE_FILTER_NEAREST,
+};
+
struct wlr_render_texture_options {
/* Source texture */
struct wlr_texture *texture;
@@ -209,6 +219,8 @@ struct wlr_render_texture_options {
const pixman_region32_t *clip;
/* Transform applied to the source texture */
enum wl_output_transform transform;
+ /* Filtering */
+ enum wlr_scale_filter_mode filter_mode;
};
/**
diff --git a/render/gles2/pass.c b/render/gles2/pass.c
index 89ca873e..b1d21616 100644
--- a/render/gles2/pass.c
+++ b/render/gles2/pass.c
@@ -170,7 +170,18 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex);
- glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ switch (options->filter_mode) {
+ case WLR_SCALE_FILTER_BILINEAR:
+ glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ break;
+ case WLR_SCALE_FILTER_NEAREST:
+ glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ break;
+ }
+
glUniform1i(shader->tex, 0);
glUniform1f(shader->alpha, alpha);
set_proj_matrix(shader->proj, pass->projection_matrix, &dst_box);
diff --git a/render/pixman/pass.c b/render/pixman/pass.c
index 3f0927ee..0528d540 100644
--- a/render/pixman/pass.c
+++ b/render/pixman/pass.c
@@ -120,6 +120,15 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
height = src_box.height;
}
+ switch (options->filter_mode) {
+ case WLR_SCALE_FILTER_BILINEAR:
+ pixman_image_set_filter(texture->image, PIXMAN_FILTER_BILINEAR, NULL, 0);
+ break;
+ case WLR_SCALE_FILTER_NEAREST:
+ pixman_image_set_filter(texture->image, PIXMAN_FILTER_NEAREST, NULL, 0);
+ break;
+ }
+
pixman_image_set_clip_region32(buffer->image, (pixman_region32_t *)options->clip);
pixman_image_composite32(PIXMAN_OP_OVER, texture->image, mask,
buffer->image, src_box.x, src_box.y, 0, 0, dest_x, dest_y,
diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c
index acc2a5ae..7ac5cf95 100644
--- a/render/vulkan/pass.c
+++ b/render/vulkan/pass.c
@@ -547,6 +547,7 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
.source = WLR_VK_SHADER_SOURCE_TEXTURE,
.layout = {
.ycbcr_format = texture->format->is_ycbcr ? texture->format : NULL,
+ .filter_mode = options->filter_mode,
},
.texture_transform = texture->transform,
});
diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c
index 205f40ad..374d6384 100644
--- a/render/vulkan/renderer.c
+++ b/render/vulkan/renderer.c
@@ -2073,6 +2073,10 @@ static bool pipeline_layout_key_equals(
assert(!a->ycbcr_format || a->ycbcr_format->is_ycbcr);
assert(!b->ycbcr_format || b->ycbcr_format->is_ycbcr);
+ if (a->filter_mode != b->filter_mode) {
+ return false;
+ }
+
if (a->ycbcr_format != b->ycbcr_format) {
return false;
}
@@ -2384,12 +2388,21 @@ struct wlr_vk_pipeline_layout *get_or_create_pipeline_layout(
pipeline_layout->key = *key;
VkResult res;
+ VkFilter filter;
+ switch (key->filter_mode) {
+ case WLR_SCALE_FILTER_BILINEAR:
+ filter = VK_FILTER_LINEAR;
+ break;
+ case WLR_SCALE_FILTER_NEAREST:
+ filter = VK_FILTER_NEAREST;
+ break;
+ }
VkSamplerYcbcrConversionInfo conversion_info;
VkSamplerCreateInfo sampler_create_info = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
- .magFilter = VK_FILTER_LINEAR,
- .minFilter = VK_FILTER_LINEAR,
+ .magFilter = filter,
+ .minFilter = filter,
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,