[Mesa-dev] [PATCH v2 1/2] vl: add a lanczos interpolation filter v2
Nayan Deshmukh
nayan26deshmukh at gmail.com
Sat Jul 23 10:00:23 UTC 2016
Hi Christian,
I tried using the approach, the artifacts are gone. But for some videos
the output quality has reduced. The quality for such videos is somewhere
between nearest neighbor and linear interpolation.
Regards,
Nayan
On Thu, Jul 21, 2016 at 7:48 PM, Christian König <deathsimple at vodafone.de>
wrote:
> Am 21.07.2016 um 16:05 schrieb Nayan Deshmukh:
>
> Hi Christian,
>
> Yes, that is for pixel center adjustment.
>
> let me give you an example, for lanczos I need frac(x) where x is the
> original
> coordinate before scaling. To calculate that first I subtract half_pixel
> and then
> multiply by the original surface size, which gives me the original
> coordinate.
>
> eg. if the coordinate before scaling was 24.5 (total size 300) after 2x it
> becomes
> 49. When the frag shader is executed we get 49.5/600 as the coordinate so
> what
> I do is 49.5/600 - 0.5/600 = 49/600 and then multiply it with 300 to get
> 24.5 the
> original coordinate.
>
>
> Well in your case the coordinates are always between 0.0 and 1.0, so
> scaling doesn't affect the coordinate.
>
> You could take a look at how I did that in the weave shader:
> 1. In the vertex shader I use 0..width instead of 0..1 for the range (from
> create_vert_shader() in vl_compositor.c):
>
> * o_vtop.x = vtex.x
> * o_vtop.y = vtex.y * tmp.x + 0.25f
>
> 2. Then in the fragment shader I just need to do the following to get the
> original coordinate to sample from:
> * t_tc.y = (round(i_tc.y - 0.5) + 0.5) / height * 2
>
> I use 0.25 and "height * 2" here because the top/bottom fields are always
> halve the height and shifted a bit up/down.
>
> For your case that should just be:
>
> o_vtex.x = i_vpos.x * video_width
> o_vtex.y = i_vpos.y * video_height
>
> In the vertex shader and then:
>
> t_tc.x = (round(i_tc.x - 0.5) + 0.5) / video_width
> t_tc.y = (round(i_tc.x - 0.5) + 0.5) / video_height
>
> In the fragment shader to get the correct coordinate. No need to actually
> mess with the destination sizes here.
>
> Regards,
> Christian.
>
>
>
> Regards,
> Nayan.
> On Thu, Jul 21, 2016 at 7:20 PM, Christian König <deathsimple at vodafone.de>
> wrote:
>
>>
>> This seems to be the reason for the artifacts.
>>
>>
>>> + ureg_SUB(shader, ureg_writemask(t_array[0], TGSI_WRITEMASK_XY),
>>>> + i_vtex, half_pixel);
>>>>
>>>
>> On debugging I found that after removing this ^^^ instruction the
>> artifacts are gone.
>> Not sure why is this happening but the filter is working fine.
>>
>> Any ideas Christian?
>>
>>
>> Could it be that your values run out of the representable numeric range?
>> Otherwise I run out of ideas as well.
>>
>> Additional to that I'm not 100% sure I get what are you trying to do
>> here. Is that for the pixel center adjustment?
>>
>> Regards,
>> Christian.
>>
>>
>> Am 20.07.2016 um 14:02 schrieb Nayan Deshmukh:
>>
>> Hi Christian,
>>
>> Thanks for the review.
>>
>>
>> On Tue, Jul 19, 2016 at 4:58 PM, Christian König <deathsimple at vodafone.de
>> > wrote:
>>
>>> Am 18.07.2016 um 21:55 schrieb Nayan Deshmukh:
>>>
>>>> v2: avoCould it be that your values run out of the representable
>>>> numeric range?iding dividing by zero when calculating lanczos
>>>>
>>>> Signed-off-by: Nayan Deshmukh <nayan26deshmukh at gmail.com>
>>>>
>>>
>>> That looks much better, but there are still quite a bunch of artifacts.
>>>
>>> Take a look at the attached screenshots. good.jpg was created with
>>> hqscalling=0, bad with hqscalling=7.
>>>
>>> Especially on the left side we have lines from top to bottom where there
>>> shouldn't be any.
>>>
>>> Regards,
>>> Christian.
>>>
>>>
>>> ---
>>>> src/gallium/auxiliary/Makefile.sources | 2 +
>>>> src/gallium/auxiliary/vl/vl_lanczos_filter.c | 447
>>>> +++++++++++++++++++++++++++
>>>> src/gallium/auxiliary/vl/vl_lanczos_filter.h | 63 ++++
>>>> 3 files changed, 512 insertions(+)
>>>> create mode 100644 src/gallium/auxiliary/vl/vl_lanczos_filter.c
>>>> create mode 100644 src/gallium/auxiliary/vl/vl_lanczos_filter.h
>>>>
>>>> diff --git a/src/gallium/auxiliary/Makefile.sources
>>>> b/src/gallium/auxiliary/Makefile.sources
>>>> index e0311bf..4eb0f65 100644
>>>> --- a/src/gallium/auxiliary/Makefile.sources
>>>> +++ b/src/gallium/auxiliary/Makefile.sources
>>>> @@ -330,6 +330,8 @@ VL_SOURCES := \
>>>> vl/vl_deint_filter.h \
>>>> vl/vl_idct.c \
>>>> vl/vl_idct.h \
>>>> + vl/vl_lanczos_filter.c \
>>>> + vl/vl_lanczos_filter.h \
>>>> vl/vl_matrix_filter.c \
>>>> vl/vl_matrix_filter.h \
>>>> vl/vl_mc.c \
>>>> diff --git a/src/gallium/auxiliary/vl/vl_lanczos_filter.c
>>>> b/src/gallium/auxiliary/vl/vl_lanczos_filter.c
>>>> new file mode 100644
>>>> index 0000000..7c69555
>>>> --- /dev/null
>>>> +++ b/src/gallium/auxiliary/vl/vl_lanczos_filter.c
>>>> @@ -0,0 +1,447 @@
>>>>
>>>> +/**************************************************************************
>>>> + *
>>>> + * Copyright 2016 Nayan Deshmukh.
>>>> + * All Rights Reserved.
>>>> + *
>>>> + * Permission is hereby granted, free of charge, to any person
>>>> obtaining a
>>>> + * copy of this software and associated documentation files (the
>>>> + * "Software"), to deal in the Software without restriction, including
>>>> + * without limitation the rights to use, copy, modify, merge, publish,
>>>> + * distribute, sub license, and/or sell copies of the Software, and to
>>>> + * permit persons to whom the Software is furnished to do so, subject
>>>> to
>>>> + * the following conditions:
>>>> + *
>>>> + * The above copyright notice and this permission notice (including the
>>>> + * next paragraph) shall be included in all copies or substantial
>>>> portions
>>>> + * of the Software.
>>>> + *
>>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>>>> EXPRESS
>>>> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>>>> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>>>> NON-INFRINGEMENT.
>>>> + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
>>>> + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
>>>> CONTRACT,
>>>> + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
>>>> + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>>>> + *
>>>> +
>>>> **************************************************************************/
>>>> +
>>>> +#include <stdio.h>
>>>> +
>>>> +#include "pipe/p_context.h"
>>>> +
>>>> +#include "tgsi/tgsi_ureg.h"
>>>> +
>>>> +#include "util/u_draw.h"
>>>> +#include "util/u_memory.h"
>>>> +#include "util/u_math.h"
>>>> +#include "util/u_rect.h"
>>>> +
>>>> +#include "vl_types.h"
>>>> +#include "vl_vertex_buffers.h"
>>>> +#include "vl_lanczos_filter.h"
>>>> +
>>>> +enum VS_OUTPUT
>>>> +{
>>>> + VS_O_VPOS = 0,
>>>> + VS_O_VTEX = 0
>>>> +};
>>>> +
>>>> +static void *
>>>> +create_vert_shader(struct vl_lanczos_filter *filter)
>>>> +{
>>>> + struct ureg_program *shader;
>>>> + struct ureg_src i_vpos;
>>>> + struct ureg_dst o_vpos, o_vtex;
>>>> +
>>>> + shader = ureg_create(PIPE_SHADER_VERTEX);
>>>> + if (!shader)
>>>> + return NULL;
>>>> +
>>>> + i_vpos = ureg_DECL_vs_input(shader, 0);
>>>> + o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION,
>>>> VS_O_VPOS);
>>>> + o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX);
>>>> +
>>>> + ureg_MOV(shader, o_vpos, i_vpos);
>>>> + ureg_MOV(shader, o_vtex, i_vpos);
>>>> +
>>>> + ureg_END(shader);
>>>> +
>>>> + return ureg_create_shader_and_destroy(shader, filter->pipe);
>>>> +}
>>>> +
>>>> +static void
>>>> +create_frag_shader_lanczos(struct ureg_program *shader, struct
>>>> ureg_src a,
>>>> + struct ureg_src x, struct ureg_dst
>>>> o_fragment)
>>>> +{
>>>> + struct ureg_dst temp[8];
>>>> + unsigned i;
>>>> +
>>>> + for(i = 0; i < 8; ++i)
>>>> + temp[i] = ureg_DECL_temporary(shader);
>>>> +
>>>> + /*
>>>> + * temp[0] = (x == 0) ? 1.0f : x
>>>> + * temp[7] = (sin(pi * x) * sin ((pi * x)/a)) / x^2
>>>> + * o_fragment = (x == 0) ? 1.0f : temp[7]
>>>> + */
>>>> + ureg_MOV(shader, temp[0], x);
>>>> + ureg_SEQ(shader, temp[1], x, ureg_imm1f(shader, 0.0f));
>>>> +
>>>> + ureg_LRP(shader, temp[0], ureg_src(temp[1]),
>>>> + ureg_imm1f(shader, 1.0f), ureg_src(temp[0]));
>>>> +
>>>> + ureg_MUL(shader, temp[2], x,
>>>> + ureg_imm1f(shader, 3.141592));
>>>> + ureg_DIV(shader, temp[3], ureg_src(temp[2]), a);
>>>> +
>>>> + ureg_SIN(shader, temp[4], ureg_src(temp[2]));
>>>> + ureg_SIN(shader, temp[5], ureg_src(temp[3]));
>>>> +
>>>> + ureg_MUL(shader, temp[6], ureg_src(temp[4]),
>>>> + ureg_src(temp[5]));
>>>> + ureg_MUL(shader, temp[7], ureg_imm1f(shader,
>>>> + 0.101321), a);
>>>> + ureg_MUL(shader, temp[7], ureg_src(temp[7]),
>>>> + ureg_src(temp[6]));
>>>> + ureg_DIV(shader, temp[7], ureg_src(temp[7]),
>>>> + ureg_src(temp[0]));
>>>> + ureg_DIV(shader, o_fragment,
>>>> + ureg_src(temp[7]), ureg_src(temp[0]));
>>>> +
>>>> + ureg_LRP(shader, o_fragment, ureg_src(temp[1]),
>>>> + ureg_imm1f(shader, 1.0f), ureg_src(o_fragment));
>>>> +
>>>> + for(i = 0; i < 8; ++i)
>>>> + ureg_release_temporary(shader, temp[i]);
>>>> +}
>>>> +
>>>> +static void *
>>>> +create_frag_shader(struct vl_lanczos_filter *filter, unsigned
>>>> num_offsets,
>>>> + struct vertex2f *offsets, unsigned a,
>>>> + unsigned video_width, unsigned video_height)
>>>> +{
>>>> + struct pipe_screen *screen = filter->pipe->screen;
>>>> + struct ureg_program *shader;
>>>> + struct ureg_src i_vtex, vtex;
>>>> + struct ureg_src sampler;
>>>> + struct ureg_src half_pixel;
>>>> + struct ureg_dst o_fragment;
>>>> + struct ureg_dst *t_array = MALLOC(sizeof(struct ureg_dst) *
>>>> (num_offsets + 2));
>>>> + struct ureg_dst x, t_sum;
>>>> + unsigned i;
>>>> + bool first;
>>>> +
>>>> + if (screen->get_shader_param(
>>>> + screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_TEMPS) <
>>>> num_offsets + 2) {
>>>> + return NULL;
>>>> + }
>>>> +
>>>> + shader = ureg_create(PIPE_SHADER_FRAGMENT);
>>>> + if (!shader) {
>>>> + return NULL;
>>>> + }
>>>> +
>>>> + i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC,
>>>> VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);
>>>> + sampler = ureg_DECL_sampler(shader, 0);
>>>> +
>>>> + for (i = 0; i < num_offsets + 2; ++i)
>>>> + t_array[i] = ureg_DECL_temporary(shader);
>>>> + x = ureg_DECL_temporary(shader);
>>>> +
>>>> + half_pixel = ureg_DECL_constant(shader, 0);
>>>> + o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
>>>> +
>>>> + /*
>>>> + * temp = (i_vtex - (0.5/dst_size)) * i_size)
>>>> + * x = frac(temp)
>>>> + * vtex = floor(i_vtex)/i_size + half_pixel
>>>> + */
>>>>
>>>
>> This seems to be the reason for the artifacts.
>>
>>
>>> + ureg_SUB(shader, ureg_writemask(t_array[0], TGSI_WRITEMASK_XY),
>>>> + i_vtex, half_pixel);
>>>>
>>>
>> On debugging I found that after removing this ^^^ instruction the
>> artifacts are gone.
>> Not sure why is this happening but the filter is working fine.
>>
>> Any ideas Christian?
>>
>> Regards,
>> Nayan.
>>
>>> + ureg_MUL(shader, ureg_writemask(t_array[1], TGSI_WRITEMASK_XY),
>>>> + ureg_src(t_array[0]), ureg_imm2f(shader, video_width,
>>>> video_height));
>>>> + ureg_FRC(shader, ureg_writemask(x, TGSI_WRITEMASK_XY),
>>>> + ureg_src(t_array[1]));
>>>> +
>>>> + ureg_FLR(shader, ureg_writemask(t_array[1], TGSI_WRITEMASK_XY),
>>>> + ureg_src(t_array[1]));
>>>> + ureg_DIV(shader, ureg_writemask(t_array[1], TGSI_WRITEMASK_XY),
>>>> + ureg_src(t_array[1]), ureg_imm2f(shader, video_width,
>>>> video_height));
>>>> + ureg_ADD(shader, ureg_writemask(t_array[1], TGSI_WRITEMASK_XY),
>>>> + ureg_src(t_array[1]), half_pixel);
>>>> + /*
>>>> + * t_array[2..*] = vtex + offset[0..*]
>>>> + * t_array[2..*] = tex(t_array[0..*], sampler)
>>>> + * o_fragment = sum(t_array[i] * lanczos(x - offsets[i].x) *
>>>> lanczos(y - offsets[i].y))
>>>> + */
>>>> + vtex = ureg_src(t_array[1]);
>>>> + for (i = 0; i < num_offsets; ++i) {
>>>> + ureg_ADD(shader, ureg_writemask(t_array[i + 2],
>>>> TGSI_WRITEMASK_XY),
>>>> + vtex, ureg_imm2f(shader, offsets[i].x,
>>>> offsets[i].y));
>>>> + ureg_MOV(shader, ureg_writemask(t_array[i + 2],
>>>> TGSI_WRITEMASK_ZW),
>>>> + ureg_imm1f(shader, 0.0f));
>>>> + }
>>>> +
>>>> + for (i = 0; i < num_offsets; ++i) {
>>>> + ureg_TEX(shader, t_array[i + 2], TGSI_TEXTURE_2D,
>>>> ureg_src(t_array[i + 2]), sampler);
>>>> + }
>>>> +
>>>> + for(i = 0, first = true; i < num_offsets; ++i) {
>>>> + if (first) {
>>>> + t_sum = t_array[i + 2];
>>>> + ureg_SUB(shader, ureg_writemask(t_array[i],
>>>> TGSI_WRITEMASK_XY),
>>>> + ureg_src(x), ureg_imm2f(shader, offsets[i].x *
>>>> video_width,
>>>> + offsets[i].y * video_height));
>>>> + create_frag_shader_lanczos(shader, ureg_imm1f(shader,
>>>> (float)(a)),
>>>> + ureg_scalar(ureg_src(t_array[i]), TGSI_SWIZZLE_X),
>>>> t_array[i + 1]);
>>>> + create_frag_shader_lanczos(shader, ureg_imm1f(shader,
>>>> (float)(a)),
>>>> + ureg_scalar(ureg_src(t_array[i]), TGSI_SWIZZLE_Y),
>>>> t_array[i]);
>>>> + ureg_MUL(shader, t_array[i + 1], ureg_src(t_array[i + 1]),
>>>> + ureg_src(t_array[i]));
>>>> + ureg_MUL(shader, t_sum, ureg_src(t_array[i + 2]),
>>>> + ureg_src(t_array[i + 1]));
>>>> + first = false;
>>>> + } else {
>>>> + ureg_SUB(shader, ureg_writemask(t_array[i],
>>>> TGSI_WRITEMASK_XY),
>>>> + ureg_src(x), ureg_imm2f(shader, offsets[i].x *
>>>> video_width,
>>>> + offsets[i].y * video_height));
>>>> + create_frag_shader_lanczos(shader, ureg_imm1f(shader,
>>>> (float)(a)),
>>>> + ureg_scalar(ureg_src(t_array[i]), TGSI_SWIZZLE_X),
>>>> t_array[i + 1]);
>>>> + create_frag_shader_lanczos(shader, ureg_imm1f(shader,
>>>> (float)(a)),
>>>> + ureg_scalar(ureg_src(t_array[i]), TGSI_SWIZZLE_Y),
>>>> t_array[i]);
>>>> + ureg_MUL(shader, t_array[i + 1], ureg_src(t_array[i + 1]),
>>>> + ureg_src(t_array[i]));
>>>> + ureg_MAD(shader, t_sum, ureg_src(t_array[i + 2]),
>>>> + ureg_src(t_array[i + 1]), ureg_src(t_sum));
>>>> + }
>>>> + }
>>>> +
>>>> + if (first)
>>>> + ureg_MOV(shader, o_fragment, ureg_imm1f(shader, 0.0f));
>>>> + else
>>>> + ureg_MOV(shader, o_fragment, ureg_src(t_sum));
>>>> +
>>>> + ureg_release_temporary(shader, x);
>>>> + ureg_END(shader);
>>>> +
>>>> + FREE(t_array);
>>>> + return ureg_create_shader_and_destroy(shader, filter->pipe);
>>>> +}
>>>> +
>>>> +bool
>>>> +vl_lanczos_filter_init(struct vl_lanczos_filter *filter, struct
>>>> pipe_context *pipe,
>>>> + unsigned size, unsigned width, unsigned height)
>>>> +{
>>>> + struct pipe_rasterizer_state rs_state;
>>>> + struct pipe_blend_state blend;
>>>> + struct vertex2f *offsets, v, sizes;
>>>> + struct pipe_sampler_state sampler;
>>>> + struct pipe_vertex_element ve;
>>>> + unsigned i, num_offsets = (2 * size) * (2 * size);
>>>> +
>>>> + assert(filter && pipe);
>>>> + assert(width && height);
>>>> + assert(size);
>>>> +
>>>> + memset(filter, 0, sizeof(*filter));
>>>> + filter->pipe = pipe;
>>>> +
>>>> + memset(&rs_state, 0, sizeof(rs_state));
>>>> + rs_state.half_pixel_center = true;
>>>> + rs_state.bottom_edge_rule = true;
>>>> + rs_state.depth_clip = 1;
>>>> + filter->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
>>>> + if (!filter->rs_state)
>>>> + goto error_rs_state;
>>>> +
>>>> + memset(&blend, 0, sizeof blend);
>>>> + blend.rt[0].rgb_func = PIPE_BLEND_ADD;
>>>> + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
>>>> + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
>>>> + blend.rt[0].alpha_func = PIPE_BLEND_ADD;
>>>> + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
>>>> + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
>>>> + blend.logicop_func = PIPE_LOGICOP_CLEAR;
>>>> + blend.rt[0].colormask = PIPE_MASK_RGBA;
>>>> + filter->blend = pipe->create_blend_state(pipe, &blend);
>>>> + if (!filter->blend)
>>>> + goto error_blend;
>>>> +
>>>> + memset(&sampler, 0, sizeof(sampler));
>>>> + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
>>>> + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
>>>> + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
>>>> + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
>>>> + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
>>>> + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
>>>> + sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
>>>> + sampler.compare_func = PIPE_FUNC_ALWAYS;
>>>> + sampler.normalized_coords = 1;
>>>> + filter->sampler = pipe->create_sampler_state(pipe, &sampler);
>>>> + if (!filter->sampler)
>>>> + goto error_sampler;
>>>> +
>>>> + filter->quad = vl_vb_upload_quads(pipe);
>>>> + if(!filter->quad.buffer)
>>>> + goto error_quad;
>>>> +
>>>> + memset(&ve, 0, sizeof(ve));
>>>> + ve.src_offset = 0;
>>>> + ve.instance_divisor = 0;
>>>> + ve.vertex_buffer_index = 0;
>>>> + ve.src_format = PIPE_FORMAT_R32G32_FLOAT;
>>>> + filter->ves = pipe->create_vertex_elements_state(pipe, 1, &ve);
>>>> + if (!filter->ves)
>>>> + goto error_ves;
>>>> +
>>>> + offsets = MALLOC(sizeof(struct vertex2f) * num_offsets);
>>>> + if (!offsets)
>>>> + goto error_offsets;
>>>> +
>>>> + sizes.x = (float)(size);
>>>> + sizes.y = (float)(size);
>>>> +
>>>> + for (v.x = -sizes.x + 1.0f, i = 0; v.x <= sizes.x; v.x += 1.0f)
>>>> + for (v.y = -sizes.y + 1.0f; v.y <= sizes.y; v.y += 1.0f)
>>>> + offsets[i++] = v;
>>>> +
>>>> + for (i = 0; i < num_offsets; ++i) {
>>>> + offsets[i].x /= width;
>>>> + offsets[i].y /= height;
>>>> + }
>>>> +
>>>> + filter->vs = create_vert_shader(filter);
>>>> + if (!filter->vs)
>>>> + goto error_vs;
>>>> +
>>>> + filter->fs = create_frag_shader(filter, num_offsets, offsets, size,
>>>> width, height);
>>>> + if (!filter->fs)
>>>> + goto error_fs;
>>>> +
>>>> + FREE(offsets);
>>>> + return true;
>>>> +
>>>> +error_fs:
>>>> + pipe->delete_vs_state(pipe, filter->vs);
>>>> +
>>>> +error_vs:
>>>> + FREE(offsets);
>>>> +
>>>> +error_offsets:
>>>> + pipe->delete_vertex_elements_state(pipe, filter->ves);
>>>> +
>>>> +error_ves:
>>>> + pipe_resource_reference(&filter->quad.buffer, NULL);
>>>> +
>>>> +error_quad:
>>>> + pipe->delete_sampler_state(pipe, filter->sampler);
>>>> +
>>>> +error_sampler:
>>>> + pipe->delete_blend_state(pipe, filter->blend);
>>>> +
>>>> +error_blend:
>>>> + pipe->delete_rasterizer_state(pipe, filter->rs_state);
>>>> +
>>>> +error_rs_state:
>>>> + return false;
>>>> +}
>>>> +
>>>> +void
>>>> +vl_lanczos_filter_cleanup(struct vl_lanczos_filter *filter)
>>>> +{
>>>> + assert(filter);
>>>> +
>>>> + filter->pipe->delete_sampler_state(filter->pipe, filter->sampler);
>>>> + filter->pipe->delete_blend_state(filter->pipe, filter->blend);
>>>> + filter->pipe->delete_rasterizer_state(filter->pipe,
>>>> filter->rs_state);
>>>> + filter->pipe->delete_vertex_elements_state(filter->pipe,
>>>> filter->ves);
>>>> + pipe_resource_reference(&filter->quad.buffer, NULL);
>>>> +
>>>> + filter->pipe->delete_vs_state(filter->pipe, filter->vs);
>>>> + filter->pipe->delete_fs_state(filter->pipe, filter->fs);
>>>> +}
>>>> +
>>>> +void
>>>> +vl_lanczos_filter_render(struct vl_lanczos_filter *filter,
>>>> + struct pipe_sampler_view *src,
>>>> + struct pipe_surface *dst,
>>>> + struct u_rect *dst_area,
>>>> + struct u_rect *dst_clip)
>>>> +{
>>>> + struct pipe_viewport_state viewport;
>>>> + struct pipe_framebuffer_state fb_state;
>>>> + struct pipe_scissor_state scissor;
>>>> + union pipe_color_union clear_color;
>>>> + struct pipe_transfer *buf_transfer;
>>>> + struct pipe_resource *surface_size;
>>>> + assert(filter && src && dst);
>>>> +
>>>> + if (dst_clip) {
>>>> + scissor.minx = dst_clip->x0;
>>>> + scissor.miny = dst_clip->y0;
>>>> + scissor.maxx = dst_clip->x1;
>>>> + scissor.maxy = dst_clip->y1;
>>>> + } else {
>>>> + scissor.minx = 0;
>>>> + scissor.miny = 0;
>>>> + scissor.maxx = dst->width;
>>>> + scissor.maxy = dst->height;
>>>> + }
>>>> +
>>>> + clear_color.f[0] = clear_color.f[1] = 0.0f;
>>>> + clear_color.f[2] = clear_color.f[3] = 0.0f;
>>>> + surface_size = pipe_buffer_create
>>>> + (
>>>> + filter->pipe->screen,
>>>> + PIPE_BIND_CONSTANT_BUFFER,
>>>> + PIPE_USAGE_DEFAULT,
>>>> + 2*sizeof(float)
>>>> + );
>>>> +
>>>> +
>>>> + memset(&viewport, 0, sizeof(viewport));
>>>> + if(dst_area){
>>>> + viewport.scale[0] = dst_area->x1 - dst_area->x0;
>>>> + viewport.scale[1] = dst_area->y1 - dst_area->y0;
>>>> + viewport.translate[0] = dst_area->x0;
>>>> + viewport.translate[1] = dst_area->y0;
>>>> + } else {
>>>> + viewport.scale[0] = dst->width;
>>>> + viewport.scale[1] = dst->height;
>>>> + }
>>>> + viewport.scale[2] = 1;
>>>> +
>>>> + float *ptr = pipe_buffer_map(filter->pipe, surface_size,
>>>> + PIPE_TRANSFER_WRITE |
>>>> PIPE_TRANSFER_DISCARD_RANGE,
>>>> + &buf_transfer);
>>>> +
>>>> + ptr[0] = 0.5f/viewport.scale[0];
>>>> + ptr[1] = 0.5f/viewport.scale[1];
>>>> +
>>>> + pipe_buffer_unmap(filter->pipe, buf_transfer);
>>>> +
>>>> + memset(&fb_state, 0, sizeof(fb_state));
>>>> + fb_state.width = dst->width;
>>>> + fb_state.height = dst->height;
>>>> + fb_state.nr_cbufs = 1;
>>>> + fb_state.cbufs[0] = dst;
>>>> +
>>>> + filter->pipe->set_scissor_states(filter->pipe, 0, 1, &scissor);
>>>> + filter->pipe->clear_render_target(filter->pipe, dst, &clear_color,
>>>> + 0, 0, dst->width, dst->height);
>>>> + pipe_set_constant_buffer(filter->pipe, PIPE_SHADER_FRAGMENT, 0,
>>>> surface_size);
>>>> + filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state);
>>>> + filter->pipe->bind_blend_state(filter->pipe, filter->blend);
>>>> + filter->pipe->bind_sampler_states(filter->pipe,
>>>> PIPE_SHADER_FRAGMENT,
>>>> + 0, 1, &filter->sampler);
>>>> + filter->pipe->set_sampler_views(filter->pipe, PIPE_SHADER_FRAGMENT,
>>>> + 0, 1, &src);
>>>> + filter->pipe->bind_vs_state(filter->pipe, filter->vs);
>>>> + filter->pipe->bind_fs_state(filter->pipe, filter->fs);
>>>> + filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
>>>> + filter->pipe->set_viewport_states(filter->pipe, 0, 1, &viewport);
>>>> + filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad);
>>>> + filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
>>>> +
>>>> + util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
>>>> +}
>>>> diff --git a/src/gallium/auxiliary/vl/vl_lanczos_filter.h
>>>> b/src/gallium/auxiliary/vl/vl_lanczos_filter.h
>>>> new file mode 100644
>>>> index 0000000..cb469aa
>>>> --- /dev/null
>>>> +++ b/src/gallium/auxiliary/vl/vl_lanczos_filter.h
>>>> @@ -0,0 +1,63 @@
>>>>
>>>> +/**************************************************************************
>>>> + *
>>>> + * Copyright 2016 Nayan Deshmukh.
>>>> + * All Rights Reserved.
>>>> + *
>>>> + * Permission is hereby granted, free of charge, to any person
>>>> obtaining a
>>>> + * copy of this software and associated documentation files (the
>>>> + * "Software"), to deal in the Software without restriction, including
>>>> + * without limitation the rights to use, copy, modify, merge, publish,
>>>> + * distribute, sub license, and/or sell copies of the Software, and to
>>>> + * permit persons to whom the Software is furnished to do so, subject
>>>> to
>>>> + * the following conditions:
>>>> + *
>>>> + * The above copyright notice and this permission notice (including the
>>>> + * next paragraph) shall be included in all copies or substantial
>>>> portions
>>>> + * of the Software.
>>>> + *
>>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>>>> EXPRESS
>>>> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>>>> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>>>> NON-INFRINGEMENT.
>>>> + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
>>>> + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
>>>> CONTRACT,
>>>> + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
>>>> + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>>>> + *
>>>> +
>>>> **************************************************************************/
>>>> +
>>>> +/* implementation of lanczos interpolation filter */
>>>> +
>>>> +#ifndef vl_lanczos_filter_h
>>>> +#define vl_lanczos_filter_h
>>>> +
>>>> +#include "pipe/p_state.h"
>>>> +
>>>> +struct vl_lanczos_filter
>>>> +{
>>>> + struct pipe_context *pipe;
>>>> + struct pipe_vertex_buffer quad;
>>>> +
>>>> + void *rs_state;
>>>> + void *blend;
>>>> + void *sampler;
>>>> + void *ves;
>>>> + void *vs, *fs;
>>>> +};
>>>> +
>>>> +bool
>>>> +vl_lanczos_filter_init(struct vl_lanczos_filter *filter, struct
>>>> pipe_context *pipe,
>>>> + unsigned size, unsigned width, unsigned height);
>>>> +
>>>> +void
>>>> +vl_lanczos_filter_cleanup(struct vl_lanczos_filter *filter);
>>>> +
>>>> +
>>>> +void
>>>> +vl_lanczos_filter_render(struct vl_lanczos_filter *filter,
>>>> + struct pipe_sampler_view *src,
>>>> + struct pipe_surface *dst,
>>>> + struct u_rect *dst_area,
>>>> + struct u_rect *dst_clip);
>>>> +
>>>> +
>>>> +#endif /* vl_lanczos_filter_h */
>>>>
>>>
>>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160723/62f1cfc4/attachment-0001.html>
More information about the mesa-dev
mailing list