From 214a431cafa5227571111841cdd864112ca1f97c Mon Sep 17 00:00:00 2001 From: David Rosca Date: Wed, 5 Mar 2025 09:24:31 +0100 Subject: [PATCH] gallium/vl: Remove mpeg12 shader decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The decoder has been broken for years. It creates 3-plane video buffer with RGB16 format for all three planes, which hasn't been working since 243475b96cc. It also doesn't make sense anymore to use shader decoder for a codec this old. Acked-by: Pavel Ondračka Reviewed-by: Leo Liu Part-of: --- src/gallium/auxiliary/meson.build | 10 - src/gallium/auxiliary/vl/vl_decoder.c | 94 -- src/gallium/auxiliary/vl/vl_decoder.h | 54 - src/gallium/auxiliary/vl/vl_idct.c | 855 ------------ src/gallium/auxiliary/vl/vl_idct.h | 119 -- src/gallium/auxiliary/vl/vl_mc.c | 657 --------- src/gallium/auxiliary/vl/vl_mc.h | 97 -- src/gallium/auxiliary/vl/vl_mpeg12_decoder.c | 1225 ----------------- src/gallium/auxiliary/vl/vl_mpeg12_decoder.h | 114 -- src/gallium/auxiliary/vl/vl_stubs.c | 44 - src/gallium/auxiliary/vl/vl_zscan.c | 543 -------- src/gallium/auxiliary/vl/vl_zscan.h | 105 -- .../drivers/d3d12/d3d12_video_dec_h264.cpp | 2 +- src/gallium/drivers/nouveau/nv50/nv84_video.c | 2 +- src/gallium/drivers/nouveau/nv50/nv84_video.h | 1 - src/gallium/drivers/nouveau/nv50/nv98_video.h | 1 - src/gallium/drivers/nouveau/nvc0/nvc0_video.h | 1 - src/gallium/drivers/virgl/virgl_screen.c | 1 - src/gallium/drivers/virgl/virgl_video.c | 1 - src/gallium/frontends/va/picture_hevc.c | 2 +- 20 files changed, 3 insertions(+), 3925 deletions(-) delete mode 100644 src/gallium/auxiliary/vl/vl_decoder.c delete mode 100644 src/gallium/auxiliary/vl/vl_decoder.h delete mode 100644 src/gallium/auxiliary/vl/vl_idct.c delete mode 100644 src/gallium/auxiliary/vl/vl_idct.h delete mode 100644 src/gallium/auxiliary/vl/vl_mc.c delete mode 100644 src/gallium/auxiliary/vl/vl_mc.h delete mode 100644 src/gallium/auxiliary/vl/vl_mpeg12_decoder.c delete mode 100644 src/gallium/auxiliary/vl/vl_mpeg12_decoder.h delete mode 100644 src/gallium/auxiliary/vl/vl_zscan.c delete mode 100644 src/gallium/auxiliary/vl/vl_zscan.h diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index c78b0affa00..b1dad4fce88 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -395,28 +395,18 @@ files_libgalliumvl = files( 'vl/vl_compositor_cs.h', 'vl/vl_csc.c', 'vl/vl_csc.h', - 'vl/vl_decoder.c', - 'vl/vl_decoder.h', 'vl/vl_defines.h', 'vl/vl_deint_filter.c', 'vl/vl_deint_filter.h', 'vl/vl_deint_filter_cs.c', 'vl/vl_deint_filter_cs.h', - 'vl/vl_idct.c', - 'vl/vl_idct.h', - 'vl/vl_mc.c', - 'vl/vl_mc.h', 'vl/vl_mpeg12_bitstream.c', 'vl/vl_mpeg12_bitstream.h', - 'vl/vl_mpeg12_decoder.c', - 'vl/vl_mpeg12_decoder.h', 'vl/vl_types.h', 'vl/vl_vertex_buffers.c', 'vl/vl_vertex_buffers.h', 'vl/vl_video_buffer.c', 'vl/vl_video_buffer.h', - 'vl/vl_zscan.c', - 'vl/vl_zscan.h', ) vlwinsys_deps = [] diff --git a/src/gallium/auxiliary/vl/vl_decoder.c b/src/gallium/auxiliary/vl/vl_decoder.c deleted file mode 100644 index 97e549d6a50..00000000000 --- a/src/gallium/auxiliary/vl/vl_decoder.c +++ /dev/null @@ -1,94 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * 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 "pipe/p_video_codec.h" - -#include "util/u_video.h" - -#include "vl_decoder.h" -#include "vl_mpeg12_decoder.h" - -bool -vl_profile_supported(struct pipe_screen *screen, enum pipe_video_profile profile, - enum pipe_video_entrypoint entrypoint) -{ - assert(screen); - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_FORMAT_MPEG12: - return entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE; - default: - return false; - } -} - -int -vl_level_supported(struct pipe_screen *screen, enum pipe_video_profile profile) -{ - assert(screen); - switch (profile) { - case PIPE_VIDEO_PROFILE_MPEG1: - return 0; - case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE: - case PIPE_VIDEO_PROFILE_MPEG2_MAIN: - return 3; - default: - return 0; - } -} - -struct pipe_video_codec * -vl_create_decoder(struct pipe_context *pipe, - const struct pipe_video_codec *templat) -{ - unsigned width = templat->width, height = templat->height; - struct pipe_video_codec temp; - bool pot_buffers; - - assert(pipe); - assert(width > 0 && height > 0); - - pot_buffers = !pipe->screen->get_video_param - ( - pipe->screen, - templat->profile, - templat->entrypoint, - PIPE_VIDEO_CAP_NPOT_TEXTURES - ); - - temp = *templat; - temp.width = pot_buffers ? util_next_power_of_two(width) : align(width, VL_MACROBLOCK_WIDTH); - temp.height = pot_buffers ? util_next_power_of_two(height) : align(height, VL_MACROBLOCK_HEIGHT); - - switch (u_reduce_video_profile(temp.profile)) { - case PIPE_VIDEO_FORMAT_MPEG12: - return vl_create_mpeg12_decoder(pipe, &temp); - - default: - return NULL; - } - return NULL; -} diff --git a/src/gallium/auxiliary/vl/vl_decoder.h b/src/gallium/auxiliary/vl/vl_decoder.h deleted file mode 100644 index 90fcc118588..00000000000 --- a/src/gallium/auxiliary/vl/vl_decoder.h +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * Copyright 2011 Christian König. - * 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. - * - **************************************************************************/ - -#ifndef vl_decoder_h -#define vl_decoder_h - -#include "pipe/p_video_codec.h" - -/** - * check if a given profile is supported with shader based decoding - */ -bool -vl_profile_supported(struct pipe_screen *screen, enum pipe_video_profile profile, - enum pipe_video_entrypoint entrypoint); - -/** - * get the maximum supported level for the given profile with shader based decoding - */ -int -vl_level_supported(struct pipe_screen *screen, enum pipe_video_profile profile); - -/** - * standard implementation of pipe->create_video_codec - */ -struct pipe_video_codec * -vl_create_decoder(struct pipe_context *pipe, - const struct pipe_video_codec *templat); - -#endif /* vl_decoder_h */ diff --git a/src/gallium/auxiliary/vl/vl_idct.c b/src/gallium/auxiliary/vl/vl_idct.c deleted file mode 100644 index 306149f48fd..00000000000 --- a/src/gallium/auxiliary/vl/vl_idct.c +++ /dev/null @@ -1,855 +0,0 @@ -/************************************************************************** - * - * Copyright 2010 Christian König - * 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 - -#include "pipe/p_context.h" -#include "pipe/p_screen.h" - -#include "util/u_draw.h" -#include "util/u_sampler.h" -#include "util/u_memory.h" - -#include "tgsi/tgsi_ureg.h" - -#include "vl_defines.h" -#include "vl_types.h" -#include "vl_vertex_buffers.h" -#include "vl_idct.h" - -enum VS_OUTPUT -{ - VS_O_VPOS = 0, - VS_O_L_ADDR0 = 0, - VS_O_L_ADDR1, - VS_O_R_ADDR0, - VS_O_R_ADDR1 -}; - -/** - * The DCT matrix stored as hex representation of floats. Equal to the following equation: - * for (i = 0; i < 8; ++i) - * for (j = 0; j < 8; ++j) - * if (i == 0) const_matrix[i][j] = 1.0f / sqrtf(8.0f); - * else const_matrix[i][j] = sqrtf(2.0f / 8.0f) * cosf((2 * j + 1) * i * M_PI / (2.0f * 8.0f)); - */ -static const uint32_t const_matrix[8][8] = { - { 0x3eb504f3, 0x3eb504f3, 0x3eb504f3, 0x3eb504f3, 0x3eb504f3, 0x3eb504f3, 0x3eb504f3, 0x3eb504f3 }, - { 0x3efb14be, 0x3ed4db31, 0x3e8e39da, 0x3dc7c5c4, 0xbdc7c5c2, 0xbe8e39d9, 0xbed4db32, 0xbefb14bf }, - { 0x3eec835f, 0x3e43ef15, 0xbe43ef14, 0xbeec835e, 0xbeec835f, 0xbe43ef1a, 0x3e43ef1b, 0x3eec835f }, - { 0x3ed4db31, 0xbdc7c5c2, 0xbefb14bf, 0xbe8e39dd, 0x3e8e39d7, 0x3efb14bf, 0x3dc7c5d0, 0xbed4db34 }, - { 0x3eb504f3, 0xbeb504f3, 0xbeb504f4, 0x3eb504f1, 0x3eb504f3, 0xbeb504f0, 0xbeb504ef, 0x3eb504f4 }, - { 0x3e8e39da, 0xbefb14bf, 0x3dc7c5c8, 0x3ed4db32, 0xbed4db34, 0xbdc7c5bb, 0x3efb14bf, 0xbe8e39d7 }, - { 0x3e43ef15, 0xbeec835f, 0x3eec835f, 0xbe43ef07, 0xbe43ef23, 0x3eec8361, 0xbeec835c, 0x3e43ef25 }, - { 0x3dc7c5c4, 0xbe8e39dd, 0x3ed4db32, 0xbefb14c0, 0x3efb14be, 0xbed4db31, 0x3e8e39ce, 0xbdc7c596 }, -}; - -static void -calc_addr(struct ureg_program *shader, struct ureg_dst addr[2], - struct ureg_src tc, struct ureg_src start, bool right_side, - bool transposed, float size) -{ - unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y; - unsigned sw_start = right_side ? TGSI_SWIZZLE_Y : TGSI_SWIZZLE_X; - - unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X; - unsigned sw_tc = right_side ? TGSI_SWIZZLE_X : TGSI_SWIZZLE_Y; - - /* - * addr[0..1].(start) = right_side ? start.x : tc.x - * addr[0..1].(tc) = right_side ? tc.y : start.y - * addr[0..1].z = tc.z - * addr[1].(start) += 1.0f / scale - */ - ureg_MOV(shader, ureg_writemask(addr[0], wm_start), ureg_scalar(start, sw_start)); - ureg_MOV(shader, ureg_writemask(addr[0], wm_tc), ureg_scalar(tc, sw_tc)); - - ureg_ADD(shader, ureg_writemask(addr[1], wm_start), ureg_scalar(start, sw_start), ureg_imm1f(shader, 1.0f / size)); - ureg_MOV(shader, ureg_writemask(addr[1], wm_tc), ureg_scalar(tc, sw_tc)); -} - -static void -increment_addr(struct ureg_program *shader, struct ureg_dst daddr[2], - struct ureg_src saddr[2], bool right_side, bool transposed, - int pos, float size) -{ - unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y; - unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X; - - /* - * daddr[0..1].(start) = saddr[0..1].(start) - * daddr[0..1].(tc) = saddr[0..1].(tc) - */ - - ureg_MOV(shader, ureg_writemask(daddr[0], wm_start), saddr[0]); - ureg_ADD(shader, ureg_writemask(daddr[0], wm_tc), saddr[0], ureg_imm1f(shader, pos / size)); - ureg_MOV(shader, ureg_writemask(daddr[1], wm_start), saddr[1]); - ureg_ADD(shader, ureg_writemask(daddr[1], wm_tc), saddr[1], ureg_imm1f(shader, pos / size)); -} - -static void -fetch_four(struct ureg_program *shader, struct ureg_dst m[2], struct ureg_src addr[2], - struct ureg_src sampler, bool resource3d) -{ - ureg_TEX(shader, m[0], resource3d ? TGSI_TEXTURE_3D : TGSI_TEXTURE_2D, addr[0], sampler); - ureg_TEX(shader, m[1], resource3d ? TGSI_TEXTURE_3D : TGSI_TEXTURE_2D, addr[1], sampler); -} - -static void -matrix_mul(struct ureg_program *shader, struct ureg_dst dst, struct ureg_dst l[2], struct ureg_dst r[2]) -{ - struct ureg_dst tmp; - - tmp = ureg_DECL_temporary(shader); - - /* - * tmp.xy = dot4(m[0][0..1], m[1][0..1]) - * dst = tmp.x + tmp.y - */ - ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_src(l[0]), ureg_src(r[0])); - ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(l[1]), ureg_src(r[1])); - ureg_ADD(shader, dst, - ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), - ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y)); - - ureg_release_temporary(shader, tmp); -} - -static void * -create_mismatch_vert_shader(struct vl_idct *idct) -{ - struct ureg_program *shader; - struct ureg_src vpos; - struct ureg_src scale; - struct ureg_dst t_tex; - struct ureg_dst o_vpos, o_addr[2]; - - shader = ureg_create(MESA_SHADER_VERTEX); - if (!shader) - return NULL; - - vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); - - t_tex = ureg_DECL_temporary(shader); - - o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); - - o_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0); - o_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1); - - /* - * scale = (VL_BLOCK_WIDTH, VL_BLOCK_HEIGHT) / (dst.width, dst.height) - * - * t_vpos = vpos + 7 / VL_BLOCK_WIDTH - * o_vpos.xy = t_vpos * scale - * - * o_addr = calc_addr(...) - * - */ - - scale = ureg_imm2f(shader, - (float)VL_BLOCK_WIDTH / idct->buffer_width, - (float)VL_BLOCK_HEIGHT / idct->buffer_height); - - ureg_MAD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), vpos, scale, scale); - ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); - - ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), vpos, scale); - calc_addr(shader, o_addr, ureg_src(t_tex), ureg_src(t_tex), false, false, idct->buffer_width / 4); - - ureg_release_temporary(shader, t_tex); - - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, idct->pipe); -} - -static void * -create_mismatch_frag_shader(struct vl_idct *idct) -{ - struct ureg_program *shader; - - struct ureg_src addr[2]; - - struct ureg_dst m[8][2]; - struct ureg_dst fragment; - - unsigned i; - - shader = ureg_create(MESA_SHADER_FRAGMENT); - if (!shader) - return NULL; - - addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR); - addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR); - - fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); - - for (i = 0; i < 8; ++i) { - m[i][0] = ureg_DECL_temporary(shader); - m[i][1] = ureg_DECL_temporary(shader); - } - - for (i = 0; i < 8; ++i) { - increment_addr(shader, m[i], addr, false, false, i, idct->buffer_height); - } - - for (i = 0; i < 8; ++i) { - struct ureg_src s_address[2]; - s_address[0] = ureg_src(m[i][0]); - s_address[1] = ureg_src(m[i][1]); - fetch_four(shader, m[i], s_address, ureg_DECL_sampler(shader, 0), false); - } - - for (i = 1; i < 8; ++i) { - ureg_ADD(shader, m[0][0], ureg_src(m[0][0]), ureg_src(m[i][0])); - ureg_ADD(shader, m[0][1], ureg_src(m[0][1]), ureg_src(m[i][1])); - } - - ureg_ADD(shader, m[0][0], ureg_src(m[0][0]), ureg_src(m[0][1])); - ureg_DP4(shader, m[0][0], ureg_abs(ureg_src(m[0][0])), ureg_imm1f(shader, 1 << 14)); - - ureg_MUL(shader, ureg_writemask(m[0][0], TGSI_WRITEMASK_W), ureg_abs(ureg_src(m[7][1])), ureg_imm1f(shader, 1 << 14)); - ureg_FRC(shader, m[0][0], ureg_src(m[0][0])); - ureg_SGT(shader, m[0][0], ureg_imm1f(shader, 0.5f), ureg_abs(ureg_src(m[0][0]))); - - ureg_CMP(shader, ureg_writemask(m[0][0], TGSI_WRITEMASK_W), ureg_negate(ureg_src(m[0][0])), - ureg_imm1f(shader, 1.0f / (1 << 15)), ureg_imm1f(shader, -1.0f / (1 << 15))); - ureg_MUL(shader, ureg_writemask(m[0][0], TGSI_WRITEMASK_W), ureg_src(m[0][0]), - ureg_scalar(ureg_src(m[0][0]), TGSI_SWIZZLE_X)); - - ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(m[7][1])); - ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(m[0][0]), ureg_src(m[7][1])); - - for (i = 0; i < 8; ++i) { - ureg_release_temporary(shader, m[i][0]); - ureg_release_temporary(shader, m[i][1]); - } - - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, idct->pipe); -} - -static void * -create_stage1_vert_shader(struct vl_idct *idct) -{ - struct ureg_program *shader; - struct ureg_src vrect, vpos; - struct ureg_src scale; - struct ureg_dst t_tex, t_start; - struct ureg_dst o_vpos, o_l_addr[2], o_r_addr[2]; - - shader = ureg_create(MESA_SHADER_VERTEX); - if (!shader) - return NULL; - - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); - vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); - - t_tex = ureg_DECL_temporary(shader); - t_start = ureg_DECL_temporary(shader); - - o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); - - o_l_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0); - o_l_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1); - - o_r_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0); - o_r_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1); - - /* - * scale = (VL_BLOCK_WIDTH, VL_BLOCK_HEIGHT) / (dst.width, dst.height) - * - * t_vpos = vpos + vrect - * o_vpos.xy = t_vpos * scale - * o_vpos.zw = vpos - * - * o_l_addr = calc_addr(...) - * o_r_addr = calc_addr(...) - * - */ - - scale = ureg_imm2f(shader, - (float)VL_BLOCK_WIDTH / idct->buffer_width, - (float)VL_BLOCK_HEIGHT / idct->buffer_height); - - ureg_ADD(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), vpos, vrect); - ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), ureg_src(t_tex), scale); - - ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_tex)); - ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); - - ureg_MUL(shader, ureg_writemask(t_start, TGSI_WRITEMASK_XY), vpos, scale); - - calc_addr(shader, o_l_addr, ureg_src(t_tex), ureg_src(t_start), false, false, idct->buffer_width / 4); - calc_addr(shader, o_r_addr, vrect, ureg_imm1f(shader, 0.0f), true, true, VL_BLOCK_WIDTH / 4); - - ureg_release_temporary(shader, t_tex); - ureg_release_temporary(shader, t_start); - - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, idct->pipe); -} - -static void * -create_stage1_frag_shader(struct vl_idct *idct) -{ - struct ureg_program *shader; - struct ureg_src l_addr[2], r_addr[2]; - struct ureg_dst l[4][2], r[2]; - struct ureg_dst *fragment; - unsigned i; - int j; - - shader = ureg_create(MESA_SHADER_FRAGMENT); - if (!shader) - return NULL; - - fragment = MALLOC(idct->nr_of_render_targets * sizeof(struct ureg_dst)); - - l_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR); - l_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR); - - r_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0, TGSI_INTERPOLATE_LINEAR); - r_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1, TGSI_INTERPOLATE_LINEAR); - - for (i = 0; i < idct->nr_of_render_targets; ++i) - fragment[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, i); - - for (i = 0; i < 4; ++i) { - l[i][0] = ureg_DECL_temporary(shader); - l[i][1] = ureg_DECL_temporary(shader); - } - - r[0] = ureg_DECL_temporary(shader); - r[1] = ureg_DECL_temporary(shader); - - for (i = 0; i < 4; ++i) { - increment_addr(shader, l[i], l_addr, false, false, i - 2, idct->buffer_height); - } - - for (i = 0; i < 4; ++i) { - struct ureg_src s_address[2]; - s_address[0] = ureg_src(l[i][0]); - s_address[1] = ureg_src(l[i][1]); - fetch_four(shader, l[i], s_address, ureg_DECL_sampler(shader, 0), false); - } - - for (i = 0; i < idct->nr_of_render_targets; ++i) { - struct ureg_src s_address[2]; - - increment_addr(shader, r, r_addr, true, true, i - (signed)idct->nr_of_render_targets / 2, VL_BLOCK_HEIGHT); - - s_address[0] = ureg_src(r[0]); - s_address[1] = ureg_src(r[1]); - fetch_four(shader, r, s_address, ureg_DECL_sampler(shader, 1), false); - - for (j = 0; j < 4; ++j) { - matrix_mul(shader, ureg_writemask(fragment[i], TGSI_WRITEMASK_X << j), l[j], r); - } - } - - for (i = 0; i < 4; ++i) { - ureg_release_temporary(shader, l[i][0]); - ureg_release_temporary(shader, l[i][1]); - } - ureg_release_temporary(shader, r[0]); - ureg_release_temporary(shader, r[1]); - - ureg_END(shader); - - FREE(fragment); - - return ureg_create_shader_and_destroy(shader, idct->pipe); -} - -void -vl_idct_stage2_vert_shader(struct vl_idct *idct, struct ureg_program *shader, - unsigned first_output, struct ureg_dst tex) -{ - struct ureg_src vrect, vpos; - struct ureg_src scale; - struct ureg_dst t_start; - struct ureg_dst o_l_addr[2], o_r_addr[2]; - - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); - vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); - - t_start = ureg_DECL_temporary(shader); - - --first_output; - - o_l_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_L_ADDR0); - o_l_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_L_ADDR1); - - o_r_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_R_ADDR0); - o_r_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_R_ADDR1); - - scale = ureg_imm2f(shader, - (float)VL_BLOCK_WIDTH / idct->buffer_width, - (float)VL_BLOCK_HEIGHT / idct->buffer_height); - - ureg_MUL(shader, ureg_writemask(tex, TGSI_WRITEMASK_Z), - ureg_scalar(vrect, TGSI_SWIZZLE_X), - ureg_imm1f(shader, VL_BLOCK_WIDTH / idct->nr_of_render_targets)); - ureg_MUL(shader, ureg_writemask(t_start, TGSI_WRITEMASK_XY), vpos, scale); - - calc_addr(shader, o_l_addr, vrect, ureg_imm1f(shader, 0.0f), false, false, VL_BLOCK_WIDTH / 4); - calc_addr(shader, o_r_addr, ureg_src(tex), ureg_src(t_start), true, false, idct->buffer_height / 4); - - ureg_MOV(shader, ureg_writemask(o_r_addr[0], TGSI_WRITEMASK_Z), ureg_src(tex)); - ureg_MOV(shader, ureg_writemask(o_r_addr[1], TGSI_WRITEMASK_Z), ureg_src(tex)); -} - -void -vl_idct_stage2_frag_shader(struct vl_idct *idct, struct ureg_program *shader, - unsigned first_input, struct ureg_dst fragment) -{ - struct ureg_src l_addr[2], r_addr[2]; - - struct ureg_dst l[2], r[2]; - - --first_input; - - l_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input + VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR); - l_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input + VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR); - - r_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input + VS_O_R_ADDR0, TGSI_INTERPOLATE_LINEAR); - r_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input + VS_O_R_ADDR1, TGSI_INTERPOLATE_LINEAR); - - l[0] = ureg_DECL_temporary(shader); - l[1] = ureg_DECL_temporary(shader); - r[0] = ureg_DECL_temporary(shader); - r[1] = ureg_DECL_temporary(shader); - - fetch_four(shader, l, l_addr, ureg_DECL_sampler(shader, 1), false); - fetch_four(shader, r, r_addr, ureg_DECL_sampler(shader, 0), true); - - matrix_mul(shader, fragment, l, r); - - ureg_release_temporary(shader, l[0]); - ureg_release_temporary(shader, l[1]); - ureg_release_temporary(shader, r[0]); - ureg_release_temporary(shader, r[1]); -} - -static bool -init_shaders(struct vl_idct *idct) -{ - idct->vs_mismatch = create_mismatch_vert_shader(idct); - if (!idct->vs_mismatch) - goto error_vs_mismatch; - - idct->fs_mismatch = create_mismatch_frag_shader(idct); - if (!idct->fs_mismatch) - goto error_fs_mismatch; - - idct->vs = create_stage1_vert_shader(idct); - if (!idct->vs) - goto error_vs; - - idct->fs = create_stage1_frag_shader(idct); - if (!idct->fs) - goto error_fs; - - return true; - -error_fs: - idct->pipe->delete_vs_state(idct->pipe, idct->vs); - -error_vs: - idct->pipe->delete_vs_state(idct->pipe, idct->vs_mismatch); - -error_fs_mismatch: - idct->pipe->delete_vs_state(idct->pipe, idct->fs); - -error_vs_mismatch: - return false; -} - -static void -cleanup_shaders(struct vl_idct *idct) -{ - idct->pipe->delete_vs_state(idct->pipe, idct->vs_mismatch); - idct->pipe->delete_fs_state(idct->pipe, idct->fs_mismatch); - idct->pipe->delete_vs_state(idct->pipe, idct->vs); - idct->pipe->delete_fs_state(idct->pipe, idct->fs); -} - -static bool -init_state(struct vl_idct *idct) -{ - struct pipe_blend_state blend; - struct pipe_rasterizer_state rs_state; - struct pipe_sampler_state sampler; - unsigned i; - - assert(idct); - - memset(&rs_state, 0, sizeof(rs_state)); - rs_state.point_size = 1; - rs_state.half_pixel_center = true; - rs_state.bottom_edge_rule = true; - rs_state.depth_clip_near = 1; - rs_state.depth_clip_far = 1; - - idct->rs_state = idct->pipe->create_rasterizer_state(idct->pipe, &rs_state); - if (!idct->rs_state) - goto error_rs_state; - - memset(&blend, 0, sizeof blend); - - blend.independent_blend_enable = 0; - blend.rt[0].blend_enable = 0; - 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_enable = 0; - blend.logicop_func = PIPE_LOGICOP_CLEAR; - /* Needed to allow color writes to FB, even if blending disabled */ - blend.rt[0].colormask = PIPE_MASK_RGBA; - blend.dither = 0; - idct->blend = idct->pipe->create_blend_state(idct->pipe, &blend); - if (!idct->blend) - goto error_blend; - - for (i = 0; i < 2; ++i) { - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; - sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; - sampler.wrap_r = PIPE_TEX_WRAP_REPEAT; - 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; - idct->samplers[i] = idct->pipe->create_sampler_state(idct->pipe, &sampler); - if (!idct->samplers[i]) - goto error_samplers; - } - - return true; - -error_samplers: - for (i = 0; i < 2; ++i) - if (idct->samplers[i]) - idct->pipe->delete_sampler_state(idct->pipe, idct->samplers[i]); - - idct->pipe->delete_rasterizer_state(idct->pipe, idct->rs_state); - -error_blend: - idct->pipe->delete_blend_state(idct->pipe, idct->blend); - -error_rs_state: - return false; -} - -static void -cleanup_state(struct vl_idct *idct) -{ - unsigned i; - - for (i = 0; i < 2; ++i) - idct->pipe->delete_sampler_state(idct->pipe, idct->samplers[i]); - - idct->pipe->delete_rasterizer_state(idct->pipe, idct->rs_state); - idct->pipe->delete_blend_state(idct->pipe, idct->blend); -} - -static bool -init_source(struct vl_idct *idct, struct vl_idct_buffer *buffer) -{ - struct pipe_resource *tex; - struct pipe_surface surf_templ; - - assert(idct && buffer); - - tex = buffer->sampler_views.individual.source->texture; - - buffer->fb_state_mismatch.width = tex->width0; - buffer->fb_state_mismatch.height = tex->height0; - buffer->fb_state_mismatch.nr_cbufs = 1; - - memset(&surf_templ, 0, sizeof(surf_templ)); - surf_templ.texture = tex; - surf_templ.format = tex->format; - surf_templ.first_layer = 0; - surf_templ.last_layer = 0; - buffer->fb_state_mismatch.cbufs[0] = surf_templ; - - buffer->viewport_mismatch.scale[0] = tex->width0; - buffer->viewport_mismatch.scale[1] = tex->height0; - buffer->viewport_mismatch.scale[2] = 1; - buffer->viewport_mismatch.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; - buffer->viewport_mismatch.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; - buffer->viewport_mismatch.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; - buffer->viewport_mismatch.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; - - return true; -} - -static void -cleanup_source(struct vl_idct_buffer *buffer) -{ - assert(buffer); - - memset(&buffer->fb_state_mismatch.cbufs[0], 0, sizeof(struct pipe_surface)); - - pipe_sampler_view_reference(&buffer->sampler_views.individual.source, NULL); -} - -static bool -init_intermediate(struct vl_idct *idct, struct vl_idct_buffer *buffer) -{ - struct pipe_resource *tex; - struct pipe_surface surf_templ; - unsigned i; - - assert(idct && buffer); - - tex = buffer->sampler_views.individual.intermediate->texture; - - buffer->fb_state.width = tex->width0; - buffer->fb_state.height = tex->height0; - buffer->fb_state.nr_cbufs = idct->nr_of_render_targets; - for(i = 0; i < idct->nr_of_render_targets; ++i) { - memset(&surf_templ, 0, sizeof(surf_templ)); - surf_templ.format = tex->format; - surf_templ.texture = tex; - surf_templ.first_layer = i; - surf_templ.last_layer = i; - buffer->fb_state.cbufs[i] = surf_templ; - } - - buffer->viewport.scale[0] = tex->width0; - buffer->viewport.scale[1] = tex->height0; - buffer->viewport.scale[2] = 1; - buffer->viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; - buffer->viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; - buffer->viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; - buffer->viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; - - return true; -} - -static void -cleanup_intermediate(struct vl_idct_buffer *buffer) -{ - assert(buffer); - - memset(buffer->fb_state.cbufs, 0, sizeof(buffer->fb_state.cbufs)); - - pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, NULL); -} - -struct pipe_sampler_view * -vl_idct_upload_matrix(struct pipe_context *pipe, float scale) -{ - struct pipe_resource tex_templ, *matrix; - struct pipe_sampler_view sv_templ, *sv; - struct pipe_transfer *buf_transfer; - unsigned i, j, pitch; - float *f; - - struct pipe_box rect = - { - 0, 0, 0, - VL_BLOCK_WIDTH / 4, - VL_BLOCK_HEIGHT, - 1 - }; - - assert(pipe); - - memset(&tex_templ, 0, sizeof(tex_templ)); - tex_templ.target = PIPE_TEXTURE_2D; - tex_templ.format = PIPE_FORMAT_R32G32B32A32_FLOAT; - tex_templ.last_level = 0; - tex_templ.width0 = 2; - tex_templ.height0 = 8; - tex_templ.depth0 = 1; - tex_templ.array_size = 1; - tex_templ.usage = PIPE_USAGE_IMMUTABLE; - tex_templ.bind = PIPE_BIND_SAMPLER_VIEW; - tex_templ.flags = 0; - - matrix = pipe->screen->resource_create(pipe->screen, &tex_templ); - if (!matrix) - goto error_matrix; - - f = pipe->texture_map(pipe, matrix, 0, - PIPE_MAP_WRITE | - PIPE_MAP_DISCARD_RANGE, - &rect, &buf_transfer); - if (!f) - goto error_map; - - pitch = buf_transfer->stride / sizeof(float); - - for(i = 0; i < VL_BLOCK_HEIGHT; ++i) - for(j = 0; j < VL_BLOCK_WIDTH; ++j) - // transpose and scale - f[i * pitch + j] = ((const float (*)[8])const_matrix)[j][i] * scale; - - pipe->texture_unmap(pipe, buf_transfer); - - memset(&sv_templ, 0, sizeof(sv_templ)); - u_sampler_view_default_template(&sv_templ, matrix, matrix->format); - sv = pipe->create_sampler_view(pipe, matrix, &sv_templ); - pipe_resource_reference(&matrix, NULL); - if (!sv) - goto error_map; - - return sv; - -error_map: - pipe_resource_reference(&matrix, NULL); - -error_matrix: - return NULL; -} - -bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe, - unsigned buffer_width, unsigned buffer_height, - unsigned nr_of_render_targets, - struct pipe_sampler_view *matrix, - struct pipe_sampler_view *transpose) -{ - assert(idct && pipe); - assert(matrix && transpose); - - idct->pipe = pipe; - idct->buffer_width = buffer_width; - idct->buffer_height = buffer_height; - idct->nr_of_render_targets = nr_of_render_targets; - - pipe_sampler_view_reference(&idct->matrix, matrix); - pipe_sampler_view_reference(&idct->transpose, transpose); - - if(!init_shaders(idct)) - return false; - - if(!init_state(idct)) { - cleanup_shaders(idct); - return false; - } - - return true; -} - -void -vl_idct_cleanup(struct vl_idct *idct) -{ - cleanup_shaders(idct); - cleanup_state(idct); - - pipe_sampler_view_reference(&idct->matrix, NULL); - pipe_sampler_view_reference(&idct->transpose, NULL); -} - -bool -vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer, - struct pipe_sampler_view *source, - struct pipe_sampler_view *intermediate) -{ - assert(buffer && idct); - assert(source && intermediate); - - memset(buffer, 0, sizeof(struct vl_idct_buffer)); - - pipe_sampler_view_reference(&buffer->sampler_views.individual.matrix, idct->matrix); - pipe_sampler_view_reference(&buffer->sampler_views.individual.source, source); - pipe_sampler_view_reference(&buffer->sampler_views.individual.transpose, idct->transpose); - pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, intermediate); - - if (!init_source(idct, buffer)) - return false; - - if (!init_intermediate(idct, buffer)) - return false; - - return true; -} - -void -vl_idct_cleanup_buffer(struct vl_idct_buffer *buffer) -{ - assert(buffer); - - cleanup_source(buffer); - cleanup_intermediate(buffer); - - pipe_sampler_view_reference(&buffer->sampler_views.individual.matrix, NULL); - pipe_sampler_view_reference(&buffer->sampler_views.individual.transpose, NULL); -} - -void -vl_idct_flush(struct vl_idct *idct, struct vl_idct_buffer *buffer, unsigned num_instances) -{ - assert(buffer); - - idct->pipe->bind_rasterizer_state(idct->pipe, idct->rs_state); - idct->pipe->bind_blend_state(idct->pipe, idct->blend); - - idct->pipe->bind_sampler_states(idct->pipe, MESA_SHADER_FRAGMENT, - 0, 2, idct->samplers); - - idct->pipe->set_sampler_views(idct->pipe, MESA_SHADER_FRAGMENT, 0, 2, 0, - buffer->sampler_views.stage[0]); - - /* mismatch control */ - idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state_mismatch); - idct->pipe->set_viewport_states(idct->pipe, 0, 1, &buffer->viewport_mismatch); - idct->pipe->bind_vs_state(idct->pipe, idct->vs_mismatch); - idct->pipe->bind_fs_state(idct->pipe, idct->fs_mismatch); - util_draw_arrays_instanced(idct->pipe, MESA_PRIM_POINTS, 0, 1, 0, num_instances); - - /* first stage */ - idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state); - idct->pipe->set_viewport_states(idct->pipe, 0, 1, &buffer->viewport); - idct->pipe->bind_vs_state(idct->pipe, idct->vs); - idct->pipe->bind_fs_state(idct->pipe, idct->fs); - util_draw_arrays_instanced(idct->pipe, MESA_PRIM_QUADS, 0, 4, 0, num_instances); -} - -void -vl_idct_prepare_stage2(struct vl_idct *idct, struct vl_idct_buffer *buffer) -{ - assert(buffer); - - /* second stage */ - idct->pipe->bind_rasterizer_state(idct->pipe, idct->rs_state); - idct->pipe->bind_sampler_states(idct->pipe, MESA_SHADER_FRAGMENT, - 0, 2, idct->samplers); - idct->pipe->set_sampler_views(idct->pipe, MESA_SHADER_FRAGMENT, - 0, 2, 0, buffer->sampler_views.stage[1]); -} diff --git a/src/gallium/auxiliary/vl/vl_idct.h b/src/gallium/auxiliary/vl/vl_idct.h deleted file mode 100644 index 04ce567f259..00000000000 --- a/src/gallium/auxiliary/vl/vl_idct.h +++ /dev/null @@ -1,119 +0,0 @@ -/************************************************************************** - * - * Copyright 2010 Christian König - * 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. - * - **************************************************************************/ - -#ifndef vl_idct_h -#define vl_idct_h - -#include "pipe/p_state.h" - -#include "tgsi/tgsi_ureg.h" - -/* shader based inverse distinct cosinus transformation - * expect usage of vl_vertex_buffers as a todo list - */ -struct vl_idct -{ - struct pipe_context *pipe; - - unsigned buffer_width; - unsigned buffer_height; - unsigned nr_of_render_targets; - - void *rs_state; - void *blend; - - void *samplers[2]; - - void *vs_mismatch, *fs_mismatch; - void *vs, *fs; - - struct pipe_sampler_view *matrix; - struct pipe_sampler_view *transpose; -}; - -/* a set of buffers to work with */ -struct vl_idct_buffer -{ - struct pipe_viewport_state viewport_mismatch; - struct pipe_viewport_state viewport; - - struct pipe_framebuffer_state fb_state_mismatch; - struct pipe_framebuffer_state fb_state; - - union - { - struct pipe_sampler_view *all[4]; - struct pipe_sampler_view *stage[2][2]; - struct { - struct pipe_sampler_view *source, *matrix; - struct pipe_sampler_view *intermediate, *transpose; - } individual; - } sampler_views; -}; - -/* upload the idct matrix, which can be shared by all idct instances of a pipe */ -struct pipe_sampler_view * -vl_idct_upload_matrix(struct pipe_context *pipe, float scale); - -void -vl_idct_stage2_vert_shader(struct vl_idct *idct, struct ureg_program *shader, - unsigned first_output, struct ureg_dst tex); - -void -vl_idct_stage2_frag_shader(struct vl_idct *idct, struct ureg_program *shader, - unsigned first_input, struct ureg_dst fragment); - -/* init an idct instance */ -bool -vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe, - unsigned buffer_width, unsigned buffer_height, - unsigned nr_of_render_targets, - struct pipe_sampler_view *matrix, - struct pipe_sampler_view *transpose); - -/* destroy an idct instance */ -void -vl_idct_cleanup(struct vl_idct *idct); - -/* init a buffer assosiated with agiven idct instance */ -bool -vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer, - struct pipe_sampler_view *source, - struct pipe_sampler_view *intermediate); - -/* cleanup a buffer of an idct instance */ -void -vl_idct_cleanup_buffer(struct vl_idct_buffer *buffer); - -/* flush the buffer and start rendering, vertex buffers needs to be setup before calling this */ -void -vl_idct_flush(struct vl_idct *idct, struct vl_idct_buffer *buffer, unsigned num_verts); - -void -vl_idct_prepare_stage2(struct vl_idct *idct, struct vl_idct_buffer *buffer); - -#endif diff --git a/src/gallium/auxiliary/vl/vl_mc.c b/src/gallium/auxiliary/vl/vl_mc.c deleted file mode 100644 index 9272186ec86..00000000000 --- a/src/gallium/auxiliary/vl/vl_mc.c +++ /dev/null @@ -1,657 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * 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 - -#include "pipe/p_context.h" - -#include "util/u_sampler.h" -#include "util/u_draw.h" - -#include "tgsi/tgsi_ureg.h" - -#include "vl_defines.h" -#include "vl_vertex_buffers.h" -#include "vl_mc.h" -#include "vl_idct.h" - -enum VS_OUTPUT -{ - VS_O_VPOS = 0, - VS_O_VTOP = 0, - VS_O_VBOTTOM, - - VS_O_FLAGS = VS_O_VTOP, - VS_O_VTEX = VS_O_VBOTTOM -}; - -static struct ureg_dst -calc_position(struct vl_mc *r, struct ureg_program *shader, struct ureg_src block_scale) -{ - struct ureg_src vrect, vpos; - struct ureg_dst t_vpos; - struct ureg_dst o_vpos; - - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); - vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); - - t_vpos = ureg_DECL_temporary(shader); - - o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); - - /* - * block_scale = (VL_MACROBLOCK_WIDTH, VL_MACROBLOCK_HEIGHT) / (dst.width, dst.height) - * - * t_vpos = (vpos + vrect) * block_scale - * o_vpos.xy = t_vpos - * o_vpos.zw = vpos - */ - ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect); - ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale); - ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos)); - ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); - - return t_vpos; -} - -static struct ureg_dst -calc_line(struct pipe_screen *screen, struct ureg_program *shader) -{ - struct ureg_dst tmp; - struct ureg_src pos; - - tmp = ureg_DECL_temporary(shader); - - if (screen->caps.fs_position_is_sysval) - pos = ureg_DECL_system_value(shader, TGSI_SEMANTIC_POSITION, 0); - else - pos = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS, - TGSI_INTERPOLATE_LINEAR); - - /* - * tmp.y = fraction(pos.y / 2) >= 0.5 ? 1 : 0 - */ - ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), pos, ureg_imm1f(shader, 0.5f)); - ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp)); - ureg_SGE(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp), ureg_imm1f(shader, 0.5f)); - - return tmp; -} - -static void * -create_ref_vert_shader(struct vl_mc *r) -{ - struct ureg_program *shader; - struct ureg_src mv_scale; - struct ureg_src vmv[2]; - struct ureg_dst t_vpos; - struct ureg_dst o_vmv[2]; - unsigned i; - - shader = ureg_create(MESA_SHADER_VERTEX); - if (!shader) - return NULL; - - vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP); - vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM); - - t_vpos = calc_position(r, shader, ureg_imm2f(shader, - (float)VL_MACROBLOCK_WIDTH / r->buffer_width, - (float)VL_MACROBLOCK_HEIGHT / r->buffer_height) - ); - - o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); - o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); - - /* - * mv_scale.xy = 0.5 / (dst.width, dst.height); - * mv_scale.z = 1.0f / 4.0f - * mv_scale.w = 1.0f / 255.0f - * - * // Apply motion vectors - * o_vmv[0..1].xy = vmv[0..1] * mv_scale + t_vpos - * o_vmv[0..1].zw = vmv[0..1] * mv_scale - * - */ - - mv_scale = ureg_imm4f(shader, - 0.5f / r->buffer_width, - 0.5f / r->buffer_height, - 1.0f / 4.0f, - 1.0f / PIPE_VIDEO_MV_WEIGHT_MAX); - - for (i = 0; i < 2; ++i) { - ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos)); - ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_ZW), mv_scale, vmv[i]); - } - - ureg_release_temporary(shader, t_vpos); - - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, r->pipe); -} - -static void * -create_ref_frag_shader(struct vl_mc *r) -{ - const float y_scale = - r->buffer_height / 2 * - r->macroblock_size / VL_MACROBLOCK_HEIGHT; - - struct ureg_program *shader; - struct ureg_src tc[2], sampler; - struct ureg_dst ref, field; - struct ureg_dst fragment; - unsigned label; - - shader = ureg_create(MESA_SHADER_FRAGMENT); - if (!shader) - return NULL; - - tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); - tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); - - sampler = ureg_DECL_sampler(shader, 0); - ref = ureg_DECL_temporary(shader); - - fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); - - field = calc_line(r->pipe->screen, shader); - - /* - * ref = field.z ? tc[1] : tc[0] - * - * // Adjust tc acording to top/bottom field selection - * if (|ref.z|) { - * ref.y *= y_scale - * ref.y = floor(ref.y) - * ref.y += ref.z - * ref.y /= y_scale - * } - * fragment.xyz = tex(ref, sampler[0]) - */ - ureg_CMP(shader, ureg_writemask(ref, TGSI_WRITEMASK_XYZ), - ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), - tc[1], tc[0]); - ureg_CMP(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), - ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), - tc[1], tc[0]); - - ureg_IF(shader, ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z), &label); - - ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), - ureg_src(ref), ureg_imm1f(shader, y_scale)); - ureg_FLR(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref)); - ureg_ADD(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), - ureg_src(ref), ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z)); - ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), - ureg_src(ref), ureg_imm1f(shader, 1.0f / y_scale)); - - ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); - ureg_ENDIF(shader); - - ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler); - - ureg_release_temporary(shader, ref); - - ureg_release_temporary(shader, field); - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, r->pipe); -} - -static void * -create_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, void *callback_priv) -{ - struct ureg_program *shader; - - struct ureg_src vrect, vpos; - struct ureg_dst t_vpos, t_vtex; - struct ureg_dst o_vpos, o_flags; - - struct vertex2f scale = { - (float)VL_BLOCK_WIDTH / r->buffer_width * VL_MACROBLOCK_WIDTH / r->macroblock_size, - (float)VL_BLOCK_HEIGHT / r->buffer_height * VL_MACROBLOCK_HEIGHT / r->macroblock_size - }; - - unsigned label; - - shader = ureg_create(MESA_SHADER_VERTEX); - if (!shader) - return NULL; - - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); - vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); - - t_vpos = calc_position(r, shader, ureg_imm2f(shader, scale.x, scale.y)); - t_vtex = ureg_DECL_temporary(shader); - - o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); - o_flags = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS); - - /* - * o_vtex.xy = t_vpos - * o_flags.z = intra * 0.5 - * - * if(interlaced) { - * t_vtex.xy = vrect.y ? { 0, scale.y } : { -scale.y : 0 } - * t_vtex.z = vpos.y % 2 - * t_vtex.y = t_vtex.z ? t_vtex.x : t_vtex.y - * o_vpos.y = t_vtex.y + t_vpos.y - * - * o_flags.w = t_vtex.z ? 0 : 1 - * } - * - */ - - vs_callback(callback_priv, r, shader, VS_O_VTEX, t_vpos); - - ureg_MUL(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_Z), - ureg_scalar(vpos, TGSI_SWIZZLE_Z), ureg_imm1f(shader, 0.5f)); - ureg_MOV(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), ureg_imm1f(shader, -1.0f)); - - if (r->macroblock_size == VL_MACROBLOCK_HEIGHT) { //TODO - ureg_IF(shader, ureg_scalar(vpos, TGSI_SWIZZLE_W), &label); - - ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY), - ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_Y)), - ureg_imm2f(shader, 0.0f, scale.y), - ureg_imm2f(shader, -scale.y, 0.0f)); - ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z), - ureg_scalar(vpos, TGSI_SWIZZLE_Y), ureg_imm1f(shader, 0.5f)); - - ureg_FRC(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z), ureg_src(t_vtex)); - - ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), - ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)), - ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_X), - ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Y)); - ureg_ADD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_Y), - ureg_src(t_vpos), ureg_src(t_vtex)); - - ureg_CMP(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), - ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)), - ureg_imm1f(shader, 0.0f), ureg_imm1f(shader, 1.0f)); - - ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); - ureg_ENDIF(shader); - } - - ureg_release_temporary(shader, t_vtex); - ureg_release_temporary(shader, t_vpos); - - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, r->pipe); -} - -static void * -create_ycbcr_frag_shader(struct vl_mc *r, float scale, bool invert, - vl_mc_ycbcr_frag_shader fs_callback, void *callback_priv) -{ - struct ureg_program *shader; - struct ureg_src flags; - struct ureg_dst tmp; - struct ureg_dst fragment; - unsigned label; - - shader = ureg_create(MESA_SHADER_FRAGMENT); - if (!shader) - return NULL; - - flags = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS, TGSI_INTERPOLATE_LINEAR); - - fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); - - tmp = calc_line(r->pipe->screen, shader); - - /* - * if (field == tc.w) - * kill(); - * else { - * fragment.xyz = tex(tc, sampler) * scale + tc.z - * fragment.w = 1.0f - * } - */ - - ureg_SEQ(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), - ureg_scalar(flags, TGSI_SWIZZLE_W), ureg_src(tmp)); - - ureg_IF(shader, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), &label); - - ureg_KILL(shader); - - ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); - ureg_ELSE(shader, &label); - - fs_callback(callback_priv, r, shader, VS_O_VTEX, tmp); - - if (scale != 1.0f) - ureg_MAD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), - ureg_src(tmp), ureg_imm1f(shader, scale), - ureg_scalar(flags, TGSI_SWIZZLE_Z)); - else - ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), - ureg_src(tmp), ureg_scalar(flags, TGSI_SWIZZLE_Z)); - - ureg_MUL(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_imm1f(shader, invert ? -1.0f : 1.0f)); - ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); - - ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); - ureg_ENDIF(shader); - - ureg_release_temporary(shader, tmp); - - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, r->pipe); -} - -static bool -init_pipe_state(struct vl_mc *r) -{ - struct pipe_sampler_state sampler; - struct pipe_blend_state blend; - struct pipe_rasterizer_state rs_state; - unsigned i; - - assert(r); - - 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_BORDER; - sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.compare_mode = PIPE_TEX_COMPARE_NONE; - sampler.compare_func = PIPE_FUNC_ALWAYS; - r->sampler_ref = r->pipe->create_sampler_state(r->pipe, &sampler); - if (!r->sampler_ref) - goto error_sampler_ref; - - for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { - memset(&blend, 0, sizeof blend); - blend.independent_blend_enable = 0; - blend.rt[0].blend_enable = 1; - blend.rt[0].rgb_func = PIPE_BLEND_ADD; - blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.rt[0].alpha_func = PIPE_BLEND_ADD; - blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.logicop_enable = 0; - blend.logicop_func = PIPE_LOGICOP_CLEAR; - blend.rt[0].colormask = i; - blend.dither = 0; - r->blend_clear[i] = r->pipe->create_blend_state(r->pipe, &blend); - if (!r->blend_clear[i]) - goto error_blend; - - blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - r->blend_add[i] = r->pipe->create_blend_state(r->pipe, &blend); - if (!r->blend_add[i]) - goto error_blend; - - blend.rt[0].rgb_func = PIPE_BLEND_REVERSE_SUBTRACT; - blend.rt[0].alpha_dst_factor = PIPE_BLEND_REVERSE_SUBTRACT; - r->blend_sub[i] = r->pipe->create_blend_state(r->pipe, &blend); - if (!r->blend_sub[i]) - goto error_blend; - } - - memset(&rs_state, 0, sizeof(rs_state)); - /*rs_state.sprite_coord_enable */ - rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; - rs_state.point_quad_rasterization = true; - rs_state.point_size = VL_BLOCK_WIDTH; - rs_state.half_pixel_center = true; - rs_state.bottom_edge_rule = true; - rs_state.depth_clip_near = 1; - rs_state.depth_clip_far = 1; - - r->rs_state = r->pipe->create_rasterizer_state(r->pipe, &rs_state); - if (!r->rs_state) - goto error_rs_state; - - return true; - -error_rs_state: -error_blend: - for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { - if (r->blend_sub[i]) - r->pipe->delete_blend_state(r->pipe, r->blend_sub[i]); - - if (r->blend_add[i]) - r->pipe->delete_blend_state(r->pipe, r->blend_add[i]); - - if (r->blend_clear[i]) - r->pipe->delete_blend_state(r->pipe, r->blend_clear[i]); - } - - r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); - -error_sampler_ref: - return false; -} - -static void -cleanup_pipe_state(struct vl_mc *r) -{ - unsigned i; - - assert(r); - - r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); - for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { - r->pipe->delete_blend_state(r->pipe, r->blend_clear[i]); - r->pipe->delete_blend_state(r->pipe, r->blend_add[i]); - r->pipe->delete_blend_state(r->pipe, r->blend_sub[i]); - } - r->pipe->delete_rasterizer_state(r->pipe, r->rs_state); -} - -bool -vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, - unsigned buffer_width, unsigned buffer_height, - unsigned macroblock_size, float scale, - vl_mc_ycbcr_vert_shader vs_callback, - vl_mc_ycbcr_frag_shader fs_callback, - void *callback_priv) -{ - assert(renderer); - assert(pipe); - - memset(renderer, 0, sizeof(struct vl_mc)); - - renderer->pipe = pipe; - renderer->buffer_width = buffer_width; - renderer->buffer_height = buffer_height; - renderer->macroblock_size = macroblock_size; - - if (!init_pipe_state(renderer)) - goto error_pipe_state; - - renderer->vs_ref = create_ref_vert_shader(renderer); - if (!renderer->vs_ref) - goto error_vs_ref; - - renderer->vs_ycbcr = create_ycbcr_vert_shader(renderer, vs_callback, callback_priv); - if (!renderer->vs_ycbcr) - goto error_vs_ycbcr; - - renderer->fs_ref = create_ref_frag_shader(renderer); - if (!renderer->fs_ref) - goto error_fs_ref; - - renderer->fs_ycbcr = create_ycbcr_frag_shader(renderer, scale, false, fs_callback, callback_priv); - if (!renderer->fs_ycbcr) - goto error_fs_ycbcr; - - renderer->fs_ycbcr_sub = create_ycbcr_frag_shader(renderer, scale, true, fs_callback, callback_priv); - if (!renderer->fs_ycbcr_sub) - goto error_fs_ycbcr_sub; - - return true; - -error_fs_ycbcr_sub: - renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); - -error_fs_ycbcr: - renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); - -error_fs_ref: - renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); - -error_vs_ycbcr: - renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); - -error_vs_ref: - cleanup_pipe_state(renderer); - -error_pipe_state: - return false; -} - -void -vl_mc_cleanup(struct vl_mc *renderer) -{ - assert(renderer); - - cleanup_pipe_state(renderer); - - renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); - renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); - renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); - renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); - renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr_sub); -} - -bool -vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer) -{ - assert(renderer && buffer); - - buffer->viewport.scale[2] = 1; - buffer->viewport.translate[0] = 0; - buffer->viewport.translate[1] = 0; - buffer->viewport.translate[2] = 0; - buffer->viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; - buffer->viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; - buffer->viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; - buffer->viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; - - buffer->fb_state.nr_cbufs = 1; - memset(&buffer->fb_state.zsbuf, 0, sizeof(buffer->fb_state.zsbuf)); - - return true; -} - -void -vl_mc_cleanup_buffer(struct vl_mc_buffer *buffer) -{ - assert(buffer); -} - -void -vl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface) -{ - assert(buffer && surface); - - buffer->surface_cleared = false; - - buffer->viewport.scale[0] = pipe_surface_width(surface); - buffer->viewport.scale[1] = pipe_surface_height(surface); - - buffer->fb_state.width = pipe_surface_width(surface); - buffer->fb_state.height = pipe_surface_height(surface); - buffer->fb_state.cbufs[0] = *surface; -} - -static void -prepare_pipe_4_rendering(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned mask) -{ - assert(buffer); - - renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state); - - if (buffer->surface_cleared) - renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add[mask]); - else - renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear[mask]); - - renderer->pipe->set_framebuffer_state(renderer->pipe, &buffer->fb_state); - renderer->pipe->set_viewport_states(renderer->pipe, 0, 1, &buffer->viewport); -} - -void -vl_mc_render_ref(struct vl_mc *renderer, struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref) -{ - assert(buffer && ref); - - prepare_pipe_4_rendering(renderer, buffer, PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B); - - renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ref); - renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref); - - renderer->pipe->set_sampler_views(renderer->pipe, MESA_SHADER_FRAGMENT, - 0, 1, 0, &ref); - renderer->pipe->bind_sampler_states(renderer->pipe, MESA_SHADER_FRAGMENT, - 0, 1, &renderer->sampler_ref); - - util_draw_arrays_instanced(renderer->pipe, MESA_PRIM_QUADS, 0, 4, 0, - renderer->buffer_width / VL_MACROBLOCK_WIDTH * - renderer->buffer_height / VL_MACROBLOCK_HEIGHT); - - buffer->surface_cleared = true; -} - -void -vl_mc_render_ycbcr(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned component, unsigned num_instances) -{ - unsigned mask = 1 << component; - - assert(buffer); - - if (num_instances == 0) - return; - - prepare_pipe_4_rendering(renderer, buffer, mask); - - renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ycbcr); - renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr); - - util_draw_arrays_instanced(renderer->pipe, MESA_PRIM_QUADS, 0, 4, 0, num_instances); - - if (buffer->surface_cleared) { - renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_sub[mask]); - renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr_sub); - util_draw_arrays_instanced(renderer->pipe, MESA_PRIM_QUADS, 0, 4, 0, num_instances); - } -} diff --git a/src/gallium/auxiliary/vl/vl_mc.h b/src/gallium/auxiliary/vl/vl_mc.h deleted file mode 100644 index ce127a6129d..00000000000 --- a/src/gallium/auxiliary/vl/vl_mc.h +++ /dev/null @@ -1,97 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * 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. - * - **************************************************************************/ - -#ifndef vl_mc_h -#define vl_mc_h - -#include "pipe/p_state.h" -#include "pipe/p_video_state.h" - -#include "tgsi/tgsi_ureg.h" - -#include "vl_defines.h" -#include "vl_types.h" - -#define VL_MC_NUM_BLENDERS (1 << VL_NUM_COMPONENTS) - -struct pipe_context; - -struct vl_mc -{ - struct pipe_context *pipe; - unsigned buffer_width; - unsigned buffer_height; - unsigned macroblock_size; - - void *rs_state; - - void *blend_clear[VL_MC_NUM_BLENDERS]; - void *blend_add[VL_MC_NUM_BLENDERS]; - void *blend_sub[VL_MC_NUM_BLENDERS]; - void *vs_ref, *vs_ycbcr; - void *fs_ref, *fs_ycbcr, *fs_ycbcr_sub; - void *sampler_ref; -}; - -struct vl_mc_buffer -{ - bool surface_cleared; - - struct pipe_viewport_state viewport; - struct pipe_framebuffer_state fb_state; -}; - -typedef void (*vl_mc_ycbcr_vert_shader)(void *priv, struct vl_mc *mc, - struct ureg_program *shader, - unsigned first_output, - struct ureg_dst tex); - -typedef void (*vl_mc_ycbcr_frag_shader)(void *priv, struct vl_mc *mc, - struct ureg_program *shader, - unsigned first_input, - struct ureg_dst dst); - -bool vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, - unsigned picture_width, unsigned picture_height, - unsigned macroblock_size, float scale, - vl_mc_ycbcr_vert_shader vs_callback, - vl_mc_ycbcr_frag_shader fs_callback, - void *callback_priv); - -void vl_mc_cleanup(struct vl_mc *renderer); - -bool vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer); - -void vl_mc_cleanup_buffer(struct vl_mc_buffer *buffer); - -void vl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface); - -void vl_mc_render_ref(struct vl_mc *renderer, struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref); - -void vl_mc_render_ycbcr(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned component, unsigned num_instances); - -#endif /* vl_mc_h */ diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c deleted file mode 100644 index f8bdf251eef..00000000000 --- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c +++ /dev/null @@ -1,1225 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * 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 -#include - -#include "util/u_memory.h" -#include "util/u_sampler.h" -#include "util/u_surface.h" -#include "util/u_video.h" - -#include "vl_mpeg12_decoder.h" -#include "vl_defines.h" - -#define SCALE_FACTOR_SNORM (32768.0f / 256.0f) -#define SCALE_FACTOR_SSCALED (1.0f / 256.0f) - -struct format_config { - enum pipe_format zscan_source_format; - enum pipe_format idct_source_format; - enum pipe_format mc_source_format; - - float idct_scale; - float mc_scale; -}; - -static const struct format_config bitstream_format_config[] = { -// { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED }, -// { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED }, - { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM }, - { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM } -}; - -static const unsigned num_bitstream_format_configs = - sizeof(bitstream_format_config) / sizeof(struct format_config); - -static const struct format_config idct_format_config[] = { -// { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED }, -// { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED }, - { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM }, - { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM } -}; - -static const unsigned num_idct_format_configs = - sizeof(idct_format_config) / sizeof(struct format_config); - -static const struct format_config mc_format_config[] = { - //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED }, - { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM } -}; - -static const unsigned num_mc_format_configs = - sizeof(mc_format_config) / sizeof(struct format_config); - -static const unsigned const_empty_block_mask_420[3][2][2] = { - { { 0x20, 0x10 }, { 0x08, 0x04 } }, - { { 0x02, 0x02 }, { 0x02, 0x02 } }, - { { 0x01, 0x01 }, { 0x01, 0x01 } } -}; - -struct video_buffer_private -{ - struct list_head list; - struct pipe_video_buffer *video_buffer; - - struct pipe_sampler_view *sampler_view_planes[VL_NUM_COMPONENTS]; - struct pipe_surface *surfaces[VL_MAX_SURFACES]; - - struct vl_mpeg12_buffer *buffer; -}; - -static void -vl_mpeg12_destroy_buffer(struct vl_mpeg12_buffer *buf); - -static void -destroy_video_buffer_private(void *private) -{ - struct video_buffer_private *priv = private; - unsigned i; - - list_del(&priv->list); - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) - pipe_sampler_view_reference(&priv->sampler_view_planes[i], NULL); - - if (priv->buffer) - vl_mpeg12_destroy_buffer(priv->buffer); - - FREE(priv); -} - -static struct video_buffer_private * -get_video_buffer_private(struct vl_mpeg12_decoder *dec, struct pipe_video_buffer *buf) -{ - struct pipe_context *pipe = dec->context; - struct video_buffer_private *priv; - struct pipe_sampler_view **sv; - struct pipe_surface *surf; - unsigned i; - - priv = vl_video_buffer_get_associated_data(buf, &dec->base); - if (priv) - return priv; - - priv = CALLOC_STRUCT(video_buffer_private); - - list_add(&priv->list, &dec->buffer_privates); - priv->video_buffer = buf; - - sv = buf->get_sampler_view_planes(buf); - for (i = 0; i < VL_NUM_COMPONENTS; ++i) - if (sv[i]) - priv->sampler_view_planes[i] = pipe->create_sampler_view(pipe, sv[i]->texture, sv[i]); - - surf = buf->get_surfaces(buf); - memcpy(priv->surfaces, surf, sizeof(priv->surfaces)); - - vl_video_buffer_set_associated_data(buf, &dec->base, priv, destroy_video_buffer_private); - - return priv; -} - -static void -free_video_buffer_privates(struct vl_mpeg12_decoder *dec) -{ - struct video_buffer_private *priv, *next; - - LIST_FOR_EACH_ENTRY_SAFE(priv, next, &dec->buffer_privates, list) { - struct pipe_video_buffer *buf = priv->video_buffer; - - vl_video_buffer_set_associated_data(buf, &dec->base, NULL, NULL); - } -} - -static bool -init_zscan_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer) -{ - struct pipe_resource *res, res_tmpl; - struct pipe_sampler_view sv_tmpl; - struct pipe_surface *destination; - - unsigned i; - - assert(dec && buffer); - - memset(&res_tmpl, 0, sizeof(res_tmpl)); - res_tmpl.target = PIPE_TEXTURE_2D; - res_tmpl.format = dec->zscan_source_format; - res_tmpl.width0 = dec->blocks_per_line * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; - res_tmpl.height0 = align(dec->num_blocks, dec->blocks_per_line) / dec->blocks_per_line; - res_tmpl.depth0 = 1; - res_tmpl.array_size = 1; - res_tmpl.usage = PIPE_USAGE_STREAM; - res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; - - res = dec->context->screen->resource_create(dec->context->screen, &res_tmpl); - if (!res) - goto error_source; - - - memset(&sv_tmpl, 0, sizeof(sv_tmpl)); - u_sampler_view_default_template(&sv_tmpl, res, res->format); - sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = PIPE_SWIZZLE_X; - buffer->zscan_source = dec->context->create_sampler_view(dec->context, res, &sv_tmpl); - pipe_resource_reference(&res, NULL); - if (!buffer->zscan_source) - goto error_sampler; - - if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) - destination = dec->idct_source->get_surfaces(dec->idct_source); - else - destination = dec->mc_source->get_surfaces(dec->mc_source); - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) - if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c, - &buffer->zscan[i], buffer->zscan_source, &destination[i])) - goto error_plane; - - return true; - -error_plane: - for (; i > 0; --i) - vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]); - -error_sampler: - pipe_sampler_view_reference(&buffer->zscan_source, NULL); - -error_source: - return false; -} - -static void -cleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer) -{ - unsigned i; - - assert(buffer); - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) - vl_zscan_cleanup_buffer(&buffer->zscan[i]); - - pipe_sampler_view_reference(&buffer->zscan_source, NULL); -} - -static bool -init_idct_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer) -{ - struct pipe_sampler_view **idct_source_sv, **mc_source_sv; - - unsigned i; - - assert(dec && buffer); - - idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source); - if (!idct_source_sv) - goto error_source_sv; - - mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); - if (!mc_source_sv) - goto error_mc_source_sv; - - for (i = 0; i < 3; ++i) - if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c, - &buffer->idct[i], idct_source_sv[i], - mc_source_sv[i])) - goto error_plane; - - return true; - -error_plane: - for (; i > 0; --i) - vl_idct_cleanup_buffer(&buffer->idct[i - 1]); - -error_mc_source_sv: -error_source_sv: - return false; -} - -static void -cleanup_idct_buffer(struct vl_mpeg12_buffer *buf) -{ - unsigned i; - - assert(buf); - - for (i = 0; i < 3; ++i) - vl_idct_cleanup_buffer(&buf->idct[i]); -} - -static bool -init_mc_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buf) -{ - assert(dec && buf); - - if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0])) - goto error_mc_y; - - if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1])) - goto error_mc_cb; - - if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2])) - goto error_mc_cr; - - return true; - -error_mc_cr: - vl_mc_cleanup_buffer(&buf->mc[1]); - -error_mc_cb: - vl_mc_cleanup_buffer(&buf->mc[0]); - -error_mc_y: - return false; -} - -static void -cleanup_mc_buffer(struct vl_mpeg12_buffer *buf) -{ - unsigned i; - - assert(buf); - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) - vl_mc_cleanup_buffer(&buf->mc[i]); -} - -static inline void -MacroBlockTypeToPipeWeights(const struct pipe_mpeg12_macroblock *mb, unsigned weights[2]) -{ - assert(mb); - - switch (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) { - case PIPE_MPEG12_MB_TYPE_MOTION_FORWARD: - weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX; - weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN; - break; - - case (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD): - weights[0] = PIPE_VIDEO_MV_WEIGHT_HALF; - weights[1] = PIPE_VIDEO_MV_WEIGHT_HALF; - break; - - case PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD: - weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN; - weights[1] = PIPE_VIDEO_MV_WEIGHT_MAX; - break; - - default: - if (mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) { - weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN; - weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN; - } else { - /* no motion vector, but also not intra mb -> - just copy the old frame content */ - weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX; - weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN; - } - break; - } -} - -static inline struct vl_motionvector -MotionVectorToPipe(const struct pipe_mpeg12_macroblock *mb, unsigned vector, - unsigned field_select_mask, unsigned weight) -{ - struct vl_motionvector mv; - - assert(mb); - - if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) { - switch (mb->macroblock_modes.bits.frame_motion_type) { - case PIPE_MPEG12_MO_TYPE_FRAME: - mv.top.x = mb->PMV[0][vector][0]; - mv.top.y = mb->PMV[0][vector][1]; - mv.top.field_select = PIPE_VIDEO_FRAME; - mv.top.weight = weight; - - mv.bottom.x = mb->PMV[0][vector][0]; - mv.bottom.y = mb->PMV[0][vector][1]; - mv.bottom.weight = weight; - mv.bottom.field_select = PIPE_VIDEO_FRAME; - break; - - case PIPE_MPEG12_MO_TYPE_FIELD: - mv.top.x = mb->PMV[0][vector][0]; - mv.top.y = mb->PMV[0][vector][1]; - mv.top.field_select = (mb->motion_vertical_field_select & field_select_mask) ? - PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD; - mv.top.weight = weight; - - mv.bottom.x = mb->PMV[1][vector][0]; - mv.bottom.y = mb->PMV[1][vector][1]; - mv.bottom.field_select = (mb->motion_vertical_field_select & (field_select_mask << 2)) ? - PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD; - mv.bottom.weight = weight; - break; - - default: - UNREACHABLE("TODO: Support DUALPRIME and 16x8"); - } - } else { - mv.top.x = mv.top.y = 0; - mv.top.field_select = PIPE_VIDEO_FRAME; - mv.top.weight = weight; - - mv.bottom.x = mv.bottom.y = 0; - mv.bottom.field_select = PIPE_VIDEO_FRAME; - mv.bottom.weight = weight; - } - return mv; -} - -static inline void -UploadYcbcrBlocks(struct vl_mpeg12_decoder *dec, - struct vl_mpeg12_buffer *buf, - const struct pipe_mpeg12_macroblock *mb) -{ - unsigned intra; - unsigned tb, x, y, num_blocks = 0; - - assert(dec && buf); - assert(mb); - - if (!mb->coded_block_pattern) - return; - - intra = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA ? 1 : 0; - - for (y = 0; y < 2; ++y) { - for (x = 0; x < 2; ++x) { - if (mb->coded_block_pattern & const_empty_block_mask_420[0][y][x]) { - - struct vl_ycbcr_block *stream = buf->ycbcr_stream[0]; - stream->x = mb->x * 2 + x; - stream->y = mb->y * 2 + y; - stream->intra = intra; - stream->coding = mb->macroblock_modes.bits.dct_type; - stream->block_num = buf->block_num++; - - buf->num_ycbcr_blocks[0]++; - buf->ycbcr_stream[0]++; - - num_blocks++; - } - } - } - - /* TODO: Implement 422, 444 */ - //assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); - - for (tb = 1; tb < 3; ++tb) { - if (mb->coded_block_pattern & const_empty_block_mask_420[tb][0][0]) { - - struct vl_ycbcr_block *stream = buf->ycbcr_stream[tb]; - stream->x = mb->x; - stream->y = mb->y; - stream->intra = intra; - stream->coding = 0; - stream->block_num = buf->block_num++; - - buf->num_ycbcr_blocks[tb]++; - buf->ycbcr_stream[tb]++; - - num_blocks++; - } - } - - memcpy(buf->texels, mb->blocks, 64 * sizeof(short) * num_blocks); - buf->texels += 64 * num_blocks; -} - -static void -vl_mpeg12_destroy_buffer(struct vl_mpeg12_buffer *buf) -{ - - assert(buf); - - cleanup_zscan_buffer(buf); - cleanup_idct_buffer(buf); - cleanup_mc_buffer(buf); - vl_vb_cleanup(&buf->vertex_stream); - - FREE(buf); -} - -static void -vl_mpeg12_destroy(struct pipe_video_codec *decoder) -{ - struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; - unsigned i; - - assert(decoder); - - free_video_buffer_privates(dec); - - /* Asserted in softpipe_delete_fs_state() for some reason */ - dec->context->bind_vs_state(dec->context, NULL); - dec->context->bind_fs_state(dec->context, NULL); - - dec->context->delete_depth_stencil_alpha_state(dec->context, dec->dsa); - dec->context->delete_sampler_state(dec->context, dec->sampler_ycbcr); - - vl_mc_cleanup(&dec->mc_y); - vl_mc_cleanup(&dec->mc_c); - dec->mc_source->destroy(dec->mc_source); - - if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { - vl_idct_cleanup(&dec->idct_y); - vl_idct_cleanup(&dec->idct_c); - dec->idct_source->destroy(dec->idct_source); - } - - vl_zscan_cleanup(&dec->zscan_y); - vl_zscan_cleanup(&dec->zscan_c); - - dec->context->delete_vertex_elements_state(dec->context, dec->ves_ycbcr); - dec->context->delete_vertex_elements_state(dec->context, dec->ves_mv); - - pipe_resource_reference(&dec->quads.buffer.resource, NULL); - pipe_resource_reference(&dec->pos.buffer.resource, NULL); - - pipe_sampler_view_reference(&dec->zscan_linear, NULL); - pipe_sampler_view_reference(&dec->zscan_normal, NULL); - pipe_sampler_view_reference(&dec->zscan_alternate, NULL); - - for (i = 0; i < 4; ++i) - if (dec->dec_buffers[i]) - vl_mpeg12_destroy_buffer(dec->dec_buffers[i]); - - dec->context->destroy(dec->context); - - FREE(dec); -} - -static struct vl_mpeg12_buffer * -vl_mpeg12_get_decode_buffer(struct vl_mpeg12_decoder *dec, struct pipe_video_buffer *target) -{ - struct video_buffer_private *priv; - struct vl_mpeg12_buffer *buffer; - - assert(dec); - - priv = get_video_buffer_private(dec, target); - if (priv->buffer) - return priv->buffer; - - buffer = dec->dec_buffers[dec->current_buffer]; - if (buffer) - return buffer; - - buffer = CALLOC_STRUCT(vl_mpeg12_buffer); - if (!buffer) - return NULL; - - if (!vl_vb_init(&buffer->vertex_stream, dec->context, - dec->base.width / VL_MACROBLOCK_WIDTH, - dec->base.height / VL_MACROBLOCK_HEIGHT)) - goto error_vertex_buffer; - - if (!init_mc_buffer(dec, buffer)) - goto error_mc; - - if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) - if (!init_idct_buffer(dec, buffer)) - goto error_idct; - - if (!init_zscan_buffer(dec, buffer)) - goto error_zscan; - - if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) - vl_mpg12_bs_init(&buffer->bs, &dec->base); - - if (dec->base.expect_chunked_decode) - priv->buffer = buffer; - else - dec->dec_buffers[dec->current_buffer] = buffer; - - return buffer; - -error_zscan: - cleanup_idct_buffer(buffer); - -error_idct: - cleanup_mc_buffer(buffer); - -error_mc: - vl_vb_cleanup(&buffer->vertex_stream); - -error_vertex_buffer: - FREE(buffer); - return NULL; -} - -static void -vl_mpeg12_begin_frame(struct pipe_video_codec *decoder, - struct pipe_video_buffer *target, - struct pipe_picture_desc *picture) -{ - struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; - struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture; - struct vl_mpeg12_buffer *buf; - - struct pipe_resource *tex; - struct pipe_box rect; - u_box_3d(0, 0, 0, 1, 1, 1, &rect); - - uint8_t intra_matrix[64]; - uint8_t non_intra_matrix[64]; - - unsigned i; - - assert(dec && target && picture); - - buf = vl_mpeg12_get_decode_buffer(dec, target); - assert(buf); - - if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) { - memcpy(intra_matrix, desc->intra_matrix, sizeof(intra_matrix)); - memcpy(non_intra_matrix, desc->non_intra_matrix, sizeof(non_intra_matrix)); - intra_matrix[0] = 1 << (7 - desc->intra_dc_precision); - } else { - memset(intra_matrix, 0x10, sizeof(intra_matrix)); - memset(non_intra_matrix, 0x10, sizeof(non_intra_matrix)); - } - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) { - struct vl_zscan *zscan = i == 0 ? &dec->zscan_y : &dec->zscan_c; - vl_zscan_upload_quant(zscan, &buf->zscan[i], intra_matrix, true); - vl_zscan_upload_quant(zscan, &buf->zscan[i], non_intra_matrix, false); - } - - vl_vb_map(&buf->vertex_stream, dec->context); - - tex = buf->zscan_source->texture; - rect.width = tex->width0; - rect.height = tex->height0; - - buf->texels = - dec->context->texture_map(dec->context, tex, 0, - PIPE_MAP_WRITE | - PIPE_MAP_DISCARD_RANGE, - &rect, &buf->tex_transfer); - - buf->block_num = 0; - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) { - buf->ycbcr_stream[i] = vl_vb_get_ycbcr_stream(&buf->vertex_stream, i); - buf->num_ycbcr_blocks[i] = 0; - } - - for (i = 0; i < VL_MAX_REF_FRAMES; ++i) - buf->mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i); - - if (dec->base.entrypoint >= PIPE_VIDEO_ENTRYPOINT_IDCT) { - for (i = 0; i < VL_NUM_COMPONENTS; ++i) - vl_zscan_set_layout(&buf->zscan[i], dec->zscan_linear); - } -} - -static void -vl_mpeg12_decode_macroblock(struct pipe_video_codec *decoder, - struct pipe_video_buffer *target, - struct pipe_picture_desc *picture, - const struct pipe_macroblock *macroblocks, - unsigned num_macroblocks) -{ - struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; - const struct pipe_mpeg12_macroblock *mb = (const struct pipe_mpeg12_macroblock *)macroblocks; - struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture; - struct vl_mpeg12_buffer *buf; - - unsigned i, j, mv_weights[2]; - - assert(dec && target && picture); - assert(macroblocks && macroblocks->codec == PIPE_VIDEO_FORMAT_MPEG12); - - buf = vl_mpeg12_get_decode_buffer(dec, target); - assert(buf); - - for (; num_macroblocks > 0; --num_macroblocks) { - unsigned mb_addr = mb->y * dec->width_in_macroblocks + mb->x; - - if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_PATTERN | PIPE_MPEG12_MB_TYPE_INTRA)) - UploadYcbcrBlocks(dec, buf, mb); - - MacroBlockTypeToPipeWeights(mb, mv_weights); - - for (i = 0; i < 2; ++i) { - if (!desc->ref[i]) continue; - - buf->mv_stream[i][mb_addr] = MotionVectorToPipe - ( - mb, i, - i ? PIPE_MPEG12_FS_FIRST_BACKWARD : PIPE_MPEG12_FS_FIRST_FORWARD, - mv_weights[i] - ); - } - - /* see section 7.6.6 of the spec */ - if (mb->num_skipped_macroblocks > 0) { - struct vl_motionvector skipped_mv[2]; - - if (desc->ref[0] && !desc->ref[1]) { - skipped_mv[0].top.x = skipped_mv[0].top.y = 0; - skipped_mv[0].top.weight = PIPE_VIDEO_MV_WEIGHT_MAX; - } else { - skipped_mv[0] = buf->mv_stream[0][mb_addr]; - skipped_mv[1] = buf->mv_stream[1][mb_addr]; - } - skipped_mv[0].top.field_select = PIPE_VIDEO_FRAME; - skipped_mv[1].top.field_select = PIPE_VIDEO_FRAME; - - skipped_mv[0].bottom = skipped_mv[0].top; - skipped_mv[1].bottom = skipped_mv[1].top; - - ++mb_addr; - for (i = 0; i < mb->num_skipped_macroblocks; ++i, ++mb_addr) { - for (j = 0; j < 2; ++j) { - if (!desc->ref[j]) continue; - buf->mv_stream[j][mb_addr] = skipped_mv[j]; - - } - } - } - - ++mb; - } -} - -static void -vl_mpeg12_decode_bitstream(struct pipe_video_codec *decoder, - struct pipe_video_buffer *target, - struct pipe_picture_desc *picture, - unsigned num_buffers, - const void * const *buffers, - const unsigned *sizes) -{ - struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; - struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture; - struct vl_mpeg12_buffer *buf; - - unsigned i; - - assert(dec && target && picture); - - buf = vl_mpeg12_get_decode_buffer(dec, target); - assert(buf); - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) - vl_zscan_set_layout(&buf->zscan[i], desc->alternate_scan ? - dec->zscan_alternate : dec->zscan_normal); - - vl_mpg12_bs_decode(&buf->bs, target, desc, num_buffers, buffers, sizes); -} - -static int -vl_mpeg12_end_frame(struct pipe_video_codec *decoder, - struct pipe_video_buffer *target, - struct pipe_picture_desc *picture) -{ - struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; - struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture; - struct pipe_sampler_view **ref_frames[2]; - struct pipe_sampler_view **mc_source_sv; - struct pipe_surface **target_surfaces; - struct pipe_vertex_buffer vb[3]; - struct vl_mpeg12_buffer *buf; - - const unsigned *plane_order; - unsigned i, j, component; - unsigned nr_components; - - assert(dec && target && picture); - assert(!target->interlaced); - - buf = vl_mpeg12_get_decode_buffer(dec, target); - - vl_vb_unmap(&buf->vertex_stream, dec->context); - - if (buf->tex_transfer) - dec->context->texture_unmap(dec->context, buf->tex_transfer); - - vb[0] = dec->quads; - vb[1] = dec->pos; - - target_surfaces = get_video_buffer_private(dec, target)->surfaces; - - for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { - if (desc->ref[i]) - ref_frames[i] = get_video_buffer_private(dec, desc->ref[i])->sampler_view_planes; - else - ref_frames[i] = NULL; - } - - dec->context->bind_vertex_elements_state(dec->context, dec->ves_mv); - for (i = 0; i < VL_NUM_COMPONENTS; ++i) { - if (!target_surfaces[i]) continue; - - vl_mc_set_surface(&buf->mc[i], target_surfaces[i]); - - for (j = 0; j < VL_MAX_REF_FRAMES; ++j) { - if (!ref_frames[j] || !ref_frames[j][i]) continue; - - vb[2] = vl_vb_get_mv(&buf->vertex_stream, j); - dec->context->set_vertex_buffers(dec->context, 3, vb); - - vl_mc_render_ref(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], ref_frames[j][i]); - } - } - - dec->context->bind_vertex_elements_state(dec->context, dec->ves_ycbcr); - for (i = 0; i < VL_NUM_COMPONENTS; ++i) { - if (!buf->num_ycbcr_blocks[i]) continue; - - vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i); - dec->context->set_vertex_buffers(dec->context, 2, vb); - - vl_zscan_render(i ? &dec->zscan_c : & dec->zscan_y, &buf->zscan[i] , buf->num_ycbcr_blocks[i]); - - if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) - vl_idct_flush(i ? &dec->idct_c : &dec->idct_y, &buf->idct[i], buf->num_ycbcr_blocks[i]); - } - - plane_order = vl_video_buffer_plane_order(target->buffer_format); - mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); - for (i = 0, component = 0; component < VL_NUM_COMPONENTS; ++i) { - if (!target_surfaces[i]) continue; - - nr_components = util_format_get_nr_components(target_surfaces[i]->texture->format); - for (j = 0; j < nr_components; ++j, ++component) { - unsigned plane = plane_order[component]; - if (!buf->num_ycbcr_blocks[plane]) continue; - - vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, plane); - dec->context->set_vertex_buffers(dec->context, 2, vb); - - if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) - vl_idct_prepare_stage2(i ? &dec->idct_c : &dec->idct_y, &buf->idct[plane]); - else { - dec->context->set_sampler_views(dec->context, - MESA_SHADER_FRAGMENT, 0, 1, 0, - &mc_source_sv[plane]); - dec->context->bind_sampler_states(dec->context, - MESA_SHADER_FRAGMENT, - 0, 1, &dec->sampler_ycbcr); - } - vl_mc_render_ycbcr(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], j, buf->num_ycbcr_blocks[plane]); - } - } - dec->context->flush(dec->context, NULL, 0); - ++dec->current_buffer; - dec->current_buffer %= 4; - return 0; -} - -static void -vl_mpeg12_flush(struct pipe_video_codec *decoder) -{ - assert(decoder); - - //Noop, for shaders it is much faster to flush everything in end_frame -} - -static bool -init_pipe_state(struct vl_mpeg12_decoder *dec) -{ - struct pipe_depth_stencil_alpha_state dsa; - struct pipe_sampler_state sampler; - unsigned i; - - assert(dec); - - memset(&dsa, 0, sizeof dsa); - dsa.depth_enabled = 0; - dsa.depth_writemask = 0; - dsa.depth_func = PIPE_FUNC_ALWAYS; - for (i = 0; i < 2; ++i) { - dsa.stencil[i].enabled = 0; - dsa.stencil[i].func = PIPE_FUNC_ALWAYS; - dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].valuemask = 0; - dsa.stencil[i].writemask = 0; - } - dsa.alpha_enabled = 0; - dsa.alpha_func = PIPE_FUNC_ALWAYS; - dsa.alpha_ref_value = 0; - dec->dsa = dec->context->create_depth_stencil_alpha_state(dec->context, &dsa); - dec->context->bind_depth_stencil_alpha_state(dec->context, dec->dsa); - - 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_BORDER; - 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; - dec->sampler_ycbcr = dec->context->create_sampler_state(dec->context, &sampler); - if (!dec->sampler_ycbcr) - return false; - - return true; -} - -static const struct format_config* -find_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs) -{ - struct pipe_screen *screen; - unsigned i; - - assert(dec); - - screen = dec->context->screen; - - for (i = 0; i < num_configs; ++i) { - if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D, - 1, 1, PIPE_BIND_SAMPLER_VIEW)) - continue; - - if (configs[i].idct_source_format != PIPE_FORMAT_NONE) { - if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D, - 1, 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) - continue; - - if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D, - 1, 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) - continue; - } else { - if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D, - 1, 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) - continue; - } - return &configs[i]; - } - - return NULL; -} - -static bool -init_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) -{ - unsigned num_channels; - - assert(dec); - - dec->zscan_source_format = format_config->zscan_source_format; - dec->zscan_linear = vl_zscan_layout(dec->context, vl_zscan_linear, dec->blocks_per_line); - dec->zscan_normal = vl_zscan_layout(dec->context, vl_zscan_normal, dec->blocks_per_line); - dec->zscan_alternate = vl_zscan_layout(dec->context, vl_zscan_alternate, dec->blocks_per_line); - - num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1; - - if (!vl_zscan_init(&dec->zscan_y, dec->context, dec->base.width, dec->base.height, - dec->blocks_per_line, dec->num_blocks, num_channels)) - return false; - - if (!vl_zscan_init(&dec->zscan_c, dec->context, dec->chroma_width, dec->chroma_height, - dec->blocks_per_line, dec->num_blocks, num_channels)) - return false; - - return true; -} - -static bool -init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) -{ - unsigned nr_of_idct_render_targets, max_inst; - enum pipe_format formats[3]; - struct pipe_video_buffer templat; - - struct pipe_sampler_view *matrix = NULL; - - nr_of_idct_render_targets = dec->context->screen->caps.max_render_targets; - - max_inst = dec->context->screen->shader_caps[MESA_SHADER_FRAGMENT].max_instructions; - - // Just assume we need 32 inst per render target, not 100% true, but should work in most cases - if (nr_of_idct_render_targets >= 4 && max_inst >= 32*4) - // more than 4 render targets usually doesn't makes any seens - nr_of_idct_render_targets = 4; - else - nr_of_idct_render_targets = 1; - - formats[0] = formats[1] = formats[2] = format_config->idct_source_format; - memset(&templat, 0, sizeof(templat)); - templat.width = dec->base.width / 4; - templat.height = dec->base.height; - dec->idct_source = vl_video_buffer_create_ex - ( - dec->context, &templat, - formats, 1, 1, PIPE_USAGE_DEFAULT, - PIPE_VIDEO_CHROMA_FORMAT_420 - ); - - if (!dec->idct_source) - goto error_idct_source; - - formats[0] = formats[1] = formats[2] = format_config->mc_source_format; - memset(&templat, 0, sizeof(templat)); - templat.width = dec->base.width / nr_of_idct_render_targets; - templat.height = dec->base.height / 4; - dec->mc_source = vl_video_buffer_create_ex - ( - dec->context, &templat, - formats, nr_of_idct_render_targets, 1, PIPE_USAGE_DEFAULT, - PIPE_VIDEO_CHROMA_FORMAT_420 - ); - - if (!dec->mc_source) - goto error_mc_source; - - if (!(matrix = vl_idct_upload_matrix(dec->context, format_config->idct_scale))) - goto error_matrix; - - if (!vl_idct_init(&dec->idct_y, dec->context, dec->base.width, dec->base.height, - nr_of_idct_render_targets, matrix, matrix)) - goto error_y; - - if(!vl_idct_init(&dec->idct_c, dec->context, dec->chroma_width, dec->chroma_height, - nr_of_idct_render_targets, matrix, matrix)) - goto error_c; - - pipe_sampler_view_reference(&matrix, NULL); - - return true; - -error_c: - vl_idct_cleanup(&dec->idct_y); - -error_y: - pipe_sampler_view_reference(&matrix, NULL); - -error_matrix: - dec->mc_source->destroy(dec->mc_source); - -error_mc_source: - dec->idct_source->destroy(dec->idct_source); - -error_idct_source: - return false; -} - -static bool -init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) -{ - enum pipe_format formats[3]; - struct pipe_video_buffer templat; - - formats[0] = formats[1] = formats[2] = format_config->mc_source_format; - assert(pipe_format_to_chroma_format(formats[0]) == dec->base.chroma_format); - memset(&templat, 0, sizeof(templat)); - templat.width = dec->base.width; - templat.height = dec->base.height; - dec->mc_source = vl_video_buffer_create_ex - ( - dec->context, &templat, - formats, 1, 1, PIPE_USAGE_DEFAULT, - PIPE_VIDEO_CHROMA_FORMAT_420 - ); - - return dec->mc_source != NULL; -} - -static void -mc_vert_shader_callback(void *priv, struct vl_mc *mc, - struct ureg_program *shader, - unsigned first_output, - struct ureg_dst tex) -{ - struct vl_mpeg12_decoder *dec = priv; - struct ureg_dst o_vtex; - - assert(priv && mc); - assert(shader); - - if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { - struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; - vl_idct_stage2_vert_shader(idct, shader, first_output, tex); - } else { - o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output); - ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex)); - } -} - -static void -mc_frag_shader_callback(void *priv, struct vl_mc *mc, - struct ureg_program *shader, - unsigned first_input, - struct ureg_dst dst) -{ - struct vl_mpeg12_decoder *dec = priv; - struct ureg_src src, sampler; - - assert(priv && mc); - assert(shader); - - if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { - struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; - vl_idct_stage2_frag_shader(idct, shader, first_input, dst); - } else { - src = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input, TGSI_INTERPOLATE_LINEAR); - sampler = ureg_DECL_sampler(shader, 0); - ureg_TEX(shader, dst, TGSI_TEXTURE_2D, src, sampler); - } -} - -struct pipe_video_codec * -vl_create_mpeg12_decoder(struct pipe_context *context, - const struct pipe_video_codec *templat) -{ - const unsigned block_size_pixels = VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; - const struct format_config *format_config; - struct vl_mpeg12_decoder *dec; - - assert(u_reduce_video_profile(templat->profile) == PIPE_VIDEO_FORMAT_MPEG12); - - dec = CALLOC_STRUCT(vl_mpeg12_decoder); - - if (!dec) - return NULL; - - dec->base = *templat; - dec->base.context = context; - dec->context = pipe_create_multimedia_context(context->screen, false); - - dec->base.destroy = vl_mpeg12_destroy; - dec->base.begin_frame = vl_mpeg12_begin_frame; - dec->base.decode_macroblock = vl_mpeg12_decode_macroblock; - dec->base.decode_bitstream = vl_mpeg12_decode_bitstream; - dec->base.end_frame = vl_mpeg12_end_frame; - dec->base.flush = vl_mpeg12_flush; - - dec->blocks_per_line = MAX2(util_next_power_of_two(dec->base.width) / block_size_pixels, 4); - dec->num_blocks = (dec->base.width * dec->base.height) / block_size_pixels; - dec->width_in_macroblocks = align(dec->base.width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; - - /* TODO: Implement 422, 444 */ - assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); - - if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - dec->chroma_width = dec->base.width / 2; - dec->chroma_height = dec->base.height / 2; - dec->num_blocks = dec->num_blocks * 2; - } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { - dec->chroma_width = dec->base.width / 2; - dec->chroma_height = dec->base.height; - dec->num_blocks = dec->num_blocks * 2 + dec->num_blocks; - } else { - dec->chroma_width = dec->base.width; - dec->chroma_height = dec->base.height; - dec->num_blocks = dec->num_blocks * 3; - } - - dec->quads = vl_vb_upload_quads(dec->context); - dec->pos = vl_vb_upload_pos( - dec->context, - dec->base.width / VL_MACROBLOCK_WIDTH, - dec->base.height / VL_MACROBLOCK_HEIGHT - ); - - dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->context); - dec->ves_mv = vl_vb_get_ves_mv(dec->context); - - switch (templat->entrypoint) { - case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: - format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs); - break; - - case PIPE_VIDEO_ENTRYPOINT_IDCT: - format_config = find_format_config(dec, idct_format_config, num_idct_format_configs); - break; - - case PIPE_VIDEO_ENTRYPOINT_MC: - format_config = find_format_config(dec, mc_format_config, num_mc_format_configs); - break; - - default: - assert(0); - FREE(dec); - return NULL; - } - - if (!format_config) { - FREE(dec); - return NULL; - } - - if (!init_zscan(dec, format_config)) - goto error_zscan; - - if (templat->entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { - if (!init_idct(dec, format_config)) - goto error_sources; - } else { - if (!init_mc_source_widthout_idct(dec, format_config)) - goto error_sources; - } - - if (!vl_mc_init(&dec->mc_y, dec->context, dec->base.width, dec->base.height, - VL_MACROBLOCK_HEIGHT, format_config->mc_scale, - mc_vert_shader_callback, mc_frag_shader_callback, dec)) - goto error_mc_y; - - // TODO - if (!vl_mc_init(&dec->mc_c, dec->context, dec->base.width, dec->base.height, - VL_BLOCK_HEIGHT, format_config->mc_scale, - mc_vert_shader_callback, mc_frag_shader_callback, dec)) - goto error_mc_c; - - if (!init_pipe_state(dec)) - goto error_pipe_state; - - list_inithead(&dec->buffer_privates); - - return &dec->base; - -error_pipe_state: - vl_mc_cleanup(&dec->mc_c); - -error_mc_c: - vl_mc_cleanup(&dec->mc_y); - -error_mc_y: - if (templat->entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { - vl_idct_cleanup(&dec->idct_y); - vl_idct_cleanup(&dec->idct_c); - dec->idct_source->destroy(dec->idct_source); - } - dec->mc_source->destroy(dec->mc_source); - -error_sources: - vl_zscan_cleanup(&dec->zscan_y); - vl_zscan_cleanup(&dec->zscan_c); - -error_zscan: - FREE(dec); - return NULL; -} diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h deleted file mode 100644 index 505dd675f66..00000000000 --- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * 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. - * - **************************************************************************/ - -#ifndef vl_mpeg12_decoder_h -#define vl_mpeg12_decoder_h - -#include "pipe/p_video_codec.h" - -#include "util/list.h" - -#include "vl_mpeg12_bitstream.h" -#include "vl_zscan.h" -#include "vl_idct.h" -#include "vl_mc.h" - -#include "vl_vertex_buffers.h" -#include "vl_video_buffer.h" - -struct pipe_screen; -struct pipe_context; - -struct vl_mpeg12_decoder -{ - struct pipe_video_codec base; - struct pipe_context *context; - - unsigned chroma_width, chroma_height; - - unsigned blocks_per_line; - unsigned num_blocks; - unsigned width_in_macroblocks; - - enum pipe_format zscan_source_format; - - struct pipe_vertex_buffer quads; - struct pipe_vertex_buffer pos; - - void *ves_ycbcr; - void *ves_mv; - - void *sampler_ycbcr; - - struct pipe_sampler_view *zscan_linear; - struct pipe_sampler_view *zscan_normal; - struct pipe_sampler_view *zscan_alternate; - - struct pipe_video_buffer *idct_source; - struct pipe_video_buffer *mc_source; - - struct vl_zscan zscan_y, zscan_c; - struct vl_idct idct_y, idct_c; - struct vl_mc mc_y, mc_c; - - void *dsa; - - unsigned current_buffer; - struct vl_mpeg12_buffer *dec_buffers[4]; - - struct list_head buffer_privates; -}; - -struct vl_mpeg12_buffer -{ - struct vl_vertex_buffer vertex_stream; - - unsigned block_num; - unsigned num_ycbcr_blocks[3]; - - struct pipe_sampler_view *zscan_source; - - struct vl_mpg12_bs bs; - struct vl_zscan_buffer zscan[VL_NUM_COMPONENTS]; - struct vl_idct_buffer idct[VL_NUM_COMPONENTS]; - struct vl_mc_buffer mc[VL_NUM_COMPONENTS]; - - struct pipe_transfer *tex_transfer; - short *texels; - - struct vl_ycbcr_block *ycbcr_stream[VL_NUM_COMPONENTS]; - struct vl_motionvector *mv_stream[VL_MAX_REF_FRAMES]; -}; - -/** - * creates a shader based mpeg12 decoder - */ -struct pipe_video_codec * -vl_create_mpeg12_decoder(struct pipe_context *pipe, - const struct pipe_video_codec *templat); - -#endif /* vl_mpeg12_decoder_h */ diff --git a/src/gallium/auxiliary/vl/vl_stubs.c b/src/gallium/auxiliary/vl/vl_stubs.c index cd6b73b850b..49504dd0b1b 100644 --- a/src/gallium/auxiliary/vl/vl_stubs.c +++ b/src/gallium/auxiliary/vl/vl_stubs.c @@ -1,39 +1,7 @@ #include -#include "vl_decoder.h" #include "vl_mpeg12_bitstream.h" -#include "vl_mpeg12_decoder.h" #include "vl_video_buffer.h" -#include "vl_zscan.h" - - -/* - * vl_decoder stubs - */ -bool -vl_profile_supported(struct pipe_screen *screen, - enum pipe_video_profile profile, - enum pipe_video_entrypoint entrypoint) -{ - assert(0); - return false; -} - -int -vl_level_supported(struct pipe_screen *screen, - enum pipe_video_profile profile) -{ - assert(0); - return 0; -} - -struct pipe_video_codec * -vl_create_decoder(struct pipe_context *pipe, - const struct pipe_video_codec *templat) -{ - assert(0); - return NULL; -} /* @@ -143,15 +111,3 @@ vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, { assert(0); } - - -/* - * vl_mpeg12_decoder stubs - */ -struct pipe_video_codec * -vl_create_mpeg12_decoder(struct pipe_context *pipe, - const struct pipe_video_codec *templat) -{ - assert(0); - return NULL; -} diff --git a/src/gallium/auxiliary/vl/vl_zscan.c b/src/gallium/auxiliary/vl/vl_zscan.c deleted file mode 100644 index 2468846cd6a..00000000000 --- a/src/gallium/auxiliary/vl/vl_zscan.c +++ /dev/null @@ -1,543 +0,0 @@ -/************************************************************************** - * - * Copyright 2011 Christian König - * 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 - -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -#include "util/u_draw.h" -#include "util/u_sampler.h" -#include "util/u_inlines.h" -#include "util/u_memory.h" - -#include "tgsi/tgsi_ureg.h" - -#include "vl_defines.h" -#include "vl_types.h" - -#include "vl_zscan.h" -#include "vl_vertex_buffers.h" - -enum VS_OUTPUT -{ - VS_O_VPOS = 0, - VS_O_VTEX = 0 -}; - -static void * -create_vert_shader(struct vl_zscan *zscan) -{ - struct ureg_program *shader; - struct ureg_src scale; - struct ureg_src vrect, vpos, block_num; - struct ureg_dst tmp; - struct ureg_dst o_vpos; - struct ureg_dst *o_vtex; - unsigned i; - - shader = ureg_create(MESA_SHADER_VERTEX); - if (!shader) - return NULL; - - o_vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_dst)); - - scale = ureg_imm2f(shader, - (float)VL_BLOCK_WIDTH / zscan->buffer_width, - (float)VL_BLOCK_HEIGHT / zscan->buffer_height); - - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); - vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); - block_num = ureg_DECL_vs_input(shader, VS_I_BLOCK_NUM); - - tmp = ureg_DECL_temporary(shader); - - o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); - - for (i = 0; i < zscan->num_channels; ++i) - o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i); - - /* - * o_vpos.xy = (vpos + vrect) * scale - * o_vpos.zw = 1.0f - * - * tmp.xy = InstanceID / blocks_per_line - * tmp.x = frac(tmp.x) - * tmp.y = floor(tmp.y) - * - * o_vtex.x = vrect.x / blocks_per_line + tmp.x - * o_vtex.y = vrect.y - * o_vtex.z = tmp.z * blocks_per_line / blocks_total - */ - ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), vpos, vrect); - ureg_MUL(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(tmp), scale); - ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); - - ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XW), ureg_scalar(block_num, TGSI_SWIZZLE_X), - ureg_imm1f(shader, 1.0f / zscan->blocks_per_line)); - - ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X)); - ureg_FLR(shader, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_src(tmp)); - - for (i = 0; i < zscan->num_channels; ++i) { - ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), - ureg_imm1f(shader, 1.0f / (zscan->blocks_per_line * VL_BLOCK_WIDTH) - * ((signed)i - (signed)zscan->num_channels / 2))); - - ureg_MAD(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_X), vrect, - ureg_imm1f(shader, 1.0f / zscan->blocks_per_line), ureg_src(tmp)); - ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Y), vrect); - ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Z), vpos); - ureg_MUL(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_W), ureg_src(tmp), - ureg_imm1f(shader, (float)zscan->blocks_per_line / zscan->blocks_total)); - } - - ureg_release_temporary(shader, tmp); - ureg_END(shader); - - FREE(o_vtex); - - return ureg_create_shader_and_destroy(shader, zscan->pipe); -} - -static void * -create_frag_shader(struct vl_zscan *zscan) -{ - struct ureg_program *shader; - struct ureg_src *vtex; - - struct ureg_src samp_src, samp_scan, samp_quant; - - struct ureg_dst *tmp; - struct ureg_dst quant, fragment; - - unsigned i; - - shader = ureg_create(MESA_SHADER_FRAGMENT); - if (!shader) - return NULL; - - vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_src)); - tmp = MALLOC(zscan->num_channels * sizeof(struct ureg_dst)); - - for (i = 0; i < zscan->num_channels; ++i) - vtex[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i, TGSI_INTERPOLATE_LINEAR); - - samp_src = ureg_DECL_sampler(shader, 0); - samp_scan = ureg_DECL_sampler(shader, 1); - samp_quant = ureg_DECL_sampler(shader, 2); - - for (i = 0; i < zscan->num_channels; ++i) - tmp[i] = ureg_DECL_temporary(shader); - quant = ureg_DECL_temporary(shader); - - fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); - - /* - * tmp.x = tex(vtex, 1) - * tmp.y = vtex.z - * fragment = tex(tmp, 0) * quant - */ - for (i = 0; i < zscan->num_channels; ++i) - ureg_TEX(shader, ureg_writemask(tmp[i], TGSI_WRITEMASK_X), TGSI_TEXTURE_2D, vtex[i], samp_scan); - - for (i = 0; i < zscan->num_channels; ++i) - ureg_MOV(shader, ureg_writemask(tmp[i], TGSI_WRITEMASK_Y), ureg_scalar(vtex[i], TGSI_SWIZZLE_W)); - - for (i = 0; i < zscan->num_channels; ++i) { - ureg_TEX(shader, ureg_writemask(tmp[0], TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D, ureg_src(tmp[i]), samp_src); - ureg_TEX(shader, ureg_writemask(quant, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, vtex[i], samp_quant); - } - - ureg_MUL(shader, quant, ureg_src(quant), ureg_imm1f(shader, 16.0f)); - ureg_MUL(shader, fragment, ureg_src(tmp[0]), ureg_src(quant)); - - for (i = 0; i < zscan->num_channels; ++i) - ureg_release_temporary(shader, tmp[i]); - ureg_END(shader); - - FREE(vtex); - FREE(tmp); - - return ureg_create_shader_and_destroy(shader, zscan->pipe); -} - -static bool -init_shaders(struct vl_zscan *zscan) -{ - assert(zscan); - - zscan->vs = create_vert_shader(zscan); - if (!zscan->vs) - goto error_vs; - - zscan->fs = create_frag_shader(zscan); - if (!zscan->fs) - goto error_fs; - - return true; - -error_fs: - zscan->pipe->delete_vs_state(zscan->pipe, zscan->vs); - -error_vs: - return false; -} - -static void -cleanup_shaders(struct vl_zscan *zscan) -{ - assert(zscan); - - zscan->pipe->delete_vs_state(zscan->pipe, zscan->vs); - zscan->pipe->delete_fs_state(zscan->pipe, zscan->fs); -} - -static bool -init_state(struct vl_zscan *zscan) -{ - struct pipe_blend_state blend; - struct pipe_rasterizer_state rs_state; - struct pipe_sampler_state sampler; - unsigned i; - - assert(zscan); - - memset(&rs_state, 0, sizeof(rs_state)); - rs_state.half_pixel_center = true; - rs_state.bottom_edge_rule = true; - rs_state.depth_clip_near = 1; - rs_state.depth_clip_far = 1; - - zscan->rs_state = zscan->pipe->create_rasterizer_state(zscan->pipe, &rs_state); - if (!zscan->rs_state) - goto error_rs_state; - - memset(&blend, 0, sizeof blend); - - blend.independent_blend_enable = 0; - blend.rt[0].blend_enable = 0; - 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_enable = 0; - blend.logicop_func = PIPE_LOGICOP_CLEAR; - /* Needed to allow color writes to FB, even if blending disabled */ - blend.rt[0].colormask = PIPE_MASK_RGBA; - blend.dither = 0; - zscan->blend = zscan->pipe->create_blend_state(zscan->pipe, &blend); - if (!zscan->blend) - goto error_blend; - - for (i = 0; i < 3; ++i) { - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; - sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; - 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; - zscan->samplers[i] = zscan->pipe->create_sampler_state(zscan->pipe, &sampler); - if (!zscan->samplers[i]) - goto error_samplers; - } - - return true; - -error_samplers: - for (i = 0; i < 2; ++i) - if (zscan->samplers[i]) - zscan->pipe->delete_sampler_state(zscan->pipe, zscan->samplers[i]); - - zscan->pipe->delete_rasterizer_state(zscan->pipe, zscan->rs_state); - -error_blend: - zscan->pipe->delete_blend_state(zscan->pipe, zscan->blend); - -error_rs_state: - return false; -} - -static void -cleanup_state(struct vl_zscan *zscan) -{ - unsigned i; - - assert(zscan); - - for (i = 0; i < 3; ++i) - zscan->pipe->delete_sampler_state(zscan->pipe, zscan->samplers[i]); - - zscan->pipe->delete_rasterizer_state(zscan->pipe, zscan->rs_state); - zscan->pipe->delete_blend_state(zscan->pipe, zscan->blend); -} - -struct pipe_sampler_view * -vl_zscan_layout(struct pipe_context *pipe, const int layout[64], unsigned blocks_per_line) -{ - const unsigned total_size = blocks_per_line * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; - - int patched_layout[64]; - - struct pipe_resource res_tmpl, *res; - struct pipe_sampler_view sv_tmpl, *sv; - struct pipe_transfer *buf_transfer; - unsigned x, y, i, pitch; - float *f; - - struct pipe_box rect; - u_box_3d(0, 0, 0, - VL_BLOCK_WIDTH * blocks_per_line, - VL_BLOCK_HEIGHT, - 1, &rect); - - assert(pipe && layout && blocks_per_line); - - for (i = 0; i < 64; ++i) - patched_layout[layout[i]] = i; - - memset(&res_tmpl, 0, sizeof(res_tmpl)); - res_tmpl.target = PIPE_TEXTURE_2D; - res_tmpl.format = PIPE_FORMAT_R32_FLOAT; - res_tmpl.width0 = VL_BLOCK_WIDTH * blocks_per_line; - res_tmpl.height0 = VL_BLOCK_HEIGHT; - res_tmpl.depth0 = 1; - res_tmpl.array_size = 1; - res_tmpl.usage = PIPE_USAGE_IMMUTABLE; - res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; - - res = pipe->screen->resource_create(pipe->screen, &res_tmpl); - if (!res) - goto error_resource; - - f = pipe->texture_map(pipe, res, - 0, PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE, - &rect, &buf_transfer); - if (!f) - goto error_map; - - pitch = buf_transfer->stride / sizeof(float); - - for (i = 0; i < blocks_per_line; ++i) - for (y = 0; y < VL_BLOCK_HEIGHT; ++y) - for (x = 0; x < VL_BLOCK_WIDTH; ++x) { - float addr = patched_layout[x + y * VL_BLOCK_WIDTH] + - i * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; - - addr /= total_size; - - f[i * VL_BLOCK_WIDTH + y * pitch + x] = addr; - } - - pipe->texture_unmap(pipe, buf_transfer); - - memset(&sv_tmpl, 0, sizeof(sv_tmpl)); - u_sampler_view_default_template(&sv_tmpl, res, res->format); - sv = pipe->create_sampler_view(pipe, res, &sv_tmpl); - pipe_resource_reference(&res, NULL); - if (!sv) - goto error_map; - - return sv; - -error_map: - pipe_resource_reference(&res, NULL); - -error_resource: - return NULL; -} - -bool -vl_zscan_init(struct vl_zscan *zscan, struct pipe_context *pipe, - unsigned buffer_width, unsigned buffer_height, - unsigned blocks_per_line, unsigned blocks_total, - unsigned num_channels) -{ - assert(zscan && pipe); - - zscan->pipe = pipe; - zscan->buffer_width = buffer_width; - zscan->buffer_height = buffer_height; - zscan->num_channels = num_channels; - zscan->blocks_per_line = blocks_per_line; - zscan->blocks_total = blocks_total; - - if(!init_shaders(zscan)) - return false; - - if(!init_state(zscan)) { - cleanup_shaders(zscan); - return false; - } - - return true; -} - -void -vl_zscan_cleanup(struct vl_zscan *zscan) -{ - assert(zscan); - - cleanup_shaders(zscan); - cleanup_state(zscan); -} - -bool -vl_zscan_init_buffer(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, - struct pipe_sampler_view *src, struct pipe_surface *dst) -{ - struct pipe_resource res_tmpl, *res; - struct pipe_sampler_view sv_tmpl; - - assert(zscan && buffer); - - memset(buffer, 0, sizeof(struct vl_zscan_buffer)); - - pipe_sampler_view_reference(&buffer->src, src); - - buffer->viewport.scale[0] = pipe_surface_width(dst); - buffer->viewport.scale[1] = pipe_surface_height(dst); - buffer->viewport.scale[2] = 1; - buffer->viewport.translate[0] = 0; - buffer->viewport.translate[1] = 0; - buffer->viewport.translate[2] = 0; - buffer->viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; - buffer->viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; - buffer->viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; - buffer->viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; - - buffer->fb_state.width = pipe_surface_width(dst); - buffer->fb_state.height = pipe_surface_height(dst); - buffer->fb_state.nr_cbufs = 1; - buffer->fb_state.cbufs[0] = *dst; - - memset(&res_tmpl, 0, sizeof(res_tmpl)); - res_tmpl.target = PIPE_TEXTURE_3D; - res_tmpl.format = PIPE_FORMAT_R8_UNORM; - res_tmpl.width0 = VL_BLOCK_WIDTH * zscan->blocks_per_line; - res_tmpl.height0 = VL_BLOCK_HEIGHT; - res_tmpl.depth0 = 2; - res_tmpl.array_size = 1; - res_tmpl.usage = PIPE_USAGE_IMMUTABLE; - res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; - - res = zscan->pipe->screen->resource_create(zscan->pipe->screen, &res_tmpl); - if (!res) - return false; - - memset(&sv_tmpl, 0, sizeof(sv_tmpl)); - u_sampler_view_default_template(&sv_tmpl, res, res->format); - sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = TGSI_SWIZZLE_X; - buffer->quant = zscan->pipe->create_sampler_view(zscan->pipe, res, &sv_tmpl); - pipe_resource_reference(&res, NULL); - if (!buffer->quant) - return false; - - return true; -} - -void -vl_zscan_cleanup_buffer(struct vl_zscan_buffer *buffer) -{ - assert(buffer); - - pipe_sampler_view_reference(&buffer->src, NULL); - pipe_sampler_view_reference(&buffer->layout, NULL); - pipe_sampler_view_reference(&buffer->quant, NULL); - memset(&buffer->fb_state.cbufs[0], 0, sizeof(struct pipe_surface)); -} - -void -vl_zscan_set_layout(struct vl_zscan_buffer *buffer, struct pipe_sampler_view *layout) -{ - assert(buffer); - assert(layout); - - pipe_sampler_view_reference(&buffer->layout, layout); -} - -void -vl_zscan_upload_quant(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, - const uint8_t matrix[64], bool intra) -{ - struct pipe_context *pipe; - struct pipe_transfer *buf_transfer; - unsigned x, y, i, pitch; - uint8_t *data; - - struct pipe_box rect; - u_box_3d(0, 0, intra ? 1 : 0, - VL_BLOCK_WIDTH, - VL_BLOCK_HEIGHT, - 1, &rect); - - assert(buffer); - assert(matrix); - - pipe = zscan->pipe; - - rect.width *= zscan->blocks_per_line; - - data = pipe->texture_map(pipe, buffer->quant->texture, - 0, PIPE_MAP_WRITE | - PIPE_MAP_DISCARD_RANGE, - &rect, &buf_transfer); - if (!data) - return; - - pitch = buf_transfer->stride; - - for (i = 0; i < zscan->blocks_per_line; ++i) - for (y = 0; y < VL_BLOCK_HEIGHT; ++y) - for (x = 0; x < VL_BLOCK_WIDTH; ++x) - data[i * VL_BLOCK_WIDTH + y * pitch + x] = matrix[x + y * VL_BLOCK_WIDTH]; - - pipe->texture_unmap(pipe, buf_transfer); -} - -void -vl_zscan_render(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, unsigned num_instances) -{ - assert(buffer); - - zscan->pipe->bind_rasterizer_state(zscan->pipe, zscan->rs_state); - zscan->pipe->bind_blend_state(zscan->pipe, zscan->blend); - zscan->pipe->bind_sampler_states(zscan->pipe, MESA_SHADER_FRAGMENT, - 0, 3, zscan->samplers); - zscan->pipe->set_framebuffer_state(zscan->pipe, &buffer->fb_state); - zscan->pipe->set_viewport_states(zscan->pipe, 0, 1, &buffer->viewport); - zscan->pipe->set_sampler_views(zscan->pipe, MESA_SHADER_FRAGMENT, - 0, 3, 0, &buffer->src); - zscan->pipe->bind_vs_state(zscan->pipe, zscan->vs); - zscan->pipe->bind_fs_state(zscan->pipe, zscan->fs); - util_draw_arrays_instanced(zscan->pipe, MESA_PRIM_QUADS, 0, 4, 0, num_instances); -} diff --git a/src/gallium/auxiliary/vl/vl_zscan.h b/src/gallium/auxiliary/vl/vl_zscan.h deleted file mode 100644 index 87fe6b4dfa1..00000000000 --- a/src/gallium/auxiliary/vl/vl_zscan.h +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************************** - * - * Copyright 2011 Christian König - * 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. - * - **************************************************************************/ - -#ifndef vl_zscan_h -#define vl_zscan_h - -#include "util/vl_zscan_data.h" -#include "util/compiler.h" -#include "pipe/p_state.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * shader based zscan and quantification - * expect usage of vl_vertex_buffers as a todo list - */ -struct vl_zscan -{ - struct pipe_context *pipe; - - unsigned buffer_width; - unsigned buffer_height; - - unsigned num_channels; - - unsigned blocks_per_line; - unsigned blocks_total; - - void *rs_state; - void *blend; - - void *samplers[3]; - - void *vs, *fs; -}; - -struct vl_zscan_buffer -{ - struct pipe_viewport_state viewport; - struct pipe_framebuffer_state fb_state; - - struct pipe_sampler_view *src, *layout, *quant; - struct pipe_surface *dst; -}; - -struct pipe_sampler_view * -vl_zscan_layout(struct pipe_context *pipe, const int layout[64], unsigned blocks_per_line); - -bool -vl_zscan_init(struct vl_zscan *zscan, struct pipe_context *pipe, - unsigned buffer_width, unsigned buffer_height, - unsigned blocks_per_line, unsigned blocks_total, - unsigned num_channels); - -void -vl_zscan_cleanup(struct vl_zscan *zscan); - -bool -vl_zscan_init_buffer(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, - struct pipe_sampler_view *src, struct pipe_surface *dst); - -void -vl_zscan_cleanup_buffer(struct vl_zscan_buffer *buffer); - -void -vl_zscan_set_layout(struct vl_zscan_buffer *buffer, struct pipe_sampler_view *layout); - -void -vl_zscan_upload_quant(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, - const uint8_t matrix[64], bool intra); - -void -vl_zscan_render(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, unsigned num_instances); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/gallium/drivers/d3d12/d3d12_video_dec_h264.cpp b/src/gallium/drivers/d3d12/d3d12_video_dec_h264.cpp index 3ee1024a10d..019c80d28ac 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_dec_h264.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_dec_h264.cpp @@ -23,7 +23,7 @@ #include "d3d12_video_dec.h" #include "d3d12_video_dec_h264.h" -#include "vl/vl_zscan.h" +#include "util/vl_zscan_data.h" #include diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video.c b/src/gallium/drivers/nouveau/nv50/nv84_video.c index f873bcf280b..39a55c1a770 100644 --- a/src/gallium/drivers/nouveau/nv50/nv84_video.c +++ b/src/gallium/drivers/nouveau/nv50/nv84_video.c @@ -28,7 +28,7 @@ #include "util/format/u_format.h" #include "util/u_sampler.h" #include "util/u_surface.h" -#include "vl/vl_zscan.h" +#include "util/vl_zscan_data.h" #include "nv50/nv84_video.h" diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video.h b/src/gallium/drivers/nouveau/nv50/nv84_video.h index 412b6962b9d..86ff6756f1a 100644 --- a/src/gallium/drivers/nouveau/nv50/nv84_video.h +++ b/src/gallium/drivers/nouveau/nv50/nv84_video.h @@ -23,7 +23,6 @@ #ifndef NV84_VIDEO_H_ #define NV84_VIDEO_H_ -#include "vl/vl_decoder.h" #include "vl/vl_video_buffer.h" #include "vl/vl_types.h" diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video.h b/src/gallium/drivers/nouveau/nv50/nv98_video.h index cec761df4ab..b7f4e5ecbb6 100644 --- a/src/gallium/drivers/nouveau/nv50/nv98_video.h +++ b/src/gallium/drivers/nouveau/nv50/nv98_video.h @@ -24,7 +24,6 @@ #include "nv50/nv50_screen.h" #include "nouveau_vp3_video.h" -#include "vl/vl_decoder.h" #include "vl/vl_types.h" #include "util/u_video.h" diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.h b/src/gallium/drivers/nouveau/nvc0/nvc0_video.h index cf3c942355b..9bc1e821720 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.h @@ -24,7 +24,6 @@ #include "nvc0/nvc0_screen.h" #include "nouveau_vp3_video.h" -#include "vl/vl_decoder.h" #include "vl/vl_types.h" #include "util/u_video.h" diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index 32dddb54554..006206f579e 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -32,7 +32,6 @@ #include "pipe/p_defines.h" #include "pipe/p_screen.h" #include "nir/nir_to_tgsi.h" -#include "vl/vl_decoder.h" #include "vl/vl_video_buffer.h" #include "virgl_screen.h" diff --git a/src/gallium/drivers/virgl/virgl_video.c b/src/gallium/drivers/virgl/virgl_video.c index 1e09ac04848..cc5237f8075 100644 --- a/src/gallium/drivers/virgl/virgl_video.c +++ b/src/gallium/drivers/virgl/virgl_video.c @@ -67,7 +67,6 @@ #include -#include "vl/vl_decoder.h" #include "vl/vl_video_buffer.h" #include "util/u_video.h" #include "util/u_memory.h" diff --git a/src/gallium/frontends/va/picture_hevc.c b/src/gallium/frontends/va/picture_hevc.c index 96242db3ac5..16ba4ca4b79 100644 --- a/src/gallium/frontends/va/picture_hevc.c +++ b/src/gallium/frontends/va/picture_hevc.c @@ -28,7 +28,7 @@ #include "util/macros.h" #include "util/u_qsort.h" #include "util/vl_rbsp.h" -#include "vl/vl_zscan.h" +#include "util/vl_zscan_data.h" #include "va_private.h" struct ref_cmp {