mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 15:40:11 +01:00
gallium/vl: Remove mpeg12 shader decoder
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 243475b96c.
It also doesn't make sense anymore to use shader decoder for a codec
this old.
Acked-by: Pavel Ondračka <pavel.ondracka@gmail.com>
Reviewed-by: Leo Liu <leo.liu@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37507>
This commit is contained in:
parent
b16910031b
commit
214a431caf
20 changed files with 3 additions and 3925 deletions
|
|
@ -395,28 +395,18 @@ files_libgalliumvl = files(
|
||||||
'vl/vl_compositor_cs.h',
|
'vl/vl_compositor_cs.h',
|
||||||
'vl/vl_csc.c',
|
'vl/vl_csc.c',
|
||||||
'vl/vl_csc.h',
|
'vl/vl_csc.h',
|
||||||
'vl/vl_decoder.c',
|
|
||||||
'vl/vl_decoder.h',
|
|
||||||
'vl/vl_defines.h',
|
'vl/vl_defines.h',
|
||||||
'vl/vl_deint_filter.c',
|
'vl/vl_deint_filter.c',
|
||||||
'vl/vl_deint_filter.h',
|
'vl/vl_deint_filter.h',
|
||||||
'vl/vl_deint_filter_cs.c',
|
'vl/vl_deint_filter_cs.c',
|
||||||
'vl/vl_deint_filter_cs.h',
|
'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.c',
|
||||||
'vl/vl_mpeg12_bitstream.h',
|
'vl/vl_mpeg12_bitstream.h',
|
||||||
'vl/vl_mpeg12_decoder.c',
|
|
||||||
'vl/vl_mpeg12_decoder.h',
|
|
||||||
'vl/vl_types.h',
|
'vl/vl_types.h',
|
||||||
'vl/vl_vertex_buffers.c',
|
'vl/vl_vertex_buffers.c',
|
||||||
'vl/vl_vertex_buffers.h',
|
'vl/vl_vertex_buffers.h',
|
||||||
'vl/vl_video_buffer.c',
|
'vl/vl_video_buffer.c',
|
||||||
'vl/vl_video_buffer.h',
|
'vl/vl_video_buffer.h',
|
||||||
'vl/vl_zscan.c',
|
|
||||||
'vl/vl_zscan.h',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
vlwinsys_deps = []
|
vlwinsys_deps = []
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 <assert.h>
|
|
||||||
|
|
||||||
#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]);
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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 <assert.h>
|
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -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 */
|
|
||||||
|
|
@ -1,39 +1,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "vl_decoder.h"
|
|
||||||
#include "vl_mpeg12_bitstream.h"
|
#include "vl_mpeg12_bitstream.h"
|
||||||
#include "vl_mpeg12_decoder.h"
|
|
||||||
#include "vl_video_buffer.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);
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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 <assert.h>
|
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "d3d12_video_dec.h"
|
#include "d3d12_video_dec.h"
|
||||||
#include "d3d12_video_dec_h264.h"
|
#include "d3d12_video_dec_h264.h"
|
||||||
#include "vl/vl_zscan.h"
|
#include "util/vl_zscan_data.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
#include "util/format/u_format.h"
|
#include "util/format/u_format.h"
|
||||||
#include "util/u_sampler.h"
|
#include "util/u_sampler.h"
|
||||||
#include "util/u_surface.h"
|
#include "util/u_surface.h"
|
||||||
#include "vl/vl_zscan.h"
|
#include "util/vl_zscan_data.h"
|
||||||
|
|
||||||
#include "nv50/nv84_video.h"
|
#include "nv50/nv84_video.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
#ifndef NV84_VIDEO_H_
|
#ifndef NV84_VIDEO_H_
|
||||||
#define NV84_VIDEO_H_
|
#define NV84_VIDEO_H_
|
||||||
|
|
||||||
#include "vl/vl_decoder.h"
|
|
||||||
#include "vl/vl_video_buffer.h"
|
#include "vl/vl_video_buffer.h"
|
||||||
#include "vl/vl_types.h"
|
#include "vl/vl_types.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
#include "nv50/nv50_screen.h"
|
#include "nv50/nv50_screen.h"
|
||||||
#include "nouveau_vp3_video.h"
|
#include "nouveau_vp3_video.h"
|
||||||
|
|
||||||
#include "vl/vl_decoder.h"
|
|
||||||
#include "vl/vl_types.h"
|
#include "vl/vl_types.h"
|
||||||
|
|
||||||
#include "util/u_video.h"
|
#include "util/u_video.h"
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
#include "nvc0/nvc0_screen.h"
|
#include "nvc0/nvc0_screen.h"
|
||||||
#include "nouveau_vp3_video.h"
|
#include "nouveau_vp3_video.h"
|
||||||
|
|
||||||
#include "vl/vl_decoder.h"
|
|
||||||
#include "vl/vl_types.h"
|
#include "vl/vl_types.h"
|
||||||
|
|
||||||
#include "util/u_video.h"
|
#include "util/u_video.h"
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@
|
||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
#include "pipe/p_screen.h"
|
#include "pipe/p_screen.h"
|
||||||
#include "nir/nir_to_tgsi.h"
|
#include "nir/nir_to_tgsi.h"
|
||||||
#include "vl/vl_decoder.h"
|
|
||||||
#include "vl/vl_video_buffer.h"
|
#include "vl/vl_video_buffer.h"
|
||||||
|
|
||||||
#include "virgl_screen.h"
|
#include "virgl_screen.h"
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "vl/vl_decoder.h"
|
|
||||||
#include "vl/vl_video_buffer.h"
|
#include "vl/vl_video_buffer.h"
|
||||||
#include "util/u_video.h"
|
#include "util/u_video.h"
|
||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
#include "util/macros.h"
|
#include "util/macros.h"
|
||||||
#include "util/u_qsort.h"
|
#include "util/u_qsort.h"
|
||||||
#include "util/vl_rbsp.h"
|
#include "util/vl_rbsp.h"
|
||||||
#include "vl/vl_zscan.h"
|
#include "util/vl_zscan_data.h"
|
||||||
#include "va_private.h"
|
#include "va_private.h"
|
||||||
|
|
||||||
struct ref_cmp {
|
struct ref_cmp {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue